text:
import SpecialFunctions: logfactorial
import Gen.ReverseDiff: TrackedReal

disttype(d::Distributions.Distribution) =
    disttype(typeof(d))
disttype(D::Type{<:Distributions.Distribution}) =
    Base.typename(D).wrapper
disttype(D::Type{<:Distributions.Categorical}) =
    Distributions.Categorical

safe_eltype(d::Distributions.Distribution) = untracked_type(eltype(d))
safe_eltype(d::ContinuousDistribution) = float(untracked_type(eltype(d)))

untracked_type(T::Type) = T
untracked_type(T::Type{<:TrackedReal{V}}) where {V} = V

"Wraps Distributions.jl distributions as Gen.jl distributions."
struct WrappedDistribution{T,D <: Distributions.Distribution} <: Gen.Distribution{T}
    dist::D
end
WrappedDistribution(d::D) where {D <: UnivariateDistribution} =
    WrappedDistribution{safe_eltype(d),D}(d)
WrappedDistribution(d::D) where {D <: MultivariateDistribution} =
    WrappedDistribution{Vector{safe_eltype(d)},D}(d)
WrappedDistribution(d::D) where {D <: MatrixDistribution} =
    WrappedDistribution{Matrix{safe_eltype(d)},D}(d)
WrappedDistribution(d::Truncated{D}) where {D} =
    WrappedDistribution{safe_eltype(d),typeof(d)}(d)

(d::WrappedDistribution)(args...) = Gen.random(d, args...)

@inline Gen.random(d::WrappedDistribution{T,D}, args...) where {T,D} =
    rand(d.dist)
@inline Gen.logpdf(d::WrappedDistribution{T,D}, x, args...) where {T,D} =
    Distributions.logpdf(disttype(d.dist)(args...), x)
@inline Gen.logpdf_grad(d::WrappedDistribution{T,D}, x, args...) where {T,D} =
    Zygote.gradient((x, args...) -> Distributions.logpdf(disttype(d.dist)(args...), x), T(x), args...)
Gen.has_output_grad(d::WrappedDistribution{T,D}) where {T,D} =
    !Gen.is_discrete(d)
Gen.has_argument_grads(d::WrappedDistribution{T,D}) where {T,D} =
    tuple((!(partype(d.dist) <: Integer) for p in params(d.dist))...)

Gen.is_discrete(::WrappedDistribution) = false
Gen.is_discrete(::WrappedDistribution{T,D}) where {T,D <: DiscreteDistribution} = true

"Repeats a distribution across an array of arbitrary dimensions."
struct ArrayedDistribution{T} <: Gen.Distribution{T}
    dist::Gen.Distribution
    dims::Dims
end
ArrayedDistribution(D::Type{<:Gen.Distribution{T}}, dims::Dims) where {T} =
    ArrayedDistribution{Array{T,length(dims)}}(D(), dims)
ArrayedDistribution(D::Type{<:Gen.Distribution{T}}, dims...) where {T} =
    ArrayedDistribution{Array{T,length(dims)}}(D(), dims)
ArrayedDistribution(d::Gen.Distribution{T}, dims::Dims) where {T} =
    ArrayedDistribution{Array{T,length(dims)}}(d, dims)
ArrayedDistribution(d::Gen.Distribution{T}, dims...) where {T} =
    ArrayedDistribution{Array{T,length(dims)}}(d, dims)

(d::ArrayedDistribution)(args...) = Gen.random(d, args...)

@inline Gen.random(d::ArrayedDistribution{T}, args...) where {T} =
    broadcast(x -> Gen.random(d.dist, args...), zeros(d.dims...))
@inline Gen.logpdf(d::ArrayedDistribution{T}, x::AbstractArray, args...) where {T} =
    size(x) != d.dims ? error("size should be $(d.dims)") :
    sum(broadcast(y -> Gen.logpdf(d.dist, y, args...), x))

function Gen.logpdf_grad(d::ArrayedDistribution{T}, x::AbstractArray, args...) where {T}
    if size(x) != d.dims error("size should be $(d.dims)") end
    grads = broadcast(y -> Gen.logpdf_grad(d.dist, y, args...), x)
    out_grad = Gen.has_output_grad(d) ? first.(grads) : nothing
    arg_grads = (has_grad ? getindex.(grads, i+1) : nothing
                 for (i, has_grad) in enumerate(Gen.has_argument_grads(d.dist)))
    return (out_grad, arg_grads...)
end

Gen.has_output_grad(d::ArrayedDistribution{T}) where {T} =
    Gen.has_output_grad(d.dist)
Gen.has_argument_grads(d::ArrayedDistribution{T}) where {T} =
    Gen.has_argument_grads(d.dist)

"Typed scalar distribution, equivalent to `rand(T)` for type `T`."
struct TypedScalarDistribution{T<:Real} <: Gen.Distribution{T} end
TypedScalarDistribution(T::Type) = TypedScalarDistribution{T}()

(d::TypedScalarDistribution)() = Gen.random(d)

@inline Gen.random(::TypedScalarDistribution{T}) where {T} =
    rand(T)

# Integers are sampled uniformly from [typemin(T), typemax(T)]
@inline Gen.logpdf(d::TypedScalarDistribution{T}, x::Integer) where {T <: Integer} =
    typemin(T) <= x <= typemax(T) ? (-sizeof(T) * 8 * log(2)) : -Inf
# Floats are sampled uniformly from (0, 1)
@inline Gen.logpdf(d::TypedScalarDistribution{T}, x::Real) where {T <: AbstractFloat} =
    0 <= x <= 1 ? 0.0 : -Inf

@inline Gen.logpdf_grad(::TypedScalarDistribution{T}, x::Integer) where {T <: Integer} =
    (nothing,)
@inline Gen.logpdf_grad(::TypedScalarDistribution{T}, x::Real) where {T <: AbstractFloat} =
    0.0

Gen.has_output_grad(::TypedScalarDistribution{T}) where {T <: Integer} =
    false
Gen.has_output_grad(::TypedScalarDistribution{T}) where {T <: AbstractFloat} =
    true

Gen.has_argument_grads(::TypedScalarDistribution) =
    ()

"Typed array distribution, equivalent to `rand(T, dims...)` for type `T`."
struct TypedArrayDistribution{T<:Real,N} <: Gen.Distribution{Array{T,N}}
    dims::Dims{N}
end
TypedArrayDistribution(T::Type, dims::Dims{N}) where {N} =
    TypedArrayDistribution{T,N}(dims)
TypedArrayDistribution(T::Type, dims...) =
    TypedArrayDistribution{T,length(dims)}(dims)

(d::TypedArrayDistribution)() = Gen.random(d)

@inline Gen.random(d::TypedArrayDistribution{T}) where {T} =
    rand(T, d.dims...)

# Integers are sampled uniformly from [typemin(T), typemax(T)]
@inline Gen.logpdf(d::TypedArrayDistribution{T}, x::AbstractArray{<:Integer}) where {T <: Integer} =
    size(x) != d.dims ? error("size should be $(d.dims)") :
    all(typemin(T) .<= x .<= typemax(T)) ? -sizeof(T)*8*log(2)*prod(d.dims) : -Inf
# Floats are sampled uniformly from (0, 1)
@inline Gen.logpdf(d::TypedArrayDistribution{T}, x::AbstractArray{<:Real}) where {T <: AbstractFloat} =
    size(x) != d.dims ? error("size should be $(d.dims)") :
    all(0 .<= x .<= 1) ? 0.0 : -Inf

@inline Gen.logpdf_grad(d::TypedArrayDistribution{T}, x::AbstractArray{<:Integer}) where {T <: Integer} =
    size(x) != d.dims ? error("size should be $(d.dims)") : (nothing,)
@inline Gen.logpdf_grad(d::TypedArrayDistribution{T}, x::AbstractArray{<:Real}) where {T <: AbstractFloat} =
    size(x) != d.dims ? error("size should be $(d.dims)") : (zeros(d.dims),)

Gen.has_output_grad(::TypedArrayDistribution{T}) where {T <: Integer} =
    false
Gen.has_output_grad(::TypedArrayDistribution{T}) where {T <: AbstractFloat} =
    true

Gen.has_argument_grads(::TypedArrayDistribution) =
    ()

"Labeled uniform distribution over indexable collections."
struct LabeledUniform{T} <: Gen.Distribution{T} end
LabeledUniform() = LabeledUniform{Any}()

(d::LabeledUniform)(args...) = Gen.random(d, args...)

@inline Gen.random(::LabeledUniform{T}, labels::AbstractArray{T}) where {T} =
    sample(labels)
@inline Gen.random(::LabeledUniform{T}, labels::Tuple{Vararg{T}}) where {T} =
    rand(labels)
@inline Gen.random(::LabeledUniform{T}, labels::AbstractString) where {T <: AbstractChar} =
    rand(labels)
@inline Gen.logpdf(::LabeledUniform{T}, x::T, labels::Indexable) where {T} =
    log(sum(x == l for l in labels) / length(labels))

Gen.logpdf_grad(::LabeledUniform, x, labels) =
    (nothing, nothing)
Gen.has_output_grad(::LabeledUniform) =
    false
Gen.has_argument_grads(::LabeledUniform) =
    (false,)

"Labeled uniform distribution over set-like collections."
struct SetUniform{T} <: Gen.Distribution{T} end
SetUniform() = SetUniform{Any}()

(d::SetUniform)(args...) = Gen.random(d, args...)

@inline Gen.random(::SetUniform{T}, support::AbstractSet{T}) where {T} =
    rand(support)
@inline Gen.random(::SetUniform{Pair{T,U}}, support::AbstractDict{T,U}) where {T,U} =
    rand(support)

@inline Gen.logpdf(::SetUniform{T}, x::T, support::AbstractSet{T}) where {T} =
    x in support ? -log(length(support)) : -Inf
@inline Gen.logpdf(::SetUniform{Pair{T,U}}, x::Pair{T,U}, support::AbstractDict{T,U}) where {T,U} =
    x in support ? -log(length(support)) : -Inf

Gen.logpdf_grad(::SetUniform, x, support) =
    (nothing, nothing)
Gen.has_output_grad(::SetUniform) =
    false
Gen.has_argument_grads(::SetUniform) =
    (false,)

"Categorical distribution over an array of labels."
struct LabeledCategorical{T} <: Gen.Distribution{T} end
LabeledCategorical() = LabeledCategorical{Any}()

(d::LabeledCategorical)(args...) = Gen.random(d, args...)

@inline Gen.random(::LabeledCategorical{T}, labels::AbstractArray{T}, weights::AbstractWeights) where {T} =
    sample(labels, weights)
@inline Gen.logpdf(::LabeledCategorical{T}, x::T, labels::AbstractArray{T}, weights::AbstractWeights) where {T} =
    log(sum((x .== vec(labels)) .* Vector(weights))) - log(sum(weights))
@inline Gen.logpdf(::LabeledCategorical{T}, x::T, labels::AbstractArray{T}, weights::UnitWeights) where {T} =
    log(sum(x .== labels) / length(labels))

@inline function Gen.logpdf_grad(::LabeledCategorical, x, labels, weights::AbstractWeights)
    grad = (x .== vec(labels)) .* (1. ./ Vector(weights)) .- 1.0 ./ sum(weights)
    return (nothing, nothing, grad)
end

Gen.has_output_grad(::LabeledCategorical) =
    false
Gen.has_argument_grads(::LabeledCategorical) =
    (false, true)

"Uniform distribution over permutations of length N."
struct RandomPermutation{T,N} <: Gen.Distribution{T} end
RandomPermutation(n::T) where {T <: Integer} = RandomPermutation{Vector{T},n}()

(d::RandomPermutation)() = Gen.random(d)

@inline Gen.random(::RandomPermutation{T,N}) where {T,N} =
    randperm(N)
@inline Gen.logpdf(::RandomPermutation{T,N}, x::T) where {T,N} =
    length(x) == N && isperm(x) ? -logfactorial(N) : -Inf

Gen.logpdf_grad(::RandomPermutation, x) =
    (nothing,)
Gen.has_output_grad(::RandomPermutation) =
    false
Gen.has_argument_grads(::RandomPermutation) =
    ()

"Uniform distribution over cyclic permutations of length N."
struct RandomCycle{T,N} <: Gen.Distribution{T} end
RandomCycle(n::T) where {T <: Integer} = RandomCycle{Vector{T},n}()

(d::RandomCycle)() = Gen.random(d)

function iscycle(v::Vector{<:Integer})
    n = length(v); seen = falses(n); i = 1
    for k in 1:n
        (0 < i <= n) && (seen[i] ⊻= true) || return false
        i = v[i]
    end
    return true
end

@inline Gen.random(::RandomCycle{T,N}) where {T,N} =
    randcycle(N)
@inline Gen.logpdf(::RandomCycle{T,N}, x::T) where {T,N} =
    length(x) == N && iscycle(x) ? -logfactorial(N-1) : -Inf

Gen.logpdf_grad(::RandomCycle, x) =
    (nothing,)
Gen.has_output_grad(::RandomCycle) =
    false
Gen.has_argument_grads(::RandomCycle) =
    ()

"Uniform distribution over permutations (shuffles) of an array."
struct RandomShuffle{T <: AbstractArray} <: Gen.Distribution{T}
    v::T # Original array to be shuffled
end

(d::RandomShuffle)() = Gen.random(d)

@inline Gen.random(d::RandomShuffle) =
    shuffle(d.v)
function Gen.logpdf(d::RandomShuffle{T}, xs::T) where {T}
    if size(xs) != size(d.v) return -Inf end
    v_counts = countmap(d.v)
    score = sum(logfactorial.(values(v_counts))) - logfactorial(length(d.v))
    for x in xs
        x in keys(v_counts) || return -Inf
        v_counts[x] -= 1
    end
    return all(values(v_counts) .== 0) ? score : -Inf
end

Gen.logpdf_grad(::RandomShuffle, x) =
    (nothing,)
Gen.has_output_grad(::RandomShuffle) =
    false
Gen.has_argument_grads(::RandomShuffle) =
    ()


text:
############################################
# Developer: Luiz Henrique Nogueira Lorena #
# 15/01/22                                 #
############################################

using Random
using CSV, DataFrames, Statistics
using JuMP, CPLEX
using PyCall, PyPlot
using ScikitLearn
using ScikitLearn.CrossValidation: train_test_split
@sk_import linear_model: LinearRegression
@sk_import metrics: r2_score

