Skip to content

env_reporter

orchard.core.logger.env_reporter

Environment Reporter.

Provides formatted logging for experiment initialization and environment configuration. Transforms complex configuration states and hardware objects into structured, human-readable log output.

The Reporter is invoked by RootOrchestrator during initialization to produce a comprehensive baseline status report covering hardware, dataset, strategy, hyperparameters, and filesystem configuration.

ReporterProtocol

Bases: Protocol

Protocol for environment reporting, allowing mocking in tests.

log_initial_status(logger_instance, cfg, paths, device, applied_threads, num_workers)

Logs the initial status of the environment.

Parameters:

Name Type Description Default
logger_instance Logger

The logger instance used to log the status.

required
cfg 'Config'

The configuration object containing environment settings.

required
paths 'RunPaths'

The paths object with directories for the run.

required
device device

The device (e.g., CPU or GPU) to be used for processing.

required
applied_threads int

The number of threads allocated for processing.

required
num_workers int

The number of worker processes to use.

required
Source code in orchard/core/logger/env_reporter.py
def log_initial_status(
    self,
    logger_instance: logging.Logger,
    cfg: "Config",
    paths: "RunPaths",
    device: torch.device,
    applied_threads: int,
    num_workers: int,
) -> None:
    """
    Logs the initial status of the environment.

    Args:
        logger_instance: The logger instance used to log the status.
        cfg: The configuration object containing environment settings.
        paths: The paths object with directories for the run.
        device: The device (e.g., CPU or GPU) to be used for processing.
        applied_threads: The number of threads allocated for processing.
        num_workers: The number of worker processes to use.
    """
    ...  # pragma: no cover

Reporter

Bases: BaseModel

Centralized logging and reporting utility for experiment lifecycle events.

Transforms complex configuration states and hardware objects into human-readable logs. Called by Orchestrator during initialization.

log_phase_header(log, title, style=None) staticmethod

Log a centered phase header with separator lines.

Parameters:

Name Type Description Default
log Logger

Logger instance to write to.

required
title str

Header text (will be uppercased and centered).

required
style str | None

Separator string (defaults to LogStyle.HEAVY).

None
Source code in orchard/core/logger/env_reporter.py
@staticmethod
def log_phase_header(
    log: logging.Logger,
    title: str,
    style: str | None = None,
) -> None:
    """
    Log a centered phase header with separator lines.

    Args:
        log: Logger instance to write to.
        title: Header text (will be uppercased and centered).
        style: Separator string (defaults to ``LogStyle.HEAVY``).
    """
    sep = style if style is not None else LogStyle.HEAVY
    log.info("")
    log.info(sep)
    log.info(title.center(LogStyle.HEADER_WIDTH))
    log.info(sep)

log_initial_status(logger_instance, cfg, paths, device, applied_threads, num_workers)

Logs verified baseline environment configuration upon initialization.

Parameters:

Name Type Description Default
logger_instance Logger

Active experiment logger

required
cfg 'Config'

Validated global configuration manifest

required
paths 'RunPaths'

Dynamic path orchestrator for current session

required
device 'torch.device'

Resolved PyTorch compute device

required
applied_threads int

Number of intra-op threads assigned

required
num_workers int

Number of DataLoader workers

required
Source code in orchard/core/logger/env_reporter.py
def log_initial_status(
    self,
    logger_instance: logging.Logger,
    cfg: "Config",
    paths: "RunPaths",
    device: "torch.device",
    applied_threads: int,
    num_workers: int,
) -> None:
    """
    Logs verified baseline environment configuration upon initialization.

    Args:
        logger_instance: Active experiment logger
        cfg: Validated global configuration manifest
        paths: Dynamic path orchestrator for current session
        device: Resolved PyTorch compute device
        applied_threads: Number of intra-op threads assigned
        num_workers: Number of DataLoader workers
    """
    # Header Block
    Reporter.log_phase_header(
        logger_instance, "ENVIRONMENT INITIALIZATION"
    )  # pragma: no mutate

    I = LogStyle.INDENT  # noqa: E741
    A = LogStyle.ARROW

    # Experiment identifier
    logger_instance.info("%s%s %-18s: %s", I, A, "Experiment", cfg.run_slug)
    logger_instance.info("")

    # Task Section
    logger_instance.info("[TASK]")
    logger_instance.info("%s%s %-18s: %s", I, A, "Type", cfg.task_type.capitalize())
    logger_instance.info("")

    # Hardware Section
    self._log_hardware_section(logger_instance, cfg, device, applied_threads, num_workers)
    logger_instance.info("")

    # Dataset Section
    self._log_dataset_section(logger_instance, cfg)
    logger_instance.info("")

    # Strategy Section
    self._log_strategy_section(logger_instance, cfg, device)
    logger_instance.info("")

    # Hyperparameters Section
    logger_instance.info("[HYPERPARAMETERS]")
    logger_instance.info("%s%s %-18s: %s", I, A, "Epochs", cfg.training.epochs)
    logger_instance.info("%s%s %-18s: %s", I, A, "Batch Size", cfg.training.batch_size)
    lr = cfg.training.learning_rate
    lr_str = f"{lr:.2e}" if isinstance(lr, (float, int)) else str(lr)
    logger_instance.info("%s%s %-18s: %s", I, A, "Initial LR", lr_str)
    logger_instance.info("")

    # Tracking Section (only if configured)
    self._log_tracking_section(logger_instance, cfg)

    # Optimization Section (only if configured)
    self._log_optimization_section(logger_instance, cfg)

    # Export Section (only if configured)
    self._log_export_section(logger_instance, cfg)

    # Filesystem Section
    logger_instance.info("[FILESYSTEM]")
    logger_instance.info("%s%s %-18s: %s", I, A, "Run Root", paths.root.name)
    logger_instance.info(
        "%s%s %-18s: config.yaml, requirements.txt, git_info.txt", I, A, "Manifest"
    )

    # Closing separator
    logger_instance.info(LogStyle.HEAVY)
    logger_instance.info("")