Skip to content

Refactor: redesign log system around V0..V9 + Python single source#703

Merged
jvjhfhg merged 1 commit intohw-native-sys:mainfrom
ChaoWao:refactor/redesign-log-system-v0-v9
Apr 30, 2026
Merged

Refactor: redesign log system around V0..V9 + Python single source#703
jvjhfhg merged 1 commit intohw-native-sys:mainfrom
ChaoWao:refactor/redesign-log-system-v0-v9

Conversation

@ChaoWao
Copy link
Copy Markdown
Collaborator

@ChaoWao ChaoWao commented Apr 30, 2026

Summary

Replace the env-var-driven log config (PTO_LOG_LEVEL / SIMPLER_LOG_LEVEL / PTO_LOG_FILE) with the Python simpler logger as single source of truth, expose INFO sub-verbosity tiers V0..V9 mapped into Python's logging integer space (15..24 with V5=20=INFO), and unify severity + verbosity into one user-facing setLevel() call.

User API

import simpler, logging

logging.getLogger("simpler").setLevel(simpler.V3)   # V3..V9 visible
logging.getLogger("simpler").setLevel(simpler.NUL)  # silent

Integer layout

level use
DEBUG 10 Python logging.DEBUG
simpler.V0 .. V4 15..19 sub-INFO, more verbose
simpler.V5 = logging.INFO 20 default threshold
simpler.V6 .. V9 21..24 above-INFO, more must-see
WARNING / ERROR 30 / 40 Python standard
simpler.NUL 60 suppress all

Plumbing

  • python/simpler/_log.py: V0..V9 / NUL constants, _split_threshold, sets the simpler logger to V5 at import (avoids root WARNING inheritance).
  • Worker.init() reads the logger via _log.get_current_config() and forwards (severity, info_v) to ChipWorker::init(..., log_level, log_info_v) once.
  • New simpler_init(ctx, log_level, log_info_v) C entry in each platform SO: pushes config to HostLogger + runner state; on onboard also calls dlog_setlevel(-1, sev, 0) unless ASCEND_GLOBAL_LOG_LEVEL is externally set.
  • AICPU receives the same values via KernelArgs.{log_level, log_info_v} (cross-process).
  • run_runtime no longer carries log args; CallConfig wire format reverts to 5 int32 + 1024-byte output_prefix.

C++ macros

  • LOG_DEBUG / LOG_WARN / LOG_ERROR + 10 fixed LOG_INFO_V0..V9.
  • LOG_ALWAYS / LOG_INFO sugar / unified_log_always / dev_log_always all removed; ops table swaps log_info + log_always for log_info_v.

Behavior change

  • Old LOG_INFO sites mass-migrated to LOG_INFO_V0 (default-hidden noise).
  • Old LOG_ALWAYS sites mass-migrated to LOG_INFO_V9 (must-see; shown by default at V5 threshold).
  • All log output goes to stderr (host + sim AICPU). Onboard AICPU still routes through CANN dlog (severity managed by CANN, verbosity by simpler).

CI / scripts grepping legacy INFO output: pass --log-level v0 (or set the simpler Python logger to simpler.V0) to see the verbose tier.

Test plan

  • C++ build green (a5sim + a2a3sim, host + onboard SOs)
  • cpput suite: 21/21 pass (build/ut_cpp ctest)
  • python UT suite: 212 pass / 8 skip / 4 deselect (torch-only)
  • Smoke: simpler.V* constants, CallConfig no longer has log fields, get_current_config() splits correctly, default V5
  • Hardware CI (a2a3 / a5 onboard) — to be exercised in PR CI

@ChaoWao ChaoWao force-pushed the refactor/redesign-log-system-v0-v9 branch from 6f325f3 to 0310987 Compare April 30, 2026 02:48
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a unified logging system that synchronizes log levels across Python, host C++, and AICPU device code, replacing the environment-variable-based PTO_LOG_LEVEL with a single source of truth in the Python simpler logger. The new system uses two orthogonal axes (severity and INFO sub-verbosity) which are propagated through KernelArgs to the device. Feedback suggests optimizing the host-side unified logging implementation by passing va_list directly to HostLogger to avoid redundant formatting steps and intermediate buffer copies.

Comment thread src/a2a3/platform/src/host/unified_log_host.cpp
Comment thread src/a5/platform/src/host/unified_log_host.cpp
Replace the env-var-driven log config (PTO_LOG_LEVEL / SIMPLER_LOG_LEVEL /
PTO_LOG_FILE) with the Python "simpler" logger as single source of truth,
expose INFO sub-verbosity tiers V0..V9 mapped into Python's logging integer
space (15..24 with V5=20=INFO), and unify severity + verbosity into one
user-facing setLevel() call.

User API:

    import simpler, logging
    logging.getLogger("simpler").setLevel(simpler.V3)   # V3..V9 visible
    logging.getLogger("simpler").setLevel(simpler.NUL)  # silent

Plumbing:
- python/simpler/_log.py: V0..V9 / NUL constants, _split_threshold, sets the
  "simpler" logger to V5 at import (avoids root WARNING inheritance).
