Перейти до основного вмісту

Асинхронна та синхронна моделі часу

Graph і Run демонструють два способи організації роботи:

  • Одноразове виконання: Graph.run(input, ...) передає вхідні дані та очікує на вихідні дані в одному виклику. Graph.run() без вхідних даних запускає граф, що належить джерелу, до досягнення кінця обробки (EOS).
  • Повторне використання виконання: Graph.build(...) повертає активний Run. Ваша програма передає вхідні дані, отримує вихідні дані, закриває вхідний потік, очищає буфер, здійснює вимірювання та зупиняє виконання.

Обидва режими використовують один і той самий Graph план і однакове апаратне забезпечення. Різниця полягає в тому, кому належить цикл.

Режим одноразової зйомки.

Використовуйте одноразовий режим, коли у вас є лише один вхідний параметр і ви хочете отримати найкоротший правильний шлях.

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 out = graph.run(
simaai::neat::TensorList{image_tensor});

Для графа, що належить джерелу, викличте Graph.run() без передачі вхідних даних:

simaai::neat::Graph graph("file_job");
graph.add(source_fragment);
graph.add(model);
graph.add(sink_fragment);

graph.run(); // Blocks until EOS or error.

Використовуйте одноразовий режим для:

  • тестування на основні функціональні можливості;
  • короткі цикли перевірки;
  • завдання, що належать до вихідного коду, і які мають бути виконані до кінця;
  • код, який не повинен керувати довготривалим дескриптором середовища виконання.

Режим повторного запуску

Використовуйте Graph.build(...), коли ваш застосунок керує циклом.

auto run = graph.build();

while (have_more_inputs()) {
run.push("image", simaai::neat::TensorList{next_tensor()});

if (auto out = run.pull("classes", /*timeout_ms=*/0)) {
consume(*out);
}
}

run.close_input();
while (auto out = run.pull("classes", /*timeout_ms=*/1000)) {
consume(*out);
}
run.close();

Використовуйте режим багаторазового використання для:

  • відео в реальному часі, RTSP або відеосигнал з камери;
  • потокова обробка, де застосунок контролює темп;
  • графи з кількома входами або кількома виходами;
  • тестування продуктивності;
  • вимірювання, експорт, злив і контроль зупинки.

Час спрацювання кнопки

Run::push(...) завершує роботу після того, як вхідні дані прийнято на межі графа. Він не чекає, поки ці дані оброблять усі вузли.

Коли черга вхідних даних заповнена:

  • OverflowPolicy::Block створює зворотний тиск на виробника;
  • OverflowPolicy::DropIncoming відхиляє нові вхідні дані.
  • OverflowPolicy::KeepLatest видаляє старіші елементи з черги вхідних даних, щоб забезпечити актуальність поточного шляху обробки;
  • try_push(...) повертає false, а не блокує виконання.

Оберіть політику, яка відповідає джерелу. Для обробки окремих файлів і пакетних завдань зазвичай потрібна політика Block. Для прямих трансляцій зазвичай потрібна політика, що забезпечує актуальність даних.

Зменшити кут випередження запалювання.

Run::pull(...) повертає наступний доступний Sample з вихідної межі.

Використовуйте зручну перевантажену версію, коли час очікування та кінець потоку можуть використовувати один і той самий шлях «відсутність зразка»:

if (auto sample = run.pull("classes", /*timeout_ms=*/1000)) {
consume(*sample);
}

Використовуйте структуроване перевантаження стану, коли час очікування, закриття та помилки мають оброблятися по-різному:

simaai::neat::Sample sample;
simaai::neat::PullError error;

switch (run.pull("classes", /*timeout_ms=*/1000, sample, &error)) {
case simaai::neat::PullStatus::Ok:
consume(sample);
break;
case simaai::neat::PullStatus::Timeout:
break;
case simaai::neat::PullStatus::Closed:
break;
case simaai::neat::PullStatus::Error:
throw std::runtime_error(error.message);
}

Відсутні приховані резервні варіанти: для графа з кількома вихідними даними потрібна назва pull("output", ...), якщо немає єдиного однозначного вихідного значення.

Телеметрія: вимірюйте показники вашого циклу.

Використовуйте Run::start_measurement(...) навколо навантаження, яким керує ваш застосунок. Повернений MeasureReport є загальнодоступною інформацією про час виконання та містить:

  • затримка та пропускна здатність від вхідних даних до вихідних;
  • лічильники, що відстежують кількість зразків, доданих, отриманих і відкинутих під час роботи;
  • час роботи плагіна/ядра та периферійних пристроїв під час запиту в MeasureOptions;
  • за бажанням можна активувати передачу даних про споживання енергії під час виконання завдання, якщо функцію моніторингу енергоспоживання вже ввімкнено.

Зберігайте налаштування, завантаження файлів, ведення журналу для кожного кадру та експорт звітів поза межами вимірюваного критичного циклу, якщо питання стосується загальної вартості застосування.

Для подальшого ознайомлення

  • Запустіть граф. — життєвий цикл, параметри, механізм регулювання навантаження, вимірювання та пропускна здатність.
  • Graph::run() — одноразова точка входу, що належить вихідному коду.
  • Graph::build() — точка входу для повторного виконання.
  • Run — штовхати, тягнути, закривати, зливати, зупиняти та вимірювати.