6666#include  " ggml-kompute.h" 
6767#endif 
6868
69+ //  disable C++17 deprecation warning for std::codecvt_utf8
70+ #if  defined(__clang__)
71+ #    pragma  clang diagnostic push
72+ #    pragma  clang diagnostic ignored "-Wdeprecated-declarations"
73+ #endif 
74+ 
75+ static  std::wstring utf8_to_utf16 (const  std::string & str) {
76+     std::wstring_convert<std::codecvt_utf8_utf16<wchar_t >> converter;
77+     return  converter.from_bytes (str);
78+ }
79+ 
80+ static  std::string utf16_to_utf8 (const  std::wstring & str) {
81+     std::wstring_convert<std::codecvt_utf8_utf16<wchar_t >> converter;
82+     return  converter.to_bytes (str);
83+ }
84+ 
85+ #if  defined(__clang__)
86+ #    pragma  clang diagnostic pop
87+ #endif 
88+ 
6989#ifdef  _WIN32
7090
7191using  dl_handle = std::remove_pointer_t <HMODULE>;
@@ -88,11 +108,6 @@ static dl_handle * dl_load_library(const std::wstring & path) {
88108    return  handle;
89109}
90110
91- static  dl_handle * dl_load_library (const  std::string & path) {
92-     std::wstring_convert<std::codecvt_utf8_utf16<wchar_t >> converter;
93-     return  dl_load_library (converter.from_bytes (path));
94- }
95- 
96111static  void  * dl_get_sym (dl_handle * handle, const  char  * name) {
97112    DWORD old_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
98113    SetErrorMode (old_mode | SEM_FAILCRITICALERRORS);
@@ -114,8 +129,8 @@ struct dl_handle_deleter {
114129    }
115130};
116131
117- static  void  * dl_load_library (const  std::string  & path) {
118-     dl_handle * handle = dlopen (path.c_str (), RTLD_NOW | RTLD_LOCAL);
132+ static  void  * dl_load_library (const  std::wstring  & path) {
133+     dl_handle * handle = dlopen (utf16_to_utf8 ( path) .c_str (), RTLD_NOW | RTLD_LOCAL);
119134
120135    return  handle;
121136}
@@ -202,27 +217,27 @@ struct ggml_backend_registry {
202217        devices.push_back (device);
203218    }
204219
205-     ggml_backend_reg_t  load_backend (const  char  *  path, bool  silent) {
220+     ggml_backend_reg_t  load_backend (const  std::wstring &  path, bool  silent) {
206221        dl_handle_ptr handle { dl_load_library (path) };
207222        if  (!handle) {
208223            if  (!silent) {
209-                 GGML_LOG_ERROR (" %s: failed to load %s\n " 
224+                 GGML_LOG_ERROR (" %s: failed to load %s\n " utf16_to_utf8 ( path). c_str () );
210225            }
211226            return  nullptr ;
212227        }
213228
214229        auto  score_fn = (ggml_backend_score_t ) dl_get_sym (handle.get (), " ggml_backend_score" 
215230        if  (score_fn && score_fn () == 0 ) {
216231            if  (!silent) {
217-                 GGML_LOG_INFO (" %s: backend %s is not supported on this system\n " 
232+                 GGML_LOG_INFO (" %s: backend %s is not supported on this system\n " utf16_to_utf8 ( path). c_str () );
218233            }
219234            return  nullptr ;
220235        }
221236
222237        auto  backend_init_fn = (ggml_backend_init_t ) dl_get_sym (handle.get (), " ggml_backend_init" 
223238        if  (!backend_init_fn) {
224239            if  (!silent) {
225-                 GGML_LOG_ERROR (" %s: failed to find ggml_backend_init in %s\n " 
240+                 GGML_LOG_ERROR (" %s: failed to find ggml_backend_init in %s\n " utf16_to_utf8 ( path). c_str () );
226241            }
227242            return  nullptr ;
228243        }
@@ -231,16 +246,16 @@ struct ggml_backend_registry {
231246        if  (!reg || reg->api_version  != GGML_BACKEND_API_VERSION) {
232247            if  (!silent) {
233248                if  (!reg) {
234-                     GGML_LOG_ERROR (" %s: failed to initialize backend from %s: ggml_backend_init returned NULL\n " 
249+                     GGML_LOG_ERROR (" %s: failed to initialize backend from %s: ggml_backend_init returned NULL\n " utf16_to_utf8 ( path). c_str () );
235250                } else  {
236251                    GGML_LOG_ERROR (" %s: failed to initialize backend from %s: incompatible API version (backend: %d, current: %d)\n " 
237-                         __func__, path, reg->api_version , GGML_BACKEND_API_VERSION);
252+                         __func__, utf16_to_utf8 ( path). c_str () , reg->api_version , GGML_BACKEND_API_VERSION);
238253                }
239254            }
240255            return  nullptr ;
241256        }
242257
243-         GGML_LOG_INFO (" %s: loaded %s backend from %s\n " ggml_backend_reg_name (reg), path);
258+         GGML_LOG_INFO (" %s: loaded %s backend from %s\n " ggml_backend_reg_name (reg), utf16_to_utf8 ( path). c_str () );
244259
245260        register_backend (reg, std::move (handle));
246261
@@ -376,14 +391,14 @@ ggml_backend_t ggml_backend_init_best(void) {
376391
377392//  Dynamic loading
378393ggml_backend_reg_t  ggml_backend_load (const  char  * path) {
379-     return  get_reg ().load_backend (path, false );
394+     return  get_reg ().load_backend (utf8_to_utf16 ( path) , false );
380395}
381396
382397void  ggml_backend_unload (ggml_backend_reg_t  reg) {
383398    get_reg ().unload_backend (reg, true );
384399}
385400
386- static  std::string  get_executable_path () {
401+ static  std::wstring  get_executable_path () {
387402#if  defined(__APPLE__)
388403    //  get executable path
389404    std::vector<char > path;
@@ -401,7 +416,7 @@ static std::string get_executable_path() {
401416    if  (last_slash != std::string::npos) {
402417        base_path = base_path.substr (0 , last_slash);
403418    }
404-     return  base_path + " /" 
419+     return  utf8_to_utf16 ( base_path + " /" ) ;
405420#elif  defined(__linux__) || defined(__FreeBSD__)
406421    std::string base_path = " ." 
407422    std::vector<char > path (1024 );
@@ -427,57 +442,63 @@ static std::string get_executable_path() {
427442        path.resize (path.size () * 2 );
428443    }
429444
430-     return  base_path + " /" 
445+     return  utf8_to_utf16 ( base_path + " /" ) ;
431446#elif  defined(_WIN32)
432-     std::vector<char > path (MAX_PATH);
433-     DWORD len = GetModuleFileNameA (NULL , path.data (), path.size ());
447+     std::vector<wchar_t > path (MAX_PATH);
448+     DWORD len = GetModuleFileNameW (NULL , path.data (), path.size ());
434449    if  (len == 0 ) {
435-         return  " " 
450+         return  {} ;
436451    }
437-     std::string  base_path (path.data (), len);
452+     std::wstring  base_path (path.data (), len);
438453    //  remove executable name
439454    auto  last_slash = base_path.find_last_of (' \\ ' 
440455    if  (last_slash != std::string::npos) {
441456        base_path = base_path.substr (0 , last_slash);
442457    }
443-     return  base_path + " \\ " 
458+     return  base_path + L" \\ " 
459+ #else 
460+     return  {};
461+ #endif 
462+ }
463+ 
464+ static  std::wstring backend_filename_prefix () {
465+ #ifdef  _WIN32
466+     return  L" ggml-" 
467+ #else 
468+     return  L" libggml-" 
444469#endif 
445470}
446471
447- static  std::string  backend_filename_prefix () {
472+ static  std::wstring  backend_filename_suffix () {
448473#ifdef  _WIN32
449-     return  " ggml- " 
474+     return  L" .dll " 
450475#else 
451-     return  " libggml- " 
476+     return  L" .so " 
452477#endif 
453478}
454479
455- static  std::string  backend_filename_suffix () {
480+ static  std::wstring  path_separator () {
456481#ifdef  _WIN32
457-     return  " .dll " 
482+     return  L" \\ " 
458483#else 
459-     return  " .so " 
484+     return  L" / " 
460485#endif 
461486}
462487
463488static  ggml_backend_reg_t  ggml_backend_load_best (const  char  * name, bool  silent, const  char  * user_search_path) {
464489    //  enumerate all the files that match [lib]ggml-name-*.[so|dll] in the search paths
465490     //  TODO: search system paths
466-     std::string  file_prefix = backend_filename_prefix () + name + " -" 
467-     std::vector<std::string > search_paths;
491+     std::wstring  file_prefix = backend_filename_prefix () + utf8_to_utf16 ( name)  + L "" 
492+     std::vector<std::wstring > search_paths;
468493    if  (user_search_path == nullptr ) {
469-         search_paths.push_back (" ./ " 
494+         search_paths.push_back (L" . "  +  path_separator () );
470495        search_paths.push_back (get_executable_path ());
471496    } else  {
472- #if  defined(_WIN32)
473-         search_paths.push_back (std::string (user_search_path) + " \\ " 
474- #else 
475-         search_paths.push_back (std::string (user_search_path) + " /" 
476- #endif 
497+         search_paths.push_back (utf8_to_utf16 (user_search_path) + path_separator ());
477498    }
478499
479500    int  best_score = 0 ;
480-     std::string  best_path;
501+     std::wstring  best_path;
481502
482503    namespace  fs  =  std::filesystem;
483504    for  (const  auto  & search_path : search_paths) {
@@ -487,27 +508,27 @@ static ggml_backend_reg_t ggml_backend_load_best(const char * name, bool silent,
487508        fs::directory_iterator dir_it (search_path, fs::directory_options::skip_permission_denied);
488509        for  (const  auto  & entry : dir_it) {
489510            if  (entry.is_regular_file ()) {
490-                 std::string  filename = entry.path ().filename ().string ();
491-                 std::string  ext = entry.path ().extension ().string ();
511+                 std::wstring  filename = entry.path ().filename ().wstring ();
512+                 std::wstring  ext = entry.path ().extension ().wstring ();
492513                if  (filename.find (file_prefix) == 0  && ext == backend_filename_suffix ()) {
493-                     dl_handle_ptr handle { dl_load_library (entry.path ().c_str ()) };
514+                     dl_handle_ptr handle { dl_load_library (entry.path ().wstring ()) };
494515                    if  (!handle && !silent) {
495-                         GGML_LOG_ERROR (" %s: failed to load %s\n " path ().string ( ).c_str ());
516+                         GGML_LOG_ERROR (" %s: failed to load %s\n " utf16_to_utf8 ( entry.path ().wstring () ).c_str ());
496517                    }
497518                    if  (handle) {
498519                        auto  score_fn = (ggml_backend_score_t ) dl_get_sym (handle.get (), " ggml_backend_score" 
499520                        if  (score_fn) {
500521                            int  s = score_fn ();
501522#ifndef  NDEBUG
502-                             GGML_LOG_DEBUG (" %s: %s score: %d\n " path ().string ( ).c_str (), s);
523+                             GGML_LOG_DEBUG (" %s: %s score: %d\n " utf16_to_utf8 ( entry.path ().wstring () ).c_str (), s);
503524#endif 
504525                            if  (s > best_score) {
505526                                best_score = s;
506-                                 best_path = entry.path ().string ();
527+                                 best_path = entry.path ().wstring ();
507528                            }
508529                        } else  {
509530                            if  (!silent) {
510-                                 GGML_LOG_INFO (" %s: failed to find ggml_backend_score in %s\n " path ().string ( ).c_str ());
531+                                 GGML_LOG_INFO (" %s: failed to find ggml_backend_score in %s\n " utf16_to_utf8 ( entry.path ().wstring () ).c_str ());
511532                            }
512533                        }
513534                    }
@@ -519,15 +540,15 @@ static ggml_backend_reg_t ggml_backend_load_best(const char * name, bool silent,
519540    if  (best_score == 0 ) {
520541        //  try to load the base backend
521542        for  (const  auto  & search_path : search_paths) {
522-             std::string  path = search_path + backend_filename_prefix () + name + backend_filename_suffix ();
543+             std::wstring  path = search_path + backend_filename_prefix () + utf8_to_utf16 ( name)  + backend_filename_suffix ();
523544            if  (fs::exists (path)) {
524-                 return  get_reg ().load_backend (path. c_str () , silent);
545+                 return  get_reg ().load_backend (path, silent);
525546            }
526547        }
527548        return  nullptr ;
528549    }
529550
530-     return  get_reg ().load_backend (best_path. c_str () , silent);
551+     return  get_reg ().load_backend (best_path, silent);
531552}
532553
533554void  ggml_backend_load_all () {
0 commit comments