- Worker.init() reads the logger via _log.get_current_config() and forwards
  (severity, info_v) to ChipWorker::init(..., log_level, log_info_v) once.
- New simpler_init(ctx, log_level, log_info_v) C entry in each platform SO:
  pushes config to HostLogger + runner state; on onboard also calls
  dlog_setlevel(-1, sev, 0) unless ASCEND_GLOBAL_LOG_LEVEL is externally set.
- AICPU receives the same values via KernelArgs.{log_level, log_info_v}
  (cross-process).
- run_runtime no longer carries log args; CallConfig wire format reverts
  to 5 int32 + 1024-byte output_prefix.

C++ macros:
- LOG_DEBUG / LOG_WARN / LOG_ERROR + 10 fixed LOG_INFO_V0..V9.
- LOG_ALWAYS / LOG_INFO sugar / unified_log_always / dev_log_always all
  removed; ops table swaps log_info+log_always for log_info_v.

Behavior change:
- Old LOG_INFO sites mass-migrated to LOG_INFO_V0 (default-hidden noise).
- Old LOG_ALWAYS sites mass-migrated to LOG_INFO_V9 (must-see; shown by
  default at V5 threshold).
- All log output goes to stderr (host + sim AICPU). Onboard AICPU still
  routes through CANN dlog (severity managed by CANN, verbosity by simpler).

CI / scripts grepping legacy INFO output: pass --log-level v0 (or set the
"simpler" Python logger to simpler.V0) to see the verbose tier.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ChaoWao ChaoWao force-pushed the refactor/redesign-log-system-v0-v9 branch from 0310987 to b2f65a3 Compare April 30, 2026 03:20
@jvjhfhg jvjhfhg merged commit 86a666c into hw-native-sys:main Apr 30, 2026
14 checks passed
@ChaoWao ChaoWao mentioned this pull request Apr 30, 2026
4 tasks
ChaoWao added a commit to ChaoWao/simpler-fork that referenced this pull request Apr 30, 2026
Three issues reported after hw-native-sys#703 merged:

1. `pytest --log-level v0` was rejected ("'V0' is not recognized as a
   logging level name"). pytest's CLI validator uses
   `int(getattr(logging, name.upper(), name))`, so the level names must be
   exposed as **attributes on the logging module** — `logging.addLevelName`
   alone is not enough. Set both: keep `addLevelName` for nice
   `%(levelname)s` formatting, and `setattr(logging, ...)` so pytest's
   getattr lookup resolves. Mirror the registration in conftest.py top-level
   too — pytest validates --log-level before conftest's first `import
   simpler`. Also expose `logging.NULL` for `pytest --log-level null`
   (pytest upcases the value before lookup).

2. L3/L4 chip subprocesses ignored the user's simpler logger level. The
   parent's `Worker.init()` snapshot was only forwarded along the L2 path;
   `_chip_process_loop` and `_chip_process_loop_with_bootstrap` called
   `ChipWorker.init()` with the binding defaults (V5/INFO). Added
   `log_level` / `log_info_v` parameters to both child loops and snapshot
   the parent's logger config once before the fork loop in
   `_start_hierarchical`, then pass it explicitly into each forked child.

3. `docs/testing.md` Configuration Sources paragraph still claimed
   `Worker.run()` snapshots into `CallConfig.log_level` / `log_info_v`
   per-run. Those CallConfig fields were dropped in C4; the actual snapshot
   is one-shot at `Worker.init()`. Rewrote the paragraph to match,
   documented the L3/L4 fork plumbing, and updated the
   `--log-level` row in the Option Reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ChaoWao added a commit that referenced this pull request Apr 30, 2026
Three issues reported after #703 merged:

1. `pytest --log-level v0` was rejected ("'V0' is not recognized as a
   logging level name"). pytest's CLI validator uses
   `int(getattr(logging, name.upper(), name))`, so the level names must be
   exposed as **attributes on the logging module** — `logging.addLevelName`
   alone is not enough. Set both: keep `addLevelName` for nice
   `%(levelname)s` formatting, and `setattr(logging, ...)` so pytest's
   getattr lookup resolves. Mirror the registration in conftest.py top-level
   too — pytest validates --log-level before conftest's first `import
   simpler`. Also expose `logging.NULL` for `pytest --log-level null`
   (pytest upcases the value before lookup).

2. L3/L4 chip subprocesses ignored the user's simpler logger level. The
   parent's `Worker.init()` snapshot was only forwarded along the L2 path;
   `_chip_process_loop` and `_chip_process_loop_with_bootstrap` called
   `ChipWorker.init()` with the binding defaults (V5/INFO). Added
   `log_level` / `log_info_v` parameters to both child loops and snapshot
   the parent's logger config once before the fork loop in
   `_start_hierarchical`, then pass it explicitly into each forked child.

3. `docs/testing.md` Configuration Sources paragraph still claimed
   `Worker.run()` snapshots into `CallConfig.log_level` / `log_info_v`
   per-run. Those CallConfig fields were dropped in C4; the actual snapshot
   is one-shot at `Worker.init()`. Rewrote the paragraph to match,
   documented the L3/L4 fork plumbing, and updated the
   `--log-level` row in the Option Reference.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants