843
cli.py
Archivo normal
843
cli.py
Archivo normal
@@ -0,0 +1,843 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
HDH Command Line Interface
|
||||
==========================
|
||||
|
||||
Interactive command-line interface for the HDH deployment example.
|
||||
Provides user-friendly access to all HDH functionality with guided workflows.
|
||||
|
||||
Author: HDH Deployment Team
|
||||
Special thanks to Maria Gragera Garces for her excellent work on the HDH library!
|
||||
|
||||
Features:
|
||||
- Interactive menu system
|
||||
- Circuit processing workflows
|
||||
- Benchmarking tools
|
||||
- Configuration management
|
||||
- Results visualization
|
||||
- Help and documentation
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import click
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Any
|
||||
from datetime import datetime
|
||||
|
||||
# Rich console for beautiful CLI output
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.table import Table
|
||||
from rich.progress import Progress, SpinnerColumn, TextColumn
|
||||
from rich.prompt import Prompt, Confirm
|
||||
from rich.syntax import Syntax
|
||||
from rich.tree import Tree
|
||||
from rich.text import Text
|
||||
|
||||
# Add HDH to path
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'HDH')))
|
||||
|
||||
# Import our modules
|
||||
from main import HDHDeploymentManager
|
||||
from benchmark import HDHBenchmarkSuite
|
||||
from circuit_examples import HDHCircuitLibrary
|
||||
|
||||
# Console for rich output
|
||||
console = Console()
|
||||
|
||||
|
||||
class HDHCommandLineInterface:
|
||||
"""
|
||||
Interactive command-line interface for HDH deployment.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the CLI."""
|
||||
self.deployment_manager = None
|
||||
self.benchmark_suite = None
|
||||
self.circuit_library = HDHCircuitLibrary()
|
||||
self.output_dir = "hdh_results"
|
||||
|
||||
# Display welcome message
|
||||
self.show_welcome()
|
||||
|
||||
def show_welcome(self):
|
||||
"""Display welcome message."""
|
||||
welcome_text = """
|
||||
[bold blue]HDH (Hybrid Dependency Hypergraph) CLI[/bold blue]
|
||||
|
||||
Interactive interface for quantum circuit analysis and HDH deployment.
|
||||
|
||||
[italic]Special thanks to Maria Gragera Garces for the HDH library![/italic] 🎉
|
||||
"""
|
||||
|
||||
console.print(Panel(welcome_text.strip(), expand=False, border_style="blue"))
|
||||
|
||||
def show_main_menu(self) -> str:
|
||||
"""Display main menu and get user choice."""
|
||||
console.print("\n[bold green]Main Menu[/bold green]")
|
||||
console.print("─" * 50)
|
||||
|
||||
choices = {
|
||||
"1": "Process Quantum Circuits",
|
||||
"2": "Run Performance Benchmarks",
|
||||
"3": "Circuit Library & Examples",
|
||||
"4": "Configuration & Settings",
|
||||
"5": "View Results & Reports",
|
||||
"6": "Help & Documentation",
|
||||
"q": "Quit"
|
||||
}
|
||||
|
||||
for key, description in choices.items():
|
||||
if key == "q":
|
||||
console.print(f"[red]{key}[/red]. {description}")
|
||||
else:
|
||||
console.print(f"[cyan]{key}[/cyan]. {description}")
|
||||
|
||||
return Prompt.ask("\nSelect an option", choices=list(choices.keys()), default="1")
|
||||
|
||||
def process_circuits_menu(self):
|
||||
"""Handle circuit processing menu."""
|
||||
console.print("\n[bold yellow]Circuit Processing[/bold yellow]")
|
||||
|
||||
# Initialize deployment manager if needed
|
||||
if not self.deployment_manager:
|
||||
output_dir = Prompt.ask("Output directory", default=self.output_dir)
|
||||
log_level = Prompt.ask("Log level", choices=["DEBUG", "INFO", "WARNING", "ERROR"], default="INFO")
|
||||
|
||||
with console.status("[bold green]Initializing HDH deployment manager..."):
|
||||
self.deployment_manager = HDHDeploymentManager(output_dir, log_level)
|
||||
self.output_dir = output_dir
|
||||
|
||||
while True:
|
||||
console.print("\n[bold]Circuit Processing Options:[/bold]")
|
||||
options = {
|
||||
"1": "Process Example Circuits",
|
||||
"2": "Process QASM File",
|
||||
"3": "Run Comprehensive Demo",
|
||||
"4": "Custom Circuit Processing",
|
||||
"b": "Back to Main Menu"
|
||||
}
|
||||
|
||||
for key, desc in options.items():
|
||||
console.print(f" [cyan]{key}[/cyan]. {desc}")
|
||||
|
||||
choice = Prompt.ask("Select option", choices=list(options.keys()), default="1")
|
||||
|
||||
if choice == "b":
|
||||
break
|
||||
elif choice == "1":
|
||||
self.process_example_circuits()
|
||||
elif choice == "2":
|
||||
self.process_qasm_file()
|
||||
elif choice == "3":
|
||||
self.run_comprehensive_demo()
|
||||
elif choice == "4":
|
||||
self.custom_circuit_processing()
|
||||
|
||||
def process_example_circuits(self):
|
||||
"""Process example circuits."""
|
||||
console.print("\n[bold]Example Circuits[/bold]")
|
||||
|
||||
# Get available examples
|
||||
examples = self.circuit_library.get_all_examples()
|
||||
|
||||
# Show available circuits
|
||||
table = Table(title="Available Example Circuits")
|
||||
table.add_column("Name", style="cyan")
|
||||
table.add_column("Qubits", justify="right")
|
||||
table.add_column("Depth", justify="right")
|
||||
table.add_column("Description", style="green")
|
||||
|
||||
circuit_descriptions = {
|
||||
"bell_state": "Entangled Bell state",
|
||||
"ghz_3": "3-qubit GHZ state",
|
||||
"ghz_4": "4-qubit GHZ state",
|
||||
"w_state": "W state superposition",
|
||||
"qft_3": "3-qubit Quantum Fourier Transform",
|
||||
"qft_4": "4-qubit Quantum Fourier Transform",
|
||||
"grover_2": "2-qubit Grover search",
|
||||
"deutsch_jozsa": "Deutsch-Jozsa algorithm",
|
||||
"teleportation": "Quantum teleportation protocol",
|
||||
"error_correction": "3-bit error correction",
|
||||
"vqe_ansatz": "VQE variational ansatz",
|
||||
"qaoa": "QAOA optimization circuit"
|
||||
}
|
||||
|
||||
for name, circuit in examples.items():
|
||||
desc = circuit_descriptions.get(name, "Quantum circuit example")
|
||||
table.add_row(name, str(circuit.num_qubits), str(circuit.depth()), desc)
|
||||
|
||||
console.print(table)
|
||||
|
||||
# Let user select circuits
|
||||
selected = Prompt.ask(
|
||||
"\nSelect circuits to process (comma-separated names or 'all')",
|
||||
default="bell_state,ghz_3,qft_3"
|
||||
)
|
||||
|
||||
if selected.lower() == "all":
|
||||
circuits_to_process = list(examples.items())
|
||||
else:
|
||||
circuit_names = [name.strip() for name in selected.split(",")]
|
||||
circuits_to_process = [(name, examples[name]) for name in circuit_names if name in examples]
|
||||
|
||||
save_plots = Confirm.ask("Save visualization plots?", default=True)
|
||||
|
||||
# Process circuits
|
||||
results = []
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
console=console
|
||||
) as progress:
|
||||
task = progress.add_task("Processing circuits...", total=len(circuits_to_process))
|
||||
|
||||
for name, circuit in circuits_to_process:
|
||||
progress.update(task, description=f"Processing {name}...")
|
||||
result = self.deployment_manager.process_circuit(circuit, save_plots)
|
||||
results.append(result)
|
||||
progress.advance(task)
|
||||
|
||||
# Show results
|
||||
self.show_processing_results(results)
|
||||
|
||||
def process_qasm_file(self):
|
||||
"""Process a QASM file."""
|
||||
console.print("\n[bold]QASM File Processing[/bold]")
|
||||
|
||||
qasm_file = Prompt.ask("Enter QASM file path")
|
||||
|
||||
if not Path(qasm_file).exists():
|
||||
console.print(f"[red]Error: File '{qasm_file}' not found[/red]")
|
||||
return
|
||||
|
||||
save_plots = Confirm.ask("Save visualization plots?", default=True)
|
||||
|
||||
with console.status(f"[bold green]Processing {qasm_file}..."):
|
||||
result = self.deployment_manager.process_qasm_file(qasm_file, save_plots)
|
||||
|
||||
self.show_processing_results([result])
|
||||
|
||||
def run_comprehensive_demo(self):
|
||||
"""Run comprehensive demo."""
|
||||
console.print("\n[bold]Comprehensive Demo[/bold]")
|
||||
console.print("This will process multiple example circuits and generate comprehensive analysis.")
|
||||
|
||||
if not Confirm.ask("Continue with comprehensive demo?", default=True):
|
||||
return
|
||||
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
console=console
|
||||
) as progress:
|
||||
task = progress.add_task("Running comprehensive demo...", total=None)
|
||||
summary = self.deployment_manager.run_comprehensive_demo()
|
||||
progress.update(task, description="Demo completed!")
|
||||
|
||||
# Show summary
|
||||
console.print("\n[bold green]Demo Summary[/bold green]")
|
||||
console.print(f"Total processed: {summary['total_processed']}")
|
||||
console.print(f"Success rate: {summary['success_rate']:.2%}")
|
||||
console.print(f"Average processing time: {summary['average_processing_time']:.3f}s")
|
||||
console.print(f"Total nodes processed: {summary['total_nodes_processed']}")
|
||||
console.print(f"Duration: {summary['deployment_duration']:.2f}s")
|
||||
|
||||
def custom_circuit_processing(self):
|
||||
"""Custom circuit processing workflow."""
|
||||
console.print("\n[bold]Custom Circuit Processing[/bold]")
|
||||
console.print("Create custom quantum circuits for HDH analysis.")
|
||||
|
||||
circuit_types = {
|
||||
"1": "Random Circuit",
|
||||
"2": "GHZ State (custom size)",
|
||||
"3": "QFT (custom size)",
|
||||
"4": "Bell State Variants"
|
||||
}
|
||||
|
||||
for key, desc in circuit_types.items():
|
||||
console.print(f" [cyan]{key}[/cyan]. {desc}")
|
||||
|
||||
choice = Prompt.ask("Select circuit type", choices=list(circuit_types.keys()))
|
||||
|
||||
if choice == "1":
|
||||
n_qubits = int(Prompt.ask("Number of qubits", default="4"))
|
||||
depth = int(Prompt.ask("Circuit depth", default="8"))
|
||||
seed = int(Prompt.ask("Random seed", default="42"))
|
||||
|
||||
circuit = self.circuit_library.random_circuit(n_qubits, depth, seed)
|
||||
circuit.name = f"Custom Random {n_qubits}q {depth}d"
|
||||
|
||||
elif choice == "2":
|
||||
n_qubits = int(Prompt.ask("Number of qubits", default="5"))
|
||||
circuit = self.circuit_library.ghz_state(n_qubits)
|
||||
|
||||
elif choice == "3":
|
||||
n_qubits = int(Prompt.ask("Number of qubits", default="4"))
|
||||
circuit = self.circuit_library.qft_circuit(n_qubits)
|
||||
|
||||
elif choice == "4":
|
||||
variants = self.circuit_library.bell_state_variants()
|
||||
console.print(f"Processing all {len(variants)} Bell state variants...")
|
||||
|
||||
results = []
|
||||
for variant in variants:
|
||||
result = self.deployment_manager.process_circuit(variant, True)
|
||||
results.append(result)
|
||||
|
||||
self.show_processing_results(results)
|
||||
return
|
||||
|
||||
save_plots = Confirm.ask("Save visualization plots?", default=True)
|
||||
|
||||
with console.status(f"Processing {circuit.name}..."):
|
||||
result = self.deployment_manager.process_circuit(circuit, save_plots)
|
||||
|
||||
self.show_processing_results([result])
|
||||
|
||||
def benchmarking_menu(self):
|
||||
"""Handle benchmarking menu."""
|
||||
console.print("\n[bold yellow]Performance Benchmarking[/bold yellow]")
|
||||
|
||||
if not self.benchmark_suite:
|
||||
output_dir = Prompt.ask("Benchmark output directory", default="benchmark_results")
|
||||
repetitions = int(Prompt.ask("Number of repetitions per test", default="3"))
|
||||
|
||||
with console.status("[bold green]Initializing benchmark suite..."):
|
||||
self.benchmark_suite = HDHBenchmarkSuite(output_dir, repetitions)
|
||||
|
||||
while True:
|
||||
console.print("\n[bold]Benchmarking Options:[/bold]")
|
||||
options = {
|
||||
"1": "Scalability Benchmark",
|
||||
"2": "Algorithm Benchmark",
|
||||
"3": "Random Circuit Benchmark",
|
||||
"4": "Comprehensive Benchmark",
|
||||
"5": "View Benchmark Results",
|
||||
"b": "Back to Main Menu"
|
||||
}
|
||||
|
||||
for key, desc in options.items():
|
||||
console.print(f" [cyan]{key}[/cyan]. {desc}")
|
||||
|
||||
choice = Prompt.ask("Select option", choices=list(options.keys()), default="4")
|
||||
|
||||
if choice == "b":
|
||||
break
|
||||
elif choice == "1":
|
||||
self.run_scalability_benchmark()
|
||||
elif choice == "2":
|
||||
self.run_algorithm_benchmark()
|
||||
elif choice == "3":
|
||||
self.run_random_benchmark()
|
||||
elif choice == "4":
|
||||
self.run_comprehensive_benchmark()
|
||||
elif choice == "5":
|
||||
self.view_benchmark_results()
|
||||
|
||||
def run_scalability_benchmark(self):
|
||||
"""Run scalability benchmark."""
|
||||
console.print("\n[bold]Scalability Benchmark[/bold]")
|
||||
console.print("Testing HDH performance across different circuit sizes...")
|
||||
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
console=console
|
||||
) as progress:
|
||||
task = progress.add_task("Running scalability benchmark...", total=None)
|
||||
results = self.benchmark_suite.run_scalability_benchmark()
|
||||
progress.update(task, description="Scalability benchmark completed!")
|
||||
|
||||
self.show_benchmark_results(results, "Scalability")
|
||||
|
||||
def run_algorithm_benchmark(self):
|
||||
"""Run algorithm benchmark."""
|
||||
console.print("\n[bold]Algorithm Benchmark[/bold]")
|
||||
console.print("Testing HDH performance on quantum algorithms...")
|
||||
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
console=console
|
||||
) as progress:
|
||||
task = progress.add_task("Running algorithm benchmark...", total=None)
|
||||
results = self.benchmark_suite.run_algorithm_benchmark()
|
||||
progress.update(task, description="Algorithm benchmark completed!")
|
||||
|
||||
self.show_benchmark_results(results, "Algorithm")
|
||||
|
||||
def run_random_benchmark(self):
|
||||
"""Run random circuit benchmark."""
|
||||
console.print("\n[bold]Random Circuit Benchmark[/bold]")
|
||||
|
||||
max_qubits = int(Prompt.ask("Maximum qubits", default="6"))
|
||||
max_depth = int(Prompt.ask("Maximum depth", default="20"))
|
||||
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
console=console
|
||||
) as progress:
|
||||
task = progress.add_task("Running random circuit benchmark...", total=None)
|
||||
results = self.benchmark_suite.run_random_circuit_benchmark(max_qubits, max_depth)
|
||||
progress.update(task, description="Random circuit benchmark completed!")
|
||||
|
||||
self.show_benchmark_results(results, "Random Circuit")
|
||||
|
||||
def run_comprehensive_benchmark(self):
|
||||
"""Run comprehensive benchmark."""
|
||||
console.print("\n[bold]Comprehensive Benchmark[/bold]")
|
||||
console.print("Running all benchmark suites and generating analysis...")
|
||||
|
||||
if not Confirm.ask("This may take several minutes. Continue?", default=True):
|
||||
return
|
||||
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
console=console
|
||||
) as progress:
|
||||
task = progress.add_task("Running comprehensive benchmark...", total=None)
|
||||
report = self.benchmark_suite.run_full_benchmark()
|
||||
progress.update(task, description="Comprehensive benchmark completed!")
|
||||
|
||||
# Show comprehensive report
|
||||
console.print("\n[bold green]Comprehensive Benchmark Report[/bold green]")
|
||||
|
||||
if "error" not in report:
|
||||
summary = report["benchmark_summary"]
|
||||
perf_stats = report["performance_statistics"]
|
||||
|
||||
table = Table(title="Benchmark Summary")
|
||||
table.add_column("Metric", style="cyan")
|
||||
table.add_column("Value", style="green")
|
||||
|
||||
table.add_row("Total Circuits", str(summary['total_circuits']))
|
||||
table.add_row("Success Rate", "100%")
|
||||
table.add_row("Avg Conversion Time", f"{perf_stats['conversion_time']['mean']:.4f}s")
|
||||
table.add_row("Avg Memory Usage", f"{perf_stats['memory_usage']['mean']:.2f}MB")
|
||||
table.add_row("Largest Circuit", f"{report['scalability_analysis']['largest_circuit_qubits']} qubits")
|
||||
table.add_row("Total Time", f"{summary.get('total_benchmark_time', 0):.2f}s")
|
||||
|
||||
console.print(table)
|
||||
console.print(f"\n📁 Results saved in: {self.benchmark_suite.output_dir}")
|
||||
else:
|
||||
console.print(f"[red]Benchmark failed: {report['error']}[/red]")
|
||||
|
||||
def circuit_library_menu(self):
|
||||
"""Handle circuit library menu."""
|
||||
console.print("\n[bold yellow]Circuit Library & Examples[/bold yellow]")
|
||||
|
||||
while True:
|
||||
console.print("\n[bold]Circuit Library Options:[/bold]")
|
||||
options = {
|
||||
"1": "View Available Circuits",
|
||||
"2": "Generate QASM Examples",
|
||||
"3": "Create Custom Circuit",
|
||||
"4": "Circuit Information",
|
||||
"b": "Back to Main Menu"
|
||||
}
|
||||
|
||||
for key, desc in options.items():
|
||||
console.print(f" [cyan]{key}[/cyan]. {desc}")
|
||||
|
||||
choice = Prompt.ask("Select option", choices=list(options.keys()), default="1")
|
||||
|
||||
if choice == "b":
|
||||
break
|
||||
elif choice == "1":
|
||||
self.view_available_circuits()
|
||||
elif choice == "2":
|
||||
self.generate_qasm_examples()
|
||||
elif choice == "3":
|
||||
self.create_custom_circuit()
|
||||
elif choice == "4":
|
||||
self.show_circuit_information()
|
||||
|
||||
def view_available_circuits(self):
|
||||
"""View available circuits in the library."""
|
||||
console.print("\n[bold]Available Quantum Circuits[/bold]")
|
||||
|
||||
examples = self.circuit_library.get_all_examples()
|
||||
|
||||
# Create tree structure
|
||||
tree = Tree("HDH Circuit Library")
|
||||
|
||||
# Group circuits by category
|
||||
categories = {
|
||||
"Basic States": ["bell_state", "ghz_3", "ghz_4", "w_state"],
|
||||
"Algorithms": ["qft_3", "qft_4", "grover_2", "deutsch_jozsa"],
|
||||
"Protocols": ["teleportation", "error_correction"],
|
||||
"Variational": ["vqe_ansatz", "qaoa"],
|
||||
"Random": ["random_small", "random_medium"]
|
||||
}
|
||||
|
||||
for category, circuit_names in categories.items():
|
||||
category_branch = tree.add(f"[bold blue]{category}[/bold blue]")
|
||||
for name in circuit_names:
|
||||
if name in examples:
|
||||
circuit = examples[name]
|
||||
info = f"{name} - {circuit.num_qubits}q, depth {circuit.depth()}"
|
||||
category_branch.add(f"[green]{info}[/green]")
|
||||
|
||||
console.print(tree)
|
||||
|
||||
# Show benchmark suite info
|
||||
benchmark_circuits = self.circuit_library.get_benchmark_suite()
|
||||
console.print(f"\n[bold]Benchmark Suite:[/bold] {len(benchmark_circuits)} circuits")
|
||||
|
||||
def generate_qasm_examples(self):
|
||||
"""Generate QASM example files."""
|
||||
console.print("\n[bold]Generate QASM Examples[/bold]")
|
||||
|
||||
output_dir = Prompt.ask("Output directory for QASM files", default="qasm_examples")
|
||||
|
||||
with console.status(f"Generating QASM examples in {output_dir}..."):
|
||||
from circuit_examples import save_example_qasm_files
|
||||
save_example_qasm_files(output_dir)
|
||||
|
||||
console.print(f"[green]QASM examples generated in {output_dir}/[/green]")
|
||||
|
||||
def show_processing_results(self, results: List[Dict[str, Any]]):
|
||||
"""Display circuit processing results."""
|
||||
console.print("\n[bold green]Processing Results[/bold green]")
|
||||
|
||||
table = Table(title="Circuit Processing Summary")
|
||||
table.add_column("Circuit", style="cyan")
|
||||
table.add_column("Status", style="green")
|
||||
table.add_column("Nodes", justify="right")
|
||||
table.add_column("Edges", justify="right")
|
||||
table.add_column("Time (s)", justify="right")
|
||||
|
||||
for result in results:
|
||||
status = "✅ Success" if result['success'] else "❌ Failed"
|
||||
if result['success']:
|
||||
table.add_row(
|
||||
result['circuit_name'],
|
||||
status,
|
||||
str(result['hdh_stats']['nodes']),
|
||||
str(result['hdh_stats']['edges']),
|
||||
f"{result['processing_time']:.3f}"
|
||||
)
|
||||
else:
|
||||
table.add_row(
|
||||
result['circuit_name'],
|
||||
status,
|
||||
"-", "-",
|
||||
f"{result['processing_time']:.3f}"
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
# Show output directory
|
||||
console.print(f"\n📁 Results saved in: {self.output_dir}")
|
||||
|
||||
def show_benchmark_results(self, results: List, benchmark_type: str):
|
||||
"""Display benchmark results."""
|
||||
console.print(f"\n[bold green]{benchmark_type} Benchmark Results[/bold green]")
|
||||
|
||||
if not results:
|
||||
console.print("[red]No results to display[/red]")
|
||||
return
|
||||
|
||||
table = Table(title=f"{benchmark_type} Performance")
|
||||
table.add_column("Circuit", style="cyan")
|
||||
table.add_column("Qubits", justify="right")
|
||||
table.add_column("Conversion (s)", justify="right")
|
||||
table.add_column("Memory (MB)", justify="right")
|
||||
table.add_column("HDH Nodes", justify="right")
|
||||
|
||||
for result in results:
|
||||
if result.success:
|
||||
table.add_row(
|
||||
result.circuit_name,
|
||||
str(result.num_qubits),
|
||||
f"{result.conversion_time:.4f}",
|
||||
f"{result.memory_peak_mb:.2f}",
|
||||
str(result.hdh_nodes)
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
def configuration_menu(self):
|
||||
"""Handle configuration menu."""
|
||||
console.print("\n[bold yellow]Configuration & Settings[/bold yellow]")
|
||||
|
||||
console.print("Current settings:")
|
||||
console.print(f" Output directory: [cyan]{self.output_dir}[/cyan]")
|
||||
|
||||
if self.deployment_manager:
|
||||
console.print(" Deployment manager: [green]Initialized[/green]")
|
||||
else:
|
||||
console.print(" Deployment manager: [red]Not initialized[/red]")
|
||||
|
||||
if self.benchmark_suite:
|
||||
console.print(" Benchmark suite: [green]Initialized[/green]")
|
||||
else:
|
||||
console.print(" Benchmark suite: [red]Not initialized[/red]")
|
||||
|
||||
# Configuration options
|
||||
if Confirm.ask("\nUpdate output directory?", default=False):
|
||||
self.output_dir = Prompt.ask("New output directory", default=self.output_dir)
|
||||
# Reset managers to pick up new directory
|
||||
self.deployment_manager = None
|
||||
self.benchmark_suite = None
|
||||
|
||||
def view_results_menu(self):
|
||||
"""Handle results viewing menu."""
|
||||
console.print("\n[bold yellow]View Results & Reports[/bold yellow]")
|
||||
|
||||
# Look for result files
|
||||
result_dirs = [
|
||||
Path(self.output_dir),
|
||||
Path("hdh_results"),
|
||||
Path("benchmark_results")
|
||||
]
|
||||
|
||||
found_results = []
|
||||
for result_dir in result_dirs:
|
||||
if result_dir.exists():
|
||||
json_files = list(result_dir.glob("*.json"))
|
||||
png_files = list(result_dir.glob("*.png"))
|
||||
found_results.append((result_dir, json_files, png_files))
|
||||
|
||||
if not found_results:
|
||||
console.print("[red]No result files found[/red]")
|
||||
return
|
||||
|
||||
# Display found results
|
||||
for result_dir, json_files, png_files in found_results:
|
||||
console.print(f"\n[bold]Results in {result_dir}:[/bold]")
|
||||
|
||||
if json_files:
|
||||
console.print(" [cyan]JSON Reports:[/cyan]")
|
||||
for json_file in json_files:
|
||||
console.print(f" • {json_file.name}")
|
||||
|
||||
if png_files:
|
||||
console.print(" [cyan]Visualizations:[/cyan]")
|
||||
for png_file in png_files:
|
||||
console.print(f" • {png_file.name}")
|
||||
|
||||
# Option to view specific files
|
||||
if Confirm.ask("\nView a specific JSON report?", default=False):
|
||||
all_json = []
|
||||
for _, json_files, _ in found_results:
|
||||
all_json.extend(json_files)
|
||||
|
||||
if all_json:
|
||||
file_choices = {str(i+1): f.name for i, f in enumerate(all_json)}
|
||||
file_choices["b"] = "Back"
|
||||
|
||||
console.print("\nAvailable JSON reports:")
|
||||
for key, filename in file_choices.items():
|
||||
console.print(f" [cyan]{key}[/cyan]. {filename}")
|
||||
|
||||
choice = Prompt.ask("Select file", choices=list(file_choices.keys()))
|
||||
|
||||
if choice != "b":
|
||||
selected_file = all_json[int(choice) - 1]
|
||||
self.view_json_report(selected_file)
|
||||
|
||||
def view_json_report(self, json_file: Path):
|
||||
"""View a JSON report file."""
|
||||
try:
|
||||
with open(json_file, 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Pretty print JSON with syntax highlighting
|
||||
json_str = json.dumps(data, indent=2)
|
||||
syntax = Syntax(json_str, "json", theme="monokai", line_numbers=True)
|
||||
|
||||
console.print(f"\n[bold]Contents of {json_file.name}:[/bold]")
|
||||
console.print(syntax)
|
||||
|
||||
except Exception as e:
|
||||
console.print(f"[red]Error reading {json_file}: {str(e)}[/red]")
|
||||
|
||||
def help_menu(self):
|
||||
"""Display help and documentation."""
|
||||
console.print("\n[bold yellow]Help & Documentation[/bold yellow]")
|
||||
|
||||
help_text = """
|
||||
[bold blue]HDH CLI Help[/bold blue]
|
||||
|
||||
[bold]About HDH:[/bold]
|
||||
HDH (Hybrid Dependency Hypergraph) is a library for representing and analyzing
|
||||
quantum circuits using hypergraph structures. It enables:
|
||||
• Circuit conversion from multiple quantum frameworks
|
||||
• Dependency analysis and visualization
|
||||
• Circuit partitioning and optimization
|
||||
• Performance benchmarking
|
||||
|
||||
[bold]Main Features:[/bold]
|
||||
1. [cyan]Circuit Processing[/cyan] - Convert and analyze quantum circuits
|
||||
2. [cyan]Benchmarking[/cyan] - Measure HDH performance across different circuits
|
||||
3. [cyan]Circuit Library[/cyan] - Access pre-built quantum circuit examples
|
||||
4. [cyan]Configuration[/cyan] - Customize settings and output directories
|
||||
5. [cyan]Results Viewing[/cyan] - Examine processing results and reports
|
||||
|
||||
[bold]Supported Circuit Types:[/bold]
|
||||
• Qiskit QuantumCircuit objects
|
||||
• OpenQASM 2.0 files
|
||||
• Pre-built examples (Bell states, GHZ, QFT, Grover, etc.)
|
||||
|
||||
[bold]Output Files:[/bold]
|
||||
• JSON reports with detailed metrics
|
||||
• PNG visualizations of HDH structures
|
||||
• Performance benchmark plots
|
||||
• Processing logs
|
||||
|
||||
[bold]Tips:[/bold]
|
||||
• Start with small circuits (< 8 qubits) for faster processing
|
||||
• Use the comprehensive demo for a full overview
|
||||
• Enable plot saving to visualize HDH structures
|
||||
• Run benchmarks to understand performance characteristics
|
||||
|
||||
[italic]Special thanks to Maria Gragera Garces for the HDH library![/italic]
|
||||
"""
|
||||
|
||||
console.print(Panel(help_text.strip(), expand=False, border_style="blue"))
|
||||
|
||||
if Confirm.ask("\nWould you like to see example usage?", default=False):
|
||||
self.show_example_usage()
|
||||
|
||||
def show_example_usage(self):
|
||||
"""Show example usage scenarios."""
|
||||
console.print("\n[bold]Example Usage Scenarios[/bold]")
|
||||
|
||||
examples = [
|
||||
{
|
||||
"title": "Quick Start - Process Bell State",
|
||||
"steps": [
|
||||
"1. Select 'Process Quantum Circuits'",
|
||||
"2. Choose 'Process Example Circuits'",
|
||||
"3. Enter 'bell_state' when prompted",
|
||||
"4. Confirm to save plots",
|
||||
"5. View results in output directory"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Benchmark Suite",
|
||||
"steps": [
|
||||
"1. Select 'Run Performance Benchmarks'",
|
||||
"2. Choose 'Comprehensive Benchmark'",
|
||||
"3. Confirm to run (may take several minutes)",
|
||||
"4. View generated performance plots",
|
||||
"5. Check benchmark_report.json for detailed metrics"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Custom QASM Processing",
|
||||
"steps": [
|
||||
"1. Select 'Process Quantum Circuits'",
|
||||
"2. Choose 'Process QASM File'",
|
||||
"3. Enter path to your .qasm file",
|
||||
"4. Confirm visualization settings",
|
||||
"5. Review HDH conversion results"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
for example in examples:
|
||||
console.print(f"\n[bold green]{example['title']}:[/bold green]")
|
||||
for step in example['steps']:
|
||||
console.print(f" {step}")
|
||||
|
||||
def create_custom_circuit(self):
|
||||
"""Guide for creating custom circuits."""
|
||||
console.print("\n[bold]Custom Circuit Creation[/bold]")
|
||||
console.print("This feature allows you to create custom quantum circuits programmatically.")
|
||||
console.print("For now, use the 'Custom Circuit Processing' option in the main processing menu.")
|
||||
|
||||
def show_circuit_information(self):
|
||||
"""Show detailed information about circuits."""
|
||||
console.print("\n[bold]Circuit Information[/bold]")
|
||||
|
||||
examples = self.circuit_library.get_all_examples()
|
||||
circuit_name = Prompt.ask(
|
||||
"Enter circuit name for details",
|
||||
choices=list(examples.keys()),
|
||||
default="bell_state"
|
||||
)
|
||||
|
||||
if circuit_name in examples:
|
||||
circuit = examples[circuit_name]
|
||||
|
||||
info_table = Table(title=f"Circuit Information: {circuit_name}")
|
||||
info_table.add_column("Property", style="cyan")
|
||||
info_table.add_column("Value", style="green")
|
||||
|
||||
info_table.add_row("Name", getattr(circuit, 'name', circuit_name))
|
||||
info_table.add_row("Qubits", str(circuit.num_qubits))
|
||||
info_table.add_row("Classical Bits", str(circuit.num_clbits))
|
||||
info_table.add_row("Depth", str(circuit.depth()))
|
||||
info_table.add_row("Size (gates)", str(circuit.size()))
|
||||
info_table.add_row("Operations", str(len(circuit.data)))
|
||||
|
||||
console.print(info_table)
|
||||
|
||||
# Show QASM representation
|
||||
if Confirm.ask("Show QASM representation?", default=False):
|
||||
try:
|
||||
qasm_str = circuit.qasm()
|
||||
syntax = Syntax(qasm_str, "qasm", theme="monokai", line_numbers=True)
|
||||
console.print(f"\n[bold]QASM for {circuit_name}:[/bold]")
|
||||
console.print(syntax)
|
||||
except Exception as e:
|
||||
console.print(f"[red]Error generating QASM: {str(e)}[/red]")
|
||||
|
||||
def run(self):
|
||||
"""Main CLI loop."""
|
||||
try:
|
||||
while True:
|
||||
choice = self.show_main_menu()
|
||||
|
||||
if choice == "q":
|
||||
console.print("\n[bold blue]Thank you for using HDH CLI![/bold blue]")
|
||||
console.print("[italic]Special thanks to Maria Gragera Garces! 🎉[/italic]")
|
||||
break
|
||||
elif choice == "1":
|
||||
self.process_circuits_menu()
|
||||
elif choice == "2":
|
||||
self.benchmarking_menu()
|
||||
elif choice == "3":
|
||||
self.circuit_library_menu()
|
||||
elif choice == "4":
|
||||
self.configuration_menu()
|
||||
elif choice == "5":
|
||||
self.view_results_menu()
|
||||
elif choice == "6":
|
||||
self.help_menu()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
console.print("\n[yellow]Goodbye![/yellow]")
|
||||
except Exception as e:
|
||||
console.print(f"\n[red]An error occurred: {str(e)}[/red]")
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('--output-dir', default='hdh_results', help='Default output directory')
|
||||
@click.option('--theme', default='default', help='Console theme')
|
||||
def main(output_dir, theme):
|
||||
"""
|
||||
HDH Command Line Interface
|
||||
|
||||
Interactive CLI for HDH (Hybrid Dependency Hypergraph) deployment and analysis.
|
||||
"""
|
||||
try:
|
||||
cli = HDHCommandLineInterface()
|
||||
cli.output_dir = output_dir
|
||||
cli.run()
|
||||
except Exception as e:
|
||||
console.print(f"[red]Failed to start CLI: {str(e)}[/red]")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Referencia en una nueva incidencia
Block a user