Skip to content

Commit 68f00b7

Browse files
committed
Enhance the QNNContextProc
1 parent a444857 commit 68f00b7

File tree

4 files changed

+81
-4
lines changed

4 files changed

+81
-4
lines changed

pybind/AppBuilder.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,11 @@ std::vector<py::array> inference_P(std::string model_name, std::string proc_name
351351
}
352352
}
353353

354-
g_LibAppBuilder.ModelInference(model_name, proc_name, share_memory_name, inputBuffers, inputSize, outputBuffers, outputSize, perf_profile, graphIndex);
354+
bool success = g_LibAppBuilder.ModelInference(model_name, proc_name, share_memory_name, inputBuffers, inputSize, outputBuffers, outputSize, perf_profile, graphIndex);
355+
if (!success) {
356+
QNN_ERR("ModelInference failed for model: %s, proc: %s", model_name.c_str(), proc_name.c_str());
357+
return {};
358+
}
355359

356360
//QNN_INF("inference_P::inference output vector length: %d\n", outputBuffers.size());
357361

script/qai_appbuilder/qnncontext.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ def __init__(self,
269269
self.proc_name = proc_name
270270
self.input_data_type = input_data_type
271271
self.output_data_type = output_data_type
272+
self.model_name = model_name
272273

273274
if self.proc_name == "None":
274275
raise ValueError("proc_name must be specified!")
@@ -282,6 +283,11 @@ def __init__(self,
282283

283284
#@timer
284285
def Inference(self, shareMemory, input, perf_profile=PerfProfile.DEFAULT, graphIndex=0):
286+
total_input_bytes = sum(arr.nbytes for arr in input)
287+
if total_input_bytes > shareMemory.share_memory_size:
288+
raise ValueError(f"Input data size {total_input_bytes} exceeds share memory size {shareMemory.share_memory_size}, you need to create a larger share memory for model {self.model_name} @ process {self.proc_name}.")
289+
# print(f"Input data size {total_input_bytes} exceeds share memory size {shareMemory.share_memory_size}, you need to create a larger share memory for model {self.model_name} @ process {self.proc_name}.")
290+
285291
return self._inference_and_reshape(
286292
input,
287293
lambda _in: self.m_context.Inference(shareMemory.m_memory, _in, perf_profile, graphIndex,

src/QnnSampleApp.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,12 +1588,18 @@ sample_app::StatusCode sample_app::QnnSampleApp::executeGraphsBuffers(std::vecto
15881588
}
15891589

15901590
// Compute the span end offset (relative to shared memory base) for this input buffer.
1591-
ptrdiff_t delta = inputBuffers[inputIdx] - pShareBuffer;
1592-
if (delta < 0) {
1591+
const uintptr_t baseAddr = reinterpret_cast<uintptr_t>(pShareBuffer);
1592+
const uintptr_t currAddr = reinterpret_cast<uintptr_t>(inputBuffers[inputIdx]);
1593+
if (currAddr < baseAddr) {
15931594
QNN_ERROR("Invalid shared buffer layout: inputIdx=%zu is below shared base pointer", inputIdx);
15941595
return StatusCode::FAILURE;
15951596
}
1596-
const size_t offsetBytes = static_cast<size_t>(delta);
1597+
const uintptr_t deltaAddr = currAddr - baseAddr;
1598+
if (deltaAddr > (std::numeric_limits<size_t>::max)()) {
1599+
QNN_ERROR("share memory size overflow while converting input offset");
1600+
return StatusCode::FAILURE;
1601+
}
1602+
const size_t offsetBytes = static_cast<size_t>(deltaAddr);
15971603
if (offsetBytes > (std::numeric_limits<size_t>::max)() - bytesNeeded) {
15981604
QNN_ERROR("share memory size overflow while accumulating required input bytes");
15991605
return StatusCode::FAILURE;

src/SVC/Utils/Utils.hpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,67 @@ BOOL TalkToSvc_Inference(std::string model_name, std::string proc_name, std::str
333333
return false;
334334
}
335335

336+
337+
// Early validation to avoid VectorToShareMem memcpy crash.
338+
if (inputBuffers.size() != inputSize.size()) {
339+
QNN_ERR("TalkToSvc_Inference: inputBuffers/inputSize length mismatch. buffers=%zu size=%zu\n", inputBuffers.size(), inputSize.size());
340+
return false;
341+
}
342+
if (!pShareMemInfo->lpBase || pShareMemInfo->size == 0) {
343+
QNN_ERR("TalkToSvc_Inference: invalid share memory base or size. name=%s lpBase=%p size=%llu\n", share_memory_name.c_str(), pShareMemInfo->lpBase, (unsigned long long)pShareMemInfo->size);
344+
return false;
345+
}
346+
347+
// Compute required size according to VectorToShareMem's offset strategy: reserve sizes of in-share buffers + sizes of out-of-share buffers.
348+
{
349+
uint8_t* base = (uint8_t*)pShareMemInfo->lpBase;
350+
uint8_t* end = base + pShareMemInfo->size;
351+
size_t reserved = 0;
352+
size_t toCopy = 0;
353+
354+
for (size_t i = 0; i < inputBuffers.size(); ++i) {
355+
uint8_t* buf = inputBuffers[i];
356+
size_t sz = inputSize[i];
357+
358+
if (!buf && sz > 0) {
359+
QNN_ERR("TalkToSvc_Inference: null input buffer at index %zu with non-zero size %llu\n", i, (unsigned long long)sz);
360+
return false;
361+
}
362+
363+
// In-share: [base, end)
364+
if (buf >= base && buf < end) {
365+
if (sz > 0 && ((size_t)(end - buf) < sz)) {
366+
QNN_ERR("TalkToSvc_Inference: in-share input buffer out of bounds. idx=%zu buf=%p size=%llu share=[%p,%p)\n", i, buf, (unsigned long long)sz, base, end);
367+
return false;
368+
}
369+
if (std::numeric_limits<size_t>::max() - reserved < sz) {
370+
QNN_ERR("TalkToSvc_Inference: size_t overflow while accumulating reserved. idx=%zu\n", i);
371+
return false;
372+
}
373+
reserved += sz;
374+
} else {
375+
if (std::numeric_limits<size_t>::max() - toCopy < sz) {
376+
QNN_ERR("TalkToSvc_Inference: size_t overflow while accumulating toCopy. idx=%zu\n", i);
377+
return false;
378+
}
379+
toCopy += sz;
380+
}
381+
}
382+
383+
if (std::numeric_limits<size_t>::max() - reserved < toCopy) {
384+
QNN_ERR("TalkToSvc_Inference: size_t overflow while computing totalNeeded.\n");
385+
return false;
386+
}
387+
388+
size_t totalNeeded = reserved + toCopy;
389+
if (totalNeeded > pShareMemInfo->size) {
390+
QNN_ERR("TalkToSvc_Inference: share memory too small. required=%llu (reserved=%llu copy=%llu) share_size=%llu name=%s\n",
391+
(unsigned long long)totalNeeded, (unsigned long long)reserved, (unsigned long long)toCopy, (unsigned long long)pShareMemInfo->size, share_memory_name.c_str());
392+
return false;
393+
}
394+
}
395+
396+
336397
HANDLE hSvcPipeInWrite = pProcInfo->hSvcPipeInWrite;
337398
HANDLE hSvcPipeOutRead = pProcInfo->hSvcPipeOutRead;
338399
DWORD dwRead = 0, dwWrite = 0;

0 commit comments

Comments
 (0)