Skip to content

Commit e22b6a4

Browse files
max-krasnyanskyalexlu-qcEhsan Bateni
committed
hex-devices: support for runtime discovery of available NPU cores
Co-authored-by: Alexander Lu <alexlu@qti.qualcomm.com> Co-authored-by: Ehsan Bateni <ebateni@qti.qualcomm.com>
1 parent 93cfc47 commit e22b6a4

3 files changed

Lines changed: 113 additions & 16 deletions

File tree

ggml/src/ggml-hexagon/ggml-hexagon.cpp

Lines changed: 101 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,72 @@ struct ggml_hexagon_device_config {
7676

7777
static ggml_hexagon_device_config opt_device_configs[GGML_HEXAGON_MAX_SESSIONS];
7878

79+
struct ggml_hexagon_domain_info {
80+
int id;
81+
std::string name;
82+
};
83+
84+
// Enumerate NSP domains via FASTRPC_GET_DOMAINS if supported.
85+
// Filters to FASTRPC_NSP type only so non-compute domains are excluded.
86+
static const std::vector<ggml_hexagon_domain_info> & ggml_hexagon_discover_domains() {
87+
static std::vector<ggml_hexagon_domain_info> cached;
88+
static bool discovered = false;
89+
if (discovered) {
90+
return cached;
91+
}
92+
discovered = true;
93+
94+
system_req_payload domain_info = {};
95+
domain_info.id = FASTRPC_GET_DOMAINS;
96+
domain_info.sys.domains = nullptr;
97+
domain_info.sys.max_domains = 0;
98+
domain_info.sys.flags = DOMAINS_LIST_FLAGS_SET_TYPE(0, FASTRPC_NSP);
99+
100+
int err = remote_system_request(&domain_info);
101+
if (err != AEE_SUCCESS) {
102+
GGML_LOG_DEBUG("ggml-hex: FASTRPC_GET_DOMAINS query failed (0x%x), using static CDSP domains\n", (unsigned) err);
103+
return cached;
104+
}
105+
106+
if (domain_info.sys.num_domains <= 0) {
107+
GGML_LOG_DEBUG("ggml-hex: FASTRPC_GET_DOMAINS reported 0 domains, using static CDSP domains\n");
108+
return cached;
109+
}
110+
111+
std::vector<fastrpc_domain> domains(domain_info.sys.num_domains);
112+
domain_info.sys.domains = domains.data();
113+
domain_info.sys.max_domains = (int) domains.size();
114+
115+
err = remote_system_request(&domain_info);
116+
if (err != AEE_SUCCESS) {
117+
GGML_LOG_WARN("ggml-hex: FASTRPC_GET_DOMAINS fetch failed (0x%x), using static CDSP domains\n", (unsigned) err);
118+
return cached;
119+
}
120+
121+
const int n_domains = std::min(domain_info.sys.num_domains, (int) domains.size());
122+
for (int i = 0; i < n_domains; i++) {
123+
GGML_LOG_INFO("ggml-hex: FASTRPC_GET_DOMAINS[%d]: type=%d id=%d name='%s' status=%d instance_id=%d\n",
124+
i, (int) domains[i].type, domains[i].id, domains[i].name, domains[i].status, domains[i].instance_id);
125+
if (domains[i].type != FASTRPC_NSP) {
126+
GGML_LOG_DEBUG("ggml-hex: skipping non-NSP domain (type=%d)\n", (int) domains[i].type);
127+
continue;
128+
}
129+
if (!domains[i].status) {
130+
GGML_LOG_WARN("ggml-hex: skipping NSP domain id=%d (status=down)\n", domains[i].id);
131+
continue;
132+
}
133+
cached.push_back({ domains[i].id, std::string(domains[i].name) });
134+
GGML_LOG_INFO("ggml-hex: using NSP domain[%zu]: id=%d name='%s'\n",
135+
cached.size() - 1, domains[i].id, domains[i].name);
136+
}
137+
return cached;
138+
}
139+
79140
static int get_domain_id(int physical_idx) {
141+
const auto & domains = ggml_hexagon_discover_domains();
142+
if (physical_idx >= 0 && physical_idx < (int) domains.size()) {
143+
return domains[physical_idx].id;
144+
}
80145
switch (physical_idx) {
81146
case 0: return 3; // CDSP0 (all devices)
82147
case 1: return 4; // CDSP1 (IQ9, IQ10)
@@ -87,6 +152,10 @@ static int get_domain_id(int physical_idx) {
87152
}
88153

89154
static std::string get_domain_name(int physical_idx) {
155+
const auto & domains = ggml_hexagon_discover_domains();
156+
if (physical_idx >= 0 && physical_idx < (int) domains.size()) {
157+
return domains[physical_idx].name;
158+
}
90159
if (physical_idx == 0) {
91160
return CDSP_DOMAIN_NAME;
92161
}
@@ -2874,13 +2943,21 @@ void ggml_hexagon_session::allocate(int dev_id) noexcept(false) {
28742943
GGML_LOG_DEBUG("ggml-hex: %s allocating new session\n", this->name.c_str());
28752944

28762945
domain * my_domain = htpdrv_get_domain(this->domain_id);
2877-
if (my_domain == NULL) {
2878-
GGML_LOG_ERROR("ggml-hex: unable to get domain struct for CDSP (domain_id %d)\n", this->domain_id);
2879-
throw std::runtime_error("ggml-hex: failed to get CDSP domain (see log for details)");
2880-
}
28812946

28822947
std::string dom_name = get_domain_name(phys_idx);
28832948

2949+
// Enable Unsigned PD for all domains
2950+
{
2951+
struct remote_rpc_control_unsigned_module u;
2952+
u.domain = -1;
2953+
u.enable = 1;
2954+
int err = remote_session_control(DSPRPC_CONTROL_UNSIGNED_MODULE, (void *) &u, sizeof(u));
2955+
if (err != AEE_SUCCESS) {
2956+
GGML_LOG_ERROR("ggml-hex: failed to enable unsigned PD for session %d : error 0x%x\n", dev_id, err);
2957+
throw std::runtime_error("ggml-hex: remote_session_control(unsign) failed (see log for details)");
2958+
}
2959+
}
2960+
28842961
// Create new session if virtual_idx > 0
28852962
if (virt_idx > 0) {
28862963
struct remote_rpc_reserve_new_session n;
@@ -2899,6 +2976,19 @@ void ggml_hexagon_session::allocate(int dev_id) noexcept(false) {
28992976
this->session_id = n.session_id;
29002977
this->domain_id = n.effective_domain_id;
29012978
this->valid_session = true;
2979+
} else {
2980+
struct remote_rpc_effective_domain_id eff = {};
2981+
eff.domain_name = const_cast<char *>(dom_name.c_str());
2982+
eff.domain_name_len = dom_name.size();
2983+
eff.session_id = 0;
2984+
2985+
int err = remote_session_control(FASTRPC_GET_EFFECTIVE_DOMAIN_ID, (void *) &eff, sizeof(eff));
2986+
if (err == AEE_SUCCESS) {
2987+
this->domain_id = eff.effective_domain_id;
2988+
} else {
2989+
GGML_LOG_DEBUG("ggml-hex: %s FASTRPC_GET_EFFECTIVE_DOMAIN_ID returned 0x%x, using domain_id %d\n",
2990+
this->name.c_str(), err, this->domain_id);
2991+
}
29022992
}
29032993

29042994
// Get session URI
@@ -2919,6 +3009,13 @@ void ggml_hexagon_session::allocate(int dev_id) noexcept(false) {
29193009

29203010
int err = remote_session_control(FASTRPC_GET_URI, (void *) &u, sizeof(u));
29213011
if (err != AEE_SUCCESS) {
3012+
if (my_domain == NULL) {
3013+
GGML_LOG_ERROR("ggml-hex: failed to get URI for session %d (physical %d, virtual %d) : error 0x%x, "
3014+
"and no static fallback URI is known for domain_id %d\n",
3015+
dev_id, phys_idx, virt_idx, err, this->domain_id);
3016+
throw std::runtime_error("ggml-hex: failed to get session URI (see log for details)");
3017+
}
3018+
29223019
// fallback to single session uris
29233020
int htp_URI_domain_len = strlen(htp_uri) + MAX_DOMAIN_NAMELEN;
29243021

@@ -2928,18 +3025,6 @@ void ggml_hexagon_session::allocate(int dev_id) noexcept(false) {
29283025
}
29293026
}
29303027

2931-
// Enable Unsigned PD
2932-
{
2933-
struct remote_rpc_control_unsigned_module u;
2934-
u.domain = this->domain_id;
2935-
u.enable = 1;
2936-
int err = remote_session_control(DSPRPC_CONTROL_UNSIGNED_MODULE, (void *) &u, sizeof(u));
2937-
if (err != AEE_SUCCESS) {
2938-
GGML_LOG_ERROR("ggml-hex: failed to enable unsigned PD for session %d : error 0x%x\n", dev_id, err);
2939-
throw std::runtime_error("ggml-hex: remote_session_control(unsign) failed (see log for details)");
2940-
}
2941-
}
2942-
29433028
// Open session
29443029
int err = htp_iface_open(session_uri, &this->handle);
29453030
if (err != AEE_SUCCESS) {

ggml/src/ggml-hexagon/htp-drv.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ typedef int (*remote_handle64_close_pfn_t)(remote_handle h);
7373
typedef int (*remote_handle_control_pfn_t)(uint32_t req, void* data, uint32_t datalen);
7474
typedef int (*remote_handle64_control_pfn_t)(remote_handle64 h, uint32_t req, void* data, uint32_t datalen);
7575
typedef int (*remote_session_control_pfn_t)(uint32_t req, void *data, uint32_t datalen);
76+
typedef int (*remote_system_request_pfn_t)(system_req_payload * req);
7677

7778
//
7879
// Driver API pfns
@@ -99,6 +100,7 @@ remote_handle64_close_pfn_t remote_handle64_close_pfn = nullptr;
99100
remote_handle_control_pfn_t remote_handle_control_pfn = nullptr;
100101
remote_handle64_control_pfn_t remote_handle64_control_pfn = nullptr;
101102
remote_session_control_pfn_t remote_session_control_pfn = nullptr;
103+
remote_system_request_pfn_t remote_system_request_pfn = nullptr;
102104

103105
//
104106
// Driver API
@@ -206,6 +208,13 @@ HTPDRV_API int remote_session_control(uint32_t req, void * data, uint32_t datale
206208
return remote_session_control_pfn(req, data, datalen);
207209
}
208210

211+
HTPDRV_API int remote_system_request(system_req_payload * req) {
212+
if (!remote_system_request_pfn) {
213+
return AEE_EUNSUPPORTEDAPI;
214+
}
215+
return remote_system_request_pfn(req);
216+
}
217+
209218
#ifdef _WIN32
210219

211220
static std::string wstr_to_str(std::wstring_view wstr) {
@@ -367,6 +376,7 @@ int htpdrv_init() {
367376
dlsym(handle.get(), remote_handle64_control_pfn_t, remote_handle64_control_pfn, remote_handle64_control, false);
368377
dlsym(handle.get(), remote_session_control_pfn_t, remote_session_control_pfn, remote_session_control, false);
369378
dlsym(handle.get(), remote_handle64_close_pfn_t, remote_handle64_close_pfn, remote_handle64_close, false);
379+
dlsym(handle.get(), remote_system_request_pfn_t, remote_system_request_pfn, remote_system_request, true);
370380

371381
lib_cdsp_rpc_handle = std::move(handle);
372382
initialized = true;

ggml/src/ggml-hexagon/htp-drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ HTPDRV_API domain * htpdrv_get_domain(int domain_id);
116116
*/
117117
HTPDRV_API int htpdrv_get_arch(int domain, int * arch);
118118

119+
HTPDRV_API int remote_system_request(system_req_payload * req);
120+
119121
#ifdef __cplusplus
120122
}
121123
#endif

0 commit comments

Comments
 (0)