py"""
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

def printCorrelationMatrix(corr):

    sns.set_theme(style="white")

    # Generate a mask for the upper triangle
    mask = np.triu(np.ones_like(corr, dtype=bool))

    # Set up the matplotlib figure
    f, ax = plt.subplots(figsize=(14, 12))
    ax.set_title('Pearson Correlation')

    # Draw the heatmap with the mask and correct aspect ratio
    sns.heatmap(corr,
                mask=mask,
                cmap="coolwarm",
                vmax=1,
                vmin = -1,
                center=0.5,
                square=True,
                linewidths=.5,
                cbar_kws={"shrink": .4},
                annot = True,
                annot_kws = {"size": 13})

def printParetoFront(XX,XY):
    sns.set_theme(style="white",font_scale=3)

    # Set up the matplotlib figure
    f, ax = plt.subplots(figsize=(14, 12))
    ax.set_title('Pareto Front')

    d = {'Total X-X correlations': XX, 'Total X-Y correlations': XY}
    df = pd.DataFrame(data=d)

    sns.lineplot(data = df,
                 x='Total X-X correlations',
                 y='Total X-Y correlations',
                 markers=True,
                 marker='o',
                 markersize = 12)

def printR2(X,Y):
    sns.set_theme(style="whitegrid",font_scale=3)
    d = {'Points': X, 'r2': Y}
    df = pd.DataFrame(data=d)
    f, ax = plt.subplots(figsize=(14, 12))
    sns.barplot(x="Points", y="r2", data=df)
"""

function loadData(dataset)
    df = CSV.read(dataset, DataFrame)
    ρ = cor(Matrix(df))                # Pearson correlation
    py"printCorrelationMatrix"(ρ)
    display(gcf())
    savefig("results/correlationMatrix.pdf")
    ρ = abs.(cor(Matrix(df)))
    return Matrix(df[:,1:end-1]), Vector(df[:,end]), ρ[1:end-1,1:end-1], ρ[1:end-1,end]
end

mutable struct Solution
    id
    obj
    variables
    θ
    φ
    r2
end

function executeVariableSelectModel(ρij, ρ0i, α)

    N = size(ρij,1)

    m = Model(CPLEX.Optimizer)

    @variable(m, u[i in 1:N], Bin)
    @variable(m, v[i in 1:N, j in 1:N; i<j])

    @objective(m, Max, α * sum( abs(ρ0i[i]) * u[i] for i in 1:N ) - (1-α) * sum( abs(ρij[i,j]) * v[i,j] for i in 1:N-1, j in i+1:N))

    for i in 1:N-1
        for j in i+1:N
            @constraint(m, v[i,j] >= 0)
            @constraint(m, v[i,j] >= u[i] + u[j] - 1)
        end
    end

    set_silent(m)

    optimize!(m)
    u_opt = JuMP.value.(u)
    v_opt = JuMP.value.(v)
    obj = JuMP.objective_value(m)

    φ = 0.0
    M = zeros(Bool,N)
    for i in 1:N-1
        for j in i+1:N
            if v_opt[i,j] > 0.5
                M[i] = M[j] = true
                φ += ρij[i,j]
            end
        end
    end

    θ = 0.0
    variaveis = []
    for i in 1:N
        if M[i]
            push!(variaveis,i)
        end
        if u_opt[i] > 0.5
            θ += ρ0i[i]
        end
    end

    return Solution(0, obj, variaveis, θ, φ, 0.0)
end

function executeRegression(X,y)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
    lin_reg = fit!(LinearRegression(), X_train, y_train)
    y_predict = predict(lin_reg, X_test)
    r2 = r2_score(y_test, y_predict)
    return r2
end

function executeNair(dataset)

    # Load data
    X, y, ρij, ρ0i = loadData(dataset)

    # Total of variables
    n = size(X,2)

    # Array to store Pareto front solutions
    solutionID = 1
    solutions = Solution[]
    solutionsTested = []

    ###########################
    # Get initial SS0 and SSF #
    ###########################

    #######################################
    # SS0 - variable with higher ρ0i value
    bestvariable = sortperm(ρ0i, rev = true)[1]
    θq = ρ0i[bestvariable]
    φq = 0

    # r2 for SS0
    X_new = reshape(X[:,bestvariable], length(X[:,bestvariable]), 1)
    r2_SS0 = executeRegression(X_new,y)

    ######################
    # SSF - all variables
    θr = sum(ρ0i)
    φr = 0.0
    for i in 1:n-1
        for j in i+1:n
            φr += ρij[i,j]
        end
    end

    # r2 for SSF
    r2_SSF = executeRegression(X,y)

    # αl for the first iteration
    αl = (φq - φr)/(θq + φq - θr - φr)

    # Objective value for SS0 and SSF
    zα = (αl * θq) - ( (1-αl) * φq )

    # Store solutions from pareto frontier SSO and SSF
    push!(solutions, Solution(solutionID,zα, [bestvariable], θq, φq, r2_SS0))
    solutionID += 1
    push!(solutions, Solution(solutionID, zα, collect(1:n), θr, φr, r2_SSF))
    solutionID += 1
    push!(solutionsTested,(solutions[1].id,solutions[2].id))

    #######################################
    # Solve the ILP with the calculated αl
    solution = executeVariableSelectModel(ρij, ρ0i, αl)

    if solution.obj > zα
        # Execute r2 for the new point
        X_new = X[:,solution.variables]
        solution.r2 = executeRegression(X_new,y)
        solution.id = solutionID
        solutionID += 1
        insert!(solutions, 2, solution)
    end

    if size(solutions,1) == 3

        pointinserted = true

        while pointinserted == true

            pointinserted = false

            i = 1
            totalpontos = size(solutions,1)

            while i < totalpontos

                solution1 = solutions[i]
                solution2 = solutions[i+1]

                if (solution1.id, solution2.id) ∉ solutionsTested

                    # Calculate αl
                    αl = (solution1.φ - solution2.φ)/(solution1.θ + solution1.φ - solution2.θ - solution2.φ)

                    # Calculate zα for SS0
                    zα = (αl * solution1.θ) - ( (1-αl) * solution1.φ )

                    # Solve the ILP with the calculated αl
                    solutionNEW = executeVariableSelectModel(ρij, ρ0i, αl)

                    #if solutionNEW.obj > zα
                    if solutionNEW.obj - zα > 0.0001
                        # Execute r2 for the new point
                        X_new = X[:,solutionNEW.variables]
                        solutionNEW.r2 = executeRegression(X_new,y)
                        solutionNEW.id = solutionID
                        solutionID += 1
                        insert!(solutions,i+1,solutionNEW)
                        pointinserted = true
                        totalpontos += 1

                        push!(solutionsTested,(solution1.id, solution2.id))
                    end

                end

                i += 1
            end

        end

    end

    # Plot Pareto Front
    XX = []
    XY = []
    for sol in solutions
        push!(XX,sol.φ)
        push!(XY,sol.θ)
    end
    py"printParetoFront"(XX,XY)
    display(gcf())
    savefig("results/paretoFront.pdf")

    py"printR2"(collect(1:size(solutions,1)), [sol.r2 for sol in solutions])
    display(gcf())
    savefig("results/r2.pdf")

    df = DataFrame(
        Point = collect(1:size(solutions,1)),
        Obj = [sol.obj for sol in solutions],
        Variables = [Int.(sol.variables) for sol in solutions],
        θ = [sol.θ for sol in solutions],
        φ = [sol.φ for sol in solutions],
        r2 = [sol.r2 for sol in solutions]
    )

    CSV.write("results/resultado.csv",df)

    print(df)

    return solutions
end

#Random.seed!(0)
solutions = executeNair("datasets/2.txt");

ext: jl


text:
using Pkg, Random
Pkg.activate(".")

module EnzymeMFABC
include("../example.jl")
end

using FileIO, JLD2

Random.seed!(444)
ABC_stats = EnzymeMFABC.do_abc.([10_000, 20_000, 40_000, 80_000])

c = map(ABC_stats) do x
    x[3]
end
v = map(ABC_stats) do x
    x[2]
end

save("ABC_stats.jld2", Dict("c" => c, "v" => v))

max_stars_repo_name: tpprescott/mf-lf

max_issues_repo_name: tpprescott/mf-lf

max_forks_repo_name: tpprescott/mf-lf


text:
include("run_scf_and_compare.jl")
include("testcases.jl")

function run_iron_lda(T; kwargs...)
    # These values were computed using ABINIT with the same kpoints as testcases.jl
    # and Ecut = 15. They are not yet converged and thus require the same discretisation
    # parameters to be obtained.
    ref_lda = [
        [ 0.055335160026957, 0.318268719950663, 0.318268719983204, 0.453844901754021,
          0.465456022940131, 0.465456022955040, 0.796938936853792, 0.9378278608989292],
        [ 0.202562784343803, 0.257484383305897, 0.298153168492320, 0.484002264268755,
          0.486738682667850, 0.586413954242265, 0.606054175235276, 0.7921984533391616],
        [-0.025828679734167, 0.379219384359043, 0.379219384380489, 0.412266299189737,
          0.421421148410838, 0.469007916884015, 1.014229786618585, 1.082646799659422],
        [ 0.122870253157049, 0.284288157581980, 0.344201118979085, 0.418278709282607,
          0.470914403053476, 0.473315810505416, 0.712342007821782, 0.8817040989078889],
        [ 0.249396221271434, 0.249396221271986, 0.283803391450257, 0.464807045105138,
          0.464807045129581, 0.600140396214226, 0.641661514945205, 0.6416615149484401],
        [ 0.215115530345620, 0.230559459189795, 0.413101385500933, 0.413101385526945,
          0.443282733300631, 0.476867020334080, 0.702492626996283, 0.7024926270118694],
        [ 0.099871712572642, 0.424238848817503, 0.424238848844880, 0.596529745402267,
          0.628841951719554, 0.628841951734441, 0.891993361117189, 1.0316903612443131],
        [ 0.273624284119989, 0.308366088258763, 0.394136428473583, 0.637445234492337,
          0.660367125811219, 0.695536341395981, 0.759456147985534, 0.9049047470326816],
        [ 0.016725290665167, 0.501424956361337, 0.501424956379435, 0.543811076656092,
          0.565010802783482, 0.63953000442497 , 1.097171561169634, 1.1851677714770334],
        [ 0.172968957815038, 0.369175928007706, 0.455665586569160, 0.556763288068905,
          0.626381596590897, 0.636563034574486, 0.834717579200534, 0.9711639337454779],
        [ 0.323081016250375, 0.323081016251097, 0.370943969450466, 0.609089414206416,
          0.609089414224977, 0.713615164563541, 0.776414016931158, 0.7764140169376185],
        [ 0.283999916316325, 0.339176502497316, 0.523562806877426, 0.523562806894741,
          0.576405064140235, 0.604381023304363, 0.808531656348124, 0.8085316563716097],
    ]
    ref_etot = -16.670871429685356

    magnetic_moments = [4.0]
    model = model_DFT(Array{T}(iron_bcc.lattice), iron_bcc.atoms, iron_bcc.positions,
                      [:lda_xc_teter93]; temperature=0.01, magnetic_moments)
    basis = PlaneWaveBasis(model; Ecut=15, fft_size=[20, 20, 20],
                           kgrid=[4, 4, 4], kshift=[1/2, 1/2, 1/2])
    run_scf_and_compare(T, basis, ref_lda, ref_etot;
                        ρ=guess_density(basis, magnetic_moments), kwargs...)
end

@testset "Iron LDA (Float64)" begin
    run_iron_lda(Float64, test_tol=5e-6, scf_tol=1e-10)
end


text:
# Call a function n times and print the average elapsed time.
function benchElapsedTime(n:: Int64, benchfun:: Function)
  acctime = 0.0
  for i = 1:n
    start = time_ns()
    benchfun()
    stop = time_ns()
    acctime += (stop - start) / 1e9
  end
  println("ELAPSEDTIME: " * string(acctime/n))
end

max_stars_repo_name: cau-placc/julia-curry

max_issues_repo_name: cau-placc/julia-curry

max_forks_repo_name: cau-placc/julia-curry


text:
# Automatically generated using Clang.jl

const CUPTI_API_VERSION = 13

# Skipping MacroDefinition: CUPTI_EVENT_OVERFLOW ( ( uint64_t ) 0xFFFFFFFFFFFFFFFFULL )
# Skipping MacroDefinition: CUPTI_EVENT_INVALID ( ( uint64_t ) 0xFFFFFFFFFFFFFFFEULL )

const CUPTILP64 = 1
const ACTIVITY_RECORD_ALIGNMENT = 8

# Skipping MacroDefinition: PACKED_ALIGNMENT __attribute__ ( ( __packed__ ) ) __attribute__ ( ( aligned ( ACTIVITY_RECORD_ALIGNMENT ) ) )
# Skipping MacroDefinition: CUPTI_UNIFIED_MEMORY_CPU_DEVICE_ID ( ( uint32_t ) 0xFFFFFFFFU )
# Skipping MacroDefinition: CUPTI_INVALID_CONTEXT_ID ( ( uint32_t ) 0xFFFFFFFFU )

const CUPTI_SOURCE_LOCATOR_ID_UNKNOWN = 0
const CUPTI_FUNCTION_INDEX_ID_INVALID = 0
const CUPTI_CORRELATION_ID_UNKNOWN = 0
const CUPTI_GRID_ID_UNKNOWN = Int64(0)
const CUPTI_TIMESTAMP_UNKNOWN = Int64(0)
const CUPTI_SYNCHRONIZATION_INVALID_VALUE = -1
const CUPTI_AUTO_BOOST_INVALID_CLIENT_PID = 0
const CUPTI_NVLINK_INVALID_PORT = -1
const CUPTI_MAX_NVLINK_PORTS = 16
const CUPTI_MAX_GPUS = 32

