From 2df2d52d15f9e520561bbfbfc322f894366ef363 Mon Sep 17 00:00:00 2001 From: Robert Ormandi <52251610+ormandi@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:02:50 -0600 Subject: [PATCH 1/3] metal : Extend how Llama.cpp locates metal resources (#10675) * It searches the resource file in the directory where the current binary is located as well. * Resolves symbolic links. Rationale: When we plug this dependency into a Bazel build and run it in the context of Bazel (e.g. testing): * the execution directory is often very different from where the files are located and no direct control over this (Bazel sandboxing), * the Bazel sandbox often use symbolic links to make files available. With this patch, we can have the resource file added to the target, can build and run tests in the context of Bazel. --- ggml/src/ggml-metal/ggml-metal.m | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ggml/src/ggml-metal/ggml-metal.m b/ggml/src/ggml-metal/ggml-metal.m index 093ae9000ab37..36d4c63de8d20 100644 --- a/ggml/src/ggml-metal/ggml-metal.m +++ b/ggml/src/ggml-metal/ggml-metal.m @@ -507,6 +507,35 @@ @implementation GGMLMetalClass #endif NSString * path_lib = [bundle pathForResource:@"default" ofType:@"metallib"]; + if (path_lib == nil) { + // Try to find the resource in the directory where the current binary located. + NSString *current_binary = [[NSProcessInfo processInfo] arguments][0]; + NSString *bin_dir = [current_binary stringByDeletingLastPathComponent]; + NSString *default_metallib_path = [NSString pathWithComponents:@[bin_dir, @"default.metallib"]]; + if ([[NSFileManager defaultManager] isReadableFileAtPath:default_metallib_path]) { + GGML_LOG_INFO("%s: found '%s'\n", __func__, [default_metallib_path UTF8String]); + NSDictionary *atts = [[NSFileManager defaultManager] attributesOfItemAtPath:default_metallib_path error:&error]; + if (atts && atts[NSFileType] == NSFileTypeSymbolicLink) { + // Optionally, if this is a symlink, try to resolve it. + default_metallib_path = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:default_metallib_path error:&error]; + if (default_metallib_path && [default_metallib_path length] > 0 && ![[default_metallib_path substringToIndex:1] isEqualToString:@"/"]) { + // It is a relative path, adding the binary directory as directory prefix. + default_metallib_path = [NSString pathWithComponents:@[bin_dir, default_metallib_path]]; + } + if (!default_metallib_path || ![[NSFileManager defaultManager] isReadableFileAtPath:default_metallib_path]) { + // Link to the resource could not be resolved. + default_metallib_path = nil; + } else { + GGML_LOG_INFO("%s: symlink resolved '%s'\n", __func__, [default_metallib_path UTF8String]); + } + } + } else { + // The resource couldn't be found in the binary's directory. + default_metallib_path = nil; + } + path_lib = default_metallib_path; + } + if (try_metallib && path_lib != nil) { // pre-compiled library found NSURL * libURL = [NSURL fileURLWithPath:path_lib]; From bcf86a9d29525b5794cf43e0129883490cf7bd57 Mon Sep 17 00:00:00 2001 From: Robert Ormandi <52251610+ormandi@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:10:37 -0600 Subject: [PATCH 2/3] Update ggml/src/ggml-metal/ggml-metal.m Co-authored-by: Georgi Gerganov --- ggml/src/ggml-metal/ggml-metal.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ggml/src/ggml-metal/ggml-metal.m b/ggml/src/ggml-metal/ggml-metal.m index 36d4c63de8d20..327d33d2a6110 100644 --- a/ggml/src/ggml-metal/ggml-metal.m +++ b/ggml/src/ggml-metal/ggml-metal.m @@ -509,9 +509,9 @@ @implementation GGMLMetalClass NSString * path_lib = [bundle pathForResource:@"default" ofType:@"metallib"]; if (path_lib == nil) { // Try to find the resource in the directory where the current binary located. - NSString *current_binary = [[NSProcessInfo processInfo] arguments][0]; - NSString *bin_dir = [current_binary stringByDeletingLastPathComponent]; - NSString *default_metallib_path = [NSString pathWithComponents:@[bin_dir, @"default.metallib"]]; + NSString * current_binary = [[NSProcessInfo processInfo] arguments][0]; + NSString * bin_dir = [current_binary stringByDeletingLastPathComponent]; + NSString * default_metallib_path = [NSString pathWithComponents:@[bin_dir, @"default.metallib"]]; if ([[NSFileManager defaultManager] isReadableFileAtPath:default_metallib_path]) { GGML_LOG_INFO("%s: found '%s'\n", __func__, [default_metallib_path UTF8String]); NSDictionary *atts = [[NSFileManager defaultManager] attributesOfItemAtPath:default_metallib_path error:&error]; From 0f4305f3e1d685dd4c73a4325569796abaebe40b Mon Sep 17 00:00:00 2001 From: Robert Ormandi <52251610+ormandi@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:10:45 -0600 Subject: [PATCH 3/3] Update ggml/src/ggml-metal/ggml-metal.m Co-authored-by: Georgi Gerganov --- ggml/src/ggml-metal/ggml-metal.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ggml/src/ggml-metal/ggml-metal.m b/ggml/src/ggml-metal/ggml-metal.m index 327d33d2a6110..8811d65d1fd80 100644 --- a/ggml/src/ggml-metal/ggml-metal.m +++ b/ggml/src/ggml-metal/ggml-metal.m @@ -514,7 +514,7 @@ @implementation GGMLMetalClass NSString * default_metallib_path = [NSString pathWithComponents:@[bin_dir, @"default.metallib"]]; if ([[NSFileManager defaultManager] isReadableFileAtPath:default_metallib_path]) { GGML_LOG_INFO("%s: found '%s'\n", __func__, [default_metallib_path UTF8String]); - NSDictionary *atts = [[NSFileManager defaultManager] attributesOfItemAtPath:default_metallib_path error:&error]; + NSDictionary * atts = [[NSFileManager defaultManager] attributesOfItemAtPath:default_metallib_path error:&error]; if (atts && atts[NSFileType] == NSFileTypeSymbolicLink) { // Optionally, if this is a symlink, try to resolve it. default_metallib_path = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:default_metallib_path error:&error];