]> git.djapps.eu Git - pkg/ggml/sources/ggml/commitdiff
ggml-backend : remove backend self-registration (#641)
authorslaren <redacted>
Thu, 7 Dec 2023 17:54:01 +0000 (18:54 +0100)
committerGitHub <redacted>
Thu, 7 Dec 2023 17:54:01 +0000 (18:54 +0100)
src/ggml-backend-impl.h
src/ggml-backend.c
src/ggml-cuda.cu
src/ggml-metal.m

index d623b885197bb692fe8cfd916d04f849d488d88d..f588af60282650fa65296ebd462b7affbfae8e2e 100644 (file)
@@ -105,36 +105,7 @@ extern "C" {
 
     typedef ggml_backend_t (*ggml_backend_init_fn)(const char * params, void * user_data);
 
-    size_t ggml_backend_register(const char * name, ggml_backend_init_fn init_fn, ggml_backend_buffer_type_t default_buffer_type, void * user_data);
-
-
-    // Register a int function to be called at program startup
-    #if defined(__GNUC__) || defined(__clang__)
-        #define GGML_CONSTRUCTOR(init_fn) \
-            static void __attribute__((constructor)) init_fn ## _ggml_constructor(void) { \
-                init_fn(); \
-            }
-    #elif defined(_MSC_VER)
-        #ifdef __cplusplus
-            #define GGML_CONSTRUCTOR(init_fn) \
-                static int init_fn ## _ggml_constructor_dummy = init_fn();
-        #else
-            #define GGML_CONSTRUCTOR(init_fn) \
-                __pragma(section(".CRT$XCV", read)) \
-                __declspec(allocate(".CRT$XCV")) int (*init_fn ## _ggml_constructor)(void) = init_fn; \
-                __pragma(comment(linker, "/include:" #init_fn "_ggml_constructor"))
-        #endif
-    #else
-        #error "GGML_CONSTRUCTOR not implemented for this compiler"
-    #endif
-
-
-    // Register a backend
-    #define GGML_BACKEND_REGISTER(name, init_fn, buft, user_data) \
-        static void init_fn ## _backend_register(void) { \
-            ggml_backend_register(name, init_fn, buft, user_data); \
-        } \
-        GGML_CONSTRUCTOR(init_fn ## _backend_register)
+    void ggml_backend_register(const char * name, ggml_backend_init_fn init_fn, ggml_backend_buffer_type_t default_buffer_type, void * user_data);
 
 #ifdef  __cplusplus
 }
index 9f31b065db4a5c2f0bf6a95cc983fff7f8ebe468..3a22cd085eac0a4bbf5b96c602c49f6c6354b38a 100644 (file)
@@ -241,6 +241,8 @@ void ggml_backend_tensor_copy(struct ggml_tensor * src, struct ggml_tensor * dst
 
 // backend registry
 
+#define GGML_MAX_BACKENDS_REG 16
+
 struct ggml_backend_reg {
     char name[128];
     ggml_backend_init_fn init_fn;
@@ -248,11 +250,36 @@ struct ggml_backend_reg {
     void * user_data;
 };
 
-#define GGML_MAX_BACKENDS_REG 16
 static struct ggml_backend_reg ggml_backend_registry[GGML_MAX_BACKENDS_REG];
 static size_t ggml_backend_registry_count = 0;
 
-size_t ggml_backend_register(const char * name, ggml_backend_init_fn init_fn, ggml_backend_buffer_type_t default_buffer_type, void * user_data) {
+static ggml_backend_t ggml_backend_reg_cpu_init(const char * params, void * user_data);
+
+static void ggml_backend_registry_init(void) {
+    static bool initialized = false;
+
+    if (initialized) {
+        return;
+    }
+
+    initialized = true;
+
+    ggml_backend_register("CPU", ggml_backend_reg_cpu_init, ggml_backend_cpu_buffer_type(), NULL);
+
+    // add forward decls here to avoid including the backend headers
+#ifdef GGML_USE_CUBLAS
+    extern void ggml_backend_cuda_reg_devices(void);
+    ggml_backend_cuda_reg_devices();
+#endif
+
+#ifdef GGML_USE_METAL
+    extern ggml_backend_t ggml_backend_reg_metal_init(const char * params, void * user_data);
+    extern ggml_backend_buffer_type_t ggml_backend_metal_buffer_type(void);
+    ggml_backend_register("Metal", ggml_backend_reg_metal_init, ggml_backend_metal_buffer_type(), NULL);
+#endif
+}
+
+void ggml_backend_register(const char * name, ggml_backend_init_fn init_fn, ggml_backend_buffer_type_t default_buffer_type, void * user_data) {
     GGML_ASSERT(ggml_backend_registry_count < GGML_MAX_BACKENDS_REG);
 
     int id = ggml_backend_registry_count;
@@ -271,15 +298,17 @@ size_t ggml_backend_register(const char * name, ggml_backend_init_fn init_fn, gg
 #endif
 
     ggml_backend_registry_count++;
-    return ggml_backend_registry_count - 1;
 }
 
-
 size_t ggml_backend_reg_get_count(void) {
+    ggml_backend_registry_init();
+
     return ggml_backend_registry_count;
 }
 
 size_t ggml_backend_reg_find_by_name(const char * name) {
+    ggml_backend_registry_init();
+
     for (size_t i = 0; i < ggml_backend_registry_count; i++) {
         // TODO: case insensitive in a portable way
         if (strcmp(ggml_backend_registry[i].name, name) == 0) {
@@ -291,6 +320,8 @@ size_t ggml_backend_reg_find_by_name(const char * name) {
 
 // init from backend:params string
 ggml_backend_t ggml_backend_reg_init_backend_from_str(const char * backend_str) {
+    ggml_backend_registry_init();
+
     const char * params = strchr(backend_str, ':');
     char backend_name[128];
     if (params == NULL) {
@@ -312,21 +343,29 @@ ggml_backend_t ggml_backend_reg_init_backend_from_str(const char * backend_str)
 }
 
 const char * ggml_backend_reg_get_name(size_t i) {
+    ggml_backend_registry_init();
+
     GGML_ASSERT(i < ggml_backend_registry_count);
     return ggml_backend_registry[i].name;
 }
 
 ggml_backend_t ggml_backend_reg_init_backend(size_t i, const char * params) {
+    ggml_backend_registry_init();
+
     GGML_ASSERT(i < ggml_backend_registry_count);
     return ggml_backend_registry[i].init_fn(params, ggml_backend_registry[i].user_data);
 }
 
 ggml_backend_buffer_type_t ggml_backend_reg_get_default_buffer_type(size_t i) {
+    ggml_backend_registry_init();
+
     GGML_ASSERT(i < ggml_backend_registry_count);
     return ggml_backend_registry[i].default_buffer_type;
 }
 
 ggml_backend_buffer_t ggml_backend_reg_alloc_buffer(size_t i, size_t size) {
+    ggml_backend_registry_init();
+
     GGML_ASSERT(i < ggml_backend_registry_count);
     return ggml_backend_buft_alloc_buffer(ggml_backend_registry[i].default_buffer_type, size);
 }
@@ -569,7 +608,6 @@ static ggml_backend_t ggml_backend_reg_cpu_init(const char * params, void * user
     GGML_UNUSED(user_data);
 }
 
-GGML_BACKEND_REGISTER("CPU", ggml_backend_reg_cpu_init, ggml_backend_cpu_buffer_type(), NULL)
 
 // scheduler
 
index 8fbd5c7e640829c596d0d41bac85d0f87a63ce21..1d2f8cacd9c33c6c0b4727552fdd6a1215189364 100644 (file)
@@ -9034,7 +9034,7 @@ static ggml_backend_t ggml_backend_reg_cuda_init(const char * params, void * use
     UNUSED(params);
 }
 
-static int ggml_backend_cuda_reg_devices() {
+extern "C" int ggml_backend_cuda_reg_devices() {
     int device_count = ggml_cuda_get_device_count();
     //int device_count = 1; // DEBUG: some tools require delaying CUDA initialization
     for (int i = 0; i < device_count; i++) {
@@ -9044,5 +9044,3 @@ static int ggml_backend_cuda_reg_devices() {
     }
     return device_count;
 }
-
-GGML_CONSTRUCTOR(ggml_backend_cuda_reg_devices)
index 0c2f86ff57186b779d8c2369d13487ede8816e27..3b43d5f6b68a511187e5a73b8fbfd085894f6c5b 100644 (file)
@@ -2057,11 +2057,11 @@ void ggml_backend_metal_set_n_cb(ggml_backend_t backend, int n_cb) {
     ggml_metal_set_n_cb(ctx, n_cb);
 }
 
-static ggml_backend_t ggml_backend_reg_metal_init(const char * params, void * user_data) {
+ggml_backend_t ggml_backend_reg_metal_init(const char * params, void * user_data); // silence warning
+
+ggml_backend_t ggml_backend_reg_metal_init(const char * params, void * user_data) {
     return ggml_backend_metal_init();
 
     GGML_UNUSED(params);
     GGML_UNUSED(user_data);
 }
-
-GGML_BACKEND_REGISTER("Metal", ggml_backend_reg_metal_init, ggml_backend_metal_buffer_type(), NULL)