@cenum CUptiResult::UInt32 begin
    CUPTI_SUCCESS = 0
    CUPTI_ERROR_INVALID_PARAMETER = 1
    CUPTI_ERROR_INVALID_DEVICE = 2
    CUPTI_ERROR_INVALID_CONTEXT = 3
    CUPTI_ERROR_INVALID_EVENT_DOMAIN_ID = 4
    CUPTI_ERROR_INVALID_EVENT_ID = 5
    CUPTI_ERROR_INVALID_EVENT_NAME = 6
    CUPTI_ERROR_INVALID_OPERATION = 7
    CUPTI_ERROR_OUT_OF_MEMORY = 8
    CUPTI_ERROR_HARDWARE = 9
    CUPTI_ERROR_PARAMETER_SIZE_NOT_SUFFICIENT = 10
    CUPTI_ERROR_API_NOT_IMPLEMENTED = 11
    CUPTI_ERROR_MAX_LIMIT_REACHED = 12
    CUPTI_ERROR_NOT_READY = 13
    CUPTI_ERROR_NOT_COMPATIBLE = 14
    CUPTI_ERROR_NOT_INITIALIZED = 15
    CUPTI_ERROR_INVALID_METRIC_ID = 16
    CUPTI_ERROR_INVALID_METRIC_NAME = 17
    CUPTI_ERROR_QUEUE_EMPTY = 18
    CUPTI_ERROR_INVALID_HANDLE = 19
    CUPTI_ERROR_INVALID_STREAM = 20
    CUPTI_ERROR_INVALID_KIND = 21
    CUPTI_ERROR_INVALID_EVENT_VALUE = 22
    CUPTI_ERROR_DISABLED = 23
    CUPTI_ERROR_INVALID_MODULE = 24
    CUPTI_ERROR_INVALID_METRIC_VALUE = 25
    CUPTI_ERROR_HARDWARE_BUSY = 26
    CUPTI_ERROR_NOT_SUPPORTED = 27
    CUPTI_ERROR_UM_PROFILING_NOT_SUPPORTED = 28
    CUPTI_ERROR_UM_PROFILING_NOT_SUPPORTED_ON_DEVICE = 29
    CUPTI_ERROR_UM_PROFILING_NOT_SUPPORTED_ON_NON_P2P_DEVICES = 30
    CUPTI_ERROR_UM_PROFILING_NOT_SUPPORTED_WITH_MPS = 31
    CUPTI_ERROR_CDP_TRACING_NOT_SUPPORTED = 32
    CUPTI_ERROR_VIRTUALIZED_DEVICE_NOT_SUPPORTED = 33
    CUPTI_ERROR_CUDA_COMPILER_NOT_COMPATIBLE = 34
    CUPTI_ERROR_INSUFFICIENT_PRIVILEGES = 35
    CUPTI_ERROR_OLD_PROFILER_API_INITIALIZED = 36
    CUPTI_ERROR_OPENACC_UNDEFINED_ROUTINE = 37
    CUPTI_ERROR_LEGACY_PROFILER_NOT_SUPPORTED = 38
    CUPTI_ERROR_MULTIPLE_SUBSCRIBERS_NOT_SUPPORTED = 39
    CUPTI_ERROR_UNKNOWN = 999
    CUPTI_ERROR_FORCE_INT = 2147483647
end

@cenum CUpti_ApiCallbackSite::UInt32 begin
    CUPTI_API_ENTER = 0
    CUPTI_API_EXIT = 1
    CUPTI_API_CBSITE_FORCE_INT = 2147483647
end

@cenum CUpti_CallbackDomain::UInt32 begin
    CUPTI_CB_DOMAIN_INVALID = 0
    CUPTI_CB_DOMAIN_DRIVER_API = 1
    CUPTI_CB_DOMAIN_RUNTIME_API = 2
    CUPTI_CB_DOMAIN_RESOURCE = 3
    CUPTI_CB_DOMAIN_SYNCHRONIZE = 4
    CUPTI_CB_DOMAIN_NVTX = 5
    CUPTI_CB_DOMAIN_SIZE = 6
    CUPTI_CB_DOMAIN_FORCE_INT = 2147483647
end

@cenum CUpti_CallbackIdResource::UInt32 begin
    CUPTI_CBID_RESOURCE_INVALID = 0
    CUPTI_CBID_RESOURCE_CONTEXT_CREATED = 1
    CUPTI_CBID_RESOURCE_CONTEXT_DESTROY_STARTING = 2
    CUPTI_CBID_RESOURCE_STREAM_CREATED = 3
    CUPTI_CBID_RESOURCE_STREAM_DESTROY_STARTING = 4
    CUPTI_CBID_RESOURCE_CU_INIT_FINISHED = 5
    CUPTI_CBID_RESOURCE_MODULE_LOADED = 6
    CUPTI_CBID_RESOURCE_MODULE_UNLOAD_STARTING = 7
    CUPTI_CBID_RESOURCE_MODULE_PROFILED = 8
    CUPTI_CBID_RESOURCE_GRAPH_CREATED = 9
    CUPTI_CBID_RESOURCE_GRAPH_DESTROY_STARTING = 10
    CUPTI_CBID_RESOURCE_GRAPH_CLONED = 11
    CUPTI_CBID_RESOURCE_GRAPHNODE_CREATE_STARTING = 12
    CUPTI_CBID_RESOURCE_GRAPHNODE_CREATED = 13
    CUPTI_CBID_RESOURCE_GRAPHNODE_DESTROY_STARTING = 14
    CUPTI_CBID_RESOURCE_GRAPHNODE_DEPENDENCY_CREATED = 15
    CUPTI_CBID_RESOURCE_GRAPHNODE_DEPENDENCY_DESTROY_STARTING = 16
    CUPTI_CBID_RESOURCE_GRAPHEXEC_CREATE_STARTING = 17
    CUPTI_CBID_RESOURCE_GRAPHEXEC_CREATED = 18
    CUPTI_CBID_RESOURCE_GRAPHEXEC_DESTROY_STARTING = 19
    CUPTI_CBID_RESOURCE_GRAPHNODE_CLONED = 20
    CUPTI_CBID_RESOURCE_SIZE = 21
    CUPTI_CBID_RESOURCE_FORCE_INT = 2147483647
end

@cenum CUpti_CallbackIdSync::UInt32 begin
    CUPTI_CBID_SYNCHRONIZE_INVALID = 0
    CUPTI_CBID_SYNCHRONIZE_STREAM_SYNCHRONIZED = 1
    CUPTI_CBID_SYNCHRONIZE_CONTEXT_SYNCHRONIZED = 2
    CUPTI_CBID_SYNCHRONIZE_SIZE = 3
    CUPTI_CBID_SYNCHRONIZE_FORCE_INT = 2147483647
end

struct CUpti_CallbackData
    callbackSite::CUpti_ApiCallbackSite
    functionName::Cstring
    functionParams::Ptr{Cvoid}
    functionReturnValue::Ptr{Cvoid}
    symbolName::Cstring
    context::CUcontext
    contextUid::UInt32
    correlationData::Ptr{UInt64}
    correlationId::UInt32
end

struct ANONYMOUS1_resourceHandle
    stream::CUstream
end

struct CUpti_ResourceData
    context::CUcontext
    resourceHandle::ANONYMOUS1_resourceHandle
    resourceDescriptor::Ptr{Cvoid}
end

struct CUpti_ModuleResourceData
    moduleId::UInt32
    cubinSize::Csize_t
    pCubin::Cstring
end

struct CUpti_GraphData
    graph::CUgraph
    originalGraph::CUgraph
    node::CUgraphNode
    originalNode::CUgraphNode
    nodeType::CUgraphNodeType
    dependency::CUgraphNode
    graphExec::CUgraphExec
end

struct CUpti_SynchronizeData
    context::CUcontext
    stream::CUstream
end

struct CUpti_NvtxData
    functionName::Cstring
    functionParams::Ptr{Cvoid}
end

const CUpti_CallbackId = UInt32
const CUpti_CallbackFunc = Ptr{Cvoid}
const CUpti_Subscriber_st = Cvoid
const CUpti_SubscriberHandle = Ptr{CUpti_Subscriber_st}
const CUpti_DomainTable = Ptr{CUpti_CallbackDomain}
const CUpti_EventID = UInt32
const CUpti_EventDomainID = UInt32
const CUpti_EventGroup = Ptr{Cvoid}

@cenum CUpti_DeviceAttributeDeviceClass::UInt32 begin
    CUPTI_DEVICE_ATTR_DEVICE_CLASS_TESLA = 0
    CUPTI_DEVICE_ATTR_DEVICE_CLASS_QUADRO = 1
    CUPTI_DEVICE_ATTR_DEVICE_CLASS_GEFORCE = 2
    CUPTI_DEVICE_ATTR_DEVICE_CLASS_TEGRA = 3
end

@cenum CUpti_DeviceAttribute::UInt32 begin
    CUPTI_DEVICE_ATTR_MAX_EVENT_ID = 1
    CUPTI_DEVICE_ATTR_MAX_EVENT_DOMAIN_ID = 2
    CUPTI_DEVICE_ATTR_GLOBAL_MEMORY_BANDWIDTH = 3
    CUPTI_DEVICE_ATTR_INSTRUCTION_PER_CYCLE = 4
    CUPTI_DEVICE_ATTR_INSTRUCTION_THROUGHPUT_SINGLE_PRECISION = 5
    CUPTI_DEVICE_ATTR_MAX_FRAME_BUFFERS = 6
    CUPTI_DEVICE_ATTR_PCIE_LINK_RATE = 7
    CUPTI_DEVICE_ATTR_PCIE_LINK_WIDTH = 8
    CUPTI_DEVICE_ATTR_PCIE_GEN = 9
    CUPTI_DEVICE_ATTR_DEVICE_CLASS = 10
    CUPTI_DEVICE_ATTR_FLOP_SP_PER_CYCLE = 11
    CUPTI_DEVICE_ATTR_FLOP_DP_PER_CYCLE = 12
    CUPTI_DEVICE_ATTR_MAX_L2_UNITS = 13
    CUPTI_DEVICE_ATTR_MAX_SHARED_MEMORY_CACHE_CONFIG_PREFER_SHARED = 14
    CUPTI_DEVICE_ATTR_MAX_SHARED_MEMORY_CACHE_CONFIG_PREFER_L1 = 15
    CUPTI_DEVICE_ATTR_MAX_SHARED_MEMORY_CACHE_CONFIG_PREFER_EQUAL = 16
    CUPTI_DEVICE_ATTR_FLOP_HP_PER_CYCLE = 17
    CUPTI_DEVICE_ATTR_NVLINK_PRESENT = 18
    CUPTI_DEVICE_ATTR_GPU_CPU_NVLINK_BW = 19
    CUPTI_DEVICE_ATTR_NVSWITCH_PRESENT = 20
    CUPTI_DEVICE_ATTR_FORCE_INT = 2147483647
end

@cenum CUpti_EventDomainAttribute::UInt32 begin
    CUPTI_EVENT_DOMAIN_ATTR_NAME = 0
    CUPTI_EVENT_DOMAIN_ATTR_INSTANCE_COUNT = 1
    CUPTI_EVENT_DOMAIN_ATTR_TOTAL_INSTANCE_COUNT = 3
    CUPTI_EVENT_DOMAIN_ATTR_COLLECTION_METHOD = 4
    CUPTI_EVENT_DOMAIN_ATTR_FORCE_INT = 2147483647
end

@cenum CUpti_EventCollectionMethod::UInt32 begin
    CUPTI_EVENT_COLLECTION_METHOD_PM = 0
    CUPTI_EVENT_COLLECTION_METHOD_SM = 1
    CUPTI_EVENT_COLLECTION_METHOD_INSTRUMENTED = 2
    CUPTI_EVENT_COLLECTION_METHOD_NVLINK_TC = 3
    CUPTI_EVENT_COLLECTION_METHOD_FORCE_INT = 2147483647
end

@cenum CUpti_EventGroupAttribute::UInt32 begin
    CUPTI_EVENT_GROUP_ATTR_EVENT_DOMAIN_ID = 0
    CUPTI_EVENT_GROUP_ATTR_PROFILE_ALL_DOMAIN_INSTANCES = 1
    CUPTI_EVENT_GROUP_ATTR_USER_DATA = 2
    CUPTI_EVENT_GROUP_ATTR_NUM_EVENTS = 3
    CUPTI_EVENT_GROUP_ATTR_EVENTS = 4
    CUPTI_EVENT_GROUP_ATTR_INSTANCE_COUNT = 5
    CUPTI_EVENT_GROUP_ATTR_PROFILING_SCOPE = 6
    CUPTI_EVENT_GROUP_ATTR_FORCE_INT = 2147483647
end

@cenum CUpti_EventProfilingScope::UInt32 begin
    CUPTI_EVENT_PROFILING_SCOPE_CONTEXT = 0
    CUPTI_EVENT_PROFILING_SCOPE_DEVICE = 1
    CUPTI_EVENT_PROFILING_SCOPE_BOTH = 2
    CUPTI_EVENT_PROFILING_SCOPE_FORCE_INT = 2147483647
end

@cenum CUpti_EventAttribute::UInt32 begin
    CUPTI_EVENT_ATTR_NAME = 0
    CUPTI_EVENT_ATTR_SHORT_DESCRIPTION = 1
    CUPTI_EVENT_ATTR_LONG_DESCRIPTION = 2
    CUPTI_EVENT_ATTR_CATEGORY = 3
    CUPTI_EVENT_ATTR_PROFILING_SCOPE = 5
    CUPTI_EVENT_ATTR_FORCE_INT = 2147483647
end

@cenum CUpti_EventCollectionMode::UInt32 begin
    CUPTI_EVENT_COLLECTION_MODE_CONTINUOUS = 0
    CUPTI_EVENT_COLLECTION_MODE_KERNEL = 1
    CUPTI_EVENT_COLLECTION_MODE_FORCE_INT = 2147483647
end

@cenum CUpti_EventCategory::UInt32 begin
    CUPTI_EVENT_CATEGORY_INSTRUCTION = 0
    CUPTI_EVENT_CATEGORY_MEMORY = 1
    CUPTI_EVENT_CATEGORY_CACHE = 2
    CUPTI_EVENT_CATEGORY_PROFILE_TRIGGER = 3
    CUPTI_EVENT_CATEGORY_SYSTEM = 4
    CUPTI_EVENT_CATEGORY_FORCE_INT = 2147483647
end

@cenum CUpti_ReadEventFlags::UInt32 begin
    CUPTI_EVENT_READ_FLAG_NONE = 0
    CUPTI_EVENT_READ_FLAG_FORCE_INT = 2147483647
end

struct CUpti_EventGroupSet
    numEventGroups::UInt32
    eventGroups::Ptr{CUpti_EventGroup}
end

struct CUpti_EventGroupSets
    numSets::UInt32
    sets::Ptr{CUpti_EventGroupSet}
end

const CUpti_KernelReplayUpdateFunc = Ptr{Cvoid}
const CUpti_MetricID = UInt32

@cenum CUpti_MetricCategory::UInt32 begin
    CUPTI_METRIC_CATEGORY_MEMORY = 0
    CUPTI_METRIC_CATEGORY_INSTRUCTION = 1
    CUPTI_METRIC_CATEGORY_MULTIPROCESSOR = 2
    CUPTI_METRIC_CATEGORY_CACHE = 3
    CUPTI_METRIC_CATEGORY_TEXTURE = 4
    CUPTI_METRIC_CATEGORY_NVLINK = 5
    CUPTI_METRIC_CATEGORY_PCIE = 6
    CUPTI_METRIC_CATEGORY_FORCE_INT = 2147483647
