-
Notifications
You must be signed in to change notification settings - Fork 55
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
Check and use only available FFTW libraries #278
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #278 +/- ##
==========================================
+ Coverage 73.08% 73.15% +0.07%
==========================================
Files 5 5
Lines 535 529 -6
==========================================
- Hits 391 387 -4
+ Misses 144 142 -2
☔ View full report in Codecov by Sentry. |
@@ -82,7 +90,6 @@ end | |||
|
|||
# If we're using MKL, load it in and set library paths appropriately. | |||
@static if fftw_provider == "mkl" | |||
import MKL_jll |
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.
Why not doing the test is_available
here? People are not going to be happy to having to unconditionally download MKL, that was the whole point of #133 (which you seemed to agree with, judging by the 👍)
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.
I was not aware of this issue. Mainly, I thought it would be more user-friendly to figure out the supported libraries in advance, before trying to set them. Only moving the check here won't help with my use case and the linked issue above.
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.
Is there any other way to check whether a library can be loaded apart from ..._jll.is_available()
? Maybe checking the system architecture is an OKish workaround?
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.
Is there any other way to check whether a library can be loaded apart from ..._jll.is_available()?
No.
Maybe checking the system architecture is an OKish workaround?
That's going to hard-code answers which may potentially change over time.
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.
Only moving the check here won't help with [...] the linked issue above.
Why not? Capture the fact that the artifact isn't available and throw a helpful error message to explain what to do, instead of getting a cryptic UndefVarError
that some users don't know what to do with.
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.
Also, if I understand this implementation correctly this is automagically changing the provider if the requested one isn't actually available, which doesn't sound very deterministic.
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.
Yeah, switching to the supported default provider was the main point - changing the LocalPreferences.toml file manually on my end creates git conflicts when moving branches and pulling all the time (and if I forget to adjust it, compilation will fail). To some extent that's already done in the current code: If you specify an invalid provider other than fftw
and mkl
, FFTW will just display an @error
and switch to the default provider (which is fixed to fftw
currently). So basically I'm in the same situation, on my computer mkl
is also an invalid provider so I would like to switch to the default one. And I guess you could hypothetically think about an analogous scenario where fftw
is invalid and you would like to switch to the mkl
as default provider.
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.
Displaying a more descriptive error message is an improvement but I think a solution that just defines the (in)valid providers correctly would be much more convenient.
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.
That's going to hard-code answers which may potentially change over time.
Yes, a bit annoying. But since I didn't see any other alternative to define the valid providers correctly, I switched to hardcoding the supported platforms.
I guess the supported platforms could always be updated easily - and probably supported platforms for MKL won't change much at least? If we're more ambitious, probably we could even automatically extract it from the Artifacts.toml files in FFTW_jll and MKL_jll.
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.
I guess the supported platforms could always be updated easily - and probably supported platforms for MKL won't change much at least?
It did change.
4bc920c
to
9a3850b
Compare
src/providers.jl
Outdated
Base.BinaryPlatforms.Platform("x86_64", "freebsd") => ("fftw",), | ||
Base.BinaryPlatforms.Platform("x86_64", "windows") => ("fftw", "mkl"), | ||
) | ||
const valid_fftw_providers = Base.BinaryPlatforms.select_platform(platforms_providers, Base.BinaryPlatforms.HostPlatform()) |
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 you do something like
const valid_fftw_providers = let
platforms_providers = Dict(...)
Base.BinaryPlatforms.select_platform(platforms_providers, Base.BinaryPlatforms.HostPlatform())
end
you avoid storing in the compile cache a useless dictionary.
src/providers.jl
Outdated
if !FFTW_jll.is_available() | ||
# more descriptive error message if FFTW is not available | ||
# (should not be possible to reach this) | ||
error("FFTW library cannot be loaded: please switch to the `mkl` provider for FFTW.jl") |
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.
Maybe provide a more helpful error message to explain how to to do this? Most users won't have a clue of what this is about.
Base.BinaryPlatforms.Platform("i686", "linux"; libc = "musl") => ("fftw",), | ||
Base.BinaryPlatforms.Platform("i686", "windows") => ("fftw", "mkl"), | ||
Base.BinaryPlatforms.Platform("powerpc64le", "linux"; libc = "glibc") => ("fftw",), | ||
Base.BinaryPlatforms.Platform("x86_64", "macos") => ("fftw", "mkl"), |
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.
#280 shows that the hardcoded list a bad idea: there's no MKL 2024 build for this platform.
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.
Yeah, I always thought that a hardcoded list is suboptimal. Ideally we would just parse the Artifacts.toml file, I think, similar to https://github.com/JuliaPackaging/JLLWrappers.jl/blob/a1025a86bc58ac40e2d1df30f4d6bf6c390d51e1/src/toplevel_generators.jl#L132-L185 - but in the best case such a functionality would be available somewhere else. I would imagine that this would be a more common use case - figuring out whether a user's platform is supported without actually loading the JLL package.
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.
But why not removing the automagic fallback, and only do what the user asks, and loudly and clearly fail if the artifact isn't available? In that case you can use is_available safely, since the user explicitly requested it
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.
Because the motivation for the PR and the problem I was trying to solve was that it failed. As a user I don't want to run into an error, I just want to use the provider that is available on my platform.
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.
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.
To clarify a bit more: In my case the MKL provider was chosen as the default for me by a package I was using, but in principle it could also be the other way around (that the currently hardcoded default FFTW_jll provider does not work but MKL_jll does). I think it would be less surprising and more user-friendly if the default provider would not be hard-coded to e.g. FFTW_jll but that it is checked which providers are actually available for the user and the default one is chosen as the first one among those. I don't think one should override explicit user settings but I think the default should work (and the error messages/list of valid providers should match the ones that are actually available).
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.
In my case the MKL provider was chosen as the default for me by a package I was using
I'm not sure packages should do that, preferences should be up to users. Especially if packages get it wrong.
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.
I agree. But I want to emphasize that the PR tries to address the problem of incorrect lists of valid providers and non-working default providers in FFTW.jl itself, and does aim (anymore) to fix incorrect settings in some downstream package.
I think it would be good to check if FFTW_jll and MKL_jll are actually available before trying to load them, as suggested in #274 (comment). I ran into this issue with a project that specified
provider = "mkl"
in a LocalPreferences.toml - precompilation will error on my MacBook since MKL is not available for Apple silicon. With this PR, FFTW will use FFTW_jll instead (if it's not available either an error is thrown) but present the user with the error message:Fixes #274.