From 723446a749fc5b4492500932dd39618310f9b646 Mon Sep 17 00:00:00 2001 From: Cody Tapscott Date: Wed, 19 Nov 2025 17:46:22 -0500 Subject: [PATCH] Add Preference to disable runtime invalidation This makes the package (nearly) `--trim` compatible and also provides a nice preference for users who do not wish for HostCPUFeatures.jl to ever cause an "invalidation storm", even if it means running with the wrong CPU info. --- Project.toml | 1 + src/HostCPUFeatures.jl | 14 +++++++++++--- src/cpu_info.jl | 19 ++++++++++++++----- src/cpu_info_aarch64.jl | 14 ++++++++++++-- src/cpu_info_x86.jl | 16 ++++++++++++---- 5 files changed, 50 insertions(+), 14 deletions(-) diff --git a/Project.toml b/Project.toml index 0fc7612..fe96591 100644 --- a/Project.toml +++ b/Project.toml @@ -7,6 +7,7 @@ version = "0.1.17" BitTwiddlingConvenienceFunctions = "62783981-4cbd-42fc-bca8-16325de8dc4b" IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +Preferences = "21216c6a-2e73-6563-6e65-726566657250" Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" [compat] diff --git a/src/HostCPUFeatures.jl b/src/HostCPUFeatures.jl index 3e8b5ba..700475e 100644 --- a/src/HostCPUFeatures.jl +++ b/src/HostCPUFeatures.jl @@ -7,6 +7,7 @@ end using Libdl, Static using Static: Zero, One, lt, gt using IfElse: ifelse +using Preferences using BitTwiddlingConvenienceFunctions: prevpow2, nextpow2, intlog2 @@ -37,19 +38,26 @@ unwrap(::StaticSymbol{S}) where {S} = S @noinline function redefine() @debug "Defining CPU name." - define_cpu_name() + redefine_cpu_name() reset_features!() reset_extra_features!() end const BASELINE_CPU_NAME = get_cpu_name() +const allow_eval = @load_preference("allow_runtime_invalidation", false) + function __init__() ccall(:jl_generating_output, Cint, ()) == 1 && return if Sys.ARCH === :x86_64 || Sys.ARCH === :i686 target = Base.unsafe_string(Base.JLOptions().cpu_target) - occursin("native", target) || return make_generic(target) + if !occursin("native", target) + make_generic(target) + return nothing + end + end + if BASELINE_CPU_NAME != Sys.CPU_NAME::String + redefine() end - BASELINE_CPU_NAME == Sys.CPU_NAME::String || redefine() return nothing end diff --git a/src/cpu_info.jl b/src/cpu_info.jl index 52b49fe..ca35d83 100644 --- a/src/cpu_info.jl +++ b/src/cpu_info.jl @@ -48,8 +48,12 @@ function reset_features!() for ext ∈ features feature, has = process_feature(ext) if _has_feature(feature) ≠ has - @debug "Defining $(has ? "presence" : "absense") of feature $feature." - set_feature(feature, has) + if allow_eval + @debug "Defining $(has ? "presence" : "absense") of feature $feature." + set_feature(feature, has) + else + @warn "Runtime invalidation was disabled, but the CPU info is out-of-date.\nWill continue with incorrect CPU feature flag: $ext." + end end end Libc.free(features_cstring) @@ -58,8 +62,13 @@ end register_size(::Type{T}) where {T} = register_size() register_size(::Type{T}) where {T<:Union{Signed,Unsigned}} = simd_integer_register_size() -function define_cpu_name() +function redefine_cpu_name() cpu = QuoteNode(Symbol(get_cpu_name())) - @eval cpu_name() = Val{$cpu}() + if allow_eval + @eval cpu_name() = Val{$cpu}() + else + @warn "Runtime invalidation was disabled, but the CPU info is out-of-date.\nWill continue with incorrect CPU name (from build time)." + end end -define_cpu_name() +cpu = QuoteNode(Symbol(get_cpu_name())) +@eval cpu_name() = Val{$cpu}() diff --git a/src/cpu_info_aarch64.jl b/src/cpu_info_aarch64.jl index 605d54d..ffa64d6 100644 --- a/src/cpu_info_aarch64.jl +++ b/src/cpu_info_aarch64.jl @@ -39,10 +39,20 @@ end function reset_extra_features!() drs = _dynamic_register_size() - register_size() ≠ drs && _set_sve_vector_width!(drs) + if register_size() ≠ drs + if allow_eval + _set_sve_vector_width!(drs) + else + @warn "Runtime invalidation was disabled, but the CPU info is out-of-date.\nWill continue with incorrect CPU register size." + end + end hassve = _has_aarch64_sve() if hassve ≠ has_feature(Val(:aarch64_sve_cpuid)) - @eval has_feature(::Val{:aarch64_sve_cpuid}) = $(Expr(:call, hassve ? :True : :False)) + if allow_eval + @eval has_feature(::Val{:aarch64_sve_cpuid}) = $(Expr(:call, hassve ? :True : :False)) + else + @warn "Runtime invalidation was disabled, but the CPU info is out-of-date.\nWill continue with incorrect CPU feature flag: :aarch64_sve_cpuid." + end end end diff --git a/src/cpu_info_x86.jl b/src/cpu_info_x86.jl index b0348c0..7550729 100644 --- a/src/cpu_info_x86.jl +++ b/src/cpu_info_x86.jl @@ -32,14 +32,22 @@ fast_int64_to_double() = has_feature(Val(:x86_64_avx512dq)) fast_half() = False() -@noinline function setfeaturefalse(s) +@inline function setfeaturefalse(s) if has_feature(Val(s)) === True() - @eval has_feature(::Val{$(QuoteNode(s))}) = False() + if allow_eval + @eval has_feature(::Val{$(QuoteNode(s))}) = False() + else + @warn "Runtime invalidation was disabled, but the CPU info is out-of-date.\nWill continue with incorrect CPU feature flag: $s." + end end end -@noinline function setfeaturetrue(s) +@inline function setfeaturetrue(s) if has_feature(Val(s)) === False() - @eval has_feature(::Val{$(QuoteNode(s))}) = True() + if allow_eval + @eval has_feature(::Val{$(QuoteNode(s))}) = True() + else + @warn "Runtime invalidation was disabled, but the CPU info is out-of-date.\nWill continue with incorrect CPU feature flag: $s." + end end end