end

@cenum CUpti_MetricEvaluationMode::UInt32 begin
    CUPTI_METRIC_EVALUATION_MODE_PER_INSTANCE = 1
    CUPTI_METRIC_EVALUATION_MODE_AGGREGATE = 2
    CUPTI_METRIC_EVALUATION_MODE_FORCE_INT = 2147483647
end

@cenum CUpti_MetricValueKind::UInt32 begin
    CUPTI_METRIC_VALUE_KIND_DOUBLE = 0
    CUPTI_METRIC_VALUE_KIND_UINT64 = 1
    CUPTI_METRIC_VALUE_KIND_PERCENT = 2
    CUPTI_METRIC_VALUE_KIND_THROUGHPUT = 3
    CUPTI_METRIC_VALUE_KIND_INT64 = 4
    CUPTI_METRIC_VALUE_KIND_UTILIZATION_LEVEL = 5
    CUPTI_METRIC_VALUE_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_MetricValueUtilizationLevel::UInt32 begin
    CUPTI_METRIC_VALUE_UTILIZATION_IDLE = 0
    CUPTI_METRIC_VALUE_UTILIZATION_LOW = 2
    CUPTI_METRIC_VALUE_UTILIZATION_MID = 5
    CUPTI_METRIC_VALUE_UTILIZATION_HIGH = 8
    CUPTI_METRIC_VALUE_UTILIZATION_MAX = 10
    CUPTI_METRIC_VALUE_UTILIZATION_FORCE_INT = 2147483647
end

@cenum CUpti_MetricAttribute::UInt32 begin
    CUPTI_METRIC_ATTR_NAME = 0
    CUPTI_METRIC_ATTR_SHORT_DESCRIPTION = 1
    CUPTI_METRIC_ATTR_LONG_DESCRIPTION = 2
    CUPTI_METRIC_ATTR_CATEGORY = 3
    CUPTI_METRIC_ATTR_VALUE_KIND = 4
    CUPTI_METRIC_ATTR_EVALUATION_MODE = 5
    CUPTI_METRIC_ATTR_FORCE_INT = 2147483647
end

struct CUpti_MetricValue
    metricValueDouble::Cdouble
end

@cenum CUpti_MetricPropertyDeviceClass::UInt32 begin
    CUPTI_METRIC_PROPERTY_DEVICE_CLASS_TESLA = 0
    CUPTI_METRIC_PROPERTY_DEVICE_CLASS_QUADRO = 1
    CUPTI_METRIC_PROPERTY_DEVICE_CLASS_GEFORCE = 2
    CUPTI_METRIC_PROPERTY_DEVICE_CLASS_TEGRA = 3
end

@cenum CUpti_MetricPropertyID::UInt32 begin
    CUPTI_METRIC_PROPERTY_MULTIPROCESSOR_COUNT = 0
    CUPTI_METRIC_PROPERTY_WARPS_PER_MULTIPROCESSOR = 1
    CUPTI_METRIC_PROPERTY_KERNEL_GPU_TIME = 2
    CUPTI_METRIC_PROPERTY_CLOCK_RATE = 3
    CUPTI_METRIC_PROPERTY_FRAME_BUFFER_COUNT = 4
    CUPTI_METRIC_PROPERTY_GLOBAL_MEMORY_BANDWIDTH = 5
    CUPTI_METRIC_PROPERTY_PCIE_LINK_RATE = 6
    CUPTI_METRIC_PROPERTY_PCIE_LINK_WIDTH = 7
    CUPTI_METRIC_PROPERTY_PCIE_GEN = 8
    CUPTI_METRIC_PROPERTY_DEVICE_CLASS = 9
    CUPTI_METRIC_PROPERTY_FLOP_SP_PER_CYCLE = 10
    CUPTI_METRIC_PROPERTY_FLOP_DP_PER_CYCLE = 11
    CUPTI_METRIC_PROPERTY_L2_UNITS = 12
    CUPTI_METRIC_PROPERTY_ECC_ENABLED = 13
    CUPTI_METRIC_PROPERTY_FLOP_HP_PER_CYCLE = 14
    CUPTI_METRIC_PROPERTY_GPU_CPU_NVLINK_BANDWIDTH = 15
end

@cenum CUpti_ActivityKind::UInt32 begin
    CUPTI_ACTIVITY_KIND_INVALID = 0
    CUPTI_ACTIVITY_KIND_MEMCPY = 1
    CUPTI_ACTIVITY_KIND_MEMSET = 2
    CUPTI_ACTIVITY_KIND_KERNEL = 3
    CUPTI_ACTIVITY_KIND_DRIVER = 4
    CUPTI_ACTIVITY_KIND_RUNTIME = 5
    CUPTI_ACTIVITY_KIND_EVENT = 6
    CUPTI_ACTIVITY_KIND_METRIC = 7
    CUPTI_ACTIVITY_KIND_DEVICE = 8
    CUPTI_ACTIVITY_KIND_CONTEXT = 9
    CUPTI_ACTIVITY_KIND_CONCURRENT_KERNEL = 10
    CUPTI_ACTIVITY_KIND_NAME = 11
    CUPTI_ACTIVITY_KIND_MARKER = 12
    CUPTI_ACTIVITY_KIND_MARKER_DATA = 13
    CUPTI_ACTIVITY_KIND_SOURCE_LOCATOR = 14
    CUPTI_ACTIVITY_KIND_GLOBAL_ACCESS = 15
    CUPTI_ACTIVITY_KIND_BRANCH = 16
    CUPTI_ACTIVITY_KIND_OVERHEAD = 17
    CUPTI_ACTIVITY_KIND_CDP_KERNEL = 18
    CUPTI_ACTIVITY_KIND_PREEMPTION = 19
    CUPTI_ACTIVITY_KIND_ENVIRONMENT = 20
    CUPTI_ACTIVITY_KIND_EVENT_INSTANCE = 21
    CUPTI_ACTIVITY_KIND_MEMCPY2 = 22
    CUPTI_ACTIVITY_KIND_METRIC_INSTANCE = 23
    CUPTI_ACTIVITY_KIND_INSTRUCTION_EXECUTION = 24
    CUPTI_ACTIVITY_KIND_UNIFIED_MEMORY_COUNTER = 25
    CUPTI_ACTIVITY_KIND_FUNCTION = 26
    CUPTI_ACTIVITY_KIND_MODULE = 27
    CUPTI_ACTIVITY_KIND_DEVICE_ATTRIBUTE = 28
    CUPTI_ACTIVITY_KIND_SHARED_ACCESS = 29
    CUPTI_ACTIVITY_KIND_PC_SAMPLING = 30
    CUPTI_ACTIVITY_KIND_PC_SAMPLING_RECORD_INFO = 31
    CUPTI_ACTIVITY_KIND_INSTRUCTION_CORRELATION = 32
    CUPTI_ACTIVITY_KIND_OPENACC_DATA = 33
    CUPTI_ACTIVITY_KIND_OPENACC_LAUNCH = 34
    CUPTI_ACTIVITY_KIND_OPENACC_OTHER = 35
    CUPTI_ACTIVITY_KIND_CUDA_EVENT = 36
    CUPTI_ACTIVITY_KIND_STREAM = 37
    CUPTI_ACTIVITY_KIND_SYNCHRONIZATION = 38
    CUPTI_ACTIVITY_KIND_EXTERNAL_CORRELATION = 39
    CUPTI_ACTIVITY_KIND_NVLINK = 40
    CUPTI_ACTIVITY_KIND_INSTANTANEOUS_EVENT = 41
    CUPTI_ACTIVITY_KIND_INSTANTANEOUS_EVENT_INSTANCE = 42
    CUPTI_ACTIVITY_KIND_INSTANTANEOUS_METRIC = 43
    CUPTI_ACTIVITY_KIND_INSTANTANEOUS_METRIC_INSTANCE = 44
    CUPTI_ACTIVITY_KIND_MEMORY = 45
    CUPTI_ACTIVITY_KIND_PCIE = 46
    CUPTI_ACTIVITY_KIND_OPENMP = 47
    CUPTI_ACTIVITY_KIND_INTERNAL_LAUNCH_API = 48
    CUPTI_ACTIVITY_KIND_COUNT = 49
    CUPTI_ACTIVITY_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityObjectKind::UInt32 begin
    CUPTI_ACTIVITY_OBJECT_UNKNOWN = 0
    CUPTI_ACTIVITY_OBJECT_PROCESS = 1
    CUPTI_ACTIVITY_OBJECT_THREAD = 2
    CUPTI_ACTIVITY_OBJECT_DEVICE = 3
    CUPTI_ACTIVITY_OBJECT_CONTEXT = 4
    CUPTI_ACTIVITY_OBJECT_STREAM = 5
    CUPTI_ACTIVITY_OBJECT_FORCE_INT = 2147483647
end

struct ANONYMOUS2_dcs
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
end

struct CUpti_ActivityObjectKindId
    dcs::ANONYMOUS2_dcs
end

@cenum CUpti_ActivityOverheadKind::UInt32 begin
    CUPTI_ACTIVITY_OVERHEAD_UNKNOWN = 0
    CUPTI_ACTIVITY_OVERHEAD_DRIVER_COMPILER = 1
    CUPTI_ACTIVITY_OVERHEAD_CUPTI_BUFFER_FLUSH = 65536
    CUPTI_ACTIVITY_OVERHEAD_CUPTI_INSTRUMENTATION = 131072
    CUPTI_ACTIVITY_OVERHEAD_CUPTI_RESOURCE = 196608
    CUPTI_ACTIVITY_OVERHEAD_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityComputeApiKind::UInt32 begin
    CUPTI_ACTIVITY_COMPUTE_API_UNKNOWN = 0
    CUPTI_ACTIVITY_COMPUTE_API_CUDA = 1
    CUPTI_ACTIVITY_COMPUTE_API_CUDA_MPS = 2
    CUPTI_ACTIVITY_COMPUTE_API_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityFlag::UInt32 begin
    CUPTI_ACTIVITY_FLAG_NONE = 0
    CUPTI_ACTIVITY_FLAG_DEVICE_CONCURRENT_KERNELS = 1
    CUPTI_ACTIVITY_FLAG_DEVICE_ATTRIBUTE_CUDEVICE = 1
    CUPTI_ACTIVITY_FLAG_MEMCPY_ASYNC = 1
    CUPTI_ACTIVITY_FLAG_MARKER_INSTANTANEOUS = 1
    CUPTI_ACTIVITY_FLAG_MARKER_START = 2
    CUPTI_ACTIVITY_FLAG_MARKER_END = 4
    CUPTI_ACTIVITY_FLAG_MARKER_SYNC_ACQUIRE = 8
    CUPTI_ACTIVITY_FLAG_MARKER_SYNC_ACQUIRE_SUCCESS = 16
    CUPTI_ACTIVITY_FLAG_MARKER_SYNC_ACQUIRE_FAILED = 32
    CUPTI_ACTIVITY_FLAG_MARKER_SYNC_RELEASE = 64
    CUPTI_ACTIVITY_FLAG_MARKER_COLOR_NONE = 1
    CUPTI_ACTIVITY_FLAG_MARKER_COLOR_ARGB = 2
    CUPTI_ACTIVITY_FLAG_GLOBAL_ACCESS_KIND_SIZE_MASK = 255
    CUPTI_ACTIVITY_FLAG_GLOBAL_ACCESS_KIND_LOAD = 256
    CUPTI_ACTIVITY_FLAG_GLOBAL_ACCESS_KIND_CACHED = 512
    CUPTI_ACTIVITY_FLAG_METRIC_OVERFLOWED = 1
    CUPTI_ACTIVITY_FLAG_METRIC_VALUE_INVALID = 2
    CUPTI_ACTIVITY_FLAG_INSTRUCTION_VALUE_INVALID = 1
    CUPTI_ACTIVITY_FLAG_INSTRUCTION_CLASS_MASK = 510
    CUPTI_ACTIVITY_FLAG_FLUSH_FORCED = 1
    CUPTI_ACTIVITY_FLAG_SHARED_ACCESS_KIND_SIZE_MASK = 255
    CUPTI_ACTIVITY_FLAG_SHARED_ACCESS_KIND_LOAD = 256
    CUPTI_ACTIVITY_FLAG_MEMSET_ASYNC = 1
    CUPTI_ACTIVITY_FLAG_THRASHING_IN_CPU = 1
    CUPTI_ACTIVITY_FLAG_THROTTLING_IN_CPU = 1
    CUPTI_ACTIVITY_FLAG_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityPCSamplingStallReason::UInt32 begin
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_INVALID = 0
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_NONE = 1
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_INST_FETCH = 2
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_EXEC_DEPENDENCY = 3
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_MEMORY_DEPENDENCY = 4
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_TEXTURE = 5
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_SYNC = 6
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_CONSTANT_MEMORY_DEPENDENCY = 7
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_PIPE_BUSY = 8
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_MEMORY_THROTTLE = 9
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_NOT_SELECTED = 10
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_OTHER = 11
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_SLEEPING = 12
    CUPTI_ACTIVITY_PC_SAMPLING_STALL_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityPCSamplingPeriod::UInt32 begin
    CUPTI_ACTIVITY_PC_SAMPLING_PERIOD_INVALID = 0
    CUPTI_ACTIVITY_PC_SAMPLING_PERIOD_MIN = 1
    CUPTI_ACTIVITY_PC_SAMPLING_PERIOD_LOW = 2
    CUPTI_ACTIVITY_PC_SAMPLING_PERIOD_MID = 3
    CUPTI_ACTIVITY_PC_SAMPLING_PERIOD_HIGH = 4
    CUPTI_ACTIVITY_PC_SAMPLING_PERIOD_MAX = 5
    CUPTI_ACTIVITY_PC_SAMPLING_PERIOD_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityMemcpyKind::UInt32 begin
    CUPTI_ACTIVITY_MEMCPY_KIND_UNKNOWN = 0
    CUPTI_ACTIVITY_MEMCPY_KIND_HTOD = 1
    CUPTI_ACTIVITY_MEMCPY_KIND_DTOH = 2
    CUPTI_ACTIVITY_MEMCPY_KIND_HTOA = 3
    CUPTI_ACTIVITY_MEMCPY_KIND_ATOH = 4
    CUPTI_ACTIVITY_MEMCPY_KIND_ATOA = 5
    CUPTI_ACTIVITY_MEMCPY_KIND_ATOD = 6
    CUPTI_ACTIVITY_MEMCPY_KIND_DTOA = 7
    CUPTI_ACTIVITY_MEMCPY_KIND_DTOD = 8
    CUPTI_ACTIVITY_MEMCPY_KIND_HTOH = 9
    CUPTI_ACTIVITY_MEMCPY_KIND_PTOP = 10
    CUPTI_ACTIVITY_MEMCPY_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityMemoryKind::UInt32 begin
    CUPTI_ACTIVITY_MEMORY_KIND_UNKNOWN = 0
    CUPTI_ACTIVITY_MEMORY_KIND_PAGEABLE = 1
    CUPTI_ACTIVITY_MEMORY_KIND_PINNED = 2
    CUPTI_ACTIVITY_MEMORY_KIND_DEVICE = 3
    CUPTI_ACTIVITY_MEMORY_KIND_ARRAY = 4
    CUPTI_ACTIVITY_MEMORY_KIND_MANAGED = 5
    CUPTI_ACTIVITY_MEMORY_KIND_DEVICE_STATIC = 6
    CUPTI_ACTIVITY_MEMORY_KIND_MANAGED_STATIC = 7
    CUPTI_ACTIVITY_MEMORY_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityPreemptionKind::UInt32 begin
    CUPTI_ACTIVITY_PREEMPTION_KIND_UNKNOWN = 0
    CUPTI_ACTIVITY_PREEMPTION_KIND_SAVE = 1
    CUPTI_ACTIVITY_PREEMPTION_KIND_RESTORE = 2
    CUPTI_ACTIVITY_PREEMPTION_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityEnvironmentKind::UInt32 begin
    CUPTI_ACTIVITY_ENVIRONMENT_UNKNOWN = 0
    CUPTI_ACTIVITY_ENVIRONMENT_SPEED = 1
    CUPTI_ACTIVITY_ENVIRONMENT_TEMPERATURE = 2
    CUPTI_ACTIVITY_ENVIRONMENT_POWER = 3
    CUPTI_ACTIVITY_ENVIRONMENT_COOLING = 4
    CUPTI_ACTIVITY_ENVIRONMENT_COUNT = 5
    CUPTI_ACTIVITY_ENVIRONMENT_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_EnvironmentClocksThrottleReason::UInt32 begin
    CUPTI_CLOCKS_THROTTLE_REASON_GPU_IDLE = 1
    CUPTI_CLOCKS_THROTTLE_REASON_USER_DEFINED_CLOCKS = 2
    CUPTI_CLOCKS_THROTTLE_REASON_SW_POWER_CAP = 4
    CUPTI_CLOCKS_THROTTLE_REASON_HW_SLOWDOWN = 8
    CUPTI_CLOCKS_THROTTLE_REASON_UNKNOWN = 2147483648
    CUPTI_CLOCKS_THROTTLE_REASON_UNSUPPORTED = 1073741824
    CUPTI_CLOCKS_THROTTLE_REASON_NONE = 0
    CUPTI_CLOCKS_THROTTLE_REASON_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityUnifiedMemoryCounterScope::UInt32 begin
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_SCOPE_UNKNOWN = 0
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_SCOPE_PROCESS_SINGLE_DEVICE = 1
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_SCOPE_PROCESS_ALL_DEVICES = 2
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_SCOPE_COUNT = 3
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_SCOPE_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityUnifiedMemoryCounterKind::UInt32 begin
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_UNKNOWN = 0
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_BYTES_TRANSFER_HTOD = 1
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_BYTES_TRANSFER_DTOH = 2
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_CPU_PAGE_FAULT_COUNT = 3
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_GPU_PAGE_FAULT = 4
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_THRASHING = 5
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_THROTTLING = 6
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_REMOTE_MAP = 7
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_BYTES_TRANSFER_DTOD = 8
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_COUNT = 9
    CUPTI_ACTIVITY_UNIFIED_MEMORY_COUNTER_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityUnifiedMemoryAccessType::UInt32 begin
    CUPTI_ACTIVITY_UNIFIED_MEMORY_ACCESS_TYPE_UNKNOWN = 0
    CUPTI_ACTIVITY_UNIFIED_MEMORY_ACCESS_TYPE_READ = 1
    CUPTI_ACTIVITY_UNIFIED_MEMORY_ACCESS_TYPE_WRITE = 2
    CUPTI_ACTIVITY_UNIFIED_MEMORY_ACCESS_TYPE_ATOMIC = 3
    CUPTI_ACTIVITY_UNIFIED_MEMORY_ACCESS_TYPE_PREFETCH = 4
