このチュートリアルでは、MINTOライブラリのロギング機能と様々なロギング制御メソッドの使い方を説明します。
1. 基本的なログ出力¶
基本的なログ出力機能を試してみましょう。
import time
import jijmodeling as jm
import ommx_openjij_adapter as oj_ad
from minto import Experiment
# Create an experiment with logging enabled
exp = Experiment(
name="tutorial_experiment",
auto_saving=False, # Disable saving for tutorial
)
def create_problem():
n = jm.Placeholder("n")
rows = jm.Placeholder("rows", ndim=1)
cols = jm.Placeholder("cols", ndim=1)
value = jm.Placeholder("value", ndim=1)
nnz = value.len_at(0)
problem = jm.Problem("qubo")
i = jm.Element("i", nnz)
x = jm.BinaryVar("x", shape=(n,))
problem += jm.sum(i, value[i] * x[rows[i]] * x[cols[i]])
return problem
def qubo_instance_data():
n = 5
rows = [0, 1, 2, 3, 4]
cols = [1, 2, 3, 4, 0]
value = [1.0, -1.0, 2.0, -2.0, 3.0]
return {"n": n, "rows": rows, "cols": cols, "value": value}
interpreter = jm.Interpreter(qubo_instance_data())
instance = interpreter.eval_problem(create_problem())
# Create and execute a run
run = exp.run()
with run:
num_sweeps = 1000
run.log_parameter("solver_type", "SimulatedAnnealing")
run.log_parameter("temperature", 1.0)
run.log_parameter("num_sweeps", num_sweeps)
solution = oj_ad.OMMXOpenJijSAAdapter.solve(instance, num_sweeps=num_sweeps)
run.log_solution(solution)
# Finish the experiment
exp.finish_experiment()2. ログ設定のカスタマイズ¶
ログの表示方法をカスタマイズしてみましょう。
from minto.logging_config import LogConfig, LogFormat, LogLevel
# Simple log configuration
simple_config = LogConfig(
format=LogFormat.SIMPLE, show_timestamps=False, show_icons=False, show_colors=False
)
print("=== Simple Log Configuration ===")
exp_simple = Experiment(
name="simple_experiment",
verbose_logging=True,
log_config=simple_config,
auto_saving=False,
collect_environment=False,
)
run = exp_simple.run()
with run:
run.log_parameter("method", "QAOA")
run.log_parameter("layers", 3)
exp_simple.finish_experiment()# Detailed log configuration
detailed_config = LogConfig(
level=LogLevel.DEBUG,
format=LogFormat.DETAILED,
show_timestamps=True,
show_icons=True,
show_colors=False, # Colors are often disabled in Jupyter environments
max_parameter_length=200, # Increase maximum parameter display length
)
print("\n=== Detailed Log Configuration ===")
exp_detailed = Experiment(
name="detailed_experiment",
verbose_logging=True,
log_config=detailed_config,
auto_saving=False,
collect_environment=False,
)
run = exp_detailed.run()
with run:
run.log_parameter("algorithm", "Quantum Annealing")
run.log_parameter("annealing_time", 20.0)
# Log objects
problem_data = {"variables": 100, "constraints": 50, "objective": "minimize"}
run.log_object("problem_instance", problem_data)
exp_detailed.finish_experiment()3. ソルバー実行ログ¶
ソルバーの実行時間とパラメータを、自動的に記録してみましょう。
# Define QUBO problem using jijmodeling (same as in basic example)
def create_problem():
n = jm.Placeholder("n")
rows = jm.Placeholder("rows", ndim=1)
cols = jm.Placeholder("cols", ndim=1)
value = jm.Placeholder("value", ndim=1)
nnz = value.len_at(0)
problem = jm.Problem("qubo")
i = jm.Element("i", nnz)
x = jm.BinaryVar("x", shape=(n,))
problem += jm.sum(i, value[i] * x[rows[i]] * x[cols[i]])
return problem
def qubo_instance_data():
n = 5
rows = [0, 1, 2, 3, 4]
cols = [1, 2, 3, 4, 0]
value = [1.0, -1.0, 2.0, -2.0, 3.0]
return {"n": n, "rows": rows, "cols": cols, "value": value}
# Prepare the problem instance
interpreter = jm.Interpreter(qubo_instance_data())
instance = interpreter.eval_problem(create_problem())
# Execute solver logging with real OpenJij solver
exp = Experiment(
name="solver_logging_experiment",
verbose_logging=True,
auto_saving=False,
collect_environment=False,
)
run = exp.run()
with run:
# Method 1: Manual parameter logging and solver execution
run.log_parameter("solver_type", "SimulatedAnnealing")
run.log_parameter("num_sweeps", 2000)
run.log_parameter("temperature", 1.0)
# Execute solver directly
solution = oj_ad.OMMXOpenJijSAAdapter.solve(instance, num_sweeps=2000)
run.log_solution(solution)
print("\n--- Using log_solver wrapper ---")
# Method 2: Using log_solver wrapper for automatic parameter logging
def solve_with_openjij(instance, num_sweeps=1000, seed=None):
"""Wrapper function for OpenJij solver"""
return oj_ad.OMMXOpenJijSAAdapter.solve(
instance, num_sweeps=num_sweeps, seed=seed
)
# Wrap the solver function to automatically log parameters and execution time
wrapped_solver = run.log_solver(
"OpenJij_SA",
solve_with_openjij,
exclude_params=["seed"], # Exclude seed from logging if desired
)
# Execute solver with automatic parameter and timing logging
solution2 = wrapped_solver(instance=instance, num_sweeps=1500, seed=42)
run.log_solution(solution2)
exp.finish_experiment()4. 複数実行¶
複数回実行し、階層的なログ表示を確認してみましょう。
# Parameter sweep experiment
exp = Experiment(
name="parameter_sweep",
verbose_logging=True,
auto_saving=False,
collect_environment=False,
)
# Execute with different temperature parameters
temperatures = [0.1, 0.5, 1.0, 2.0]
for i, temp in enumerate(temperatures):
run = exp.run()
with run:
run.log_parameter("temperature", temp)
run.log_parameter("algorithm", "Simulated Annealing")
run.log_parameter("max_iterations", 1000)
# Execute dummy optimization
time.sleep(0.05) # Simulate computation time
# Simulate results based on temperature
import random
energy = random.uniform(-100, -50) * (1 + temp)
run.log_solution("best_solution", f"energy: {energy:.2f}")
run.log_parameter("final_energy", energy)
exp.finish_experiment()5. グローバル設定の使用¶
グローバルログを設定し、複数の実験間でそれを共有する方法を示します。
from minto.logger import configure_logging, get_logger
# Global log configuration
configure_logging(
enabled=True,
level=LogLevel.INFO,
show_timestamps=True,
show_icons=True,
show_colors=False, # For Jupyter environments
)
print("=== Experiment 1 using Global Configuration ===")
exp1 = Experiment(
name="global_config_exp1",
verbose_logging=True, # Global configuration is automatically applied
auto_saving=False,
collect_environment=False,
)
run = exp1.run()
with run:
run.log_parameter("method", "Genetic Algorithm")
run.log_parameter("population_size", 100)
exp1.finish_experiment()
print("\n=== Experiment 2 using Global Configuration ===")
exp2 = Experiment(
name="global_config_exp2",
verbose_logging=True, # Same global configuration is applied
auto_saving=False,
collect_environment=False,
)
run = exp2.run()
with run:
run.log_parameter("method", "Particle Swarm Optimization")
run.log_parameter("swarm_size", 50)
exp2.finish_experiment()6. 直接的なロガーの利用¶
Experiment/Runクラスを用いずに、ロガーを直接利用する方法も示します。
# Get the global logger
logger = get_logger()
print("=== Direct Logger Usage ===")
# Manual experiment logging
logger.log_experiment_start("manual_experiment")
# Manual run logging
logger.log_run_start(0)
logger.log_parameter("manual_param", "direct_logging")
logger.log_object("custom_object", {"type": "manual", "value": 42})
# Log solver execution
logger.log_solver("manual_solver", execution_time=1.5)
# End run and experiment
logger.log_run_end(0, 2.0)
logger.log_experiment_end("manual_experiment", 2.0, 1)7. 環境固有の設定例¶
開発環境・本番環境・CI環境など、それぞれの環境に適した推奨設定を確認してみましょう。
# Development environment configuration
dev_config = LogConfig(
level=LogLevel.DEBUG,
format=LogFormat.DETAILED,
show_timestamps=True,
show_icons=True,
show_colors=False, # For Jupyter
max_parameter_length=300, # Allow longer parameter values in development
)
print("=== Development Environment Configuration ===")
exp_dev = Experiment(
name="development_test",
verbose_logging=True,
log_config=dev_config,
auto_saving=False,
collect_environment=False,
)
run = exp_dev.run()
with run:
run.log_parameter("debug_mode", True)
run.log_parameter("verbose_output", True)
exp_dev.finish_experiment()
# Production environment configuration
prod_config = LogConfig(
level=LogLevel.WARNING,
format=LogFormat.MINIMAL, # Use MINIMAL instead of COMPACT
show_timestamps=True,
show_icons=False,
show_colors=False,
max_parameter_length=50, # Limit parameter length in production
)
print("\n=== Production Environment Configuration ===")
exp_prod = Experiment(
name="production_test",
verbose_logging=True,
log_config=prod_config,
auto_saving=False,
collect_environment=False,
)
run = exp_prod.run()
with run:
run.log_parameter("production_mode", True)
# Only WARNING level and above are displayed, so normal parameter logs won't be shown
exp_prod.finish_experiment()まとめ¶
このチュートリアルでは、Mintoライブラリのロギング機能について学びました。
基本的なログ出力:
verbose_logging=Trueにより、簡単にロギングできますカスタム設定:
LogConfigを用いて、ログ表示の詳細を設定することができますソルバーロギング:
log_solverにより、自動でソルバー実行のロギングが可能です階層的なログ表示: 複数回実行を行った場合にも、明確な階層構造を表示してくれます
グローバル設定:
configure_loggingを用いることで、一括での設定ができますダイレクトロガー: 低レベルAPIにより、柔軟な設定が可能です
環境適応: 開発環境と本番環境への最適化
これらの機能を活用することで、実験の進行状況を効率的にモニタリングし、デバッグと最適化作業を大幅に改善することができます。