Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "HostCPUFeatures"
uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0"
authors = ["Chris Elrod <elrodc@gmail.com> and contributors"]
version = "0.1.17"
version = "0.1.18"

[deps]
BitTwiddlingConvenienceFunctions = "62783981-4cbd-42fc-bca8-16325de8dc4b"
Expand Down
40 changes: 22 additions & 18 deletions src/HostCPUFeatures.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module HostCPUFeatures
if isdefined(Base, :Experimental) &&
isdefined(Base.Experimental, Symbol("@max_methods"))
@eval Base.Experimental.@max_methods 1
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@max_methods"))
@eval Base.Experimental.@max_methods 1
end

using Libdl, Static
Expand All @@ -10,8 +9,13 @@ using IfElse: ifelse

using BitTwiddlingConvenienceFunctions: prevpow2, nextpow2, intlog2

export has_feature, fma_fast, pick_vector_width, pick_vector_width_shift, register_count,
register_size, simd_integer_register_size
export has_feature,
fma_fast,
pick_vector_width,
pick_vector_width_shift,
register_count,
register_size,
simd_integer_register_size

function get_cpu_name()::String
if isdefined(Sys, :CPU_NAME)
Expand All @@ -22,19 +26,19 @@ function get_cpu_name()::String
end
include("cpu_info.jl")
if (Sys.ARCH === :x86_64) || (Sys.ARCH === :i686)
include("cpu_info_x86.jl")
include("cpu_info_x86.jl")
elseif Sys.ARCH === :aarch64
include("cpu_info_aarch64.jl")
include("cpu_info_aarch64.jl")
else
include("cpu_info_generic.jl")
include("cpu_info_generic.jl")
end
include("pick_vector_width.jl")
include("static_features.jl")

unwrap(::Val{S}) where {S} = S
unwrap(::StaticInt{S}) where {S} = S
unwrap(::StaticFloat64{S}) where {S} = S
unwrap(::StaticSymbol{S}) where {S} = S

@noinline function redefine()
@debug "Defining CPU name."
define_cpu_name()
Expand All @@ -43,14 +47,14 @@ unwrap(::StaticSymbol{S}) where {S} = S
reset_extra_features!()
end
const BASELINE_CPU_NAME = get_cpu_name()
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)
end
BASELINE_CPU_NAME == Sys.CPU_NAME::String || redefine()
return nothing
end
# 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)
# end
# BASELINE_CPU_NAME == Sys.CPU_NAME::String || redefine()
# return nothing
# end

end
60 changes: 32 additions & 28 deletions src/cpu_info.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
function feature_string()
llvmlib_path = VERSION ≥ v"1.6.0-DEV.1429" ? Base.libllvm_path() : only(filter(lib->occursin(r"LLVM\b", basename(lib)), Libdl.dllist()))
libllvm = Libdl.dlopen(llvmlib_path)
gethostcpufeatures = Libdl.dlsym(libllvm, :LLVMGetHostCPUFeatures)
features_cstring = ccall(gethostcpufeatures, Cstring, ())
features = filter(ext -> (ext ≠ "" && (m = match(r"\d", ext); isnothing(m) ? true : m.offset != 2)), split(unsafe_string(features_cstring), ','))
features, features_cstring
llvmlib_path =
VERSION ≥ v"1.6.0-DEV.1429" ? Base.libllvm_path() :
only(filter(lib -> occursin(r"LLVM\b", basename(lib)), Libdl.dllist()))
libllvm = Libdl.dlopen(llvmlib_path)
gethostcpufeatures = Libdl.dlsym(libllvm, :LLVMGetHostCPUFeatures)
features_cstring = ccall(gethostcpufeatures, Cstring, ())
features = filter(
ext -> (ext ≠ "" && (m = match(r"\d", ext); isnothing(m) ? true : m.offset != 2)),
split(unsafe_string(features_cstring), ','),
)
features, features_cstring
end

const FEATURE_SET = Set{String}()
Expand All @@ -16,20 +21,20 @@ archstr() = Sys.ARCH === :i686 ? "x86_64_" : string(Sys.ARCH) * '_'
feature_name(ext) = archstr() * ext[2:end]
process_feature(ext) = (feature_name(ext), first(ext) == '+')

