99#include < chrono>
1010#include < mutex>
1111#include < string>
12+ #include < dlfcn.h>
1213
1314#ifdef _WIN32
1415# include < sal.h>
@@ -51,6 +52,15 @@ static int opt_experimental = 0;
5152static int opt_opmask = HTP_OPMASK_QUEUE | HTP_OPMASK_QUANTIZE | HTP_OPMASK_COMPUTE;
5253static int opt_opsync = 0 ; // synchronous ops
5354
55+ // function signature defined in rpcmem.h
56+ using pfn_rpc_mem_alloc = void *(*)(int , uint32_t , size_t );
57+
58+ // Dynamic pointers to functions in lib[cdsp]rpc.so, used for backward compatibility with older SoCs
59+ // library open happens in the constructor of ggml_hexagon_registry, and closed in the destructor
60+
61+ // dynamic pointer to function rpcmem_alloc or rpcmem_alloc2 at runtime
62+ static pfn_rpc_mem_alloc _pfn_rpc_mem_alloc = nullptr ;
63+
5464#define HEX_VERBOSE (...) \
5565 if (opt_verbose) GGML_LOG_DEBUG(__VA_ARGS__)
5666
@@ -367,7 +377,9 @@ struct ggml_backend_hexagon_buffer_context {
367377 ggml_backend_hexagon_buffer_context (ggml_hexagon_session * sess, size_t size, bool repack) {
368378 size += 4 * 1024 ; // extra page for padding
369379
370- this ->base = (uint8_t *) rpcmem_alloc (RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS | RPCMEM_HEAP_NOREG, size);
380+ GGML_ASSERT (_pfn_rpc_mem_alloc != nullptr );
381+
382+ this ->base = (uint8_t *) _pfn_rpc_mem_alloc (RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS | RPCMEM_HEAP_NOREG, size);
371383 if (!this ->base ) {
372384 GGML_LOG_ERROR (" ggml-hex: %s failed to allocate buffer : size %zu\n " , sess->name .c_str (), size);
373385 throw std::runtime_error (" ggml-hex: rpcmem_alloc failed (see log for details)" );
@@ -1683,7 +1695,7 @@ void ggml_hexagon_session::allocate(int dev_id) noexcept(false) {
16831695 sprintf (htp_uri, " file:///libggml-htp-v%u.so?htp_iface_skel_handle_invoke&_modver=1.0" , opt_arch);
16841696
16851697 char session_uri[256 ];
1686- if ( false ) {
1698+ {
16871699 struct remote_rpc_get_uri u;
16881700 u.session_id = this ->session_id ;
16891701 u.domain_name = const_cast <char *>(CDSP_DOMAIN_NAME);
@@ -1695,13 +1707,13 @@ void ggml_hexagon_session::allocate(int dev_id) noexcept(false) {
16951707
16961708 int err = remote_session_control (FASTRPC_GET_URI, (void *) &u, sizeof (u));
16971709 if (err != AEE_SUCCESS) {
1698- GGML_LOG_ERROR (" ggml-hex: failed to get URI for session %d : error 0x%x\n " , dev_id, err);
1699- throw std::runtime_error (" ggml-hex: remote_session_control(get-uri) failed (see log for details)" );
1700- }
1701- } else {
1702- int htp_URI_domain_len = strlen (htp_uri) + MAX_DOMAIN_NAMELEN;
1710+ // fallback to single session uris
1711+ int htp_URI_domain_len = strlen (htp_uri) + MAX_DOMAIN_NAMELEN;
1712+
1713+ snprintf (session_uri, htp_URI_domain_len, " %s%s" , htp_uri, my_domain->uri );
17031714
1704- snprintf (session_uri, htp_URI_domain_len, " %s%s" , htp_uri, my_domain->uri );
1715+ GGML_LOG_WARN (" ggml-hex: failed to get URI for session %d : error 0x%x. Falling back to single session URI: %s\n " , dev_id, err, session_uri);
1716+ }
17051717 }
17061718
17071719 // Enable Unsigned PD
@@ -3659,6 +3671,9 @@ struct ggml_hexagon_registry {
36593671 ~ggml_hexagon_registry ();
36603672
36613673 ggml_backend_device devices[GGML_HEXAGON_MAX_SESSIONS];
3674+
3675+ // dynamic handles
3676+ void * _rpc_lib_handle = nullptr ;
36623677};
36633678
36643679ggml_hexagon_registry::ggml_hexagon_registry (ggml_backend_reg_t reg) {
@@ -3685,6 +3700,30 @@ ggml_hexagon_registry::ggml_hexagon_registry(ggml_backend_reg_t reg) {
36853700 devices[i].context = nullptr ;
36863701 }
36873702 }
3703+
3704+ // obtain handle to dsp library
3705+ _rpc_lib_handle = dlopen (" libcdsprpc.so" , RTLD_NOW | RTLD_LOCAL);
3706+ if (nullptr == _rpc_lib_handle) {
3707+ GGML_LOG_ERROR (" ggml-hex: failed to load rpc lib: %s" , dlerror ());
3708+ throw std::runtime_error (" failed to load rpc lib" );
3709+ }
3710+
3711+ // attempt to load rpc_memalloc2 first
3712+ _pfn_rpc_mem_alloc = reinterpret_cast <pfn_rpc_mem_alloc>(dlsym (_rpc_lib_handle," rpcmem_alloc2" ));
3713+
3714+ // fallback to rpc_memalloc
3715+ if (_pfn_rpc_mem_alloc == nullptr ) {
3716+ _pfn_rpc_mem_alloc = reinterpret_cast <pfn_rpc_mem_alloc>(dlsym (_rpc_lib_handle," rpcmem_alloc" ));
3717+
3718+ if (_pfn_rpc_mem_alloc == nullptr ) {
3719+ GGML_LOG_ERROR (" ggml-hex: failed to get rpcmem_alloc function address: %s" , dlerror ());
3720+ throw std::runtime_error (" failed to get rpcmem_alloc function address" );
3721+ } else {
3722+ GGML_LOG_INFO (" ggml-hex: using rpcmem_alloc\n " );
3723+ }
3724+ } else {
3725+ GGML_LOG_INFO (" ggml-hex: using rpcmem_alloc2\n " );
3726+ }
36883727}
36893728
36903729ggml_hexagon_registry::~ggml_hexagon_registry () {
@@ -3695,6 +3734,8 @@ ggml_hexagon_registry::~ggml_hexagon_registry() {
36953734 auto sess = static_cast <ggml_hexagon_session *>(devices[i].context );
36963735 delete sess;
36973736 }
3737+
3738+ if (_rpc_lib_handle) dlclose (_rpc_lib_handle);
36983739}
36993740
37003741static const char * ggml_backend_hexagon_reg_get_name (ggml_backend_reg_t reg) {
0 commit comments