fix: library loading for swift dynamic frameworks#2568
fix: library loading for swift dynamic frameworks#2568angeloskath merged 2 commits intoml-explore:mainfrom
Conversation
|
@davidkoski do you mind checking this change is useful for MLX Swift? |
| std::tie(lib, error[3]) = load_colocated_library(device, "Resources/default"); | ||
| if (lib) { | ||
| return lib; | ||
| } |
There was a problem hiding this comment.
load_colocated_library will get the directory of the binary that contains the get_binary_directory(). In the case of an embedded .framework it would be something like x.app/Contents/Frameworks/MLX.framework/Versions/A. This would then append Resources/default and .metallib onto that and load the file.
I think this works if the default.metallib is hoisted out of the mlx-swift_Cmlx.bundle/Contents/Resources. I am not sure it is because I don't have a .framework wrapping the MLX swiftpm library myself, but such a thing could surely be done.
There was a problem hiding this comment.
That said, I am surprised that this does not do the same thing:
std::pair<MTL::Library*, NS::Error*> load_swiftpm_library(
MTL::Device* device,
const std::string& lib_name) {
#ifdef SWIFTPM_BUNDLE
...
auto bundles = NS::Bundle::allBundles();
for (int i = 0, c = (int)bundles->count(); i < c; i++) {
auto bundle = reinterpret_cast<NS::Bundle*>(bundles->object(i));
library = try_load_bundle(device, bundle->resourceURL(), lib_name);That should scan all bundles (frameworks are considered bundles) looking for a default.metallib.
There was a problem hiding this comment.
It doesn't work this way, because bundles doesn't contain MLX framework path. In current configuration, it always looks for for main bundle and tries to load default.metallib from mlx-swift_Cmlx.bundle. But with dynamic frameworks, app directory looks next way:
- App.app
- Contents
- Frameworks
- MLX
- Resources
- default.metallib
- Resources
- MLX
- Resources
- Frameworks
- Contents
NSBundle <~Work/DerivedData/Eney-dyyiohebtzyjuwbwalhqtrcvkvcn/Build/Products/Debug/App.app> (loaded),
NSBundle </System/Library/Extensions/AGXMetalG13X.bundle> (loaded),
NSBundle </System/Library/Input Methods/PressAndHold.app/Contents/PlugIns/PAH_Extension.appex> (not yet loaded),
NSBundle </System/Library/CoreServices/SystemAppearance.bundle> (not yet loaded)
There was a problem hiding this comment.
@davidkoski I've covered a questions related to load_swiftpm_library above
There was a problem hiding this comment.
OK, if the default.metallib is in the Resources directory, I agree this looks good.
It might be, but:
|
angeloskath
left a comment
There was a problem hiding this comment.
This looks fine to me also given the discussion and @davidkoski 's agreement, so I 'll merge after the tests clear.
angeloskath
left a comment
There was a problem hiding this comment.
@bilousoleksandr the NS::Error error[4] needs to be NS::Error error[5].
Fixed |
|
@angeloskath could you re-approve the PR to enable CI run? |
chore: pre-commit hook changes
f63f0b0 to
f1c0dd6
Compare
Proposed changes
By default, Dynamic Framework doesn't create a resources bundle and packs all resources inside its own
Resourcesfolder.To fix the issue related to SwiftPM, add try loading metal library from
Framework/../Resources/default.metallibwhenmlxcodebase is built as a dynamic framework.Checklist
Put an
xin the boxes that apply.pre-commit run --all-filesto format my code / installed pre-commit prior to committing changes