-
Notifications
You must be signed in to change notification settings - Fork 36
Add extended_platform_key_abi
#10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| using Pkg.Artifacts, Pkg.BinaryPlatforms, Logging | ||
|
|
||
| export AnyPlatform, ExtendedPlatform, base_platform | ||
| export AnyPlatform, ExtendedPlatform, base_platform, extended_platform_key_abi | ||
|
|
||
| """ | ||
| AnyPlatform() | ||
|
|
@@ -207,3 +207,55 @@ function Pkg.Artifacts.pack_platform!(meta::Dict, p::ExtendedPlatform) | |
| # override the default ones | ||
| Artifacts.pack_platform!(meta, base_platform(p)) | ||
| end | ||
|
|
||
| # Get the list of CPU features for the host system querying libLLVM | ||
| function get_cpu_features() | ||
| if VERSION < v"1.4" | ||
| error("Cannot automatically detect the features of the CPU with this version of Julia!") | ||
| end | ||
| features = filter(f -> startswith(f, "+"), | ||
| split(unsafe_string(ccall(:LLVMGetHostCPUFeatures, Cstring, ())), | ||
| ",")) | ||
| return sort!(replace.(features, r"^\+" => "")) | ||
| end | ||
|
|
||
| # Get the microarchitecture of a CPU from the list of its features. | ||
| # TODO: support other architectures, like armv7l and aarch64. | ||
| function march(cpu_features::Vector{String}) | ||
| # List of CPU features from https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html | ||
| if all(in(cpu_features), ("mmx", "sse", "sse2")) # Generic x86_64 | ||
| if all(in(cpu_features), ("sse3", "ssse3", "sse4.1", "sse4.2", "popcnt", "avx", "aes", "pclmul")) # avx | ||
| if all(in(cpu_features), ("movbe", "avx2", "fsgsbase", "rdrnd", "fma", "bmi", "bmi2", "f16c")) # avx2 | ||
| # Some names are different: ADCX -> ADX, PREFETCHW -> PRFCHW | ||
| if all(in(cpu_features), ("pku", "rdseed", "adx", "prfchw", "clflushopt", "xsavec", "xsaves", "avx512f", "clwb", "avx512vl", "avx512bw", "avx512dq", "avx512cd")) # avx512 | ||
| return "avx512" | ||
| end | ||
| return "avx2" | ||
| end | ||
| return "avx" | ||
| end | ||
| return "x86_64" | ||
| else | ||
| @warn "Cannot determine the microarchitecture for the given set of features!" | ||
| return nothing | ||
|
Comment on lines
+239
to
+240
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't want a hard failure if we can't determine the microarchitecture from the given set of features, but it's better to issue a warning just in case we're we're getting strange results. Also, this function would need to be used only when we're asking the set of features for an architecture we know we support (currently only |
||
| end | ||
| end | ||
|
|
||
| # NOTE: the keyword arguments are *not* part of the public API, they're only | ||
| # used for testing purposes and they may change in the future. | ||
| """ | ||
| extended_platform_key_abi() | ||
|
|
||
| Returns the `Platform` representing the current platform. It is an | ||
| [`ExtendedPlatform`](@ref) if it possible to detect additional features, like | ||
| the microarchitecture. | ||
| """ | ||
| function extended_platform_key_abi(; p::Platform = platform_key_abi(), | ||
| cpu_features::Vector{String} = get_cpu_features()) | ||
|
|
||
| if arch(p) == :x86_64 | ||
| return ExtendedPlatform(p; march=march(cpu_features)) | ||
| else | ||
| return p | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we go by this route, all the microarchitecture stuff will work only with Julia v1.4+, as this requires libllvm v8+. Not too bad since the alternative would be to have some code in Base to do the same, but that would require Julia v1.6 or more.