25#include <hailo/hailort.h>
26#include <hailo/hailort.hpp>
32#define HAILO_CHECK(obj, msg) do { if (!obj) LFATAL(msg << ": " << obj.status() << " [" << \
33 hailo_get_status_message(obj.status()) << ']'); } while (0)
63 std::vector<hailo_vstream_info_t> ret;
64 for (
auto const & vs : itsInStreams) ret.emplace_back(vs.get_info());
70{
return itsOutAttrs; }
75 std::vector<hailo_vstream_info_t> ret;
76 for (
auto const & vs : itsOutStreams) ret.emplace_back(vs.get_info());
91 dataroot::freeze(doit);
99 bool success =
false;
bool first_time =
true;
103 if (itsDevice)
LFATAL(
"Network already loaded... restart the module to load a new one.");
106 auto dev = hailort::Device::create_pcie();
107 if (!dev)
LFATAL(
"Failed to create PCIe device:" << dev.status());
108 itsDevice = dev.release();
112 LINFO(
"Loading HEF file " << m <<
" ...");
113 auto hef = hailort::Hef::create(m);
116 std::vector<std::string> ngn = hef->get_network_groups_names();
117 for (std::string
const & n : ngn)
LINFO(
"Network Group: " << n);
118 if (ngn.size() != 1)
LERROR(
"More than one network groups in HEF -- USING FIRST ONE");
120 auto configure_params = hef->create_configure_params(HAILO_STREAM_INTERFACE_PCIE);
121 HAILO_CHECK(configure_params,
"Could not configure params from HEF file " << m);
123 auto network_groups = itsDevice->configure(hef.value(), configure_params.value());
127 if (first_time ==
false)
129 engine()->
reportError(
"Hailo PCIe driver failure uncorrectable by soft reset -- Reloading JeVois module");
131 HAILO_CHECK(network_groups,
"Could not configure device");
135 LERROR(
"Could not configure device: " << network_groups.status() <<
" [" <<
136 hailo_get_status_message(network_groups.status()) <<
"] -- RESETTING HAILO DRIVER");
140 itsDevice->reset(HAILO_RESET_DEVICE_MODE_FORCED_SOFT);
149 first_time =
false;
success =
false;
153 if (network_groups->empty())
LFATAL(
"HEF file " << m <<
" does not contain any network groups");
154 itsNetGroup = std::move(network_groups->at(0));
160 constexpr bool QUANTIZED =
true;
161 constexpr hailo_format_type_t FORMAT_TYPE = HAILO_FORMAT_TYPE_AUTO;
163 auto vstreams = hailort::VStreamsBuilder::create_vstreams(*itsNetGroup, QUANTIZED, FORMAT_TYPE);
164 HAILO_CHECK(vstreams,
"Failed to create vstreams");
166 itsInStreams = std::move(vstreams->first);
167 itsOutStreams = std::move(vstreams->second);
170 auto activated_network_group = itsNetGroup->activate();
171 HAILO_CHECK(activated_network_group,
"Failed activating network group");
172 itsActiveNetGroup = activated_network_group.release();
175 for (
auto const & vs : itsInStreams)
178 auto const & attr = itsInAttrs.back();
182 for (
auto const & vs : itsOutStreams)
185 auto const & attr = itsOutAttrs.back();
192 itsDevice->set_throttling_state(! turbo::get());
198 if (itsDevice) itsDevice->set_throttling_state(! newval);
203 std::vector<std::string> & info)
205 if (blobs.size() != itsInStreams.size())
206 LFATAL(
"Received " << blobs.size() <<
" blobs, but network has " << itsInStreams.size() <<
" inputs");
209 for (
size_t i = 0; i < blobs.size(); ++i)
213 if (err.empty() ==
false)
LFATAL(err);
216 std::vector<std::future<std::string>> fvec(itsInStreams.size() + itsOutStreams.size());
217 bool const dq = dequant::get();
219 for (uint32_t i = 0; i < itsOutStreams.size(); ++i)
220 fvec[i + itsInStreams.size()] =
jevois::async([
this](uint32_t i,
bool dq) -> std::string
222 auto const & attr = itsOutAttrs[i];
223 uint8_t * tensor_data = (uint8_t *)itsRawOutMats[i].data;
224 size_t const sz = itsRawOutMats[i].total() * itsRawOutMats[i].elemSize();
226 auto status = itsOutStreams[i].read(hailort::MemoryView(tensor_data, sz));
227 if (status != HAILO_SUCCESS)
LFATAL(
"Failed to collect output " << i <<
" from device: " << status);
236 itsOutMats[i] = itsRawOutMats[i];
243 for (
size_t b = 0; b < blobs.size(); ++b)
244 fvec[b] =
jevois::async([
this, &blobs](
size_t b) -> std::string
246 cv::Mat
const & blob = blobs[b];
247 size_t const sz = blob.total() * blob.elemSize();
250 auto status = itsInStreams[b].write(hailort::MemoryView(blob.data, sz));
251 if (status != HAILO_SUCCESS)
LFATAL(
"Failed to write input " << b <<
" data to device: " << status);
257 static std::string devstr =
"- Hailo8: ---W, ---C";
258 if ((jevois::frameNum() % 30) == 0)
260 bool throttle = itsDevice->get_throttling_state().value();
261 hailo_chip_temperature_info_t
const temp = itsDevice->get_chip_temperature().value();
262 float pwr = itsDevice->power_measurement(HAILO_DVM_OPTIONS_AUTO, HAILO_POWER_MEASUREMENT_TYPES__POWER).value();
264 devstr =
jevois::sformat(
"- Hailo8: %.1fW, %.0fC%s", pwr, temp.ts0_temperature, throttle ?
"" :
" (turbo)");
269 info.insert(info.end(), std::make_move_iterator(retvec.begin()), std::make_move_iterator(retvec.end()));
270 info.emplace_back(devstr);
#define HAILO_CHECK(obj, msg)
void requestSetFormat(int idx)
Use this to request a format change from within process()
void reportError(std::string const &err)
std::vector< cv::Mat > doprocess(std::vector< cv::Mat > const &blobs, std::vector< std::string > &info) override
Process input blobs and obtain output blobs.
void load() override
Load from disk.
std::vector< hailo_vstream_info_t > inputInfos() const
Hailo-only get input stream infos.
virtual ~NetworkHailo()
Destructor.
void onParamChange(network::turbo const &par, bool const &newval) override
void freeze(bool doit) override
Freeze/unfreeze parameters that users should not change while running.
virtual std::vector< vsi_nn_tensor_attr_t > inputShapes() override
Get shapes of all input tensors.
NetworkHailo(std::string const &instance)
Constructor.
virtual std::vector< vsi_nn_tensor_attr_t > outputShapes() override
Get shapes of all output tensors.
std::vector< hailo_vstream_info_t > outputInfos() const
Hailo-only get input stream infos, can be used to post-process quantized outputs.
Abstract class to represent a neural network.
virtual void freeze(bool doit)
Freeze/unfreeze parameters that users should not change while running.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
vsi_nn_tensor_attr_t tensorattr(TfLiteTensor const *t)
Get tensor shape and type attributes for a TensorFlow Lite tensor.
std::string attrstr(vsi_nn_tensor_attr_t const &attr)
Get a string describing the specs of a tensor, including quantification specs (not provided by shapes...
cv::Mat attrmat(vsi_nn_tensor_attr_t const &attr, void *dataptr=nullptr)
Construct a cv::Mat from attr and possibly data pointer.
cv::Mat dequantize(cv::Mat const &m, vsi_nn_tensor_attr_t const &attr)
Dequantize an output to float32 according to the quantization spec in attr.
std::string shapestr(cv::Mat const &m)
Get a string of the form: "nD AxBxC... TYPE" from an n-dimensional cv::Mat with data type TYPE.
std::vector< int > attrdims(vsi_nn_tensor_attr_t const &attr)
Get a tensor dims as a vector of int, useful to construct a matching cv::Mat.
bool attrmatch(vsi_nn_tensor_attr_t const &attr, cv::Mat const &blob)
Check that a cv::Mat blob matches exactly the spec of an attr.
std::vector< T > joinall(std::vector< std::future< T > > &fvec, bool multiline=true)
Collect results from several async threads that are all returning a T result.
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async(Function &&f, Args &&... args)
Async execution using a thread pool.
std::string system(std::string const &cmd, bool errtoo=true)
Execute a command and grab stdout output to a string.
std::string sformat(char const *fmt,...) __attribute__((format(__printf__
Create a string using printf style arguments.
std::filesystem::path absolutePath(std::filesystem::path const &root, std::filesystem::path const &path)
Compute an absolute path from two paths.
Main namespace for all JeVois classes and functions.