Запустіть граф.
Graph – це план. Run – це засіб для запуску та виконання.
Використовуйте цю сторінку після створення графа. Якщо вам все ще потрібно визначити, які вузли або фрагменти мають бути в графі, почніть з Граф. Якщо граф вже виглядає правильно, на цій сторінці ви можете запустити його, перевірити, виміряти та забезпечити його стабільну роботу з реальними даними.
Оберіть одноразове або багаторазове виконання.
Використовуйте найкоротший можливий шлях у середовищі виконання, який відповідає вимогам завдання:
| Потрібно | Використовуйте | Чому? |
|---|---|---|
| Введіть один набір даних і отримайте один результат. | Graph.run(...) | Найкоротший маршрут, який можна пройти за один раз. |
| Послідовно передавайте багато вхідних даних протягом певного часу. | Graph.build(...) та Run. | Повторно використовує середовище виконання та надає можливість керування за допомогою механізмів «push» і «pull». |
| Використовуйте іменовані вхідні або вихідні параметри. | Graph.build(...) та названо run.push(...) / run.pull(...). | Забезпечує чітке визначення застосунків із кількома вхідними та вихідними даними. |
| Нехай вихідні вузли визначають структуру графа. | Graph.build() або Graph.run() без введення даних від програми. | Використовуйте, коли граф містить камеру, файл, джерело RTSP або інший вузол-джерело. |
| Вимірюйте, експортуй те, зливайте або зупиняйте навмисно. | Run | Надає можливість контролювати життєвий цикл і проводити діагностику. |
Без жодних чарів. Створіть граф, запустіть його, перевірте результат.
Оберіть, яким чином дані надходитимуть у граф.
Перш ніж налаштовувати черги, визначте, кому належать вхідні дані.
| Стиль графа. | Як здійснюється введення даних. | Як ви це робите. |
|---|---|---|
| Граф, що відображається за допомогою застосунку. | Ваша програма викликає Graph.run(input, ...), run.run(input, ...), run.push(...) або run.try_push(...). | Створіть або запустіть із вхідними даними. Перевірте назви кінцевих точок перед додаванням до графів із кількома вхідними даними. |
| Граф, що належить джерелу. | У графі міститься вихідний вузол або фрагмент, наприклад, ф айл, камера, RTSP або вхідний потік. | Створіть або запустіть без введення даних із програми: graph.build() або graph.run(). Отримуйте результати, використовуйте вузли виводу або використовуйте функції зворотного виклику, залежно від графа. |
Якщо граф є власником джерела, не намагайтеся в нього щось додати. Натомість перевірте, що воно генерує.
Запустіть граф, яким володіє джерело.
Якщо граф містить власну початкову вузлу, створіть або запустіть його без введення даних від програми. Не додавайте дані до графа, який вже містить початкову вузлу. Отримуйте іменовані вихідні дані, коли граф їх надає; дозвольте кінцевим вузлам обробляти вихідні дані, коли граф закінчується кінцевою вузлою.
Використовуйте graph.run() для завдання, яке передбачає передачу даних від початкової вузли до кінцевої, де граф одночасно є джерелом і приймачем даних. Використовуйте graph.build(), коли вашій програмі потрібно отримати результати, виміряти час виконання або навмисно зупинити процес.
auto run = graph.build();
while (running && run.can_pull()) {
auto sample = run.pull("detections", /*timeout_ms=*/1000);
if (!sample) {
continue;
}
handle(*sample);
}
run.close();
Для джерел, які працюють тривалий час, налаштуйте свою програму таким чином, щоб вона визначала, коли потрібно вийти з циклу, і викликала close(). Тайм-аут означає, що протягом цього проміжку часу не було отримано жодних даних; це не завжди означає, що джерело завершило роботу.
Запустити один раз.
Використовуйте Graph.run(...), коли вам потрібна одна синхронна операція надсилання/отримання даних у графі.
simaai::neat::Graph graph("classifier");
graph.add(simaai::neat::nodes::Input("image"));
graph.add(model);
graph.add(simaai::neat::nodes::Output("classes"));
simaai::neat::TensorList outputs = graph.run(std::vector<cv::Mat>{frame});
У Python передавайте список або кортеж. graph.run([tensor]) означає «один вхідний граф», а не «додайте розмірність пакета».
Створіть багаторазовий сценарій виконання.
Використовуйте Graph.build(...), коли ваш застосунок керує циклом.
auto run = graph.build();
run.push("image", std::vector<cv::Mat>{frame});
simaai::neat::TensorList outputs = run.pull_tensors("classes", /*timeout_ms=*/2000);
run.close_input();
while (auto sample = run.pull(/*timeout_ms=*/100)) {
// Drain remaining output after end-of-input.
}
run.close();
Використовуйте close_input(), коли завершите передачу даних і захочете, щоб поточна робота завершилася. Використовуйте close(), коли захочете зупинити виконання; у C++ також передбачено stop() як команду для негайної зупинки.
Використовуйте повторно використовуваний блок для обробки запитів/відповідей.
Graph.run(...) — це найкоротший одноразовий шлях. Якщо вам потрібна однакова структура запиту/відповіді без щоразу пере будови графа, створіть один Run, який можна повторно використовувати, і викликайте run.run(...).
Використовуйте це, коли:
- граф залишається активним протягом багатьох запитів;
- кожний запит все одно має чекати на отримання власного результату;
- наразі вам не потрібні окремі потоки для виробника та споживача.
auto run = graph.build();
for (const auto& frame : frames) {
simaai::neat::TensorList outputs = run.run(
std::vector<cv::Mat>{frame},
/*timeout_ms=*/2000);
handle(outputs);
}
run.close();
Перейдіть від run.run(...) до явного використання push(...) / pull(...), коли вам потрібна обробка даних у процесі, потоки «виробник/споживач», неблокуючий механізм передачі даних, іменоване опитування вихідних даних або керування вивантаженням.
Перевірте кінцеві точки середовища виконання.
Перш ніж передавати дані в багатовхідний граф, запитайте у Run, які імена він приймає.
auto run = graph.build();
for (const auto& name : run.input_names()) {
std::cout << "input: " << name << "\n";
}
for (const auto& name : run.output_names()) {
std::cout << "output: " << name << "\n";
}
Якщо в графі є більше одного загальнодоступного входу або виходу, використовуйте іменовані push(...) та pull(...). Не потрібно, щоб Neat намагався вгадати, який саме провід ви мали на увазі.