From 9a2e61340accd72fe48febadc61ecb768e33d134 Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Wed, 29 Jan 2025 15:15:59 +0100 Subject: [PATCH 01/10] Add basic structure for OpenQASM processing --- .../CircuitProcessingConfiguration.java | 39 +++++++++++++ .../solver/CircuitProcessingSolver.java | 12 ++++ .../solver/MoveToExecutionSolver.java | 58 +++++++++++++++++++ .../solver/MoveToMitigationSolver.java | 44 ++++++++++++++ .../solver/MoveToOptimizationSolver.java | 44 ++++++++++++++ .../solver/executor/ExecutionResult.java | 13 +++++ .../solver/executor/ExecutionSolver.java | 36 ++++++++++++ .../executor/ExecutorConfiguration.java | 32 ++++++++++ .../ErrorMitigationConfiguration.java | 34 +++++++++++ .../mitigation/ErrorMitigationSolver.java | 35 +++++++++++ .../OptimizationConfiguration.java | 32 ++++++++++ .../optimization/OptimizationSolver.java | 35 +++++++++++ 12 files changed, 414 insertions(+) create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionResult.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java create mode 100644 src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java new file mode 100644 index 00000000..193657ce --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java @@ -0,0 +1,39 @@ +package edu.kit.provideq.toolbox.circuit.processing; + +import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToExecutionSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToMitigationSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToOptimizationSolver; +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManager; +import edu.kit.provideq.toolbox.meta.ProblemType; +import java.util.Set; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CircuitProcessingConfiguration { + public static final ProblemType CIRCUIT_PROCESSING = new ProblemType<>( + "circuit-processing", + String.class, + String.class, + null + ); + + @Bean + ProblemManager getCircuitProcessingManager( + MoveToExecutionSolver moveToExecutionSolver, + MoveToOptimizationSolver moveToOptimizationSolver, + MoveToMitigationSolver moveToMitigationSolver + ) { + return new ProblemManager<>( + CIRCUIT_PROCESSING, + Set.of( + moveToExecutionSolver, + moveToOptimizationSolver, + moveToMitigationSolver + ), + // TODO: dummy problem + Set.of(new Problem<>(CIRCUIT_PROCESSING)) + ); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java new file mode 100644 index 00000000..7c978ad2 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java @@ -0,0 +1,12 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver; + +import edu.kit.provideq.toolbox.circuit.processing.CircuitProcessingConfiguration; +import edu.kit.provideq.toolbox.meta.ProblemSolver; +import edu.kit.provideq.toolbox.meta.ProblemType; + +public abstract class CircuitProcessingSolver implements ProblemSolver { + @Override + public ProblemType getProblemType() { + return CircuitProcessingConfiguration.CIRCUIT_PROCESSING; + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java new file mode 100644 index 00000000..19d555c8 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java @@ -0,0 +1,58 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver; + +import edu.kit.provideq.toolbox.Solution; +import edu.kit.provideq.toolbox.SolutionStatus; +import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionResult; +import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutorConfiguration; +import edu.kit.provideq.toolbox.meta.SolvingProperties; +import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; +import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import java.util.List; + +@Component +public class MoveToExecutionSolver extends CircuitProcessingSolver { + private static final SubRoutineDefinition EXECUTOR_SUBROUTINE = + new SubRoutineDefinition<>( + ExecutorConfiguration.EXECUTOR_CONFIG, + "Creates a execution solver" + ); + + @Override + public String getName() { + return "Execute QASM Code"; + } + + @Override + public String getDescription() { + return "Move QASM input to the executors"; + } + + @Override + public List> getSubRoutines() { + return List.of(EXECUTOR_SUBROUTINE); + } + + @Override + public Mono> solve( + String input, + SubRoutineResolver subRoutineResolver, + SolvingProperties properties + ) { + return subRoutineResolver.runSubRoutine(EXECUTOR_SUBROUTINE, input) + .map(executionResultSolution -> { + Solution solution = new Solution<>(this); + SolutionStatus status = executionResultSolution.getStatus(); + if (status == SolutionStatus.ERROR) { + solution.fail(); + solution.setDebugData("An error occurred while executing the circuit"); + return solution; + } + solution.complete(); + solution.setSolutionData(executionResultSolution.getSolutionData().toString()); + return solution; + }); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java new file mode 100644 index 00000000..4c70a353 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java @@ -0,0 +1,44 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver; + +import edu.kit.provideq.toolbox.Solution; +import edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationConfiguration; +import edu.kit.provideq.toolbox.meta.SolvingProperties; +import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; +import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import java.util.List; + +@Component +public class MoveToMitigationSolver extends CircuitProcessingSolver { + private static final SubRoutineDefinition MITIGATOR_SUBROUTINE = + new SubRoutineDefinition<>( + ErrorMitigationConfiguration.MITIGATION_CONFIG, + "Creates a mitigation solver" + ); + + @Override + public String getName() { + return "Mitigate QASM Code Errors"; + } + + @Override + public String getDescription() { + return "Move QASM input to the error mitigators"; + } + + @Override + public List> getSubRoutines() { + return List.of(MITIGATOR_SUBROUTINE); + } + + @Override + public Mono> solve( + String input, + SubRoutineResolver subRoutineResolver, + SolvingProperties properties + ) { + return subRoutineResolver.runSubRoutine(MITIGATOR_SUBROUTINE, input); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java new file mode 100644 index 00000000..a6d938f6 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java @@ -0,0 +1,44 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver; + +import edu.kit.provideq.toolbox.Solution; +import edu.kit.provideq.toolbox.circuit.processing.solver.optimization.OptimizationConfiguration; +import edu.kit.provideq.toolbox.meta.SolvingProperties; +import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; +import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import java.util.List; + +@Component +public class MoveToOptimizationSolver extends CircuitProcessingSolver { + private static final SubRoutineDefinition OPTIMIZER_SUBROUTINE = + new SubRoutineDefinition<>( + OptimizationConfiguration.OPTIMIZATION_CONFIG, + "Creates a optimization solver" + ); + + @Override + public String getName() { + return "Optimize QASM Code"; + } + + @Override + public String getDescription() { + return "Move QASM input to the optimizers"; + } + + @Override + public List> getSubRoutines() { + return List.of(OPTIMIZER_SUBROUTINE); + } + + @Override + public Mono> solve( + String input, + SubRoutineResolver subRoutineResolver, + SolvingProperties properties + ) { + return subRoutineResolver.runSubRoutine(OPTIMIZER_SUBROUTINE, input); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionResult.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionResult.java new file mode 100644 index 00000000..4751c2b7 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionResult.java @@ -0,0 +1,13 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver.executor; + +import java.util.Optional; + +public record ExecutionResult(Optional resultString, Optional circuit) { + public boolean hasResult() { + return resultString.isPresent(); + } + + public boolean hasCircuit() { + return circuit.isPresent(); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java new file mode 100644 index 00000000..9043bdea --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java @@ -0,0 +1,36 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver.executor; + +import edu.kit.provideq.toolbox.Solution; +import edu.kit.provideq.toolbox.meta.ProblemSolver; +import edu.kit.provideq.toolbox.meta.ProblemType; +import edu.kit.provideq.toolbox.meta.SolvingProperties; +import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import java.util.Optional; + +@Component +public class ExecutionSolver implements ProblemSolver { + @Override + public String getName() { + return "Execute OpenQASM circuit"; + } + + @Override + public String getDescription() { + return "Execute an OpenQASM circuit"; + } + + @Override + public Mono> solve(String input, SubRoutineResolver subRoutineResolver, SolvingProperties properties) { + var solution = new Solution<>(this); + solution.setSolutionData(new ExecutionResult(Optional.of(input), Optional.empty())); + return Mono.just(solution); + } + + @Override + public ProblemType getProblemType() { + return ExecutorConfiguration.EXECUTOR_CONFIG; + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java new file mode 100644 index 00000000..d93390f2 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java @@ -0,0 +1,32 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver.executor; + +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManager; +import edu.kit.provideq.toolbox.meta.ProblemType; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Set; + +@Configuration +public class ExecutorConfiguration { + public static final ProblemType EXECUTOR_CONFIG = new ProblemType<>( + "circuit-processing-executor", + String.class, + ExecutionResult.class, + null + ); + + @Bean + ProblemManager getExecutorProblemManager( + ExecutionSolver executionSolver + ) { + return new ProblemManager<>( + EXECUTOR_CONFIG, + Set.of( + executionSolver + ), + Set.of(new Problem<>(EXECUTOR_CONFIG)) + ); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java new file mode 100644 index 00000000..953efc12 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java @@ -0,0 +1,34 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver.mitigation; + +import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionResult; +import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionSolver; +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManager; +import edu.kit.provideq.toolbox.meta.ProblemType; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Set; + +@Configuration +public class ErrorMitigationConfiguration { + public static final ProblemType MITIGATION_CONFIG = new ProblemType<>( + "circuit-processing-mitigation", + String.class, + String.class, + null + ); + + @Bean + ProblemManager getMitigationProblemManager( + ErrorMitigationSolver errorMitigationSolver + ) { + return new ProblemManager<>( + MITIGATION_CONFIG, + Set.of( + errorMitigationSolver + ), + Set.of(new Problem<>(MITIGATION_CONFIG)) + ); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java new file mode 100644 index 00000000..5c70686a --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java @@ -0,0 +1,35 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver.mitigation; + +import edu.kit.provideq.toolbox.Solution; +import edu.kit.provideq.toolbox.meta.ProblemSolver; +import edu.kit.provideq.toolbox.meta.ProblemType; +import edu.kit.provideq.toolbox.meta.SolvingProperties; +import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +@Component +public class ErrorMitigationSolver implements ProblemSolver { + + @Override + public String getName() { + return "Mitigate Errors for OpenQASM"; + } + + @Override + public String getDescription() { + return "Run error mitigation strategies on an OpenQASM circuit"; + } + + @Override + public Mono> solve(String input, SubRoutineResolver subRoutineResolver, SolvingProperties properties) { + var solution = new Solution<>(this); + solution.setSolutionData(input); + return Mono.just(solution); + } + + @Override + public ProblemType getProblemType() { + return ErrorMitigationConfiguration.MITIGATION_CONFIG; + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java new file mode 100644 index 00000000..78dfbbfd --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java @@ -0,0 +1,32 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver.optimization; + +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManager; +import edu.kit.provideq.toolbox.meta.ProblemType; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Set; + +@Configuration +public class OptimizationConfiguration { + public static final ProblemType OPTIMIZATION_CONFIG = new ProblemType<>( + "circuit-processing-optimization", + String.class, + String.class, + null + ); + + @Bean + ProblemManager getOptimizationProblemManager( + OptimizationSolver optimizationSolver + ) { + return new ProblemManager<>( + OPTIMIZATION_CONFIG, + Set.of( + optimizationSolver + ), + Set.of(new Problem<>(OPTIMIZATION_CONFIG)) + ); + } +} diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java new file mode 100644 index 00000000..fcf51939 --- /dev/null +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java @@ -0,0 +1,35 @@ +package edu.kit.provideq.toolbox.circuit.processing.solver.optimization; + +import edu.kit.provideq.toolbox.Solution; +import edu.kit.provideq.toolbox.meta.ProblemSolver; +import edu.kit.provideq.toolbox.meta.ProblemType; +import edu.kit.provideq.toolbox.meta.SolvingProperties; +import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +@Component +public class OptimizationSolver implements ProblemSolver { + + @Override + public String getName() { + return "Optimize OpenQASM circuit"; + } + + @Override + public String getDescription() { + return "Run optimization algorithms on an OpenQASM circuit"; + } + + @Override + public Mono> solve(String input, SubRoutineResolver subRoutineResolver, SolvingProperties properties) { + var solution = new Solution<>(this); + solution.setSolutionData(input); + return Mono.just(solution); + } + + @Override + public ProblemType getProblemType() { + return OptimizationConfiguration.OPTIMIZATION_CONFIG; + } +} From 07eb190c4120938b43f8f84c133401c56e582fb8 Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Mon, 10 Mar 2025 12:27:27 +0100 Subject: [PATCH 02/10] Add execution and optimization solvers --- .../decompose_multi_cx_optimizer.py | 19 ++++ .../remove_redundancies_optimizer.py | 19 ++++ .../aer-noisy/aer_noisy_executor.py | 27 +++++ .../default-executor/default_executor.py | 18 +++ .../projectq-executor/projectq_executor.py | 17 +++ .../qulacs-executor/qulacs_executor.py | 18 +++ solvers/circuitprocessing/requirements.txt | 5 + .../CircuitProcessingConfiguration.java | 21 +++- .../solver/CircuitProcessingSolver.java | 7 ++ .../solver/MoveToExecutionSolver.java | 2 +- .../solver/executor/ExecutionSolver.java | 100 +++++++++++++++- .../optimization/OptimizationSolver.java | 107 +++++++++++++++++- 12 files changed, 350 insertions(+), 10 deletions(-) create mode 100644 solvers/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py create mode 100644 solvers/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py create mode 100644 solvers/circuitprocessing/aer-noisy/aer_noisy_executor.py create mode 100644 solvers/circuitprocessing/default-executor/default_executor.py create mode 100644 solvers/circuitprocessing/projectq-executor/projectq_executor.py create mode 100644 solvers/circuitprocessing/qulacs-executor/qulacs_executor.py create mode 100644 solvers/circuitprocessing/requirements.txt diff --git a/solvers/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py b/solvers/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py new file mode 100644 index 00000000..3d62f964 --- /dev/null +++ b/solvers/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py @@ -0,0 +1,19 @@ +import sys +from pytket.qasm import circuit_from_qasm_str, circuit_to_qasm_str +from pytket.predicates import CompilationUnit +from pytket.passes import DecomposeMultiQubitsCX + + +input_circuit = sys.argv[1] + +try: + circuit = circuit_from_qasm_str(input_circuit) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +pass1 = DecomposeMultiQubitsCX() +cu = CompilationUnit(circuit) +pass1.apply(cu) + +print(circuit_to_qasm_str(cu.circuit)) \ No newline at end of file diff --git a/solvers/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py b/solvers/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py new file mode 100644 index 00000000..58b57e68 --- /dev/null +++ b/solvers/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py @@ -0,0 +1,19 @@ +import sys +from pytket.qasm import circuit_from_qasm_str, circuit_to_qasm_str +from pytket.predicates import CompilationUnit +from pytket.passes import RemoveRedundancies + + +input_circuit = sys.argv[1] + +try: + circuit = circuit_from_qasm_str(input_circuit) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +pass1 = RemoveRedundancies() +cu = CompilationUnit(circuit) +pass1.apply(cu) + +print(circuit_to_qasm_str(cu.circuit)) \ No newline at end of file diff --git a/solvers/circuitprocessing/aer-noisy/aer_noisy_executor.py b/solvers/circuitprocessing/aer-noisy/aer_noisy_executor.py new file mode 100644 index 00000000..9db4439b --- /dev/null +++ b/solvers/circuitprocessing/aer-noisy/aer_noisy_executor.py @@ -0,0 +1,27 @@ +import sys +from pytket.qasm import circuit_from_qasm_str +from pytket.extensions.qiskit import AerBackend + +from qiskit_aer.noise import NoiseModel +from qiskit_aer.noise.errors import depolarizing_error + +input_circuit = sys.argv[1] +shots = sys.argv[2] + +try: + circuit = circuit_from_qasm_str(input_circuit) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +# https://docs.quantinuum.com/tket/user-guide/manual/manual_noise.html +noise_model = NoiseModel() +noise_model.add_readout_error([[0.9, 0.1],[0.1, 0.9]], [0]) +noise_model.add_readout_error([[0.95, 0.05],[0.05, 0.95]], [1]) +noise_model.add_quantum_error(depolarizing_error(0.1, 2), ["cx"], [0, 1]) + +backend = AerBackend(noise_model) +c = backend.get_compiled_circuit(circuit) +handle = backend.process_circuit(c, n_shots=int(shots)) +counts = backend.get_result(handle).get_counts() +print(counts) \ No newline at end of file diff --git a/solvers/circuitprocessing/default-executor/default_executor.py b/solvers/circuitprocessing/default-executor/default_executor.py new file mode 100644 index 00000000..9ce98997 --- /dev/null +++ b/solvers/circuitprocessing/default-executor/default_executor.py @@ -0,0 +1,18 @@ +import sys +from pytket.qasm import circuit_from_qasm_str +from pytket.extensions.qiskit import AerBackend + +input_circuit = sys.argv[1] +shots = int(sys.argv[2]) + +try: + circuit = circuit_from_qasm_str(input_circuit) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +backend = AerBackend() +c = backend.get_compiled_circuit(circuit) +handle = backend.process_circuit(c, n_shots=shots) +counts = backend.get_result(handle).get_counts() +print(counts) \ No newline at end of file diff --git a/solvers/circuitprocessing/projectq-executor/projectq_executor.py b/solvers/circuitprocessing/projectq-executor/projectq_executor.py new file mode 100644 index 00000000..8600c2bd --- /dev/null +++ b/solvers/circuitprocessing/projectq-executor/projectq_executor.py @@ -0,0 +1,17 @@ +import sys +from pytket.qasm import circuit_from_qasm_str +from pytket.extensions.projectq import ProjectQBackend + +input_circuit = sys.argv[1] +shots = int(sys.argv[2]) + +try: + circuit = circuit_from_qasm_str(input_circuit) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +backend = ProjectQBackend() +handle = backend.process_circuit(circuit, n_shots=shots) +result = backend.get_result(handle) +print(result.get_shots()) \ No newline at end of file diff --git a/solvers/circuitprocessing/qulacs-executor/qulacs_executor.py b/solvers/circuitprocessing/qulacs-executor/qulacs_executor.py new file mode 100644 index 00000000..9652f6b0 --- /dev/null +++ b/solvers/circuitprocessing/qulacs-executor/qulacs_executor.py @@ -0,0 +1,18 @@ +import sys +from pytket.qasm import circuit_from_qasm_str +from pytket.extensions.qulacs import QulacsBackend + +input_circuit = sys.argv[1] +shots = int(sys.argv[2]) + +try: + circuit = circuit_from_qasm_str(input_circuit) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +backend = QulacsBackend() +c = backend.get_compiled_circuit(circuit) +handle = backend.process_circuit(c, n_shots=shots) +counts = backend.get_result(handle).get_counts() +print(counts) \ No newline at end of file diff --git a/solvers/circuitprocessing/requirements.txt b/solvers/circuitprocessing/requirements.txt new file mode 100644 index 00000000..40a709cf --- /dev/null +++ b/solvers/circuitprocessing/requirements.txt @@ -0,0 +1,5 @@ +pytket +pytket-qiskit +pytket-pyquil +pytket-projectq +pytket-qulacs \ No newline at end of file diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java index 193657ce..2a72d788 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java @@ -25,6 +25,24 @@ ProblemManager getCircuitProcessingManager( MoveToOptimizationSolver moveToOptimizationSolver, MoveToMitigationSolver moveToMitigationSolver ) { + Problem demo = new Problem<>(CIRCUIT_PROCESSING); + demo.setInput(""" + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[2]; + creg c[2]; + h q[0]; + cx q[0],q[1]; + measure q[0] -> c[0]; + measure q[1] -> c[1];"""); + Problem secondDemo = new Problem<>(CIRCUIT_PROCESSING); + secondDemo.setInput(""" + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[3]; + crz(0.5) q[0], q[1]; + t q[2]; + cswap q[2], q[0], q[1];"""); return new ProblemManager<>( CIRCUIT_PROCESSING, Set.of( @@ -32,8 +50,7 @@ ProblemManager getCircuitProcessingManager( moveToOptimizationSolver, moveToMitigationSolver ), - // TODO: dummy problem - Set.of(new Problem<>(CIRCUIT_PROCESSING)) + Set.of(demo, secondDemo) ); } } diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java index 7c978ad2..507ce9c6 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java @@ -3,8 +3,15 @@ import edu.kit.provideq.toolbox.circuit.processing.CircuitProcessingConfiguration; import edu.kit.provideq.toolbox.meta.ProblemSolver; import edu.kit.provideq.toolbox.meta.ProblemType; +import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; public abstract class CircuitProcessingSolver implements ProblemSolver { + public static final SubRoutineDefinition CIRCUIT_PROCESSING_SUBROUTINE = + new SubRoutineDefinition<>( + CircuitProcessingConfiguration.CIRCUIT_PROCESSING, + "Creates a circuit processing solver" + ); + @Override public ProblemType getProblemType() { return CircuitProcessingConfiguration.CIRCUIT_PROCESSING; diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java index 19d555c8..8d919d7c 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java @@ -47,7 +47,7 @@ public Mono> solve( SolutionStatus status = executionResultSolution.getStatus(); if (status == SolutionStatus.ERROR) { solution.fail(); - solution.setDebugData("An error occurred while executing the circuit"); + solution.setDebugData(executionResultSolution.getDebugData()); return solution; } solution.complete(); diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java index 9043bdea..c96df7f1 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java @@ -5,13 +5,38 @@ import edu.kit.provideq.toolbox.meta.ProblemType; import edu.kit.provideq.toolbox.meta.SolvingProperties; import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import edu.kit.provideq.toolbox.meta.setting.SolverSetting; +import edu.kit.provideq.toolbox.meta.setting.basic.IntegerSetting; +import edu.kit.provideq.toolbox.meta.setting.basic.SelectSetting; +import edu.kit.provideq.toolbox.process.PythonProcessRunner; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; +import java.util.List; import java.util.Optional; @Component public class ExecutionSolver implements ProblemSolver { + private static final String SETTING_NUMBER_OF_SHOTS = "Number of shots"; + private static final String SETTING_SELECT_SIMULATOR = "Selected Simulator"; + private static final int DEFAULT_NUMBER_OF_SHOTS = 1024; + private static final QuantumSimulator DEFAULT_SIMULATOR = QuantumSimulator.AER; + + private final String scriptPath; + private final ApplicationContext context; + + @Autowired + public ExecutionSolver( + @Value("${circuitprocessing.base.directory}") String scriptPath, + ApplicationContext context + ) { + this.context = context; + this.scriptPath = scriptPath; + } + @Override public String getName() { return "Execute OpenQASM circuit"; @@ -22,10 +47,51 @@ public String getDescription() { return "Execute an OpenQASM circuit"; } + @Override + public List getSolverSettings() { + return List.of( + new IntegerSetting( + SETTING_NUMBER_OF_SHOTS, + "The number of shots to run", + 1, + 10000, + DEFAULT_NUMBER_OF_SHOTS), + new SelectSetting<>( + SETTING_SELECT_SIMULATOR, + "The simulator to run the code with", + List.of(QuantumSimulator.values()), + QuantumSimulator.AER, + QuantumSimulator::getValue + ) + ); + } + @Override public Mono> solve(String input, SubRoutineResolver subRoutineResolver, SolvingProperties properties) { var solution = new Solution<>(this); - solution.setSolutionData(new ExecutionResult(Optional.of(input), Optional.empty())); + + int shotNumber = properties.getSetting(SETTING_NUMBER_OF_SHOTS) + .map(IntegerSetting::getValue) + .orElse(DEFAULT_NUMBER_OF_SHOTS); + + QuantumSimulator selectedSimulator = properties + .>getSetting(SETTING_SELECT_SIMULATOR) + .map(s -> s.getSelectedOptionT(QuantumSimulator::fromValue)) + .orElse(DEFAULT_SIMULATOR); + + var processResult = context + .getBean(PythonProcessRunner.class, scriptPath + selectedSimulator.getScriptPath()) + .withArguments(input, String.valueOf(shotNumber)) + .readOutputString() + .run(getProblemType(), solution.getId()); + + if (processResult.success()) { + solution.complete(); + solution.setSolutionData(new ExecutionResult(processResult.output(), Optional.of(input))); + return Mono.just(solution); + } + solution.fail(); + processResult.errorOutput().ifPresent(solution::setDebugData); return Mono.just(solution); } @@ -33,4 +99,36 @@ public Mono> solve(String input, SubRoutineResolver su public ProblemType getProblemType() { return ExecutorConfiguration.EXECUTOR_CONFIG; } + + enum QuantumSimulator { + AER("AerBackend", "default-executor/default_executor.py"), + // PROJECTQ("ProjectQBackend", "projectq-executor/projectq_executor.py"), + QULACS("QulacsBackend", "qulacs-executor/qulacs_executor.py"), + AER_NOISY("Aer Noisy Backend (max. 2 qubits)", "aer-noisy/aer_noisy_executor.py"); + + private final String value; + private final String scriptPath; + + QuantumSimulator(String value, String scriptPath) { + this.value = value; + this.scriptPath = scriptPath; + } + + public String getValue() { + return value; + } + + public String getScriptPath() { + return scriptPath; + } + + public static QuantumSimulator fromValue(String value) { + for (QuantumSimulator simulator : values()) { + if (simulator.value.equals(value)) { + return simulator; + } + } + throw new IllegalArgumentException("Unknown value: " + value); + } + } } diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java index fcf51939..846fad84 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java @@ -1,15 +1,36 @@ package edu.kit.provideq.toolbox.circuit.processing.solver.optimization; import edu.kit.provideq.toolbox.Solution; -import edu.kit.provideq.toolbox.meta.ProblemSolver; -import edu.kit.provideq.toolbox.meta.ProblemType; -import edu.kit.provideq.toolbox.meta.SolvingProperties; -import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.CircuitProcessingSolver; +import edu.kit.provideq.toolbox.meta.*; +import edu.kit.provideq.toolbox.meta.setting.SolverSetting; +import edu.kit.provideq.toolbox.meta.setting.basic.SelectSetting; +import edu.kit.provideq.toolbox.process.PythonProcessRunner; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; +import java.util.List; + @Component public class OptimizationSolver implements ProblemSolver { + private static final String SETTING_SELECT_OPTIMIZER = "Selected Optimization Pass"; + private static final OptimizationSolver.QuantumOptimizer DEFAULT_OPTIMIZER = + QuantumOptimizer.DECOMPOSE_MULTI_CX; + + private final String scriptPath; + private final ApplicationContext context; + + @Autowired + public OptimizationSolver( + @Value("${circuitoptimizing.base.directory}") String scriptPath, + ApplicationContext context + ) { + this.scriptPath = scriptPath; + this.context = context; + } @Override public String getName() { @@ -22,9 +43,51 @@ public String getDescription() { } @Override - public Mono> solve(String input, SubRoutineResolver subRoutineResolver, SolvingProperties properties) { + public List> getSubRoutines() { + return List.of(CircuitProcessingSolver.CIRCUIT_PROCESSING_SUBROUTINE); + } + + @Override + public List getSolverSettings() { + return List.of( + new SelectSetting<>( + SETTING_SELECT_OPTIMIZER, + "The optimization pass to refactor the code with", + List.of(OptimizationSolver.QuantumOptimizer.values()), + QuantumOptimizer.DECOMPOSE_MULTI_CX, + OptimizationSolver.QuantumOptimizer::getValue + ) + ); + } + + @Override + public Mono> solve( + String input, + SubRoutineResolver subRoutineResolver, + SolvingProperties properties + ) { var solution = new Solution<>(this); - solution.setSolutionData(input); + + OptimizationSolver.QuantumOptimizer selectedOptimizer = properties + .>getSetting(SETTING_SELECT_OPTIMIZER) + .map(s -> s.getSelectedOptionT(OptimizationSolver.QuantumOptimizer::fromValue)) + .orElse(DEFAULT_OPTIMIZER); + + var processResult = context + .getBean(PythonProcessRunner.class, scriptPath + selectedOptimizer.getScriptPath()) + .withArguments(input) + .readOutputString() + .run(getProblemType(), solution.getId()); + + if (processResult.success() && processResult.output().isPresent()) { + solution.complete(); + solution.setSolutionData(processResult.output().get()); + return subRoutineResolver + .runSubRoutine(CircuitProcessingSolver.CIRCUIT_PROCESSING_SUBROUTINE, + processResult.output().get()); + } + solution.fail(); + processResult.errorOutput().ifPresent(solution::setDebugData); return Mono.just(solution); } @@ -32,4 +95,36 @@ public Mono> solve(String input, SubRoutineResolver subRoutineR public ProblemType getProblemType() { return OptimizationConfiguration.OPTIMIZATION_CONFIG; } + + enum QuantumOptimizer { + DECOMPOSE_MULTI_CX("DecomposeMultiQubitsCX", + "decompose-multi-cx/decompose_multi_cx_optimizer.py"), + REMOVE_REDUNDANCIES("RemoveRedundancies", + "remove-redundancies/remove_redundancies_optimizer.py"); + + private final String value; + private final String scriptPath; + + QuantumOptimizer(String value, String scriptPath) { + this.value = value; + this.scriptPath = scriptPath; + } + + public String getValue() { + return value; + } + + public String getScriptPath() { + return scriptPath; + } + + public static OptimizationSolver.QuantumOptimizer fromValue(String value) { + for (OptimizationSolver.QuantumOptimizer simulator : values()) { + if (simulator.value.equals(value)) { + return simulator; + } + } + throw new IllegalArgumentException("Unknown value: " + value); + } + } } From ecbbc863f63aede0f61d25518b997a915942a5b2 Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Mon, 10 Mar 2025 13:28:22 +0100 Subject: [PATCH 03/10] Merge dev, account for checkstyle errors --- .../processing/CircuitProcessingConfiguration.java | 3 +-- .../processing/solver/MoveToExecutionSolver.java | 3 +-- .../processing/solver/MoveToMitigationSolver.java | 3 +-- .../processing/solver/MoveToOptimizationSolver.java | 3 +-- .../processing/solver/executor/ExecutionSolver.java | 11 +++++++---- .../solver/executor/ExecutorConfiguration.java | 6 ++---- .../mitigation/ErrorMitigationConfiguration.java | 8 ++------ .../solver/mitigation/ErrorMitigationSolver.java | 6 +++++- .../optimization/OptimizationConfiguration.java | 6 ++---- .../solver/optimization/OptimizationSolver.java | 9 ++++++--- 10 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java index 2a72d788..c0092195 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java @@ -15,8 +15,7 @@ public class CircuitProcessingConfiguration { public static final ProblemType CIRCUIT_PROCESSING = new ProblemType<>( "circuit-processing", String.class, - String.class, - null + String.class ); @Bean diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java index 8d919d7c..8d1d6b60 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java @@ -7,11 +7,10 @@ import edu.kit.provideq.toolbox.meta.SolvingProperties; import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import java.util.List; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; -import java.util.List; - @Component public class MoveToExecutionSolver extends CircuitProcessingSolver { private static final SubRoutineDefinition EXECUTOR_SUBROUTINE = diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java index 4c70a353..56e68fcd 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java @@ -5,11 +5,10 @@ import edu.kit.provideq.toolbox.meta.SolvingProperties; import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import java.util.List; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; -import java.util.List; - @Component public class MoveToMitigationSolver extends CircuitProcessingSolver { private static final SubRoutineDefinition MITIGATOR_SUBROUTINE = diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java index a6d938f6..d213b4ec 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java @@ -5,11 +5,10 @@ import edu.kit.provideq.toolbox.meta.SolvingProperties; import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; import edu.kit.provideq.toolbox.meta.SubRoutineResolver; +import java.util.List; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; -import java.util.List; - @Component public class MoveToOptimizationSolver extends CircuitProcessingSolver { private static final SubRoutineDefinition OPTIMIZER_SUBROUTINE = diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java index c96df7f1..58ed0aeb 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java @@ -9,15 +9,14 @@ import edu.kit.provideq.toolbox.meta.setting.basic.IntegerSetting; import edu.kit.provideq.toolbox.meta.setting.basic.SelectSetting; import edu.kit.provideq.toolbox.process.PythonProcessRunner; +import java.util.List; +import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; -import java.util.List; -import java.util.Optional; - @Component public class ExecutionSolver implements ProblemSolver { private static final String SETTING_NUMBER_OF_SHOTS = "Number of shots"; @@ -67,7 +66,11 @@ public List getSolverSettings() { } @Override - public Mono> solve(String input, SubRoutineResolver subRoutineResolver, SolvingProperties properties) { + public Mono> solve( + String input, + SubRoutineResolver subRoutineResolver, + SolvingProperties properties + ) { var solution = new Solution<>(this); int shotNumber = properties.getSetting(SETTING_NUMBER_OF_SHOTS) diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java index d93390f2..7701bc1a 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java @@ -3,18 +3,16 @@ import edu.kit.provideq.toolbox.meta.Problem; import edu.kit.provideq.toolbox.meta.ProblemManager; import edu.kit.provideq.toolbox.meta.ProblemType; +import java.util.Set; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.Set; - @Configuration public class ExecutorConfiguration { public static final ProblemType EXECUTOR_CONFIG = new ProblemType<>( "circuit-processing-executor", String.class, - ExecutionResult.class, - null + ExecutionResult.class ); @Bean diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java index 953efc12..26afe47f 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java @@ -1,22 +1,18 @@ package edu.kit.provideq.toolbox.circuit.processing.solver.mitigation; -import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionResult; -import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionSolver; import edu.kit.provideq.toolbox.meta.Problem; import edu.kit.provideq.toolbox.meta.ProblemManager; import edu.kit.provideq.toolbox.meta.ProblemType; +import java.util.Set; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.Set; - @Configuration public class ErrorMitigationConfiguration { public static final ProblemType MITIGATION_CONFIG = new ProblemType<>( "circuit-processing-mitigation", String.class, - String.class, - null + String.class ); @Bean diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java index 5c70686a..5f6c3f87 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java @@ -22,7 +22,11 @@ public String getDescription() { } @Override - public Mono> solve(String input, SubRoutineResolver subRoutineResolver, SolvingProperties properties) { + public Mono> solve( + String input, + SubRoutineResolver subRoutineResolver, + SolvingProperties properties + ) { var solution = new Solution<>(this); solution.setSolutionData(input); return Mono.just(solution); diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java index 78dfbbfd..bfbe3f17 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java @@ -3,18 +3,16 @@ import edu.kit.provideq.toolbox.meta.Problem; import edu.kit.provideq.toolbox.meta.ProblemManager; import edu.kit.provideq.toolbox.meta.ProblemType; +import java.util.Set; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.Set; - @Configuration public class OptimizationConfiguration { public static final ProblemType OPTIMIZATION_CONFIG = new ProblemType<>( "circuit-processing-optimization", String.class, - String.class, - null + String.class ); @Bean diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java index 846fad84..8c883e00 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java @@ -2,18 +2,21 @@ import edu.kit.provideq.toolbox.Solution; import edu.kit.provideq.toolbox.circuit.processing.solver.CircuitProcessingSolver; -import edu.kit.provideq.toolbox.meta.*; +import edu.kit.provideq.toolbox.meta.ProblemSolver; +import edu.kit.provideq.toolbox.meta.ProblemType; +import edu.kit.provideq.toolbox.meta.SolvingProperties; +import edu.kit.provideq.toolbox.meta.SubRoutineDefinition; +import edu.kit.provideq.toolbox.meta.SubRoutineResolver; import edu.kit.provideq.toolbox.meta.setting.SolverSetting; import edu.kit.provideq.toolbox.meta.setting.basic.SelectSetting; import edu.kit.provideq.toolbox.process.PythonProcessRunner; +import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; -import java.util.List; - @Component public class OptimizationSolver implements ProblemSolver { private static final String SETTING_SELECT_OPTIMIZER = "Selected Optimization Pass"; From b83fe15a145824b24dcac13a996d8b2c127c8534 Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Wed, 19 Mar 2025 17:29:27 +0100 Subject: [PATCH 04/10] Implement suggestions --- .../projectq-executor/projectq_executor.py | 17 ----------------- solvers/circuitprocessing/requirements.txt | 2 -- .../solver/executor/ExecutionSolver.java | 2 +- .../solver/optimization/OptimizationSolver.java | 5 +++-- 4 files changed, 4 insertions(+), 22 deletions(-) delete mode 100644 solvers/circuitprocessing/projectq-executor/projectq_executor.py diff --git a/solvers/circuitprocessing/projectq-executor/projectq_executor.py b/solvers/circuitprocessing/projectq-executor/projectq_executor.py deleted file mode 100644 index 8600c2bd..00000000 --- a/solvers/circuitprocessing/projectq-executor/projectq_executor.py +++ /dev/null @@ -1,17 +0,0 @@ -import sys -from pytket.qasm import circuit_from_qasm_str -from pytket.extensions.projectq import ProjectQBackend - -input_circuit = sys.argv[1] -shots = int(sys.argv[2]) - -try: - circuit = circuit_from_qasm_str(input_circuit) -except Exception as e: - print("Was not able to convert to OpenQASM: ", e) - sys.exit(1) - -backend = ProjectQBackend() -handle = backend.process_circuit(circuit, n_shots=shots) -result = backend.get_result(handle) -print(result.get_shots()) \ No newline at end of file diff --git a/solvers/circuitprocessing/requirements.txt b/solvers/circuitprocessing/requirements.txt index 40a709cf..4fde5da3 100644 --- a/solvers/circuitprocessing/requirements.txt +++ b/solvers/circuitprocessing/requirements.txt @@ -1,5 +1,3 @@ pytket pytket-qiskit -pytket-pyquil -pytket-projectq pytket-qulacs \ No newline at end of file diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java index 58ed0aeb..754967fe 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java @@ -53,7 +53,7 @@ public List getSolverSettings() { SETTING_NUMBER_OF_SHOTS, "The number of shots to run", 1, - 10000, + 1000000, DEFAULT_NUMBER_OF_SHOTS), new SelectSetting<>( SETTING_SELECT_SIMULATOR, diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java index 8c883e00..ebd8dced 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java @@ -37,12 +37,13 @@ public OptimizationSolver( @Override public String getName() { - return "Optimize OpenQASM circuit"; + return "Apply Tket Optimization Pass"; } @Override public String getDescription() { - return "Run optimization algorithms on an OpenQASM circuit"; + return "Transform the given circuit into an optimized but equivalent circuit using" + + "Tket compilation passes (e.g. removing redundancies)."; } @Override From 28ff4cde6d74f876549e381b6d3378cf8e27a2bb Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Mon, 10 Mar 2025 12:27:27 +0100 Subject: [PATCH 05/10] Add execution and optimization solvers --- .../projectq-executor/projectq_executor.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 solvers/circuitprocessing/projectq-executor/projectq_executor.py diff --git a/solvers/circuitprocessing/projectq-executor/projectq_executor.py b/solvers/circuitprocessing/projectq-executor/projectq_executor.py new file mode 100644 index 00000000..8600c2bd --- /dev/null +++ b/solvers/circuitprocessing/projectq-executor/projectq_executor.py @@ -0,0 +1,17 @@ +import sys +from pytket.qasm import circuit_from_qasm_str +from pytket.extensions.projectq import ProjectQBackend + +input_circuit = sys.argv[1] +shots = int(sys.argv[2]) + +try: + circuit = circuit_from_qasm_str(input_circuit) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +backend = ProjectQBackend() +handle = backend.process_circuit(circuit, n_shots=shots) +result = backend.get_result(handle) +print(result.get_shots()) \ No newline at end of file From b31e1b2db094ad81b560a9f877af1bdec91253b0 Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Wed, 19 Mar 2025 17:29:27 +0100 Subject: [PATCH 06/10] Implement suggestions --- .../projectq-executor/projectq_executor.py | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 solvers/circuitprocessing/projectq-executor/projectq_executor.py diff --git a/solvers/circuitprocessing/projectq-executor/projectq_executor.py b/solvers/circuitprocessing/projectq-executor/projectq_executor.py deleted file mode 100644 index 8600c2bd..00000000 --- a/solvers/circuitprocessing/projectq-executor/projectq_executor.py +++ /dev/null @@ -1,17 +0,0 @@ -import sys -from pytket.qasm import circuit_from_qasm_str -from pytket.extensions.projectq import ProjectQBackend - -input_circuit = sys.argv[1] -shots = int(sys.argv[2]) - -try: - circuit = circuit_from_qasm_str(input_circuit) -except Exception as e: - print("Was not able to convert to OpenQASM: ", e) - sys.exit(1) - -backend = ProjectQBackend() -handle = backend.process_circuit(circuit, n_shots=shots) -result = backend.get_result(handle) -print(result.get_shots()) \ No newline at end of file From d377a8b6c36b8e4f23ae0205933f68e7fcbfe30f Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Mon, 26 May 2025 13:52:30 +0200 Subject: [PATCH 07/10] Preliminary migration for circuit processing to venvs --- .../aer-noisy/aer_noisy_executor.py | 11 +++++++++-- .../default-executor/default_executor.py | 11 +++++++++-- .../qulacs-executor/qulacs_executor.py | 11 +++++++++-- .../{ => circuitexecution}/requirements.txt | 0 .../decompose_multi_cx_optimizer.py | 10 ++++++++-- .../remove_redundancies_optimizer.py | 7 ++++++- .../circuitoptimizing/requirements.txt | 1 + .../solver/executor/ExecutionSolver.java | 14 +++++++++++--- .../solver/optimization/OptimizationSolver.java | 14 +++++++++++--- 9 files changed, 64 insertions(+), 15 deletions(-) rename solvers/circuitprocessing/{ => circuitexecution}/aer-noisy/aer_noisy_executor.py (82%) rename solvers/circuitprocessing/{ => circuitexecution}/default-executor/default_executor.py (70%) rename solvers/circuitprocessing/{ => circuitexecution}/qulacs-executor/qulacs_executor.py (70%) rename solvers/circuitprocessing/{ => circuitexecution}/requirements.txt (100%) rename solvers/{ => circuitprocessing}/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py (69%) rename solvers/{ => circuitprocessing}/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py (75%) create mode 100644 solvers/circuitprocessing/circuitoptimizing/requirements.txt diff --git a/solvers/circuitprocessing/aer-noisy/aer_noisy_executor.py b/solvers/circuitprocessing/circuitexecution/aer-noisy/aer_noisy_executor.py similarity index 82% rename from solvers/circuitprocessing/aer-noisy/aer_noisy_executor.py rename to solvers/circuitprocessing/circuitexecution/aer-noisy/aer_noisy_executor.py index 9db4439b..c63a4388 100644 --- a/solvers/circuitprocessing/aer-noisy/aer_noisy_executor.py +++ b/solvers/circuitprocessing/circuitexecution/aer-noisy/aer_noisy_executor.py @@ -5,8 +5,15 @@ from qiskit_aer.noise import NoiseModel from qiskit_aer.noise.errors import depolarizing_error -input_circuit = sys.argv[1] -shots = sys.argv[2] +input_path = sys.argv[1] +num_runs = sys.argv[2] + +# read input from file +with open(input_path, 'r') as input_file: + text = input_file.read() + +input_circuit = text +shots = num_runs try: circuit = circuit_from_qasm_str(input_circuit) diff --git a/solvers/circuitprocessing/default-executor/default_executor.py b/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py similarity index 70% rename from solvers/circuitprocessing/default-executor/default_executor.py rename to solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py index 9ce98997..c5a43bde 100644 --- a/solvers/circuitprocessing/default-executor/default_executor.py +++ b/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py @@ -2,8 +2,15 @@ from pytket.qasm import circuit_from_qasm_str from pytket.extensions.qiskit import AerBackend -input_circuit = sys.argv[1] -shots = int(sys.argv[2]) +input_path = sys.argv[1] +num_runs = sys.argv[2] + +# read input from file +with open(input_path, 'r') as input_file: + text = input_file.read() + +input_circuit = text +shots = num_runs try: circuit = circuit_from_qasm_str(input_circuit) diff --git a/solvers/circuitprocessing/qulacs-executor/qulacs_executor.py b/solvers/circuitprocessing/circuitexecution/qulacs-executor/qulacs_executor.py similarity index 70% rename from solvers/circuitprocessing/qulacs-executor/qulacs_executor.py rename to solvers/circuitprocessing/circuitexecution/qulacs-executor/qulacs_executor.py index 9652f6b0..71963c62 100644 --- a/solvers/circuitprocessing/qulacs-executor/qulacs_executor.py +++ b/solvers/circuitprocessing/circuitexecution/qulacs-executor/qulacs_executor.py @@ -2,8 +2,15 @@ from pytket.qasm import circuit_from_qasm_str from pytket.extensions.qulacs import QulacsBackend -input_circuit = sys.argv[1] -shots = int(sys.argv[2]) +input_path = sys.argv[1] +num_runs = sys.argv[2] + +# read input from file +with open(input_path, 'r') as input_file: + text = input_file.read() + +input_circuit = text +shots = num_runs try: circuit = circuit_from_qasm_str(input_circuit) diff --git a/solvers/circuitprocessing/requirements.txt b/solvers/circuitprocessing/circuitexecution/requirements.txt similarity index 100% rename from solvers/circuitprocessing/requirements.txt rename to solvers/circuitprocessing/circuitexecution/requirements.txt diff --git a/solvers/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py b/solvers/circuitprocessing/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py similarity index 69% rename from solvers/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py rename to solvers/circuitprocessing/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py index 3d62f964..3378a019 100644 --- a/solvers/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py +++ b/solvers/circuitprocessing/circuitoptimizing/decompose-multi-cx/decompose_multi_cx_optimizer.py @@ -3,8 +3,13 @@ from pytket.predicates import CompilationUnit from pytket.passes import DecomposeMultiQubitsCX +input_path = sys.argv[1] -input_circuit = sys.argv[1] +# read input from file +with open(input_path, 'r') as input_file: + text = input_file.read() + +input_circuit = text try: circuit = circuit_from_qasm_str(input_circuit) @@ -16,4 +21,5 @@ cu = CompilationUnit(circuit) pass1.apply(cu) -print(circuit_to_qasm_str(cu.circuit)) \ No newline at end of file +print(circuit_to_qasm_str(cu.circuit)) + diff --git a/solvers/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py b/solvers/circuitprocessing/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py similarity index 75% rename from solvers/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py rename to solvers/circuitprocessing/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py index 58b57e68..a238a84a 100644 --- a/solvers/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py +++ b/solvers/circuitprocessing/circuitoptimizing/remove-redundancies/remove_redundancies_optimizer.py @@ -3,8 +3,13 @@ from pytket.predicates import CompilationUnit from pytket.passes import RemoveRedundancies +input_path = sys.argv[1] -input_circuit = sys.argv[1] +# read input from file +with open(input_path, 'r') as input_file: + text = input_file.read() + +input_circuit = text try: circuit = circuit_from_qasm_str(input_circuit) diff --git a/solvers/circuitprocessing/circuitoptimizing/requirements.txt b/solvers/circuitprocessing/circuitoptimizing/requirements.txt new file mode 100644 index 00000000..f32bd3e4 --- /dev/null +++ b/solvers/circuitprocessing/circuitoptimizing/requirements.txt @@ -0,0 +1 @@ +pytket \ No newline at end of file diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java index 754967fe..9cca644d 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java @@ -8,6 +8,7 @@ import edu.kit.provideq.toolbox.meta.setting.SolverSetting; import edu.kit.provideq.toolbox.meta.setting.basic.IntegerSetting; import edu.kit.provideq.toolbox.meta.setting.basic.SelectSetting; +import edu.kit.provideq.toolbox.process.ProcessRunner; import edu.kit.provideq.toolbox.process.PythonProcessRunner; import java.util.List; import java.util.Optional; @@ -25,14 +26,17 @@ public class ExecutionSolver implements ProblemSolver { private static final QuantumSimulator DEFAULT_SIMULATOR = QuantumSimulator.AER; private final String scriptPath; + private final String venv; private final ApplicationContext context; @Autowired public ExecutionSolver( - @Value("${circuitprocessing.base.directory}") String scriptPath, + @Value("${path.circuitprocessing.circuitexecution}") String scriptPath, + @Value("${venv.circuitprocessing.circuitexecution}") String venv, ApplicationContext context ) { this.context = context; + this.venv = venv; this.scriptPath = scriptPath; } @@ -83,8 +87,12 @@ public Mono> solve( .orElse(DEFAULT_SIMULATOR); var processResult = context - .getBean(PythonProcessRunner.class, scriptPath + selectedSimulator.getScriptPath()) - .withArguments(input, String.valueOf(shotNumber)) + .getBean(PythonProcessRunner.class, scriptPath + selectedSimulator.getScriptPath(), venv) + .withArguments( + ProcessRunner.INPUT_FILE_PATH, + String.valueOf(shotNumber) + ) + .writeInputFile(input) .readOutputString() .run(getProblemType(), solution.getId()); diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java index ebd8dced..be8d1b4d 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationSolver.java @@ -9,6 +9,7 @@ import edu.kit.provideq.toolbox.meta.SubRoutineResolver; import edu.kit.provideq.toolbox.meta.setting.SolverSetting; import edu.kit.provideq.toolbox.meta.setting.basic.SelectSetting; +import edu.kit.provideq.toolbox.process.ProcessRunner; import edu.kit.provideq.toolbox.process.PythonProcessRunner; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; @@ -24,14 +25,17 @@ public class OptimizationSolver implements ProblemSolver { QuantumOptimizer.DECOMPOSE_MULTI_CX; private final String scriptPath; + private final String venv; private final ApplicationContext context; @Autowired public OptimizationSolver( - @Value("${circuitoptimizing.base.directory}") String scriptPath, + @Value("${path.circuitprocessing.circuitoptimization}") String scriptPath, + @Value("${venv.circuitprocessing.circuitoptimization}") String venv, ApplicationContext context ) { this.scriptPath = scriptPath; + this.venv = venv; this.context = context; } @@ -77,9 +81,13 @@ public Mono> solve( .map(s -> s.getSelectedOptionT(OptimizationSolver.QuantumOptimizer::fromValue)) .orElse(DEFAULT_OPTIMIZER); + //String[] inputArray = new String[]{input}; var processResult = context - .getBean(PythonProcessRunner.class, scriptPath + selectedOptimizer.getScriptPath()) - .withArguments(input) + .getBean(PythonProcessRunner.class, scriptPath + selectedOptimizer.getScriptPath(), venv) + .withArguments( + ProcessRunner.INPUT_FILE_PATH + ) + .writeInputFile(input) .readOutputString() .run(getProblemType(), solution.getId()); From 2dd60ba5ce09b0384b456e53245436f6f3f2d247 Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Wed, 22 Apr 2026 05:15:40 +0200 Subject: [PATCH 08/10] Fix issues caused by changes on develop --- .../circuit/processing/CircuitProcessingConfiguration.java | 2 ++ .../circuit/processing/solver/CircuitProcessingSolver.java | 3 ++- .../circuit/processing/solver/MoveToExecutionSolver.java | 3 ++- .../circuit/processing/solver/MoveToMitigationSolver.java | 3 ++- .../circuit/processing/solver/MoveToOptimizationSolver.java | 3 ++- .../processing/solver/executor/ExecutorConfiguration.java | 2 ++ .../solver/mitigation/ErrorMitigationConfiguration.java | 2 ++ .../solver/optimization/OptimizationConfiguration.java | 2 ++ src/main/resources/application.properties | 2 +- 9 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java index c0092195..85abdd4b 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java @@ -14,6 +14,8 @@ public class CircuitProcessingConfiguration { public static final ProblemType CIRCUIT_PROCESSING = new ProblemType<>( "circuit-processing", + "A quantum circuit processing problem that routes a QASM circuit through optimization, " + + "error mitigation, or execution.", String.class, String.class ); diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java index 507ce9c6..9d00eff2 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/CircuitProcessingSolver.java @@ -9,7 +9,8 @@ public abstract class CircuitProcessingSolver implements ProblemSolver CIRCUIT_PROCESSING_SUBROUTINE = new SubRoutineDefinition<>( CircuitProcessingConfiguration.CIRCUIT_PROCESSING, - "Creates a circuit processing solver" + "Creates a circuit processing solver", + true ); @Override diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java index 8d1d6b60..023cd7b8 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToExecutionSolver.java @@ -16,7 +16,8 @@ public class MoveToExecutionSolver extends CircuitProcessingSolver { private static final SubRoutineDefinition EXECUTOR_SUBROUTINE = new SubRoutineDefinition<>( ExecutorConfiguration.EXECUTOR_CONFIG, - "Creates a execution solver" + "Creates a execution solver", + true ); @Override diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java index 56e68fcd..fcfe9892 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToMitigationSolver.java @@ -14,7 +14,8 @@ public class MoveToMitigationSolver extends CircuitProcessingSolver { private static final SubRoutineDefinition MITIGATOR_SUBROUTINE = new SubRoutineDefinition<>( ErrorMitigationConfiguration.MITIGATION_CONFIG, - "Creates a mitigation solver" + "Creates a mitigation solver", + true ); @Override diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java index d213b4ec..794e7b68 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/MoveToOptimizationSolver.java @@ -14,7 +14,8 @@ public class MoveToOptimizationSolver extends CircuitProcessingSolver { private static final SubRoutineDefinition OPTIMIZER_SUBROUTINE = new SubRoutineDefinition<>( OptimizationConfiguration.OPTIMIZATION_CONFIG, - "Creates a optimization solver" + "Creates a optimization solver", + true ); @Override diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java index 7701bc1a..1501f0b4 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java @@ -11,6 +11,8 @@ public class ExecutorConfiguration { public static final ProblemType EXECUTOR_CONFIG = new ProblemType<>( "circuit-processing-executor", + "A quantum circuit execution problem that runs a given QASM circuit on a quantum backend " + + "and returns the measurement results.", String.class, ExecutionResult.class ); diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java index 26afe47f..4fd0952a 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java @@ -11,6 +11,8 @@ public class ErrorMitigationConfiguration { public static final ProblemType MITIGATION_CONFIG = new ProblemType<>( "circuit-processing-mitigation", + "A quantum circuit error mitigation problem that applies error mitigation techniques to " + + "a given QASM circuit.", String.class, String.class ); diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java index bfbe3f17..32f2fed7 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java @@ -11,6 +11,8 @@ public class OptimizationConfiguration { public static final ProblemType OPTIMIZATION_CONFIG = new ProblemType<>( "circuit-processing-optimization", + "A quantum circuit optimization problem that reduces gate count or circuit depth of a " + + "given QASM circuit.", String.class, String.class ); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 01cdfc62..9fb3dbe3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1 @@ -# default spring profile, correct one will be set during runtime (see ToolboxServerApplication.java) # options: mac, windows, linux spring.profiles.active=linux springdoc.swagger-ui.operationsSorter=alpha springdoc.swagger-ui.tagsSorter=alpha working.directory=jobs examples.directory=examples springdoc.swagger-ui.path=/ # Solvers name.solvers=solvers # Non OS-specific solvers: (typically GAMS and Python) name.gams=gams path.gams=${name.solvers}/${name.gams} name.gams.max-cut=max-cut path.gams.max-cut=${path.gams}/${name.gams.max-cut}/maxcut.gms name.gams.sat=sat path.gams.sat=${path.gams}/${name.gams.sat}/sat.gms name.qiskit=qiskit path.qiskit=${name.solvers}/${name.qiskit} name.qiskit.knapsack=knapsack path.qiskit.knapsack=${path.qiskit}/${name.qiskit.knapsack}/knapsack_qiskit.py venv.qiskit.knapsack=${name.solvers}_${name.qiskit}_${name.qiskit.knapsack} name.qiskit.materialsimulation=materialsimulation path.qiskit.materialsimulation=${path.qiskit}/${name.qiskit.materialsimulation}/material_simulation_qiskit.py venv.qiskit.materialsimulation=${name.solvers}_${name.qiskit}_${name.qiskit.materialsimulation} name.qiskit.max-cut=max-cut path.qiskit.max-cut=${path.qiskit}/${name.qiskit.max-cut}/maxCut_qiskit.py venv.qiskit.max-cut=${name.solvers}_${name.qiskit}_${name.qiskit.max-cut} name.qiskit.qubo=qubo path.qiskit.qubo=${path.qiskit}/${name.qiskit.qubo}/qubo_qiskit.py venv.qiskit.qubo=${name.solvers}_${name.qiskit}_${name.qiskit.qubo} name.cirq=cirq path.cirq=${name.solvers}/${name.cirq} name.cirq.max-cut=max-cut path.cirq.max-cut=${path.cirq}/${name.cirq.max-cut}/max_cut_cirq.py venv.cirq.max-cut=${name.solvers}_${name.cirq}_${name.cirq.max-cut} name.qrisp=qrisp path.qrisp=${name.solvers}/${name.qrisp} name.qrisp.vrp=vrp path.qrisp.vrp=${path.qrisp}/${name.qrisp.vrp}/grover.py venv.qrisp.vrp=${name.solvers}_${name.qrisp}_${name.qrisp.vrp} name.qrisp.qubo=qubo path.qrisp.qubo=${path.qrisp}/${name.qrisp.qubo}/qaoa.py venv.qrisp.qubo=${name.solvers}_${name.qrisp}_${name.qrisp.qubo} name.qrisp.sat=sat path.qrisp.sat.grover=${path.qrisp}/${name.qrisp.sat}/grover.py path.qrisp.sat.exact=${path.qrisp}/${name.qrisp.sat}/exact_grover.py venv.qrisp.sat=${name.solvers}_${name.qrisp}_${name.qrisp.sat} name.dwave=dwave path.dwave=${name.solvers}/${name.dwave} name.dwave.qubo=qubo path.dwave.qubo=${path.dwave}/${name.dwave.qubo}/main.py venv.dwave.qubo=${name.solvers}_${name.dwave}_${name.dwave.qubo} # Non OS-specific custom solvers: (solvers that are not part of a framework) name.custom=custom path.custom=${name.solvers}/${name.custom} name.custom.hs-knapsack=hs-knapsack path.custom.hs-knapsack=${path.custom}/${name.custom.hs-knapsack}/knapsack.py venv.custom.hs-knapsack=${name.solvers}_${name.custom}_${name.custom.hs-knapsack} name.custom.lkh=lkh path.custom.lkh=${path.custom}/${name.custom.lkh}/vrp_lkh.py venv.custom.lkh=${name.solvers}_${name.custom}_${name.custom.lkh} name.custom.berger-vrp=berger-vrp name.custom.sharp-sat-bruteforce=sharp-sat-bruteforce path.custom.sharp-sat-bruteforce=${path.custom}/${name.custom.sharp-sat-bruteforce}/exact-solution-counter.py venv.custom.sharp-sat-bruteforce=${name.solvers}_${name.custom}_${name.custom.sharp-sat-bruteforce} name.custom.sharp-sat-ganak=sharp-sat-ganak venv.custom.sharp-sat-ganak=${name.solvers}_${name.custom}_${name.custom.sharp-sat-ganak} # Demonstrators name.demonstrators=demonstrators name.demonstrators.cplex=cplex path.demonstrators.cplex=${name.demonstrators}/${name.demonstrators.cplex} name.demonstrators.cplex.mip=mip-solver path.demonstrators.cplex.mip=${path.demonstrators.cplex}/${name.demonstrators.cplex.mip}/mip-solver.py venv.demonstrators.cplex.mip=${name.demonstrators}_${name.demonstrators.cplex}_${name.demonstrators.cplex.mip} name.demonstrators.qiskit=qiskit path.demonstrators.qiskit=${name.demonstrators}/${name.demonstrators.qiskit} name.demonstrators.qiskit.molecule-energy=molecule-energy path.demonstrators.qiskit.molecule-energy=${path.demonstrators.qiskit}/${name.demonstrators.qiskit.molecule-energy}/molecule-energy.py venv.demonstrators.qiskit.molecule-energy=${name.demonstrators}_${name.demonstrators.qiskit}_${name.demonstrators.qiskit.molecule-energy} \ No newline at end of file +# default spring profile, correct one will be set during runtime (see ToolboxServerApplication.java) # options: mac, windows, linux spring.profiles.active=linux springdoc.swagger-ui.operationsSorter=alpha springdoc.swagger-ui.tagsSorter=alpha working.directory=jobs examples.directory=examples springdoc.swagger-ui.path=/ # Solvers name.solvers=solvers # Non OS-specific solvers: (typically GAMS and Python) name.gams=gams path.gams=${name.solvers}/${name.gams} name.gams.max-cut=max-cut path.gams.max-cut=${path.gams}/${name.gams.max-cut}/maxcut.gms name.gams.sat=sat path.gams.sat=${path.gams}/${name.gams.sat}/sat.gms name.qiskit=qiskit path.qiskit=${name.solvers}/${name.qiskit} name.qiskit.knapsack=knapsack path.qiskit.knapsack=${path.qiskit}/${name.qiskit.knapsack}/knapsack_qiskit.py venv.qiskit.knapsack=${name.solvers}_${name.qiskit}_${name.qiskit.knapsack} name.qiskit.materialsimulation=materialsimulation path.qiskit.materialsimulation=${path.qiskit}/${name.qiskit.materialsimulation}/material_simulation_qiskit.py venv.qiskit.materialsimulation=${name.solvers}_${name.qiskit}_${name.qiskit.materialsimulation} name.qiskit.max-cut=max-cut path.qiskit.max-cut=${path.qiskit}/${name.qiskit.max-cut}/maxCut_qiskit.py venv.qiskit.max-cut=${name.solvers}_${name.qiskit}_${name.qiskit.max-cut} name.qiskit.qubo=qubo path.qiskit.qubo=${path.qiskit}/${name.qiskit.qubo}/qubo_qiskit.py venv.qiskit.qubo=${name.solvers}_${name.qiskit}_${name.qiskit.qubo} name.cirq=cirq path.cirq=${name.solvers}/${name.cirq} name.cirq.max-cut=max-cut path.cirq.max-cut=${path.cirq}/${name.cirq.max-cut}/max_cut_cirq.py venv.cirq.max-cut=${name.solvers}_${name.cirq}_${name.cirq.max-cut} name.qrisp=qrisp path.qrisp=${name.solvers}/${name.qrisp} name.qrisp.vrp=vrp path.qrisp.vrp=${path.qrisp}/${name.qrisp.vrp}/grover.py venv.qrisp.vrp=${name.solvers}_${name.qrisp}_${name.qrisp.vrp} name.qrisp.qubo=qubo path.qrisp.qubo=${path.qrisp}/${name.qrisp.qubo}/qaoa.py venv.qrisp.qubo=${name.solvers}_${name.qrisp}_${name.qrisp.qubo} name.qrisp.sat=sat path.qrisp.sat.grover=${path.qrisp}/${name.qrisp.sat}/grover.py path.qrisp.sat.exact=${path.qrisp}/${name.qrisp.sat}/exact_grover.py venv.qrisp.sat=${name.solvers}_${name.qrisp}_${name.qrisp.sat} name.dwave=dwave path.dwave=${name.solvers}/${name.dwave} name.dwave.qubo=qubo path.dwave.qubo=${path.dwave}/${name.dwave.qubo}/main.py venv.dwave.qubo=${name.solvers}_${name.dwave}_${name.dwave.qubo} # Non OS-specific custom solvers: (solvers that are not part of a framework) name.custom=custom path.custom=${name.solvers}/${name.custom} name.custom.hs-knapsack=hs-knapsack path.custom.hs-knapsack=${path.custom}/${name.custom.hs-knapsack}/knapsack.py venv.custom.hs-knapsack=${name.solvers}_${name.custom}_${name.custom.hs-knapsack} name.custom.lkh=lkh path.custom.lkh=${path.custom}/${name.custom.lkh}/vrp_lkh.py venv.custom.lkh=${name.solvers}_${name.custom}_${name.custom.lkh} name.custom.berger-vrp=berger-vrp name.custom.sharp-sat-bruteforce=sharp-sat-bruteforce path.custom.sharp-sat-bruteforce=${path.custom}/${name.custom.sharp-sat-bruteforce}/exact-solution-counter.py venv.custom.sharp-sat-bruteforce=${name.solvers}_${name.custom}_${name.custom.sharp-sat-bruteforce} name.custom.sharp-sat-ganak=sharp-sat-ganak venv.custom.sharp-sat-ganak=${name.solvers}_${name.custom}_${name.custom.sharp-sat-ganak} # Demonstrators name.demonstrators=demonstrators name.demonstrators.cplex=cplex path.demonstrators.cplex=${name.demonstrators}/${name.demonstrators.cplex} name.demonstrators.cplex.mip=mip-solver path.demonstrators.cplex.mip=${path.demonstrators.cplex}/${name.demonstrators.cplex.mip}/mip-solver.py venv.demonstrators.cplex.mip=${name.demonstrators}_${name.demonstrators.cplex}_${name.demonstrators.cplex.mip} name.demonstrators.qiskit=qiskit path.demonstrators.qiskit=${name.demonstrators}/${name.demonstrators.qiskit} name.demonstrators.qiskit.molecule-energy=molecule-energy path.demonstrators.qiskit.molecule-energy=${path.demonstrators.qiskit}/${name.demonstrators.qiskit.molecule-energy}/molecule-energy.py venv.demonstrators.qiskit.molecule-energy=${name.demonstrators}_${name.demonstrators.qiskit}_${name.demonstrators.qiskit.molecule-energy} name.circuitprocessing=circuitprocessing path.circuitprocessing=${name.solvers}/${name.circuitprocessing} name.circuitprocessing.circuitexecution=circuitexecution path.circuitprocessing.circuitexecution=${path.circuitprocessing}/${name.circuitprocessing.circuitexecution}/ venv.circuitprocessing.circuitexecution=${name.solvers}_${name.circuitprocessing}_${name.circuitprocessing.circuitexecution} name.circuitprocessing.circuitoptimization=circuitoptimizing path.circuitprocessing.circuitoptimization=${path.circuitprocessing}/${name.circuitprocessing.circuitoptimization}/ venv.circuitprocessing.circuitoptimization=${name.solvers}_${name.circuitprocessing}_${name.circuitprocessing.circuitoptimization} \ No newline at end of file From a76802fc03c890b3aa7f30d6a71306c9f733944b Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Wed, 29 Apr 2026 13:30:44 +0200 Subject: [PATCH 09/10] Add basic testing for circuit processing --- .../default-executor/default_executor.py | 2 +- .../circuitexecution/requirements.txt | 2 +- .../mitigation/ErrorMitigationSolver.java | 1 + .../api/CircuitProcessingSolversTest.java | 101 ++++++++++++++++++ .../api/ErrorMitigationSolverTest.java | 38 +++++++ .../toolbox/api/ExecutionSolverTest.java | 49 +++++++++ .../toolbox/api/OptimizationSolverTest.java | 63 +++++++++++ 7 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java create mode 100644 src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java create mode 100644 src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java create mode 100644 src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java diff --git a/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py b/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py index c5a43bde..96c6c2e6 100644 --- a/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py +++ b/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py @@ -10,7 +10,7 @@ text = input_file.read() input_circuit = text -shots = num_runs +shots = int(num_runs) try: circuit = circuit_from_qasm_str(input_circuit) diff --git a/solvers/circuitprocessing/circuitexecution/requirements.txt b/solvers/circuitprocessing/circuitexecution/requirements.txt index 4fde5da3..46f05119 100644 --- a/solvers/circuitprocessing/circuitexecution/requirements.txt +++ b/solvers/circuitprocessing/circuitexecution/requirements.txt @@ -1,3 +1,3 @@ pytket pytket-qiskit -pytket-qulacs \ No newline at end of file +# pytket-qulacs \ No newline at end of file diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java index 5f6c3f87..6399409e 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationSolver.java @@ -29,6 +29,7 @@ public Mono> solve( ) { var solution = new Solution<>(this); solution.setSolutionData(input); + solution.complete(); return Mono.just(solution); } diff --git a/src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java b/src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java new file mode 100644 index 00000000..0ea70b1c --- /dev/null +++ b/src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java @@ -0,0 +1,101 @@ +package edu.kit.provideq.toolbox.api; + +import static edu.kit.provideq.toolbox.circuit.processing.CircuitProcessingConfiguration.CIRCUIT_PROCESSING; +import static edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutorConfiguration.EXECUTOR_CONFIG; +import static edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationConfiguration.MITIGATION_CONFIG; +import static edu.kit.provideq.toolbox.circuit.processing.solver.optimization.OptimizationConfiguration.OPTIMIZATION_CONFIG; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToExecutionSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToMitigationSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToOptimizationSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.optimization.OptimizationSolver; +import java.time.Duration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.reactive.server.WebTestClient; + +@SpringBootTest +@AutoConfigureMockMvc +class CircuitProcessingSolversTest { + private static final String CIRCUIT = """ + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[2]; + creg c[2]; + h q[0]; + cx q[0],q[1]; + measure q[0] -> c[0]; + measure q[1] -> c[1];"""; + + @Autowired + private WebTestClient client; + + @Autowired + private MoveToMitigationSolver moveToMitigationSolver; + + @Autowired + private MoveToExecutionSolver moveToExecutionSolver; + + @Autowired + private MoveToOptimizationSolver moveToOptimizationSolver; + + @Autowired + private ErrorMitigationSolver errorMitigationSolver; + + @Autowired + private ExecutionSolver executionSolver; + + @Autowired + private OptimizationSolver optimizationSolver; + + @BeforeEach + void beforeEach() { + this.client = this.client.mutate() + .responseTimeout(Duration.ofSeconds(60)) + .build(); + } + + @Test + void testMoveToMitigationSolver() { + var problemDto = ApiTestHelper.createProblem(client, moveToMitigationSolver, CIRCUIT, CIRCUIT_PROCESSING); + var subProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); + ApiTestHelper.setProblemSolver(client, errorMitigationSolver, subProblemId, MITIGATION_CONFIG.getId()); + var solvedDto = ApiTestHelper.trySolveFor(60, client, problemDto.getId(), CIRCUIT_PROCESSING); + ApiTestHelper.testSolution(solvedDto); + assertEquals(CIRCUIT, solvedDto.getSolution().getSolutionData()); + } + + @Test + void testMoveToExecutionSolver() { + var problemDto = ApiTestHelper.createProblem(client, moveToExecutionSolver, CIRCUIT, CIRCUIT_PROCESSING); + var subProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); + ApiTestHelper.setProblemSolver(client, executionSolver, subProblemId, EXECUTOR_CONFIG.getId()); + var solvedDto = ApiTestHelper.trySolveFor(60, client, problemDto.getId(), CIRCUIT_PROCESSING); + ApiTestHelper.testSolution(solvedDto); + assertFalse(solvedDto.getSolution().getSolutionData().isBlank()); + } + + @Test + void testMoveToOptimizationSolver() { + var problemDto = ApiTestHelper.createProblem(client, moveToOptimizationSolver, CIRCUIT, CIRCUIT_PROCESSING); + var optSubProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); + var optDto = ApiTestHelper.setProblemSolver( + client, optimizationSolver, optSubProblemId, OPTIMIZATION_CONFIG.getId()); + var circuitSubProblemId = optDto.getSubProblems().get(0).getSubProblemIds().get(0); + var mitigationEntryDto = ApiTestHelper.setProblemSolver( + client, moveToMitigationSolver, circuitSubProblemId, CIRCUIT_PROCESSING.getId()); + var mitigationId = mitigationEntryDto.getSubProblems().get(0).getSubProblemIds().get(0); + ApiTestHelper.setProblemSolver(client, errorMitigationSolver, mitigationId, MITIGATION_CONFIG.getId()); + var solvedDto = ApiTestHelper.trySolveFor(120, client, problemDto.getId(), CIRCUIT_PROCESSING); + ApiTestHelper.testSolution(solvedDto); + assertTrue(solvedDto.getSolution().getSolutionData().contains("OPENQASM")); + } +} diff --git a/src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java b/src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java new file mode 100644 index 00000000..7c5ff690 --- /dev/null +++ b/src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java @@ -0,0 +1,38 @@ +package edu.kit.provideq.toolbox.api; + +import static edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationConfiguration.MITIGATION_CONFIG; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationSolver; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.reactive.server.WebTestClient; + +@SpringBootTest +@AutoConfigureMockMvc +class ErrorMitigationSolverTest { + private static final String CIRCUIT = """ + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[2]; + creg c[2]; + h q[0]; + cx q[0],q[1]; + measure q[0] -> c[0]; + measure q[1] -> c[1];"""; + + @Autowired + private WebTestClient client; + + @Autowired + private ErrorMitigationSolver errorMitigationSolver; + + @Test + void testErrorMitigationSolver() { + var problem = ApiTestHelper.createProblem(client, errorMitigationSolver, CIRCUIT, MITIGATION_CONFIG); + ApiTestHelper.testSolution(problem); + assertEquals(CIRCUIT, problem.getSolution().getSolutionData()); + } +} diff --git a/src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java b/src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java new file mode 100644 index 00000000..acb704c1 --- /dev/null +++ b/src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java @@ -0,0 +1,49 @@ +package edu.kit.provideq.toolbox.api; + +import static edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutorConfiguration.EXECUTOR_CONFIG; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import edu.kit.provideq.toolbox.Solution; +import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionSolver; +import java.time.Duration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.reactive.server.WebTestClient; + +@SpringBootTest +@AutoConfigureMockMvc +class ExecutionSolverTest { + private static final String CIRCUIT = """ + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[2]; + creg c[2]; + h q[0]; + cx q[0],q[1]; + measure q[0] -> c[0]; + measure q[1] -> c[1];"""; + + @Autowired + private WebTestClient client; + + @Autowired + private ExecutionSolver executionSolver; + + @BeforeEach + void beforeEach() { + this.client = this.client.mutate() + .responseTimeout(Duration.ofSeconds(60)) + .build(); + } + + @Test + void testExecutionSolver() { + var problem = ApiTestHelper.createProblem(client, executionSolver, CIRCUIT, EXECUTOR_CONFIG); + ApiTestHelper.testSolution(problem); + Solution solution = problem.getSolution(); + assertTrue(solution.getSolutionData().toString().contains("OPENQASM")); + } +} diff --git a/src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java b/src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java new file mode 100644 index 00000000..5ec157b8 --- /dev/null +++ b/src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java @@ -0,0 +1,63 @@ +package edu.kit.provideq.toolbox.api; + +import static edu.kit.provideq.toolbox.circuit.processing.CircuitProcessingConfiguration.CIRCUIT_PROCESSING; +import static edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationConfiguration.MITIGATION_CONFIG; +import static edu.kit.provideq.toolbox.circuit.processing.solver.optimization.OptimizationConfiguration.OPTIMIZATION_CONFIG; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToMitigationSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationSolver; +import edu.kit.provideq.toolbox.circuit.processing.solver.optimization.OptimizationSolver; +import java.time.Duration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.reactive.server.WebTestClient; + +@SpringBootTest +@AutoConfigureMockMvc +class OptimizationSolverTest { + private static final String CIRCUIT = """ + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[2]; + creg c[2]; + h q[0]; + cx q[0],q[1]; + measure q[0] -> c[0]; + measure q[1] -> c[1];"""; + + @Autowired + private WebTestClient client; + + @Autowired + private OptimizationSolver optimizationSolver; + + @Autowired + private MoveToMitigationSolver moveToMitigationSolver; + + @Autowired + private ErrorMitigationSolver errorMitigationSolver; + + @BeforeEach + void beforeEach() { + this.client = this.client.mutate() + .responseTimeout(Duration.ofSeconds(60)) + .build(); + } + + @Test + void testOptimizationSolver() { + var problemDto = ApiTestHelper.createProblem(client, optimizationSolver, CIRCUIT, OPTIMIZATION_CONFIG); + var circuitSubProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); + var mitigationEntryDto = ApiTestHelper.setProblemSolver( + client, moveToMitigationSolver, circuitSubProblemId, CIRCUIT_PROCESSING.getId()); + var mitigationId = mitigationEntryDto.getSubProblems().get(0).getSubProblemIds().get(0); + ApiTestHelper.setProblemSolver(client, errorMitigationSolver, mitigationId, MITIGATION_CONFIG.getId()); + var solvedDto = ApiTestHelper.trySolveFor(120, client, problemDto.getId(), OPTIMIZATION_CONFIG); + ApiTestHelper.testSolution(solvedDto); + assertTrue(solvedDto.getSolution().getSolutionData().contains("OPENQASM")); + } +} From c461dfeeb58c0054e541436b472237a2c5c083de Mon Sep 17 00:00:00 2001 From: ekulos-code Date: Thu, 7 May 2026 18:52:05 +0200 Subject: [PATCH 10/10] Add problem fetching from files for tests and configs Merge circuit execution files --- .../aer-noisy/aer_noisy_executor.py | 34 --------------- .../default-executor/default_executor.py | 25 ----------- .../circuitexecution/executor.py | 40 +++++++++++++++++ .../qulacs-executor/qulacs_executor.py | 25 ----------- .../CircuitProcessingConfiguration.java | 43 +++++++++++-------- .../solver/executor/ExecutionSolver.java | 23 +++++----- .../executor/ExecutorConfiguration.java | 23 ++++++++-- .../ErrorMitigationConfiguration.java | 23 ++++++++-- .../OptimizationConfiguration.java | 23 ++++++++-- .../circuit/processing/bell-state.qasm | 8 ++++ .../toolbox/circuit/processing/cswap.qasm | 6 +++ .../api/CircuitProcessingSolversTest.java | 39 +++++++++++------ .../api/ErrorMitigationSolverTest.java | 38 ++++++++++------ .../toolbox/api/ExecutionSolverTest.java | 29 ++++++++----- .../toolbox/api/OptimizationSolverTest.java | 31 ++++++++----- 15 files changed, 236 insertions(+), 174 deletions(-) delete mode 100644 solvers/circuitprocessing/circuitexecution/aer-noisy/aer_noisy_executor.py delete mode 100644 solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py create mode 100644 solvers/circuitprocessing/circuitexecution/executor.py delete mode 100644 solvers/circuitprocessing/circuitexecution/qulacs-executor/qulacs_executor.py create mode 100644 src/main/resources/edu/kit/provideq/toolbox/circuit/processing/bell-state.qasm create mode 100644 src/main/resources/edu/kit/provideq/toolbox/circuit/processing/cswap.qasm diff --git a/solvers/circuitprocessing/circuitexecution/aer-noisy/aer_noisy_executor.py b/solvers/circuitprocessing/circuitexecution/aer-noisy/aer_noisy_executor.py deleted file mode 100644 index c63a4388..00000000 --- a/solvers/circuitprocessing/circuitexecution/aer-noisy/aer_noisy_executor.py +++ /dev/null @@ -1,34 +0,0 @@ -import sys -from pytket.qasm import circuit_from_qasm_str -from pytket.extensions.qiskit import AerBackend - -from qiskit_aer.noise import NoiseModel -from qiskit_aer.noise.errors import depolarizing_error - -input_path = sys.argv[1] -num_runs = sys.argv[2] - -# read input from file -with open(input_path, 'r') as input_file: - text = input_file.read() - -input_circuit = text -shots = num_runs - -try: - circuit = circuit_from_qasm_str(input_circuit) -except Exception as e: - print("Was not able to convert to OpenQASM: ", e) - sys.exit(1) - -# https://docs.quantinuum.com/tket/user-guide/manual/manual_noise.html -noise_model = NoiseModel() -noise_model.add_readout_error([[0.9, 0.1],[0.1, 0.9]], [0]) -noise_model.add_readout_error([[0.95, 0.05],[0.05, 0.95]], [1]) -noise_model.add_quantum_error(depolarizing_error(0.1, 2), ["cx"], [0, 1]) - -backend = AerBackend(noise_model) -c = backend.get_compiled_circuit(circuit) -handle = backend.process_circuit(c, n_shots=int(shots)) -counts = backend.get_result(handle).get_counts() -print(counts) \ No newline at end of file diff --git a/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py b/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py deleted file mode 100644 index 96c6c2e6..00000000 --- a/solvers/circuitprocessing/circuitexecution/default-executor/default_executor.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys -from pytket.qasm import circuit_from_qasm_str -from pytket.extensions.qiskit import AerBackend - -input_path = sys.argv[1] -num_runs = sys.argv[2] - -# read input from file -with open(input_path, 'r') as input_file: - text = input_file.read() - -input_circuit = text -shots = int(num_runs) - -try: - circuit = circuit_from_qasm_str(input_circuit) -except Exception as e: - print("Was not able to convert to OpenQASM: ", e) - sys.exit(1) - -backend = AerBackend() -c = backend.get_compiled_circuit(circuit) -handle = backend.process_circuit(c, n_shots=shots) -counts = backend.get_result(handle).get_counts() -print(counts) \ No newline at end of file diff --git a/solvers/circuitprocessing/circuitexecution/executor.py b/solvers/circuitprocessing/circuitexecution/executor.py new file mode 100644 index 00000000..379288f1 --- /dev/null +++ b/solvers/circuitprocessing/circuitexecution/executor.py @@ -0,0 +1,40 @@ +import sys +from pytket.qasm import circuit_from_qasm_str + +input_path = sys.argv[1] +num_runs = int(sys.argv[2]) +backend_name = sys.argv[3] + +with open(input_path, 'r') as input_file: + text = input_file.read() + +try: + circuit = circuit_from_qasm_str(text) +except Exception as e: + print("Was not able to convert to OpenQASM: ", e) + sys.exit(1) + +if backend_name == "aer": + from pytket.extensions.qiskit import AerBackend + backend = AerBackend() +elif backend_name == "qulacs": + from pytket.extensions.qulacs import QulacsBackend + backend = QulacsBackend() +elif backend_name == "aer_noisy": + from pytket.extensions.qiskit import AerBackend + from qiskit_aer.noise import NoiseModel + from qiskit_aer.noise.errors import depolarizing_error + # https://docs.quantinuum.com/tket/user-guide/manual/manual_noise.html + noise_model = NoiseModel() + noise_model.add_readout_error([[0.9, 0.1], [0.1, 0.9]], [0]) + noise_model.add_readout_error([[0.95, 0.05], [0.05, 0.95]], [1]) + noise_model.add_quantum_error(depolarizing_error(0.1, 2), ["cx"], [0, 1]) + backend = AerBackend(noise_model) +else: + print(f"Unknown backend: {backend_name}", file=sys.stderr) + sys.exit(1) + +c = backend.get_compiled_circuit(circuit) +handle = backend.process_circuit(c, n_shots=num_runs) +counts = backend.get_result(handle).get_counts() +print(counts) diff --git a/solvers/circuitprocessing/circuitexecution/qulacs-executor/qulacs_executor.py b/solvers/circuitprocessing/circuitexecution/qulacs-executor/qulacs_executor.py deleted file mode 100644 index 71963c62..00000000 --- a/solvers/circuitprocessing/circuitexecution/qulacs-executor/qulacs_executor.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys -from pytket.qasm import circuit_from_qasm_str -from pytket.extensions.qulacs import QulacsBackend - -input_path = sys.argv[1] -num_runs = sys.argv[2] - -# read input from file -with open(input_path, 'r') as input_file: - text = input_file.read() - -input_circuit = text -shots = num_runs - -try: - circuit = circuit_from_qasm_str(input_circuit) -except Exception as e: - print("Was not able to convert to OpenQASM: ", e) - sys.exit(1) - -backend = QulacsBackend() -c = backend.get_compiled_circuit(circuit) -handle = backend.process_circuit(c, n_shots=shots) -counts = backend.get_result(handle).get_counts() -print(counts) \ No newline at end of file diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java index 85abdd4b..1011d7fb 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/CircuitProcessingConfiguration.java @@ -1,11 +1,16 @@ package edu.kit.provideq.toolbox.circuit.processing; +import edu.kit.provideq.toolbox.ResourceProvider; import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToExecutionSolver; import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToMitigationSolver; import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToOptimizationSolver; +import edu.kit.provideq.toolbox.exception.MissingExampleException; import edu.kit.provideq.toolbox.meta.Problem; import edu.kit.provideq.toolbox.meta.ProblemManager; import edu.kit.provideq.toolbox.meta.ProblemType; +import java.io.IOException; +import java.util.HashSet; +import java.util.Objects; import java.util.Set; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -22,28 +27,11 @@ public class CircuitProcessingConfiguration { @Bean ProblemManager getCircuitProcessingManager( + ResourceProvider provider, MoveToExecutionSolver moveToExecutionSolver, MoveToOptimizationSolver moveToOptimizationSolver, MoveToMitigationSolver moveToMitigationSolver ) { - Problem demo = new Problem<>(CIRCUIT_PROCESSING); - demo.setInput(""" - OPENQASM 2.0; - include "qelib1.inc"; - qreg q[2]; - creg c[2]; - h q[0]; - cx q[0],q[1]; - measure q[0] -> c[0]; - measure q[1] -> c[1];"""); - Problem secondDemo = new Problem<>(CIRCUIT_PROCESSING); - secondDemo.setInput(""" - OPENQASM 2.0; - include "qelib1.inc"; - qreg q[3]; - crz(0.5) q[0], q[1]; - t q[2]; - cswap q[2], q[0], q[1];"""); return new ProblemManager<>( CIRCUIT_PROCESSING, Set.of( @@ -51,7 +39,24 @@ ProblemManager getCircuitProcessingManager( moveToOptimizationSolver, moveToMitigationSolver ), - Set.of(demo, secondDemo) + loadExampleProblems(provider) ); } + + private Set> loadExampleProblems(ResourceProvider provider) { + try { + String[] problemNames = new String[] {"bell-state.qasm", "cswap.qasm"}; + var problemSet = new HashSet>(); + for (var problemName : problemNames) { + var problemStream = Objects.requireNonNull( + getClass().getResourceAsStream(problemName), "Problem " + problemName + " not found"); + var problem = new Problem<>(CIRCUIT_PROCESSING); + problem.setInput(provider.readStream(problemStream)); + problemSet.add(problem); + } + return problemSet; + } catch (IOException e) { + throw new MissingExampleException(CIRCUIT_PROCESSING, e); + } + } } diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java index 9cca644d..3b216c5e 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutionSolver.java @@ -87,10 +87,11 @@ public Mono> solve( .orElse(DEFAULT_SIMULATOR); var processResult = context - .getBean(PythonProcessRunner.class, scriptPath + selectedSimulator.getScriptPath(), venv) + .getBean(PythonProcessRunner.class, scriptPath + "executor.py", venv) .withArguments( ProcessRunner.INPUT_FILE_PATH, - String.valueOf(shotNumber) + String.valueOf(shotNumber), + selectedSimulator.getBackendKey() ) .writeInputFile(input) .readOutputString() @@ -112,25 +113,25 @@ public ProblemType getProblemType() { } enum QuantumSimulator { - AER("AerBackend", "default-executor/default_executor.py"), - // PROJECTQ("ProjectQBackend", "projectq-executor/projectq_executor.py"), - QULACS("QulacsBackend", "qulacs-executor/qulacs_executor.py"), - AER_NOISY("Aer Noisy Backend (max. 2 qubits)", "aer-noisy/aer_noisy_executor.py"); + AER("AerBackend", "aer"), + // PROJECTQ("ProjectQBackend", "projectq"), + QULACS("QulacsBackend", "qulacs"), + AER_NOISY("Aer Noisy Backend (max. 2 qubits)", "aer_noisy"); private final String value; - private final String scriptPath; + private final String backendKey; - QuantumSimulator(String value, String scriptPath) { + QuantumSimulator(String value, String backendKey) { this.value = value; - this.scriptPath = scriptPath; + this.backendKey = backendKey; } public String getValue() { return value; } - public String getScriptPath() { - return scriptPath; + public String getBackendKey() { + return backendKey; } public static QuantumSimulator fromValue(String value) { diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java index 1501f0b4..939122b7 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/executor/ExecutorConfiguration.java @@ -1,8 +1,12 @@ package edu.kit.provideq.toolbox.circuit.processing.solver.executor; +import edu.kit.provideq.toolbox.ResourceProvider; +import edu.kit.provideq.toolbox.exception.MissingExampleException; import edu.kit.provideq.toolbox.meta.Problem; import edu.kit.provideq.toolbox.meta.ProblemManager; import edu.kit.provideq.toolbox.meta.ProblemType; +import java.io.IOException; +import java.util.Objects; import java.util.Set; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -19,14 +23,25 @@ public class ExecutorConfiguration { @Bean ProblemManager getExecutorProblemManager( + ResourceProvider provider, ExecutionSolver executionSolver ) { return new ProblemManager<>( EXECUTOR_CONFIG, - Set.of( - executionSolver - ), - Set.of(new Problem<>(EXECUTOR_CONFIG)) + Set.of(executionSolver), + loadExampleProblems(provider) ); } + + private Set> loadExampleProblems(ResourceProvider provider) { + try { + var problemStream = Objects.requireNonNull( + getClass().getResourceAsStream("../../bell-state.qasm"), "Problem bell-state.qasm not found"); + var problem = new Problem<>(EXECUTOR_CONFIG); + problem.setInput(provider.readStream(problemStream)); + return Set.of(problem); + } catch (IOException e) { + throw new MissingExampleException(EXECUTOR_CONFIG, e); + } + } } diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java index 4fd0952a..f9ee685b 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/mitigation/ErrorMitigationConfiguration.java @@ -1,8 +1,12 @@ package edu.kit.provideq.toolbox.circuit.processing.solver.mitigation; +import edu.kit.provideq.toolbox.ResourceProvider; +import edu.kit.provideq.toolbox.exception.MissingExampleException; import edu.kit.provideq.toolbox.meta.Problem; import edu.kit.provideq.toolbox.meta.ProblemManager; import edu.kit.provideq.toolbox.meta.ProblemType; +import java.io.IOException; +import java.util.Objects; import java.util.Set; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -19,14 +23,25 @@ public class ErrorMitigationConfiguration { @Bean ProblemManager getMitigationProblemManager( + ResourceProvider provider, ErrorMitigationSolver errorMitigationSolver ) { return new ProblemManager<>( MITIGATION_CONFIG, - Set.of( - errorMitigationSolver - ), - Set.of(new Problem<>(MITIGATION_CONFIG)) + Set.of(errorMitigationSolver), + loadExampleProblems(provider) ); } + + private Set> loadExampleProblems(ResourceProvider provider) { + try { + var problemStream = Objects.requireNonNull( + getClass().getResourceAsStream("../../bell-state.qasm"), "Problem bell-state.qasm not found"); + var problem = new Problem<>(MITIGATION_CONFIG); + problem.setInput(provider.readStream(problemStream)); + return Set.of(problem); + } catch (IOException e) { + throw new MissingExampleException(MITIGATION_CONFIG, e); + } + } } diff --git a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java index 32f2fed7..6de1e680 100644 --- a/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java +++ b/src/main/java/edu/kit/provideq/toolbox/circuit/processing/solver/optimization/OptimizationConfiguration.java @@ -1,8 +1,12 @@ package edu.kit.provideq.toolbox.circuit.processing.solver.optimization; +import edu.kit.provideq.toolbox.ResourceProvider; +import edu.kit.provideq.toolbox.exception.MissingExampleException; import edu.kit.provideq.toolbox.meta.Problem; import edu.kit.provideq.toolbox.meta.ProblemManager; import edu.kit.provideq.toolbox.meta.ProblemType; +import java.io.IOException; +import java.util.Objects; import java.util.Set; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -19,14 +23,25 @@ public class OptimizationConfiguration { @Bean ProblemManager getOptimizationProblemManager( + ResourceProvider provider, OptimizationSolver optimizationSolver ) { return new ProblemManager<>( OPTIMIZATION_CONFIG, - Set.of( - optimizationSolver - ), - Set.of(new Problem<>(OPTIMIZATION_CONFIG)) + Set.of(optimizationSolver), + loadExampleProblems(provider) ); } + + private Set> loadExampleProblems(ResourceProvider provider) { + try { + var problemStream = Objects.requireNonNull( + getClass().getResourceAsStream("../../bell-state.qasm"), "Problem bell-state.qasm not found"); + var problem = new Problem<>(OPTIMIZATION_CONFIG); + problem.setInput(provider.readStream(problemStream)); + return Set.of(problem); + } catch (IOException e) { + throw new MissingExampleException(OPTIMIZATION_CONFIG, e); + } + } } diff --git a/src/main/resources/edu/kit/provideq/toolbox/circuit/processing/bell-state.qasm b/src/main/resources/edu/kit/provideq/toolbox/circuit/processing/bell-state.qasm new file mode 100644 index 00000000..c3bf3c2b --- /dev/null +++ b/src/main/resources/edu/kit/provideq/toolbox/circuit/processing/bell-state.qasm @@ -0,0 +1,8 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[2]; +creg c[2]; +h q[0]; +cx q[0],q[1]; +measure q[0] -> c[0]; +measure q[1] -> c[1]; diff --git a/src/main/resources/edu/kit/provideq/toolbox/circuit/processing/cswap.qasm b/src/main/resources/edu/kit/provideq/toolbox/circuit/processing/cswap.qasm new file mode 100644 index 00000000..b2bce4dc --- /dev/null +++ b/src/main/resources/edu/kit/provideq/toolbox/circuit/processing/cswap.qasm @@ -0,0 +1,6 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[3]; +crz(0.5) q[0], q[1]; +t q[2]; +cswap q[2], q[0], q[1]; diff --git a/src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java b/src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java index 0ea70b1c..e31e8382 100644 --- a/src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java +++ b/src/test/java/edu/kit/provideq/toolbox/api/CircuitProcessingSolversTest.java @@ -14,7 +14,12 @@ import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionSolver; import edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationSolver; import edu.kit.provideq.toolbox.circuit.processing.solver.optimization.OptimizationSolver; +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManager; +import edu.kit.provideq.toolbox.meta.ProblemManagerProvider; import java.time.Duration; +import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -25,19 +30,12 @@ @SpringBootTest @AutoConfigureMockMvc class CircuitProcessingSolversTest { - private static final String CIRCUIT = """ - OPENQASM 2.0; - include "qelib1.inc"; - qreg q[2]; - creg c[2]; - h q[0]; - cx q[0],q[1]; - measure q[0] -> c[0]; - measure q[1] -> c[1];"""; - @Autowired private WebTestClient client; + @Autowired + private ProblemManagerProvider problemManagerProvider; + @Autowired private MoveToMitigationSolver moveToMitigationSolver; @@ -56,26 +54,38 @@ class CircuitProcessingSolversTest { @Autowired private OptimizationSolver optimizationSolver; + private ProblemManager problemManager; + private List problems; + @BeforeEach void beforeEach() { this.client = this.client.mutate() .responseTimeout(Duration.ofSeconds(60)) .build(); + problemManager = problemManagerProvider.findProblemManagerForType(CIRCUIT_PROCESSING).get(); + problems = problemManager.getExampleInstances() + .stream() + .map(Problem::getInput) + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); } @Test void testMoveToMitigationSolver() { - var problemDto = ApiTestHelper.createProblem(client, moveToMitigationSolver, CIRCUIT, CIRCUIT_PROCESSING); + var circuit = problems.get(0); + var problemDto = ApiTestHelper.createProblem(client, moveToMitigationSolver, circuit, CIRCUIT_PROCESSING); var subProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); ApiTestHelper.setProblemSolver(client, errorMitigationSolver, subProblemId, MITIGATION_CONFIG.getId()); var solvedDto = ApiTestHelper.trySolveFor(60, client, problemDto.getId(), CIRCUIT_PROCESSING); ApiTestHelper.testSolution(solvedDto); - assertEquals(CIRCUIT, solvedDto.getSolution().getSolutionData()); + assertEquals(circuit, solvedDto.getSolution().getSolutionData()); } @Test void testMoveToExecutionSolver() { - var problemDto = ApiTestHelper.createProblem(client, moveToExecutionSolver, CIRCUIT, CIRCUIT_PROCESSING); + var circuit = problems.get(0); + var problemDto = ApiTestHelper.createProblem(client, moveToExecutionSolver, circuit, CIRCUIT_PROCESSING); var subProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); ApiTestHelper.setProblemSolver(client, executionSolver, subProblemId, EXECUTOR_CONFIG.getId()); var solvedDto = ApiTestHelper.trySolveFor(60, client, problemDto.getId(), CIRCUIT_PROCESSING); @@ -85,7 +95,8 @@ void testMoveToExecutionSolver() { @Test void testMoveToOptimizationSolver() { - var problemDto = ApiTestHelper.createProblem(client, moveToOptimizationSolver, CIRCUIT, CIRCUIT_PROCESSING); + var circuit = problems.get(0); + var problemDto = ApiTestHelper.createProblem(client, moveToOptimizationSolver, circuit, CIRCUIT_PROCESSING); var optSubProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); var optDto = ApiTestHelper.setProblemSolver( client, optimizationSolver, optSubProblemId, OPTIMIZATION_CONFIG.getId()); diff --git a/src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java b/src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java index 7c5ff690..1815a325 100644 --- a/src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java +++ b/src/test/java/edu/kit/provideq/toolbox/api/ErrorMitigationSolverTest.java @@ -4,6 +4,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationSolver; +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManager; +import edu.kit.provideq.toolbox.meta.ProblemManagerProvider; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -13,26 +19,34 @@ @SpringBootTest @AutoConfigureMockMvc class ErrorMitigationSolverTest { - private static final String CIRCUIT = """ - OPENQASM 2.0; - include "qelib1.inc"; - qreg q[2]; - creg c[2]; - h q[0]; - cx q[0],q[1]; - measure q[0] -> c[0]; - measure q[1] -> c[1];"""; - @Autowired private WebTestClient client; + @Autowired + private ProblemManagerProvider problemManagerProvider; + @Autowired private ErrorMitigationSolver errorMitigationSolver; + private ProblemManager problemManager; + private List problems; + + @BeforeEach + void beforeEach() { + problemManager = problemManagerProvider.findProblemManagerForType(MITIGATION_CONFIG).get(); + problems = problemManager.getExampleInstances() + .stream() + .map(Problem::getInput) + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); + } + @Test void testErrorMitigationSolver() { - var problem = ApiTestHelper.createProblem(client, errorMitigationSolver, CIRCUIT, MITIGATION_CONFIG); + var circuit = problems.get(0); + var problem = ApiTestHelper.createProblem(client, errorMitigationSolver, circuit, MITIGATION_CONFIG); ApiTestHelper.testSolution(problem); - assertEquals(CIRCUIT, problem.getSolution().getSolutionData()); + assertEquals(circuit, problem.getSolution().getSolutionData()); } } diff --git a/src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java b/src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java index acb704c1..11549377 100644 --- a/src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java +++ b/src/test/java/edu/kit/provideq/toolbox/api/ExecutionSolverTest.java @@ -5,7 +5,11 @@ import edu.kit.provideq.toolbox.Solution; import edu.kit.provideq.toolbox.circuit.processing.solver.executor.ExecutionSolver; +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManagerProvider; import java.time.Duration; +import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -16,32 +20,35 @@ @SpringBootTest @AutoConfigureMockMvc class ExecutionSolverTest { - private static final String CIRCUIT = """ - OPENQASM 2.0; - include "qelib1.inc"; - qreg q[2]; - creg c[2]; - h q[0]; - cx q[0],q[1]; - measure q[0] -> c[0]; - measure q[1] -> c[1];"""; - @Autowired private WebTestClient client; + @Autowired + private ProblemManagerProvider problemManagerProvider; + @Autowired private ExecutionSolver executionSolver; + private List problems; + @BeforeEach void beforeEach() { this.client = this.client.mutate() .responseTimeout(Duration.ofSeconds(60)) .build(); + problems = problemManagerProvider.findProblemManagerForType(EXECUTOR_CONFIG).get() + .getExampleInstances() + .stream() + .map(Problem::getInput) + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); } @Test void testExecutionSolver() { - var problem = ApiTestHelper.createProblem(client, executionSolver, CIRCUIT, EXECUTOR_CONFIG); + var circuit = problems.get(0); + var problem = ApiTestHelper.createProblem(client, executionSolver, circuit, EXECUTOR_CONFIG); ApiTestHelper.testSolution(problem); Solution solution = problem.getSolution(); assertTrue(solution.getSolutionData().toString().contains("OPENQASM")); diff --git a/src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java b/src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java index 5ec157b8..4945a5c7 100644 --- a/src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java +++ b/src/test/java/edu/kit/provideq/toolbox/api/OptimizationSolverTest.java @@ -8,7 +8,12 @@ import edu.kit.provideq.toolbox.circuit.processing.solver.MoveToMitigationSolver; import edu.kit.provideq.toolbox.circuit.processing.solver.mitigation.ErrorMitigationSolver; import edu.kit.provideq.toolbox.circuit.processing.solver.optimization.OptimizationSolver; +import edu.kit.provideq.toolbox.meta.Problem; +import edu.kit.provideq.toolbox.meta.ProblemManager; +import edu.kit.provideq.toolbox.meta.ProblemManagerProvider; import java.time.Duration; +import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -19,19 +24,12 @@ @SpringBootTest @AutoConfigureMockMvc class OptimizationSolverTest { - private static final String CIRCUIT = """ - OPENQASM 2.0; - include "qelib1.inc"; - qreg q[2]; - creg c[2]; - h q[0]; - cx q[0],q[1]; - measure q[0] -> c[0]; - measure q[1] -> c[1];"""; - @Autowired private WebTestClient client; + @Autowired + private ProblemManagerProvider problemManagerProvider; + @Autowired private OptimizationSolver optimizationSolver; @@ -41,16 +39,27 @@ class OptimizationSolverTest { @Autowired private ErrorMitigationSolver errorMitigationSolver; + private ProblemManager problemManager; + private List problems; + @BeforeEach void beforeEach() { this.client = this.client.mutate() .responseTimeout(Duration.ofSeconds(60)) .build(); + problemManager = problemManagerProvider.findProblemManagerForType(OPTIMIZATION_CONFIG).get(); + problems = problemManager.getExampleInstances() + .stream() + .map(Problem::getInput) + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); } @Test void testOptimizationSolver() { - var problemDto = ApiTestHelper.createProblem(client, optimizationSolver, CIRCUIT, OPTIMIZATION_CONFIG); + var circuit = problems.get(0); + var problemDto = ApiTestHelper.createProblem(client, optimizationSolver, circuit, OPTIMIZATION_CONFIG); var circuitSubProblemId = problemDto.getSubProblems().get(0).getSubProblemIds().get(0); var mitigationEntryDto = ApiTestHelper.setProblemSolver( client, moveToMitigationSolver, circuitSubProblemId, CIRCUIT_PROCESSING.getId());