diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b7cce9f1..1ebc676a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -294,11 +294,18 @@ if (LLAMA_CUBLAS) endif() if (LLAMA_METAL) + add_executable(embedfile embedfile.c) + + add_custom_command( + OUTPUT ggml_metal_file.c + COMMAND embedfile ggml_metal_file bin/ggml-metal.metal + DEPENDS ggml-metal.metal) + find_library(FOUNDATION_LIBRARY Foundation REQUIRED) find_library(METAL_FRAMEWORK Metal REQUIRED) find_library(METALKIT_FRAMEWORK MetalKit REQUIRED) - set(GGML_SOURCES_METAL ggml-metal.m ggml-metal.h) + set(GGML_SOURCES_METAL ggml_metal_file.c ggml-metal.m ggml-metal.h) add_compile_definitions(GGML_USE_METAL) #add_compile_definitions(GGML_METAL_NDEBUG) diff --git a/embedfile.c b/embedfile.c new file mode 100644 index 000000000..38ebaf16c --- /dev/null +++ b/embedfile.c @@ -0,0 +1,52 @@ +#include +#include + +FILE* open_or_exit(const char* fname, const char* mode) +{ + FILE* f = fopen(fname, mode); + if (f == NULL) { + perror(fname); + exit(EXIT_FAILURE); + } + return f; +} + +int main(int argc, char** argv) +{ + if (argc < 3) { + fprintf(stderr, "USAGE: %s {sym} {rsrc}\n\n" + " Creates {sym}.c from the contents of {rsrc}\n", + argv[0]); + return EXIT_FAILURE; + } + + const char* sym = argv[1]; + FILE* in = open_or_exit(argv[2], "r"); + + char symfile[256]; + snprintf(symfile, sizeof(symfile), "%s.c", sym); + + FILE* out = open_or_exit(symfile,"w"); + fprintf(out, "#include \n"); + fprintf(out, "const char %s[] = {\n", sym); + + unsigned char buf[256]; + size_t nread = 0; + size_t linecount = 0; + do { + nread = fread(buf, 1, sizeof(buf), in); + size_t i; + for (i=0; i < nread; i++) { + fprintf(out, "0x%02x, ", buf[i]); + if (++linecount == 10) { fprintf(out, "\n"); linecount = 0; } + } + } while (nread > 0); + if (linecount > 0) fprintf(out, "\n"); + fprintf(out, "};\n"); + fprintf(out, "const size_t %s_len = sizeof(%s);\n\n",sym,sym); + + fclose(in); + fclose(out); + + return EXIT_SUCCESS; +} diff --git a/ggml-metal.m b/ggml-metal.m index 88e7e1356..088c40185 100644 --- a/ggml-metal.m +++ b/ggml-metal.m @@ -102,6 +102,9 @@ struct ggml_metal_context { #undef GGML_METAL_DECL_KERNEL }; +const char ggml_metal_file[]; +const size_t ggml_metal_file_len; + // MSL code // TODO: move the contents here when ready // for now it is easier to work in a separate file @@ -140,7 +143,8 @@ struct ggml_metal_context * ggml_metal_init(int n_cb) { ctx->d_queue = dispatch_queue_create("llama.cpp", DISPATCH_QUEUE_CONCURRENT); -#if 0 +#if 1 + NSString * const msl_library_source = [[NSString alloc] initWithBytes: ggml_metal_file length: ggml_metal_file_len encoding: NSASCIIStringEncoding]; // compile from source string and show compile log { NSError * error = nil; @@ -151,6 +155,7 @@ struct ggml_metal_context * ggml_metal_init(int n_cb) { return NULL; } } + [msl_library_source release]; #else UNUSED(msl_library_source);