Source code for qailab.qlauncher.passes.backward

 1""" Backward pass algorithm implementation in quantum_launcher. """
 2from collections.abc import Callable
 3from typing import Any, Literal
 4from quantum_launcher.base.base import Backend, Problem, Result
 5from quantum_launcher.routines.qiskit_routines import QiskitBackend
 6from qailab.qlauncher.passes.forward import ForwardPass
 7from qailab.gradient.gradient_calculation import calculate_jacobian
 8
 9
[docs] 10class BackwardPass(ForwardPass): 11 """ Backward Pass, calculates two jacobian matrices: w.r.t. to input and w.r.t. weights""" 12 13 def __init__(self, gradient_method: Literal['param_shift', 'spsa', 'lin_comb'] = 'param_shift', shots: int = 1024) -> None: 14 self.gradient_method = gradient_method 15 self.shots = shots 16 super().__init__() 17
[docs] 18 def run(self, problem: Problem, backend: Backend, formatter: Callable[..., Any] | None = None) -> Result: 19 if formatter is None: 20 raise ValueError('Formatter for Backward pass not found!') 21 if not isinstance(backend, QiskitBackend): 22 raise ValueError('Wrong sampler given into') 23 24 format_result = formatter(problem)[0] 25 if not isinstance(format_result, tuple): 26 raise ValueError("Don't use autobind") 27 28 circuit, params = format_result 29 30 input_params = {x: params[x] for x in params if x.name.startswith('input')} 31 weight_params = {x: params[x] for x in params if x.name.startswith('weight')} 32 33 # All other params must be assigned. 34 input_jacobian = calculate_jacobian( 35 circuit.assign_parameters(weight_params), 36 input_params, 37 backend, 38 self.gradient_method, 39 self.shots 40 ) 41 weight_jacobian = calculate_jacobian( 42 circuit.assign_parameters(input_params), 43 weight_params, 44 backend, 45 self.gradient_method, 46 self.shots 47 ) 48 49 return Result('', 0, '', 0, {}, {}, self.shots, 0, 0, {'input': input_jacobian, 'weight': weight_jacobian})