end

@cenum CUpti_ActivityUnifiedMemoryMigrationCause::UInt32 begin
    CUPTI_ACTIVITY_UNIFIED_MEMORY_MIGRATION_CAUSE_UNKNOWN = 0
    CUPTI_ACTIVITY_UNIFIED_MEMORY_MIGRATION_CAUSE_USER = 1
    CUPTI_ACTIVITY_UNIFIED_MEMORY_MIGRATION_CAUSE_COHERENCE = 2
    CUPTI_ACTIVITY_UNIFIED_MEMORY_MIGRATION_CAUSE_PREFETCH = 3
    CUPTI_ACTIVITY_UNIFIED_MEMORY_MIGRATION_CAUSE_EVICTION = 4
    CUPTI_ACTIVITY_UNIFIED_MEMORY_MIGRATION_CAUSE_ACCESS_COUNTERS = 5
end

@cenum CUpti_ActivityUnifiedMemoryRemoteMapCause::UInt32 begin
    CUPTI_ACTIVITY_UNIFIED_MEMORY_REMOTE_MAP_CAUSE_UNKNOWN = 0
    CUPTI_ACTIVITY_UNIFIED_MEMORY_REMOTE_MAP_CAUSE_COHERENCE = 1
    CUPTI_ACTIVITY_UNIFIED_MEMORY_REMOTE_MAP_CAUSE_THRASHING = 2
    CUPTI_ACTIVITY_UNIFIED_MEMORY_REMOTE_MAP_CAUSE_POLICY = 3
    CUPTI_ACTIVITY_UNIFIED_MEMORY_REMOTE_MAP_CAUSE_OUT_OF_MEMORY = 4
    CUPTI_ACTIVITY_UNIFIED_MEMORY_REMOTE_MAP_CAUSE_EVICTION = 5
end

@cenum CUpti_ActivityInstructionClass::UInt32 begin
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_UNKNOWN = 0
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_FP_32 = 1
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_FP_64 = 2
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_INTEGER = 3
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_BIT_CONVERSION = 4
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_CONTROL_FLOW = 5
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_GLOBAL = 6
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_SHARED = 7
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_LOCAL = 8
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_GENERIC = 9
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_SURFACE = 10
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_CONSTANT = 11
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_TEXTURE = 12
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_GLOBAL_ATOMIC = 13
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_SHARED_ATOMIC = 14
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_SURFACE_ATOMIC = 15
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_INTER_THREAD_COMMUNICATION = 16
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_BARRIER = 17
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_MISCELLANEOUS = 18
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_FP_16 = 19
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_UNIFORM = 20
    CUPTI_ACTIVITY_INSTRUCTION_CLASS_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityPartitionedGlobalCacheConfig::UInt32 begin
    CUPTI_ACTIVITY_PARTITIONED_GLOBAL_CACHE_CONFIG_UNKNOWN = 0
    CUPTI_ACTIVITY_PARTITIONED_GLOBAL_CACHE_CONFIG_NOT_SUPPORTED = 1
    CUPTI_ACTIVITY_PARTITIONED_GLOBAL_CACHE_CONFIG_OFF = 2
    CUPTI_ACTIVITY_PARTITIONED_GLOBAL_CACHE_CONFIG_ON = 3
    CUPTI_ACTIVITY_PARTITIONED_GLOBAL_CACHE_CONFIG_FORCE_INT = 2147483647
end

@cenum CUpti_ActivitySynchronizationType::UInt32 begin
    CUPTI_ACTIVITY_SYNCHRONIZATION_TYPE_UNKNOWN = 0
    CUPTI_ACTIVITY_SYNCHRONIZATION_TYPE_EVENT_SYNCHRONIZE = 1
    CUPTI_ACTIVITY_SYNCHRONIZATION_TYPE_STREAM_WAIT_EVENT = 2
    CUPTI_ACTIVITY_SYNCHRONIZATION_TYPE_STREAM_SYNCHRONIZE = 3
    CUPTI_ACTIVITY_SYNCHRONIZATION_TYPE_CONTEXT_SYNCHRONIZE = 4
    CUPTI_ACTIVITY_SYNCHRONIZATION_TYPE_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityStreamFlag::UInt32 begin
    CUPTI_ACTIVITY_STREAM_CREATE_FLAG_UNKNOWN = 0
    CUPTI_ACTIVITY_STREAM_CREATE_FLAG_DEFAULT = 1
    CUPTI_ACTIVITY_STREAM_CREATE_FLAG_NON_BLOCKING = 2
    CUPTI_ACTIVITY_STREAM_CREATE_FLAG_NULL = 3
    CUPTI_ACTIVITY_STREAM_CREATE_MASK = 65535
    CUPTI_ACTIVITY_STREAM_CREATE_FLAG_FORCE_INT = 2147483647
end

@cenum CUpti_LinkFlag::UInt32 begin
    CUPTI_LINK_FLAG_INVALID = 0
    CUPTI_LINK_FLAG_PEER_ACCESS = 2
    CUPTI_LINK_FLAG_SYSMEM_ACCESS = 4
    CUPTI_LINK_FLAG_PEER_ATOMICS = 8
    CUPTI_LINK_FLAG_SYSMEM_ATOMICS = 16
    CUPTI_LINK_FLAG_FORCE_INT = 2147483647
end

struct CUpti_ActivityUnifiedMemoryCounterConfig
    scope::CUpti_ActivityUnifiedMemoryCounterScope
    kind::CUpti_ActivityUnifiedMemoryCounterKind
    deviceId::UInt32
    enable::UInt32
end

struct CUpti_ActivityAutoBoostState
    enabled::UInt32
    pid::UInt32
end

struct CUpti_ActivityPCSamplingConfig
    size::UInt32
    samplingPeriod::CUpti_ActivityPCSamplingPeriod
    samplingPeriod2::UInt32
end

struct CUpti_Activity
    kind::CUpti_ActivityKind
end

struct CUpti_ActivityMemcpy
    kind::CUpti_ActivityKind
    copyKind::UInt8
    srcKind::UInt8
    dstKind::UInt8
    flags::UInt8
    bytes::UInt64
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    correlationId::UInt32
    runtimeCorrelationId::UInt32
    pad::UInt32
    reserved0::Ptr{Cvoid}
end

struct CUpti_ActivityMemcpy3
    kind::CUpti_ActivityKind
    copyKind::UInt8
    srcKind::UInt8
    dstKind::UInt8
    flags::UInt8
    bytes::UInt64
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    correlationId::UInt32
    runtimeCorrelationId::UInt32
    pad::UInt32
    reserved0::Ptr{Cvoid}
    graphNodeId::UInt64
end

struct CUpti_ActivityMemcpyPtoP
    kind::CUpti_ActivityKind
    copyKind::UInt8
    srcKind::UInt8
    dstKind::UInt8
    flags::UInt8
    bytes::UInt64
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    srcDeviceId::UInt32
    srcContextId::UInt32
    dstDeviceId::UInt32
    dstContextId::UInt32
    correlationId::UInt32
    reserved0::Ptr{Cvoid}
end

const CUpti_ActivityMemcpy2 = CUpti_ActivityMemcpyPtoP

struct CUpti_ActivityMemcpyPtoP2
    kind::CUpti_ActivityKind
    copyKind::UInt8
    srcKind::UInt8
    dstKind::UInt8
    flags::UInt8
    bytes::UInt64
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    srcDeviceId::UInt32
    srcContextId::UInt32
    dstDeviceId::UInt32
    dstContextId::UInt32
    correlationId::UInt32
    reserved0::Ptr{Cvoid}
    graphNodeId::UInt64
end

struct CUpti_ActivityMemset
    kind::CUpti_ActivityKind
    value::UInt32
    bytes::UInt64
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    correlationId::UInt32
    flags::UInt16
    memoryKind::UInt16
    pad::UInt32
    reserved0::Ptr{Cvoid}
end

struct CUpti_ActivityMemset2
    kind::CUpti_ActivityKind
    value::UInt32
    bytes::UInt64
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    correlationId::UInt32
    flags::UInt16
    memoryKind::UInt16
    pad::UInt32
    reserved0::Ptr{Cvoid}
    graphNodeId::UInt64
end

struct CUpti_ActivityMemory
    kind::CUpti_ActivityKind
    memoryKind::CUpti_ActivityMemoryKind
    address::UInt64
    bytes::UInt64
    start::UInt64
    _end::UInt64
    allocPC::UInt64
    freePC::UInt64
    processId::UInt32
    deviceId::UInt32
    contextId::UInt32
    pad::UInt32
    name::Cstring
end

struct CUpti_ActivityKernel
    kind::CUpti_ActivityKind
    cacheConfigRequested::UInt8
    cacheConfigExecuted::UInt8
    registersPerThread::UInt16
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    gridX::Int32
    gridY::Int32
    gridZ::Int32
    blockX::Int32
    blockY::Int32
    blockZ::Int32
    staticSharedMemory::Int32
    dynamicSharedMemory::Int32
    localMemoryPerThread::UInt32
    localMemoryTotal::UInt32
    correlationId::UInt32
    runtimeCorrelationId::UInt32
    pad::UInt32
    name::Cstring
    reserved0::Ptr{Cvoid}
end

struct ANONYMOUS3_cacheConfig
    both::UInt8
end

struct CUpti_ActivityKernel2
    kind::CUpti_ActivityKind
    cacheConfig::ANONYMOUS3_cacheConfig
    sharedMemoryConfig::UInt8
    registersPerThread::UInt16
    start::UInt64
    _end::UInt64
    completed::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    gridX::Int32
    gridY::Int32
    gridZ::Int32
    blockX::Int32
    blockY::Int32
    blockZ::Int32
    staticSharedMemory::Int32
    dynamicSharedMemory::Int32
    localMemoryPerThread::UInt32
    localMemoryTotal::UInt32
    correlationId::UInt32
    gridId::Int64
    name::Cstring
    reserved0::Ptr{Cvoid}
end

struct ANONYMOUS4_cacheConfig
    both::UInt8
end

