diff --git a/ggml/src/ggml-backend-impl.h b/ggml/src/ggml-backend-impl.h index 3a2b2d24ab..f58f914e70 100644 --- a/ggml/src/ggml-backend-impl.h +++ b/ggml/src/ggml-backend-impl.h @@ -221,6 +221,9 @@ extern "C" { // (optional) get a pointer to a function in the backend // backends can add custom functions that are not part of the standard ggml-backend interface void * (*get_proc_address)(ggml_backend_reg_t reg, const char * name); + + // (optional) free backend reg (before unloading the dynamic library) + void (*free)(ggml_backend_reg_t reg); }; struct ggml_backend_reg { @@ -236,8 +239,6 @@ extern "C" { // Optional: obtain a score for the backend based on the system configuration // Higher scores are preferred, 0 means the backend is not supported in the current system typedef int (*ggml_backend_score_t)(void); - // Optional: release all resources held by the backend (before unloading the dynamic library) - typedef void (*ggml_backend_reg_free_t)(ggml_backend_reg_t reg); #ifdef GGML_BACKEND_DL # ifdef __cplusplus @@ -255,13 +256,6 @@ extern "C" { int ggml_backend_score(void) { \ return score_fn(); \ } -# define GGML_BACKEND_DL_FREE_IMPL(free_fn) \ - extern "C" { \ - GGML_BACKEND_API void ggml_backend_reg_free(ggml_backend_reg_t reg); \ - } \ - void ggml_backend_reg_free(ggml_backend_reg_t reg) { \ - free_fn(reg); \ - } # else # define GGML_BACKEND_DL_IMPL(reg_fn) \ GGML_BACKEND_API ggml_backend_reg_t ggml_backend_init(void); \ @@ -273,16 +267,10 @@ extern "C" { int ggml_backend_score(void) { \ return score_fn(); \ } -# define GGML_BACKEND_DL_FREE_IMPL(free_fn) \ - GGML_BACKEND_API void ggml_backend_reg_free(ggml_backend_reg_t reg); \ - void ggml_backend_reg_free(ggml_backend_reg_t reg) { \ - free_fn(reg); \ - } # endif #else # define GGML_BACKEND_DL_IMPL(reg_fn) # define GGML_BACKEND_DL_SCORE_IMPL(score_fn) -# define GGML_BACKEND_DL_FREE_IMPL(free_fn) #endif #ifdef __cplusplus diff --git a/ggml/src/ggml-backend-reg.cpp b/ggml/src/ggml-backend-reg.cpp index 15ba6c8a7b..416bd95eed 100644 --- a/ggml/src/ggml-backend-reg.cpp +++ b/ggml/src/ggml-backend-reg.cpp @@ -278,11 +278,8 @@ struct ggml_backend_registry { devices.end()); // if backend supports free(), use it - if (it->handle) { - auto * free_fn = (ggml_backend_reg_free_t) dl_get_sym(it->handle.get(), "ggml_backend_reg_free"); - if (free_fn) { - free_fn(reg); - } + if (reg->iface.free) { + reg->iface.free(reg); } // remove backend diff --git a/ggml/src/ggml-cuda/ggml-cuda.cu b/ggml/src/ggml-cuda/ggml-cuda.cu index 152cc16cdd..9e70fcb75c 100644 --- a/ggml/src/ggml-cuda/ggml-cuda.cu +++ b/ggml/src/ggml-cuda/ggml-cuda.cu @@ -5722,17 +5722,40 @@ static void * ggml_backend_cuda_reg_get_proc_address(ggml_backend_reg_t reg, con return nullptr; } +static bool ggml_backend_cuda_reg_initialized = false; + +static void ggml_backend_cuda_reg_free(ggml_backend_reg_t reg) { + ggml_backend_cuda_reg_context * ctx = (ggml_backend_cuda_reg_context *) reg->context; + + for (ggml_backend_dev_t dev : ctx->devices) { + int device = ((ggml_backend_cuda_device_context *) dev->context)->device; + delete (ggml_backend_cuda_device_context *) dev->context; + delete dev; + + cudaError_t err = cudaSetDevice(device); + if (err == cudaSuccess) { + cudaDeviceReset(); + } + } + + delete ctx; + reg->context = nullptr; + + ggml_backend_cuda_reg_initialized = false; +} + static const ggml_backend_reg_i ggml_backend_cuda_reg_interface = { /* .get_name = */ ggml_backend_cuda_reg_get_name, /* .get_device_count = */ ggml_backend_cuda_reg_get_device_count, /* .get_device = */ ggml_backend_cuda_reg_get_device, /* .get_proc_address = */ ggml_backend_cuda_reg_get_proc_address, + /* .free = */ ggml_backend_cuda_reg_free, }; // backend registry ggml_backend_reg_t ggml_backend_cuda_reg() { static ggml_backend_reg reg; - static bool initialized = false; + bool & initialized = ggml_backend_cuda_reg_initialized; { static std::mutex mutex; @@ -5779,23 +5802,6 @@ ggml_backend_reg_t ggml_backend_cuda_reg() { return ® } -static void ggml_backend_cuda_reg_free(ggml_backend_reg_t reg) { - ggml_backend_cuda_reg_context * ctx = (ggml_backend_cuda_reg_context *) reg->context; - - for (ggml_backend_dev_t dev : ctx->devices) { - int device = ((ggml_backend_cuda_device_context *) dev->context)->device; - delete (ggml_backend_cuda_device_context *) dev->context; - delete dev; - - cudaError_t err = cudaSetDevice(device); - if (err == cudaSuccess) { - cudaDeviceReset(); - } - } - - delete ctx; -} - ggml_backend_t ggml_backend_cuda_init(int device) { if (device < 0 || device >= ggml_backend_cuda_get_device_count()) { GGML_LOG_ERROR("%s: invalid device %d\n", __func__, device); @@ -5819,4 +5825,3 @@ ggml_backend_t ggml_backend_cuda_init(int device) { } GGML_BACKEND_DL_IMPL(ggml_backend_cuda_reg) -GGML_BACKEND_DL_FREE_IMPL(ggml_backend_cuda_reg_free)