From f996b2c85819d924c1bae47fcbb47fbf0d1a8979 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 20 Feb 2023 18:47:08 -0500 Subject: [PATCH 1/6] rework initialization --- Project.toml | 18 ++++++++-- deps/build.jl | 97 -------------------------------------------------- src/PAPI.jl | 93 ++++++++++++++++++++++++++++++++++++----------- src/options.jl | 11 ++++++ 4 files changed, 99 insertions(+), 120 deletions(-) delete mode 100644 deps/build.jl create mode 100644 src/options.jl diff --git a/Project.toml b/Project.toml index 36bff99..c131bb5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,16 +1,28 @@ name = "PAPI" uuid = "c3f66453-0ce3-4e3d-8601-c404262f204f" authors = ["Tom Haber "] -version = "0.3.0" +version = "0.4.0" [deps] JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" NUMA_jll = "7f51dc2b-bb24-59f8-b771-bb1490e4195d" PAPI_jll = "062e04e5-c3d3-5549-ab66-579a72a7bc1b" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +Preferences = "21216c6a-2e73-6563-6e65-726566657250" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[weakdeps] +CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + [compat] -julia = "1" +CUDA = "4" +JSON = "0.21" +NUMA_jll = "2" +PAPI_jll = "7" +Statistics = "1" +Preferences = "1" +julia = "1.6" + +[extras] +CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" diff --git a/deps/build.jl b/deps/build.jl deleted file mode 100644 index 07047b5..0000000 --- a/deps/build.jl +++ /dev/null @@ -1,97 +0,0 @@ -using Pkg.TOML, Libdl - -config_toml = joinpath(first(DEPOT_PATH), "prefs", "PAPI.toml") -mkpath(dirname(config_toml)) - -if !isfile(config_toml) - touch(config_toml) -end - -config = TOML.parsefile(config_toml) -update_config = false - -if haskey(ENV, "JULIA_PAPI_BINARY") - config["binary"] = ENV["JULIA_PAPI_BINARY"] - update_config = true -end - -if haskey(ENV, "JULIA_PAPI_LIBRARY") - config["library"] = ENV["JULIA_PAPI_LIBRARY"] - update_config = true -end - -if haskey(ENV, "JULIA_PAPI_PATH") - config["path"] = ENV["JULIA_PAPI_PATH"] - update_config = true -end - -if update_config - open(config_toml, write=true) do f - TOML.print(f, config) - end -end - -binary = get(config, "binary", "") - -# 2. generate deps.jl -deps = if binary == "system" - @info "using system PAPI" - library = get(config, "library", "libpapi") - path = get(config, "path", "") - - const libpapi = find_library(library, path == "" ? [] : [joinpath(path, "lib"), joinpath(path, "lib64")]) - if libpapi == "" - error("libpapi could not be found") - end - - papi_version = try - papi_version_cmd = Cmd([path == "" ? "papi_version" : joinpath(path, "bin", "papi_version")]) - output = chomp(read(papi_version_cmd, String)) - startswith(output, "PAPI Version: ") || error("unexpected output from $papi_version") - v = output[15:end] - m = match(r"^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?$", v) - m === nothing && throw(ArgumentError("invalid version string: $v")) - major, minor, patch, _ = map(m.captures) do x - x !== nothing ? parse(Int, x) : 0 - end - VersionNumber(major, minor, patch) - catch e - error("failed to find papi version: $e") - end - - quote - const libpapi = $libpapi - const papi_version = $papi_version - end -else - @warn "using PAPI_jll: the use of a system library is probably recommended" - papi_version = v"6.0.0" - - quote - using PAPI_jll - const papi_version = $papi_version - end -end - -remove_line_numbers(x) = x -function remove_line_numbers(ex::Expr) - if ex.head == :macrocall - ex.args[2] = nothing - else - ex.args = [remove_line_numbers(arg) for arg in ex.args if !(arg isa LineNumberNode)] - end - return ex -end - -# only update deps.jl if it has changed. -# allows users to call Pkg.build("PAPI") without triggering another round of precompilation -deps_str = - """ - # This file has been generated automatically. - # It will be overwritten the next time `Pkg.build("PAPI")` is called. - """ * - string(remove_line_numbers(deps)) - -if !isfile("deps.jl") || deps_str != read("deps.jl", String) - write("deps.jl", deps_str) -end diff --git a/src/PAPI.jl b/src/PAPI.jl index 4e1c45b..d31a903 100644 --- a/src/PAPI.jl +++ b/src/PAPI.jl @@ -1,11 +1,59 @@ module PAPI using NUMA_jll +using PAPI_jll +using Preferences -try - include(joinpath(dirname(@__DIR__), "deps","deps.jl")) -catch e - error("PAPI.jl not properly configured, please run `Pkg.build(\"PAPI\")`.") +if !PAPI_jll.is_available() + const libpapi = load_preference(PAPI_jll, "libPAPI_path", nothing) + is_available() = libpapi !== nothing +else + is_available() = PAPI_jll.is_available() +end + +""" + locate() + +Locate the PAPI library currently being used, by PAPI.jl +""" +function locate() + if libpapi === nothing + error("libpapi not available. Use `set_library` to set the path to libpapi") + end + return libpapi +end + +""" + set_library!(path) + +Change the library path used by PAPI.jl for `libpapi.so` to `path`. + +!!! note + You will need to restart Julia to use the new library. + +!!! warning + Due to a bug in Julia (until 1.6.5 and 1.7.1), setting preferences in transitive dependencies + is broken (https://github.com/JuliaPackaging/Preferences.jl/issues/24). To fix this either update + your version of Julia, or add PAPI_jll as a direct dependency to your project. +""" +function set_library!(path) + if !ispath(path) + error("PAPI library path $path not found") + end + set_preferences!( + PAPI_jll, + "libPAPI_path" => realpath(path); + force=true, + ) + @warn "PAPI library path changed, you will need to restart Julia for the change to take effect" path + + if VERSION <= v"1.6.5" || VERSION == v"1.7.0" + @warn """ + Due to a bug in Julia (until 1.6.5 and 1.7.1), setting preferences in transitive dependencies + is broken (https://github.com/JuliaPackaging/Preferences.jl/issues/24). To fix this either update + your version of Julia, or add PAPI_jll as a direct dependency to your project. + """ + end end const REFCOUNT = Ref(zero(UInt)) @@ -19,6 +67,7 @@ end include("constants.jl") include("error.jl") +include("options.jl") include("events.jl") include("eventsets.jl") include("counters.jl") @@ -28,25 +77,29 @@ include("prettyprint.jl") include("serialization.jl") include("numa.jl") +if is_available() + const papi_current_version = get_option(PAPI_LIB_VERSION, C_NULL) +end + function __init__() - papi_current_version = (papi_version.major << 24) | (papi_version.minor << 16) - - # init the library and make sure that some counters are available - rv = ccall((:PAPI_library_init, libpapi), Cint, (Cint,), papi_current_version) - if rv != papi_current_version - if rv > 0 - error("PAPI library version mismatch!") - else - throw(PAPIError(rv)) - end - end + if is_available() + # init the library and make sure that some counters are available + rv = ccall((:PAPI_library_init, libpapi), Cint, (Cint,), papi_current_version) + if rv != papi_current_version + if rv > 0 + error("PAPI library version mismatch!") + else + throw(PAPIError(rv)) + end + end - if num_counters() == 0 - error("PAPI init error: No counters are available on the current system") - end + if num_counters() == 0 + error("PAPI init error: No counters are available on the current system") + end - REFCOUNT[] += 1 - atexit(deref_shutdown) + REFCOUNT[] += 1 + atexit(deref_shutdown) + end end """ diff --git a/src/options.jl b/src/options.jl new file mode 100644 index 0000000..1c6ed3d --- /dev/null +++ b/src/options.jl @@ -0,0 +1,11 @@ +const PAPI_LIB_VERSION = Cint(21) + +get_option(opt, ptr) = ccall((:PAPI_get_opt, libpapi), Cint, (Cint, Ptr{Cvoid}), opt, ptr) + +function version() + ver = get_option(PAPI_LIB_VERSION, C_NULL) + major = ver >> 24 + minor = ver >> 16 & (1 << 8 - 1) + patch = ver & (1 << 8 - 1) + VersionNumber(major, minor, patch) +end \ No newline at end of file From 3f15f4498293322a605233a9c1aa70767364b899 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 20 Feb 2023 18:50:37 -0500 Subject: [PATCH 2/6] fixup! rework initialization --- test/Project.toml | 3 +++ test/runtests.jl | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 test/Project.toml diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..73f75fc --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,3 @@ +[deps] +CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/runtests.jl b/test/runtests.jl index 25161f1..9f30dfd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,10 @@ using PAPI, Test +if !PAPI.is_available() + @info "PAPI is not available on this Platform use PAPI.set_library" + exit() +end + include("eventset.jl") #include("counting.jl") include("serialization.jl") From c94c1edf595b41d8d3943ffb3f301f8036c76cfe Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 20 Feb 2023 19:22:38 -0500 Subject: [PATCH 3/6] auto generate headers --- Project.toml | 2 +- gen/LocalPreferences.toml | 2 + gen/Project.toml | 6 + gen/generator.jl | 23 + gen/generator.toml | 8 + gen/prologue.jl | 1 + src/API/7/libPAPI.jl | 1981 +++++++++++++++++++++++++++++++++++++ src/PAPI.jl | 27 +- 8 files changed, 2041 insertions(+), 9 deletions(-) create mode 100644 gen/LocalPreferences.toml create mode 100644 gen/Project.toml create mode 100644 gen/generator.jl create mode 100644 gen/generator.toml create mode 100644 gen/prologue.jl create mode 100644 src/API/7/libPAPI.jl diff --git a/Project.toml b/Project.toml index c131bb5..86a9fa5 100644 --- a/Project.toml +++ b/Project.toml @@ -20,8 +20,8 @@ CUDA = "4" JSON = "0.21" NUMA_jll = "2" PAPI_jll = "7" -Statistics = "1" Preferences = "1" +Statistics = "1" julia = "1.6" [extras] diff --git a/gen/LocalPreferences.toml b/gen/LocalPreferences.toml new file mode 100644 index 0000000..4cbb0f7 --- /dev/null +++ b/gen/LocalPreferences.toml @@ -0,0 +1,2 @@ +[CUDA_Runtime_jll] +version = "none" diff --git a/gen/Project.toml b/gen/Project.toml new file mode 100644 index 0000000..1e79921 --- /dev/null +++ b/gen/Project.toml @@ -0,0 +1,6 @@ +[deps] +Clang = "40e3b903-d033-50b4-a0cc-940c62c95e31" +PAPI_jll = "062e04e5-c3d3-5549-ab66-579a72a7bc1b" + +[extras] +CUDA_Runtime_jll = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" diff --git a/gen/generator.jl b/gen/generator.jl new file mode 100644 index 0000000..92c9c24 --- /dev/null +++ b/gen/generator.jl @@ -0,0 +1,23 @@ +using Clang.Generators +using PAPI_jll + +@assert PAPI_jll.is_available() + +cd(@__DIR__) + +include_dir = normpath(PAPI_jll.artifact_dir, "include") + +options = load_options(joinpath(@__DIR__, "generator.toml")) + +# add compiler flags, e.g. "-DXXXXXXXXX" +args = get_default_args() # Note you must call this function firstly and then append your own flags +push!(args, "-I$include_dir") + +# there is also an experimental `detect_headers` function for auto-detecting top-level headers in the directory +headers = [joinpath(include_dir, "papi.h")] + +# create context +ctx = create_context(headers, args, options) + +# run generator +build!(ctx) \ No newline at end of file diff --git a/gen/generator.toml b/gen/generator.toml new file mode 100644 index 0000000..d4dc8f4 --- /dev/null +++ b/gen/generator.toml @@ -0,0 +1,8 @@ +[general] +library_name = "libpapi" +output_file_path = "./libPAPI.jl" +module_name = "API" +jll_pkg_name = "PAPI_jll" +prologue_file_path = "./prologue.jl" +print_enum_as_integer = true +print_using_CEnum = false diff --git a/gen/prologue.jl b/gen/prologue.jl new file mode 100644 index 0000000..68ed292 --- /dev/null +++ b/gen/prologue.jl @@ -0,0 +1 @@ +PAPI_VERSION_NUMBER(maj,min,rev,inc) = (((maj)<<24) | ((min)<<16) | ((rev)<<8) | (inc)) diff --git a/src/API/7/libPAPI.jl b/src/API/7/libPAPI.jl new file mode 100644 index 0000000..5c8f425 --- /dev/null +++ b/src/API/7/libPAPI.jl @@ -0,0 +1,1981 @@ +module API + +using PAPI_jll +export PAPI_jll + +PAPI_VERSION_NUMBER(maj,min,rev,inc) = (((maj)<<24) | ((min)<<16) | ((rev)<<8) | (inc)) + + +function PAPI_get_event_component(EventCode) + ccall((:PAPI_get_event_component, libpapi), Cint, (Cint,), EventCode) +end + +function PAPI_strerror(arg1) + ccall((:PAPI_strerror, libpapi), Ptr{Cchar}, (Cint,), arg1) +end + +const var"##Ctag#304" = UInt32 +const PAPI_L1_DCM_idx = 0 % UInt32 +const PAPI_L1_ICM_idx = 1 % UInt32 +const PAPI_L2_DCM_idx = 2 % UInt32 +const PAPI_L2_ICM_idx = 3 % UInt32 +const PAPI_L3_DCM_idx = 4 % UInt32 +const PAPI_L3_ICM_idx = 5 % UInt32 +const PAPI_L1_TCM_idx = 6 % UInt32 +const PAPI_L2_TCM_idx = 7 % UInt32 +const PAPI_L3_TCM_idx = 8 % UInt32 +const PAPI_CA_SNP_idx = 9 % UInt32 +const PAPI_CA_SHR_idx = 10 % UInt32 +const PAPI_CA_CLN_idx = 11 % UInt32 +const PAPI_CA_INV_idx = 12 % UInt32 +const PAPI_CA_ITV_idx = 13 % UInt32 +const PAPI_L3_LDM_idx = 14 % UInt32 +const PAPI_L3_STM_idx = 15 % UInt32 +const PAPI_BRU_IDL_idx = 16 % UInt32 +const PAPI_FXU_IDL_idx = 17 % UInt32 +const PAPI_FPU_IDL_idx = 18 % UInt32 +const PAPI_LSU_IDL_idx = 19 % UInt32 +const PAPI_TLB_DM_idx = 20 % UInt32 +const PAPI_TLB_IM_idx = 21 % UInt32 +const PAPI_TLB_TL_idx = 22 % UInt32 +const PAPI_L1_LDM_idx = 23 % UInt32 +const PAPI_L1_STM_idx = 24 % UInt32 +const PAPI_L2_LDM_idx = 25 % UInt32 +const PAPI_L2_STM_idx = 26 % UInt32 +const PAPI_BTAC_M_idx = 27 % UInt32 +const PAPI_PRF_DM_idx = 28 % UInt32 +const PAPI_L3_DCH_idx = 29 % UInt32 +const PAPI_TLB_SD_idx = 30 % UInt32 +const PAPI_CSR_FAL_idx = 31 % UInt32 +const PAPI_CSR_SUC_idx = 32 % UInt32 +const PAPI_CSR_TOT_idx = 33 % UInt32 +const PAPI_MEM_SCY_idx = 34 % UInt32 +const PAPI_MEM_RCY_idx = 35 % UInt32 +const PAPI_MEM_WCY_idx = 36 % UInt32 +const PAPI_STL_ICY_idx = 37 % UInt32 +const PAPI_FUL_ICY_idx = 38 % UInt32 +const PAPI_STL_CCY_idx = 39 % UInt32 +const PAPI_FUL_CCY_idx = 40 % UInt32 +const PAPI_HW_INT_idx = 41 % UInt32 +const PAPI_BR_UCN_idx = 42 % UInt32 +const PAPI_BR_CN_idx = 43 % UInt32 +const PAPI_BR_TKN_idx = 44 % UInt32 +const PAPI_BR_NTK_idx = 45 % UInt32 +const PAPI_BR_MSP_idx = 46 % UInt32 +const PAPI_BR_PRC_idx = 47 % UInt32 +const PAPI_FMA_INS_idx = 48 % UInt32 +const PAPI_TOT_IIS_idx = 49 % UInt32 +const PAPI_TOT_INS_idx = 50 % UInt32 +const PAPI_INT_INS_idx = 51 % UInt32 +const PAPI_FP_INS_idx = 52 % UInt32 +const PAPI_LD_INS_idx = 53 % UInt32 +const PAPI_SR_INS_idx = 54 % UInt32 +const PAPI_BR_INS_idx = 55 % UInt32 +const PAPI_VEC_INS_idx = 56 % UInt32 +const PAPI_RES_STL_idx = 57 % UInt32 +const PAPI_FP_STAL_idx = 58 % UInt32 +const PAPI_TOT_CYC_idx = 59 % UInt32 +const PAPI_LST_INS_idx = 60 % UInt32 +const PAPI_SYC_INS_idx = 61 % UInt32 +const PAPI_L1_DCH_idx = 62 % UInt32 +const PAPI_L2_DCH_idx = 63 % UInt32 +const PAPI_L1_DCA_idx = 64 % UInt32 +const PAPI_L2_DCA_idx = 65 % UInt32 +const PAPI_L3_DCA_idx = 66 % UInt32 +const PAPI_L1_DCR_idx = 67 % UInt32 +const PAPI_L2_DCR_idx = 68 % UInt32 +const PAPI_L3_DCR_idx = 69 % UInt32 +const PAPI_L1_DCW_idx = 70 % UInt32 +const PAPI_L2_DCW_idx = 71 % UInt32 +const PAPI_L3_DCW_idx = 72 % UInt32 +const PAPI_L1_ICH_idx = 73 % UInt32 +const PAPI_L2_ICH_idx = 74 % UInt32 +const PAPI_L3_ICH_idx = 75 % UInt32 +const PAPI_L1_ICA_idx = 76 % UInt32 +const PAPI_L2_ICA_idx = 77 % UInt32 +const PAPI_L3_ICA_idx = 78 % UInt32 +const PAPI_L1_ICR_idx = 79 % UInt32 +const PAPI_L2_ICR_idx = 80 % UInt32 +const PAPI_L3_ICR_idx = 81 % UInt32 +const PAPI_L1_ICW_idx = 82 % UInt32 +const PAPI_L2_ICW_idx = 83 % UInt32 +const PAPI_L3_ICW_idx = 84 % UInt32 +const PAPI_L1_TCH_idx = 85 % UInt32 +const PAPI_L2_TCH_idx = 86 % UInt32 +const PAPI_L3_TCH_idx = 87 % UInt32 +const PAPI_L1_TCA_idx = 88 % UInt32 +const PAPI_L2_TCA_idx = 89 % UInt32 +const PAPI_L3_TCA_idx = 90 % UInt32 +const PAPI_L1_TCR_idx = 91 % UInt32 +const PAPI_L2_TCR_idx = 92 % UInt32 +const PAPI_L3_TCR_idx = 93 % UInt32 +const PAPI_L1_TCW_idx = 94 % UInt32 +const PAPI_L2_TCW_idx = 95 % UInt32 +const PAPI_L3_TCW_idx = 96 % UInt32 +const PAPI_FML_INS_idx = 97 % UInt32 +const PAPI_FAD_INS_idx = 98 % UInt32 +const PAPI_FDV_INS_idx = 99 % UInt32 +const PAPI_FSQ_INS_idx = 100 % UInt32 +const PAPI_FNV_INS_idx = 101 % UInt32 +const PAPI_FP_OPS_idx = 102 % UInt32 +const PAPI_SP_OPS_idx = 103 % UInt32 +const PAPI_DP_OPS_idx = 104 % UInt32 +const PAPI_VEC_SP_idx = 105 % UInt32 +const PAPI_VEC_DP_idx = 106 % UInt32 +const PAPI_REF_CYC_idx = 107 % UInt32 +const PAPI_END_idx = 108 % UInt32 + +const var"##Ctag#305" = UInt32 +const PAPI_ENUM_EVENTS = 0 % UInt32 +const PAPI_ENUM_FIRST = 1 % UInt32 +const PAPI_PRESET_ENUM_AVAIL = 2 % UInt32 +const PAPI_PRESET_ENUM_MSC = 3 % UInt32 +const PAPI_PRESET_ENUM_INS = 4 % UInt32 +const PAPI_PRESET_ENUM_IDL = 5 % UInt32 +const PAPI_PRESET_ENUM_BR = 6 % UInt32 +const PAPI_PRESET_ENUM_CND = 7 % UInt32 +const PAPI_PRESET_ENUM_MEM = 8 % UInt32 +const PAPI_PRESET_ENUM_CACH = 9 % UInt32 +const PAPI_PRESET_ENUM_L1 = 10 % UInt32 +const PAPI_PRESET_ENUM_L2 = 11 % UInt32 +const PAPI_PRESET_ENUM_L3 = 12 % UInt32 +const PAPI_PRESET_ENUM_TLB = 13 % UInt32 +const PAPI_PRESET_ENUM_FP = 14 % UInt32 +const PAPI_NTV_ENUM_UMASKS = 15 % UInt32 +const PAPI_NTV_ENUM_UMASK_COMBOS = 16 % UInt32 +const PAPI_NTV_ENUM_IARR = 17 % UInt32 +const PAPI_NTV_ENUM_DARR = 18 % UInt32 +const PAPI_NTV_ENUM_OPCM = 19 % UInt32 +const PAPI_NTV_ENUM_IEAR = 20 % UInt32 +const PAPI_NTV_ENUM_DEAR = 21 % UInt32 +const PAPI_NTV_ENUM_GROUPS = 22 % UInt32 + +const PAPI_thread_id_t = Culong + +struct _papi_all_thr_spec + data::NTuple{24, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_all_thr_spec}, f::Symbol) + f === :num && return Ptr{Cint}(x + 0) + f === :id && return Ptr{Ptr{PAPI_thread_id_t}}(x + 8) + f === :data && return Ptr{Ptr{Ptr{Cvoid}}}(x + 16) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_all_thr_spec, f::Symbol) + r = Ref{_papi_all_thr_spec}(x) + ptr = Base.unsafe_convert(Ptr{_papi_all_thr_spec}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_all_thr_spec}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_all_thr_spec_t = _papi_all_thr_spec + +# typedef void ( * PAPI_overflow_handler_t ) ( int EventSet , void * address , long long overflow_vector , void * context ) +const PAPI_overflow_handler_t = Ptr{Cvoid} + +const vptr_t = Ptr{Cvoid} + +struct _papi_sprofil + data::NTuple{32, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_sprofil}, f::Symbol) + f === :pr_base && return Ptr{Ptr{Cvoid}}(x + 0) + f === :pr_size && return Ptr{Cuint}(x + 8) + f === :pr_off && return Ptr{vptr_t}(x + 16) + f === :pr_scale && return Ptr{Cuint}(x + 24) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_sprofil, f::Symbol) + r = Ref{_papi_sprofil}(x) + ptr = Base.unsafe_convert(Ptr{_papi_sprofil}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_sprofil}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_sprofil_t = _papi_sprofil + +struct _papi_itimer_option + data::NTuple{16, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_itimer_option}, f::Symbol) + f === :itimer_num && return Ptr{Cint}(x + 0) + f === :itimer_sig && return Ptr{Cint}(x + 4) + f === :ns && return Ptr{Cint}(x + 8) + f === :flags && return Ptr{Cint}(x + 12) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_itimer_option, f::Symbol) + r = Ref{_papi_itimer_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_itimer_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_itimer_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_itimer_option_t = _papi_itimer_option + +struct _papi_inherit_option + data::NTuple{8, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_inherit_option}, f::Symbol) + f === :eventset && return Ptr{Cint}(x + 0) + f === :inherit && return Ptr{Cint}(x + 4) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_inherit_option, f::Symbol) + r = Ref{_papi_inherit_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_inherit_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_inherit_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_inherit_option_t = _papi_inherit_option + +struct _papi_domain_option + data::NTuple{12, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_domain_option}, f::Symbol) + f === :def_cidx && return Ptr{Cint}(x + 0) + f === :eventset && return Ptr{Cint}(x + 4) + f === :domain && return Ptr{Cint}(x + 8) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_domain_option, f::Symbol) + r = Ref{_papi_domain_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_domain_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_domain_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_domain_option_t = _papi_domain_option + +struct _papi_granularity_option + data::NTuple{12, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_granularity_option}, f::Symbol) + f === :def_cidx && return Ptr{Cint}(x + 0) + f === :eventset && return Ptr{Cint}(x + 4) + f === :granularity && return Ptr{Cint}(x + 8) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_granularity_option, f::Symbol) + r = Ref{_papi_granularity_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_granularity_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_granularity_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_granularity_option_t = _papi_granularity_option + +struct _papi_preload_option + data::NTuple{258, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_preload_option}, f::Symbol) + f === :lib_preload_env && return Ptr{NTuple{128, Cchar}}(x + 0) + f === :lib_preload_sep && return Ptr{Cchar}(x + 128) + f === :lib_dir_env && return Ptr{NTuple{128, Cchar}}(x + 129) + f === :lib_dir_sep && return Ptr{Cchar}(x + 257) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_preload_option, f::Symbol) + r = Ref{_papi_preload_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_preload_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_preload_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_preload_info_t = _papi_preload_option + +struct _papi_component_option + data::NTuple{2272, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_component_option}, f::Symbol) + f === :name && return Ptr{NTuple{128, Cchar}}(x + 0) + f === :short_name && return Ptr{NTuple{64, Cchar}}(x + 128) + f === :description && return Ptr{NTuple{128, Cchar}}(x + 192) + f === :version && return Ptr{NTuple{64, Cchar}}(x + 320) + f === :support_version && return Ptr{NTuple{64, Cchar}}(x + 384) + f === :kernel_version && return Ptr{NTuple{64, Cchar}}(x + 448) + f === :disabled_reason && return Ptr{NTuple{1024, Cchar}}(x + 512) + f === :disabled && return Ptr{Cint}(x + 1536) + f === :initialized && return Ptr{Cint}(x + 1540) + f === :CmpIdx && return Ptr{Cint}(x + 1544) + f === :num_cntrs && return Ptr{Cint}(x + 1548) + f === :num_mpx_cntrs && return Ptr{Cint}(x + 1552) + f === :num_preset_events && return Ptr{Cint}(x + 1556) + f === :num_native_events && return Ptr{Cint}(x + 1560) + f === :default_domain && return Ptr{Cint}(x + 1564) + f === :available_domains && return Ptr{Cint}(x + 1568) + f === :default_granularity && return Ptr{Cint}(x + 1572) + f === :available_granularities && return Ptr{Cint}(x + 1576) + f === :hardware_intr_sig && return Ptr{Cint}(x + 1580) + f === :component_type && return Ptr{Cint}(x + 1584) + f === :pmu_names && return Ptr{NTuple{80, Ptr{Cchar}}}(x + 1592) + f === :reserved && return Ptr{NTuple{8, Cint}}(x + 2232) + f === :hardware_intr && return (Ptr{Cuint}(x + 2264), 0, 1) + f === :precise_intr && return (Ptr{Cuint}(x + 2264), 1, 1) + f === :posix1b_timers && return (Ptr{Cuint}(x + 2264), 2, 1) + f === :kernel_profile && return (Ptr{Cuint}(x + 2264), 3, 1) + f === :kernel_multiplex && return (Ptr{Cuint}(x + 2264), 4, 1) + f === :fast_counter_read && return (Ptr{Cuint}(x + 2264), 5, 1) + f === :fast_real_timer && return (Ptr{Cuint}(x + 2264), 6, 1) + f === :fast_virtual_timer && return (Ptr{Cuint}(x + 2264), 7, 1) + f === :attach && return (Ptr{Cuint}(x + 2264), 8, 1) + f === :attach_must_ptrace && return (Ptr{Cuint}(x + 2264), 9, 1) + f === :cntr_umasks && return (Ptr{Cuint}(x + 2264), 10, 1) + f === :cpu && return (Ptr{Cuint}(x + 2264), 11, 1) + f === :inherit && return (Ptr{Cuint}(x + 2264), 12, 1) + f === :reserved_bits && return (Ptr{Cuint}(x + 2264), 13, 19) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_component_option, f::Symbol) + r = Ref{_papi_component_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_component_option}, r) + fptr = getproperty(ptr, f) + begin + if fptr isa Ptr + return GC.@preserve(r, unsafe_load(fptr)) + else + (baseptr, offset, width) = fptr + ty = eltype(baseptr) + baseptr32 = convert(Ptr{UInt32}, baseptr) + u64 = GC.@preserve(r, unsafe_load(baseptr32)) + if offset + width > 32 + u64 |= GC.@preserve(r, unsafe_load(baseptr32 + 4)) << 32 + end + u64 = u64 >> offset & (1 << width - 1) + return u64 % ty + end + end +end + +function Base.setproperty!(x::Ptr{_papi_component_option}, f::Symbol, v) + fptr = getproperty(x, f) + if fptr isa Ptr + unsafe_store!(getproperty(x, f), v) + else + (baseptr, offset, width) = fptr + baseptr32 = convert(Ptr{UInt32}, baseptr) + u64 = unsafe_load(baseptr32) + straddle = offset + width > 32 + if straddle + u64 |= unsafe_load(baseptr32 + 4) << 32 + end + mask = 1 << width - 1 + u64 &= ~(mask << offset) + u64 |= (unsigned(v) & mask) << offset + unsafe_store!(baseptr32, u64 & typemax(UInt32)) + if straddle + unsafe_store!(baseptr32 + 4, u64 >> 32) + end + end +end + +const PAPI_component_info_t = _papi_component_option + +struct _papi_mpx_info + data::NTuple{12, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_mpx_info}, f::Symbol) + f === :timer_sig && return Ptr{Cint}(x + 0) + f === :timer_num && return Ptr{Cint}(x + 4) + f === :timer_us && return Ptr{Cint}(x + 8) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_mpx_info, f::Symbol) + r = Ref{_papi_mpx_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_mpx_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_mpx_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_mpx_info_t = _papi_mpx_info + +# typedef int ( * PAPI_debug_handler_t ) ( int code ) +const PAPI_debug_handler_t = Ptr{Cvoid} + +struct _papi_debug_option + data::NTuple{16, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_debug_option}, f::Symbol) + f === :level && return Ptr{Cint}(x + 0) + f === :handler && return Ptr{PAPI_debug_handler_t}(x + 8) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_debug_option, f::Symbol) + r = Ref{_papi_debug_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_debug_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_debug_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_debug_option_t = _papi_debug_option + +struct _papi_address_map + data::NTuple{1072, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_address_map}, f::Symbol) + f === :name && return Ptr{NTuple{1024, Cchar}}(x + 0) + f === :text_start && return Ptr{vptr_t}(x + 1024) + f === :text_end && return Ptr{vptr_t}(x + 1032) + f === :data_start && return Ptr{vptr_t}(x + 1040) + f === :data_end && return Ptr{vptr_t}(x + 1048) + f === :bss_start && return Ptr{vptr_t}(x + 1056) + f === :bss_end && return Ptr{vptr_t}(x + 1064) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_address_map, f::Symbol) + r = Ref{_papi_address_map}(x) + ptr = Base.unsafe_convert(Ptr{_papi_address_map}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_address_map}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_address_map_t = _papi_address_map + +struct _papi_program_info + data::NTuple{2096, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_program_info}, f::Symbol) + f === :fullname && return Ptr{NTuple{1024, Cchar}}(x + 0) + f === :address_info && return Ptr{PAPI_address_map_t}(x + 1024) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_program_info, f::Symbol) + r = Ref{_papi_program_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_program_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_program_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_exe_info_t = _papi_program_info + +struct _papi_shared_lib_info + data::NTuple{16, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_shared_lib_info}, f::Symbol) + f === :map && return Ptr{Ptr{PAPI_address_map_t}}(x + 0) + f === :count && return Ptr{Cint}(x + 8) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_shared_lib_info, f::Symbol) + r = Ref{_papi_shared_lib_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_shared_lib_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_shared_lib_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_shlib_info_t = _papi_shared_lib_info + +const PAPI_user_defined_events_file_t = Ptr{Cchar} + +struct _papi_mh_tlb_info + data::NTuple{16, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_mh_tlb_info}, f::Symbol) + f === :type && return Ptr{Cint}(x + 0) + f === :num_entries && return Ptr{Cint}(x + 4) + f === :page_size && return Ptr{Cint}(x + 8) + f === :associativity && return Ptr{Cint}(x + 12) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_mh_tlb_info, f::Symbol) + r = Ref{_papi_mh_tlb_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_mh_tlb_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_mh_tlb_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_mh_tlb_info_t = _papi_mh_tlb_info + +struct _papi_mh_cache_info + data::NTuple{20, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_mh_cache_info}, f::Symbol) + f === :type && return Ptr{Cint}(x + 0) + f === :size && return Ptr{Cint}(x + 4) + f === :line_size && return Ptr{Cint}(x + 8) + f === :num_lines && return Ptr{Cint}(x + 12) + f === :associativity && return Ptr{Cint}(x + 16) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_mh_cache_info, f::Symbol) + r = Ref{_papi_mh_cache_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_mh_cache_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_mh_cache_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_mh_cache_info_t = _papi_mh_cache_info + +struct _papi_mh_level_info + data::NTuple{216, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_mh_level_info}, f::Symbol) + f === :tlb && return Ptr{NTuple{6, PAPI_mh_tlb_info_t}}(x + 0) + f === :cache && return Ptr{NTuple{6, PAPI_mh_cache_info_t}}(x + 96) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_mh_level_info, f::Symbol) + r = Ref{_papi_mh_level_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_mh_level_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_mh_level_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_mh_level_t = _papi_mh_level_info + +struct _papi_mh_info + data::NTuple{868, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_mh_info}, f::Symbol) + f === :levels && return Ptr{Cint}(x + 0) + f === :level && return Ptr{NTuple{4, PAPI_mh_level_t}}(x + 4) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_mh_info, f::Symbol) + r = Ref{_papi_mh_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_mh_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_mh_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_mh_info_t = _papi_mh_info + +struct _papi_hw_info + data::NTuple{1480, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_hw_info}, f::Symbol) + f === :ncpu && return Ptr{Cint}(x + 0) + f === :threads && return Ptr{Cint}(x + 4) + f === :cores && return Ptr{Cint}(x + 8) + f === :sockets && return Ptr{Cint}(x + 12) + f === :nnodes && return Ptr{Cint}(x + 16) + f === :totalcpus && return Ptr{Cint}(x + 20) + f === :vendor && return Ptr{Cint}(x + 24) + f === :vendor_string && return Ptr{NTuple{128, Cchar}}(x + 28) + f === :model && return Ptr{Cint}(x + 156) + f === :model_string && return Ptr{NTuple{128, Cchar}}(x + 160) + f === :revision && return Ptr{Cfloat}(x + 288) + f === :cpuid_family && return Ptr{Cint}(x + 292) + f === :cpuid_model && return Ptr{Cint}(x + 296) + f === :cpuid_stepping && return Ptr{Cint}(x + 300) + f === :cpu_max_mhz && return Ptr{Cint}(x + 304) + f === :cpu_min_mhz && return Ptr{Cint}(x + 308) + f === :mem_hierarchy && return Ptr{PAPI_mh_info_t}(x + 312) + f === :virtualized && return Ptr{Cint}(x + 1180) + f === :virtual_vendor_string && return Ptr{NTuple{128, Cchar}}(x + 1184) + f === :virtual_vendor_version && return Ptr{NTuple{128, Cchar}}(x + 1312) + f === :mhz && return Ptr{Cfloat}(x + 1440) + f === :clock_mhz && return Ptr{Cint}(x + 1444) + f === :reserved && return Ptr{NTuple{8, Cint}}(x + 1448) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_hw_info, f::Symbol) + r = Ref{_papi_hw_info}(x) + ptr = Base.unsafe_convert(Ptr{_papi_hw_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_hw_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_hw_info_t = _papi_hw_info + +struct _papi_attach_option + data::NTuple{16, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_attach_option}, f::Symbol) + f === :eventset && return Ptr{Cint}(x + 0) + f === :tid && return Ptr{Culong}(x + 8) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_attach_option, f::Symbol) + r = Ref{_papi_attach_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_attach_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_attach_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_attach_option_t = _papi_attach_option + +struct _papi_cpu_option + data::NTuple{8, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_cpu_option}, f::Symbol) + f === :eventset && return Ptr{Cint}(x + 0) + f === :cpu_num && return Ptr{Cuint}(x + 4) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_cpu_option, f::Symbol) + r = Ref{_papi_cpu_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_cpu_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_cpu_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_cpu_option_t = _papi_cpu_option + +struct _papi_multiplex_option + data::NTuple{12, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_multiplex_option}, f::Symbol) + f === :eventset && return Ptr{Cint}(x + 0) + f === :ns && return Ptr{Cint}(x + 4) + f === :flags && return Ptr{Cint}(x + 8) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_multiplex_option, f::Symbol) + r = Ref{_papi_multiplex_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_multiplex_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_multiplex_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_multiplex_option_t = _papi_multiplex_option + +struct _papi_addr_range_option + data::NTuple{32, UInt8} +end + +function Base.getproperty(x::Ptr{_papi_addr_range_option}, f::Symbol) + f === :eventset && return Ptr{Cint}(x + 0) + f === :start && return Ptr{vptr_t}(x + 8) + f === :_end && return Ptr{vptr_t}(x + 16) + f === :start_off && return Ptr{Cint}(x + 24) + f === :end_off && return Ptr{Cint}(x + 28) + return getfield(x, f) +end + +function Base.getproperty(x::_papi_addr_range_option, f::Symbol) + r = Ref{_papi_addr_range_option}(x) + ptr = Base.unsafe_convert(Ptr{_papi_addr_range_option}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_papi_addr_range_option}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_addr_range_option_t = _papi_addr_range_option + +struct PAPI_option_t + data::NTuple{264, UInt8} +end + +function Base.getproperty(x::Ptr{PAPI_option_t}, f::Symbol) + f === :preload && return Ptr{PAPI_preload_info_t}(x + 0) + f === :debug && return Ptr{PAPI_debug_option_t}(x + 0) + f === :inherit && return Ptr{PAPI_inherit_option_t}(x + 0) + f === :granularity && return Ptr{PAPI_granularity_option_t}(x + 0) + f === :defgranularity && return Ptr{PAPI_granularity_option_t}(x + 0) + f === :domain && return Ptr{PAPI_domain_option_t}(x + 0) + f === :defdomain && return Ptr{PAPI_domain_option_t}(x + 0) + f === :attach && return Ptr{PAPI_attach_option_t}(x + 0) + f === :cpu && return Ptr{PAPI_cpu_option_t}(x + 0) + f === :multiplex && return Ptr{PAPI_multiplex_option_t}(x + 0) + f === :itimer && return Ptr{PAPI_itimer_option_t}(x + 0) + f === :hw_info && return Ptr{Ptr{PAPI_hw_info_t}}(x + 0) + f === :shlib_info && return Ptr{Ptr{PAPI_shlib_info_t}}(x + 0) + f === :exe_info && return Ptr{Ptr{PAPI_exe_info_t}}(x + 0) + f === :cmp_info && return Ptr{Ptr{PAPI_component_info_t}}(x + 0) + f === :addr && return Ptr{PAPI_addr_range_option_t}(x + 0) + f === :events_file && return Ptr{PAPI_user_defined_events_file_t}(x + 0) + return getfield(x, f) +end + +function Base.getproperty(x::PAPI_option_t, f::Symbol) + r = Ref{PAPI_option_t}(x) + ptr = Base.unsafe_convert(Ptr{PAPI_option_t}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{PAPI_option_t}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +struct _dmem_t + data::NTuple{96, UInt8} +end + +function Base.getproperty(x::Ptr{_dmem_t}, f::Symbol) + f === :peak && return Ptr{Clonglong}(x + 0) + f === :size && return Ptr{Clonglong}(x + 8) + f === :resident && return Ptr{Clonglong}(x + 16) + f === :high_water_mark && return Ptr{Clonglong}(x + 24) + f === :shared && return Ptr{Clonglong}(x + 32) + f === :text && return Ptr{Clonglong}(x + 40) + f === :library && return Ptr{Clonglong}(x + 48) + f === :heap && return Ptr{Clonglong}(x + 56) + f === :locked && return Ptr{Clonglong}(x + 64) + f === :stack && return Ptr{Clonglong}(x + 72) + f === :pagesize && return Ptr{Clonglong}(x + 80) + f === :pte && return Ptr{Clonglong}(x + 88) + return getfield(x, f) +end + +function Base.getproperty(x::_dmem_t, f::Symbol) + r = Ref{_dmem_t}(x) + ptr = Base.unsafe_convert(Ptr{_dmem_t}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{_dmem_t}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_dmem_info_t = _dmem_t + +const var"##Ctag#318" = UInt32 +const PAPI_LOCATION_CORE = 0 % UInt32 +const PAPI_LOCATION_CPU = 1 % UInt32 +const PAPI_LOCATION_PACKAGE = 2 % UInt32 +const PAPI_LOCATION_UNCORE = 3 % UInt32 + +const var"##Ctag#319" = UInt32 +const PAPI_DATATYPE_INT64 = 0 % UInt32 +const PAPI_DATATYPE_UINT64 = 1 % UInt32 +const PAPI_DATATYPE_FP64 = 2 % UInt32 +const PAPI_DATATYPE_BIT64 = 3 % UInt32 + +const var"##Ctag#320" = UInt32 +const PAPI_VALUETYPE_RUNNING_SUM = 0 % UInt32 +const PAPI_VALUETYPE_ABSOLUTE = 1 % UInt32 + +const var"##Ctag#321" = UInt32 +const PAPI_TIMESCOPE_SINCE_START = 0 % UInt32 +const PAPI_TIMESCOPE_SINCE_LAST = 1 % UInt32 +const PAPI_TIMESCOPE_UNTIL_NEXT = 2 % UInt32 +const PAPI_TIMESCOPE_POINT = 3 % UInt32 + +const var"##Ctag#322" = UInt32 +const PAPI_UPDATETYPE_ARBITRARY = 0 % UInt32 +const PAPI_UPDATETYPE_PUSH = 1 % UInt32 +const PAPI_UPDATETYPE_PULL = 2 % UInt32 +const PAPI_UPDATETYPE_FIXEDFREQ = 3 % UInt32 + +struct event_info + data::NTuple{6680, UInt8} +end + +function Base.getproperty(x::Ptr{event_info}, f::Symbol) + f === :event_code && return Ptr{Cuint}(x + 0) + f === :symbol && return Ptr{NTuple{1024, Cchar}}(x + 4) + f === :short_descr && return Ptr{NTuple{64, Cchar}}(x + 1028) + f === :long_descr && return Ptr{NTuple{1024, Cchar}}(x + 1092) + f === :component_index && return Ptr{Cint}(x + 2116) + f === :units && return Ptr{NTuple{64, Cchar}}(x + 2120) + f === :location && return Ptr{Cint}(x + 2184) + f === :data_type && return Ptr{Cint}(x + 2188) + f === :value_type && return Ptr{Cint}(x + 2192) + f === :timescope && return Ptr{Cint}(x + 2196) + f === :update_type && return Ptr{Cint}(x + 2200) + f === :update_freq && return Ptr{Cint}(x + 2204) + f === :count && return Ptr{Cuint}(x + 2208) + f === :event_type && return Ptr{Cuint}(x + 2212) + f === :derived && return Ptr{NTuple{64, Cchar}}(x + 2216) + f === :postfix && return Ptr{NTuple{256, Cchar}}(x + 2280) + f === :code && return Ptr{NTuple{12, Cuint}}(x + 2536) + f === :name && return Ptr{NTuple{12, NTuple{256, Cchar}}}(x + 2584) + f === :note && return Ptr{NTuple{1024, Cchar}}(x + 5656) + return getfield(x, f) +end + +function Base.getproperty(x::event_info, f::Symbol) + r = Ref{event_info}(x) + ptr = Base.unsafe_convert(Ptr{event_info}, r) + fptr = getproperty(ptr, f) + GC.@preserve r unsafe_load(fptr) +end + +function Base.setproperty!(x::Ptr{event_info}, f::Symbol, v) + unsafe_store!(getproperty(x, f), v) +end + +const PAPI_event_info_t = event_info + +const PAPI_dev_type_id_e = UInt32 +const PAPI_DEV_TYPE_ID__CPU = 0 % UInt32 +const PAPI_DEV_TYPE_ID__CUDA = 1 % UInt32 +const PAPI_DEV_TYPE_ID__ROCM = 2 % UInt32 +const PAPI_DEV_TYPE_ID__MAX_NUM = 3 % UInt32 + +const var"##Ctag#324" = UInt32 +const PAPI_DEV_TYPE_ENUM__FIRST = 0 % UInt32 +const PAPI_DEV_TYPE_ENUM__CPU = 1 % UInt32 +const PAPI_DEV_TYPE_ENUM__CUDA = 2 % UInt32 +const PAPI_DEV_TYPE_ENUM__ROCM = 4 % UInt32 +const PAPI_DEV_TYPE_ENUM__ALL = 7 % UInt32 + +const PAPI_dev_type_attr_e = UInt32 +const PAPI_DEV_TYPE_ATTR__INT_PAPI_ID = 0 % UInt32 +const PAPI_DEV_TYPE_ATTR__INT_VENDOR_ID = 1 % UInt32 +const PAPI_DEV_TYPE_ATTR__CHAR_NAME = 2 % UInt32 +const PAPI_DEV_TYPE_ATTR__INT_COUNT = 3 % UInt32 +const PAPI_DEV_TYPE_ATTR__CHAR_STATUS = 4 % UInt32 + +const PAPI_dev_attr_e = UInt32 +const PAPI_DEV_ATTR__CPU_CHAR_NAME = 0 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1I_CACHE_SIZE = 1 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1D_CACHE_SIZE = 2 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L2U_CACHE_SIZE = 3 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L3U_CACHE_SIZE = 4 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1I_CACHE_LINE_SIZE = 5 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1D_CACHE_LINE_SIZE = 6 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L2U_CACHE_LINE_SIZE = 7 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L3U_CACHE_LINE_SIZE = 8 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1I_CACHE_LINE_COUNT = 9 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1D_CACHE_LINE_COUNT = 10 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L2U_CACHE_LINE_COUNT = 11 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L3U_CACHE_LINE_COUNT = 12 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1I_CACHE_ASSOC = 13 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L1D_CACHE_ASSOC = 14 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L2U_CACHE_ASSOC = 15 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_L3U_CACHE_ASSOC = 16 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_SOCKET_COUNT = 17 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_NUMA_COUNT = 18 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_CORE_COUNT = 19 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_THREAD_COUNT = 20 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_FAMILY = 21 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_MODEL = 22 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_STEPPING = 23 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_NUMA_MEM_SIZE = 24 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_THR_NUMA_AFFINITY = 25 % UInt32 +const PAPI_DEV_ATTR__CPU_UINT_THR_PER_NUMA = 26 % UInt32 +const PAPI_DEV_ATTR__CUDA_ULONG_UID = 27 % UInt32 +const PAPI_DEV_ATTR__CUDA_CHAR_DEVICE_NAME = 28 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_WARP_SIZE = 29 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_SHM_PER_BLK = 30 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_SHM_PER_SM = 31 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_BLK_DIM_X = 32 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_BLK_DIM_Y = 33 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_BLK_DIM_Z = 34 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_GRD_DIM_X = 35 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_GRD_DIM_Y = 36 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_GRD_DIM_Z = 37 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_THR_PER_BLK = 38 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_SM_COUNT = 39 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_MULTI_KERNEL = 40 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_MAP_HOST_MEM = 41 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_MEMCPY_OVERLAP = 42 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_UNIFIED_ADDR = 43 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_MANAGED_MEM = 44 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_COMP_CAP_MAJOR = 45 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_COMP_CAP_MINOR = 46 % UInt32 +const PAPI_DEV_ATTR__CUDA_UINT_BLK_PER_SM = 47 % UInt32 +const PAPI_DEV_ATTR__ROCM_ULONG_UID = 48 % UInt32 +const PAPI_DEV_ATTR__ROCM_CHAR_DEVICE_NAME = 49 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_WAVEFRONT_SIZE = 50 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_WORKGROUP_SIZE = 51 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_WAVE_PER_CU = 52 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_SHM_PER_WG = 53 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_WG_DIM_X = 54 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_WG_DIM_Y = 55 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_WG_DIM_Z = 56 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_GRD_DIM_X = 57 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_GRD_DIM_Y = 58 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_GRD_DIM_Z = 59 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_CU_COUNT = 60 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_SIMD_PER_CU = 61 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_COMP_CAP_MAJOR = 62 % UInt32 +const PAPI_DEV_ATTR__ROCM_UINT_COMP_CAP_MINOR = 63 % UInt32 + +function PAPI_accum(EventSet, values) + ccall((:PAPI_accum, libpapi), Cint, (Cint, Ptr{Clonglong}), EventSet, values) +end + +function PAPI_add_event(EventSet, Event) + ccall((:PAPI_add_event, libpapi), Cint, (Cint, Cint), EventSet, Event) +end + +function PAPI_add_named_event(EventSet, EventName) + ccall((:PAPI_add_named_event, libpapi), Cint, (Cint, Ptr{Cchar}), EventSet, EventName) +end + +function PAPI_add_events(EventSet, Events, number) + ccall((:PAPI_add_events, libpapi), Cint, (Cint, Ptr{Cint}, Cint), EventSet, Events, number) +end + +function PAPI_assign_eventset_component(EventSet, cidx) + ccall((:PAPI_assign_eventset_component, libpapi), Cint, (Cint, Cint), EventSet, cidx) +end + +function PAPI_attach(EventSet, tid) + ccall((:PAPI_attach, libpapi), Cint, (Cint, Culong), EventSet, tid) +end + +function PAPI_cleanup_eventset(EventSet) + ccall((:PAPI_cleanup_eventset, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_create_eventset(EventSet) + ccall((:PAPI_create_eventset, libpapi), Cint, (Ptr{Cint},), EventSet) +end + +function PAPI_detach(EventSet) + ccall((:PAPI_detach, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_destroy_eventset(EventSet) + ccall((:PAPI_destroy_eventset, libpapi), Cint, (Ptr{Cint},), EventSet) +end + +function PAPI_enum_event(EventCode, modifier) + ccall((:PAPI_enum_event, libpapi), Cint, (Ptr{Cint}, Cint), EventCode, modifier) +end + +function PAPI_enum_cmp_event(EventCode, modifier, cidx) + ccall((:PAPI_enum_cmp_event, libpapi), Cint, (Ptr{Cint}, Cint, Cint), EventCode, modifier, cidx) +end + +function PAPI_event_code_to_name(EventCode, out) + ccall((:PAPI_event_code_to_name, libpapi), Cint, (Cint, Ptr{Cchar}), EventCode, out) +end + +function PAPI_event_name_to_code(in, out) + ccall((:PAPI_event_name_to_code, libpapi), Cint, (Ptr{Cchar}, Ptr{Cint}), in, out) +end + +function PAPI_get_dmem_info(dest) + ccall((:PAPI_get_dmem_info, libpapi), Cint, (Ptr{PAPI_dmem_info_t},), dest) +end + +function PAPI_get_event_info(EventCode, info) + ccall((:PAPI_get_event_info, libpapi), Cint, (Cint, Ptr{PAPI_event_info_t}), EventCode, info) +end + +function PAPI_get_executable_info() + ccall((:PAPI_get_executable_info, libpapi), Ptr{PAPI_exe_info_t}, ()) +end + +function PAPI_get_hardware_info() + ccall((:PAPI_get_hardware_info, libpapi), Ptr{PAPI_hw_info_t}, ()) +end + +function PAPI_get_component_info(cidx) + ccall((:PAPI_get_component_info, libpapi), Ptr{PAPI_component_info_t}, (Cint,), cidx) +end + +function PAPI_get_multiplex(EventSet) + ccall((:PAPI_get_multiplex, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_get_opt(option, ptr) + ccall((:PAPI_get_opt, libpapi), Cint, (Cint, Ptr{PAPI_option_t}), option, ptr) +end + +function PAPI_get_cmp_opt(option, ptr, cidx) + ccall((:PAPI_get_cmp_opt, libpapi), Cint, (Cint, Ptr{PAPI_option_t}, Cint), option, ptr, cidx) +end + +function PAPI_get_real_cyc() + ccall((:PAPI_get_real_cyc, libpapi), Clonglong, ()) +end + +function PAPI_get_real_nsec() + ccall((:PAPI_get_real_nsec, libpapi), Clonglong, ()) +end + +function PAPI_get_real_usec() + ccall((:PAPI_get_real_usec, libpapi), Clonglong, ()) +end + +function PAPI_get_shared_lib_info() + ccall((:PAPI_get_shared_lib_info, libpapi), Ptr{PAPI_shlib_info_t}, ()) +end + +function PAPI_get_thr_specific(tag, ptr) + ccall((:PAPI_get_thr_specific, libpapi), Cint, (Cint, Ptr{Ptr{Cvoid}}), tag, ptr) +end + +function PAPI_get_overflow_event_index(Eventset, overflow_vector, array, number) + ccall((:PAPI_get_overflow_event_index, libpapi), Cint, (Cint, Clonglong, Ptr{Cint}, Ptr{Cint}), Eventset, overflow_vector, array, number) +end + +function PAPI_get_virt_cyc() + ccall((:PAPI_get_virt_cyc, libpapi), Clonglong, ()) +end + +function PAPI_get_virt_nsec() + ccall((:PAPI_get_virt_nsec, libpapi), Clonglong, ()) +end + +function PAPI_get_virt_usec() + ccall((:PAPI_get_virt_usec, libpapi), Clonglong, ()) +end + +function PAPI_is_initialized() + ccall((:PAPI_is_initialized, libpapi), Cint, ()) +end + +function PAPI_library_init(version) + ccall((:PAPI_library_init, libpapi), Cint, (Cint,), version) +end + +function PAPI_list_events(EventSet, Events, number) + ccall((:PAPI_list_events, libpapi), Cint, (Cint, Ptr{Cint}, Ptr{Cint}), EventSet, Events, number) +end + +function PAPI_list_threads(tids, number) + ccall((:PAPI_list_threads, libpapi), Cint, (Ptr{Culong}, Ptr{Cint}), tids, number) +end + +function PAPI_lock(arg1) + ccall((:PAPI_lock, libpapi), Cint, (Cint,), arg1) +end + +function PAPI_multiplex_init() + ccall((:PAPI_multiplex_init, libpapi), Cint, ()) +end + +function PAPI_num_cmp_hwctrs(cidx) + ccall((:PAPI_num_cmp_hwctrs, libpapi), Cint, (Cint,), cidx) +end + +function PAPI_num_events(EventSet) + ccall((:PAPI_num_events, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_overflow(EventSet, EventCode, threshold, flags, handler) + ccall((:PAPI_overflow, libpapi), Cint, (Cint, Cint, Cint, Cint, PAPI_overflow_handler_t), EventSet, EventCode, threshold, flags, handler) +end + +function PAPI_perror(msg) + ccall((:PAPI_perror, libpapi), Cvoid, (Ptr{Cchar},), msg) +end + +function PAPI_profil(buf, bufsiz, offset, scale, EventSet, EventCode, threshold, flags) + ccall((:PAPI_profil, libpapi), Cint, (Ptr{Cvoid}, Cuint, vptr_t, Cuint, Cint, Cint, Cint, Cint), buf, bufsiz, offset, scale, EventSet, EventCode, threshold, flags) +end + +function PAPI_query_event(EventCode) + ccall((:PAPI_query_event, libpapi), Cint, (Cint,), EventCode) +end + +function PAPI_query_named_event(EventName) + ccall((:PAPI_query_named_event, libpapi), Cint, (Ptr{Cchar},), EventName) +end + +function PAPI_read(EventSet, values) + ccall((:PAPI_read, libpapi), Cint, (Cint, Ptr{Clonglong}), EventSet, values) +end + +function PAPI_read_ts(EventSet, values, cyc) + ccall((:PAPI_read_ts, libpapi), Cint, (Cint, Ptr{Clonglong}, Ptr{Clonglong}), EventSet, values, cyc) +end + +function PAPI_register_thread() + ccall((:PAPI_register_thread, libpapi), Cint, ()) +end + +function PAPI_remove_event(EventSet, EventCode) + ccall((:PAPI_remove_event, libpapi), Cint, (Cint, Cint), EventSet, EventCode) +end + +function PAPI_remove_named_event(EventSet, EventName) + ccall((:PAPI_remove_named_event, libpapi), Cint, (Cint, Ptr{Cchar}), EventSet, EventName) +end + +function PAPI_remove_events(EventSet, Events, number) + ccall((:PAPI_remove_events, libpapi), Cint, (Cint, Ptr{Cint}, Cint), EventSet, Events, number) +end + +function PAPI_reset(EventSet) + ccall((:PAPI_reset, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_set_debug(level) + ccall((:PAPI_set_debug, libpapi), Cint, (Cint,), level) +end + +function PAPI_set_cmp_domain(domain, cidx) + ccall((:PAPI_set_cmp_domain, libpapi), Cint, (Cint, Cint), domain, cidx) +end + +function PAPI_set_domain(domain) + ccall((:PAPI_set_domain, libpapi), Cint, (Cint,), domain) +end + +function PAPI_set_cmp_granularity(granularity, cidx) + ccall((:PAPI_set_cmp_granularity, libpapi), Cint, (Cint, Cint), granularity, cidx) +end + +function PAPI_set_granularity(granularity) + ccall((:PAPI_set_granularity, libpapi), Cint, (Cint,), granularity) +end + +function PAPI_set_multiplex(EventSet) + ccall((:PAPI_set_multiplex, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_set_opt(option, ptr) + ccall((:PAPI_set_opt, libpapi), Cint, (Cint, Ptr{PAPI_option_t}), option, ptr) +end + +function PAPI_set_thr_specific(tag, ptr) + ccall((:PAPI_set_thr_specific, libpapi), Cint, (Cint, Ptr{Cvoid}), tag, ptr) +end + +function PAPI_shutdown() + ccall((:PAPI_shutdown, libpapi), Cvoid, ()) +end + +function PAPI_sprofil(prof, profcnt, EventSet, EventCode, threshold, flags) + ccall((:PAPI_sprofil, libpapi), Cint, (Ptr{PAPI_sprofil_t}, Cint, Cint, Cint, Cint, Cint), prof, profcnt, EventSet, EventCode, threshold, flags) +end + +function PAPI_start(EventSet) + ccall((:PAPI_start, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_state(EventSet, status) + ccall((:PAPI_state, libpapi), Cint, (Cint, Ptr{Cint}), EventSet, status) +end + +function PAPI_stop(EventSet, values) + ccall((:PAPI_stop, libpapi), Cint, (Cint, Ptr{Clonglong}), EventSet, values) +end + +function PAPI_thread_id() + ccall((:PAPI_thread_id, libpapi), Culong, ()) +end + +function PAPI_thread_init(id_fn) + ccall((:PAPI_thread_init, libpapi), Cint, (Ptr{Cvoid},), id_fn) +end + +function PAPI_unlock(arg1) + ccall((:PAPI_unlock, libpapi), Cint, (Cint,), arg1) +end + +function PAPI_unregister_thread() + ccall((:PAPI_unregister_thread, libpapi), Cint, ()) +end + +function PAPI_write(EventSet, values) + ccall((:PAPI_write, libpapi), Cint, (Cint, Ptr{Clonglong}), EventSet, values) +end + +function PAPI_get_eventset_component(EventSet) + ccall((:PAPI_get_eventset_component, libpapi), Cint, (Cint,), EventSet) +end + +function PAPI_get_component_index(name) + ccall((:PAPI_get_component_index, libpapi), Cint, (Ptr{Cchar},), name) +end + +function PAPI_disable_component(cidx) + ccall((:PAPI_disable_component, libpapi), Cint, (Cint,), cidx) +end + +function PAPI_disable_component_by_name(name) + ccall((:PAPI_disable_component_by_name, libpapi), Cint, (Ptr{Cchar},), name) +end + +function PAPI_num_components() + ccall((:PAPI_num_components, libpapi), Cint, ()) +end + +function PAPI_flips_rate(event, rtime, ptime, flpins, mflips) + ccall((:PAPI_flips_rate, libpapi), Cint, (Cint, Ptr{Cfloat}, Ptr{Cfloat}, Ptr{Clonglong}, Ptr{Cfloat}), event, rtime, ptime, flpins, mflips) +end + +function PAPI_flops_rate(event, rtime, ptime, flpops, mflops) + ccall((:PAPI_flops_rate, libpapi), Cint, (Cint, Ptr{Cfloat}, Ptr{Cfloat}, Ptr{Clonglong}, Ptr{Cfloat}), event, rtime, ptime, flpops, mflops) +end + +function PAPI_ipc(rtime, ptime, ins, ipc) + ccall((:PAPI_ipc, libpapi), Cint, (Ptr{Cfloat}, Ptr{Cfloat}, Ptr{Clonglong}, Ptr{Cfloat}), rtime, ptime, ins, ipc) +end + +function PAPI_epc(event, rtime, ptime, ref, core, evt, epc) + ccall((:PAPI_epc, libpapi), Cint, (Cint, Ptr{Cfloat}, Ptr{Cfloat}, Ptr{Clonglong}, Ptr{Clonglong}, Ptr{Clonglong}, Ptr{Cfloat}), event, rtime, ptime, ref, core, evt, epc) +end + +# no prototype is found for this function at papi.h:1224:8, please use with caution +function PAPI_rate_stop() + ccall((:PAPI_rate_stop, libpapi), Cint, ()) +end + +function PAPI_enum_dev_type(enum_modifier, handle) + ccall((:PAPI_enum_dev_type, libpapi), Cint, (Cint, Ptr{Ptr{Cvoid}}), enum_modifier, handle) +end + +function PAPI_get_dev_type_attr(handle, attr, value) + ccall((:PAPI_get_dev_type_attr, libpapi), Cint, (Ptr{Cvoid}, PAPI_dev_type_attr_e, Ptr{Cvoid}), handle, attr, value) +end + +function PAPI_get_dev_attr(handle, id, attr, value) + ccall((:PAPI_get_dev_attr, libpapi), Cint, (Ptr{Cvoid}, Cint, PAPI_dev_attr_e, Ptr{Cvoid}), handle, id, attr, value) +end + +function PAPI_hl_region_begin(region) + ccall((:PAPI_hl_region_begin, libpapi), Cint, (Ptr{Cchar},), region) +end + +function PAPI_hl_read(region) + ccall((:PAPI_hl_read, libpapi), Cint, (Ptr{Cchar},), region) +end + +function PAPI_hl_region_end(region) + ccall((:PAPI_hl_region_end, libpapi), Cint, (Ptr{Cchar},), region) +end + +# no prototype is found for this function at papi.h:1241:8, please use with caution +function PAPI_hl_stop() + ccall((:PAPI_hl_stop, libpapi), Cint, ()) +end + +function PAPI_num_hwctrs() + ccall((:PAPI_num_hwctrs, libpapi), Cint, ()) +end + +const PAPI_VERSION = PAPI_VERSION_NUMBER(7, 0, 0, 0) + +const PAPI_VER_CURRENT = PAPI_VERSION & 0xffff0000 + +const PAPI_NATIVE_MASK = 0x40000000 + +const PAPI_PRESET_MASK = 0x80000000 + +const PAPI_UE_MASK = 0xc0000000 + +const PAPI_PRESET_AND_MASK = 0x7fffffff + +const PAPI_NATIVE_AND_MASK = 0xbfffffff + +const PAPI_UE_AND_MASK = 0x3fffffff + +const PAPI_MAX_PRESET_EVENTS = 128 + +const PAPI_MAX_USER_EVENTS = 50 + +const USER_EVENT_OPERATION_LEN = 512 + +const PAPI_L1_DCM = PAPI_L1_DCM_idx | PAPI_PRESET_MASK + +const PAPI_L1_ICM = PAPI_L1_ICM_idx | PAPI_PRESET_MASK + +const PAPI_L2_DCM = PAPI_L2_DCM_idx | PAPI_PRESET_MASK + +const PAPI_L2_ICM = PAPI_L2_ICM_idx | PAPI_PRESET_MASK + +const PAPI_L3_DCM = PAPI_L3_DCM_idx | PAPI_PRESET_MASK + +const PAPI_L3_ICM = PAPI_L3_ICM_idx | PAPI_PRESET_MASK + +const PAPI_L1_TCM = PAPI_L1_TCM_idx | PAPI_PRESET_MASK + +const PAPI_L2_TCM = PAPI_L2_TCM_idx | PAPI_PRESET_MASK + +const PAPI_L3_TCM = PAPI_L3_TCM_idx | PAPI_PRESET_MASK + +const PAPI_CA_SNP = PAPI_CA_SNP_idx | PAPI_PRESET_MASK + +const PAPI_CA_SHR = PAPI_CA_SHR_idx | PAPI_PRESET_MASK + +const PAPI_CA_CLN = PAPI_CA_CLN_idx | PAPI_PRESET_MASK + +const PAPI_CA_INV = PAPI_CA_INV_idx | PAPI_PRESET_MASK + +const PAPI_CA_ITV = PAPI_CA_ITV_idx | PAPI_PRESET_MASK + +const PAPI_L3_LDM = PAPI_L3_LDM_idx | PAPI_PRESET_MASK + +const PAPI_L3_STM = PAPI_L3_STM_idx | PAPI_PRESET_MASK + +const PAPI_BRU_IDL = PAPI_BRU_IDL_idx | PAPI_PRESET_MASK + +const PAPI_FXU_IDL = PAPI_FXU_IDL_idx | PAPI_PRESET_MASK + +const PAPI_FPU_IDL = PAPI_FPU_IDL_idx | PAPI_PRESET_MASK + +const PAPI_LSU_IDL = PAPI_LSU_IDL_idx | PAPI_PRESET_MASK + +const PAPI_TLB_DM = PAPI_TLB_DM_idx | PAPI_PRESET_MASK + +const PAPI_TLB_IM = PAPI_TLB_IM_idx | PAPI_PRESET_MASK + +const PAPI_TLB_TL = PAPI_TLB_TL_idx | PAPI_PRESET_MASK + +const PAPI_L1_LDM = PAPI_L1_LDM_idx | PAPI_PRESET_MASK + +const PAPI_L1_STM = PAPI_L1_STM_idx | PAPI_PRESET_MASK + +const PAPI_L2_LDM = PAPI_L2_LDM_idx | PAPI_PRESET_MASK + +const PAPI_L2_STM = PAPI_L2_STM_idx | PAPI_PRESET_MASK + +const PAPI_BTAC_M = PAPI_BTAC_M_idx | PAPI_PRESET_MASK + +const PAPI_PRF_DM = PAPI_PRF_DM_idx | PAPI_PRESET_MASK + +const PAPI_L3_DCH = PAPI_L3_DCH_idx | PAPI_PRESET_MASK + +const PAPI_TLB_SD = PAPI_TLB_SD_idx | PAPI_PRESET_MASK + +const PAPI_CSR_FAL = PAPI_CSR_FAL_idx | PAPI_PRESET_MASK + +const PAPI_CSR_SUC = PAPI_CSR_SUC_idx | PAPI_PRESET_MASK + +const PAPI_CSR_TOT = PAPI_CSR_TOT_idx | PAPI_PRESET_MASK + +const PAPI_MEM_SCY = PAPI_MEM_SCY_idx | PAPI_PRESET_MASK + +const PAPI_MEM_RCY = PAPI_MEM_RCY_idx | PAPI_PRESET_MASK + +const PAPI_MEM_WCY = PAPI_MEM_WCY_idx | PAPI_PRESET_MASK + +const PAPI_STL_ICY = PAPI_STL_ICY_idx | PAPI_PRESET_MASK + +const PAPI_FUL_ICY = PAPI_FUL_ICY_idx | PAPI_PRESET_MASK + +const PAPI_STL_CCY = PAPI_STL_CCY_idx | PAPI_PRESET_MASK + +const PAPI_FUL_CCY = PAPI_FUL_CCY_idx | PAPI_PRESET_MASK + +const PAPI_HW_INT = PAPI_HW_INT_idx | PAPI_PRESET_MASK + +const PAPI_BR_UCN = PAPI_BR_UCN_idx | PAPI_PRESET_MASK + +const PAPI_BR_CN = PAPI_BR_CN_idx | PAPI_PRESET_MASK + +const PAPI_BR_TKN = PAPI_BR_TKN_idx | PAPI_PRESET_MASK + +const PAPI_BR_NTK = PAPI_BR_NTK_idx | PAPI_PRESET_MASK + +const PAPI_BR_MSP = PAPI_BR_MSP_idx | PAPI_PRESET_MASK + +const PAPI_BR_PRC = PAPI_BR_PRC_idx | PAPI_PRESET_MASK + +const PAPI_FMA_INS = PAPI_FMA_INS_idx | PAPI_PRESET_MASK + +const PAPI_TOT_IIS = PAPI_TOT_IIS_idx | PAPI_PRESET_MASK + +const PAPI_TOT_INS = PAPI_TOT_INS_idx | PAPI_PRESET_MASK + +const PAPI_INT_INS = PAPI_INT_INS_idx | PAPI_PRESET_MASK + +const PAPI_FP_INS = PAPI_FP_INS_idx | PAPI_PRESET_MASK + +const PAPI_LD_INS = PAPI_LD_INS_idx | PAPI_PRESET_MASK + +const PAPI_SR_INS = PAPI_SR_INS_idx | PAPI_PRESET_MASK + +const PAPI_BR_INS = PAPI_BR_INS_idx | PAPI_PRESET_MASK + +const PAPI_VEC_INS = PAPI_VEC_INS_idx | PAPI_PRESET_MASK + +const PAPI_RES_STL = PAPI_RES_STL_idx | PAPI_PRESET_MASK + +const PAPI_FP_STAL = PAPI_FP_STAL_idx | PAPI_PRESET_MASK + +const PAPI_TOT_CYC = PAPI_TOT_CYC_idx | PAPI_PRESET_MASK + +const PAPI_LST_INS = PAPI_LST_INS_idx | PAPI_PRESET_MASK + +const PAPI_SYC_INS = PAPI_SYC_INS_idx | PAPI_PRESET_MASK + +const PAPI_L1_DCH = PAPI_L1_DCH_idx | PAPI_PRESET_MASK + +const PAPI_L2_DCH = PAPI_L2_DCH_idx | PAPI_PRESET_MASK + +const PAPI_L1_DCA = PAPI_L1_DCA_idx | PAPI_PRESET_MASK + +const PAPI_L2_DCA = PAPI_L2_DCA_idx | PAPI_PRESET_MASK + +const PAPI_L3_DCA = PAPI_L3_DCA_idx | PAPI_PRESET_MASK + +const PAPI_L1_DCR = PAPI_L1_DCR_idx | PAPI_PRESET_MASK + +const PAPI_L2_DCR = PAPI_L2_DCR_idx | PAPI_PRESET_MASK + +const PAPI_L3_DCR = PAPI_L3_DCR_idx | PAPI_PRESET_MASK + +const PAPI_L1_DCW = PAPI_L1_DCW_idx | PAPI_PRESET_MASK + +const PAPI_L2_DCW = PAPI_L2_DCW_idx | PAPI_PRESET_MASK + +const PAPI_L3_DCW = PAPI_L3_DCW_idx | PAPI_PRESET_MASK + +const PAPI_L1_ICH = PAPI_L1_ICH_idx | PAPI_PRESET_MASK + +const PAPI_L2_ICH = PAPI_L2_ICH_idx | PAPI_PRESET_MASK + +const PAPI_L3_ICH = PAPI_L3_ICH_idx | PAPI_PRESET_MASK + +const PAPI_L1_ICA = PAPI_L1_ICA_idx | PAPI_PRESET_MASK + +const PAPI_L2_ICA = PAPI_L2_ICA_idx | PAPI_PRESET_MASK + +const PAPI_L3_ICA = PAPI_L3_ICA_idx | PAPI_PRESET_MASK + +const PAPI_L1_ICR = PAPI_L1_ICR_idx | PAPI_PRESET_MASK + +const PAPI_L2_ICR = PAPI_L2_ICR_idx | PAPI_PRESET_MASK + +const PAPI_L3_ICR = PAPI_L3_ICR_idx | PAPI_PRESET_MASK + +const PAPI_L1_ICW = PAPI_L1_ICW_idx | PAPI_PRESET_MASK + +const PAPI_L2_ICW = PAPI_L2_ICW_idx | PAPI_PRESET_MASK + +const PAPI_L3_ICW = PAPI_L3_ICW_idx | PAPI_PRESET_MASK + +const PAPI_L1_TCH = PAPI_L1_TCH_idx | PAPI_PRESET_MASK + +const PAPI_L2_TCH = PAPI_L2_TCH_idx | PAPI_PRESET_MASK + +const PAPI_L3_TCH = PAPI_L3_TCH_idx | PAPI_PRESET_MASK + +const PAPI_L1_TCA = PAPI_L1_TCA_idx | PAPI_PRESET_MASK + +const PAPI_L2_TCA = PAPI_L2_TCA_idx | PAPI_PRESET_MASK + +const PAPI_L3_TCA = PAPI_L3_TCA_idx | PAPI_PRESET_MASK + +const PAPI_L1_TCR = PAPI_L1_TCR_idx | PAPI_PRESET_MASK + +const PAPI_L2_TCR = PAPI_L2_TCR_idx | PAPI_PRESET_MASK + +const PAPI_L3_TCR = PAPI_L3_TCR_idx | PAPI_PRESET_MASK + +const PAPI_L1_TCW = PAPI_L1_TCW_idx | PAPI_PRESET_MASK + +const PAPI_L2_TCW = PAPI_L2_TCW_idx | PAPI_PRESET_MASK + +const PAPI_L3_TCW = PAPI_L3_TCW_idx | PAPI_PRESET_MASK + +const PAPI_FML_INS = PAPI_FML_INS_idx | PAPI_PRESET_MASK + +const PAPI_FAD_INS = PAPI_FAD_INS_idx | PAPI_PRESET_MASK + +const PAPI_FDV_INS = PAPI_FDV_INS_idx | PAPI_PRESET_MASK + +const PAPI_FSQ_INS = PAPI_FSQ_INS_idx | PAPI_PRESET_MASK + +const PAPI_FNV_INS = PAPI_FNV_INS_idx | PAPI_PRESET_MASK + +const PAPI_FP_OPS = PAPI_FP_OPS_idx | PAPI_PRESET_MASK + +const PAPI_SP_OPS = PAPI_SP_OPS_idx | PAPI_PRESET_MASK + +const PAPI_DP_OPS = PAPI_DP_OPS_idx | PAPI_PRESET_MASK + +const PAPI_VEC_SP = PAPI_VEC_SP_idx | PAPI_PRESET_MASK + +const PAPI_VEC_DP = PAPI_VEC_DP_idx | PAPI_PRESET_MASK + +const PAPI_REF_CYC = PAPI_REF_CYC_idx | PAPI_PRESET_MASK + +const PAPI_END = PAPI_END_idx | PAPI_PRESET_MASK + +const PAPI_OK = 0 + +const PAPI_EINVAL = -1 + +const PAPI_ENOMEM = -2 + +const PAPI_ESYS = -3 + +const PAPI_ECMP = -4 + +const PAPI_ESBSTR = -4 + +const PAPI_ECLOST = -5 + +const PAPI_EBUG = -6 + +const PAPI_ENOEVNT = -7 + +const PAPI_ECNFLCT = -8 + +const PAPI_ENOTRUN = -9 + +const PAPI_EISRUN = -10 + +const PAPI_ENOEVST = -11 + +const PAPI_ENOTPRESET = -12 + +const PAPI_ENOCNTR = -13 + +const PAPI_EMISC = -14 + +const PAPI_EPERM = -15 + +const PAPI_ENOINIT = -16 + +const PAPI_ENOCMP = -17 + +const PAPI_ENOSUPP = -18 + +const PAPI_ENOIMPL = -19 + +const PAPI_EBUF = -20 + +const PAPI_EINVAL_DOM = -21 + +const PAPI_EATTR = -22 + +const PAPI_ECOUNT = -23 + +const PAPI_ECOMBO = -24 + +const PAPI_ECMP_DISABLED = -25 + +const PAPI_EDELAY_INIT = -26 + +const PAPI_EMULPASS = -27 + +const PAPI_NUM_ERRORS = 28 + +const PAPI_NOT_INITED = 0 + +const PAPI_LOW_LEVEL_INITED = 1 + +const PAPI_HIGH_LEVEL_INITED = 2 + +const PAPI_THREAD_LEVEL_INITED = 4 + +const PAPI_NULL = -1 + +const PAPI_DOM_USER = 0x01 + +const PAPI_DOM_MIN = PAPI_DOM_USER + +const PAPI_DOM_KERNEL = 0x02 + +const PAPI_DOM_OTHER = 0x04 + +const PAPI_DOM_SUPERVISOR = 0x08 + +const PAPI_DOM_ALL = ((PAPI_DOM_USER | PAPI_DOM_KERNEL) | PAPI_DOM_OTHER) | PAPI_DOM_SUPERVISOR + +const PAPI_DOM_MAX = PAPI_DOM_ALL + +const PAPI_DOM_HWSPEC = 0x80000000 + +const PAPI_USR1_TLS = 0x00 + +const PAPI_USR2_TLS = 0x01 + +const PAPI_TLS_HIGH_LEVEL = 0x02 + +const PAPI_NUM_TLS = 0x03 + +const PAPI_TLS_USR1 = PAPI_USR1_TLS + +const PAPI_TLS_USR2 = PAPI_USR2_TLS + +const PAPI_TLS_NUM = PAPI_NUM_TLS + +const PAPI_TLS_ALL_THREADS = 0x10 + +const PAPI_USR1_LOCK = 0x00 + +const PAPI_USR2_LOCK = 0x01 + +const PAPI_NUM_LOCK = 0x02 + +const PAPI_LOCK_USR1 = PAPI_USR1_LOCK + +const PAPI_LOCK_USR2 = PAPI_USR2_LOCK + +const PAPI_LOCK_NUM = PAPI_NUM_LOCK + +const PAPI_VENDOR_UNKNOWN = 0 + +const PAPI_VENDOR_INTEL = 1 + +const PAPI_VENDOR_AMD = 2 + +const PAPI_VENDOR_IBM = 3 + +const PAPI_VENDOR_CRAY = 4 + +const PAPI_VENDOR_SUN = 5 + +const PAPI_VENDOR_FREESCALE = 6 + +const PAPI_VENDOR_ARM = 7 + +const PAPI_VENDOR_MIPS = 8 + +const PAPI_VENDOR_ARM_ARM = 0x41 + +const PAPI_VENDOR_ARM_BROADCOM = 0x42 + +const PAPI_VENDOR_ARM_CAVIUM = 0x43 + +const PAPI_VENDOR_ARM_FUJITSU = 0x46 + +const PAPI_VENDOR_ARM_HISILICON = 0x48 + +const PAPI_VENDOR_ARM_APM = 0x50 + +const PAPI_VENDOR_ARM_QUALCOMM = 0x51 + +const PAPI_GRN_THR = 0x01 + +const PAPI_GRN_MIN = PAPI_GRN_THR + +const PAPI_GRN_PROC = 0x02 + +const PAPI_GRN_PROCG = 0x04 + +const PAPI_GRN_SYS = 0x08 + +const PAPI_GRN_SYS_CPU = 0x10 + +const PAPI_GRN_MAX = PAPI_GRN_SYS_CPU + +const PAPI_STOPPED = 0x01 + +const PAPI_RUNNING = 0x02 + +const PAPI_PAUSED = 0x04 + +const PAPI_NOT_INIT = 0x08 + +const PAPI_OVERFLOWING = 0x10 + +const PAPI_PROFILING = 0x20 + +const PAPI_MULTIPLEXING = 0x40 + +const PAPI_ATTACHED = 0x80 + +const PAPI_CPU_ATTACHED = 0x0100 + +const PAPI_QUIET = 0 + +const PAPI_VERB_ECONT = 1 + +const PAPI_VERB_ESTOP = 2 + +const PAPI_PROFIL_POSIX = 0x00 + +const PAPI_PROFIL_RANDOM = 0x01 + +const PAPI_PROFIL_WEIGHTED = 0x02 + +const PAPI_PROFIL_COMPRESS = 0x04 + +const PAPI_PROFIL_BUCKET_16 = 0x08 + +const PAPI_PROFIL_BUCKET_32 = 0x10 + +const PAPI_PROFIL_BUCKET_64 = 0x20 + +const PAPI_PROFIL_FORCE_SW = 0x40 + +const PAPI_PROFIL_DATA_EAR = 0x80 + +const PAPI_PROFIL_INST_EAR = 0x0100 + +const PAPI_PROFIL_BUCKETS = (PAPI_PROFIL_BUCKET_16 | PAPI_PROFIL_BUCKET_32) | PAPI_PROFIL_BUCKET_64 + +const PAPI_OVERFLOW_FORCE_SW = 0x40 + +const PAPI_OVERFLOW_HARDWARE = 0x80 + +const PAPI_MULTIPLEX_DEFAULT = 0x00 + +const PAPI_MULTIPLEX_FORCE_SW = 0x01 + +const PAPI_INHERIT_ALL = 1 + +const PAPI_INHERIT_NONE = 0 + +const PAPI_DETACH = 1 + +const PAPI_DEBUG = 2 + +const PAPI_MULTIPLEX = 3 + +const PAPI_DEFDOM = 4 + +const PAPI_DOMAIN = 5 + +const PAPI_DEFGRN = 6 + +const PAPI_GRANUL = 7 + +const PAPI_DEF_MPX_NS = 8 + +const PAPI_MAX_MPX_CTRS = 11 + +const PAPI_PROFIL = 12 + +const PAPI_PRELOAD = 13 + +const PAPI_CLOCKRATE = 14 + +const PAPI_MAX_HWCTRS = 15 + +const PAPI_HWINFO = 16 + +const PAPI_EXEINFO = 17 + +const PAPI_MAX_CPUS = 18 + +const PAPI_ATTACH = 19 + +const PAPI_SHLIBINFO = 20 + +const PAPI_LIB_VERSION = 21 + +const PAPI_COMPONENTINFO = 22 + +const PAPI_DATA_ADDRESS = 23 + +const PAPI_INSTR_ADDRESS = 24 + +const PAPI_DEF_ITIMER = 25 + +const PAPI_DEF_ITIMER_NS = 26 + +const PAPI_CPU_ATTACH = 27 + +const PAPI_INHERIT = 28 + +const PAPI_USER_EVENTS_FILE = 29 + +const PAPI_INIT_SLOTS = 64 + +const PAPI_MIN_STR_LEN = 64 + +const PAPI_MAX_STR_LEN = 128 + +const PAPI_2MAX_STR_LEN = 256 + +const PAPI_HUGE_STR_LEN = 1024 + +const PAPI_PMU_MAX = 80 + +const PAPI_DERIVED = 0x01 + +const PAPI_ENUM_ALL = PAPI_ENUM_EVENTS + +const PAPI_PRESET_BIT_MSC = 1 << PAPI_PRESET_ENUM_MSC + +const PAPI_PRESET_BIT_INS = 1 << PAPI_PRESET_ENUM_INS + +const PAPI_PRESET_BIT_IDL = 1 << PAPI_PRESET_ENUM_IDL + +const PAPI_PRESET_BIT_BR = 1 << PAPI_PRESET_ENUM_BR + +const PAPI_PRESET_BIT_CND = 1 << PAPI_PRESET_ENUM_CND + +const PAPI_PRESET_BIT_MEM = 1 << PAPI_PRESET_ENUM_MEM + +const PAPI_PRESET_BIT_CACH = 1 << PAPI_PRESET_ENUM_CACH + +const PAPI_PRESET_BIT_L1 = 1 << PAPI_PRESET_ENUM_L1 + +const PAPI_PRESET_BIT_L2 = 1 << PAPI_PRESET_ENUM_L2 + +const PAPI_PRESET_BIT_L3 = 1 << PAPI_PRESET_ENUM_L3 + +const PAPI_PRESET_BIT_TLB = 1 << PAPI_PRESET_ENUM_TLB + +const PAPI_PRESET_BIT_FP = 1 << PAPI_PRESET_ENUM_FP + +const PAPI_NTV_GROUP_AND_MASK = 0x00ff0000 + +const PAPI_NTV_GROUP_SHIFT = 16 + +const long_long = Clonglong + +const u_long_long = Culonglong + +const PAPI_MH_TYPE_EMPTY = 0x00 + +const PAPI_MH_TYPE_INST = 0x01 + +const PAPI_MH_TYPE_DATA = 0x02 + +const PAPI_MH_TYPE_VECTOR = 0x04 + +const PAPI_MH_TYPE_TRACE = 0x08 + +const PAPI_MH_TYPE_UNIFIED = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_DATA + +const PAPI_MH_TYPE_WT = 0x00 + +const PAPI_MH_TYPE_WB = 0x10 + +const PAPI_MH_TYPE_UNKNOWN = 0x0000 + +const PAPI_MH_TYPE_LRU = 0x0100 + +const PAPI_MH_TYPE_PSEUDO_LRU = 0x0200 + +const PAPI_MH_TYPE_FIFO = 0x0400 + +const PAPI_MH_TYPE_TLB = 0x1000 + +const PAPI_MH_TYPE_PREF = 0x2000 + +const PAPI_MH_TYPE_RD_ALLOC = 0x00010000 + +const PAPI_MH_TYPE_WR_ALLOC = 0x00020000 + +const PAPI_MH_TYPE_RW_ALLOC = 0x00040000 + +const PAPI_MH_MAX_LEVELS = 6 + +const PAPI_MAX_MEM_HIERARCHY_LEVELS = 4 + +const PAPIF_DMEM_VMPEAK = 1 + +const PAPIF_DMEM_VMSIZE = 2 + +const PAPIF_DMEM_RESIDENT = 3 + +const PAPIF_DMEM_HIGH_WATER = 4 + +const PAPIF_DMEM_SHARED = 5 + +const PAPIF_DMEM_TEXT = 6 + +const PAPIF_DMEM_LIBRARY = 7 + +const PAPIF_DMEM_HEAP = 8 + +const PAPIF_DMEM_LOCKED = 9 + +const PAPIF_DMEM_STACK = 10 + +const PAPIF_DMEM_PAGESIZE = 11 + +const PAPIF_DMEM_PTE = 12 + +const PAPIF_DMEM_MAXVAL = 12 + +const PAPI_MAX_INFO_TERMS = 12 + +end # module diff --git a/src/PAPI.jl b/src/PAPI.jl index d31a903..1df494a 100644 --- a/src/PAPI.jl +++ b/src/PAPI.jl @@ -6,9 +6,24 @@ using Preferences if !PAPI_jll.is_available() const libpapi = load_preference(PAPI_jll, "libPAPI_path", nothing) - is_available() = libpapi !== nothing +end + +function lib_version() + PAPI_LIB_VERSION = Cint(21) + return ccall((:PAPI_get_opt, libpapi), Cint, (Cint, Ptr{Cvoid}), PAPI_LIB_VERSION, C_NULL) +end + +if libpapi !== nothing + major = lib_version() >> 24 + api_file = joinpath(@__DIR__, "API", string(major), "libPAPI.jl") + if !isfile(api_file) + @warn "File an issue to regenerate headers for PAPI version" major + else + include(api_file) + is_available() = true + end else - is_available() = PAPI_jll.is_available() + is_available() = false end """ @@ -77,15 +92,11 @@ include("prettyprint.jl") include("serialization.jl") include("numa.jl") -if is_available() - const papi_current_version = get_option(PAPI_LIB_VERSION, C_NULL) -end - function __init__() if is_available() # init the library and make sure that some counters are available - rv = ccall((:PAPI_library_init, libpapi), Cint, (Cint,), papi_current_version) - if rv != papi_current_version + rv = API.PAPI_library_init(API.PAPI_VER_CURRENT) + if rv != API.PAPI_VER_CURRENT if rv > 0 error("PAPI library version mismatch!") else From 1cfddf0b1de4ebb15dc4e59bcab3a2deee967ace Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sun, 19 Mar 2023 15:45:31 -0400 Subject: [PATCH 4/6] support local better --- src/API/7/libPAPI.jl | 4 +--- src/PAPI.jl | 21 ++++++++++++++------- src/components.jl | 43 ++++++++++++++++++++++++++++++++++++------- src/eventsets.jl | 3 ++- 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/API/7/libPAPI.jl b/src/API/7/libPAPI.jl index 5c8f425..4c6227d 100644 --- a/src/API/7/libPAPI.jl +++ b/src/API/7/libPAPI.jl @@ -1,8 +1,6 @@ module API -using PAPI_jll -export PAPI_jll - +import ..PAPI: libpapi PAPI_VERSION_NUMBER(maj,min,rev,inc) = (((maj)<<24) | ((min)<<16) | ((rev)<<8) | (inc)) diff --git a/src/PAPI.jl b/src/PAPI.jl index 1df494a..0c32ead 100644 --- a/src/PAPI.jl +++ b/src/PAPI.jl @@ -1,11 +1,19 @@ module PAPI using NUMA_jll -using PAPI_jll +import PAPI_jll using Preferences -if !PAPI_jll.is_available() - const libpapi = load_preference(PAPI_jll, "libPAPI_path", nothing) +const libPAPI_preference = @load_preference("libPAPI_path", nothing) + +if libPAPI_preference === nothing + if PAPI_jll.is_available() + const libpapi = PAPI_jll.libPAPI_path + else + const libpapi = nothing + end +else + const libpapi = libPAPI_preference end function lib_version() @@ -55,10 +63,9 @@ function set_library!(path) if !ispath(path) error("PAPI library path $path not found") end - set_preferences!( - PAPI_jll, - "libPAPI_path" => realpath(path); - force=true, + @set_preferences!( + "libPAPI_path" => realpath(path), + force=true ) @warn "PAPI library path changed, you will need to restart Julia for the change to take effect" path diff --git a/src/components.jl b/src/components.jl index ef0b173..672d65b 100644 --- a/src/components.jl +++ b/src/components.jl @@ -2,24 +2,30 @@ struct Component cid::Cint end +# No GC safety needed +Base.cconvert(::Type{Cint}, c::Component) = c.cid + import Base: iterate, IteratorSize, SizeUnknown, eltype IteratorSize(::Type{Component}) = SizeUnknown() eltype(::Type{Component}) = Native function iterate(comp::Component) - id = Ref{Cuint}(PAPI_NATIVE_MASK) - ret = ccall((:PAPI_enum_cmp_event, libpapi), Cint, (Ptr{Cuint}, Cint, Cint), id, PAPI_ENUM_FIRST, comp.cid) + r_id = Ref{Cint}(Cint(0)| API.PAPI_NATIVE_MASK) + ret = API.PAPI_enum_cmp_event(r_id, API.PAPI_ENUM_FIRST, comp) if ret == PAPI_OK - (Native(id[]), id) + id = r_id[] + (Native(id), id) else nothing end end -function iterate(comp::Component, id::Ref{Cuint}) - ret = ccall((:PAPI_enum_cmp_event, libpapi), Cint, (Ptr{Cuint}, Cint, Cint), id, PAPI_ENUM_EVENTS, comp.cid) +function iterate(comp::Component, id::Cint) + r_id = Ref(id) + ret = API.PAPI_enum_cmp_event(r_id, API.PAPI_ENUM_EVENTS, comp) if ret == PAPI_OK - (Native(id[]), id) + id = r_id[] + (Native(id), id) else nothing end @@ -46,7 +52,7 @@ end function list_components() numcmp = ccall((:PAPI_num_components, libpapi), Cint, ()) - map(0:numcmp-1) do cid + map(0:(numcmp-1)) do cid info = ccall((:PAPI_get_component_info, libpapi), Ptr{UInt8}, (Cint,), cid) if info == C_NULL throw(PAPIError("PAPI_get_component_info returned NULL")) @@ -91,3 +97,26 @@ function available_native() events end + +function EventSet(c::Component) + ev_set = EventSet() + API.PAPI_assign_eventset_component(ev_set, c) + return ev_set +end + +function info(c::Component) + info = API.PAPI_get_component_info(c) + name = Base.unsafe_string(Base.unsafe_convert(Ptr{Cchar}, info.name)) + + initialized = Base.unsafe_load(info.initialized) + disabled = Base.unsafe_load(info.disabled) + + if disabled == 0 + disabled = false + disabled_reason = nothing + else + disabled = PAPIError(disabled) + disabled_reason = Base.unsafe_string(Base.unsafe_convert(Ptr{Cchar}, info.disabled_reason)) + end + return (;name, initialized, disabled, disabled_reason) +end \ No newline at end of file diff --git a/src/eventsets.jl b/src/eventsets.jl index b91788f..fa0804f 100644 --- a/src/eventsets.jl +++ b/src/eventsets.jl @@ -22,7 +22,8 @@ mutable struct EventSet end # allows us to pass EventSet objects directly into ccall signatures -function Base.cconvert(::Type{Cint}, evtset::EventSet) +Base.cconvert(::Type{Cint}, evtset::EventSet) = evtset +function Base.unsafe_convert(::Type{Cint}, evtset::EventSet) evtset.val end From bc8d643679219beb5fe2bd69b8f3948592606d08 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 20 Mar 2023 10:08:23 -0400 Subject: [PATCH 5/6] Add CUDA example --- examples/cuda.jl | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 examples/cuda.jl diff --git a/examples/cuda.jl b/examples/cuda.jl new file mode 100644 index 0000000..d3386c7 --- /dev/null +++ b/examples/cuda.jl @@ -0,0 +1,106 @@ +using CUDA +import Libdl + +CUDA.versioninfo() +# Libdl.dlopen(CUDA.CUDA_Driver_jll.libcuda, Libdl.RTLD_NOW | Libdl.RTLD_GLOBAL) +# Libdl.dlopen(CUDA.CUDA_Runtime_jll.libcudart, Libdl.RTLD_NOW | Libdl.RTLD_GLOBAL) +# Libdl.dlopen(CUDA.CUDA_Runtime_jll.libcupti, Libdl.RTLD_NOW | Libdl.RTLD_GLOBAL) + +using PAPI +using Unitful + +# module CycleUnits +# using Unitful +# @unit nat "nat" Nat 1 false +# @unit bit "bit" Bit log(2)*u"nat" false +# @unit B "B" Byte 8bit false +# Unitful.register(@__MODULE__) +# end + +# https://crd.lbl.gov/assets/Uploads/ECP22-Roofline-2-NVIDIA-and-NERSC.pdf +# https://www.exascaleproject.org/wp-content/uploads/2021/01/PAPI_BOF_Presentation-pdf.pdf + +# - DRAM: `cuda:::dram__bytes.sum` +# - L2: `cuda:::lts__t_bytes.sum` +# - L1: `cuda:::l1tex__t_bytes.sum` + +# - Double precision: +# - `cuda:::sm__sass_thread_inst_executed_op_dadd_pred_on.sum` +# - `cuda:::sm__sass_thread_inst_executed_op_dmul_pred_on.sum` +# - `cuda:::sm__sass_thread_inst_executed_op_dfma_pred_on.sum` + +function time_events!(ev_set, dev) + @assert PAPI.try_add_event(ev_set, PAPI.name_to_event("cuda:::sm__cycles_elapsed.avg:device=$dev")) + @assert PAPI.try_add_event(ev_set, PAPI.name_to_event("cuda:::sm__cycles_elapsed.avg.per_second:device=$dev")) +end + +function memory_events!(ev_set, dev) + @assert PAPI.try_add_event(ev_set, PAPI.name_to_event("cuda:::dram__bytes.sum.per_second:device=$dev")) + @assert PAPI.try_add_event(ev_set, PAPI.name_to_event("cuda:::lts__t_bytes.sum.per_second:device=$dev")) # L2 + @assert PAPI.try_add_event(ev_set, PAPI.name_to_event("cuda:::l1tex__t_bytes.sum.per_second:device=$dev")) +end + +function float_events!(ev_set, dev, ::Type{T}) where T<:AbstractFloat + prefix = if T == Float64 + 'd' + elseif T == Float32 + 'f' + elseif T == Float16 + 'h' + else + error("Unknown $T") + end + @assert PAPI.try_add_event(ev_set, + PAPI.name_to_event("cuda:::sm__sass_thread_inst_executed_op_$(prefix)add_pred_on.sum:device=$dev")) + @assert PAPI.try_add_event(ev_set, + PAPI.name_to_event("cuda:::sm__sass_thread_inst_executed_op_$(prefix)mul_pred_on.sum:device=$dev")) + @assert PAPI.try_add_event(ev_set, + PAPI.name_to_event("cuda:::sm__sass_thread_inst_executed_op_$(prefix)fma_pred_on.sum:device=$dev")) +end + +function measure(f, ::Type{T}) where T + pcuda = PAPI.find_component("cuda") + ev_set_mem = PAPI.EventSet(pcuda) + ev_set_flops = PAPI.EventSet(pcuda) + + dev = CUDA.device().handle + memory_events!(ev_set_mem, dev) + time_events!(ev_set_mem, dev) + + float_events!(ev_set_flops, dev, T) + + PAPI.start_counters(ev_set_mem) + CUDA.@sync f() + counters = PAPI.stop_counters(ev_set_mem) + + # dram, l2, l1 in bytes.per_second + dram, l2, l1, cycles, cycles_per_second = counters + time = cycles/cycles_per_second + + PAPI.start_counters(ev_set_flops) + CUDA.@sync f() + + counters = PAPI.stop_counters(ev_set_flops) + add, mul, fma = counters + + flop = add + mul + 2fma + flops = flop/time + + (;dram, l2, l1, cycles, cycles_per_second, time, add, mul, fma, flop, flops) +end + +function square_kernel!(A, B) + idx = threadIdx().x + @inbounds b = B[idx] + @inbounds A[idx] = b^2 + nothing +end + +A = CUDA.zeros(1024) +B = CUDA.zeros(1024) + +results = measure(eltype(A)) do + @cuda threads=1024 square_kernel!(A, B) +end + +@show results From a46cd2e1f6540b75e7e39fcdb380f7d812b8763a Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 21 Mar 2023 12:36:15 -0400 Subject: [PATCH 6/6] Make CUDA flop counting work with JLL --- src/PAPI.jl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/PAPI.jl b/src/PAPI.jl index 0c32ead..8e26167 100644 --- a/src/PAPI.jl +++ b/src/PAPI.jl @@ -8,7 +8,7 @@ const libPAPI_preference = @load_preference("libPAPI_path", nothing) if libPAPI_preference === nothing if PAPI_jll.is_available() - const libpapi = PAPI_jll.libPAPI_path + const libpapi = PAPI_jll.libpapi_path else const libpapi = nothing end @@ -100,6 +100,18 @@ include("serialization.jl") include("numa.jl") function __init__() + if PAPI_jll.is_available() + cuda = PAPI_jll.host_platform["cuda"] + if cuda !== "local" && cuda !== "none" + CUDA_Runtime = PAPI_jll.CUDA_Runtime_jll + CUDA_Driver = CUDA_Runtime.CUDA_Driver_jll + ENV["PAPI_CUDA_MAIN"] = CUDA_Driver.libcuda + ENV["PAPI_CUDA_RUNTIME"] = CUDA_Runtime.libcudart + ENV["PAPI_CUDA_CUPTI"] = CUDA_Runtime.libcupti + ENV["PAPI_CUDA_PERFWORKS"] = CUDA_Runtime.libnvperf_host + end + end + if is_available() # init the library and make sure that some counters are available rv = API.PAPI_library_init(API.PAPI_VER_CURRENT)