diff --git a/ggml/src/ggml-metal/ggml-metal.m b/ggml/src/ggml-metal/ggml-metal.m index 093ae9000..9573a16b3 100644 --- a/ggml/src/ggml-metal/ggml-metal.m +++ b/ggml/src/ggml-metal/ggml-metal.m @@ -507,6 +507,34 @@ static struct ggml_backend_metal_context * ggml_metal_init(ggml_backend_dev_t de #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 *currentBinary = [[NSProcessInfo processInfo] arguments][0]; + NSString *binDir = [currentBinary stringByDeletingLastPathComponent]; + NSString *defaultMetalibPath = [NSString pathWithComponents:@[binDir, @"default.metallib"]]; + NSDictionary *atts = [[NSFileManager defaultManager] attributesOfItemAtPath:defaultMetalibPath error:&error]; + if (error) { + GGML_METAL_LOG_ERROR("%s: error: %s\n", __func__, [[error description] UTF8String]); + return NULL; + } + if (!atts) { + GGML_METAL_LOG_ERROR("%s: error: src path attribute is NULL\n", __func__); + return NULL; + } + if (atts[NSFileType] == NSFileTypeSymbolicLink) { + // Optionally, if this is a symlink, try to resolve it. + defaultMetalibPath = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:defaultMetalibPath error:&error]; + if (error) { + GGML_METAL_LOG_ERROR("%s: error: %s\n", __func__, [[error description] UTF8String]); + return NULL; + } + if (defaultMetalibPath && [defaultMetalibPath length] > 0 && ![[defaultMetalibPath substringToIndex:1] isEqualToString:@"/"]) { + defaultMetalibPath = [NSString pathWithComponents:@[binDir, defaultMetalibPath]]; + } + } + path_lib = defaultMetalibPath; + } + if (try_metallib && path_lib != nil) { // pre-compiled library found NSURL * libURL = [NSURL fileURLWithPath:path_lib];