95#ifdef MNE_USE_ONNXRUNTIME
97 throw std::runtime_error(
"MlOnnxModel::predict – No ONNX model loaded. Call load() first.");
101 auto inputShape = input.
shape();
102 Ort::Value inputTensor = Ort::Value::CreateTensor<float>(
104 const_cast<float*
>(input.
data()),
105 static_cast<size_t>(input.
size()),
110 std::vector<const char*> inputNamePtrs;
111 inputNamePtrs.reserve(m_inputNames.size());
112 for (
const auto& n : m_inputNames)
113 inputNamePtrs.push_back(n.c_str());
115 std::vector<const char*> outputNamePtrs;
116 outputNamePtrs.reserve(m_outputNames.size());
117 for (
const auto& n : m_outputNames)
118 outputNamePtrs.push_back(n.c_str());
121 Ort::RunOptions runOpts;
122 auto outputTensors = m_session->Run(
124 inputNamePtrs.data(), &inputTensor, inputNamePtrs.size(),
125 outputNamePtrs.data(), outputNamePtrs.size());
127 if (outputTensors.empty() || !outputTensors[0].IsTensor()) {
128 throw std::runtime_error(
"MlOnnxModel::predict – Model produced no valid output tensor.");
132 auto outputInfo = outputTensors[0].GetTensorTypeAndShapeInfo();
133 std::vector<int64_t> outputShape = outputInfo.GetShape();
134 const float* outputData = outputTensors[0].GetTensorData<
float>();
136 return MlTensor(outputData, std::move(outputShape));
139 throw std::runtime_error(
"ONNX Runtime not available. Build with -DUSE_ONNXRUNTIME=ON");
156#ifdef MNE_USE_ONNXRUNTIME
159 if (!QFileInfo::exists(path)) {
160 qWarning() <<
"MlOnnxModel::load – File does not exist:" << path;
166 Ort::SessionOptions sessionOpts;
167 sessionOpts.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
168 sessionOpts.SetIntraOpNumThreads(1);
169 sessionOpts.DisableMemPattern();
172 std::string modelPathStd = path.toStdString();
173 m_session = std::make_unique<Ort::Session>(ortEnv(), modelPathStd.c_str(), sessionOpts);
176 m_memoryInfo = std::make_unique<Ort::MemoryInfo>(
177 Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault));
180 Ort::AllocatorWithDefaultOptions allocator;
181 size_t numInputs = m_session->GetInputCount();
182 m_inputNames.clear();
183 m_inputShapes.clear();
184 m_inputNames.reserve(numInputs);
185 m_inputShapes.reserve(numInputs);
187 for (
size_t i = 0; i < numInputs; ++i) {
188 auto namePtr = m_session->GetInputNameAllocated(i, allocator);
189 m_inputNames.emplace_back(namePtr.get());
191 auto typeInfo = m_session->GetInputTypeInfo(i);
192 auto shape = typeInfo.GetTensorTypeAndShapeInfo().GetShape();
194 m_inputShapes.push_back(std::move(shape));
198 size_t numOutputs = m_session->GetOutputCount();
199 m_outputNames.clear();
200 m_outputNames.reserve(numOutputs);
201 for (
size_t i = 0; i < numOutputs; ++i) {
202 auto namePtr = m_session->GetOutputNameAllocated(i, allocator);
203 m_outputNames.emplace_back(namePtr.get());
206 qDebug() <<
"MlOnnxModel::load – Session created for" << path
207 <<
"(" << numInputs <<
"inputs," << numOutputs <<
"outputs)";
210 }
catch (
const Ort::Exception& e) {
211 qWarning() <<
"MlOnnxModel::load – ORT error:" << e.what();
217 qWarning() <<
"MlOnnxModel::load – Path stored but no ONNX Runtime session created (build with -DUSE_ONNXRUNTIME=ON).";