From f1cff5339c7fbdb1696233e4d33ec94b6240c0ac Mon Sep 17 00:00:00 2001 From: donghufeng Date: Mon, 2 Dec 2024 16:59:50 +0800 Subject: [PATCH] fix precommit --- examples/quantum_rl/misc/utils.py | 5 +- examples/quantum_rl/models/quantum_models.py | 33 ++++--- .../quantum_rl/models/quantum_operations.py | 8 +- examples/quantum_rl/search/nsganet.py | 57 ++++++------ .../search/quantum_evolution_search.py | 4 +- .../quantum_rl/search/quantum_train_search.py | 2 +- .../quantum_rl/validation/quantum_train.py | 24 ------ quafu/algorithms/__init__.py | 11 +++ quafu/algorithms/estimator.py | 5 -- quafu/algorithms/gradients/__init__.py | 10 +++ quafu/algorithms/gradients/gradiant.py | 17 +++- quafu/algorithms/gradients/vjp.py | 7 +- quafu/algorithms/templates/amplitude.py | 2 +- quafu/algorithms/templates/angle.py | 1 - quafu/algorithms/templates/basic_entangle.py | 8 +- quafu/backends/backends.py | 1 - quafu/circuits/quantum_circuit.py | 86 ++++++++++++++----- quafu/circuits/quantum_register.py | 6 +- quafu/dagcircuits/circuit_dag.py | 48 ++--------- quafu/dagcircuits/dag_circuit.py | 25 ++---- quafu/dagcircuits/instruction_node.py | 29 +++---- quafu/elements/__init__.py | 25 ++++++ quafu/elements/element_gates/element_gates.py | 6 -- quafu/elements/instruction.py | 3 +- quafu/elements/matrices/__init__.py | 67 ++++++++++++++- quafu/elements/noise.py | 6 +- quafu/elements/oracle.py | 7 +- setup.cfg | 6 +- 28 files changed, 282 insertions(+), 227 deletions(-) diff --git a/examples/quantum_rl/misc/utils.py b/examples/quantum_rl/misc/utils.py index d9d4f722..2b5f05d1 100644 --- a/examples/quantum_rl/misc/utils.py +++ b/examples/quantum_rl/misc/utils.py @@ -126,7 +126,7 @@ def get_obs_policy(obsw, beta): """ Output the final policy. """ - process = tf.keras.Sequential( + return tf.keras.Sequential( [ Alternating_(obsw), tf.keras.layers.Lambda(lambda x: x * beta), @@ -134,7 +134,6 @@ def get_obs_policy(obsw, beta): ], name="obs_policy", ) - return process def get_height(position): @@ -172,7 +171,6 @@ def gather_episodes( while not all(done): unfinished_ids = [i for i in range(n_episodes) if not done[i]] normalized_states = [s / state_bounds for i, s in enumerate(states) if not done[i]] - # height = [get_height(s[0]) for i, s in enumerate(states) if not done[i]] for i, state in zip(unfinished_ids, normalized_states): trajectories[i]["states"].append(state) @@ -187,7 +185,6 @@ def gather_episodes( circuit, _, _ = generate_circuit(qubits, genotype, newtheta, newlamda, states.numpy()[0]) taskid, expectation = get_quafu_exp(circuit, n_qubits, backend_quafu, shots) tasklist.append(taskid) - # print('gather_episodes_exp:', expectation) obsw = model.get_layer("observables-policy").get_weights()[0] obspolicy = get_obs_policy(obsw, beta) diff --git a/examples/quantum_rl/models/quantum_models.py b/examples/quantum_rl/models/quantum_models.py index bf3a07c3..1ca10e1a 100644 --- a/examples/quantum_rl/models/quantum_models.py +++ b/examples/quantum_rl/models/quantum_models.py @@ -1,9 +1,8 @@ import cirq -import models.quantum_genotypes as genotypes import numpy as np import tensorflow as tf import tensorflow_quantum as tfq -from models.quantum_operations import * +from models.quantum_operations import OPS def generate_circuit(qubits, genotype, newtheta=None, newlamda=None, state=None): @@ -13,16 +12,16 @@ def generate_circuit(qubits, genotype, newtheta=None, newlamda=None, state=None) op_entangle, pos_entangle = zip(*genotype.entangle) op_measure, pos_measure = zip(*genotype.measure) - dict = {} + dict_data = {} for name, pos in zip(op_vpqc, pos_vpqc): - dict[pos] = name + dict_data[pos] = name for name, pos in zip(op_dpqc, pos_dpqc): - dict[pos] = name + dict_data[pos] = name for name, pos in zip(op_entangle, pos_entangle): - dict[pos] = name + dict_data[pos] = name for name, pos in zip(op_measure, pos_measure): - dict[pos] = name - length = len(dict) + dict_data[pos] = name + length = len(dict_data) circuit = cirq.Circuit() params = [] @@ -30,20 +29,20 @@ def generate_circuit(qubits, genotype, newtheta=None, newlamda=None, state=None) p_count = 0 i_count = 0 for i in range(length): - if dict[i] == "variationalPQC": - cir, pa = OPS[dict[i]](qubits, p_count, newtheta) + if dict_data[i] == "variationalPQC": + cir, pa = OPS[dict_data[i]](qubits, p_count, newtheta) circuit += cir params += pa p_count += 1 - elif dict[i] == "dataencodingPQC": - cir, inp = OPS[dict[i]](qubits, i, i_count, newlamda, state) + elif dict_data[i] == "dataencodingPQC": + cir, inp = OPS[dict_data[i]](qubits, i, i_count, newlamda, state) circuit += cir inputs += inp i_count += 1 - elif dict[i] == "entanglement": - cir = OPS[dict[i]](qubits) + elif dict_data[i] == "entanglement": + cir = OPS[dict_data[i]](qubits) circuit += cir - elif dict[i] == "measurement": + elif dict_data[i] == "measurement": pass else: raise NameError("Unknown quantum genotype operation") @@ -163,6 +162,4 @@ def generate_model_policy(qubits, genotype, n_actions, beta, observables, env): name="observables-policy", ) policy = process(nsganet_pqc) - model = tf.keras.Model(inputs=[input_tensor], outputs=policy) - - return model + return tf.keras.Model(inputs=[input_tensor], outputs=policy) diff --git a/examples/quantum_rl/models/quantum_operations.py b/examples/quantum_rl/models/quantum_operations.py index dabd5ec2..c1ec9d67 100644 --- a/examples/quantum_rl/models/quantum_operations.py +++ b/examples/quantum_rl/models/quantum_operations.py @@ -29,9 +29,7 @@ def entangling_layer(qubits): Return a layer of CZ entangling gates on `qubits` (arranged in a circular topology). Note: for lower depth of compiled circuits, you can only choose adjacent CZ """ - cz_ops = [cirq.CZ(q0, q1) for q0, q1 in zip(qubits, qubits[1:])] - # cz_ops += ([cirq.CZ(qubits[0], qubits[-1])] if len(qubits) != 2 else []) - return cz_ops + return [cirq.CZ(q0, q1) for q0, q1 in zip(qubits, qubits[1:])] def generate_vpqc(qubits, position, params=None): @@ -40,7 +38,7 @@ def generate_vpqc(qubits, position, params=None): n_qubits = len(qubits) # Sympy symbols or load parameters for variational angles - if params == None: + if params is None: params = sympy.symbols(f"theta({3*position*n_qubits}:{3*(position+1)*n_qubits})") else: params = params[3 * position * n_qubits : 3 * (position + 1) * n_qubits] @@ -61,7 +59,7 @@ def generate_dpqc(qubits, position, count, params=None, state=None): n_qubits = len(qubits) # Sympy symbols or load parameters for encoding angles - if params == None: + if params is None: inputs = sympy.symbols(f"x{position}" + f"_(0:{n_qubits})") else: inputs = params[count * n_qubits : (count + 1) * n_qubits] diff --git a/examples/quantum_rl/search/nsganet.py b/examples/quantum_rl/search/nsganet.py index 6ee5432d..dda275e3 100644 --- a/examples/quantum_rl/search/nsganet.py +++ b/examples/quantum_rl/search/nsganet.py @@ -133,44 +133,43 @@ def calc_crowding_distance(F): if n_points <= 2: return np.full(n_points, infinity) - else: - # sort each column and get index - I = np.argsort(F, axis=0, kind="mergesort") + # sort each column and get index + I = np.argsort(F, axis=0, kind="mergesort") - # now really sort the whole array - F = F[I, np.arange(n_obj)] + # now really sort the whole array + F = F[I, np.arange(n_obj)] - # get the distance to the last element in sorted list and replace zeros with actual values - dist = np.concatenate([F, np.full((1, n_obj), np.inf)]) - np.concatenate([np.full((1, n_obj), -np.inf), F]) + # get the distance to the last element in sorted list and replace zeros with actual values + dist = np.concatenate([F, np.full((1, n_obj), np.inf)]) - np.concatenate([np.full((1, n_obj), -np.inf), F]) - index_dist_is_zero = np.where(dist == 0) + index_dist_is_zero = np.where(dist == 0) - dist_to_last = np.copy(dist) - for i, j in zip(*index_dist_is_zero): - dist_to_last[i, j] = dist_to_last[i - 1, j] + dist_to_last = np.copy(dist) + for i, j in zip(*index_dist_is_zero): + dist_to_last[i, j] = dist_to_last[i - 1, j] - dist_to_next = np.copy(dist) - for i, j in reversed(list(zip(*index_dist_is_zero))): - dist_to_next[i, j] = dist_to_next[i + 1, j] + dist_to_next = np.copy(dist) + for i, j in reversed(list(zip(*index_dist_is_zero))): + dist_to_next[i, j] = dist_to_next[i + 1, j] - # normalize all the distances - norm = np.max(F, axis=0) - np.min(F, axis=0) - norm[norm == 0] = np.nan - dist_to_last, dist_to_next = dist_to_last[:-1] / norm, dist_to_next[1:] / norm + # normalize all the distances + norm = np.max(F, axis=0) - np.min(F, axis=0) + norm[norm == 0] = np.nan + dist_to_last, dist_to_next = dist_to_last[:-1] / norm, dist_to_next[1:] / norm - # if we divided by zero because all values in one columns are equal replace by none - dist_to_last[np.isnan(dist_to_last)] = 0.0 - dist_to_next[np.isnan(dist_to_next)] = 0.0 + # if we divided by zero because all values in one columns are equal replace by none + dist_to_last[np.isnan(dist_to_last)] = 0.0 + dist_to_next[np.isnan(dist_to_next)] = 0.0 - # sum up the distance to next and last and norm by objectives - also reorder from sorted list - J = np.argsort(I, axis=0) - crowding = ( - np.sum( - dist_to_last[J, np.arange(n_obj)] + dist_to_next[J, np.arange(n_obj)], - axis=1, - ) - / n_obj + # sum up the distance to next and last and norm by objectives - also reorder from sorted list + J = np.argsort(I, axis=0) + crowding = ( + np.sum( + dist_to_last[J, np.arange(n_obj)] + dist_to_next[J, np.arange(n_obj)], + axis=1, ) + / n_obj + ) # replace infinity with a large number crowding[np.isinf(crowding)] = infinity diff --git a/examples/quantum_rl/search/quantum_evolution_search.py b/examples/quantum_rl/search/quantum_evolution_search.py index f1c723b7..b569f0d9 100644 --- a/examples/quantum_rl/search/quantum_evolution_search.py +++ b/examples/quantum_rl/search/quantum_evolution_search.py @@ -126,7 +126,6 @@ def _evaluate(self, x, out, *args, **kwargs): def do_every_generations(algorithm): """Store statistic information of every generation.""" gen = algorithm.n_gen - pop_var = algorithm.pop.get("X") pop_obj = algorithm.pop.get("F") # report generation info to files @@ -177,14 +176,13 @@ def main(qubits, n_actions, observables): # configure the nsga-net method method = engine.nsganet(pop_size=args.pop_size, n_offsprings=args.n_offspring, eliminate_duplicates=True) - res = minimize( + return minimize( problem, method, callback=do_every_generations, termination=("n_gen", args.n_gens), ) - return if __name__ == "__main__": diff --git a/examples/quantum_rl/search/quantum_train_search.py b/examples/quantum_rl/search/quantum_train_search.py index 40ed9a4d..6ab02839 100644 --- a/examples/quantum_rl/search/quantum_train_search.py +++ b/examples/quantum_rl/search/quantum_train_search.py @@ -101,6 +101,6 @@ def reinforce_update(states, actions, returns, model): if avg_rewards >= 500.0 and env_name == "CartPole-v1": break - elif avg_rewards >= -110 and env_name == "MountainCar-v0": + if avg_rewards >= -110 and env_name == "MountainCar-v0": break return episode_reward_history diff --git a/examples/quantum_rl/validation/quantum_train.py b/examples/quantum_rl/validation/quantum_train.py index 13adf8b7..b266f36a 100644 --- a/examples/quantum_rl/validation/quantum_train.py +++ b/examples/quantum_rl/validation/quantum_train.py @@ -20,7 +20,6 @@ parser.add_argument("--save", type=str, default="qEXP-quafu18_6", help="experiment name") parser.add_argument("--batch_size", type=int, default=1, help="batch size") parser.add_argument("--n_episodes", type=int, default=100, help="the number of episodes") -# parser.add_argument('--infer_episodes', type=int, default=5, help='the number of infer episodes') parser.add_argument("--gamma", type=float, default=1.0, help="discount parameter") parser.add_argument("--env_name", type=str, default="CartPole-v1", help="environment name") parser.add_argument( @@ -171,29 +170,6 @@ def reinforce_update(states, actions, returns, logits2, model): break return episode_reward_history - -# def infer(model): -# episode_reward_history = [] -# for batch in range(args.infer_episodes // args.batch_size): -# # Gather episodes -# episodes = gather_episodes(args.state_bounds, args.n_actions, model, args.batch_size, args.env_name, qubits, genotype) - -# # Group states, actions and returns in numpy arrays -# rewards = [ep['rewards'] for ep in episodes] - -# # Store collected rewards -# for ep_rwds in rewards: -# episode_reward_history.append(np.sum(ep_rwds)) - -# avg_rewards = np.mean(episode_reward_history[-10:]) - -# logging.info('valid finished episode: %f', (batch + 1) * args.batch_size) -# logging.info('valid average rewards: %f', avg_rewards) - -# if avg_rewards >= 500.0: -# break -# return episode_reward_history - if __name__ == "__main__": qubits = cirq.GridQubit.rect(1, args.n_qubits) genotype = eval("genotypes.%s" % args.arch) diff --git a/quafu/algorithms/__init__.py b/quafu/algorithms/__init__.py index ab95ae72..16295baf 100644 --- a/quafu/algorithms/__init__.py +++ b/quafu/algorithms/__init__.py @@ -19,3 +19,14 @@ from .templates.amplitude import AmplitudeEmbedding from .templates.angle import AngleEmbedding from .templates.basic_entangle import BasicEntangleLayers + +__all__ = [ + "AmplitudeEmbedding", + "AngleEmbedding", + "BasicEntangleLayers", + "AlterLayeredAnsatz", + "QAOAAnsatz", + "QuantumNeuralNetwork", + "Estimator", + "Hamiltonian", +] diff --git a/quafu/algorithms/estimator.py b/quafu/algorithms/estimator.py index 74400437..9ec9df82 100644 --- a/quafu/algorithms/estimator.py +++ b/quafu/algorithms/estimator.py @@ -165,11 +165,6 @@ def _measure_obs(self, qc: QuantumCircuit, measure_base: Optional[List] = None) def _run_simulation(self, observables: Hamiltonian): """Run using quafu simulator""" - # sim_state = simulate(self._circ).get_statevector() - # expectation = np.matmul( - # np.matmul(sim_state.conj().T, observables.get_matrix()), sim_state - # ).real - # return expectation return execute_circuit(self._circ, observables) def clear_cache(self): diff --git a/quafu/algorithms/gradients/__init__.py b/quafu/algorithms/gradients/__init__.py index 1c3b61bf..445d151f 100644 --- a/quafu/algorithms/gradients/__init__.py +++ b/quafu/algorithms/gradients/__init__.py @@ -15,3 +15,13 @@ from .gradiant import grad_adjoint, grad_finit_diff, grad_para_shift from .param_shift import ParamShift from .vjp import compute_vjp, jacobian, run_circ + +__all__ = [ + "grad_adjoint", + "grad_finit_diff", + "grad_para_shift", + "ParamShift", + "compute_vjp", + "jacobian", + "run_circ", +] diff --git a/quafu/algorithms/gradients/gradiant.py b/quafu/algorithms/gradients/gradiant.py index 16aba83e..6ba573a9 100644 --- a/quafu/algorithms/gradients/gradiant.py +++ b/quafu/algorithms/gradients/gradiant.py @@ -43,10 +43,13 @@ def grad_para_shift(qc: QuantumCircuit, hamiltonian, backend=SVSimulator()): for i, op in enumerate(qc.gates): if len(op.paras) > 0: - if isinstance(op.paras[0], Parameter) or isinstance(op.paras[0], ParameterExpression): + if isinstance(op.paras[0], Parameter) or isinstance( + op.paras[0], ParameterExpression + ): if op.name not in ["RX", "RY", "RZ"]: raise CircuitError( - "It seems the circuit can not apply parameter-shift rule to calculate gradient. You may need compile the circuit first" + "It seems the circuit can not apply parameter-shift rule to calculate gradient." + " You may need compile the circuit first" ) op.paras[0] = op.paras[0] + np.pi / 2 res1 = sum(backend.run(qc, hamiltonian=hamiltonian)["pauli_expects"]) @@ -136,14 +139,20 @@ def grad_adjoint(qc, hamiltonian, psi_in=np.array([], dtype=complex)): end = len(qc.gates) gate_grads = [[] for _ in range(end)] for i, op in enumerate(qc.gates): - if len(op.paras) > 0 and (isinstance(op.paras[0], Parameter) or isinstance(op.paras[0], ParameterExpression)): + if len(op.paras) > 0 and ( + isinstance(op.paras[0], Parameter) + or isinstance(op.paras[0], ParameterExpression) + ): begin = i break for i in range(begin, end)[::-1]: op = qc.gates[i] phi = backend._apply_op(op.dagger(), phi) - if len(op.paras) > 0 and (isinstance(op.paras[0], Parameter) or isinstance(op.paras[0], ParameterExpression)): + if len(op.paras) > 0 and ( + isinstance(op.paras[0], Parameter) + or isinstance(op.paras[0], ParameterExpression) + ): mu = np.copy(phi) mu = backend._apply_op(grad_gate(op), mu) gate_grads[i].append(np.real(2.0 * np.inner(lam.conj(), mu))) diff --git a/quafu/algorithms/gradients/vjp.py b/quafu/algorithms/gradients/vjp.py index c9505d2b..e8b2d0ee 100644 --- a/quafu/algorithms/gradients/vjp.py +++ b/quafu/algorithms/gradients/vjp.py @@ -102,7 +102,8 @@ def jacobian( def compute_vjp(jac: np.ndarray, dy: np.ndarray): - r"""compute vector-jacobian product + r""" + Compute vector-jacobian product. Args: jac (np.ndarray): jac with shape (batch_size, num_outputs, num_params) @@ -133,6 +134,4 @@ def compute_vjp(jac: np.ndarray, dy: np.ndarray): # Compute vector-Jacobian product using Einstein summation convention # the scripts simply mean 'jac-dims,dy-dims->vjp-dims'; so num_outputs is summed over - vjp = np.einsum("ijk,ij->ik", jac, dy) - - return vjp + return np.einsum("ijk,ij->ik", jac, dy) diff --git a/quafu/algorithms/templates/amplitude.py b/quafu/algorithms/templates/amplitude.py index 75180ace..a02cbd2a 100644 --- a/quafu/algorithms/templates/amplitude.py +++ b/quafu/algorithms/templates/amplitude.py @@ -136,7 +136,7 @@ def _build(self): return gate_list -## MottonenStatePreparation related functions. +# MottonenStatePreparation related functions. def gray_code(rank): """Generates the Gray code of given rank. diff --git a/quafu/algorithms/templates/angle.py b/quafu/algorithms/templates/angle.py index 5a75307a..3b59e76b 100644 --- a/quafu/algorithms/templates/angle.py +++ b/quafu/algorithms/templates/angle.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. """Angel Embedding in Quantum Data embedding.""" -import numpy as np import quafu.elements.element_gates as qeg from quafu.elements import Parameter, QuantumGate diff --git a/quafu/algorithms/templates/basic_entangle.py b/quafu/algorithms/templates/basic_entangle.py index 8c87afdf..c6876773 100644 --- a/quafu/algorithms/templates/basic_entangle.py +++ b/quafu/algorithms/templates/basic_entangle.py @@ -31,13 +31,13 @@ def __init__(self, weights=None, num_qubits=None, repeat=None, rotation="X"): repeat(int): the number of layers, only work while the weights is not provided """ if num_qubits is None: - raise ValueError(f"num_qubits must be provided") + raise ValueError("num_qubits must be provided") if weights is not None: weights = np.asarray(weights) shape = np.shape(weights) - ##TODO(): If weights are batched, i.e. dim>3, additional processing is required + #TODO(): If weights are batched, i.e. dim>3, additional processing is required if weights.ndim > 2: - raise ValueError(f"Weights tensor must be 2-dimensional ") + raise ValueError("Weights tensor must be 2-dimensional ") if not (len(shape) == 3 or len(shape) == 2): # 3 is when batching, 2 is no batching raise ValueError( @@ -50,7 +50,7 @@ def __init__(self, weights=None, num_qubits=None, repeat=None, rotation="X"): else: self.weights = None if repeat is None: - raise ValueError(f"repeat must be provided if weights is None") + raise ValueError("repeat must be provided if weights is None") # convert weights to numpy array if weights is list otherwise keep unchanged self.weights = weights self.num_qubits = num_qubits diff --git a/quafu/backends/backends.py b/quafu/backends/backends.py index 516d3406..7bae7054 100644 --- a/quafu/backends/backends.py +++ b/quafu/backends/backends.py @@ -29,7 +29,6 @@ def __init__(self, backend_info: dict): self.system_id = backend_info["system_id"] self.status = backend_info["status"] self.qv = backend_info["QV"] - # self.task_in_queue = backend_info["task_in_queue"] def get_chip_info(self, user: User = None): user = User() if user is None else user diff --git a/quafu/circuits/quantum_circuit.py b/quafu/circuits/quantum_circuit.py index bc891939..2442ac9c 100644 --- a/quafu/circuits/quantum_circuit.py +++ b/quafu/circuits/quantum_circuit.py @@ -123,7 +123,9 @@ def gates(self, gates: list): self._gates = gates def __lshift__(self, operation: Instruction): - max_pos = max(operation.pos) if isinstance(operation.pos, Iterable) else operation.pos + max_pos = ( + max(operation.pos) if isinstance(operation.pos, Iterable) else operation.pos + ) if max_pos >= self.num: raise CircuitError("Operation act on qubit that not allocated") self.add_ins(operation) @@ -197,8 +199,12 @@ def add_noise(self, channel: str, channel_args, qubits=[], gates=[]): if add_q and add_g: for q in op.pos: if q in qubits: - newinstructions.append(Instruction.ins_classes[channel](q, *channel_args)) - newgates.append(Instruction.ins_classes[channel](q, *channel_args)) + newinstructions.append( + Instruction.ins_classes[channel](q, *channel_args) + ) + newgates.append( + Instruction.ins_classes[channel](q, *channel_args) + ) self.instructions = newinstructions self._gates = newgates return self @@ -215,7 +221,9 @@ def noised(self): def get_parameter_grads(self): if self._has_wrap: - print("warning: The circuit has wrapped gates, it will unwarp automaticllay") + print( + "warning: The circuit has wrapped gates, it will unwarp automaticllay" + ) self.unwrap() self._parameter_grads = {} for i, op in enumerate(self.gates): @@ -230,9 +238,13 @@ def get_parameter_grads(self): para_grads = para.grad() for var in para._variables: if var not in self._parameter_grads.keys(): - self._parameter_grads[var] = [[(i, j), para_grads[para._variables[var]]]] + self._parameter_grads[var] = [ + [(i, j), para_grads[para._variables[var]]] + ] else: - self._parameter_grads[var].append([(i, j), para_grads[para._variables[var]]]) + self._parameter_grads[var].append( + [(i, j), para_grads[para._variables[var]]] + ) self._variables = list(self._parameter_grads.keys()) return self._parameter_grads @@ -264,7 +276,9 @@ def _update_params(self, values, order=[]): need pass the order to match untranspiled circuit's variable. """ if len(values) != len(self.variables): - raise CircuitError("The size of input values must be the same to the parameters") + raise CircuitError( + "The size of input values must be the same to the parameters" + ) for i in range(len(values)): val = values[order[i]] if order else values[i] self._variables[i].value = val @@ -279,7 +293,9 @@ def update_params(self, paras_list: List[Any]): CircuitError """ if len(paras_list) != len(self.parameterized_gates): - raise CircuitError("`params_list` must have the same size with parameterized gates") + raise CircuitError( + "`params_list` must have the same size with parameterized gates" + ) # TODO(): Support updating part of params of a single gate for gate, paras in zip(self.parameterized_gates, paras_list): @@ -290,7 +306,9 @@ def angles2parameters(self): for g in self.gates: if all(isinstance(x, float) for x in g.paras): for i in range(len(g.paras)): - g.paras[i] = Parameter(f"{self._def_para_name}_{self._para_id}", value=g.paras[i]) + g.paras[i] = Parameter( + f"{self._def_para_name}_{self._para_id}", value=g.paras[i] + ) self._para_id += 1 self.get_parameter_grads() @@ -429,7 +447,9 @@ def draw_circuit(self, width: int = 4, return_str: bool = False): tq2 = reduce_map[max(gate.targs)] printlist[tq1 * 2, l] = "#" printlist[tq2 * 2, l] = "#" - if tq1 + tq2 in [reduce_map[ctrl] * 2 for ctrl in gate.ctrls]: + if tq1 + tq2 in [ + reduce_map[ctrl] * 2 for ctrl in gate.ctrls + ]: printlist[tq1 + tq2, l] = "*" + gate.symbol else: printlist[tq1 + tq2, l] = gate.symbol @@ -450,14 +470,23 @@ def draw_circuit(self, width: int = 4, return_str: bool = False): for j in range(2 * num - 1): if j % 2 == 0: linestr = ("q[%d]" % (reduce_map_inv[j // 2])).ljust(6) + "".join( - [printlist[j, l].center(int(printlist[-1, l]), "-") for l in range(depth)] + [ + printlist[j, l].center(int(printlist[-1, l]), "-") + for l in range(depth) + ] ) if reduce_map_inv[j // 2] in self.measures.keys(): linestr += " M->c[%d]" % self.measures[reduce_map_inv[j // 2]] circuitstr.append(linestr) else: circuitstr.append( - "".ljust(6) + "".join([printlist[j, l].center(int(printlist[-1, l]), " ") for l in range(depth)]) + "".ljust(6) + + "".join( + [ + printlist[j, l].center(int(printlist[-1, l]), " ") + for l in range(depth) + ] + ) ) circuitstr = "\n".join(circuitstr) @@ -490,7 +519,9 @@ def to_openqasm(self, with_para=False) -> str: openqasm text. """ - valid_gates = list(QuantumGate.gate_classes.keys()) # TODO:include instruction futher + valid_gates = list( + QuantumGate.gate_classes.keys() + ) # TODO:include instruction futher valid_gates.extend(["barrier", "delay", "reset"]) qasm = 'OPENQASM 2.0;\ninclude "qelib1.inc";\n' @@ -546,7 +577,9 @@ def _reallocate(self, num, qbits: List[int]): for i in range(len(op.targs)): op.targs[i] = qbits_map[op.targs[i]] - def add_controls(self, ctrlnum, ctrls: List[int] = [], targs: List[int] = [], inplace=False) -> "QuantumCircuit": + def add_controls( + self, ctrlnum, ctrls: List[int] = [], targs: List[int] = [], inplace=False + ) -> "QuantumCircuit": num = 0 instrs = [] if len(ctrls + targs) == 0: @@ -664,11 +697,15 @@ def unwrap(self): circ = op.circuit.unwrap() for op_ in circ.instructions: instructions.append(op_) - if isinstance(op_, (QuantumGate, Delay, Barrier, XYResonance, KrausChannel)): + if isinstance( + op_, (QuantumGate, Delay, Barrier, XYResonance, KrausChannel) + ): gates.append(op_) else: instructions.append(op) - if isinstance(op, (QuantumGate, Delay, Barrier, XYResonance, KrausChannel)): + if isinstance( + op, (QuantumGate, Delay, Barrier, XYResonance, KrausChannel) + ): gates.append(op) self.instructions = instructions @@ -677,7 +714,7 @@ def unwrap(self): return self # # # # # # # # # # # # # # helper functions # # # # # # # # # # # # # # - def id(self, pos: int) -> "QuantumCircuit": + def id(self, pos: int) -> "QuantumCircuit": # noqa: A003 """ Identity gate. @@ -1002,7 +1039,9 @@ def barrier(self, qlist: List[int] = None) -> "QuantumCircuit": Add barrier for qubits in qlist. Args: - qlist (list[int]): A list contain the qubit need add barrier. When qlist contain at least two qubit, the barrier will be added from minimum qubit to maximum qubit. For example: barrier([0, 2]) create barrier for qubits 0, 1, 2. To create discrete barrier, using barrier([0]), barrier([2]). + qlist (list[int]): A list contain the qubit need add barrier. When qlist contain at least two qubit, + the barrier will be added from minimum qubit to maximum qubit. For example: barrier([0, 2]) create + barrier for qubits 0, 1, 2. To create discrete barrier, using barrier([0]), barrier([2]). """ if qlist is None: qlist = list(range(self.num)) @@ -1150,15 +1189,15 @@ def measure(self, pos: List[int] = None, cbits: List[int] = None) -> None: if not len(set(cbits)) == len(cbits): raise ValueError("Classical bits not uniquely assigned.") if not len(cbits) == n_num: - raise ValueError("Number of measured bits should equal to the number of classical bits") + raise ValueError( + "Number of measured bits should equal to the number of classical bits" + ) else: cbits = list(range(e_num, e_num + n_num)) for cbit in cbits: if cbit < 0 or cbit > self.cbits_num: raise ValueError("Cbits index out of range.") - # _sorted_indices = sorted(range(n_num), key=lambda k: cbits[k]) - # cbits = [_sorted_indices.index(i) + e_num for i in range(n_num)] measure = Measure(dict(zip(pos, cbits))) self._measures.append(measure) @@ -1205,7 +1244,10 @@ def cif(self, cbits: List[int], condition: int): instructions = [] for i in range(len(self.instructions) - 1, -1, -1): - if isinstance(self.instructions[i], Cif) and self.instructions[i].instructions is None: + if ( + isinstance(self.instructions[i], Cif) + and self.instructions[i].instructions is None + ): instructions.reverse() self.instructions[i].set_ins(instructions) self.instructions = self.instructions[0 : i + 1] diff --git a/quafu/circuits/quantum_register.py b/quafu/circuits/quantum_register.py index 1d971903..25a392e9 100644 --- a/quafu/circuits/quantum_register.py +++ b/quafu/circuits/quantum_register.py @@ -63,8 +63,7 @@ def __init__(self, num: int = 0, name: str = None): def __getitem__(self, item): if item < len(self.qubits): return self.qubits[item] - else: - raise IndexError("Index out of range:", item) + raise IndexError("Index out of range:", item) def __iter__(self): self._i = 0 @@ -75,8 +74,7 @@ def __next__(self): x = self._i self._i += 1 return self.qubits[x] - else: - raise StopIteration + raise StopIteration def __len__(self): return len(self.qubits) diff --git a/quafu/dagcircuits/circuit_dag.py b/quafu/dagcircuits/circuit_dag.py index 08ae7f58..53d4573e 100755 --- a/quafu/dagcircuits/circuit_dag.py +++ b/quafu/dagcircuits/circuit_dag.py @@ -19,7 +19,6 @@ import numpy as np from IPython.display import SVG, Image -# import pygraphviz as pgv from networkx.drawing.nx_pydot import write_dot from quafu.dagcircuits.dag_circuit import ( # dag_circuit.py in the same folder as circuit_dag.py now DAGCircuit, @@ -27,7 +26,6 @@ from quafu.dagcircuits.instruction_node import ( # instruction_node.py in the same folder as circuit_dag.py now InstructionNode, ) -from quafu.elements import Barrier, Delay, XYResonance from quafu import QuantumCircuit from ..elements.element_gates import ( @@ -104,11 +102,9 @@ def gate_to_node(input_gate, specific_label): ): # if paras is True and not a list, make it a list gate.paras = [gate.paras] - # hashable_gate = InstructionNode(gate.name, gate.pos, gate.paras,gate.matrix,gate.duration,gate.unit, label=i) - hashable_gate = InstructionNode( + return InstructionNode( gate.name, gate.pos, gate.paras, gate.duration, gate.unit, label=specific_label ) - return hashable_gate # Building a DAG Graph using DAGCircuit from a QuantumCircuit @@ -144,18 +140,12 @@ def circuit_to_dag(circuit: QuantumCircuit, measure_flag=True): # A dictionary to store the last use of any qubit qubit_last_use = {} - # g = nx.MultiDiGraph() # two nodes can have multiple edges - # g = nx.DiGraph() # two nodes can only have one edge g = DAGCircuit() # two nodes can only have one edge # Add the start node - # g.add_node(-1,{"color": "green"}) g.add_nodes_from([(-1, {"color": "green"})]) # deepcopy the circuit to avoid modifying the original circuit - # gates = copy.deepcopy(circuit.gates) # need to import copy - # change to: gate = copy.deepcopy(input_gate) in gate_to_node() - for gate in circuit.gates: # transform gate to node hashable_gate = gate_to_node(gate, specific_label=i) @@ -189,7 +179,6 @@ def circuit_to_dag(circuit: QuantumCircuit, measure_flag=True): qubit_last_use[qubit] = measure_gate # Add the end node - # g.add_node(float('inf'),{"color": "red"}) g.add_nodes_from([(float("inf"), {"color": "red"})]) for qubit in qubit_last_use: @@ -306,7 +295,6 @@ def node_to_gate(node_in_dag): control_qubits = gate_in_dag.pos[:-1] target_qubit = gate_in_dag.pos[-1] return gate_class(control_qubits, target_qubit) - # print('gate_in_dag', gate_in_dag) return gate_class(*args) @@ -343,16 +331,7 @@ def dag_to_circuit(dep_graph, n: int): """ qcircuit = QuantumCircuit(n) - # print('222222222222222dep_graph', dep_graph.edges()) - # print('is_directed_acyclic_graph', nx.is_directed_acyclic_graph(dep_graph)) - # list_nodes = list(nx.topological_sort(dep_graph)) - # print('list_nodes', list_nodes) - # print('dagcircuit is dag?',dep_graph.is_dag()) - # show_dag(dep_graph) for gate in list(nx.topological_sort(dep_graph)): - # for gate in list_nodes: - # print('gate',gate) - if gate not in [-1, float("inf")]: # measure gate to do if gate.name == "measure": @@ -417,33 +396,19 @@ def draw_dag(dep_g, output_format="png"): def nodelist_to_dag(op_nodes: List[Any]) -> DAGCircuit: - # Starting Label Index - i = 0 - # A dictionary to store the last use of any qubit qubit_last_use = {} - # g = nx.MultiDiGraph() # two nodes can have multiple edges - # g = nx.DiGraph() # two nodes can only have one edge g = DAGCircuit() # Add the start node - # g.add_node(-1,{"color": "green"}) g.add_nodes_from([(-1, {"color": "green"})]) - # deepcopy the circuit to avoid modifying the original circuit - # gates = copy.deepcopy(circuit.gates) # need to import copy - # change to: gate = copy.deepcopy(input_gate) in gate_to_node() - for op_node in op_nodes: # transform gate to node hashable_gate = copy.deepcopy(op_node) g.add_node(hashable_gate, color="blue") - # # my add - # if len(hashable_gate.pos) == 1 and hashable_gate.paras is None: - # hashable_gate.paras = 6.283185307179586 - # Add edges based on qubit_last_use; update last use for qubit in hashable_gate.pos: if qubit in qubit_last_use: @@ -454,7 +419,6 @@ def nodelist_to_dag(op_nodes: List[Any]) -> DAGCircuit: qubit_last_use[qubit] = hashable_gate # Add the end node - # g.add_node(float('inf'),{"color": "red"}) g.add_nodes_from([(float("inf"), {"color": "red"})]) for qubit in qubit_last_use: @@ -483,11 +447,10 @@ def nodelist_qubit_mapping_dict(nodes_list): mapping_pos = list(range(len(nodes_list_qubits_used))) # mapping, get a dict - nodes_qubit_mapping_dict = dict( + return dict( zip(sorted(list(nodes_list_qubits_used)), mapping_pos) ) - return nodes_qubit_mapping_dict def nodelist_qubit_mapping_dict_reverse(nodes_list): @@ -495,15 +458,15 @@ def nodelist_qubit_mapping_dict_reverse(nodes_list): Args: nodes_list: a list of nodes Returns: - nodes_qubit_mapping_dict_reverse: a dict about keys are the new qubits and values are the qubits used by the nodes + nodes_qubit_mapping_dict_reverse: a dict about keys are the new qubits and values + are the qubits used by the nodes """ nodes_qubit_mapping_dict = nodelist_qubit_mapping_dict(nodes_list) # reverse mapping, get a dict - nodes_qubit_mapping_dict_reverse = { + return { value: key for key, value in nodes_qubit_mapping_dict.items() } - return nodes_qubit_mapping_dict_reverse # a function to map nodes_list @@ -563,7 +526,6 @@ def show_dag(dag: DAGCircuit) -> None: # Convert to array and plot. data = np.array(im) - # print("data.shape",data.shape) original_width, original_height = data.shape[1], data.shape[0] # Calculate the scaling ratio so that the maximum size does not exceed 2^16. max_size = 2**16 diff --git a/quafu/dagcircuits/dag_circuit.py b/quafu/dagcircuits/dag_circuit.py index a25ad65e..fc0b9400 100755 --- a/quafu/dagcircuits/dag_circuit.py +++ b/quafu/dagcircuits/dag_circuit.py @@ -88,7 +88,7 @@ def update_qubits_used(self): """ if -1 not in self.nodes: raise ValueError("-1 should be in DAGCircuit, please add it first") - self.qubits_used = set([int(edge[2]["label"][1:]) for edge in self.out_edges(-1, data=True)]) + self.qubits_used = set(int(edge[2]["label"][1:]) for edge in self.out_edges(-1, data=True)) return self.qubits_used def update_cbits_used(self): @@ -180,9 +180,6 @@ def node_qubits_predecessors(self, node: InstructionNode): Returns: node_qubits_predecessors: dict of {qubits -> predecessors }of node """ - # for edge in self.in_edges(node, data=True): - # print(edge[0], edge[1], edge[2]) - if node not in self.nodes: raise ValueError("node should be in DAGCircuit") if node in [-1]: @@ -190,8 +187,7 @@ def node_qubits_predecessors(self, node: InstructionNode): predecessor_nodes = [edge[0] for edge in self.in_edges(node, data=True)] qubits_labels = [int(edge[2]["label"][1:]) for edge in self.in_edges(node, data=True)] - node_qubits_predecessors = dict(zip(qubits_labels, predecessor_nodes)) - return node_qubits_predecessors + return dict(zip(qubits_labels, predecessor_nodes)) def node_qubits_successors(self, node: InstructionNode): """ @@ -209,8 +205,7 @@ def node_qubits_successors(self, node: InstructionNode): raise ValueError('float("inf") has no successors') successor_nodes = [edge[1] for edge in self.out_edges(node, data=True)] qubits_labels = [int(edge[2]["label"][1:]) for edge in self.out_edges(node, data=True)] - node_qubits_successors = dict(zip(qubits_labels, successor_nodes)) - return node_qubits_successors + return dict(zip(qubits_labels, successor_nodes)) def node_qubits_inedges(self, node: InstructionNode): """ @@ -225,13 +220,10 @@ def node_qubits_inedges(self, node: InstructionNode): if node in [-1]: raise ValueError("-1 has no predecessors") - inedges = [edge for edge in self.in_edges(node, data=True, keys=True)] # we can get u,v,k,d + inedges = list(self.in_edges(node, data=True, keys=True)) # we can get u,v,k,d qubits_labels = [int(edge[2]["label"][1:]) for edge in self.in_edges(node, data=True)] - node_qubits_inedges = dict(zip(qubits_labels, inedges)) - - # node_qubits_inedges[qubit] is a tuple of (u,v,k,d) + return dict(zip(qubits_labels, inedges)) - return node_qubits_inedges def node_qubits_outedges(self, node: InstructionNode): """ @@ -247,8 +239,7 @@ def node_qubits_outedges(self, node: InstructionNode): raise ValueError('float("inf") has no successors') outedges = [edge for edge in self.out_edges(node, data=True, keys=True)] # we can get u,v,k,d qubits_labels = [int(edge[2]["label"][1:]) for edge in self.out_edges(node, data=True)] - node_qubits_outedges = dict(zip(qubits_labels, outedges)) - return node_qubits_outedges + return dict(zip(qubits_labels, outedges)) def remove_instruction_node(self, gate: InstructionNode): """ @@ -490,9 +481,7 @@ def substitute_node_with_dag(self, gate: InstructionNode, input_dag): # Add nodes and edges from input_dag to self self.add_nodes_from(input_dag.nodes(data=True)) self.add_edges_from(input_dag.edges(data=True)) - - # Update other attributes of the DAG (like qubits_used etc.) - # self.update_qubits_used() + return def is_dag(self) -> bool: """ diff --git a/quafu/dagcircuits/instruction_node.py b/quafu/dagcircuits/instruction_node.py index 2a72d1d1..7d69837a 100755 --- a/quafu/dagcircuits/instruction_node.py +++ b/quafu/dagcircuits/instruction_node.py @@ -26,7 +26,8 @@ class InstructionNode: name : Any The name of the gate. pos : Union[List[Any], Dict[Any, Any]] - The position of the gate in the circuit. If the gate is a measurement gate, it is a dictionary with qubit indices as keys and classical bit indices as values. + The position of the gate in the circuit. If the gate is a measurement gate, it is a dictionary with qubit + indices as keys and classical bit indices as values. paras : List[Any] The parameters of the gate. duration : int @@ -49,7 +50,6 @@ class InstructionNode: name: Any # gate.name pos: Union[List[Any], Dict[Any, Any]] # gate.pos | Dict[Any,Any] for measure paras: List[Any] # gate.paras - # matrix:List[Any] # for gate in [QuantumGate] duration: int # for gate in [Delay,XYResonance] in quafu unit: str # for gate in [Delay,XYResonance] in quafu label: Union[str, int] @@ -66,25 +66,20 @@ def __str__(self): if self.paras is None: return f"{self.label}{{{self.name}({args})}}" + if not isinstance(self.paras, list): + if isinstance(self.paras, float): + formatted_paras = [f"{self.paras:.3f}"] + else: + formatted_paras = [str(self.paras)] else: - # if self.paras not a list, then make it a list of str of .3f float - if not isinstance(self.paras, list): - if isinstance(self.paras, float): - formatted_paras = [f"{self.paras:.3f}"] - else: - formatted_paras = [str(self.paras)] + if all(isinstance(p, float) for p in self.paras): + formatted_paras = [f"{p:.3f}" for p in self.paras] else: - if all(isinstance(p, float) for p in self.paras): - formatted_paras = [f"{p:.3f}" for p in self.paras] - else: - # for p in self.paras: - # print(p, type(p)) - formatted_paras = [str(p) for p in self.paras] - # print(formatted_paras) + formatted_paras = [str(p) for p in self.paras] - formatted_paras_str = ",".join(formatted_paras) + formatted_paras_str = ",".join(formatted_paras) - return f"{self.label}{{{self.name}({args})}}({formatted_paras_str})" + return f"{self.label}{{{self.name}({args})}}({formatted_paras_str})" def __repr__(self): return str(self) diff --git a/quafu/elements/__init__.py b/quafu/elements/__init__.py index c667bddc..9c23735b 100644 --- a/quafu/elements/__init__.py +++ b/quafu/elements/__init__.py @@ -26,3 +26,28 @@ ) from .unitary import UnitaryDecomposer from .utils import extract_float, reorder_matrix + +__all__ = [ + "Cif", + "Barrier", + "CircuitWrapper", + "ControlledCircuitWrapper", + "ControlledGate", + "ControlledOracle", + "Instruction", + "KrausChannel", + "Measure", + "OracleGate", + "Parameter", + "ParameterExpression", + "ParameterType", + "QuantumGate", + "QuantumPulse", + "Reset", + "UnitaryChannel", + "UnitaryDecomposer", + "XYResonance", + "extract_float", + "reorder_matrix", + "Delay", +] diff --git a/quafu/elements/element_gates/element_gates.py b/quafu/elements/element_gates/element_gates.py index aa5801e9..83124005 100644 --- a/quafu/elements/element_gates/element_gates.py +++ b/quafu/elements/element_gates/element_gates.py @@ -240,12 +240,6 @@ def __init__(self, pos: int, theta: ParameterType): super().__init__("RZ", [pos], [theta], wrap_para(mat.rz_mat)) -# @QuantumGate.register() -# class U2(QuantumGate): -# def __init__(self, pos: int, phi: float, _lambda: float): -# super().__init__("U2", [pos], [phi, _lambda], u2matrix(phi, _lambda)) - - @QuantumGate.register() class U3Gate(QuantumGate): def __init__(self, pos: int, theta: ParameterType, phi: ParameterType, _lambda: ParameterType): diff --git a/quafu/elements/instruction.py b/quafu/elements/instruction.py index bfc115cc..61cfc983 100644 --- a/quafu/elements/instruction.py +++ b/quafu/elements/instruction.py @@ -167,8 +167,7 @@ def named_paras(self): def to_qasm(self, with_para): lines = ["measure q[%d] -> meas[%d];\n" % (q, c) for q, c in zip(self.qbits, self.cbits)] - qasm = "".join(lines) - return qasm + return "".join(lines) Instruction.register_ins(Barrier) diff --git a/quafu/elements/matrices/__init__.py b/quafu/elements/matrices/__init__.py index 5561e82a..4451ed36 100644 --- a/quafu/elements/matrices/__init__.py +++ b/quafu/elements/matrices/__init__.py @@ -12,5 +12,70 @@ # See the License for the specific language governing permissions and # limitations under the License. """Matrices module.""" -from .mat_lib import * +from .mat_lib import ( + IdMatrix, + XMatrix, + YMatrix, + ZMatrix, + SMatrix, + SXMatrix, + SYMatrix, + TMatrix, + WMatrix, + SWMatrix, + HMatrix, + SwapMatrix, + ISwapMatrix, + CXMatrix, + CYMatrix, + CZMatrix, + CTMatrix, + ToffoliMatrix, + FredkinMatrix, + rx_mat, + ry_mat, + rz_mat, + pmatrix, + rxx_mat, + ryy_mat, + rzz_mat, + u2matrix, + u3matrix, + mat_dict, +) from .mat_utils import is_hermitian, is_zero, stack_matrices + +__all__ = [ + "IdMatrix", + "XMatrix", + "YMatrix", + "ZMatrix", + "SMatrix", + "SXMatrix", + "SYMatrix", + "TMatrix", + "WMatrix", + "SWMatrix", + "HMatrix", + "SwapMatrix", + "ISwapMatrix", + "CXMatrix", + "CYMatrix", + "CZMatrix", + "CTMatrix", + "ToffoliMatrix", + "FredkinMatrix", + "rx_mat", + "ry_mat", + "rz_mat", + "pmatrix", + "rxx_mat", + "ryy_mat", + "rzz_mat", + "u2matrix", + "u3matrix", + "mat_dict", + "is_hermitian", + "is_zero", + "stack_matrices", +] diff --git a/quafu/elements/noise.py b/quafu/elements/noise.py index df157d0d..0c35d544 100644 --- a/quafu/elements/noise.py +++ b/quafu/elements/noise.py @@ -57,10 +57,8 @@ def to_qasm(self, with_para): @property def symbol(self): if len(self.paras) > 0: - symbol = "%s(" % self.name + ",".join(["%.3f" % para for para in self.paras]) + ")" - return symbol - else: - return "%s" % self.name + return "%s(" % self.name + ",".join(["%.3f" % para for para in self.paras]) + ")" + return "%s" % self.name def __repr__(self): return self.symbol diff --git a/quafu/elements/oracle.py b/quafu/elements/oracle.py index 469928a8..b331073d 100644 --- a/quafu/elements/oracle.py +++ b/quafu/elements/oracle.py @@ -92,15 +92,14 @@ def __instantiate_gates__(self) -> None: """ Instantiate the gate structure through coping ins and bit mapping. """ - bit_mapping = dict((i, p) for i, p in enumerate(self.pos)) + bit_mapping = dict(enumerate(self.pos)) def map_pos(pos): if isinstance(pos, int): return bit_mapping[pos] - elif isinstance(pos, Iterable): + if isinstance(pos, Iterable): return [bit_mapping[p] for p in pos] - else: - raise ValueError + raise ValueError for gate in self.gate_structure: gate_ = copy.deepcopy(gate) diff --git a/setup.cfg b/setup.cfg index 250f1b62..803f6ba9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,6 @@ [flake8] -# ignore doc related rule, should remove in the future: D100, D103, D415, D104, D101, D102, D200, D205, D403, D107, D105, D411, D405, D301, D202, D208, D209, D417, D300, D419, SCS108 -ignore = E731, N803, N806, N802, W503, D212, D100, D103, D415, D104, D101, D102, D200, D205, D403, D107, D105, D411, D405, D301, D202, D208, D209, D417, D300, D419, SCS108 +# ignore doc related rule, should remove in the future: D100, D103, D415, D104, D101, D102, D200, D205, D403, D107, D105, D411, D405, D301, D202, D208, D209, D417, D300, D419, SCS108, D210, W191, E101 +ignore = E203, E741, E731, N803, N806, N802, W503, D212, D100, D103, D415, D104, D101, D102, D200, D205, D403, D107, D105, D411, D405, D301, D202, D208, D209, D417, D300, D419, SCS108, D210, W191, E101 max-line-length = 120 +exclude = + doc