92#ifdef MNE_USE_ONNXRUNTIME
94 throw std::runtime_error(
"MlOnnxModel::predict – No ONNX model loaded. Call load() first.");
98 auto inputShape = input.
shape();
99 Ort::Value inputTensor = Ort::Value::CreateTensor<float>(
101 const_cast<float*
>(input.
data()),
102 static_cast<size_t>(input.
size()),
107 std::vector<const char*> inputNamePtrs;
108 inputNamePtrs.reserve(m_inputNames.size());
109 for (
const auto& n : m_inputNames)
110 inputNamePtrs.push_back(n.c_str());
112 std::vector<const char*> outputNamePtrs;
113 outputNamePtrs.reserve(m_outputNames.size());
114 for (
const auto& n : m_outputNames)
115 outputNamePtrs.push_back(n.c_str());
118 Ort::RunOptions runOpts;
119 auto outputTensors = m_session->Run(
121 inputNamePtrs.data(), &inputTensor, inputNamePtrs.size(),
122 outputNamePtrs.data(), outputNamePtrs.size());
124 if (outputTensors.empty() || !outputTensors[0].IsTensor()) {
125 throw std::runtime_error(
"MlOnnxModel::predict – Model produced no valid output tensor.");
129 auto outputInfo = outputTensors[0].GetTensorTypeAndShapeInfo();
130 std::vector<int64_t> outputShape = outputInfo.GetShape();
131 const float* outputData = outputTensors[0].GetTensorData<
float>();
133 return MlTensor(outputData, std::move(outputShape));
136 throw std::runtime_error(
"ONNX Runtime not available. Build with -DUSE_ONNXRUNTIME=ON");
153#ifdef MNE_USE_ONNXRUNTIME
156 if (!QFileInfo::exists(path)) {
157 qWarning() <<
"MlOnnxModel::load – File does not exist:" << path;
163 Ort::SessionOptions sessionOpts;
164 sessionOpts.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
165 sessionOpts.SetIntraOpNumThreads(1);
166 sessionOpts.DisableMemPattern();
169 std::string modelPathStd = path.toStdString();
170 m_session = std::make_unique<Ort::Session>(ortEnv(), modelPathStd.c_str(), sessionOpts);
173 m_memoryInfo = std::make_unique<Ort::MemoryInfo>(
174 Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault));
177 Ort::AllocatorWithDefaultOptions allocator;
178 size_t numInputs = m_session->GetInputCount();
179 m_inputNames.clear();
180 m_inputShapes.clear();
181 m_inputNames.reserve(numInputs);
182 m_inputShapes.reserve(numInputs);
184 for (
size_t i = 0; i < numInputs; ++i) {
185 auto namePtr = m_session->GetInputNameAllocated(i, allocator);
186 m_inputNames.emplace_back(namePtr.get());
188 auto typeInfo = m_session->GetInputTypeInfo(i);
189 auto shape = typeInfo.GetTensorTypeAndShapeInfo().GetShape();
191 m_inputShapes.push_back(std::move(shape));
195 size_t numOutputs = m_session->GetOutputCount();
196 m_outputNames.clear();
197 m_outputNames.reserve(numOutputs);
198 for (
size_t i = 0; i < numOutputs; ++i) {
199 auto namePtr = m_session->GetOutputNameAllocated(i, allocator);
200 m_outputNames.emplace_back(namePtr.get());
203 qDebug() <<
"MlOnnxModel::load – Session created for" << path
204 <<
"(" << numInputs <<
"inputs," << numOutputs <<
"outputs)";
207 }
catch (
const Ort::Exception& e) {
208 qWarning() <<
"MlOnnxModel::load – ORT error:" << e.what();
214 qWarning() <<
"MlOnnxModel::load – Path stored but no ONNX Runtime session created (build with -DUSE_ONNXRUNTIME=ON).";