Didzis Gosko commited on
Commit
a46b62a
·
unverified ·
1 Parent(s): 3443ee7

metal : option to embed MSL source into compiled binary (#1842)

Browse files

* ggml : embed Metal library source (ggml-metal.metal) into binary

enable by setting WHISPER_EMBED_METAL_LIBRARY

* rename the build option

* rename the preprocessor directive

* generate Metal library embedding assembly on-fly during build process

Files changed (3) hide show
  1. CMakeLists.txt +25 -0
  2. Makefile +18 -0
  3. ggml-metal.m +9 -0
CMakeLists.txt CHANGED
@@ -68,6 +68,7 @@ if (APPLE)
68
  option(WHISPER_METAL_NDEBUG "whisper: disable Metal debugging" OFF)
69
  option(WHISPER_COREML "whisper: enable Core ML framework" OFF)
70
  option(WHISPER_COREML_ALLOW_FALLBACK "whisper: allow non-CoreML fallback" OFF)
 
71
  else()
72
  option(WHISPER_BLAS "whisper: use BLAS libraries" OFF)
73
  option(WHISPER_BLAS_VENDOR "whisper: BLAS library vendor" Generic)
@@ -147,6 +148,30 @@ if (APPLE)
147
 
148
  # copy ggml-metal.metal to bin directory
149
  configure_file(ggml-metal.metal bin/ggml-metal.metal COPYONLY)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  endif()
151
 
152
  if (WHISPER_COREML)
 
68
  option(WHISPER_METAL_NDEBUG "whisper: disable Metal debugging" OFF)
69
  option(WHISPER_COREML "whisper: enable Core ML framework" OFF)
70
  option(WHISPER_COREML_ALLOW_FALLBACK "whisper: allow non-CoreML fallback" OFF)
71
+ option(WHISPER_METAL_EMBED_LIBRARY "whisper: embed Metal library" OFF)
72
  else()
73
  option(WHISPER_BLAS "whisper: use BLAS libraries" OFF)
74
  option(WHISPER_BLAS_VENDOR "whisper: BLAS library vendor" Generic)
 
148
 
149
  # copy ggml-metal.metal to bin directory
150
  configure_file(ggml-metal.metal bin/ggml-metal.metal COPYONLY)
151
+
152
+ if (WHISPER_METAL_EMBED_LIBRARY)
153
+ enable_language(ASM)
154
+ set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_METAL_EMBED_LIBRARY)
155
+
156
+ set(METALLIB_SOURCE "${CMAKE_SOURCE_DIR}/ggml-metal.metal")
157
+
158
+ file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/autogenerated")
159
+ set(EMBED_METALLIB_ASSEMBLY "${CMAKE_BINARY_DIR}/autogenerated/ggml-embed-metallib.s")
160
+
161
+ add_custom_command(
162
+ OUTPUT ${EMBED_METALLIB_ASSEMBLY}
163
+ COMMAND echo ".section __DATA,__ggml_metallib" > ${EMBED_METALLIB_ASSEMBLY}
164
+ COMMAND echo ".globl _ggml_metallib_start" >> ${EMBED_METALLIB_ASSEMBLY}
165
+ COMMAND echo "_ggml_metallib_start:" >> ${EMBED_METALLIB_ASSEMBLY}
166
+ COMMAND echo ".incbin \\\"${METALLIB_SOURCE}\\\"" >> ${EMBED_METALLIB_ASSEMBLY}
167
+ COMMAND echo ".globl _ggml_metallib_end" >> ${EMBED_METALLIB_ASSEMBLY}
168
+ COMMAND echo "_ggml_metallib_end:" >> ${EMBED_METALLIB_ASSEMBLY}
169
+ DEPENDS ${METALLIB_SOURCE}
170
+ COMMENT "Generate assembly for embedded Metal library"
171
+ )
172
+
173
+ set(GGML_SOURCES_METAL ${GGML_SOURCES_METAL} ${EMBED_METALLIB_ASSEMBLY})
174
+ endif()
175
  endif()
176
 
177
  if (WHISPER_COREML)
Makefile CHANGED
@@ -345,6 +345,24 @@ ggml-metal.o: ggml-metal.m ggml-metal.h
345
  $(CC) $(CFLAGS) -c $< -o $@
346
 
347
  WHISPER_OBJ += ggml-metal.o
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  endif
349
 
350
  libwhisper.a: $(WHISPER_OBJ)
 
345
  $(CC) $(CFLAGS) -c $< -o $@
346
 
347
  WHISPER_OBJ += ggml-metal.o
348
+
349
+ ifdef WHISPER_METAL_EMBED_LIBRARY
350
+ CFLAGS += -DGGML_METAL_EMBED_LIBRARY
351
+
352
+ ggml-metal-embed.o: ggml-metal.metal
353
+ @echo "Embedding Metal library"
354
+ $(eval TEMP_ASSEMBLY=$(shell mktemp))
355
+ @echo ".section __DATA, __ggml_metallib" > $(TEMP_ASSEMBLY)
356
+ @echo ".globl _ggml_metallib_start" >> $(TEMP_ASSEMBLY)
357
+ @echo "_ggml_metallib_start:" >> $(TEMP_ASSEMBLY)
358
+ @echo ".incbin \"$<\"" >> $(TEMP_ASSEMBLY)
359
+ @echo ".globl _ggml_metallib_end" >> $(TEMP_ASSEMBLY)
360
+ @echo "_ggml_metallib_end:" >> $(TEMP_ASSEMBLY)
361
+ @$(AS) $(TEMP_ASSEMBLY) -o $@
362
+ @rm -f ${TEMP_ASSEMBLY}
363
+
364
+ WHISPER_OBJ += ggml-metal-embed.o
365
+ endif
366
  endif
367
 
368
  libwhisper.a: $(WHISPER_OBJ)
ggml-metal.m CHANGED
@@ -272,6 +272,14 @@ static struct ggml_metal_context * ggml_metal_init(int n_cb) {
272
  return NULL;
273
  }
274
  } else {
 
 
 
 
 
 
 
 
275
  GGML_METAL_LOG_INFO("%s: default.metallib not found, loading from source\n", __func__);
276
 
277
  NSString * sourcePath;
@@ -294,6 +302,7 @@ static struct ggml_metal_context * ggml_metal_init(int n_cb) {
294
  GGML_METAL_LOG_ERROR("%s: error: %s\n", __func__, [[error description] UTF8String]);
295
  return NULL;
296
  }
 
297
 
298
  @autoreleasepool {
299
  // dictionary of preprocessor macros
 
272
  return NULL;
273
  }
274
  } else {
275
+ #if GGML_METAL_EMBED_LIBRARY
276
+ GGML_METAL_LOG_INFO("%s: using embedded metal library\n", __func__);
277
+
278
+ extern const char ggml_metallib_start[];
279
+ extern const char ggml_metallib_end[];
280
+
281
+ NSString * src = [[NSString alloc] initWithBytes:ggml_metallib_start length:(ggml_metallib_end-ggml_metallib_start) encoding:NSUTF8StringEncoding];
282
+ #else
283
  GGML_METAL_LOG_INFO("%s: default.metallib not found, loading from source\n", __func__);
284
 
285
  NSString * sourcePath;
 
302
  GGML_METAL_LOG_ERROR("%s: error: %s\n", __func__, [[error description] UTF8String]);
303
  return NULL;
304
  }
305
+ #endif
306
 
307
  @autoreleasepool {
308
  // dictionary of preprocessor macros