struct CUpti_ActivityKernel3
    kind::CUpti_ActivityKind
    cacheConfig::ANONYMOUS4_cacheConfig
    sharedMemoryConfig::UInt8
    registersPerThread::UInt16
    partitionedGlobalCacheRequested::CUpti_ActivityPartitionedGlobalCacheConfig
    partitionedGlobalCacheExecuted::CUpti_ActivityPartitionedGlobalCacheConfig
    start::UInt64
    _end::UInt64
    completed::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    gridX::Int32
    gridY::Int32
    gridZ::Int32
    blockX::Int32
    blockY::Int32
    blockZ::Int32
    staticSharedMemory::Int32
    dynamicSharedMemory::Int32
    localMemoryPerThread::UInt32
    localMemoryTotal::UInt32
    correlationId::UInt32
    gridId::Int64
    name::Cstring
    reserved0::Ptr{Cvoid}
end

@cenum CUpti_ActivityLaunchType::UInt32 begin
    CUPTI_ACTIVITY_LAUNCH_TYPE_REGULAR = 0
    CUPTI_ACTIVITY_LAUNCH_TYPE_COOPERATIVE_SINGLE_DEVICE = 1
    CUPTI_ACTIVITY_LAUNCH_TYPE_COOPERATIVE_MULTI_DEVICE = 2
end

struct ANONYMOUS5_cacheConfig
    both::UInt8
end

struct CUpti_ActivityKernel4
    kind::CUpti_ActivityKind
    cacheConfig::ANONYMOUS5_cacheConfig
    sharedMemoryConfig::UInt8
    registersPerThread::UInt16
    partitionedGlobalCacheRequested::CUpti_ActivityPartitionedGlobalCacheConfig
    partitionedGlobalCacheExecuted::CUpti_ActivityPartitionedGlobalCacheConfig
    start::UInt64
    _end::UInt64
    completed::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    gridX::Int32
    gridY::Int32
    gridZ::Int32
    blockX::Int32
    blockY::Int32
    blockZ::Int32
    staticSharedMemory::Int32
    dynamicSharedMemory::Int32
    localMemoryPerThread::UInt32
    localMemoryTotal::UInt32
    correlationId::UInt32
    gridId::Int64
    name::Cstring
    reserved0::Ptr{Cvoid}
    queued::UInt64
    submitted::UInt64
    launchType::UInt8
    isSharedMemoryCarveoutRequested::UInt8
    sharedMemoryCarveoutRequested::UInt8
    padding::UInt8
    sharedMemoryExecuted::UInt32
end

@cenum CUpti_FuncShmemLimitConfig::UInt32 begin
    CUPTI_FUNC_SHMEM_LIMIT_DEFAULT = 0
    CUPTI_FUNC_SHMEM_LIMIT_OPTIN = 1
    CUPTI_FUNC_SHMEM_LIMIT_FORCE_INT = 2147483647
end

struct ANONYMOUS6_cacheConfig
    both::UInt8
end

struct CUpti_ActivityKernel5
    kind::CUpti_ActivityKind
    cacheConfig::ANONYMOUS6_cacheConfig
    sharedMemoryConfig::UInt8
    registersPerThread::UInt16
    partitionedGlobalCacheRequested::CUpti_ActivityPartitionedGlobalCacheConfig
    partitionedGlobalCacheExecuted::CUpti_ActivityPartitionedGlobalCacheConfig
    start::UInt64
    _end::UInt64
    completed::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    gridX::Int32
    gridY::Int32
    gridZ::Int32
    blockX::Int32
    blockY::Int32
    blockZ::Int32
    staticSharedMemory::Int32
    dynamicSharedMemory::Int32
    localMemoryPerThread::UInt32
    localMemoryTotal::UInt32
    correlationId::UInt32
    gridId::Int64
    name::Cstring
    reserved0::Ptr{Cvoid}
    queued::UInt64
    submitted::UInt64
    launchType::UInt8
    isSharedMemoryCarveoutRequested::UInt8
    sharedMemoryCarveoutRequested::UInt8
    padding::UInt8
    sharedMemoryExecuted::UInt32
    graphNodeId::UInt64
    shmemLimitConfig::CUpti_FuncShmemLimitConfig
    padding2::UInt32
end

struct ANONYMOUS7_cacheConfig
    both::UInt8
end

struct CUpti_ActivityCdpKernel
    kind::CUpti_ActivityKind
    cacheConfig::ANONYMOUS7_cacheConfig
    sharedMemoryConfig::UInt8
    registersPerThread::UInt16
    start::UInt64
    _end::UInt64
    deviceId::UInt32
    contextId::UInt32
    streamId::UInt32
    gridX::Int32
    gridY::Int32
    gridZ::Int32
    blockX::Int32
    blockY::Int32
    blockZ::Int32
    staticSharedMemory::Int32
    dynamicSharedMemory::Int32
    localMemoryPerThread::UInt32
    localMemoryTotal::UInt32
    correlationId::UInt32
    gridId::Int64
    parentGridId::Int64
    queued::UInt64
    submitted::UInt64
    completed::UInt64
    parentBlockX::UInt32
    parentBlockY::UInt32
    parentBlockZ::UInt32
    pad::UInt32
    name::Cstring
end

struct CUpti_ActivityPreemption
    kind::CUpti_ActivityKind
    preemptionKind::CUpti_ActivityPreemptionKind
    timestamp::UInt64
    gridId::Int64
    blockX::UInt32
    blockY::UInt32
    blockZ::UInt32
    pad::UInt32
end

struct CUpti_ActivityAPI
    kind::CUpti_ActivityKind
    cbid::CUpti_CallbackId
    start::UInt64
    _end::UInt64
    processId::UInt32
    threadId::UInt32
    correlationId::UInt32
    returnValue::UInt32
end

struct CUpti_ActivityEvent
    kind::CUpti_ActivityKind
    id::CUpti_EventID
    value::UInt64
    domain::CUpti_EventDomainID
    correlationId::UInt32
end

struct CUpti_ActivityEventInstance
    kind::CUpti_ActivityKind
    id::CUpti_EventID
    domain::CUpti_EventDomainID
    instance::UInt32
    value::UInt64
    correlationId::UInt32
    pad::UInt32
end

struct CUpti_ActivityMetric
    kind::CUpti_ActivityKind
    id::CUpti_MetricID
    value::CUpti_MetricValue
    correlationId::UInt32
    flags::UInt8
    pad::NTuple{3, UInt8}
end

struct CUpti_ActivityMetricInstance
    kind::CUpti_ActivityKind
    id::CUpti_MetricID
    value::CUpti_MetricValue
    instance::UInt32
    correlationId::UInt32
    flags::UInt8
    pad::NTuple{7, UInt8}
end

struct CUpti_ActivitySourceLocator
    kind::CUpti_ActivityKind
    id::UInt32
    lineNumber::UInt32
    pad::UInt32
    fileName::Cstring
end

struct CUpti_ActivityGlobalAccess
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    pcOffset::UInt32
    executed::UInt32
    threadsExecuted::UInt64
    l2_transactions::UInt64
end

struct CUpti_ActivityGlobalAccess2
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    pcOffset::UInt32
    threadsExecuted::UInt64
    l2_transactions::UInt64
    theoreticalL2Transactions::UInt64
    executed::UInt32
    pad::UInt32
end

struct CUpti_ActivityGlobalAccess3
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    executed::UInt32
    pcOffset::UInt64
    threadsExecuted::UInt64
    l2_transactions::UInt64
    theoreticalL2Transactions::UInt64
end

struct CUpti_ActivityBranch
    kind::CUpti_ActivityKind
    sourceLocatorId::UInt32
    correlationId::UInt32
    pcOffset::UInt32
    executed::UInt32
    diverged::UInt32
    threadsExecuted::UInt64
end

struct CUpti_ActivityBranch2
    kind::CUpti_ActivityKind
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    pcOffset::UInt32
    diverged::UInt32
    threadsExecuted::UInt64
    executed::UInt32
    pad::UInt32
end

struct CUpti_ActivityDevice
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    globalMemoryBandwidth::UInt64
    globalMemorySize::UInt64
    constantMemorySize::UInt32
    l2CacheSize::UInt32
    numThreadsPerWarp::UInt32
    coreClockRate::UInt32
    numMemcpyEngines::UInt32
    numMultiprocessors::UInt32
    maxIPC::UInt32
    maxWarpsPerMultiprocessor::UInt32
    maxBlocksPerMultiprocessor::UInt32
    maxRegistersPerBlock::UInt32
    maxSharedMemoryPerBlock::UInt32
    maxThreadsPerBlock::UInt32
    maxBlockDimX::UInt32
    maxBlockDimY::UInt32
    maxBlockDimZ::UInt32
    maxGridDimX::UInt32
    maxGridDimY::UInt32
    maxGridDimZ::UInt32
    computeCapabilityMajor::UInt32
    computeCapabilityMinor::UInt32
    id::UInt32
    pad::UInt32
    name::Cstring
end

struct CUpti_ActivityDevice2
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    globalMemoryBandwidth::UInt64
    globalMemorySize::UInt64
    constantMemorySize::UInt32
    l2CacheSize::UInt32
    numThreadsPerWarp::UInt32
    coreClockRate::UInt32
    numMemcpyEngines::UInt32
    numMultiprocessors::UInt32
    maxIPC::UInt32
    maxWarpsPerMultiprocessor::UInt32
    maxBlocksPerMultiprocessor::UInt32
    maxSharedMemoryPerMultiprocessor::UInt32
    maxRegistersPerMultiprocessor::UInt32
    maxRegistersPerBlock::UInt32
    maxSharedMemoryPerBlock::UInt32
    maxThreadsPerBlock::UInt32
    maxBlockDimX::UInt32
    maxBlockDimY::UInt32
    maxBlockDimZ::UInt32
    maxGridDimX::UInt32
    maxGridDimY::UInt32
    maxGridDimZ::UInt32
    computeCapabilityMajor::UInt32
    computeCapabilityMinor::UInt32
    id::UInt32
    eccEnabled::UInt32
    uuid::CUuuid
    name::Cstring
end

struct ANONYMOUS8_attribute
    cu::CUdevice_attribute
end

struct ANONYMOUS9_value
    vDouble::Cdouble
end

struct CUpti_ActivityDeviceAttribute
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    deviceId::UInt32
    attribute::ANONYMOUS8_attribute
    value::ANONYMOUS9_value
end

struct CUpti_ActivityContext
    kind::CUpti_ActivityKind
    contextId::UInt32
    deviceId::UInt32
    computeApiKind::UInt16
    nullStreamId::UInt16
end

struct CUpti_ActivityName
    kind::CUpti_ActivityKind
    objectKind::CUpti_ActivityObjectKind
    objectId::CUpti_ActivityObjectKindId
    pad::UInt32
    name::Cstring
end

struct CUpti_ActivityMarker
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    timestamp::UInt64
    id::UInt32
    objectKind::CUpti_ActivityObjectKind
    objectId::CUpti_ActivityObjectKindId
    pad::UInt32
    name::Cstring
end

struct CUpti_ActivityMarker2
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    timestamp::UInt64
    id::UInt32
    objectKind::CUpti_ActivityObjectKind
    objectId::CUpti_ActivityObjectKindId
    pad::UInt32
    name::Cstring
    domain::Cstring
end

struct CUpti_ActivityMarkerData
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    id::UInt32
    payloadKind::CUpti_MetricValueKind
    payload::CUpti_MetricValue
    color::UInt32
    category::UInt32
end

struct CUpti_ActivityOverhead
    kind::CUpti_ActivityKind
    overheadKind::CUpti_ActivityOverheadKind
    objectKind::CUpti_ActivityObjectKind
    objectId::CUpti_ActivityObjectKindId
    start::UInt64
    _end::UInt64
end

struct ANONYMOUS11_speed
    smClock::UInt32
    memoryClock::UInt32
    pcieLinkGen::UInt32
    pcieLinkWidth::UInt32
    clocksThrottleReasons::CUpti_EnvironmentClocksThrottleReason
end

struct ANONYMOUS10_data
    speed::ANONYMOUS11_speed
end

struct CUpti_ActivityEnvironment
    kind::CUpti_ActivityKind
    deviceId::UInt32
    timestamp::UInt64
    environmentKind::CUpti_ActivityEnvironmentKind
    data::ANONYMOUS10_data
end

struct CUpti_ActivityInstructionExecution
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    pcOffset::UInt32
    threadsExecuted::UInt64
    notPredOffThreadsExecuted::UInt64
    executed::UInt32
    pad::UInt32
end

struct CUpti_ActivityPCSampling
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    pcOffset::UInt32
    samples::UInt32
    stallReason::CUpti_ActivityPCSamplingStallReason
end

struct CUpti_ActivityPCSampling2
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    pcOffset::UInt32
    latencySamples::UInt32
    samples::UInt32
    stallReason::CUpti_ActivityPCSamplingStallReason
    pad::UInt32
end

struct CUpti_ActivityPCSampling3
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    latencySamples::UInt32
    samples::UInt32
    stallReason::CUpti_ActivityPCSamplingStallReason
    pcOffset::UInt64
end

struct CUpti_ActivityPCSamplingRecordInfo
    kind::CUpti_ActivityKind
    correlationId::UInt32
    totalSamples::UInt64
    droppedSamples::UInt64
    samplingPeriodInCycles::UInt64
end

struct CUpti_ActivityUnifiedMemoryCounter
    kind::CUpti_ActivityKind
    counterKind::CUpti_ActivityUnifiedMemoryCounterKind
    scope::CUpti_ActivityUnifiedMemoryCounterScope
    deviceId::UInt32
    value::UInt64
    timestamp::UInt64
    processId::UInt32
    pad::UInt32
end

struct CUpti_ActivityUnifiedMemoryCounter2
    kind::CUpti_ActivityKind
    counterKind::CUpti_ActivityUnifiedMemoryCounterKind
    value::UInt64
    start::UInt64
    _end::UInt64
    address::UInt64
    srcId::UInt32
    dstId::UInt32
    streamId::UInt32
    processId::UInt32
    flags::UInt32
    pad::UInt32
end

struct CUpti_ActivityFunction
    kind::CUpti_ActivityKind
    id::UInt32
    contextId::UInt32
    moduleId::UInt32
    functionIndex::UInt32
    pad::UInt32
    name::Cstring
end

struct CUpti_ActivityModule
    kind::CUpti_ActivityKind
    contextId::UInt32
    id::UInt32
    cubinSize::UInt32
    cubin::Ptr{Cvoid}
end

