ggml-backend : remove backend self-registration

This commit is contained in:
Georgi Gerganov 2023-12-07 19:58:12 +02:00
parent ba03f9ca15
commit d050bbe831
No known key found for this signature in database
GPG key ID: 449E073F9DC10735
4 changed files with 48 additions and 41 deletions

View 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
}

View 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

View file

@ -9264,7 +9264,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++) {
@ -9274,5 +9274,3 @@ static int ggml_backend_cuda_reg_devices() {
}
return device_count;
}
GGML_CONSTRUCTOR(ggml_backend_cuda_reg_devices)

View file

@ -2092,11 +2092,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)