has_feature(_) = False()
@noinline function set_feature(feature::String, has::Bool)
featqn = QuoteNode(Symbol(feature))
if has
@eval has_feature(::Val{$featqn}) = True()
else
@eval has_feature(::Val{$featqn}) = False()
end
end
# has_feature(_) = False()
# @noinline function set_feature(feature::String, has::Bool)
# featqn = QuoteNode(Symbol(feature))
# if has
# @eval has_feature(::Val{$featqn}) = True()
# else
# @eval has_feature(::Val{$featqn}) = False()
# end
# end

function set_features!()
features, features_cstring = feature_string()
znver3 = get_cpu_name() === "znver3"
for ext features
for ext in features
feature, has = process_feature(ext)
if znver3 && occursin("512", feature)
has = false
Expand All @@ -39,27 +44,26 @@ function set_features!()
end
Libc.free(features_cstring)
end
set_features!()

# set_features!()


function reset_features!()
features, features_cstring = feature_string()
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)
end
features, features_cstring = feature_string()
for ext in features
feature, has = process_feature(ext)
if _has_feature(feature) ≠ has
@debug "Defining $(has ? "presence" : "absense") of feature $feature."
set_feature(feature, has)
end
Libc.free(features_cstring)
end
Libc.free(features_cstring)
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()
cpu = QuoteNode(Symbol(get_cpu_name()))
@eval cpu_name() = Val{$cpu}()
cpu = QuoteNode(Symbol(get_cpu_name()))
@eval cpu_name() = Val{$cpu}()
end
define_cpu_name()
41 changes: 21 additions & 20 deletions src/cpu_info_aarch64.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@

_has_aarch64_sve() = (Base.libllvm_version ≥ v"11") && (Base.BinaryPlatforms.CPUID.test_cpu_feature(Base.BinaryPlatforms.CPUID.JL_AArch64_sve))
_has_aarch64_sve() =
(Base.libllvm_version ≥ v"11") &&
(Base.BinaryPlatforms.CPUID.test_cpu_feature(Base.BinaryPlatforms.CPUID.JL_AArch64_sve))

if Int === Int64
@noinline vscale() = ccall("llvm.vscale.i64", llvmcall, Int64, ())
@noinline vscale() = ccall("llvm.vscale.i64", llvmcall, Int64, ())
else
@noinline vscale() = ccall("llvm.vscale.i32", llvmcall, Int32, ())
@noinline vscale() = ccall("llvm.vscale.i32", llvmcall, Int32, ())
end

# TODO: find actually support SVE
Expand All @@ -20,30 +22,30 @@ function _dynamic_register_size()
end

function _set_sve_vector_width!(bytes = _dynamic_register_size())
@eval begin
register_size() = StaticInt{$bytes}()
simd_integer_register_size() = StaticInt{$bytes}()
end
nothing
@eval begin
register_size() = StaticInt{$bytes}()
simd_integer_register_size() = StaticInt{$bytes}()
end
nothing
end


if _has_aarch64_sve()# && !(Bool(has_feature(Val(:aarch64_sve))))
has_feature(::Val{:aarch64_sve_cpuid}) = True()
_set_sve_vector_width!()
has_feature(::Val{:aarch64_sve_cpuid}) = True()
_set_sve_vector_width!()
else
# has_feature(::Val{:aarch64_svejl}) = False()
register_size() = StaticInt{16}()
simd_integer_register_size() = StaticInt{16}()
# has_feature(::Val{:aarch64_svejl}) = False()
register_size() = StaticInt{16}()
simd_integer_register_size() = StaticInt{16}()
end

function reset_extra_features!()
drs = _dynamic_register_size()
register_size() ≠ drs && _set_sve_vector_width!(drs)
hassve = _has_aarch64_sve()
if hassve ≠ has_feature(Val(:aarch64_sve_cpuid))
@eval has_feature(::Val{:aarch64_sve_cpuid}) = $(Expr(:call, hassve ? :True : :False))
end
drs = _dynamic_register_size()
register_size() ≠ drs && _set_sve_vector_width!(drs)
hassve = _has_aarch64_sve()
if hassve ≠ has_feature(Val(:aarch64_sve_cpuid))
@eval has_feature(::Val{:aarch64_sve_cpuid}) = $(Expr(:call, hassve ? :True : :False))
end
end

fma_fast() = True()
Expand All @@ -53,4 +55,3 @@ has_opmask_registers() = has_feature(Val(:aarch64_sve_cpuid))
fast_int64_to_double() = True()

fast_half() = False()

1 change: 0 additions & 1 deletion src/cpu_info_generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ reset_extra_features!() = nothing

fast_int64_to_double() = True()
fast_half() = False()

Loading