struct CUpti_ActivitySharedAccess
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    correlationId::UInt32
    functionId::UInt32
    pcOffset::UInt32
    threadsExecuted::UInt64
    sharedTransactions::UInt64
    theoreticalSharedTransactions::UInt64
    executed::UInt32
    pad::UInt32
end

struct CUpti_ActivityCudaEvent
    kind::CUpti_ActivityKind
    correlationId::UInt32
    contextId::UInt32
    streamId::UInt32
    eventId::UInt32
    pad::UInt32
end

struct CUpti_ActivityStream
    kind::CUpti_ActivityKind
    contextId::UInt32
    streamId::UInt32
    priority::UInt32
    flag::CUpti_ActivityStreamFlag
    correlationId::UInt32
end

struct CUpti_ActivitySynchronization
    kind::CUpti_ActivityKind
    type::CUpti_ActivitySynchronizationType
    start::UInt64
    _end::UInt64
    correlationId::UInt32
    contextId::UInt32
    streamId::UInt32
    cudaEventId::UInt32
end

struct CUpti_ActivityInstructionCorrelation
    kind::CUpti_ActivityKind
    flags::CUpti_ActivityFlag
    sourceLocatorId::UInt32
    functionId::UInt32
    pcOffset::UInt32
    pad::UInt32
end

@cenum CUpti_OpenAccEventKind::UInt32 begin
    CUPTI_OPENACC_EVENT_KIND_INVALID = 0
    CUPTI_OPENACC_EVENT_KIND_DEVICE_INIT = 1
    CUPTI_OPENACC_EVENT_KIND_DEVICE_SHUTDOWN = 2
    CUPTI_OPENACC_EVENT_KIND_RUNTIME_SHUTDOWN = 3
    CUPTI_OPENACC_EVENT_KIND_ENQUEUE_LAUNCH = 4
    CUPTI_OPENACC_EVENT_KIND_ENQUEUE_UPLOAD = 5
    CUPTI_OPENACC_EVENT_KIND_ENQUEUE_DOWNLOAD = 6
    CUPTI_OPENACC_EVENT_KIND_WAIT = 7
    CUPTI_OPENACC_EVENT_KIND_IMPLICIT_WAIT = 8
    CUPTI_OPENACC_EVENT_KIND_COMPUTE_CONSTRUCT = 9
    CUPTI_OPENACC_EVENT_KIND_UPDATE = 10
    CUPTI_OPENACC_EVENT_KIND_ENTER_DATA = 11
    CUPTI_OPENACC_EVENT_KIND_EXIT_DATA = 12
    CUPTI_OPENACC_EVENT_KIND_CREATE = 13
    CUPTI_OPENACC_EVENT_KIND_DELETE = 14
    CUPTI_OPENACC_EVENT_KIND_ALLOC = 15
    CUPTI_OPENACC_EVENT_KIND_FREE = 16
    CUPTI_OPENACC_EVENT_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_OpenAccConstructKind::UInt32 begin
    CUPTI_OPENACC_CONSTRUCT_KIND_UNKNOWN = 0
    CUPTI_OPENACC_CONSTRUCT_KIND_PARALLEL = 1
    CUPTI_OPENACC_CONSTRUCT_KIND_KERNELS = 2
    CUPTI_OPENACC_CONSTRUCT_KIND_LOOP = 3
    CUPTI_OPENACC_CONSTRUCT_KIND_DATA = 4
    CUPTI_OPENACC_CONSTRUCT_KIND_ENTER_DATA = 5
    CUPTI_OPENACC_CONSTRUCT_KIND_EXIT_DATA = 6
    CUPTI_OPENACC_CONSTRUCT_KIND_HOST_DATA = 7
    CUPTI_OPENACC_CONSTRUCT_KIND_ATOMIC = 8
    CUPTI_OPENACC_CONSTRUCT_KIND_DECLARE = 9
    CUPTI_OPENACC_CONSTRUCT_KIND_INIT = 10
    CUPTI_OPENACC_CONSTRUCT_KIND_SHUTDOWN = 11
    CUPTI_OPENACC_CONSTRUCT_KIND_SET = 12
    CUPTI_OPENACC_CONSTRUCT_KIND_UPDATE = 13
    CUPTI_OPENACC_CONSTRUCT_KIND_ROUTINE = 14
    CUPTI_OPENACC_CONSTRUCT_KIND_WAIT = 15
    CUPTI_OPENACC_CONSTRUCT_KIND_RUNTIME_API = 16
    CUPTI_OPENACC_CONSTRUCT_KIND_FORCE_INT = 2147483647
end

@cenum CUpti_OpenMpEventKind::UInt32 begin
    CUPTI_OPENMP_EVENT_KIND_INVALID = 0
    CUPTI_OPENMP_EVENT_KIND_PARALLEL = 1
    CUPTI_OPENMP_EVENT_KIND_TASK = 2
    CUPTI_OPENMP_EVENT_KIND_THREAD = 3
    CUPTI_OPENMP_EVENT_KIND_IDLE = 4
    CUPTI_OPENMP_EVENT_KIND_WAIT_BARRIER = 5
    CUPTI_OPENMP_EVENT_KIND_WAIT_TASKWAIT = 6
    CUPTI_OPENMP_EVENT_KIND_FORCE_INT = 2147483647
end

struct CUpti_ActivityOpenAcc
    kind::CUpti_ActivityKind
    eventKind::CUpti_OpenAccEventKind
    parentConstruct::CUpti_OpenAccConstructKind
    version::UInt32
    implicit::UInt32
    deviceType::UInt32
    deviceNumber::UInt32
    threadId::UInt32
    async::UInt64
    asyncMap::UInt64
    lineNo::UInt32
    endLineNo::UInt32
    funcLineNo::UInt32
    funcEndLineNo::UInt32
    start::UInt64
    _end::UInt64
    cuDeviceId::UInt32
    cuContextId::UInt32
    cuStreamId::UInt32
    cuProcessId::UInt32
    cuThreadId::UInt32
    externalId::UInt32
    srcFile::Cstring
    funcName::Cstring
end

struct CUpti_ActivityOpenAccData
    kind::CUpti_ActivityKind
    eventKind::CUpti_OpenAccEventKind
    parentConstruct::CUpti_OpenAccConstructKind
    version::UInt32
    implicit::UInt32
    deviceType::UInt32
    deviceNumber::UInt32
    threadId::UInt32
    async::UInt64
    asyncMap::UInt64
    lineNo::UInt32
    endLineNo::UInt32
    funcLineNo::UInt32
    funcEndLineNo::UInt32
    start::UInt64
    _end::UInt64
    cuDeviceId::UInt32
    cuContextId::UInt32
    cuStreamId::UInt32
    cuProcessId::UInt32
    cuThreadId::UInt32
    externalId::UInt32
    srcFile::Cstring
    funcName::Cstring
    bytes::UInt64
    hostPtr::UInt64
    devicePtr::UInt64
    varName::Cstring
end

struct CUpti_ActivityOpenAccLaunch
    kind::CUpti_ActivityKind
    eventKind::CUpti_OpenAccEventKind
    parentConstruct::CUpti_OpenAccConstructKind
    version::UInt32
    implicit::UInt32
    deviceType::UInt32
    deviceNumber::UInt32
    threadId::UInt32
    async::UInt64
    asyncMap::UInt64
    lineNo::UInt32
    endLineNo::UInt32
    funcLineNo::UInt32
    funcEndLineNo::UInt32
    start::UInt64
    _end::UInt64
    cuDeviceId::UInt32
    cuContextId::UInt32
    cuStreamId::UInt32
    cuProcessId::UInt32
    cuThreadId::UInt32
    externalId::UInt32
    srcFile::Cstring
    funcName::Cstring
    numGangs::UInt64
    numWorkers::UInt64
    vectorLength::UInt64
    kernelName::Cstring
end

struct CUpti_ActivityOpenAccOther
    kind::CUpti_ActivityKind
    eventKind::CUpti_OpenAccEventKind
    parentConstruct::CUpti_OpenAccConstructKind
    version::UInt32
    implicit::UInt32
    deviceType::UInt32
    deviceNumber::UInt32
    threadId::UInt32
    async::UInt64
    asyncMap::UInt64
    lineNo::UInt32
    endLineNo::UInt32
    funcLineNo::UInt32
    funcEndLineNo::UInt32
    start::UInt64
    _end::UInt64
    cuDeviceId::UInt32
    cuContextId::UInt32
    cuStreamId::UInt32
    cuProcessId::UInt32
    cuThreadId::UInt32
    externalId::UInt32
    srcFile::Cstring
    funcName::Cstring
end

struct CUpti_ActivityOpenMp
    kind::CUpti_ActivityKind
    eventKind::CUpti_OpenMpEventKind
    version::UInt32
    threadId::UInt32
    start::UInt64
    _end::UInt64
    cuProcessId::UInt32
    cuThreadId::UInt32
end

@cenum CUpti_ExternalCorrelationKind::UInt32 begin
    CUPTI_EXTERNAL_CORRELATION_KIND_INVALID = 0
    CUPTI_EXTERNAL_CORRELATION_KIND_UNKNOWN = 1
    CUPTI_EXTERNAL_CORRELATION_KIND_OPENACC = 2
    CUPTI_EXTERNAL_CORRELATION_KIND_CUSTOM0 = 3
    CUPTI_EXTERNAL_CORRELATION_KIND_CUSTOM1 = 4
    CUPTI_EXTERNAL_CORRELATION_KIND_CUSTOM2 = 5
    CUPTI_EXTERNAL_CORRELATION_KIND_SIZE = 6
    CUPTI_EXTERNAL_CORRELATION_KIND_FORCE_INT = 2147483647
end

struct CUpti_ActivityExternalCorrelation
    kind::CUpti_ActivityKind
    externalKind::CUpti_ExternalCorrelationKind
    externalId::UInt64
    correlationId::UInt32
    reserved::UInt32
end

@cenum CUpti_DevType::UInt32 begin
    CUPTI_DEV_TYPE_INVALID = 0
    CUPTI_DEV_TYPE_GPU = 1
    CUPTI_DEV_TYPE_NPU = 2
    CUPTI_DEV_TYPE_FORCE_INT = 2147483647
end

struct ANONYMOUS12_idDev0
    uuidDev::CUuuid
end

struct ANONYMOUS13_idDev1
    uuidDev::CUuuid
end

struct CUpti_ActivityNvLink
    kind::CUpti_ActivityKind
    nvlinkVersion::UInt32
    typeDev0::CUpti_DevType
    typeDev1::CUpti_DevType
    idDev0::ANONYMOUS12_idDev0
    idDev1::ANONYMOUS13_idDev1
    flag::UInt32
    physicalNvLinkCount::UInt32
    portDev0::NTuple{4, Int8}
    portDev1::NTuple{4, Int8}
    bandwidth::UInt64
end

struct ANONYMOUS14_idDev0
    uuidDev::CUuuid
end

struct ANONYMOUS15_idDev1
    uuidDev::CUuuid
end

struct CUpti_ActivityNvLink2
    kind::CUpti_ActivityKind
    nvlinkVersion::UInt32
    typeDev0::CUpti_DevType
    typeDev1::CUpti_DevType
    idDev0::ANONYMOUS14_idDev0
    idDev1::ANONYMOUS15_idDev1
    flag::UInt32
    physicalNvLinkCount::UInt32
    portDev0::NTuple{16, Int8}
    portDev1::NTuple{16, Int8}
    bandwidth::UInt64
end

struct ANONYMOUS16_idDev0
    uuidDev::CUuuid
end

struct ANONYMOUS17_idDev1
    uuidDev::CUuuid
end

struct CUpti_ActivityNvLink3
    kind::CUpti_ActivityKind
    nvlinkVersion::UInt32
    typeDev0::CUpti_DevType
    typeDev1::CUpti_DevType
    idDev0::ANONYMOUS16_idDev0
    idDev1::ANONYMOUS17_idDev1
    flag::UInt32
    physicalNvLinkCount::UInt32
    portDev0::NTuple{16, Int8}
    portDev1::NTuple{16, Int8}
    bandwidth::UInt64
    nvswitchConnected::UInt8
    pad::NTuple{7, UInt8}
end

@cenum CUpti_PcieDeviceType::UInt32 begin
    CUPTI_PCIE_DEVICE_TYPE_GPU = 0
    CUPTI_PCIE_DEVICE_TYPE_BRIDGE = 1
    CUPTI_PCIE_DEVICE_TYPE_FORCE_INT = 2147483647
end

struct ANONYMOUS18_id
    devId::CUdevice
end

struct ANONYMOUS20_gpuAttr
    uuidDev::CUuuid
    peerDev::NTuple{32, CUdevice}
end

struct ANONYMOUS19_attr
    gpuAttr::ANONYMOUS20_gpuAttr
end

struct CUpti_ActivityPcie
    kind::CUpti_ActivityKind
    type::CUpti_PcieDeviceType
    id::ANONYMOUS18_id
    domain::UInt32
    pcieGeneration::UInt16
    linkRate::UInt16
    linkWidth::UInt16
    upstreamBus::UInt16
    attr::ANONYMOUS19_attr
end

@cenum CUpti_PcieGen::UInt32 begin
    CUPTI_PCIE_GEN_GEN1 = 1
    CUPTI_PCIE_GEN_GEN2 = 2
    CUPTI_PCIE_GEN_GEN3 = 3
    CUPTI_PCIE_GEN_GEN4 = 4
    CUPTI_PCIE_GEN_FORCE_INT = 2147483647
end

struct CUpti_ActivityInstantaneousEvent
    kind::CUpti_ActivityKind
    id::CUpti_EventID
    value::UInt64
    timestamp::UInt64
    deviceId::UInt32
    reserved::UInt32
end

struct CUpti_ActivityInstantaneousEventInstance
    kind::CUpti_ActivityKind
    id::CUpti_EventID
    value::UInt64
    timestamp::UInt64
    deviceId::UInt32
    instance::UInt8
    pad::NTuple{3, UInt8}
end

struct CUpti_ActivityInstantaneousMetric
    kind::CUpti_ActivityKind
    id::CUpti_MetricID
    value::CUpti_MetricValue
    timestamp::UInt64
    deviceId::UInt32
    flags::UInt8
    pad::NTuple{3, UInt8}
end

struct CUpti_ActivityInstantaneousMetricInstance
    kind::CUpti_ActivityKind
    id::CUpti_MetricID
    value::CUpti_MetricValue
    timestamp::UInt64
    deviceId::UInt32
    flags::UInt8
    instance::UInt8
    pad::NTuple{2, UInt8}
end

