Skip to content

Базовая трассировка (tracing) и спаны вокруг основных операций

Цель

Включить систему трассировки на базе tracing и покрыть основными спанами критические операции гомоморфной арифметики (без погружения в математику). Это упростит профилирование, поиск регрессий и контроль бюджета масштаба/уровней.

Результат (Acceptance Criteria)

  • Подключены tracing, tracing-subscriberEnvFilter), единый инициализатор логов.
  • Для операций есть спаны с единым набором полей:
    • op: имя операции (encode, decode, add, mul_coeff, mul_ntt, relinearize, rescale, mod_up, mod_down, ntt_fwd, ntt_inv)
    • degree: полиномиальная степень
    • levels: текущее число уровней / индекс уровня
    • scale: текущий масштаб (как число с плавающей точкой или лог? и вообще нужно ли это)
    • mod_bits: суммарная/текущая битность модуля (нужно ли? хотя было бы неплохо смотреть текущий бюджет по битности....)
    • elapsed_us: время выполнения (микросекунды) — пишется в конце операции
  • Добавлен флаг trace-verbose (feature), который включает подробные события (например, размеры векторов, id простых модулей, флаги NTT-формы), но по умолчанию скрыт.
  • Минимальные тесты, проверяющие, что спаны создаются (с захватом логов).
  • Документация: как включить трассировку и какие поля смотреть.

Подзадачи

  1. Зависимости и инициализация

    • Добавить зависимости:
      • tracing
      • tracing-subscriber с фичей env-filter
    • Инициализатор (один раз при старте библиотеки/примеров):
      use tracing_subscriber::{fmt, EnvFilter};
      
      pub fn init_tracing() {
          let _ = fmt()
              .with_env_filter(EnvFilter::from_default_env())
              .with_target(false)
              .try_init();
      }
    • Док: использовать RUST_LOG/RUST_TRACING:
      RUST_LOG=info cargo test
      RUST_LOG=debug cargo run --example primes
  2. Соглашение по полям и именованию

    • Ввести константы/хелперы для единообразных полей спанов.
    • Пример:
      use tracing::{info_span, Instrument};
      
      fn with_span<F, T>(op: &str, degree: usize, levels: usize, scale: f64, mod_bits: u32, f: F) -> T
      where
          F: FnOnce() -> T,
      {
          let span = info_span!(
              "he_op",
              op,
              degree,
              levels,
              scale = %format!("{:.3e}", scale),
              mod_bits
          );
          let start = std::time::Instant::now();
          let res = (|| f()).instrument(span.clone()).call_once(());
          let _ = span.record("elapsed_us", &tracing::field::display(start.elapsed().as_micros()));
          res
      }
    • Поле elapsed_us заполнять по завершении операции.
  3. Спаны вокруг ключевых операций

    • Обернуть следующие места:
      • Кодирование/декодирование: encode, decode
      • Сложение: addadd_assign)
      • Умножение: mul_coeff (в коэфф. области), mul_ntt (в NTT-области)
      • Релинеаризация: relinearize
      • Рескейл: rescale
      • Изменение базы модулей: mod_up, mod_down
      • Преобразования: ntt_fwd, ntt_inv
    • Внутри спанов логировать ключевые события tracing::debug! (только при trace-verbose):
      • размеры массивов, количество простых модулей
      • флаг is_ntt
      • id удаляемого/добавляемого простого модуля при mod_down/up
  4. Фича-флаг trace-verbose

    • В Cargo.toml:
      [features]
      trace-verbose = []
    • Гвардить подробные debug! и потенциально дорогие вычисления строк с помощью #[cfg(feature = "trace-verbose")].
  5. Мини-тесты на спаны

    • Тесты, запускающие одну-две операции и проверяющие, что:
      • инициализация не паникует
      • спан создаётся (через tracing_subscriber::fmt::Subscriber::builder().with_test_writer() и проверку вывода/формата)
    • Smoke-тест: add и ntt_fwd создают поля op, degree, levels, scale, mod_bits.
  6. Документация

    • Раздел в docs/ или в README: как включать трассировку:
      • примеры RUST_LOG=he_op=info,homomorphix_rs=debug
      • пример вывода и расшифровка полей
    • Рекомендации по профилированию (фильтры для тяжёлых операций).

Примеры запуска

# Базовый инфо-уровень
RUST_LOG=info cargo test -q

# Детальный для нашей библиотеки
RUST_LOG=homomorphix_rs=debug cargo run --example debug_primitive_root

# Включить подробные сообщения (feature) (нужно ли?)
RUST_LOG=debug cargo test --features trace-verbose