@cenum CUpti_ActivityAttribute::UInt32 begin
    CUPTI_ACTIVITY_ATTR_DEVICE_BUFFER_SIZE = 0
    CUPTI_ACTIVITY_ATTR_DEVICE_BUFFER_SIZE_CDP = 1
    CUPTI_ACTIVITY_ATTR_DEVICE_BUFFER_POOL_LIMIT = 2
    CUPTI_ACTIVITY_ATTR_PROFILING_SEMAPHORE_POOL_SIZE = 3
    CUPTI_ACTIVITY_ATTR_PROFILING_SEMAPHORE_POOL_LIMIT = 4
    CUPTI_ACTIVITY_ATTR_ZEROED_OUT_ACTIVITY_BUFFER = 5
    CUPTI_ACTIVITY_ATTR_DEVICE_BUFFER_FORCE_INT = 2147483647
end

@cenum CUpti_ActivityThreadIdType::UInt32 begin
    CUPTI_ACTIVITY_THREAD_ID_TYPE_DEFAULT = 0
    CUPTI_ACTIVITY_THREAD_ID_TYPE_SYSTEM = 1
    CUPTI_ACTIVITY_THREAD_ID_TYPE_FORCE_INT = 2147483647
end

const CUpti_BuffersCallbackRequestFunc = Ptr{Cvoid}
const CUpti_BuffersCallbackCompleteFunc = Ptr{Cvoid}

@cenum CUpti_DeviceVirtualizationMode::UInt32 begin
    CUPTI_DEVICE_VIRTUALIZATION_MODE_NONE = 0
    CUPTI_DEVICE_VIRTUALIZATION_MODE_PASS_THROUGH = 1
    CUPTI_DEVICE_VIRTUALIZATION_MODE_VIRTUAL_GPU = 2
    CUPTI_DEVICE_VIRTUALIZATION_MODE_FORCE_INT = 2147483647
end

# Skipping MacroDefinition: CUPTI_PROFILER_STRUCT_SIZE ( type_ , lastfield_ ) ( offsetof ( type_ , lastfield_ ) + sizeof ( ( ( type_ * ) 0 ) -> lastfield_ ) )
# Skipping MacroDefinition: CUpti_Profiler_Initialize_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_Initialize_Params , pPriv )
# Skipping MacroDefinition: CUpti_Profiler_DeInitialize_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_DeInitialize_Params , pPriv )
# Skipping MacroDefinition: CUpti_Profiler_CounterDataImageOptions_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_CounterDataImageOptions , maxRangeNameLength )
# Skipping MacroDefinition: CUpti_Profiler_CounterDataImage_CalculateSize_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_CounterDataImage_CalculateSize_Params , counterDataImageSize )
# Skipping MacroDefinition: CUpti_Profiler_CounterDataImage_Initialize_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_CounterDataImage_Initialize_Params , pCounterDataImage )
# Skipping MacroDefinition: CUpti_Profiler_CounterDataImage_CalculateScratchBufferSize_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_CounterDataImage_CalculateScratchBufferSize_Params , counterDataScratchBufferSize )
# Skipping MacroDefinition: CUpti_Profiler_CounterDataImage_InitializeScratchBuffer_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_CounterDataImage_InitializeScratchBuffer_Params , pCounterDataScratchBuffer )
# Skipping MacroDefinition: CUpti_Profiler_BeginSession_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_BeginSession_Params , maxLaunchesPerPass )
# Skipping MacroDefinition: CUpti_Profiler_EndSession_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_EndSession_Params , ctx )
# Skipping MacroDefinition: CUpti_Profiler_SetConfig_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_SetConfig_Params , targetNestingLevel )
# Skipping MacroDefinition: CUpti_Profiler_UnsetConfig_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_UnsetConfig_Params , ctx )
# Skipping MacroDefinition: CUpti_Profiler_BeginPass_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_BeginPass_Params , ctx )
# Skipping MacroDefinition: CUpti_Profiler_EndPass_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_EndPass_Params , allPassesSubmitted )
# Skipping MacroDefinition: CUpti_Profiler_EnableProfiling_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_EnableProfiling_Params , ctx )
# Skipping MacroDefinition: CUpti_Profiler_DisableProfiling_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_DisableProfiling_Params , ctx )
# Skipping MacroDefinition: CUpti_Profiler_IsPassCollected_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_IsPassCollected_Params , allPassesCollected )
# Skipping MacroDefinition: CUpti_Profiler_FlushCounterData_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_FlushCounterData_Params , numTraceBytesDropped )
# Skipping MacroDefinition: CUpti_Profiler_PushRange_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_PushRange_Params , rangeNameLength )
# Skipping MacroDefinition: CUpti_Profiler_PopRange_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_PopRange_Params , ctx )
# Skipping MacroDefinition: CUpti_Profiler_GetCounterAvailability_Params_STRUCT_SIZE CUPTI_PROFILER_STRUCT_SIZE ( CUpti_Profiler_GetCounterAvailability_Params , pCounterAvailabilityImage )

@cenum CUpti_ProfilerRange::UInt32 begin
    CUPTI_Range_INVALID = 0
    CUPTI_AutoRange = 1
    CUPTI_UserRange = 2
    CUPTI_Range_COUNT = 3
end

@cenum CUpti_ProfilerReplayMode::UInt32 begin
    CUPTI_Replay_INVALID = 0
    CUPTI_ApplicationReplay = 1
    CUPTI_KernelReplay = 2
    CUPTI_UserReplay = 3
    CUPTI_Replay_COUNT = 4
end

struct CUpti_Profiler_Initialize_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
end

struct CUpti_Profiler_DeInitialize_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
end

struct CUpti_Profiler_CounterDataImageOptions
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    pCounterDataPrefix::Ptr{UInt8}
    counterDataPrefixSize::Csize_t
    maxNumRanges::UInt32
    maxNumRangeTreeNodes::UInt32
    maxRangeNameLength::UInt32
end

struct CUpti_Profiler_CounterDataImage_CalculateSize_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    sizeofCounterDataImageOptions::Csize_t
    pOptions::Ptr{CUpti_Profiler_CounterDataImageOptions}
    counterDataImageSize::Csize_t
end

struct CUpti_Profiler_CounterDataImage_Initialize_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    sizeofCounterDataImageOptions::Csize_t
    pOptions::Ptr{CUpti_Profiler_CounterDataImageOptions}
    counterDataImageSize::Csize_t
    pCounterDataImage::Ptr{UInt8}
end

struct CUpti_Profiler_CounterDataImage_CalculateScratchBufferSize_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    counterDataImageSize::Csize_t
    pCounterDataImage::Ptr{UInt8}
    counterDataScratchBufferSize::Csize_t
end

struct CUpti_Profiler_CounterDataImage_InitializeScratchBuffer_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    counterDataImageSize::Csize_t
    pCounterDataImage::Ptr{UInt8}
    counterDataScratchBufferSize::Csize_t
    pCounterDataScratchBuffer::Ptr{UInt8}
end

struct CUpti_Profiler_BeginSession_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
    counterDataImageSize::Csize_t
    pCounterDataImage::Ptr{UInt8}
    counterDataScratchBufferSize::Csize_t
    pCounterDataScratchBuffer::Ptr{UInt8}
    bDumpCounterDataInFile::UInt8
    pCounterDataFilePath::Cstring
    range::CUpti_ProfilerRange
    replayMode::CUpti_ProfilerReplayMode
    maxRangesPerPass::Csize_t
    maxLaunchesPerPass::Csize_t
end

struct CUpti_Profiler_EndSession_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
end

struct CUpti_Profiler_SetConfig_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
    pConfig::Ptr{UInt8}
    configSize::Csize_t
    minNestingLevel::UInt16
    numNestingLevels::UInt16
    passIndex::Csize_t
    targetNestingLevel::UInt16
end

struct CUpti_Profiler_UnsetConfig_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
end

struct CUpti_Profiler_BeginPass_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
end

struct CUpti_Profiler_EndPass_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
    targetNestingLevel::UInt16
    passIndex::Csize_t
    allPassesSubmitted::UInt8
end

struct CUpti_Profiler_EnableProfiling_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
end

struct CUpti_Profiler_DisableProfiling_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
end

struct CUpti_Profiler_IsPassCollected_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
    numRangesDropped::Csize_t
    numTraceBytesDropped::Csize_t
    onePassCollected::UInt8
    allPassesCollected::UInt8
end

struct CUpti_Profiler_FlushCounterData_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
    numRangesDropped::Csize_t
    numTraceBytesDropped::Csize_t
end

struct CUpti_Profiler_PushRange_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
    pRangeName::Cstring
    rangeNameLength::Csize_t
end

struct CUpti_Profiler_PopRange_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
end

struct CUpti_Profiler_GetCounterAvailability_Params
    structSize::Csize_t
    pPriv::Ptr{Cvoid}
    ctx::CUcontext
    counterAvailabilityImageSize::Csize_t
    pCounterAvailabilityImage::Ptr{UInt8}
end


text:
"""
    cross(fs::AbstractVector{<:GP})

Creates a multi-output GP from an `AbstractVector` of `GP`s.
"""
function cross(fs::AbstractVector{<:AbstractGP})
    consistency_checks(fs)
    return CompositeGP((cross, fs), first(fs).gpc)
end

function consistency_checks(fs)
    @assert length(fs) >= 1
    @assert all([f.gpc == first(fs).gpc for f in fs])
end
Zygote.@nograd consistency_checks

const cross_args{T<:AbstractVector{<:AbstractGP}} = Tuple{typeof(cross), T}

function mean_vector((_, fs)::cross_args, x::BlockData)
    blks = map((f, blk)->mean_vector(f, blk), fs, blocks(x))
    return Array(mortar(blks))
end

function cov((_, fs)::cross_args, x::BlockData)
    Cs = reshape(map((f, blk)->cov(f, (cross, fs), blk, x), fs, blocks(x)), :, 1)
    return Array(mortar(reshape(Cs, :, 1)))
end

function cov_diag((_, fs)::cross_args, x::BlockData)
    cs = map(cov_diag, fs, blocks(x))
    return Array(mortar(cs))
end

function cov((_, fs)::cross_args, x::BlockData, x′::BlockData)
    Cs = reshape(map((f, blk)->cov(f, (cross, fs), blk, x′), fs, blocks(x)), :, 1)
    return Array(mortar(reshape(Cs, :, 1)))
end

function cov_diag((_, fs)::cross_args, x::BlockData, x′::BlockData)
    cs = map(cov_diag, fs, blocks(x), blocks(x′))
    return Array(mortar(cs))
end

function cov((_, fs)::cross_args, f′::AbstractGP, x::BlockData, x′::AV)
    Cs = reshape(map((f, x)->cov(f, f′, x, x′), fs, blocks(x)), :, 1)
    return Array(mortar(Cs))
end
function cov(f::AbstractGP, (_, fs)::cross_args, x::AV, x′::BlockData)
    Cs = reshape(map((f′, x′)->cov(f, f′, x, x′), fs, blocks(x′)), 1, :)
    return Array(mortar(Cs))
end

function cov_diag(args::cross_args, f′::AbstractGP, x::BlockData, x′::AV)
    return diag(cov(args, f′, x, x′))
end
function cov_diag(f::AbstractGP, args::cross_args, x::AV, x′::BlockData)
    return diag(cov(f, args, x, x′))
end

#
# Util for multi-process versions of `rand`, `logpdf`, and `elbo`.
#

function finites_to_block(fs::AV{<:FiniteGP})
    return FiniteGP(
        cross(map(f->f.f, fs)),
        BlockData(map(f->f.x, fs)),
        make_block_noise(map(f->f.Σy, fs)),
    )
end

make_block_noise(Σys::Vector{<:Diagonal}) = Diagonal(Vector(mortar(diag.(Σys))))
make_block_noise(Σys::Vector) = block_diagonal(Σys)

function _get_indices(fs)
    sz = cumsum(map(length, fs))
    return [sz[n] - length(fs[n]) + 1:sz[n] for n in eachindex(fs)]
end
Zygote.@nograd _get_indices

#
# multi-process `rand`
#

function rand(rng::AbstractRNG, fs::AV{<:FiniteGP}, N::Int)
    Y = rand(rng, finites_to_block(fs), N)
    idx = _get_indices(fs)
    return map(n->Y[idx[n], :], eachindex(fs))
end
rand(rng::AbstractRNG, fs::AV{<:FiniteGP}) = vec.(rand(rng, fs, 1))
rand(fs::AV{<:FiniteGP}, N::Int) = rand(Random.GLOBAL_RNG, fs, N)
rand(fs::AV{<:FiniteGP}) = vec.(rand(Random.GLOBAL_RNG, fs))

#
# multi-process `logpdf`
#

function logpdf(fs::AV{<:FiniteGP}, ys::Vector{<:AV{<:Real}})
    return logpdf(finites_to_block(fs), vcat(ys...))
end
logpdf(fs::Vector{<:Observation}) = logpdf(get_f.(fs), get_y.(fs))

#
# multi-process `elbo`
#

function elbo(fs::Vector{<:FiniteGP}, ys::Vector{<:AV{<:Real}}, us::Vector{<:FiniteGP})
    return elbo(finites_to_block(fs), Vector(mortar(ys)), finites_to_block(us))
end

function elbo(fs::Vector{<:FiniteGP}, ys::Vector{<:AV{<:Real}}, u::FiniteGP)
    return elbo(finites_to_block(fs), Vector(mortar(ys)), u)
end

elbo(f::FiniteGP, y::AV{<:Real}, us::Vector{<:FiniteGP}) = elbo(f, y, finites_to_block(us))


text:
using HERE
using Test
using Revise

function loadkey()
    if "key" in keys(ENV)               # For Travis CI testing
        return ENV["key"]
    else
        open("test\\keys") do f         # For local testing
            return strip(readline(f))
        end
    end
end

testkey = loadkey()

@testset "Traffic API" begin
    df = flow(apikey=testkey, bbox="39.8485715,-86.0969867;39.8358934,-86.0757964")
    @test !isempty(df)
end

@testset "Weather API" begin
    df = weather(;apikey=testkey, info="weather observation", loc=(name = "Jaipur",))
    @test !isempty(df)

    df = weather(;apikey=testkey, info="weather forecast", loc=(name = "Jaipur",))
    @test !isempty(df)

    df = weather(;apikey=testkey, info="weather alert", loc=(name = "Jaipur",))
    display(df)
    @test !isempty(df)

    df = weather(;apikey=testkey, info="astronomy forecast", loc=(name = "Jaipur",))
    @test !isempty(df)
end