From 5a2d414ff07b6bd6580f08d5cdb76cd0ceb7af6c Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 13 Jan 2026 17:27:45 +0100 Subject: [PATCH 001/110] Combining Gates and builing combined U3 works. --- include/na/zoned/decomposer/Decomposer.hpp | 71 ++++++ src/na/zoned/decomposer/Decomposer.cpp | 266 +++++++++++++++++++++ test/na/zoned/test_decomposer.cpp | 206 ++++++++++++++++ 3 files changed, 543 insertions(+) create mode 100644 include/na/zoned/decomposer/Decomposer.hpp create mode 100644 src/na/zoned/decomposer/Decomposer.cpp create mode 100644 test/na/zoned/test_decomposer.cpp diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp new file mode 100644 index 000000000..83f7c1aaf --- /dev/null +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include "ir/operations/StandardOperation.hpp" +#include "na/zoned/Types.hpp" + +#include + +namespace na::zoned { + + class Decomposer { + public: + /** + * Converts commonly used single qubit gates into their Quaternion representation + * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) with X,Y,Z Pauli Matrices + * @param op a reference_wrapper to the operation to be converted + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the quaternion + */ + static auto convert_gate_to_quaternion(std::reference_wrapper op) -> std::array; + /** + * Merges the quaternions representing two gates as in a Matrix multiplication of the gates + * @param q1 the first Quaternion to be combined + * @param q2 the second Quaternion to be combined + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the combined quaternion + */ + static auto combine_quaternions(const std::array& q1, + const std::array& q2) -> std::array; + /** + * Calculates the values of the U3-Gate parameters theta, phi and lambda + * @param quat is a quaternion representing a single qubit gate + * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ gate angles + */ + static auto get_U3_angles_from_quaternion(std::array quat) -> std::array; + + /** + * Calculates the largest value of the U3-Gate parameter theta from a vector of Operations. + * Fails when provided gates aren't all U3-Gates. + * @param layer is a SingleQubitGateLayers of a scheduled + */ + static auto calc_theta_max(const SingleQubitGateLayer& layer)->qc::fp; + + /** + * Takes a vector of SingleQubitGateLayer's and, for each layer + * , transforms all gates into U3 gates + * , combining all gates acting on the same qubit into a single U3 gate + * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit + */ + [[nodiscard]] auto transform_to_U3(const std::vector& layers) const + -> std::vector; + + /** + * Create a new Decomposer. + * @param n_qubits is the number of qubits in the circuit to be decomposed + */ + Decomposer(int n_qubits); + + [[nodiscard]] auto + decompose(const std::pair, + std::vector>& schedule) + -> std::pair, + std::vector>; + private: + struct { + std::array angles; + int qubit; + } struct_U3; + + int N_qubits; + + }; + +} // namespace na::zoned \ No newline at end of file diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp new file mode 100644 index 000000000..6ac34e93d --- /dev/null +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -0,0 +1,266 @@ +// +// Created by cpsch on 11.12.2025. +// +#include "na/zoned/decomposer/decomposer.hpp" + +//#include "ir/operations/StandardOperation.hpp" +#include "ir/operations/CompoundOperation.hpp" + +#include +#include + +namespace na::zoned { +Decomposer::Decomposer(int n_qubits) { + N_qubits=n_qubits; +}; + + +auto Decomposer::combine_quaternions(const std::array& q1, + const std::array& q2) -> std::array { + std::array new_quat{}; + new_quat[0]=q1[0]*q2[0]-q1[1]*q2[1]-q1[2]*q2[2]-q1[3]*q2[3]; + new_quat[1]=q1[0]*q2[1]+q1[1]*q2[0]+q1[2]*q2[3]-q1[3]*q2[2]; + new_quat[2]=q1[0]*q2[2]-q1[1]*q2[3]+q1[2]*q2[0]+q1[3]*q2[1]; + new_quat[3]=q1[0]*q2[3]+q1[1]*q2[2]-q1[2]*q2[1]+q1[3]*q2[0]; + return new_quat; +} + +auto Decomposer::convert_gate_to_quaternion(std::reference_wrapper op) -> std::array { + assert(op.get().getNqubits() == 1); + std::array quat; + //TODO: Figure out if I need -i factor + //TODO: Phase? + if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { + quat={cos(op.get().getParameter().front()),0,0,sin(op.get().getParameter().front())}; + } else if (op.get().getType() == qc::Z) { + quat={0,0,0,1}; + } else if (op.get().getType() == qc::S) { + quat={cos(qc::PI_4),0,0,sin(qc::PI_4)}; + } else if (op.get().getType() == qc::Sdg) { + quat={cos(-qc::PI_4),0,0,sin(-qc::PI_4)}; + } else if (op.get().getType() == qc::T) { + quat={cos(qc::PI_4/2),0,0,sin(qc::PI_4/2)}; + } else if (op.get().getType() == qc::Tdg) { + quat={cos(-qc::PI_4/2),0,0,sin(-qc::PI_4/2)}; + } else if (op.get().getType() == qc::U) { + quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)} + ,{cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}), + {cos(op.get().getParameter().at(2)/2),0,0,sin(op.get().getParameter().at(2)/2)}); + } else if (op.get().getType() == qc::U2) { + quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().front()/2),0,0,sin(op.get().getParameter().front()/2)} + ,{cos(qc::PI_2),0,sin(qc::PI_2),0}), + {cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)}); + } else if (op.get().getType() == qc::RX) { + quat={cos(op.get().getParameter().front()/2),sin(op.get().getParameter().front()/2),0,0}; + } else if (op.get().getType() == qc::RY) { + quat={cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}; + } else if (op.get().getType() == qc::H) { + //TODO: Double check this + quat=combine_quaternions(combine_quaternions({1,0,0,0} + ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), + {cos(qc::PI_2),0,0,sin(qc::PI_2)}); + } else if (op.get().getType() == qc::X) { + quat={0,1,0,0}; + } else if (op.get().getType() == qc::Y) { + quat={0,1,0,0}; + } else if (op.get().getType() == qc::Vdg) { + quat=combine_quaternions(combine_quaternions({cos(qc::PI_4),0,0,sin(qc::PI_4)} + ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), + {cos(-qc::PI_4),0,0,sin(-qc::PI_4)}); + } else if (op.get().getType() == qc::SX) { + quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} + ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), + {cos(qc::PI_4),0,0,sin(qc::PI_4)}); + } else if (op.get().getType() == qc::SXdg || + op.get().getType() == qc::V) { + quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} + ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), + {cos(qc::PI_4),0,0,sin(qc::PI_4)}); + } else { + // if the gate type is not recognized, an error is printed and the + // gate is not included in the output. + std::ostringstream oss; + oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + << op.get().getType() << "\n"; + throw std::invalid_argument(oss.str()); + } + return quat; + } + + auto Decomposer::get_U3_angles_from_quaternion(std::array quat) -> std::array { + //TODO: Is there a prescribed eps somewhere? Else where should THIS eps be defined + qc::fp eps=1e-5; + qc::fp theta; + qc::fp phi; + qc::fp lambda; + if (abs(quat[0])>eps||abs(quat[3])>eps) { + theta=2.*std::atan2(std::sqrt(quat[2]*quat[2]+quat[1]*quat[1]),std::sqrt(quat[0]*quat[0]+quat[3]*quat[3])); + qc::fp alph_1=std::atan2(quat[3],quat[0]); //phi+ lambda + if (abs(quat[1])>eps||abs(quat[2])>eps) { + qc::fp alph_2=-1*std::atan2(quat[1],quat[2]); + phi=alph_1+alph_2; //phi + lambda=alph_1-alph_2; + } else { + //TODO: Which was set to zero??? + phi=0; + lambda=2*alph_1; + } + } else { + theta=qc::PI; //or § PI if sin(theta/2)=-1... Relevant? Or is the -1= exp(i*pi) just global phase + if (abs(quat[1])>eps||abs(quat[2])>eps) { + phi=0; + lambda= 2*std::atan2(quat[1],quat[2]); + //2*tan(q1/q2) = phi-lambda, but can't be disentangled + } else { + //This should never happen! Exception?? + phi=0.; + lambda=0.; + } + } + return {theta,phi,lambda}; +} + + + auto Decomposer::calc_theta_max(const SingleQubitGateLayer& layer) -> qc::fp { + //TODO: Error Handling improvement? + qc::fp theta_max=0; + for (auto gate :layer) { + if (gate.get().getType()== qc::U){ + std::vector params=gate.get().getParameter(); + if (abs(params[0])>theta_max) {theta_max=abs(params[0]);} + } else { + // if the gate type is not U3, an error is printed. + std::ostringstream oss; + oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + << gate.get().getType() << "\n"; + throw std::invalid_argument(oss.str()); + } + } + return theta_max; +} + +//TOD0:Return vector of structs +auto Decomposer::transform_to_U3(const std::vector& layers) const + -> std::vector { + //How to sort gates with same qubit + //How to get Matrix Representations?? + std::vector new_layers; + for (const auto& layer: layers) { + std::vector>> gates(this->N_qubits); + SingleQubitGateLayer new_layer; + for (auto gate:layer) { + gates[gate.get().getNtargets()].push_back(gate); + } + + for (auto qubit_gates:gates) { + if (!qubit_gates.empty()) { + + std::array quat = convert_gate_to_quaternion(qubit_gates[0]); + for (auto i=1;i angles=get_U3_angles_from_quaternion(quat); + //TODO: Don't return Op here? + const qc::Operation *new_op=new qc::StandardOperation(qubit_gates[0].get().getTargets().front(),qc::U,{angles[0],angles[1],angles[2]}); + new_layer.emplace_back(*new_op); + } + } + new_layers.push_back(new_layer); + } + return new_layers; +} + + +auto Decomposer::decompose( + const std::pair, + std::vector>& schedule) + -> std::pair, + std::vector> { + //TODO:make U3Layer vector + std::vector U3Layers=this->transform_to_U3(schedule.first); + std::vector NewSingleQubitLayers=std::vector{}; + + for (const auto& layer: U3Layers) { + qc::fp theta_max=calc_theta_max(layer); + SingleQubitGateLayer FrontLayer; + SingleQubitGateLayer MidLayer; + SingleQubitGateLayer BackLayer; + SingleQubitGateLayer NewLayer; + + + for (auto gate:layer){ + //TODO: ONly ANgles at this point + std::vector params=gate.get().getParameter(); + qc::fp theta=params[0]; + qc::fp phi_minus=params[1]; + qc::fp phi_plus=params[2]; + //TODO: Decide whether to make this a separate function for each gate in rel to theta_max + //TODO: Add mod 2PI/TAU + qc::fp alpha, chi, beta; + if (theta==theta_max) { + alpha=qc::PI_2; + chi=qc::PI; + }else { + qc::fp kappa=sqrt((sin(theta/2)*sin(theta/2))/(sin(theta_max)*sin(theta_max)-(sin(theta/2)*sin(theta/2)))); + alpha=atan(cos(theta_max/2)*kappa); + chi=fmod(2*atan(kappa),qc::TAU); + } + if (theta!=0) { + beta=theta_max<0?qc::PI_2:-1*qc::PI_2; + }else { + beta=0; + } + qc::fp gamma_plus=fmod(phi_plus-(alpha+beta),qc::TAU); + qc::fp gamma_minus=fmod(phi_minus-(alpha-beta),qc::TAU); + + //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) + // GR(theta_max/2, PI_2)==Global Y due to PI_2 + + + //TODO: Does this work?? + auto sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_minus}); + qc::Operation *op=&sop; + FrontLayer.emplace_back(std::reference_wrapper(*op)); + + sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{chi}); + op=&sop; + MidLayer.emplace_back(std::reference_wrapper(*op)); + + sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_plus}); + op=&sop; + MidLayer.emplace_back(std::reference_wrapper(*op)); + }//gate::layer + + + + std::vector< std::unique_ptr> GR_plus; + std::vector< std::unique_ptr> GR_minus; + + for (auto i=0; iN_qubits; ++i) { + GR_plus.emplace_back(new qc::StandardOperation(i,qc::RY,{theta_max/2})); + GR_minus.emplace_back(new qc::StandardOperation(i,qc::RY,{-1*theta_max/2})); + } + + for (auto gate:FrontLayer) { + NewLayer.push_back(gate); + } + + auto cop= qc::CompoundOperation(std::move(GR_plus),true); + qc::Operation *ryp=&cop; + NewLayer.emplace_back(*ryp); + + for (auto gate:MidLayer) { + NewLayer.push_back(gate); + } + cop=qc::CompoundOperation(std::move(GR_minus),true); + qc::Operation *rym=&cop; + NewLayer.emplace_back(*rym); + + for (auto gate:BackLayer) { + NewLayer.push_back(gate); + } + NewSingleQubitLayers.push_back(NewLayer); + }//layer::SingleQubitLayers + return std::pair{NewSingleQubitLayers,schedule.second}; +} +}// namespace na::zoned \ No newline at end of file diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp new file mode 100644 index 000000000..771b05853 --- /dev/null +++ b/test/na/zoned/test_decomposer.cpp @@ -0,0 +1,206 @@ +// +// Created by cpsch on 16.12.2025. +// + +#include "ir/QuantumComputation.hpp" +#include "na/zoned/decomposer/Decomposer.hpp" +#include "na/zoned/scheduler/ASAPScheduler.hpp" + +#include +#include +#include +#include +#include + +namespace na::zoned { +constexpr std::string_view architectureJson = R"({ + "name": "asap_scheduler_architecture", + "storage_zones": [{ + "zone_id": 0, + "slms": [{"id": 0, "site_separation": [3, 3], "r": 20, "c": 20, "location": [0, 0]}], + "offset": [0, 0], + "dimension": [60, 60] + }], + "entanglement_zones": [{ + "zone_id": 0, + "slms": [ + {"id": 1, "site_separation": [12, 10], "r": 4, "c": 4, "location": [5, 70]}, + {"id": 2, "site_separation": [12, 10], "r": 4, "c": 4, "location": [7, 70]} + ], + "offset": [5, 70], + "dimension": [50, 40] + }], + "aods":[{"id": 0, "site_separation": 2, "r": 20, "c": 20}], + "rydberg_range": [[[5, 70], [55, 110]]] +})"; +//TODO: Tests for the U3 decomposition +class DecomposerTest : public ::testing::Test { +protected: + Decomposer decomposer=Decomposer(4); + Architecture architecture; + ASAPScheduler::Config config{.maxFillingFactor = .8}; + ASAPScheduler scheduler; + DecomposerTest() + : architecture(Architecture::fromJSONString(architectureJson)), + scheduler(architecture, config) {} +}; + +qc::fp epsilon=1e-5; + +TEST(Test,ThreeQuaternionCombiTest) { + std::array q1={cos(qc::PI_4),0,0,sin(qc::PI_4)}; + std::array q2={cos(qc::PI_2),0,sin(qc::PI_2),0}; + std::array q12=Decomposer::combine_quaternions(q1,q2); + EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(-1*cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); + std::array q3={cos(qc::PI_2),0,0,sin(qc::PI_2)}; + std::array q13=Decomposer::combine_quaternions(q12,q3); + EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); + +} + +TEST(Test,ThreeQuaternionU3Test) { + std::array q1={cos(qc::PI_2),0,0,sin(qc::PI_2)}; + std::array q2={cos(qc::PI_4/2),0,sin(qc::PI_4/2),0}; + std::array q12=Decomposer::combine_quaternions(q1,q2); + //TODO:FIgure this out!!! + EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(-1*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(cos(qc::PI_4/2),epsilon))); + std::array q3={cos(qc::PI_4),0,0,sin(qc::PI_4)}; + std::array q13=Decomposer::combine_quaternions(q12,q3); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), + ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); + +} + +TEST(Test,SingleXGateAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::X); + + qc::QuantumComputation qc(n); + qc.rx(qc::PI, 0); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(-1*qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); +} + +TEST(Test,SingleU3GateAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI_4,qc::PI,qc::PI_2}); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), + ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); + + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI_4,epsilon), + ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); +} + +TEST(Test, ThetaPiAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI,qc::PI,qc::PI_2}); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(-r2,epsilon),::testing::DoubleNear(r2,epsilon),::testing::DoubleNear(0,epsilon))); + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(-1*qc::PI_2,epsilon))); + +} + +TEST(Test, ThetaZeroAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::U,{0,qc::PI,qc::PI_2}); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(r2,epsilon))); + + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(3*qc::PI_2,epsilon))); + +} + +TEST_F(DecomposerTest, SingleRXGate) { + // ┌───────┐ + // q: ┤ Rx(π) ├ + // └───────┘ + size_t n=1; + qc::QuantumComputation qc(n); + qc.rx(qc::PI, 0); + Decomposer decomposer=Decomposer(n); + const auto& sched = + scheduler.schedule(qc); + // auto decomp=decomposer.decompose(sched); +} + +TEST_F(DecomposerTest, SingleU3Gate) { + // ┌───────────────┐ + // q:─┤ U3(π/4,π,π/2) ├─ + // └───────────────┘ + size_t n=1; + qc::QuantumComputation qc(n); + qc.u(qc::PI_4,qc::PI,qc::PI_2,0); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + +TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { + // ┌───────┐ ┌───────┐ + // q: ┤ X ├──┤ Z ├ + // └───────┘ └───────┘ + size_t n=1; + qc::QuantumComputation qc(n); + qc.x(0); + qc.z(0); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + +TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { + // ┌───────┐ + // q_0: ─┤ X ├─ + // └───────┘ + // ┌───────┐ + // q_1: ─┤ Z ├─ + // └───────┘ + + size_t n=2; + qc::QuantumComputation qc(n); + qc.x(0); + qc.z(1); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + +TEST_F(DecomposerTest, TwoU3GatesTwoQubits) { + // ┌───────────────┐ + // q_0: ─┤ U3(π/4,π,π/2) ├─ + // └───────────────┘ + // ┌───────────────┐ + // q_1: ─┤ U3(π/2,π/2,π) ├─ + // └───────────────┘ + size_t n=2; + qc::QuantumComputation qc(n); + qc.u(qc::PI_4,qc::PI,qc::PI_2,0); + qc.u(qc::PI_2,qc::PI_2,qc::PI,1); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + + +} // namespace na::zoned \ No newline at end of file From 8d4bb8f5d0f23346aaf93d534900d8006b6c7b36 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 20 Jan 2026 14:53:42 +0100 Subject: [PATCH 002/110] Changed internal handling of U3 gates. --- include/na/zoned/decomposer/Decomposer.hpp | 39 ++- src/na/zoned/decomposer/Decomposer.cpp | 324 ++++++++++----------- test/na/zoned/test_decomposer.cpp | 39 ++- 3 files changed, 223 insertions(+), 179 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index 83f7c1aaf..942881b6a 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -8,6 +8,14 @@ namespace na::zoned { class Decomposer { + private: + struct struct_U3{ + std::array angles; + int qubit; + } ; + static inline constexpr qc::fp epsilon=1e-5; + int N_qubits; + public: /** * Converts commonly used single qubit gates into their Quaternion representation @@ -29,24 +37,33 @@ namespace na::zoned { * @param quat is a quaternion representing a single qubit gate * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ gate angles */ - static auto get_U3_angles_from_quaternion(std::array quat) -> std::array; + static auto get_U3_angles_from_quaternion(const std::array& quat) -> std::array; /** - * Calculates the largest value of the U3-Gate parameter theta from a vector of Operations. - * Fails when provided gates aren't all U3-Gates. + * Calculates the largest value of the U3-Gate parameter theta from a vector + * of Operations. Fails when provided gates aren't all U3-Gates. * @param layer is a SingleQubitGateLayers of a scheduled + * @returns the maximal value of theta in the given layer */ - static auto calc_theta_max(const SingleQubitGateLayer& layer)->qc::fp; + static auto calc_theta_max(const std::vector& layer)->qc::fp; /** * Takes a vector of SingleQubitGateLayer's and, for each layer - * , transforms all gates into U3 gates + * , transforms all gates into U3 gates represented by struct_U3's * , combining all gates acting on the same qubit into a single U3 gate * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit + * @returns a vector of vectors of a struct_U3's representing the single qubit gate layers */ [[nodiscard]] auto transform_to_U3(const std::vector& layers) const - -> std::vector; - + -> std::vector>; + /** + * Takes a vector of qc::fp's representing the U3-Gate angles of a single qubit hate and the maximal value of theta + * for the single qubit gate layer and calculates the transversal decomposition angles as in Nottingham et. al. 2024 + * @param angles is a std::array of qc::fp representing (theta,phi, lambda) + * @param theta_max the maximal theta value of the single-qubit qate layer + * @returns an array of qc::fp values giving the angles (chi, gamma_minus, gamma_plus) + */ + auto static get_decomposition_angles (const std::array& angles,qc::fp theta_max )-> std::array; /** * Create a new Decomposer. * @param n_qubits is the number of qubits in the circuit to be decomposed @@ -55,16 +72,10 @@ namespace na::zoned { [[nodiscard]] auto decompose(const std::pair, - std::vector>& schedule) + std::vector>& schedule) const -> std::pair, std::vector>; - private: - struct { - std::array angles; - int qubit; - } struct_U3; - int N_qubits; }; diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index 6ac34e93d..534891fa6 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -15,169 +15,198 @@ Decomposer::Decomposer(int n_qubits) { }; -auto Decomposer::combine_quaternions(const std::array& q1, - const std::array& q2) -> std::array { - std::array new_quat{}; - new_quat[0]=q1[0]*q2[0]-q1[1]*q2[1]-q1[2]*q2[2]-q1[3]*q2[3]; - new_quat[1]=q1[0]*q2[1]+q1[1]*q2[0]+q1[2]*q2[3]-q1[3]*q2[2]; - new_quat[2]=q1[0]*q2[2]-q1[1]*q2[3]+q1[2]*q2[0]+q1[3]*q2[1]; - new_quat[3]=q1[0]*q2[3]+q1[1]*q2[2]-q1[2]*q2[1]+q1[3]*q2[0]; - return new_quat; -} - -auto Decomposer::convert_gate_to_quaternion(std::reference_wrapper op) -> std::array { +auto Decomposer::convert_gate_to_quaternion( + std::reference_wrapper op) -> std::array { assert(op.get().getNqubits() == 1); - std::array quat; - //TODO: Figure out if I need -i factor - //TODO: Phase? + std::array quat{}; + // TODO: Phase? if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat={cos(op.get().getParameter().front()),0,0,sin(op.get().getParameter().front())}; - } else if (op.get().getType() == qc::Z) { - quat={0,0,0,1}; - } else if (op.get().getType() == qc::S) { - quat={cos(qc::PI_4),0,0,sin(qc::PI_4)}; - } else if (op.get().getType() == qc::Sdg) { - quat={cos(-qc::PI_4),0,0,sin(-qc::PI_4)}; - } else if (op.get().getType() == qc::T) { - quat={cos(qc::PI_4/2),0,0,sin(qc::PI_4/2)}; - } else if (op.get().getType() == qc::Tdg) { - quat={cos(-qc::PI_4/2),0,0,sin(-qc::PI_4/2)}; - } else if (op.get().getType() == qc::U) { - quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)} - ,{cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}), - {cos(op.get().getParameter().at(2)/2),0,0,sin(op.get().getParameter().at(2)/2)}); - } else if (op.get().getType() == qc::U2) { - quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().front()/2),0,0,sin(op.get().getParameter().front()/2)} - ,{cos(qc::PI_2),0,sin(qc::PI_2),0}), - {cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)}); - } else if (op.get().getType() == qc::RX) { - quat={cos(op.get().getParameter().front()/2),sin(op.get().getParameter().front()/2),0,0}; - } else if (op.get().getType() == qc::RY) { - quat={cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}; - } else if (op.get().getType() == qc::H) { - //TODO: Double check this - quat=combine_quaternions(combine_quaternions({1,0,0,0} - ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), - {cos(qc::PI_2),0,0,sin(qc::PI_2)}); - } else if (op.get().getType() == qc::X) { - quat={0,1,0,0}; - } else if (op.get().getType() == qc::Y) { - quat={0,1,0,0}; - } else if (op.get().getType() == qc::Vdg) { - quat=combine_quaternions(combine_quaternions({cos(qc::PI_4),0,0,sin(qc::PI_4)} - ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), - {cos(-qc::PI_4),0,0,sin(-qc::PI_4)}); - } else if (op.get().getType() == qc::SX) { - quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} - ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), - {cos(qc::PI_4),0,0,sin(qc::PI_4)}); - } else if (op.get().getType() == qc::SXdg || - op.get().getType() == qc::V) { - quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} - ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), - {cos(qc::PI_4),0,0,sin(qc::PI_4)}); - } else { - // if the gate type is not recognized, an error is printed and the - // gate is not included in the output. - std::ostringstream oss; - oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " - << op.get().getType() << "\n"; - throw std::invalid_argument(oss.str()); - } - return quat; - } + quat = {cos(op.get().getParameter().front()), 0, 0, + sin(op.get().getParameter().front())}; + } else if (op.get().getType() == qc::Z) { + quat = {0, 0, 0, 1}; + } else if (op.get().getType() == qc::S) { + quat = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + } else if (op.get().getType() == qc::Sdg) { + quat = {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}; + } else if (op.get().getType() == qc::T) { + quat = {cos(qc::PI_4 / 2), 0, 0, sin(qc::PI_4 / 2)}; + } else if (op.get().getType() == qc::Tdg) { + quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; + } else if (op.get().getType() == qc::U) { + quat = combine_quaternions( + combine_quaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, + sin(op.get().getParameter().at(1) / 2)}, + {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}), + {cos(op.get().getParameter().at(2) / 2), 0, 0, + sin(op.get().getParameter().at(2) / 2)}); + } else if (op.get().getType() == qc::U2) { + quat = combine_quaternions( + combine_quaternions({cos(op.get().getParameter().front() / 2), 0, 0, + sin(op.get().getParameter().front() / 2)}, + {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), + {cos(op.get().getParameter().at(1) / 2), 0, 0, + sin(op.get().getParameter().at(1) / 2)}); + } else if (op.get().getType() == qc::RX) { + quat = {cos(op.get().getParameter().front() / 2), + sin(op.get().getParameter().front() / 2), 0, 0}; + } else if (op.get().getType() == qc::RY) { + quat = {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}; + } else if (op.get().getType() == qc::H) { + quat = combine_quaternions( + combine_quaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); + } else if (op.get().getType() == qc::X) { + quat = {0, 1, 0, 0}; + } else if (op.get().getType() == qc::Y) { + quat = {0, 1, 0, 0}; + } else if (op.get().getType() == qc::Vdg) { + quat = combine_quaternions( + combine_quaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); + } else if (op.get().getType() == qc::SX) { + quat = combine_quaternions( + combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); + } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { + quat = combine_quaternions( + combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); + } else { + // if the gate type is not recognized, an error is printed and the + // gate is not included in the output. + std::ostringstream oss; + oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + << op.get().getType() << "\n"; + throw std::invalid_argument(oss.str()); + } + return quat; +} + +auto Decomposer::combine_quaternions(const std::array& q1, + const std::array& q2) + -> std::array { + std::array new_quat{}; + new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; + new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; + new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; + new_quat[3] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]; + return new_quat; +} - auto Decomposer::get_U3_angles_from_quaternion(std::array quat) -> std::array { - //TODO: Is there a prescribed eps somewhere? Else where should THIS eps be defined - qc::fp eps=1e-5; + auto Decomposer::get_U3_angles_from_quaternion( + const std::array& quat) + -> std::array { + // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be + // defined qc::fp theta; qc::fp phi; qc::fp lambda; - if (abs(quat[0])>eps||abs(quat[3])>eps) { - theta=2.*std::atan2(std::sqrt(quat[2]*quat[2]+quat[1]*quat[1]),std::sqrt(quat[0]*quat[0]+quat[3]*quat[3])); - qc::fp alph_1=std::atan2(quat[3],quat[0]); //phi+ lambda - if (abs(quat[1])>eps||abs(quat[2])>eps) { - qc::fp alph_2=-1*std::atan2(quat[1],quat[2]); - phi=alph_1+alph_2; //phi - lambda=alph_1-alph_2; + if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { + theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), + std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); + qc::fp alph_1 = std::atan2(quat[3], quat[0]); // phi+ lambda + if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + qc::fp alph_2 = -1 * std::atan2(quat[1], quat[2]); + phi = alph_1 + alph_2; // phi + lambda = alph_1 - alph_2; } else { - //TODO: Which was set to zero??? - phi=0; - lambda=2*alph_1; + // TODO: Which was set to zero??? + phi = 0; + lambda = 2 * alph_1; } } else { - theta=qc::PI; //or § PI if sin(theta/2)=-1... Relevant? Or is the -1= exp(i*pi) just global phase - if (abs(quat[1])>eps||abs(quat[2])>eps) { - phi=0; - lambda= 2*std::atan2(quat[1],quat[2]); - //2*tan(q1/q2) = phi-lambda, but can't be disentangled + theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= + // exp(i*pi) just global phase + if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + phi = 0; + lambda = 2 * std::atan2(quat[1], quat[2]); + // 2*tan(q1/q2) = phi-lambda, but can't be disentangled } else { - //This should never happen! Exception?? - phi=0.; - lambda=0.; + // This should never happen! Exception?? + phi = 0.; + lambda = 0.; } } - return {theta,phi,lambda}; + return {theta, phi, lambda}; } - - auto Decomposer::calc_theta_max(const SingleQubitGateLayer& layer) -> qc::fp { - //TODO: Error Handling improvement? - qc::fp theta_max=0; - for (auto gate :layer) { - if (gate.get().getType()== qc::U){ - std::vector params=gate.get().getParameter(); - if (abs(params[0])>theta_max) {theta_max=abs(params[0]);} - } else { - // if the gate type is not U3, an error is printed. - std::ostringstream oss; - oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " - << gate.get().getType() << "\n"; - throw std::invalid_argument(oss.str()); - } + auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { + qc::fp theta_max = 0; + for (auto gate : layer) { + if (abs(gate.angles[0]) > theta_max) { + theta_max = abs(gate.angles[0]); + } } - return theta_max; + return theta_max; } -//TOD0:Return vector of structs -auto Decomposer::transform_to_U3(const std::vector& layers) const - -> std::vector { - //How to sort gates with same qubit - //How to get Matrix Representations?? - std::vector new_layers; - for (const auto& layer: layers) { - std::vector>> gates(this->N_qubits); - SingleQubitGateLayer new_layer; - for (auto gate:layer) { +auto Decomposer::transform_to_U3( + const std::vector& layers) const + -> std::vector> { + // auto u=struct_U3({0,0,0},0); + std::vector> new_layers; + for (const auto& layer : layers) { + std::vector>> gates( + this->N_qubits); + std::vector new_layer; + for (auto gate : layer) { gates[gate.get().getNtargets()].push_back(gate); } - for (auto qubit_gates:gates) { + for (auto qubit_gates : gates) { if (!qubit_gates.empty()) { - - std::array quat = convert_gate_to_quaternion(qubit_gates[0]); - for (auto i=1;i quat = convert_gate_to_quaternion(qubit_gates[0]); + for (auto i = 1; i < qubit_gates.size(); i++) { + quat = combine_quaternions( + quat, convert_gate_to_quaternion(qubit_gates[i])); } - std::array angles=get_U3_angles_from_quaternion(quat); - //TODO: Don't return Op here? - const qc::Operation *new_op=new qc::StandardOperation(qubit_gates[0].get().getTargets().front(),qc::U,{angles[0],angles[1],angles[2]}); - new_layer.emplace_back(*new_op); + std::array angles = get_U3_angles_from_quaternion(quat); + new_layer.emplace_back( + struct_U3(angles, + qubit_gates[0].get().getTargets().front())); } } new_layers.push_back(new_layer); } return new_layers; } +auto Decomposer::get_decomposition_angles(const std::array& angles, + qc::fp theta_max)-> std::array{ + qc::fp alpha, chi, beta; + //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) + if (abs(angles[0]-theta_max) < epsilon) { + alpha=qc::PI_2; + chi=qc::PI; + }else { + qc::fp kappa=sqrt((sin(angles[0]/2)*sin(angles[0]/2))/(sin(theta_max)*sin(theta_max)-(sin(angles[0]/2)*sin(angles[0]/2)))); + alpha=atan(cos(theta_max/2)*kappa); + chi=fmod(2*atan(kappa),qc::TAU); + } + + if (abs(angles[0]) > epsilon) { + beta=theta_max<0?qc::PI_2:-1*qc::PI_2; + }else { + beta=0; + } + qc::fp gamma_plus=fmod(angles[2]-(alpha+beta),qc::TAU); + qc::fp gamma_minus=fmod(angles[1]-(alpha-beta),qc::TAU); + + return {chi,gamma_minus,gamma_plus}; +} auto Decomposer::decompose( const std::pair, - std::vector>& schedule) + std::vector>& schedule) const -> std::pair, std::vector> { - //TODO:make U3Layer vector - std::vector U3Layers=this->transform_to_U3(schedule.first); + std::vector> U3Layers=transform_to_U3(schedule.first); std::vector NewSingleQubitLayers=std::vector{}; for (const auto& layer: U3Layers) { @@ -187,52 +216,23 @@ auto Decomposer::decompose( SingleQubitGateLayer BackLayer; SingleQubitGateLayer NewLayer; - for (auto gate:layer){ - //TODO: ONly ANgles at this point - std::vector params=gate.get().getParameter(); - qc::fp theta=params[0]; - qc::fp phi_minus=params[1]; - qc::fp phi_plus=params[2]; - //TODO: Decide whether to make this a separate function for each gate in rel to theta_max - //TODO: Add mod 2PI/TAU - qc::fp alpha, chi, beta; - if (theta==theta_max) { - alpha=qc::PI_2; - chi=qc::PI; - }else { - qc::fp kappa=sqrt((sin(theta/2)*sin(theta/2))/(sin(theta_max)*sin(theta_max)-(sin(theta/2)*sin(theta/2)))); - alpha=atan(cos(theta_max/2)*kappa); - chi=fmod(2*atan(kappa),qc::TAU); - } - if (theta!=0) { - beta=theta_max<0?qc::PI_2:-1*qc::PI_2; - }else { - beta=0; - } - qc::fp gamma_plus=fmod(phi_plus-(alpha+beta),qc::TAU); - qc::fp gamma_minus=fmod(phi_minus-(alpha-beta),qc::TAU); + std::array decomp_angles=get_decomposition_angles(gate.angles,theta_max); - //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) // GR(theta_max/2, PI_2)==Global Y due to PI_2 - - - //TODO: Does this work?? - auto sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_minus}); + auto sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[1]}); qc::Operation *op=&sop; FrontLayer.emplace_back(std::reference_wrapper(*op)); - sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{chi}); + sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[0]}); op=&sop; MidLayer.emplace_back(std::reference_wrapper(*op)); - sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_plus}); + sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[2]}); op=&sop; MidLayer.emplace_back(std::reference_wrapper(*op)); }//gate::layer - - std::vector< std::unique_ptr> GR_plus; std::vector< std::unique_ptr> GR_minus; diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index 771b05853..61ec42027 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -33,7 +33,8 @@ constexpr std::string_view architectureJson = R"({ "aods":[{"id": 0, "site_separation": 2, "r": 20, "c": 20}], "rydberg_range": [[[5, 70], [55, 110]]] })"; -//TODO: Tests for the U3 decomposition + + class DecomposerTest : public ::testing::Test { protected: Decomposer decomposer=Decomposer(4); @@ -64,7 +65,6 @@ TEST(Test,ThreeQuaternionU3Test) { std::array q1={cos(qc::PI_2),0,0,sin(qc::PI_2)}; std::array q2={cos(qc::PI_4/2),0,sin(qc::PI_4/2),0}; std::array q12=Decomposer::combine_quaternions(q1,q2); - //TODO:FIgure this out!!! EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), ::testing::DoubleNear(-1*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(cos(qc::PI_4/2),epsilon))); std::array q3={cos(qc::PI_4),0,0,sin(qc::PI_4)}; @@ -127,11 +127,44 @@ TEST(Test, ThetaZeroAngleTest) { } +//One or Two Decomposition Tests? + + +TEST(Test, RXDecompositionTest) { + size_t n=1; + std::array rx={qc::PI,-qc::PI_2,qc::PI_2}; + //middle entry gamma_minus is -3/2 PI?? + EXPECT_THAT(Decomposer::get_decomposition_angles(rx,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + +} + +TEST(Test,U3DecompositionTest) { + size_t n=1; + std::array u3={qc::PI_4,qc::PI,qc::PI_2}; + // gamm minus i - PI_" not PI_2 and gam_plus is 0 not PI!! + EXPECT_THAT(Decomposer::get_decomposition_angles(u3,qc::PI_4),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(-qc::PI_2,epsilon))); +} + +TEST(Test,DoubleDecompositionTest) { + size_t n=1; + std::array x1={qc::PI,-qc::PI_2,qc::PI_2}; + std::array z2={0,0,qc::PI}; + //gamm_min is - 3/2 PI not 0 and gamm_plus is PI_2 not zero + EXPECT_THAT(Decomposer::get_decomposition_angles(x1,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); + // gamm_min is 0 not PI_2 and gamm_plus is PI not PI_2 + EXPECT_THAT(Decomposer::get_decomposition_angles(z2,qc::PI),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + +} + TEST_F(DecomposerTest, SingleRXGate) { // ┌───────┐ // q: ┤ Rx(π) ├ // └───────┘ - size_t n=1; + int n=1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); Decomposer decomposer=Decomposer(n); From 75caf7b9ea2a46ad130b420097914ce3b5dbf21c Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 22 Jan 2026 14:07:19 +0100 Subject: [PATCH 003/110] Changed --- include/na/zoned/decomposer/Decomposer.hpp | 11 ++-- src/na/zoned/decomposer/Decomposer.cpp | 68 ++++++++++------------ test/na/zoned/test_decomposer.cpp | 22 ++++++- 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index 942881b6a..f9faebf99 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -1,5 +1,6 @@ #pragma once +#include "DecomposerBase.hpp" #include "ir/operations/StandardOperation.hpp" #include "na/zoned/Types.hpp" @@ -7,7 +8,7 @@ namespace na::zoned { - class Decomposer { + class Decomposer : public DecomposerBase{ private: struct struct_U3{ std::array angles; @@ -54,7 +55,7 @@ namespace na::zoned { * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit * @returns a vector of vectors of a struct_U3's representing the single qubit gate layers */ - [[nodiscard]] auto transform_to_U3(const std::vector& layers) const + [[nodiscard]] auto transform_to_U3(const std::vector& layers) const -> std::vector>; /** * Takes a vector of qc::fp's representing the U3-Gate angles of a single qubit hate and the maximal value of theta @@ -71,10 +72,8 @@ namespace na::zoned { Decomposer(int n_qubits); [[nodiscard]] auto - decompose(const std::pair, - std::vector>& schedule) const - -> std::pair, - std::vector>; + decompose(const std::vector& singleQubitGateLayers) const + -> std::vector override; }; diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index 534891fa6..45cee0589 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -145,10 +145,9 @@ auto Decomposer::combine_quaternions(const std::array& q1, } return theta_max; } - -auto Decomposer::transform_to_U3( - const std::vector& layers) const - -> std::vector> { + auto Decomposer::transform_to_U3( + const std::vector& layers) const + -> std::vector> { // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { @@ -156,7 +155,7 @@ auto Decomposer::transform_to_U3( this->N_qubits); std::vector new_layer; for (auto gate : layer) { - gates[gate.get().getNtargets()].push_back(gate); + gates[gate.get().getTargets().front()].push_back(gate); } for (auto qubit_gates : gates) { @@ -181,19 +180,18 @@ auto Decomposer::get_decomposition_angles(const std::array& angles, qc::fp alpha, chi, beta; //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) if (abs(angles[0]-theta_max) < epsilon) { - alpha=qc::PI_2; chi=qc::PI; + if (abs(cos(theta_max/2)) epsilon) { - beta=theta_max<0?qc::PI_2:-1*qc::PI_2; - }else { - beta=0; - } + beta=angles[0]<0?-1*qc::PI_2:qc::PI_2; qc::fp gamma_plus=fmod(angles[2]-(alpha+beta),qc::TAU); qc::fp gamma_minus=fmod(angles[1]-(alpha-beta),qc::TAU); @@ -201,12 +199,10 @@ auto Decomposer::get_decomposition_angles(const std::array& angles, } -auto Decomposer::decompose( - const std::pair, - std::vector>& schedule) const - -> std::pair, - std::vector> { - std::vector> U3Layers=transform_to_U3(schedule.first); +auto Decomposer::decompose(const std::vector& singleQubitGateLayers) const + -> std::vector{ + + std::vector> U3Layers=transform_to_U3(singleQubitGateLayers); std::vector NewSingleQubitLayers=std::vector{}; for (const auto& layer: U3Layers) { @@ -221,16 +217,16 @@ auto Decomposer::decompose( // GR(theta_max/2, PI_2)==Global Y due to PI_2 auto sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[1]}); - qc::Operation *op=&sop; - FrontLayer.emplace_back(std::reference_wrapper(*op)); + std::unique_ptr op=std::make_unique(sop); + FrontLayer.emplace_back(std::move(op)); sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[0]}); - op=&sop; - MidLayer.emplace_back(std::reference_wrapper(*op)); + op=std::make_unique(sop); + MidLayer.emplace_back(std::move(op)); sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[2]}); - op=&sop; - MidLayer.emplace_back(std::reference_wrapper(*op)); + op=std::make_unique(sop); + BackLayer.emplace_back(std::move(op)); }//gate::layer std::vector< std::unique_ptr> GR_plus; @@ -241,26 +237,26 @@ auto Decomposer::decompose( GR_minus.emplace_back(new qc::StandardOperation(i,qc::RY,{-1*theta_max/2})); } - for (auto gate:FrontLayer) { - NewLayer.push_back(gate); + for (auto&& gate:FrontLayer) { + NewLayer.push_back(std::move(gate)); } auto cop= qc::CompoundOperation(std::move(GR_plus),true); - qc::Operation *ryp=&cop; - NewLayer.emplace_back(*ryp); + std::unique_ptr ryp=std::make_unique(cop); + NewLayer.emplace_back(std::move(ryp)); - for (auto gate:MidLayer) { - NewLayer.push_back(gate); + for (auto&& gate:MidLayer) { + NewLayer.push_back(std::move(gate)); } cop=qc::CompoundOperation(std::move(GR_minus),true); - qc::Operation *rym=&cop; - NewLayer.emplace_back(*rym); + std::unique_ptr rym=std::make_unique(cop); + NewLayer.emplace_back(std::move(rym)); - for (auto gate:BackLayer) { - NewLayer.push_back(gate); + for (auto&& gate:BackLayer) { + NewLayer.push_back(std::move(gate)); } - NewSingleQubitLayers.push_back(NewLayer); + NewSingleQubitLayers.push_back(std::move(NewLayer)); }//layer::SingleQubitLayers - return std::pair{NewSingleQubitLayers,schedule.second}; + return NewSingleQubitLayers; } }// namespace na::zoned \ No newline at end of file diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index 61ec42027..e7896f309 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -133,9 +133,8 @@ TEST(Test, ThetaZeroAngleTest) { TEST(Test, RXDecompositionTest) { size_t n=1; std::array rx={qc::PI,-qc::PI_2,qc::PI_2}; - //middle entry gamma_minus is -3/2 PI?? EXPECT_THAT(Decomposer::get_decomposition_angles(rx,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); } @@ -170,7 +169,24 @@ TEST_F(DecomposerTest, SingleRXGate) { Decomposer decomposer=Decomposer(n); const auto& sched = scheduler.schedule(qc); - // auto decomp=decomposer.decompose(sched); + auto decomp=decomposer.decompose(sched.first); + //DEcomposition for (PI,0,PI) NOT (PI,-PI_2,PI_2) due to back calculation!! EQUivalent!! + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 5); + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + } TEST_F(DecomposerTest, SingleU3Gate) { From 9134d22d577b718a1330c736eb8d75555ed37c06 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 27 Jan 2026 13:24:34 +0100 Subject: [PATCH 004/110] Added more Tests --- src/na/zoned/decomposer/Decomposer.cpp | 3 +- test/na/zoned/test_decomposer.cpp | 172 +++++++++++++++++++++---- 2 files changed, 148 insertions(+), 27 deletions(-) diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index 45cee0589..f17c6c793 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -116,7 +116,6 @@ auto Decomposer::combine_quaternions(const std::array& q1, phi = alph_1 + alph_2; // phi lambda = alph_1 - alph_2; } else { - // TODO: Which was set to zero??? phi = 0; lambda = 2 * alph_1; } @@ -126,7 +125,7 @@ auto Decomposer::combine_quaternions(const std::array& q1, if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { phi = 0; lambda = 2 * std::atan2(quat[1], quat[2]); - // 2*tan(q1/q2) = phi-lambda, but can't be disentangled + // atan can give PI instead of 0 Problem? } else { // This should never happen! Exception?? phi = 0.; diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index e7896f309..d8b403bc8 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -127,7 +127,6 @@ TEST(Test, ThetaZeroAngleTest) { } -//One or Two Decomposition Tests? TEST(Test, RXDecompositionTest) { @@ -150,10 +149,8 @@ TEST(Test,DoubleDecompositionTest) { size_t n=1; std::array x1={qc::PI,-qc::PI_2,qc::PI_2}; std::array z2={0,0,qc::PI}; - //gamm_min is - 3/2 PI not 0 and gamm_plus is PI_2 not zero EXPECT_THAT(Decomposer::get_decomposition_angles(x1,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); - // gamm_min is 0 not PI_2 and gamm_plus is PI not PI_2 EXPECT_THAT(Decomposer::get_decomposition_angles(z2,qc::PI),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); @@ -170,7 +167,6 @@ TEST_F(DecomposerTest, SingleRXGate) { const auto& sched = scheduler.schedule(qc); auto decomp=decomposer.decompose(sched.first); - //DEcomposition for (PI,0,PI) NOT (PI,-PI_2,PI_2) due to back calculation!! EQUivalent!! EXPECT_EQ(decomp.size(),1); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); @@ -190,18 +186,38 @@ TEST_F(DecomposerTest, SingleRXGate) { } TEST_F(DecomposerTest, SingleU3Gate) { - // ┌───────────────┐ - // q:─┤ U3(π/4,π,π/2) ├─ - // └───────────────┘ - size_t n=1; + // ┌─────────────┐ + // q: ┤ U3(0,π,π/2) ├ + // └─────────────┘ + int n=1; qc::QuantumComputation qc(n); - qc.u(qc::PI_4,qc::PI,qc::PI_2,0); + qc.u(0.0,qc::PI,qc::PI_2, 0); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 5); + + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); } +//TEST with U3(o,?,?) +//TEST with two Single Qubit Layers + TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ // q: ┤ X ├──┤ Z ├ @@ -211,8 +227,26 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { qc.x(0); qc.z(0); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 5); + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + //TODO: FIgure out i this is always Positive + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(3*qc::PI_2,epsilon))); } @@ -229,27 +263,115 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { qc.x(0); qc.z(1); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = - scheduler.schedule(qc); + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 8); + + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[0][1]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][1]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_TRUE(decomp[0][2]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][2]->isGlobal(n)); + + EXPECT_EQ(decomp[0][3]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][3]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + + EXPECT_TRUE(decomp[0][5]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][5]->isGlobal(n)); + + EXPECT_EQ(decomp[0][6]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][6]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[0][7]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][7]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); } -TEST_F(DecomposerTest, TwoU3GatesTwoQubits) { - // ┌───────────────┐ - // q_0: ─┤ U3(π/4,π,π/2) ├─ - // └───────────────┘ - // ┌───────────────┐ - // q_1: ─┤ U3(π/2,π/2,π) ├─ - // └───────────────┘ +TEST_F(DecomposerTest, TwoQubitsTwoLayers) { + // ┌───────┐ ┌───────┐ + // q_0: ─┤ X ├───■───┤ Z ├─ + // └───────┘ │ └───────┘ + // │ ┌───────┐ + // q_1: ─────────────■───┤ X ├─ + // └───────┘ + size_t n=2; qc::QuantumComputation qc(n); - qc.u(qc::PI_4,qc::PI,qc::PI_2,0); - qc.u(qc::PI_2,qc::PI_2,qc::PI,1); + qc.x(0); + qc.cz(0, 1); + qc.z(0); + qc.x(1); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = - scheduler.schedule(qc); + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(),2); + EXPECT_EQ(decomp[0].size(), 5); + EXPECT_EQ(decomp[1].size(), 8); -} + //Layer 1 + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + //Layer 2 + + EXPECT_EQ(decomp[1][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[1][1]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][1]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_TRUE(decomp[1][2]->isCompoundOperation()); + EXPECT_TRUE(decomp[1][2]->isGlobal(n)); + + EXPECT_EQ(decomp[1][3]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][3]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + + EXPECT_EQ(decomp[1][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][4]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + + EXPECT_TRUE(decomp[1][5]->isCompoundOperation()); + EXPECT_TRUE(decomp[1][5]->isGlobal(n)); + + EXPECT_EQ(decomp[1][6]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][6]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[1][7]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][7]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + +} } // namespace na::zoned \ No newline at end of file From 134416082ead6109357fed9922bbf3df79e8ef26 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 08:50:54 +0000 Subject: [PATCH 005/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/decomposer/Decomposer.hpp | 156 ++++--- src/na/zoned/decomposer/Decomposer.cpp | 153 +++---- test/na/zoned/test_decomposer.cpp | 452 ++++++++++++--------- 3 files changed, 432 insertions(+), 329 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index f9faebf99..c9b6bd8bc 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + #pragma once #include "DecomposerBase.hpp" @@ -8,74 +18,90 @@ namespace na::zoned { - class Decomposer : public DecomposerBase{ - private: - struct struct_U3{ - std::array angles; - int qubit; - } ; - static inline constexpr qc::fp epsilon=1e-5; - int N_qubits; +class Decomposer : public DecomposerBase { +private: + struct struct_U3 { + std::array angles; + int qubit; + }; + static inline constexpr qc::fp epsilon = 1e-5; + int N_qubits; - public: - /** - * Converts commonly used single qubit gates into their Quaternion representation - * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) with X,Y,Z Pauli Matrices - * @param op a reference_wrapper to the operation to be converted - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the quaternion - */ - static auto convert_gate_to_quaternion(std::reference_wrapper op) -> std::array; - /** - * Merges the quaternions representing two gates as in a Matrix multiplication of the gates - * @param q1 the first Quaternion to be combined - * @param q2 the second Quaternion to be combined - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the combined quaternion - */ - static auto combine_quaternions(const std::array& q1, - const std::array& q2) -> std::array; - /** - * Calculates the values of the U3-Gate parameters theta, phi and lambda - * @param quat is a quaternion representing a single qubit gate - * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ gate angles - */ - static auto get_U3_angles_from_quaternion(const std::array& quat) -> std::array; +public: + /** + * Converts commonly used single qubit gates into their Quaternion + * representation + * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) + * with X,Y,Z Pauli Matrices + * @param op a reference_wrapper to the operation to be converted + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the + * components of the quaternion + */ + static auto + convert_gate_to_quaternion(std::reference_wrapper op) + -> std::array; + /** + * Merges the quaternions representing two gates as in a Matrix multiplication + * of the gates + * @param q1 the first Quaternion to be combined + * @param q2 the second Quaternion to be combined + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the + * components of the combined quaternion + */ + static auto combine_quaternions(const std::array& q1, + const std::array& q2) + -> std::array; + /** + * Calculates the values of the U3-Gate parameters theta, phi and lambda + * @param quat is a quaternion representing a single qubit gate + * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ + * gate angles + */ + static auto get_U3_angles_from_quaternion(const std::array& quat) + -> std::array; - /** - * Calculates the largest value of the U3-Gate parameter theta from a vector - * of Operations. Fails when provided gates aren't all U3-Gates. - * @param layer is a SingleQubitGateLayers of a scheduled - * @returns the maximal value of theta in the given layer - */ - static auto calc_theta_max(const std::vector& layer)->qc::fp; + /** + * Calculates the largest value of the U3-Gate parameter theta from a vector + * of Operations. Fails when provided gates aren't all U3-Gates. + * @param layer is a SingleQubitGateLayers of a scheduled + * @returns the maximal value of theta in the given layer + */ + static auto calc_theta_max(const std::vector& layer) -> qc::fp; - /** - * Takes a vector of SingleQubitGateLayer's and, for each layer - * , transforms all gates into U3 gates represented by struct_U3's - * , combining all gates acting on the same qubit into a single U3 gate - * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit - * @returns a vector of vectors of a struct_U3's representing the single qubit gate layers - */ - [[nodiscard]] auto transform_to_U3(const std::vector& layers) const - -> std::vector>; - /** - * Takes a vector of qc::fp's representing the U3-Gate angles of a single qubit hate and the maximal value of theta - * for the single qubit gate layer and calculates the transversal decomposition angles as in Nottingham et. al. 2024 - * @param angles is a std::array of qc::fp representing (theta,phi, lambda) - * @param theta_max the maximal theta value of the single-qubit qate layer - * @returns an array of qc::fp values giving the angles (chi, gamma_minus, gamma_plus) - */ - auto static get_decomposition_angles (const std::array& angles,qc::fp theta_max )-> std::array; - /** - * Create a new Decomposer. - * @param n_qubits is the number of qubits in the circuit to be decomposed - */ - Decomposer(int n_qubits); + /** + * Takes a vector of SingleQubitGateLayer's and, for each layer + * , transforms all gates into U3 gates represented by struct_U3's + * , combining all gates acting on the same qubit into a single U3 gate + * @param layers is a std::vector of SingleQubitGateLayers of a scheduled + * circuit + * @returns a vector of vectors of a struct_U3's representing the single qubit + * gate layers + */ + [[nodiscard]] auto + transform_to_U3(const std::vector& layers) const + -> std::vector>; + /** + * Takes a vector of qc::fp's representing the U3-Gate angles of a single + * qubit hate and the maximal value of theta for the single qubit gate layer + * and calculates the transversal decomposition angles as in Nottingham et. + * al. 2024 + * @param angles is a std::array of qc::fp representing (theta,phi, lambda) + * @param theta_max the maximal theta value of the single-qubit qate layer + * @returns an array of qc::fp values giving the angles (chi, gamma_minus, + * gamma_plus) + */ + auto static get_decomposition_angles(const std::array& angles, + qc::fp theta_max) + -> std::array; + /** + * Create a new Decomposer. + * @param n_qubits is the number of qubits in the circuit to be decomposed + */ + Decomposer(int n_qubits); - [[nodiscard]] auto - decompose(const std::vector& singleQubitGateLayers) const + [[nodiscard]] auto decompose( + const std::vector& singleQubitGateLayers) const -> std::vector override; +}; - - }; - -} // namespace na::zoned \ No newline at end of file +} // namespace na::zoned diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index f17c6c793..f44761054 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -1,19 +1,26 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + // // Created by cpsch on 11.12.2025. // #include "na/zoned/decomposer/decomposer.hpp" -//#include "ir/operations/StandardOperation.hpp" +// #include "ir/operations/StandardOperation.hpp" #include "ir/operations/CompoundOperation.hpp" #include #include namespace na::zoned { -Decomposer::Decomposer(int n_qubits) { - N_qubits=n_qubits; -}; - +Decomposer::Decomposer(int n_qubits) { N_qubits = n_qubits; }; auto Decomposer::convert_gate_to_quaternion( std::reference_wrapper op) -> std::array { @@ -99,9 +106,8 @@ auto Decomposer::combine_quaternions(const std::array& q1, return new_quat; } - auto Decomposer::get_U3_angles_from_quaternion( - const std::array& quat) - -> std::array { +auto Decomposer::get_U3_angles_from_quaternion( + const std::array& quat) -> std::array { // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be // defined qc::fp theta; @@ -110,14 +116,14 @@ auto Decomposer::combine_quaternions(const std::array& q1, if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); - qc::fp alph_1 = std::atan2(quat[3], quat[0]); // phi+ lambda + qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // phi+ lambda if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { - qc::fp alph_2 = -1 * std::atan2(quat[1], quat[2]); - phi = alph_1 + alph_2; // phi - lambda = alph_1 - alph_2; + qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); + phi = alpha_1 + alpha_2; // phi + lambda = alpha_1 - alpha_2; } else { phi = 0; - lambda = 2 * alph_1; + lambda = 2 * alpha_1; } } else { theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= @@ -135,18 +141,18 @@ auto Decomposer::combine_quaternions(const std::array& q1, return {theta, phi, lambda}; } - auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { +auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { - if (abs(gate.angles[0]) > theta_max) { - theta_max = abs(gate.angles[0]); - } + if (abs(gate.angles[0]) > theta_max) { + theta_max = abs(gate.angles[0]); + } } return theta_max; } - auto Decomposer::transform_to_U3( - const std::vector& layers) const - -> std::vector> { +auto Decomposer::transform_to_U3( + const std::vector& layers) const + -> std::vector> { // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { @@ -166,8 +172,7 @@ auto Decomposer::combine_quaternions(const std::array& q1, } std::array angles = get_U3_angles_from_quaternion(quat); new_layer.emplace_back( - struct_U3(angles, - qubit_gates[0].get().getTargets().front())); + struct_U3(angles, qubit_gates[0].get().getTargets().front())); } } new_layers.push_back(new_layer); @@ -175,87 +180,99 @@ auto Decomposer::combine_quaternions(const std::array& q1, return new_layers; } auto Decomposer::get_decomposition_angles(const std::array& angles, - qc::fp theta_max)-> std::array{ + qc::fp theta_max) + -> std::array { qc::fp alpha, chi, beta; - //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - if (abs(angles[0]-theta_max) < epsilon) { - chi=qc::PI; - if (abs(cos(theta_max/2))Rz(gamma_minus)GR(theta_max/2, + // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) + if (abs(angles[0] - theta_max) < epsilon) { + chi = qc::PI; + if (abs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? + alpha = 0; + } else { + alpha = qc::PI_2; } - }else { - qc::fp kappa=sqrt((sin(angles[0]/2)*sin(angles[0]/2))/(sin(theta_max)*sin(theta_max)-(sin(angles[0]/2)*sin(angles[0]/2)))); - alpha=atan(cos(theta_max/2)*kappa); - chi=fmod(2*atan(kappa),qc::TAU); + } else { + qc::fp kappa = sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / + (sin(theta_max) * sin(theta_max) - + (sin(angles[0] / 2) * sin(angles[0] / 2)))); + alpha = atan(cos(theta_max / 2) * kappa); + chi = fmod(2 * atan(kappa), qc::TAU); } - beta=angles[0]<0?-1*qc::PI_2:qc::PI_2; - qc::fp gamma_plus=fmod(angles[2]-(alpha+beta),qc::TAU); - qc::fp gamma_minus=fmod(angles[1]-(alpha-beta),qc::TAU); + beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; + qc::fp gamma_plus = fmod(angles[2] - (alpha + beta), qc::TAU); + qc::fp gamma_minus = fmod(angles[1] - (alpha - beta), qc::TAU); - return {chi,gamma_minus,gamma_plus}; + return {chi, gamma_minus, gamma_plus}; } +auto Decomposer::decompose( + const std::vector& singleQubitGateLayers) const + -> std::vector { -auto Decomposer::decompose(const std::vector& singleQubitGateLayers) const - -> std::vector{ + std::vector> U3Layers = + transform_to_U3(singleQubitGateLayers); + std::vector NewSingleQubitLayers = + std::vector{}; - std::vector> U3Layers=transform_to_U3(singleQubitGateLayers); - std::vector NewSingleQubitLayers=std::vector{}; - - for (const auto& layer: U3Layers) { - qc::fp theta_max=calc_theta_max(layer); + for (const auto& layer : U3Layers) { + qc::fp theta_max = calc_theta_max(layer); SingleQubitGateLayer FrontLayer; SingleQubitGateLayer MidLayer; SingleQubitGateLayer BackLayer; SingleQubitGateLayer NewLayer; - for (auto gate:layer){ - std::array decomp_angles=get_decomposition_angles(gate.angles,theta_max); + for (auto gate : layer) { + std::array decomp_angles = + get_decomposition_angles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - auto sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[1]}); - std::unique_ptr op=std::make_unique(sop); + auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); + std::unique_ptr op = + std::make_unique(sop); FrontLayer.emplace_back(std::move(op)); - sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[0]}); - op=std::make_unique(sop); + sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}); + op = std::make_unique(sop); MidLayer.emplace_back(std::move(op)); - sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[2]}); - op=std::make_unique(sop); + sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}); + op = std::make_unique(sop); BackLayer.emplace_back(std::move(op)); - }//gate::layer + } // gate::layer - std::vector< std::unique_ptr> GR_plus; - std::vector< std::unique_ptr> GR_minus; + std::vector> GR_plus; + std::vector> GR_minus; - for (auto i=0; iN_qubits; ++i) { - GR_plus.emplace_back(new qc::StandardOperation(i,qc::RY,{theta_max/2})); - GR_minus.emplace_back(new qc::StandardOperation(i,qc::RY,{-1*theta_max/2})); + for (auto i = 0; i < this->N_qubits; ++i) { + GR_plus.emplace_back( + new qc::StandardOperation(i, qc::RY, {theta_max / 2})); + GR_minus.emplace_back( + new qc::StandardOperation(i, qc::RY, {-1 * theta_max / 2})); } - for (auto&& gate:FrontLayer) { + for (auto&& gate : FrontLayer) { NewLayer.push_back(std::move(gate)); } - auto cop= qc::CompoundOperation(std::move(GR_plus),true); - std::unique_ptr ryp=std::make_unique(cop); + auto cop = qc::CompoundOperation(std::move(GR_plus), true); + std::unique_ptr ryp = + std::make_unique(cop); NewLayer.emplace_back(std::move(ryp)); - for (auto&& gate:MidLayer) { + for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - cop=qc::CompoundOperation(std::move(GR_minus),true); - std::unique_ptr rym=std::make_unique(cop); + cop = qc::CompoundOperation(std::move(GR_minus), true); + std::unique_ptr rym = + std::make_unique(cop); NewLayer.emplace_back(std::move(rym)); - for (auto&& gate:BackLayer) { + for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); } NewSingleQubitLayers.push_back(std::move(NewLayer)); - }//layer::SingleQubitLayers + } // layer::SingleQubitLayers return NewSingleQubitLayers; } -}// namespace na::zoned \ No newline at end of file +} // namespace na::zoned diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index d8b403bc8..f2ed429c7 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + // // Created by cpsch on 16.12.2025. // @@ -34,10 +44,9 @@ constexpr std::string_view architectureJson = R"({ "rydberg_range": [[[5, 70], [55, 110]]] })"; - class DecomposerTest : public ::testing::Test { protected: - Decomposer decomposer=Decomposer(4); + Decomposer decomposer = Decomposer(4); Architecture architecture; ASAPScheduler::Config config{.maxFillingFactor = .8}; ASAPScheduler scheduler; @@ -46,208 +55,246 @@ class DecomposerTest : public ::testing::Test { scheduler(architecture, config) {} }; -qc::fp epsilon=1e-5; - -TEST(Test,ThreeQuaternionCombiTest) { - std::array q1={cos(qc::PI_4),0,0,sin(qc::PI_4)}; - std::array q2={cos(qc::PI_2),0,sin(qc::PI_2),0}; - std::array q12=Decomposer::combine_quaternions(q1,q2); - EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(-1*cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); - std::array q3={cos(qc::PI_2),0,0,sin(qc::PI_2)}; - std::array q13=Decomposer::combine_quaternions(q12,q3); - EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); - +qc::fp epsilon = 1e-5; + +TEST(Test, ThreeQuaternionCombiTest) { + std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; + std::array q12 = Decomposer::combine_quaternions(q1, q2); + EXPECT_THAT(q12, ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), + ::testing::DoubleNear(cos(qc::PI_4), epsilon), + ::testing::DoubleNear(0, epsilon))); + std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; + std::array q13 = Decomposer::combine_quaternions(q12, q3); + EXPECT_THAT( + q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(cos(qc::PI_4), epsilon), + ::testing::DoubleNear(cos(qc::PI_4), epsilon), + ::testing::DoubleNear(0, epsilon))); } -TEST(Test,ThreeQuaternionU3Test) { - std::array q1={cos(qc::PI_2),0,0,sin(qc::PI_2)}; - std::array q2={cos(qc::PI_4/2),0,sin(qc::PI_4/2),0}; - std::array q12=Decomposer::combine_quaternions(q1,q2); - EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(-1*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(cos(qc::PI_4/2),epsilon))); - std::array q3={cos(qc::PI_4),0,0,sin(qc::PI_4)}; - std::array q13=Decomposer::combine_quaternions(q12,q3); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), - ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); - +TEST(Test, ThreeQuaternionU3Test) { + std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; + std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; + std::array q12 = Decomposer::combine_quaternions(q1, q2); + EXPECT_THAT(q12, ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); + std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + std::array q13 = Decomposer::combine_quaternions(q12, q3); + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q13, ::testing::ElementsAre( + ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); } -TEST(Test,SingleXGateAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::X); +TEST(Test, SingleXGateAngleTest) { + size_t n = 1; + const qc::Operation* op = new qc::StandardOperation(0, qc::X); qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - std::array q=Decomposer::convert_gate_to_quaternion( + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(-1*qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_THAT( + Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(-1 * qc::PI_2, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon))); } -TEST(Test,SingleU3GateAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI_4,qc::PI,qc::PI_2}); - std::array q=Decomposer::convert_gate_to_quaternion( +TEST(Test, SingleU3GateAngleTest) { + size_t n = 1; + const qc::Operation* op = + new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), - ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); - - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI_4,epsilon), - ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q, ::testing::ElementsAre( + ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); + + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), + ::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, ThetaPiAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI,qc::PI,qc::PI_2}); - std::array q=Decomposer::convert_gate_to_quaternion( + size_t n = 1; + const qc::Operation* op = + new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(-r2,epsilon),::testing::DoubleNear(r2,epsilon),::testing::DoubleNear(0,epsilon))); - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(-1*qc::PI_2,epsilon))); - + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-r2, epsilon), + ::testing::DoubleNear(r2, epsilon), + ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); } TEST(Test, ThetaZeroAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::U,{0,qc::PI,qc::PI_2}); - std::array q=Decomposer::convert_gate_to_quaternion( + size_t n = 1; + const qc::Operation* op = + new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(r2,epsilon))); - - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(3*qc::PI_2,epsilon))); - + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(r2, epsilon))); + + EXPECT_THAT( + Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(3 * qc::PI_2, epsilon))); } - - TEST(Test, RXDecompositionTest) { - size_t n=1; - std::array rx={qc::PI,-qc::PI_2,qc::PI_2}; - EXPECT_THAT(Decomposer::get_decomposition_angles(rx,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); - + size_t n = 1; + std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; + EXPECT_THAT(Decomposer::get_decomposition_angles(rx, qc::PI), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); } -TEST(Test,U3DecompositionTest) { - size_t n=1; - std::array u3={qc::PI_4,qc::PI,qc::PI_2}; - // gamm minus i - PI_" not PI_2 and gam_plus is 0 not PI!! - EXPECT_THAT(Decomposer::get_decomposition_angles(u3,qc::PI_4),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(-qc::PI_2,epsilon))); +TEST(Test, U3DecompositionTest) { + size_t n = 1; + std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; + // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! + EXPECT_THAT( + Decomposer::get_decomposition_angles(u3, qc::PI_4), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(-qc::PI_2, epsilon))); } -TEST(Test,DoubleDecompositionTest) { - size_t n=1; - std::array x1={qc::PI,-qc::PI_2,qc::PI_2}; - std::array z2={0,0,qc::PI}; - EXPECT_THAT(Decomposer::get_decomposition_angles(x1,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); - EXPECT_THAT(Decomposer::get_decomposition_angles(z2,qc::PI),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); - +TEST(Test, DoubleDecompositionTest) { + size_t n = 1; + std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; + std::array z2 = {0, 0, qc::PI}; + EXPECT_THAT(Decomposer::get_decomposition_angles(x1, qc::PI), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT(Decomposer::get_decomposition_angles(z2, qc::PI), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST_F(DecomposerTest, SingleRXGate) { // ┌───────┐ // q: ┤ Rx(π) ├ // └───────┘ - int n=1; + int n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - Decomposer decomposer=Decomposer(n); - const auto& sched = - scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } TEST_F(DecomposerTest, SingleU3Gate) { // ┌─────────────┐ // q: ┤ U3(0,π,π/2) ├ // └─────────────┘ - int n=1; + int n = 1; qc::QuantumComputation qc(n); - qc.u(0.0,qc::PI,qc::PI_2, 0); - Decomposer decomposer=Decomposer(n); - const auto& sched = - scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + qc.u(0.0, qc::PI, qc::PI_2, 0); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } -//TEST with U3(o,?,?) -//TEST with two Single Qubit Layers +// TEST with U3(o,?,?) +// TEST with two Single Qubit Layers TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ // q: ┤ X ├──┤ Z ├ // └───────┘ └───────┘ - size_t n=1; + size_t n = 1; qc::QuantumComputation qc(n); qc.x(0); qc.z(0); - Decomposer decomposer=Decomposer(n); - const auto& sched = - scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - //TODO: FIgure out i this is always Positive - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(3*qc::PI_2,epsilon))); - + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + // TODO: FIgure out i this is always Positive + EXPECT_THAT( + decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(3 * qc::PI_2, epsilon))); } TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { @@ -258,46 +305,51 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { // q_1: ─┤ Z ├─ // └───────┘ - size_t n=2; + size_t n = 2; qc::QuantumComputation qc(n); qc.x(0); qc.z(1); - Decomposer decomposer=Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 8); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_EQ(decomp[0][1]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][1]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][1]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][1]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][1]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][2]->isCompoundOperation()); EXPECT_TRUE(decomp[0][2]->isGlobal(n)); - EXPECT_EQ(decomp[0][3]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][3]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][3]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][3]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][3]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); EXPECT_TRUE(decomp[0][5]->isCompoundOperation()); EXPECT_TRUE(decomp[0][5]->isGlobal(n)); - EXPECT_EQ(decomp[0][6]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][6]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - - EXPECT_EQ(decomp[0][7]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][7]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][6]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][6]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][6]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); + EXPECT_EQ(decomp[0][7]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][7]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][7]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } TEST_F(DecomposerTest, TwoQubitsTwoLayers) { @@ -308,70 +360,78 @@ TEST_F(DecomposerTest, TwoQubitsTwoLayers) { // q_1: ─────────────■───┤ X ├─ // └───────┘ - size_t n=2; + size_t n = 2; qc::QuantumComputation qc(n); qc.x(0); qc.cz(0, 1); qc.z(0); qc.x(1); - Decomposer decomposer=Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),2); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 2); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[1].size(), 8); - //Layer 1 - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + // Layer 1 + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - //Layer 2 + // Layer 2 - EXPECT_EQ(decomp[1][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[1][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_EQ(decomp[1][1]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][1]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[1][1]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][1]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][1]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[1][2]->isCompoundOperation()); EXPECT_TRUE(decomp[1][2]->isGlobal(n)); - EXPECT_EQ(decomp[1][3]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][3]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_EQ(decomp[1][3]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][3]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][3]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); - EXPECT_EQ(decomp[1][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][4]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[1][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][4]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[1][5]->isCompoundOperation()); EXPECT_TRUE(decomp[1][5]->isGlobal(n)); - EXPECT_EQ(decomp[1][6]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][6]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - - EXPECT_EQ(decomp[1][7]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][7]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[1][6]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][6]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][6]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); + EXPECT_EQ(decomp[1][7]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][7]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][7]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } -} // namespace na::zoned \ No newline at end of file +} // namespace na::zoned From 802b829b99458ae1aea19b77e0bd4a7f4778c457 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:13:09 +0100 Subject: [PATCH 006/110] =?UTF-8?q?=F0=9F=8E=A8=20Adjust=20to=20naming=20c?= =?UTF-8?q?onvention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/decomposer/Decomposer.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index c9b6bd8bc..310a560c1 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -19,13 +19,11 @@ namespace na::zoned { class Decomposer : public DecomposerBase { -private: - struct struct_U3 { + struct StructU3 { std::array angles; - int qubit; + qc::Qubit qubit; }; - static inline constexpr qc::fp epsilon = 1e-5; - int N_qubits; + size_t nQubits; public: /** From 20c47a91835a08efd7d9f6e53c20120fac57c671 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:22:14 +0100 Subject: [PATCH 007/110] =?UTF-8?q?=F0=9F=8E=A8=20Rename=20to=20NativeGate?= =?UTF-8?q?Decomposer=20and=20include=20in=20Compiler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/Compiler.hpp | 14 ++++++++++++++ .../{Decomposer.hpp => NativeGateDecomposer.hpp} | 4 ++-- .../{Decomposer.cpp => NativeGateDecomposer.cpp} | 0 test/na/zoned/test_compiler.cpp | 3 +++ ...omposer.cpp => test_native_gate_decomposer.cpp} | 0 5 files changed, 19 insertions(+), 2 deletions(-) rename include/na/zoned/decomposer/{Decomposer.hpp => NativeGateDecomposer.hpp} (97%) rename src/na/zoned/decomposer/{Decomposer.cpp => NativeGateDecomposer.cpp} (100%) rename test/na/zoned/{test_decomposer.cpp => test_native_gate_decomposer.cpp} (100%) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index 1a7bb7c58..f9c084eaa 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -12,6 +12,7 @@ #include "Architecture.hpp" #include "code_generator/CodeGenerator.hpp" +#include "decomposer/NativeGateDecomposer.hpp" #include "decomposer/NoOpDecomposer.hpp" #include "ir/QuantumComputation.hpp" #include "ir/operations/Operation.hpp" @@ -311,4 +312,17 @@ class RoutingAwareCompiler final explicit RoutingAwareCompiler(const Architecture& architecture) : Compiler(architecture) {} }; + +class RoutingAwareNativeGateCompiler final + : public Compiler { +public: + RoutingAwareNativeGateCompiler(const Architecture& architecture, + const Config& config) + : Compiler(architecture, config) {} + + explicit RoutingAwareNativeGateCompiler(const Architecture& architecture) + : Compiler(architecture) {} +}; } // namespace na::zoned diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp similarity index 97% rename from include/na/zoned/decomposer/Decomposer.hpp rename to include/na/zoned/decomposer/NativeGateDecomposer.hpp index 310a560c1..1f453f0e5 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -18,7 +18,7 @@ namespace na::zoned { -class Decomposer : public DecomposerBase { +class NativeGateDecomposer : public DecomposerBase { struct StructU3 { std::array angles; qc::Qubit qubit; @@ -95,7 +95,7 @@ class Decomposer : public DecomposerBase { * Create a new Decomposer. * @param n_qubits is the number of qubits in the circuit to be decomposed */ - Decomposer(int n_qubits); + NativeGateDecomposer(int n_qubits); [[nodiscard]] auto decompose( const std::vector& singleQubitGateLayers) const diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp similarity index 100% rename from src/na/zoned/decomposer/Decomposer.cpp rename to src/na/zoned/decomposer/NativeGateDecomposer.cpp diff --git a/test/na/zoned/test_compiler.cpp b/test/na/zoned/test_compiler.cpp index 1dad1696e..5a6f9ba91 100644 --- a/test/na/zoned/test_compiler.cpp +++ b/test/na/zoned/test_compiler.cpp @@ -185,6 +185,9 @@ COMPILER_TEST(RelaxedRoutingAwareCompiler, RoutingAwareCompiler, relaxedRoutingAwareConfiguration); COMPILER_TEST(FastRelaxedRoutingAwareCompiler, RoutingAwareCompiler, fastRelaxedRoutingAwareConfiguration); +COMPILER_TEST(FastRelaxedRoutingAwareNativeGateCompiler, + RoutingAwareNativeGateCompiler, + fastRelaxedRoutingAwareConfiguration); // Tests that the bug described in issue // https://github.com/munich-quantum-toolkit/qmap/issues/727 is fixed. diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp similarity index 100% rename from test/na/zoned/test_decomposer.cpp rename to test/na/zoned/test_native_gate_decomposer.cpp From 8fac867ba527a78b890836ff913b0e3c7a0464f3 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:27:28 +0100 Subject: [PATCH 008/110] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20newly=20introduced?= =?UTF-8?q?=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 5 +++- .../zoned/decomposer/NativeGateDecomposer.cpp | 29 ++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 1f453f0e5..7b9250d3d 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -23,7 +23,10 @@ class NativeGateDecomposer : public DecomposerBase { std::array angles; qc::Qubit qubit; }; - size_t nQubits; + size_t nQubits_; + + constexpr static qc::fp epsilon = + std::numeric_limits::epsilon() * 1024; public: /** diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index f44761054..8a2d85fe9 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -11,7 +11,7 @@ // // Created by cpsch on 11.12.2025. // -#include "na/zoned/decomposer/decomposer.hpp" +#include "na/zoned/decomposer/NativeGateDecomposer.hpp" // #include "ir/operations/StandardOperation.hpp" #include "ir/operations/CompoundOperation.hpp" @@ -20,9 +20,11 @@ #include namespace na::zoned { -Decomposer::Decomposer(int n_qubits) { N_qubits = n_qubits; }; +NativeGateDecomposer::NativeGateDecomposer(int n_qubits) { + nQubits_ = n_qubits; +}; -auto Decomposer::convert_gate_to_quaternion( +auto NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper op) -> std::array { assert(op.get().getNqubits() == 1); std::array quat{}; @@ -95,8 +97,8 @@ auto Decomposer::convert_gate_to_quaternion( return quat; } -auto Decomposer::combine_quaternions(const std::array& q1, - const std::array& q2) +auto NativeGateDecomposer::combine_quaternions(const std::array& q1, + const std::array& q2) -> std::array { std::array new_quat{}; new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; @@ -106,7 +108,7 @@ auto Decomposer::combine_quaternions(const std::array& q1, return new_quat; } -auto Decomposer::get_U3_angles_from_quaternion( +auto NativeGateDecomposer::get_U3_angles_from_quaternion( const std::array& quat) -> std::array { // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be // defined @@ -141,7 +143,8 @@ auto Decomposer::get_U3_angles_from_quaternion( return {theta, phi, lambda}; } -auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { +auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) + -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { if (abs(gate.angles[0]) > theta_max) { @@ -150,14 +153,14 @@ auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { } return theta_max; } -auto Decomposer::transform_to_U3( +auto NativeGateDecomposer::transform_to_U3( const std::vector& layers) const -> std::vector> { // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( - this->N_qubits); + this->nQubits_); std::vector new_layer; for (auto gate : layer) { gates[gate.get().getTargets().front()].push_back(gate); @@ -179,8 +182,8 @@ auto Decomposer::transform_to_U3( } return new_layers; } -auto Decomposer::get_decomposition_angles(const std::array& angles, - qc::fp theta_max) +auto NativeGateDecomposer::get_decomposition_angles( + const std::array& angles, qc::fp theta_max) -> std::array { qc::fp alpha, chi, beta; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, @@ -206,7 +209,7 @@ auto Decomposer::get_decomposition_angles(const std::array& angles, return {chi, gamma_minus, gamma_plus}; } -auto Decomposer::decompose( +auto NativeGateDecomposer::decompose( const std::vector& singleQubitGateLayers) const -> std::vector { @@ -244,7 +247,7 @@ auto Decomposer::decompose( std::vector> GR_plus; std::vector> GR_minus; - for (auto i = 0; i < this->N_qubits; ++i) { + for (auto i = 0; i < this->nQubits_; ++i) { GR_plus.emplace_back( new qc::StandardOperation(i, qc::RY, {theta_max / 2})); GR_minus.emplace_back( From 59fcb5e72e346aaf4d1e9a98025874f8f3ce295e Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:43:51 +0100 Subject: [PATCH 009/110] =?UTF-8?q?=F0=9F=8E=A8=20Add=20nQubits=20to=20dec?= =?UTF-8?q?ompose=20interface=20and=20fix=20resulting=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../na/zoned/decomposer/DecomposerBase.hpp | 6 +- .../zoned/decomposer/NativeGateDecomposer.hpp | 30 ++++++---- .../na/zoned/decomposer/NoOpDecomposer.hpp | 16 ++--- .../zoned/decomposer/NativeGateDecomposer.cpp | 19 +++--- src/na/zoned/decomposer/NoOpDecomposer.cpp | 3 +- test/na/zoned/test_native_gate_decomposer.cpp | 59 +++++++++---------- 6 files changed, 69 insertions(+), 64 deletions(-) diff --git a/include/na/zoned/decomposer/DecomposerBase.hpp b/include/na/zoned/decomposer/DecomposerBase.hpp index 997dd095a..7713f5f48 100644 --- a/include/na/zoned/decomposer/DecomposerBase.hpp +++ b/include/na/zoned/decomposer/DecomposerBase.hpp @@ -24,12 +24,14 @@ class DecomposerBase { virtual ~DecomposerBase() = default; /** * This function defines the interface of the decomposer. + * @param nQubits is the number of qubits in the quantum computation. * @param singleQubitGateLayers are the layers of single-qubit gates that are * meant to be first decomposed into the native gate set. * @return the new single-qubit gate layers */ - [[nodiscard]] virtual auto decompose( - const std::vector& singleQubitGateLayers) const + [[nodiscard]] virtual auto + decompose(size_t nQubits, + const std::vector& singleQubitGateLayers) -> std::vector = 0; }; } // namespace na::zoned diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 7b9250d3d..118605a1f 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -23,12 +23,26 @@ class NativeGateDecomposer : public DecomposerBase { std::array angles; qc::Qubit qubit; }; - size_t nQubits_; + size_t nQubits_ = 0; constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; public: + /// The configuration of the NativeGateDecomposer + struct Config { + template + friend void to_json(BasicJsonType& /* unused */, + const Config& /* unused */) {} + template + friend void from_json(const BasicJsonType& /* unused */, + Config& /* unused */) {} + }; + + /// Create a new NativeGateDecomposer. + NativeGateDecomposer(const Architecture& /* unused */, + const Config& /* unused */) {} + /** * Converts commonly used single qubit gates into their Quaternion * representation @@ -67,7 +81,7 @@ class NativeGateDecomposer : public DecomposerBase { * @param layer is a SingleQubitGateLayers of a scheduled * @returns the maximal value of theta in the given layer */ - static auto calc_theta_max(const std::vector& layer) -> qc::fp; + static auto calc_theta_max(const std::vector& layer) -> qc::fp; /** * Takes a vector of SingleQubitGateLayer's and, for each layer @@ -80,7 +94,7 @@ class NativeGateDecomposer : public DecomposerBase { */ [[nodiscard]] auto transform_to_U3(const std::vector& layers) const - -> std::vector>; + -> std::vector>; /** * Takes a vector of qc::fp's representing the U3-Gate angles of a single * qubit hate and the maximal value of theta for the single qubit gate layer @@ -94,14 +108,10 @@ class NativeGateDecomposer : public DecomposerBase { auto static get_decomposition_angles(const std::array& angles, qc::fp theta_max) -> std::array; - /** - * Create a new Decomposer. - * @param n_qubits is the number of qubits in the circuit to be decomposed - */ - NativeGateDecomposer(int n_qubits); - [[nodiscard]] auto decompose( - const std::vector& singleQubitGateLayers) const + [[nodiscard]] auto + decompose(size_t nQubits, + const std::vector& singleQubitGateLayers) -> std::vector override; }; diff --git a/include/na/zoned/decomposer/NoOpDecomposer.hpp b/include/na/zoned/decomposer/NoOpDecomposer.hpp index 65b8c4f07..2942195d3 100644 --- a/include/na/zoned/decomposer/NoOpDecomposer.hpp +++ b/include/na/zoned/decomposer/NoOpDecomposer.hpp @@ -27,17 +27,10 @@ class NoOpDecomposer : public DecomposerBase { public: /// The configuration of the NoOpDecomposer struct Config { - template < - typename BasicJsonType, - nlohmann::detail::enable_if_t< - nlohmann::detail::is_basic_json::value, int> = 0> + template friend void to_json(BasicJsonType& /* unused */, const Config& /* unused */) {} - - template < - typename BasicJsonType, - nlohmann::detail::enable_if_t< - nlohmann::detail::is_basic_json::value, int> = 0> + template friend void from_json(const BasicJsonType& /* unused */, Config& /* unused */) {} }; @@ -48,8 +41,9 @@ class NoOpDecomposer : public DecomposerBase { NoOpDecomposer(const Architecture& /* unused */, const Config& /* unused */) { } - [[nodiscard]] auto decompose( - const std::vector& singleQubitGateLayers) const + [[nodiscard]] auto + decompose(size_t nQubits, + const std::vector& singleQubitGateLayers) -> std::vector override; }; } // namespace na::zoned diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 8a2d85fe9..24833d402 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -20,9 +20,6 @@ #include namespace na::zoned { -NativeGateDecomposer::NativeGateDecomposer(int n_qubits) { - nQubits_ = n_qubits; -}; auto NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper op) -> std::array { @@ -143,7 +140,7 @@ auto NativeGateDecomposer::get_U3_angles_from_quaternion( return {theta, phi, lambda}; } -auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) +auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { @@ -155,13 +152,13 @@ auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) } auto NativeGateDecomposer::transform_to_U3( const std::vector& layers) const - -> std::vector> { + -> std::vector> { // auto u=struct_U3({0,0,0},0); - std::vector> new_layers; + std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( this->nQubits_); - std::vector new_layer; + std::vector new_layer; for (auto gate : layer) { gates[gate.get().getTargets().front()].push_back(gate); } @@ -175,7 +172,7 @@ auto NativeGateDecomposer::transform_to_U3( } std::array angles = get_U3_angles_from_quaternion(quat); new_layer.emplace_back( - struct_U3(angles, qubit_gates[0].get().getTargets().front())); + StructU3(angles, qubit_gates[0].get().getTargets().front())); } } new_layers.push_back(new_layer); @@ -210,10 +207,12 @@ auto NativeGateDecomposer::get_decomposition_angles( } auto NativeGateDecomposer::decompose( - const std::vector& singleQubitGateLayers) const + const size_t nQubits, + const std::vector& singleQubitGateLayers) -> std::vector { + nQubits_ = nQubits; - std::vector> U3Layers = + std::vector> U3Layers = transform_to_U3(singleQubitGateLayers); std::vector NewSingleQubitLayers = std::vector{}; diff --git a/src/na/zoned/decomposer/NoOpDecomposer.cpp b/src/na/zoned/decomposer/NoOpDecomposer.cpp index 6c8ae3973..8dd5684f3 100644 --- a/src/na/zoned/decomposer/NoOpDecomposer.cpp +++ b/src/na/zoned/decomposer/NoOpDecomposer.cpp @@ -18,7 +18,8 @@ namespace na::zoned { auto NoOpDecomposer::decompose( - const std::vector& singleQubitGateLayers) const + size_t /* unused */, + const std::vector& singleQubitGateLayers) -> std::vector { std::vector result; result.reserve(singleQubitGateLayers.size()); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index f2ed429c7..428500b04 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -13,7 +13,7 @@ // #include "ir/QuantumComputation.hpp" -#include "na/zoned/decomposer/Decomposer.hpp" +#include "na/zoned/decomposer/NativeGateDecomposer.hpp" #include "na/zoned/scheduler/ASAPScheduler.hpp" #include @@ -46,13 +46,15 @@ constexpr std::string_view architectureJson = R"({ class DecomposerTest : public ::testing::Test { protected: - Decomposer decomposer = Decomposer(4); Architecture architecture; - ASAPScheduler::Config config{.maxFillingFactor = .8}; + ASAPScheduler::Config schedulerConfig{.maxFillingFactor = .8}; ASAPScheduler scheduler; + NativeGateDecomposer::Config decomposerConfig{}; + NativeGateDecomposer decomposer; DecomposerTest() : architecture(Architecture::fromJSONString(architectureJson)), - scheduler(architecture, config) {} + scheduler(architecture, schedulerConfig), + decomposer(architecture, decomposerConfig) {} }; qc::fp epsilon = 1e-5; @@ -60,14 +62,15 @@ qc::fp epsilon = 1e-5; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; - std::array q12 = Decomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), ::testing::DoubleNear(0, epsilon))); std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; - std::array q13 = Decomposer::combine_quaternions(q12, q3); + std::array q13 = + NativeGateDecomposer::combine_quaternions(q12, q3); EXPECT_THAT( q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), @@ -78,14 +81,15 @@ TEST(Test, ThreeQuaternionCombiTest) { TEST(Test, ThreeQuaternionU3Test) { std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; - std::array q12 = Decomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - std::array q13 = Decomposer::combine_quaternions(q12, q3); + std::array q13 = + NativeGateDecomposer::combine_quaternions(q12, q3); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), @@ -100,10 +104,10 @@ TEST(Test, SingleXGateAngleTest) { qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -113,7 +117,7 @@ TEST(Test, SingleU3GateAngleTest) { size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre( @@ -122,7 +126,7 @@ TEST(Test, SingleU3GateAngleTest) { ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q), + EXPECT_THAT(NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -132,7 +136,7 @@ TEST(Test, ThetaPiAngleTest) { size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), @@ -140,7 +144,7 @@ TEST(Test, ThetaPiAngleTest) { ::testing::DoubleNear(r2, epsilon), ::testing::DoubleNear(0, epsilon))); EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); @@ -150,7 +154,7 @@ TEST(Test, ThetaZeroAngleTest) { size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), @@ -159,7 +163,7 @@ TEST(Test, ThetaZeroAngleTest) { ::testing::DoubleNear(r2, epsilon))); EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(3 * qc::PI_2, epsilon))); @@ -168,7 +172,7 @@ TEST(Test, ThetaZeroAngleTest) { TEST(Test, RXDecompositionTest) { size_t n = 1; std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; - EXPECT_THAT(Decomposer::get_decomposition_angles(rx, qc::PI), + EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(rx, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); @@ -179,7 +183,7 @@ TEST(Test, U3DecompositionTest) { std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! EXPECT_THAT( - Decomposer::get_decomposition_angles(u3, qc::PI_4), + NativeGateDecomposer::get_decomposition_angles(u3, qc::PI_4), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-qc::PI_2, epsilon))); @@ -189,11 +193,11 @@ TEST(Test, DoubleDecompositionTest) { size_t n = 1; std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; std::array z2 = {0, 0, qc::PI}; - EXPECT_THAT(Decomposer::get_decomposition_angles(x1, qc::PI), + EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(x1, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); - EXPECT_THAT(Decomposer::get_decomposition_angles(z2, qc::PI), + EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(z2, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -206,9 +210,8 @@ TEST_F(DecomposerTest, SingleRXGate) { int n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); @@ -236,9 +239,8 @@ TEST_F(DecomposerTest, SingleU3Gate) { int n = 1; qc::QuantumComputation qc(n); qc.u(0.0, qc::PI, qc::PI_2, 0); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); @@ -271,9 +273,8 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { qc::QuantumComputation qc(n); qc.x(0); qc.z(0); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); @@ -309,9 +310,8 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { qc::QuantumComputation qc(n); qc.x(0); qc.z(1); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 8); @@ -366,9 +366,8 @@ TEST_F(DecomposerTest, TwoQubitsTwoLayers) { qc.cz(0, 1); qc.z(0); qc.x(1); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 2); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[1].size(), 8); From 8933446445455dc931d6a9439d0a9ca97a13ceb4 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:47:16 +0100 Subject: [PATCH 010/110] =?UTF-8?q?=F0=9F=8E=A8=20Improve=20docstring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../na/zoned/decomposer/NativeGateDecomposer.hpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 118605a1f..16fc7189c 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -44,13 +44,15 @@ class NativeGateDecomposer : public DecomposerBase { const Config& /* unused */) {} /** - * Converts commonly used single qubit gates into their Quaternion - * representation - * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) - * with X,Y,Z Pauli Matrices + * @brief Converts commonly used single qubit gates into their Quaternion + * representation. + * @details A single qubit gate R_v(phi) with rotation axis v=(v0,v1,v2) + * and rotation angle phi can be represented as a quaternion: + * @code quaternion(R_v(phi)) = (cos(phi/2) * I, v0 * sin(phi/2) * X, v1 * + * sin(phi/2) * Y, v2 * sin(phi/2) * Z)@endcode with X, Y, Z Pauli Matrices. * @param op a reference_wrapper to the operation to be converted - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the - * components of the quaternion + * @returns an array of four `qc::fp` values `{q0, q1, q2, q3}` denoting the + * components of the quaternion. */ static auto convert_gate_to_quaternion(std::reference_wrapper op) From 2931f5dbfebece1f8deea294998adf0f3b1c8500 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:56:42 +0100 Subject: [PATCH 011/110] =?UTF-8?q?=F0=9F=8E=A8=20Improve=20docstrings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 16fc7189c..effedb6dc 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -19,10 +19,19 @@ namespace na::zoned { class NativeGateDecomposer : public DecomposerBase { + /** + * A minimal struct to store the parameters of a U3 gate along with the qubit + * it acts on. + */ struct StructU3 { std::array angles; qc::Qubit qubit; }; + /** + * A quaternion is represented by an array of four `qc::fp` values `{q0, q1, + * q2, q3}` denoting the components of the quaternion. + */ + using Quaternion = std::array; size_t nQubits_ = 0; constexpr static qc::fp epsilon = @@ -51,61 +60,61 @@ class NativeGateDecomposer : public DecomposerBase { * @code quaternion(R_v(phi)) = (cos(phi/2) * I, v0 * sin(phi/2) * X, v1 * * sin(phi/2) * Y, v2 * sin(phi/2) * Z)@endcode with X, Y, Z Pauli Matrices. * @param op a reference_wrapper to the operation to be converted - * @returns an array of four `qc::fp` values `{q0, q1, q2, q3}` denoting the - * components of the quaternion. + * @returns a quaternion. */ static auto convert_gate_to_quaternion(std::reference_wrapper op) - -> std::array; + -> Quaternion; /** - * Merges the quaternions representing two gates as in a Matrix multiplication - * of the gates - * @param q1 the first Quaternion to be combined - * @param q2 the second Quaternion to be combined - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the - * components of the combined quaternion + * @brief Merges the quaternions representing two gates as in a matrix + * multiplication of the gates. + * @param q1 the first quaternion to be combined. + * @param q2 the second quaternion to be combined. + * @returns an quaternion. */ - static auto combine_quaternions(const std::array& q1, - const std::array& q2) - -> std::array; + static auto combine_quaternions(const Quaternion& q1, const Quaternion& q2) + -> Quaternion; /** - * Calculates the values of the U3-Gate parameters theta, phi and lambda - * @param quat is a quaternion representing a single qubit gate - * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ - * gate angles + * @brief Calculates the values of the U3-gate parameters theta, phi, and + * lambda. + * @param quat is a quaternion representing a single qubit gate. + * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving + * the U3 gate angles. */ - static auto get_U3_angles_from_quaternion(const std::array& quat) + static auto get_U3_angles_from_quaternion(const Quaternion& quat) -> std::array; /** - * Calculates the largest value of the U3-Gate parameter theta from a vector - * of Operations. Fails when provided gates aren't all U3-Gates. - * @param layer is a SingleQubitGateLayers of a scheduled - * @returns the maximal value of theta in the given layer + * @brief Calculates the largest value of the U3-gate parameter theta from a + * vector of operations. + * @param layer is a vector of U3 parameters. + * @returns the maximal value of theta in the given layer. */ static auto calc_theta_max(const std::vector& layer) -> qc::fp; /** - * Takes a vector of SingleQubitGateLayer's and, for each layer - * , transforms all gates into U3 gates represented by struct_U3's - * , combining all gates acting on the same qubit into a single U3 gate + * @brief Takes a vector of SingleQubitGateLayers and, for each layer, + * transforms all gates into U3 gates represented by `StructU3` objects. + * @details It combines all gates acting on the same qubit into a single U3 + * gate. * @param layers is a std::vector of SingleQubitGateLayers of a scheduled - * circuit - * @returns a vector of vectors of a struct_U3's representing the single qubit - * gate layers + * circuit. + * @returns a vector of vectors of StructU3 objects representing the single + * qubit gate layers. */ [[nodiscard]] auto transform_to_U3(const std::vector& layers) const -> std::vector>; /** - * Takes a vector of qc::fp's representing the U3-Gate angles of a single - * qubit hate and the maximal value of theta for the single qubit gate layer - * and calculates the transversal decomposition angles as in Nottingham et. - * al. 2024 - * @param angles is a std::array of qc::fp representing (theta,phi, lambda) - * @param theta_max the maximal theta value of the single-qubit qate layer - * @returns an array of qc::fp values giving the angles (chi, gamma_minus, - * gamma_plus) + * @brief Takes a vector of `qc::fp` representing the U3-gate angles of a + * single-qubit gate and the maximal value of theta for the single qubit gate + * layer and calculates the transversal decomposition angles as in Nottingham + * et. al. 2024. + * @param angles is a `std::array` of `qc::fp` representing (theta, phi, + * lambda). + * @param theta_max the maximal theta value of the single-qubit qate layer. + * @returns an array of `qc::fp` values giving the angles (chi, gamma_minus, + * gamma_plus). */ auto static get_decomposition_angles(const std::array& angles, qc::fp theta_max) From b789b03920ddc1df21a35b2f567aa969015ffb07 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 3 Feb 2026 18:01:57 +0100 Subject: [PATCH 012/110] Fixed errors translating gates into Quaternions Small fixes --- .../zoned/decomposer/NativeGateDecomposer.hpp | 14 ++-- .../zoned/decomposer/NativeGateDecomposer.cpp | 76 +++++++++---------- test/na/zoned/test_native_gate_decomposer.cpp | 42 +++++----- 3 files changed, 60 insertions(+), 72 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index effedb6dc..c2cd5bd5c 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -63,7 +63,7 @@ class NativeGateDecomposer : public DecomposerBase { * @returns a quaternion. */ static auto - convert_gate_to_quaternion(std::reference_wrapper op) + convertGateToQuaternion(std::reference_wrapper op) -> Quaternion; /** * @brief Merges the quaternions representing two gates as in a matrix @@ -72,7 +72,7 @@ class NativeGateDecomposer : public DecomposerBase { * @param q2 the second quaternion to be combined. * @returns an quaternion. */ - static auto combine_quaternions(const Quaternion& q1, const Quaternion& q2) + static auto combineQuaternions(const Quaternion& q1, const Quaternion& q2) -> Quaternion; /** * @brief Calculates the values of the U3-gate parameters theta, phi, and @@ -81,7 +81,7 @@ class NativeGateDecomposer : public DecomposerBase { * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving * the U3 gate angles. */ - static auto get_U3_angles_from_quaternion(const Quaternion& quat) + static auto getU3AnglesFromQuaternion(const Quaternion& quat) -> std::array; /** @@ -90,7 +90,7 @@ class NativeGateDecomposer : public DecomposerBase { * @param layer is a vector of U3 parameters. * @returns the maximal value of theta in the given layer. */ - static auto calc_theta_max(const std::vector& layer) -> qc::fp; + static auto calcThetaMax(const std::vector& layer) -> qc::fp; /** * @brief Takes a vector of SingleQubitGateLayers and, for each layer, @@ -103,7 +103,7 @@ class NativeGateDecomposer : public DecomposerBase { * qubit gate layers. */ [[nodiscard]] auto - transform_to_U3(const std::vector& layers) const + transformToU3(const std::vector& layers) const -> std::vector>; /** * @brief Takes a vector of `qc::fp` representing the U3-gate angles of a @@ -112,11 +112,11 @@ class NativeGateDecomposer : public DecomposerBase { * et. al. 2024. * @param angles is a `std::array` of `qc::fp` representing (theta, phi, * lambda). - * @param theta_max the maximal theta value of the single-qubit qate layer. + * @param theta_max the maximal theta value of the single-qubit gate layer. * @returns an array of `qc::fp` values giving the angles (chi, gamma_minus, * gamma_plus). */ - auto static get_decomposition_angles(const std::array& angles, + auto static getDecompositionAngles(const std::array& angles, qc::fp theta_max) -> std::array; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 24833d402..28eab666b 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -21,14 +21,13 @@ namespace na::zoned { -auto NativeGateDecomposer::convert_gate_to_quaternion( - std::reference_wrapper op) -> std::array { +auto NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper op) -> Quaternion { assert(op.get().getNqubits() == 1); - std::array quat{}; - // TODO: Phase? + Quaternion quat{}; if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front()), 0, 0, - sin(op.get().getParameter().front())}; + quat = {cos(op.get().getParameter().front()/2), 0, 0, + sin(op.get().getParameter().front()/2)}; } else if (op.get().getType() == qc::Z) { quat = {0, 0, 0, 1}; } else if (op.get().getType() == qc::S) { @@ -40,16 +39,16 @@ auto NativeGateDecomposer::convert_gate_to_quaternion( } else if (op.get().getType() == qc::Tdg) { quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; } else if (op.get().getType() == qc::U) { - quat = combine_quaternions( - combine_quaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, + quat = combineQuaternions( + combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}, {cos(op.get().getParameter().front() / 2), 0, sin(op.get().getParameter().front() / 2), 0}), {cos(op.get().getParameter().at(2) / 2), 0, 0, sin(op.get().getParameter().at(2) / 2)}); } else if (op.get().getType() == qc::U2) { - quat = combine_quaternions( - combine_quaternions({cos(op.get().getParameter().front() / 2), 0, 0, + quat = combineQuaternions( + combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, sin(op.get().getParameter().front() / 2)}, {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, @@ -61,26 +60,26 @@ auto NativeGateDecomposer::convert_gate_to_quaternion( quat = {cos(op.get().getParameter().front() / 2), 0, sin(op.get().getParameter().front() / 2), 0}; } else if (op.get().getType() == qc::H) { - quat = combine_quaternions( - combine_quaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + quat = combineQuaternions( + combineQuaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); } else if (op.get().getType() == qc::X) { quat = {0, 1, 0, 0}; } else if (op.get().getType() == qc::Y) { - quat = {0, 1, 0, 0}; + quat = {0, 0, 1, 0}; } else if (op.get().getType() == qc::Vdg) { - quat = combine_quaternions( - combine_quaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, + quat = combineQuaternions( + combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); } else if (op.get().getType() == qc::SX) { - quat = combine_quaternions( - combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + quat = combineQuaternions( + combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { - quat = combine_quaternions( - combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + quat = combineQuaternions( + combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else { @@ -94,10 +93,10 @@ auto NativeGateDecomposer::convert_gate_to_quaternion( return quat; } -auto NativeGateDecomposer::combine_quaternions(const std::array& q1, - const std::array& q2) - -> std::array { - std::array new_quat{}; +auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, + const Quaternion& q2) + -> Quaternion { + Quaternion new_quat{}; new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; @@ -105,10 +104,8 @@ auto NativeGateDecomposer::combine_quaternions(const std::array& q1, return new_quat; } -auto NativeGateDecomposer::get_U3_angles_from_quaternion( - const std::array& quat) -> std::array { - // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be - // defined +auto NativeGateDecomposer::getU3AnglesFromQuaternion( + const Quaternion& quat) -> std::array { qc::fp theta; qc::fp phi; qc::fp lambda; @@ -140,7 +137,7 @@ auto NativeGateDecomposer::get_U3_angles_from_quaternion( return {theta, phi, lambda}; } -auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) +auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { @@ -150,10 +147,9 @@ auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) } return theta_max; } -auto NativeGateDecomposer::transform_to_U3( +auto NativeGateDecomposer::transformToU3( const std::vector& layers) const -> std::vector> { - // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( @@ -165,12 +161,12 @@ auto NativeGateDecomposer::transform_to_U3( for (auto qubit_gates : gates) { if (!qubit_gates.empty()) { - std::array quat = convert_gate_to_quaternion(qubit_gates[0]); + std::array quat = convertGateToQuaternion(qubit_gates[0]); for (auto i = 1; i < qubit_gates.size(); i++) { - quat = combine_quaternions( - quat, convert_gate_to_quaternion(qubit_gates[i])); + quat = combineQuaternions( + quat, convertGateToQuaternion(qubit_gates[i])); } - std::array angles = get_U3_angles_from_quaternion(quat); + std::array angles = getU3AnglesFromQuaternion(quat); new_layer.emplace_back( StructU3(angles, qubit_gates[0].get().getTargets().front())); } @@ -179,10 +175,10 @@ auto NativeGateDecomposer::transform_to_U3( } return new_layers; } -auto NativeGateDecomposer::get_decomposition_angles( +auto NativeGateDecomposer::getDecompositionAngles( const std::array& angles, qc::fp theta_max) -> std::array { - qc::fp alpha, chi, beta; + qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) if (abs(angles[0] - theta_max) < epsilon) { @@ -199,7 +195,7 @@ auto NativeGateDecomposer::get_decomposition_angles( alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } - beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; + qc::fp beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; qc::fp gamma_plus = fmod(angles[2] - (alpha + beta), qc::TAU); qc::fp gamma_minus = fmod(angles[1] - (alpha - beta), qc::TAU); @@ -213,12 +209,12 @@ auto NativeGateDecomposer::decompose( nQubits_ = nQubits; std::vector> U3Layers = - transform_to_U3(singleQubitGateLayers); + transformToU3(singleQubitGateLayers); std::vector NewSingleQubitLayers = std::vector{}; for (const auto& layer : U3Layers) { - qc::fp theta_max = calc_theta_max(layer); + qc::fp theta_max = calcThetaMax(layer); SingleQubitGateLayer FrontLayer; SingleQubitGateLayer MidLayer; SingleQubitGateLayer BackLayer; @@ -226,7 +222,7 @@ auto NativeGateDecomposer::decompose( for (auto gate : layer) { std::array decomp_angles = - get_decomposition_angles(gate.angles, theta_max); + getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 428500b04..0d807cf03 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -62,7 +62,7 @@ qc::fp epsilon = 1e-5; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; - std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combineQuaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), @@ -70,7 +70,7 @@ TEST(Test, ThreeQuaternionCombiTest) { ::testing::DoubleNear(0, epsilon))); std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; std::array q13 = - NativeGateDecomposer::combine_quaternions(q12, q3); + NativeGateDecomposer::combineQuaternions(q12, q3); EXPECT_THAT( q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), @@ -81,7 +81,7 @@ TEST(Test, ThreeQuaternionCombiTest) { TEST(Test, ThreeQuaternionU3Test) { std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; - std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combineQuaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), @@ -89,7 +89,7 @@ TEST(Test, ThreeQuaternionU3Test) { ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q13 = - NativeGateDecomposer::combine_quaternions(q12, q3); + NativeGateDecomposer::combineQuaternions(q12, q3); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), @@ -99,25 +99,23 @@ TEST(Test, ThreeQuaternionU3Test) { } TEST(Test, SingleXGateAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::X); - qc::QuantumComputation qc(n); + qc::QuantumComputation qc(1); qc.rx(qc::PI, 0); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); EXPECT_THAT( - NativeGateDecomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, SingleU3GateAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre( @@ -126,17 +124,16 @@ TEST(Test, SingleU3GateAngleTest) { ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); - EXPECT_THAT(NativeGateDecomposer::get_U3_angles_from_quaternion(q), + EXPECT_THAT(NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, ThetaPiAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), @@ -144,17 +141,16 @@ TEST(Test, ThetaPiAngleTest) { ::testing::DoubleNear(r2, epsilon), ::testing::DoubleNear(0, epsilon))); EXPECT_THAT( - NativeGateDecomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); } TEST(Test, ThetaZeroAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), @@ -163,41 +159,38 @@ TEST(Test, ThetaZeroAngleTest) { ::testing::DoubleNear(r2, epsilon))); EXPECT_THAT( - NativeGateDecomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(3 * qc::PI_2, epsilon))); } TEST(Test, RXDecompositionTest) { - size_t n = 1; std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; - EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(rx, qc::PI), + EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(rx, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); } TEST(Test, U3DecompositionTest) { - size_t n = 1; std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! EXPECT_THAT( - NativeGateDecomposer::get_decomposition_angles(u3, qc::PI_4), + NativeGateDecomposer::getDecompositionAngles(u3, qc::PI_4), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-qc::PI_2, epsilon))); } TEST(Test, DoubleDecompositionTest) { - size_t n = 1; std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; std::array z2 = {0, 0, qc::PI}; - EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(x1, qc::PI), + EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(x1, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); - EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(z2, qc::PI), + EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(z2, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -292,7 +285,6 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { EXPECT_TRUE(decomp[0][3]->isGlobal(n)); EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - // TODO: FIgure out i this is always Positive EXPECT_THAT( decomp[0][4]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(3 * qc::PI_2, epsilon))); From f93ed5e04103164df41903eab82396fb277d371b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 17:02:48 +0000 Subject: [PATCH 013/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 3 +- .../zoned/decomposer/NativeGateDecomposer.cpp | 30 +++++++++---------- test/na/zoned/test_native_gate_decomposer.cpp | 6 ++-- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index c2cd5bd5c..a81cca4e4 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -117,8 +117,7 @@ class NativeGateDecomposer : public DecomposerBase { * gamma_plus). */ auto static getDecompositionAngles(const std::array& angles, - qc::fp theta_max) - -> std::array; + qc::fp theta_max) -> std::array; [[nodiscard]] auto decompose(size_t nQubits, diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 28eab666b..e8c71e3b2 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -26,8 +26,8 @@ auto NativeGateDecomposer::convertGateToQuaternion( assert(op.get().getNqubits() == 1); Quaternion quat{}; if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front()/2), 0, 0, - sin(op.get().getParameter().front()/2)}; + quat = {cos(op.get().getParameter().front() / 2), 0, 0, + sin(op.get().getParameter().front() / 2)}; } else if (op.get().getType() == qc::Z) { quat = {0, 0, 0, 1}; } else if (op.get().getType() == qc::S) { @@ -41,16 +41,16 @@ auto NativeGateDecomposer::convertGateToQuaternion( } else if (op.get().getType() == qc::U) { quat = combineQuaternions( combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, - sin(op.get().getParameter().at(1) / 2)}, - {cos(op.get().getParameter().front() / 2), 0, - sin(op.get().getParameter().front() / 2), 0}), + sin(op.get().getParameter().at(1) / 2)}, + {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}), {cos(op.get().getParameter().at(2) / 2), 0, 0, sin(op.get().getParameter().at(2) / 2)}); } else if (op.get().getType() == qc::U2) { quat = combineQuaternions( combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, - sin(op.get().getParameter().front() / 2)}, - {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), + sin(op.get().getParameter().front() / 2)}, + {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}); } else if (op.get().getType() == qc::RX) { @@ -70,17 +70,17 @@ auto NativeGateDecomposer::convertGateToQuaternion( } else if (op.get().getType() == qc::Vdg) { quat = combineQuaternions( combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); } else if (op.get().getType() == qc::SX) { quat = combineQuaternions( combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { quat = combineQuaternions( combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else { // if the gate type is not recognized, an error is printed and the @@ -94,7 +94,7 @@ auto NativeGateDecomposer::convertGateToQuaternion( } auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, - const Quaternion& q2) + const Quaternion& q2) -> Quaternion { Quaternion new_quat{}; new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; @@ -104,8 +104,8 @@ auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, return new_quat; } -auto NativeGateDecomposer::getU3AnglesFromQuaternion( - const Quaternion& quat) -> std::array { +auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) + -> std::array { qc::fp theta; qc::fp phi; qc::fp lambda; @@ -163,8 +163,8 @@ auto NativeGateDecomposer::transformToU3( if (!qubit_gates.empty()) { std::array quat = convertGateToQuaternion(qubit_gates[0]); for (auto i = 1; i < qubit_gates.size(); i++) { - quat = combineQuaternions( - quat, convertGateToQuaternion(qubit_gates[i])); + quat = + combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); } std::array angles = getU3AnglesFromQuaternion(quat); new_layer.emplace_back( diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 0d807cf03..821a72fe8 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -69,8 +69,7 @@ TEST(Test, ThreeQuaternionCombiTest) { ::testing::DoubleNear(cos(qc::PI_4), epsilon), ::testing::DoubleNear(0, epsilon))); std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; - std::array q13 = - NativeGateDecomposer::combineQuaternions(q12, q3); + std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); EXPECT_THAT( q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), @@ -88,8 +87,7 @@ TEST(Test, ThreeQuaternionU3Test) { ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - std::array q13 = - NativeGateDecomposer::combineQuaternions(q12, q3); + std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), From b5c499d68d10d4aa5a904b86c2f8302cb2870f9f Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 5 Feb 2026 14:12:59 +0100 Subject: [PATCH 014/110] Fixed errors translating gates into Quaternions Small fixes --- include/na/zoned/Compiler.hpp | 4 ++-- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index f9c084eaa..4a66f01ed 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -204,7 +204,7 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Decomposing..."); const auto decomposingStart = std::chrono::system_clock::now(); const auto& decomposedSingleQubitGateLayers = - SELF.decompose(singleQubitGateLayers); + SELF.decompose(qComp.getNqubits(), singleQubitGateLayers); const auto decomposingEnd = std::chrono::system_clock::now(); statistics_.decomposingTime = std::chrono::duration_cast(decomposingEnd - @@ -314,7 +314,7 @@ class RoutingAwareCompiler final }; class RoutingAwareNativeGateCompiler final - : public Compiler { public: diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 28eab666b..c5be54bbc 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -242,7 +242,7 @@ auto NativeGateDecomposer::decompose( std::vector> GR_plus; std::vector> GR_minus; - for (auto i = 0; i < this->nQubits_; ++i) { + for (size_t i = 0; i < this->nQubits_; ++i) { GR_plus.emplace_back( new qc::StandardOperation(i, qc::RY, {theta_max / 2})); GR_minus.emplace_back( From 31e85de783e65bb20b30f89b6a17a7a680e2571a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:15:24 +0000 Subject: [PATCH 015/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/Compiler.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index 4a66f01ed..ce37b3414 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -314,9 +314,9 @@ class RoutingAwareCompiler final }; class RoutingAwareNativeGateCompiler final - : public Compiler { + : public Compiler { public: RoutingAwareNativeGateCompiler(const Architecture& architecture, const Config& config) From 371ff1fd270fe5b493395a92260dcf79d4b0893e Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sat, 7 Feb 2026 15:59:08 +0100 Subject: [PATCH 016/110] Adressed an outdated Test and some signed/unsigned type issues --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 4 ++-- test/na/zoned/test_native_gate_decomposer.cpp | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 9a441656a..ab479a200 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -162,13 +162,13 @@ auto NativeGateDecomposer::transformToU3( for (auto qubit_gates : gates) { if (!qubit_gates.empty()) { std::array quat = convertGateToQuaternion(qubit_gates[0]); - for (auto i = 1; i < qubit_gates.size(); i++) { + for (size_t i = 1; i < qubit_gates.size(); i++) { quat = combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); } std::array angles = getU3AnglesFromQuaternion(quat); new_layer.emplace_back( - StructU3(angles, qubit_gates[0].get().getTargets().front())); + StructU3{angles, qubit_gates[0].get().getTargets().front()}); } } new_layers.push_back(new_layer); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 821a72fe8..1e3cb2154 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -98,16 +98,13 @@ TEST(Test, ThreeQuaternionU3Test) { TEST(Test, SingleXGateAngleTest) { const qc::Operation* op = new qc::StandardOperation(0, qc::X); - - qc::QuantumComputation qc(1); - qc.rx(qc::PI, 0); std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); EXPECT_THAT( NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(-1 * qc::PI_2, epsilon), - ::testing::DoubleNear(qc::PI_2, epsilon))); + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(qc::PI, epsilon))); } TEST(Test, SingleU3GateAngleTest) { From 309271122c1492d8df1fa071aabadacb8f55064c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 15:00:29 +0000 Subject: [PATCH 017/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/na/zoned/test_native_gate_decomposer.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 1e3cb2154..3b3adaa0f 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -100,11 +100,10 @@ TEST(Test, SingleXGateAngleTest) { const qc::Operation* op = new qc::StandardOperation(0, qc::X); std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); - EXPECT_THAT( - NativeGateDecomposer::getU3AnglesFromQuaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(qc::PI, epsilon))); + EXPECT_THAT(NativeGateDecomposer::getU3AnglesFromQuaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(qc::PI, epsilon))); } TEST(Test, SingleU3GateAngleTest) { From fe4e45c45b2a278e18e055a33c7b9117d3c06b69 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sat, 7 Feb 2026 17:19:59 +0100 Subject: [PATCH 018/110] switched abs with fabs --- .../zoned/decomposer/NativeGateDecomposer.cpp | 23 +++++++++---------- test/na/zoned/test_native_gate_decomposer.cpp | 3 ++- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index ab479a200..5575c746a 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -12,8 +12,6 @@ // Created by cpsch on 11.12.2025. // #include "na/zoned/decomposer/NativeGateDecomposer.hpp" - -// #include "ir/operations/StandardOperation.hpp" #include "ir/operations/CompoundOperation.hpp" #include @@ -50,7 +48,7 @@ auto NativeGateDecomposer::convertGateToQuaternion( quat = combineQuaternions( combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, sin(op.get().getParameter().front() / 2)}, - {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}); } else if (op.get().getType() == qc::RX) { @@ -86,7 +84,7 @@ auto NativeGateDecomposer::convertGateToQuaternion( // if the gate type is not recognized, an error is printed and the // gate is not included in the output. std::ostringstream oss; - oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() << "\n"; throw std::invalid_argument(oss.str()); } @@ -109,11 +107,11 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) qc::fp theta; qc::fp phi; qc::fp lambda; - if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { + if (std::fabs(quat[0]) > epsilon || std::fabs(quat[3]) > epsilon) { theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // phi+ lambda - if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); phi = alpha_1 + alpha_2; // phi lambda = alpha_1 - alpha_2; @@ -124,7 +122,7 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) } else { theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= // exp(i*pi) just global phase - if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { phi = 0; lambda = 2 * std::atan2(quat[1], quat[2]); // atan can give PI instead of 0 Problem? @@ -141,7 +139,7 @@ auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { - if (abs(gate.angles[0]) > theta_max) { + if (std::fabs(gate.angles[0]) > theta_max) { theta_max = abs(gate.angles[0]); } } @@ -181,9 +179,9 @@ auto NativeGateDecomposer::getDecompositionAngles( qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - if (abs(angles[0] - theta_max) < epsilon) { + if (std::fabs(angles[0] - theta_max) < epsilon) { chi = qc::PI; - if (abs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? + if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; } else { alpha = qc::PI_2; @@ -244,9 +242,10 @@ auto NativeGateDecomposer::decompose( for (size_t i = 0; i < this->nQubits_; ++i) { GR_plus.emplace_back( - new qc::StandardOperation(i, qc::RY, {theta_max / 2})); + std::make_unique(i, qc::RY, std::initializer_list{theta_max / 2})); GR_minus.emplace_back( - new qc::StandardOperation(i, qc::RY, {-1 * theta_max / 2})); + std::make_unique(i, qc::RY, std::initializer_list{-1 * theta_max / 2})); + } for (auto&& gate : FrontLayer) { diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 1e3cb2154..c4a9905d6 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -57,7 +57,8 @@ class DecomposerTest : public ::testing::Test { decomposer(architecture, decomposerConfig) {} }; -qc::fp epsilon = 1e-5; +constexpr static qc::fp epsilon = + std::numeric_limits::epsilon() * 1024; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; From 230221302be1e785a0eeb7415802d0209a8e1215 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sat, 7 Feb 2026 17:35:36 +0100 Subject: [PATCH 019/110] switched abs with fabs --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 14 +++++++------- test/na/zoned/test_native_gate_decomposer.cpp | 12 +++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 5575c746a..42c43460d 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -12,6 +12,7 @@ // Created by cpsch on 11.12.2025. // #include "na/zoned/decomposer/NativeGateDecomposer.hpp" + #include "ir/operations/CompoundOperation.hpp" #include @@ -84,8 +85,8 @@ auto NativeGateDecomposer::convertGateToQuaternion( // if the gate type is not recognized, an error is printed and the // gate is not included in the output. std::ostringstream oss; - oss << "ERROR: Unsupported single-qubit gate: " - << op.get().getType() << "\n"; + oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() + << "\n"; throw std::invalid_argument(oss.str()); } return quat; @@ -241,11 +242,10 @@ auto NativeGateDecomposer::decompose( std::vector> GR_minus; for (size_t i = 0; i < this->nQubits_; ++i) { - GR_plus.emplace_back( - std::make_unique(i, qc::RY, std::initializer_list{theta_max / 2})); - GR_minus.emplace_back( - std::make_unique(i, qc::RY, std::initializer_list{-1 * theta_max / 2})); - + GR_plus.emplace_back(std::make_unique( + i, qc::RY, std::initializer_list{theta_max / 2})); + GR_minus.emplace_back(std::make_unique( + i, qc::RY, std::initializer_list{-1 * theta_max / 2})); } for (auto&& gate : FrontLayer) { diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index c4a9905d6..f1aa12bce 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -57,8 +57,7 @@ class DecomposerTest : public ::testing::Test { decomposer(architecture, decomposerConfig) {} }; -constexpr static qc::fp epsilon = - std::numeric_limits::epsilon() * 1024; +constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; @@ -101,11 +100,10 @@ TEST(Test, SingleXGateAngleTest) { const qc::Operation* op = new qc::StandardOperation(0, qc::X); std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); - EXPECT_THAT( - NativeGateDecomposer::getU3AnglesFromQuaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(qc::PI, epsilon))); + EXPECT_THAT(NativeGateDecomposer::getU3AnglesFromQuaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(qc::PI, epsilon))); } TEST(Test, SingleU3GateAngleTest) { From 5879e7f014fcc1e81914763fc48d7ae20e66707e Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 9 Feb 2026 17:36:06 +0100 Subject: [PATCH 020/110] made some changes to pushing decomposed operations into layers changed check for calculation of decomposition angles for sin/theta_m) near sin(theta) --- .../zoned/decomposer/NativeGateDecomposer.cpp | 32 ++++++------------- test/na/zoned/test_native_gate_decomposer.cpp | 4 +-- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 42c43460d..6013115d5 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -141,7 +141,7 @@ auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) qc::fp theta_max = 0; for (auto gate : layer) { if (std::fabs(gate.angles[0]) > theta_max) { - theta_max = abs(gate.angles[0]); + theta_max = std::fabs(gate.angles[0]); } } return theta_max; @@ -180,7 +180,8 @@ auto NativeGateDecomposer::getDecompositionAngles( qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - if (std::fabs(angles[0] - theta_max) < epsilon) { + qc::fp sin_sq_diff= (sin(theta_max/2) * sin(theta_max/2) - (sin(angles[0] / 2) * sin(angles[0] / 2))); + if (std::fabs(sin_sq_diff) < epsilon ) { chi = qc::PI; if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; @@ -188,9 +189,7 @@ auto NativeGateDecomposer::getDecompositionAngles( alpha = qc::PI_2; } } else { - qc::fp kappa = sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / - (sin(theta_max) * sin(theta_max) - - (sin(angles[0] / 2) * sin(angles[0] / 2)))); + qc::fp kappa = std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } @@ -224,18 +223,11 @@ auto NativeGateDecomposer::decompose( getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); - std::unique_ptr op = - std::make_unique(sop); - FrontLayer.emplace_back(std::move(op)); + FrontLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}); - op = std::make_unique(sop); - MidLayer.emplace_back(std::move(op)); + MidLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}); - op = std::make_unique(sop); - BackLayer.emplace_back(std::move(op)); + BackLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer std::vector> GR_plus; @@ -252,18 +244,12 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - auto cop = qc::CompoundOperation(std::move(GR_plus), true); - std::unique_ptr ryp = - std::make_unique(cop); - NewLayer.emplace_back(std::move(ryp)); + NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - cop = qc::CompoundOperation(std::move(GR_minus), true); - std::unique_ptr rym = - std::make_unique(cop); - NewLayer.emplace_back(std::move(rym)); + NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index f1aa12bce..fa4e8a7c1 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -88,7 +88,7 @@ TEST(Test, ThreeQuaternionU3Test) { ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); - qc::fp r2 = 1 / sqrt(2); + qc::fp r2 = 1 / std::sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), @@ -249,8 +249,6 @@ TEST_F(DecomposerTest, SingleU3Gate) { ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } -// TEST with U3(o,?,?) -// TEST with two Single Qubit Layers TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ From ebe39049e51a6bbd8fd695c0f922e0c179ebeed1 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 9 Feb 2026 17:41:39 +0100 Subject: [PATCH 021/110] made some changes to pushing decomposed operations into layers changed check for calculation of decomposition angles for sin/theta_m) near sin(theta) --- .../zoned/decomposer/NativeGateDecomposer.cpp | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 6013115d5..1be86f718 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -180,8 +180,9 @@ auto NativeGateDecomposer::getDecompositionAngles( qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - qc::fp sin_sq_diff= (sin(theta_max/2) * sin(theta_max/2) - (sin(angles[0] / 2) * sin(angles[0] / 2))); - if (std::fabs(sin_sq_diff) < epsilon ) { + qc::fp sin_sq_diff = (sin(theta_max / 2) * sin(theta_max / 2) - + (sin(angles[0] / 2) * sin(angles[0] / 2))); + if (std::fabs(sin_sq_diff) < epsilon) { chi = qc::PI; if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; @@ -189,7 +190,8 @@ auto NativeGateDecomposer::getDecompositionAngles( alpha = qc::PI_2; } } else { - qc::fp kappa = std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); + qc::fp kappa = + std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } @@ -223,11 +225,14 @@ auto NativeGateDecomposer::decompose( getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - FrontLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); + FrontLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - MidLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); + MidLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - BackLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); + BackLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer std::vector> GR_plus; @@ -244,12 +249,14 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); + NewLayer.emplace_back( + std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); + NewLayer.emplace_back( + std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); From 0f0d42984fc0f99a0edf2542917013770cfc81bf Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:41:51 +0000 Subject: [PATCH 022/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.cpp | 25 +++++++++++++------ test/na/zoned/test_native_gate_decomposer.cpp | 1 - 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 6013115d5..6cda304a9 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -180,8 +180,9 @@ auto NativeGateDecomposer::getDecompositionAngles( qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - qc::fp sin_sq_diff= (sin(theta_max/2) * sin(theta_max/2) - (sin(angles[0] / 2) * sin(angles[0] / 2))); - if (std::fabs(sin_sq_diff) < epsilon ) { + qc::fp sin_sq_diff = (sin(theta_max / 2) * sin(theta_max / 2) - + (sin(angles[0] / 2) * sin(angles[0] / 2))); + if (std::fabs(sin_sq_diff) < epsilon) { chi = qc::PI; if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; @@ -189,7 +190,8 @@ auto NativeGateDecomposer::getDecompositionAngles( alpha = qc::PI_2; } } else { - qc::fp kappa = std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); + qc::fp kappa = + std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / sin_sq_diff); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } @@ -223,11 +225,14 @@ auto NativeGateDecomposer::decompose( getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - FrontLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); + FrontLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - MidLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); + MidLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - BackLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); + BackLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer std::vector> GR_plus; @@ -244,12 +249,16 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); + NewLayer.emplace_back( + std::move(std::make_unique( + qc::CompoundOperation(std::move(GR_plus), true)))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); + NewLayer.emplace_back( + std::move(std::make_unique( + qc::CompoundOperation(std::move(GR_minus), true)))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index fa4e8a7c1..4e89d598a 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -249,7 +249,6 @@ TEST_F(DecomposerTest, SingleU3Gate) { ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } - TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ // q: ┤ X ├──┤ Z ├ From 844e78ceeb1a693b8117c8a0ad25c891c19ff955 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 9 Feb 2026 17:52:02 +0100 Subject: [PATCH 023/110] minor comment change --- test/na/zoned/test_native_gate_decomposer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 4e89d598a..61f969281 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -169,7 +169,6 @@ TEST(Test, RXDecompositionTest) { TEST(Test, U3DecompositionTest) { std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; - // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! EXPECT_THAT( NativeGateDecomposer::getDecompositionAngles(u3, qc::PI_4), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), From 0b2de5aca45abf40ade3447d237f343e4447b95e Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 16 Feb 2026 11:35:09 +0100 Subject: [PATCH 024/110] added check for empty target vector in operation --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 6cda304a9..63079e519 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -155,7 +155,10 @@ auto NativeGateDecomposer::transformToU3( this->nQubits_); std::vector new_layer; for (auto gate : layer) { - gates[gate.get().getTargets().front()].push_back(gate); + //WHat are operations with empty targets doing?? + if (!gate.get().getTargets().empty()) { + gates[gate.get().getTargets().front()].push_back(gate); + } } for (auto qubit_gates : gates) { From b9e34ca144dc061dc692d6aa75024f68932ae1db Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 10:36:08 +0000 Subject: [PATCH 025/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 63079e519..84451b477 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -155,7 +155,7 @@ auto NativeGateDecomposer::transformToU3( this->nQubits_); std::vector new_layer; for (auto gate : layer) { - //WHat are operations with empty targets doing?? + // WHat are operations with empty targets doing?? if (!gate.get().getTargets().empty()) { gates[gate.get().getTargets().front()].push_back(gate); } From cdaf880def9003e739fbd75b505db98de791e132 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Fri, 27 Feb 2026 18:30:44 +0100 Subject: [PATCH 026/110] Coverage Tests added --- test/na/zoned/test_native_gate_decomposer.cpp | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 61f969281..dd51895d8 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -59,6 +59,149 @@ class DecomposerTest : public ::testing::Test { constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; +// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, SX, Sxdg, Unrecognized, H _>Just do them all? + +TEST(Test, ZRotGateTranslationTest) { + + qc::StandardOperation op =qc::StandardOperation(0, qc::Z); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon))); + + op =qc::StandardOperation(0, qc::RZ, {qc::PI_2}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + op =qc::StandardOperation(0, qc::P,{qc::PI_2}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + + op =qc::StandardOperation(0, qc::S); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + + op =qc::StandardOperation(0, qc::Sdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1/std::sqrt(2), epsilon))); + op =qc::StandardOperation(0, qc::T); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0.5*std::sqrt(2-std::sqrt(2)), epsilon))); + + op =qc::StandardOperation(0, qc::Tdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-0.5*std::sqrt(2-std::sqrt(2)), epsilon))); + + + +} + +TEST(Test, XYRotGateTranslationTest) { + qc::StandardOperation op =qc::StandardOperation(0, qc::X); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::RX,{qc::PI_2}); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::Y); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0,qc::RY,{qc::PI_2}); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::SX); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::SXdg); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(-1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + +} + +TEST(Test, UGateTranslationTest) { + qc::fp p=qc::PI_2; + qc::fp t=qc::PI_4; + qc::fp l=qc::PI_4; + qc::StandardOperation op =qc::StandardOperation(0, qc::U,{t,p,l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); + + t=qc::PI_2; + op =qc::StandardOperation(0, qc::U2,{p,l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); + + t=-1*qc::PI_2; + l=-1*qc::PI_2; + + op =qc::StandardOperation(0, qc::Vdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); + op =qc::StandardOperation(0, qc::H); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + +} + TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; From 2f96f6e9d38178723e0bd7b54f48fa44a9e691dd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 17:33:09 +0000 Subject: [PATCH 027/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/na/zoned/test_native_gate_decomposer.cpp | 302 +++++++++++------- 1 file changed, 182 insertions(+), 120 deletions(-) diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index dd51895d8..3daab4da3 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -59,147 +59,209 @@ class DecomposerTest : public ::testing::Test { constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; -// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, SX, Sxdg, Unrecognized, H _>Just do them all? +// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, +// SX, Sxdg, Unrecognized, H _>Just do them all? TEST(Test, ZRotGateTranslationTest) { - qc::StandardOperation op =qc::StandardOperation(0, qc::Z); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon))); - - op =qc::StandardOperation(0, qc::RZ, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - op =qc::StandardOperation(0, qc::P,{qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - - op =qc::StandardOperation(0, qc::S); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - - op =qc::StandardOperation(0, qc::Sdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-1/std::sqrt(2), epsilon))); - op =qc::StandardOperation(0, qc::T); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0.5*std::sqrt(2-std::sqrt(2)), epsilon))); - - op =qc::StandardOperation(0, qc::Tdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-0.5*std::sqrt(2-std::sqrt(2)), epsilon))); - + qc::StandardOperation op = qc::StandardOperation(0, qc::Z); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon))); + op = qc::StandardOperation(0, qc::RZ, {qc::PI_2}); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::P, {qc::PI_2}); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::S); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + + op = qc::StandardOperation(0, qc::Sdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::T); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); + + op = qc::StandardOperation(0, qc::Tdg); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); } TEST(Test, XYRotGateTranslationTest) { - qc::StandardOperation op =qc::StandardOperation(0, qc::X); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); - - op =qc::StandardOperation(0, qc::RX,{qc::PI_2}); - - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + qc::StandardOperation op = qc::StandardOperation(0, qc::X); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::Y); + op = qc::StandardOperation(0, qc::RX, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0,qc::RY,{qc::PI_2}); + op = qc::StandardOperation(0, qc::Y); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::SX); + op = qc::StandardOperation(0, qc::RY, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::SXdg); + op = qc::StandardOperation(0, qc::SX); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(-1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + op = qc::StandardOperation(0, qc::SXdg); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(-1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); } TEST(Test, UGateTranslationTest) { - qc::fp p=qc::PI_2; - qc::fp t=qc::PI_4; - qc::fp l=qc::PI_4; - qc::StandardOperation op =qc::StandardOperation(0, qc::U,{t,p,l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - - t=qc::PI_2; - op =qc::StandardOperation(0, qc::U2,{p,l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - - t=-1*qc::PI_2; - l=-1*qc::PI_2; - - op =qc::StandardOperation(0, qc::Vdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - op =qc::StandardOperation(0, qc::H); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - + qc::fp p = qc::PI_2; + qc::fp t = qc::PI_4; + qc::fp l = qc::PI_4; + qc::StandardOperation op = qc::StandardOperation(0, qc::U, {t, p, l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + + t = qc::PI_2; + op = qc::StandardOperation(0, qc::U2, {p, l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + + t = -1 * qc::PI_2; + l = -1 * qc::PI_2; + + op = qc::StandardOperation(0, qc::Vdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + op = qc::StandardOperation(0, qc::H); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); } TEST(Test, ThreeQuaternionCombiTest) { From 49386a5f247fabee5d4da9fb4f0eba8d015ac8b8 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Wed, 4 Mar 2026 17:18:27 +0100 Subject: [PATCH 028/110] Small fixes --- .../zoned/decomposer/NativeGateDecomposer.cpp | 10 +- test/na/zoned/test_native_gate_decomposer.cpp | 306 +++++++++++------- 2 files changed, 188 insertions(+), 128 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 84451b477..41052593a 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -252,16 +252,14 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back( - std::move(std::make_unique( - qc::CompoundOperation(std::move(GR_plus), true)))); + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_plus), true))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back( - std::move(std::make_unique( - qc::CompoundOperation(std::move(GR_minus), true)))); + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_minus), true))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index dd51895d8..85c19d1ee 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -59,147 +59,209 @@ class DecomposerTest : public ::testing::Test { constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; -// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, SX, Sxdg, Unrecognized, H _>Just do them all? +// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, +// SX, Sxdg, Unrecognized, H _>Just do them all? TEST(Test, ZRotGateTranslationTest) { - qc::StandardOperation op =qc::StandardOperation(0, qc::Z); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon))); - - op =qc::StandardOperation(0, qc::RZ, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - op =qc::StandardOperation(0, qc::P,{qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - - op =qc::StandardOperation(0, qc::S); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - - op =qc::StandardOperation(0, qc::Sdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-1/std::sqrt(2), epsilon))); - op =qc::StandardOperation(0, qc::T); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0.5*std::sqrt(2-std::sqrt(2)), epsilon))); - - op =qc::StandardOperation(0, qc::Tdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-0.5*std::sqrt(2-std::sqrt(2)), epsilon))); - + qc::StandardOperation op = qc::StandardOperation(0, qc::Z); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon))); + op = qc::StandardOperation(0, qc::RZ, {qc::PI_2}); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::P, {qc::PI_2}); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::S); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + + op = qc::StandardOperation(0, qc::Sdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::T); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); + + op = qc::StandardOperation(0, qc::Tdg); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); } TEST(Test, XYRotGateTranslationTest) { - qc::StandardOperation op =qc::StandardOperation(0, qc::X); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); - - op =qc::StandardOperation(0, qc::RX,{qc::PI_2}); - - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + qc::StandardOperation op = qc::StandardOperation(0, qc::X); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::Y); + op = qc::StandardOperation(0, qc::RX, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0,qc::RY,{qc::PI_2}); + op = qc::StandardOperation(0, qc::Y); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::SX); + op = qc::StandardOperation(0, qc::RY, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::SXdg); + op = qc::StandardOperation(0, qc::SX); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(-1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + op = qc::StandardOperation(0, qc::SXdg); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(-1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); } TEST(Test, UGateTranslationTest) { - qc::fp p=qc::PI_2; - qc::fp t=qc::PI_4; - qc::fp l=qc::PI_4; - qc::StandardOperation op =qc::StandardOperation(0, qc::U,{t,p,l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - - t=qc::PI_2; - op =qc::StandardOperation(0, qc::U2,{p,l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - - t=-1*qc::PI_2; - l=-1*qc::PI_2; - - op =qc::StandardOperation(0, qc::Vdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - op =qc::StandardOperation(0, qc::H); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - + qc::fp p = qc::PI_2; + qc::fp t = qc::PI_4; + qc::fp l = qc::PI_4; + qc::StandardOperation op = qc::StandardOperation(0, qc::U, {t, p, l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + + t = qc::PI_2; + op = qc::StandardOperation(0, qc::U2, {p, l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + + t = -1 * qc::PI_2; + l = -1 * qc::PI_2; + + op = qc::StandardOperation(0, qc::Vdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + op = qc::StandardOperation(0, qc::H); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); } TEST(Test, ThreeQuaternionCombiTest) { @@ -336,7 +398,7 @@ TEST_F(DecomposerTest, SingleRXGate) { // ┌───────┐ // q: ┤ Rx(π) ├ // └───────┘ - int n = 1; + size_t n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); const auto& sched = scheduler.schedule(qc); @@ -365,7 +427,7 @@ TEST_F(DecomposerTest, SingleU3Gate) { // ┌─────────────┐ // q: ┤ U3(0,π,π/2) ├ // └─────────────┘ - int n = 1; + size_t n = 1; qc::QuantumComputation qc(n); qc.u(0.0, qc::PI, qc::PI_2, 0); const auto& sched = scheduler.schedule(qc); From a3f5ac310c53154a7f84f31c8bf38548a5fefb5d Mon Sep 17 00:00:00 2001 From: ga96dup Date: Wed, 4 Mar 2026 17:21:26 +0100 Subject: [PATCH 029/110] Small fixes --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 41052593a..01312aa3d 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -253,13 +253,13 @@ auto NativeGateDecomposer::decompose( } NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_plus), true))); + qc::CompoundOperation(std::move(GR_plus), true))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_minus), true))); + qc::CompoundOperation(std::move(GR_minus), true))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); From c0480446487c01e06de6b9b8b35dd0b64dbcc497 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 13 Jan 2026 17:27:45 +0100 Subject: [PATCH 030/110] Combining Gates and builing combined U3 works. --- include/na/zoned/decomposer/Decomposer.hpp | 71 ++++++ src/na/zoned/decomposer/Decomposer.cpp | 266 +++++++++++++++++++++ test/na/zoned/test_decomposer.cpp | 206 ++++++++++++++++ 3 files changed, 543 insertions(+) create mode 100644 include/na/zoned/decomposer/Decomposer.hpp create mode 100644 src/na/zoned/decomposer/Decomposer.cpp create mode 100644 test/na/zoned/test_decomposer.cpp diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp new file mode 100644 index 000000000..83f7c1aaf --- /dev/null +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include "ir/operations/StandardOperation.hpp" +#include "na/zoned/Types.hpp" + +#include + +namespace na::zoned { + + class Decomposer { + public: + /** + * Converts commonly used single qubit gates into their Quaternion representation + * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) with X,Y,Z Pauli Matrices + * @param op a reference_wrapper to the operation to be converted + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the quaternion + */ + static auto convert_gate_to_quaternion(std::reference_wrapper op) -> std::array; + /** + * Merges the quaternions representing two gates as in a Matrix multiplication of the gates + * @param q1 the first Quaternion to be combined + * @param q2 the second Quaternion to be combined + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the combined quaternion + */ + static auto combine_quaternions(const std::array& q1, + const std::array& q2) -> std::array; + /** + * Calculates the values of the U3-Gate parameters theta, phi and lambda + * @param quat is a quaternion representing a single qubit gate + * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ gate angles + */ + static auto get_U3_angles_from_quaternion(std::array quat) -> std::array; + + /** + * Calculates the largest value of the U3-Gate parameter theta from a vector of Operations. + * Fails when provided gates aren't all U3-Gates. + * @param layer is a SingleQubitGateLayers of a scheduled + */ + static auto calc_theta_max(const SingleQubitGateLayer& layer)->qc::fp; + + /** + * Takes a vector of SingleQubitGateLayer's and, for each layer + * , transforms all gates into U3 gates + * , combining all gates acting on the same qubit into a single U3 gate + * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit + */ + [[nodiscard]] auto transform_to_U3(const std::vector& layers) const + -> std::vector; + + /** + * Create a new Decomposer. + * @param n_qubits is the number of qubits in the circuit to be decomposed + */ + Decomposer(int n_qubits); + + [[nodiscard]] auto + decompose(const std::pair, + std::vector>& schedule) + -> std::pair, + std::vector>; + private: + struct { + std::array angles; + int qubit; + } struct_U3; + + int N_qubits; + + }; + +} // namespace na::zoned \ No newline at end of file diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp new file mode 100644 index 000000000..6ac34e93d --- /dev/null +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -0,0 +1,266 @@ +// +// Created by cpsch on 11.12.2025. +// +#include "na/zoned/decomposer/decomposer.hpp" + +//#include "ir/operations/StandardOperation.hpp" +#include "ir/operations/CompoundOperation.hpp" + +#include +#include + +namespace na::zoned { +Decomposer::Decomposer(int n_qubits) { + N_qubits=n_qubits; +}; + + +auto Decomposer::combine_quaternions(const std::array& q1, + const std::array& q2) -> std::array { + std::array new_quat{}; + new_quat[0]=q1[0]*q2[0]-q1[1]*q2[1]-q1[2]*q2[2]-q1[3]*q2[3]; + new_quat[1]=q1[0]*q2[1]+q1[1]*q2[0]+q1[2]*q2[3]-q1[3]*q2[2]; + new_quat[2]=q1[0]*q2[2]-q1[1]*q2[3]+q1[2]*q2[0]+q1[3]*q2[1]; + new_quat[3]=q1[0]*q2[3]+q1[1]*q2[2]-q1[2]*q2[1]+q1[3]*q2[0]; + return new_quat; +} + +auto Decomposer::convert_gate_to_quaternion(std::reference_wrapper op) -> std::array { + assert(op.get().getNqubits() == 1); + std::array quat; + //TODO: Figure out if I need -i factor + //TODO: Phase? + if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { + quat={cos(op.get().getParameter().front()),0,0,sin(op.get().getParameter().front())}; + } else if (op.get().getType() == qc::Z) { + quat={0,0,0,1}; + } else if (op.get().getType() == qc::S) { + quat={cos(qc::PI_4),0,0,sin(qc::PI_4)}; + } else if (op.get().getType() == qc::Sdg) { + quat={cos(-qc::PI_4),0,0,sin(-qc::PI_4)}; + } else if (op.get().getType() == qc::T) { + quat={cos(qc::PI_4/2),0,0,sin(qc::PI_4/2)}; + } else if (op.get().getType() == qc::Tdg) { + quat={cos(-qc::PI_4/2),0,0,sin(-qc::PI_4/2)}; + } else if (op.get().getType() == qc::U) { + quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)} + ,{cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}), + {cos(op.get().getParameter().at(2)/2),0,0,sin(op.get().getParameter().at(2)/2)}); + } else if (op.get().getType() == qc::U2) { + quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().front()/2),0,0,sin(op.get().getParameter().front()/2)} + ,{cos(qc::PI_2),0,sin(qc::PI_2),0}), + {cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)}); + } else if (op.get().getType() == qc::RX) { + quat={cos(op.get().getParameter().front()/2),sin(op.get().getParameter().front()/2),0,0}; + } else if (op.get().getType() == qc::RY) { + quat={cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}; + } else if (op.get().getType() == qc::H) { + //TODO: Double check this + quat=combine_quaternions(combine_quaternions({1,0,0,0} + ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), + {cos(qc::PI_2),0,0,sin(qc::PI_2)}); + } else if (op.get().getType() == qc::X) { + quat={0,1,0,0}; + } else if (op.get().getType() == qc::Y) { + quat={0,1,0,0}; + } else if (op.get().getType() == qc::Vdg) { + quat=combine_quaternions(combine_quaternions({cos(qc::PI_4),0,0,sin(qc::PI_4)} + ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), + {cos(-qc::PI_4),0,0,sin(-qc::PI_4)}); + } else if (op.get().getType() == qc::SX) { + quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} + ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), + {cos(qc::PI_4),0,0,sin(qc::PI_4)}); + } else if (op.get().getType() == qc::SXdg || + op.get().getType() == qc::V) { + quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} + ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), + {cos(qc::PI_4),0,0,sin(qc::PI_4)}); + } else { + // if the gate type is not recognized, an error is printed and the + // gate is not included in the output. + std::ostringstream oss; + oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + << op.get().getType() << "\n"; + throw std::invalid_argument(oss.str()); + } + return quat; + } + + auto Decomposer::get_U3_angles_from_quaternion(std::array quat) -> std::array { + //TODO: Is there a prescribed eps somewhere? Else where should THIS eps be defined + qc::fp eps=1e-5; + qc::fp theta; + qc::fp phi; + qc::fp lambda; + if (abs(quat[0])>eps||abs(quat[3])>eps) { + theta=2.*std::atan2(std::sqrt(quat[2]*quat[2]+quat[1]*quat[1]),std::sqrt(quat[0]*quat[0]+quat[3]*quat[3])); + qc::fp alph_1=std::atan2(quat[3],quat[0]); //phi+ lambda + if (abs(quat[1])>eps||abs(quat[2])>eps) { + qc::fp alph_2=-1*std::atan2(quat[1],quat[2]); + phi=alph_1+alph_2; //phi + lambda=alph_1-alph_2; + } else { + //TODO: Which was set to zero??? + phi=0; + lambda=2*alph_1; + } + } else { + theta=qc::PI; //or § PI if sin(theta/2)=-1... Relevant? Or is the -1= exp(i*pi) just global phase + if (abs(quat[1])>eps||abs(quat[2])>eps) { + phi=0; + lambda= 2*std::atan2(quat[1],quat[2]); + //2*tan(q1/q2) = phi-lambda, but can't be disentangled + } else { + //This should never happen! Exception?? + phi=0.; + lambda=0.; + } + } + return {theta,phi,lambda}; +} + + + auto Decomposer::calc_theta_max(const SingleQubitGateLayer& layer) -> qc::fp { + //TODO: Error Handling improvement? + qc::fp theta_max=0; + for (auto gate :layer) { + if (gate.get().getType()== qc::U){ + std::vector params=gate.get().getParameter(); + if (abs(params[0])>theta_max) {theta_max=abs(params[0]);} + } else { + // if the gate type is not U3, an error is printed. + std::ostringstream oss; + oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + << gate.get().getType() << "\n"; + throw std::invalid_argument(oss.str()); + } + } + return theta_max; +} + +//TOD0:Return vector of structs +auto Decomposer::transform_to_U3(const std::vector& layers) const + -> std::vector { + //How to sort gates with same qubit + //How to get Matrix Representations?? + std::vector new_layers; + for (const auto& layer: layers) { + std::vector>> gates(this->N_qubits); + SingleQubitGateLayer new_layer; + for (auto gate:layer) { + gates[gate.get().getNtargets()].push_back(gate); + } + + for (auto qubit_gates:gates) { + if (!qubit_gates.empty()) { + + std::array quat = convert_gate_to_quaternion(qubit_gates[0]); + for (auto i=1;i angles=get_U3_angles_from_quaternion(quat); + //TODO: Don't return Op here? + const qc::Operation *new_op=new qc::StandardOperation(qubit_gates[0].get().getTargets().front(),qc::U,{angles[0],angles[1],angles[2]}); + new_layer.emplace_back(*new_op); + } + } + new_layers.push_back(new_layer); + } + return new_layers; +} + + +auto Decomposer::decompose( + const std::pair, + std::vector>& schedule) + -> std::pair, + std::vector> { + //TODO:make U3Layer vector + std::vector U3Layers=this->transform_to_U3(schedule.first); + std::vector NewSingleQubitLayers=std::vector{}; + + for (const auto& layer: U3Layers) { + qc::fp theta_max=calc_theta_max(layer); + SingleQubitGateLayer FrontLayer; + SingleQubitGateLayer MidLayer; + SingleQubitGateLayer BackLayer; + SingleQubitGateLayer NewLayer; + + + for (auto gate:layer){ + //TODO: ONly ANgles at this point + std::vector params=gate.get().getParameter(); + qc::fp theta=params[0]; + qc::fp phi_minus=params[1]; + qc::fp phi_plus=params[2]; + //TODO: Decide whether to make this a separate function for each gate in rel to theta_max + //TODO: Add mod 2PI/TAU + qc::fp alpha, chi, beta; + if (theta==theta_max) { + alpha=qc::PI_2; + chi=qc::PI; + }else { + qc::fp kappa=sqrt((sin(theta/2)*sin(theta/2))/(sin(theta_max)*sin(theta_max)-(sin(theta/2)*sin(theta/2)))); + alpha=atan(cos(theta_max/2)*kappa); + chi=fmod(2*atan(kappa),qc::TAU); + } + if (theta!=0) { + beta=theta_max<0?qc::PI_2:-1*qc::PI_2; + }else { + beta=0; + } + qc::fp gamma_plus=fmod(phi_plus-(alpha+beta),qc::TAU); + qc::fp gamma_minus=fmod(phi_minus-(alpha-beta),qc::TAU); + + //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) + // GR(theta_max/2, PI_2)==Global Y due to PI_2 + + + //TODO: Does this work?? + auto sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_minus}); + qc::Operation *op=&sop; + FrontLayer.emplace_back(std::reference_wrapper(*op)); + + sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{chi}); + op=&sop; + MidLayer.emplace_back(std::reference_wrapper(*op)); + + sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_plus}); + op=&sop; + MidLayer.emplace_back(std::reference_wrapper(*op)); + }//gate::layer + + + + std::vector< std::unique_ptr> GR_plus; + std::vector< std::unique_ptr> GR_minus; + + for (auto i=0; iN_qubits; ++i) { + GR_plus.emplace_back(new qc::StandardOperation(i,qc::RY,{theta_max/2})); + GR_minus.emplace_back(new qc::StandardOperation(i,qc::RY,{-1*theta_max/2})); + } + + for (auto gate:FrontLayer) { + NewLayer.push_back(gate); + } + + auto cop= qc::CompoundOperation(std::move(GR_plus),true); + qc::Operation *ryp=&cop; + NewLayer.emplace_back(*ryp); + + for (auto gate:MidLayer) { + NewLayer.push_back(gate); + } + cop=qc::CompoundOperation(std::move(GR_minus),true); + qc::Operation *rym=&cop; + NewLayer.emplace_back(*rym); + + for (auto gate:BackLayer) { + NewLayer.push_back(gate); + } + NewSingleQubitLayers.push_back(NewLayer); + }//layer::SingleQubitLayers + return std::pair{NewSingleQubitLayers,schedule.second}; +} +}// namespace na::zoned \ No newline at end of file diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp new file mode 100644 index 000000000..771b05853 --- /dev/null +++ b/test/na/zoned/test_decomposer.cpp @@ -0,0 +1,206 @@ +// +// Created by cpsch on 16.12.2025. +// + +#include "ir/QuantumComputation.hpp" +#include "na/zoned/decomposer/Decomposer.hpp" +#include "na/zoned/scheduler/ASAPScheduler.hpp" + +#include +#include +#include +#include +#include + +namespace na::zoned { +constexpr std::string_view architectureJson = R"({ + "name": "asap_scheduler_architecture", + "storage_zones": [{ + "zone_id": 0, + "slms": [{"id": 0, "site_separation": [3, 3], "r": 20, "c": 20, "location": [0, 0]}], + "offset": [0, 0], + "dimension": [60, 60] + }], + "entanglement_zones": [{ + "zone_id": 0, + "slms": [ + {"id": 1, "site_separation": [12, 10], "r": 4, "c": 4, "location": [5, 70]}, + {"id": 2, "site_separation": [12, 10], "r": 4, "c": 4, "location": [7, 70]} + ], + "offset": [5, 70], + "dimension": [50, 40] + }], + "aods":[{"id": 0, "site_separation": 2, "r": 20, "c": 20}], + "rydberg_range": [[[5, 70], [55, 110]]] +})"; +//TODO: Tests for the U3 decomposition +class DecomposerTest : public ::testing::Test { +protected: + Decomposer decomposer=Decomposer(4); + Architecture architecture; + ASAPScheduler::Config config{.maxFillingFactor = .8}; + ASAPScheduler scheduler; + DecomposerTest() + : architecture(Architecture::fromJSONString(architectureJson)), + scheduler(architecture, config) {} +}; + +qc::fp epsilon=1e-5; + +TEST(Test,ThreeQuaternionCombiTest) { + std::array q1={cos(qc::PI_4),0,0,sin(qc::PI_4)}; + std::array q2={cos(qc::PI_2),0,sin(qc::PI_2),0}; + std::array q12=Decomposer::combine_quaternions(q1,q2); + EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(-1*cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); + std::array q3={cos(qc::PI_2),0,0,sin(qc::PI_2)}; + std::array q13=Decomposer::combine_quaternions(q12,q3); + EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); + +} + +TEST(Test,ThreeQuaternionU3Test) { + std::array q1={cos(qc::PI_2),0,0,sin(qc::PI_2)}; + std::array q2={cos(qc::PI_4/2),0,sin(qc::PI_4/2),0}; + std::array q12=Decomposer::combine_quaternions(q1,q2); + //TODO:FIgure this out!!! + EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(-1*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(cos(qc::PI_4/2),epsilon))); + std::array q3={cos(qc::PI_4),0,0,sin(qc::PI_4)}; + std::array q13=Decomposer::combine_quaternions(q12,q3); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), + ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); + +} + +TEST(Test,SingleXGateAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::X); + + qc::QuantumComputation qc(n); + qc.rx(qc::PI, 0); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(-1*qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); +} + +TEST(Test,SingleU3GateAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI_4,qc::PI,qc::PI_2}); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), + ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); + + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI_4,epsilon), + ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); +} + +TEST(Test, ThetaPiAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI,qc::PI,qc::PI_2}); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(-r2,epsilon),::testing::DoubleNear(r2,epsilon),::testing::DoubleNear(0,epsilon))); + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(-1*qc::PI_2,epsilon))); + +} + +TEST(Test, ThetaZeroAngleTest) { + size_t n=1; + const qc::Operation *op=new qc::StandardOperation(0,qc::U,{0,qc::PI,qc::PI_2}); + std::array q=Decomposer::convert_gate_to_quaternion( + std::reference_wrapper(*op)); + qc::fp r2=1/sqrt(2); + EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(r2,epsilon))); + + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(3*qc::PI_2,epsilon))); + +} + +TEST_F(DecomposerTest, SingleRXGate) { + // ┌───────┐ + // q: ┤ Rx(π) ├ + // └───────┘ + size_t n=1; + qc::QuantumComputation qc(n); + qc.rx(qc::PI, 0); + Decomposer decomposer=Decomposer(n); + const auto& sched = + scheduler.schedule(qc); + // auto decomp=decomposer.decompose(sched); +} + +TEST_F(DecomposerTest, SingleU3Gate) { + // ┌───────────────┐ + // q:─┤ U3(π/4,π,π/2) ├─ + // └───────────────┘ + size_t n=1; + qc::QuantumComputation qc(n); + qc.u(qc::PI_4,qc::PI,qc::PI_2,0); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + +TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { + // ┌───────┐ ┌───────┐ + // q: ┤ X ├──┤ Z ├ + // └───────┘ └───────┘ + size_t n=1; + qc::QuantumComputation qc(n); + qc.x(0); + qc.z(0); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + +TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { + // ┌───────┐ + // q_0: ─┤ X ├─ + // └───────┘ + // ┌───────┐ + // q_1: ─┤ Z ├─ + // └───────┘ + + size_t n=2; + qc::QuantumComputation qc(n); + qc.x(0); + qc.z(1); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + +TEST_F(DecomposerTest, TwoU3GatesTwoQubits) { + // ┌───────────────┐ + // q_0: ─┤ U3(π/4,π,π/2) ├─ + // └───────────────┘ + // ┌───────────────┐ + // q_1: ─┤ U3(π/2,π/2,π) ├─ + // └───────────────┘ + size_t n=2; + qc::QuantumComputation qc(n); + qc.u(qc::PI_4,qc::PI,qc::PI_2,0); + qc.u(qc::PI_2,qc::PI_2,qc::PI,1); + Decomposer decomposer=Decomposer(n); + const auto& [singleQubitGateLayers, twoQubitGateLayers] = + scheduler.schedule(qc); + +} + + +} // namespace na::zoned \ No newline at end of file From 4c2e71fcf254260fb969b3b2cf3c211144e663a2 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 20 Jan 2026 14:53:42 +0100 Subject: [PATCH 031/110] Changed internal handling of U3 gates. --- include/na/zoned/decomposer/Decomposer.hpp | 39 ++- src/na/zoned/decomposer/Decomposer.cpp | 324 ++++++++++----------- test/na/zoned/test_decomposer.cpp | 39 ++- 3 files changed, 223 insertions(+), 179 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index 83f7c1aaf..942881b6a 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -8,6 +8,14 @@ namespace na::zoned { class Decomposer { + private: + struct struct_U3{ + std::array angles; + int qubit; + } ; + static inline constexpr qc::fp epsilon=1e-5; + int N_qubits; + public: /** * Converts commonly used single qubit gates into their Quaternion representation @@ -29,24 +37,33 @@ namespace na::zoned { * @param quat is a quaternion representing a single qubit gate * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ gate angles */ - static auto get_U3_angles_from_quaternion(std::array quat) -> std::array; + static auto get_U3_angles_from_quaternion(const std::array& quat) -> std::array; /** - * Calculates the largest value of the U3-Gate parameter theta from a vector of Operations. - * Fails when provided gates aren't all U3-Gates. + * Calculates the largest value of the U3-Gate parameter theta from a vector + * of Operations. Fails when provided gates aren't all U3-Gates. * @param layer is a SingleQubitGateLayers of a scheduled + * @returns the maximal value of theta in the given layer */ - static auto calc_theta_max(const SingleQubitGateLayer& layer)->qc::fp; + static auto calc_theta_max(const std::vector& layer)->qc::fp; /** * Takes a vector of SingleQubitGateLayer's and, for each layer - * , transforms all gates into U3 gates + * , transforms all gates into U3 gates represented by struct_U3's * , combining all gates acting on the same qubit into a single U3 gate * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit + * @returns a vector of vectors of a struct_U3's representing the single qubit gate layers */ [[nodiscard]] auto transform_to_U3(const std::vector& layers) const - -> std::vector; - + -> std::vector>; + /** + * Takes a vector of qc::fp's representing the U3-Gate angles of a single qubit hate and the maximal value of theta + * for the single qubit gate layer and calculates the transversal decomposition angles as in Nottingham et. al. 2024 + * @param angles is a std::array of qc::fp representing (theta,phi, lambda) + * @param theta_max the maximal theta value of the single-qubit qate layer + * @returns an array of qc::fp values giving the angles (chi, gamma_minus, gamma_plus) + */ + auto static get_decomposition_angles (const std::array& angles,qc::fp theta_max )-> std::array; /** * Create a new Decomposer. * @param n_qubits is the number of qubits in the circuit to be decomposed @@ -55,16 +72,10 @@ namespace na::zoned { [[nodiscard]] auto decompose(const std::pair, - std::vector>& schedule) + std::vector>& schedule) const -> std::pair, std::vector>; - private: - struct { - std::array angles; - int qubit; - } struct_U3; - int N_qubits; }; diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index 6ac34e93d..534891fa6 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -15,169 +15,198 @@ Decomposer::Decomposer(int n_qubits) { }; -auto Decomposer::combine_quaternions(const std::array& q1, - const std::array& q2) -> std::array { - std::array new_quat{}; - new_quat[0]=q1[0]*q2[0]-q1[1]*q2[1]-q1[2]*q2[2]-q1[3]*q2[3]; - new_quat[1]=q1[0]*q2[1]+q1[1]*q2[0]+q1[2]*q2[3]-q1[3]*q2[2]; - new_quat[2]=q1[0]*q2[2]-q1[1]*q2[3]+q1[2]*q2[0]+q1[3]*q2[1]; - new_quat[3]=q1[0]*q2[3]+q1[1]*q2[2]-q1[2]*q2[1]+q1[3]*q2[0]; - return new_quat; -} - -auto Decomposer::convert_gate_to_quaternion(std::reference_wrapper op) -> std::array { +auto Decomposer::convert_gate_to_quaternion( + std::reference_wrapper op) -> std::array { assert(op.get().getNqubits() == 1); - std::array quat; - //TODO: Figure out if I need -i factor - //TODO: Phase? + std::array quat{}; + // TODO: Phase? if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat={cos(op.get().getParameter().front()),0,0,sin(op.get().getParameter().front())}; - } else if (op.get().getType() == qc::Z) { - quat={0,0,0,1}; - } else if (op.get().getType() == qc::S) { - quat={cos(qc::PI_4),0,0,sin(qc::PI_4)}; - } else if (op.get().getType() == qc::Sdg) { - quat={cos(-qc::PI_4),0,0,sin(-qc::PI_4)}; - } else if (op.get().getType() == qc::T) { - quat={cos(qc::PI_4/2),0,0,sin(qc::PI_4/2)}; - } else if (op.get().getType() == qc::Tdg) { - quat={cos(-qc::PI_4/2),0,0,sin(-qc::PI_4/2)}; - } else if (op.get().getType() == qc::U) { - quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)} - ,{cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}), - {cos(op.get().getParameter().at(2)/2),0,0,sin(op.get().getParameter().at(2)/2)}); - } else if (op.get().getType() == qc::U2) { - quat=combine_quaternions(combine_quaternions({cos(op.get().getParameter().front()/2),0,0,sin(op.get().getParameter().front()/2)} - ,{cos(qc::PI_2),0,sin(qc::PI_2),0}), - {cos(op.get().getParameter().at(1)/2),0,0,sin(op.get().getParameter().at(1)/2)}); - } else if (op.get().getType() == qc::RX) { - quat={cos(op.get().getParameter().front()/2),sin(op.get().getParameter().front()/2),0,0}; - } else if (op.get().getType() == qc::RY) { - quat={cos(op.get().getParameter().front()/2),0,sin(op.get().getParameter().front()/2),0}; - } else if (op.get().getType() == qc::H) { - //TODO: Double check this - quat=combine_quaternions(combine_quaternions({1,0,0,0} - ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), - {cos(qc::PI_2),0,0,sin(qc::PI_2)}); - } else if (op.get().getType() == qc::X) { - quat={0,1,0,0}; - } else if (op.get().getType() == qc::Y) { - quat={0,1,0,0}; - } else if (op.get().getType() == qc::Vdg) { - quat=combine_quaternions(combine_quaternions({cos(qc::PI_4),0,0,sin(qc::PI_4)} - ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), - {cos(-qc::PI_4),0,0,sin(-qc::PI_4)}); - } else if (op.get().getType() == qc::SX) { - quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} - ,{cos(qc::PI_4),0,sin(qc::PI_4),0}), - {cos(qc::PI_4),0,0,sin(qc::PI_4)}); - } else if (op.get().getType() == qc::SXdg || - op.get().getType() == qc::V) { - quat=combine_quaternions(combine_quaternions({cos(-qc::PI_4),0,0,sin(-qc::PI_4)} - ,{cos(-qc::PI_4),0,sin(-qc::PI_4),0}), - {cos(qc::PI_4),0,0,sin(qc::PI_4)}); - } else { - // if the gate type is not recognized, an error is printed and the - // gate is not included in the output. - std::ostringstream oss; - oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " - << op.get().getType() << "\n"; - throw std::invalid_argument(oss.str()); - } - return quat; - } + quat = {cos(op.get().getParameter().front()), 0, 0, + sin(op.get().getParameter().front())}; + } else if (op.get().getType() == qc::Z) { + quat = {0, 0, 0, 1}; + } else if (op.get().getType() == qc::S) { + quat = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + } else if (op.get().getType() == qc::Sdg) { + quat = {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}; + } else if (op.get().getType() == qc::T) { + quat = {cos(qc::PI_4 / 2), 0, 0, sin(qc::PI_4 / 2)}; + } else if (op.get().getType() == qc::Tdg) { + quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; + } else if (op.get().getType() == qc::U) { + quat = combine_quaternions( + combine_quaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, + sin(op.get().getParameter().at(1) / 2)}, + {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}), + {cos(op.get().getParameter().at(2) / 2), 0, 0, + sin(op.get().getParameter().at(2) / 2)}); + } else if (op.get().getType() == qc::U2) { + quat = combine_quaternions( + combine_quaternions({cos(op.get().getParameter().front() / 2), 0, 0, + sin(op.get().getParameter().front() / 2)}, + {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), + {cos(op.get().getParameter().at(1) / 2), 0, 0, + sin(op.get().getParameter().at(1) / 2)}); + } else if (op.get().getType() == qc::RX) { + quat = {cos(op.get().getParameter().front() / 2), + sin(op.get().getParameter().front() / 2), 0, 0}; + } else if (op.get().getType() == qc::RY) { + quat = {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}; + } else if (op.get().getType() == qc::H) { + quat = combine_quaternions( + combine_quaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); + } else if (op.get().getType() == qc::X) { + quat = {0, 1, 0, 0}; + } else if (op.get().getType() == qc::Y) { + quat = {0, 1, 0, 0}; + } else if (op.get().getType() == qc::Vdg) { + quat = combine_quaternions( + combine_quaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); + } else if (op.get().getType() == qc::SX) { + quat = combine_quaternions( + combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); + } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { + quat = combine_quaternions( + combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); + } else { + // if the gate type is not recognized, an error is printed and the + // gate is not included in the output. + std::ostringstream oss; + oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + << op.get().getType() << "\n"; + throw std::invalid_argument(oss.str()); + } + return quat; +} + +auto Decomposer::combine_quaternions(const std::array& q1, + const std::array& q2) + -> std::array { + std::array new_quat{}; + new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; + new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; + new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; + new_quat[3] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]; + return new_quat; +} - auto Decomposer::get_U3_angles_from_quaternion(std::array quat) -> std::array { - //TODO: Is there a prescribed eps somewhere? Else where should THIS eps be defined - qc::fp eps=1e-5; + auto Decomposer::get_U3_angles_from_quaternion( + const std::array& quat) + -> std::array { + // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be + // defined qc::fp theta; qc::fp phi; qc::fp lambda; - if (abs(quat[0])>eps||abs(quat[3])>eps) { - theta=2.*std::atan2(std::sqrt(quat[2]*quat[2]+quat[1]*quat[1]),std::sqrt(quat[0]*quat[0]+quat[3]*quat[3])); - qc::fp alph_1=std::atan2(quat[3],quat[0]); //phi+ lambda - if (abs(quat[1])>eps||abs(quat[2])>eps) { - qc::fp alph_2=-1*std::atan2(quat[1],quat[2]); - phi=alph_1+alph_2; //phi - lambda=alph_1-alph_2; + if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { + theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), + std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); + qc::fp alph_1 = std::atan2(quat[3], quat[0]); // phi+ lambda + if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + qc::fp alph_2 = -1 * std::atan2(quat[1], quat[2]); + phi = alph_1 + alph_2; // phi + lambda = alph_1 - alph_2; } else { - //TODO: Which was set to zero??? - phi=0; - lambda=2*alph_1; + // TODO: Which was set to zero??? + phi = 0; + lambda = 2 * alph_1; } } else { - theta=qc::PI; //or § PI if sin(theta/2)=-1... Relevant? Or is the -1= exp(i*pi) just global phase - if (abs(quat[1])>eps||abs(quat[2])>eps) { - phi=0; - lambda= 2*std::atan2(quat[1],quat[2]); - //2*tan(q1/q2) = phi-lambda, but can't be disentangled + theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= + // exp(i*pi) just global phase + if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + phi = 0; + lambda = 2 * std::atan2(quat[1], quat[2]); + // 2*tan(q1/q2) = phi-lambda, but can't be disentangled } else { - //This should never happen! Exception?? - phi=0.; - lambda=0.; + // This should never happen! Exception?? + phi = 0.; + lambda = 0.; } } - return {theta,phi,lambda}; + return {theta, phi, lambda}; } - - auto Decomposer::calc_theta_max(const SingleQubitGateLayer& layer) -> qc::fp { - //TODO: Error Handling improvement? - qc::fp theta_max=0; - for (auto gate :layer) { - if (gate.get().getType()== qc::U){ - std::vector params=gate.get().getParameter(); - if (abs(params[0])>theta_max) {theta_max=abs(params[0]);} - } else { - // if the gate type is not U3, an error is printed. - std::ostringstream oss; - oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " - << gate.get().getType() << "\n"; - throw std::invalid_argument(oss.str()); - } + auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { + qc::fp theta_max = 0; + for (auto gate : layer) { + if (abs(gate.angles[0]) > theta_max) { + theta_max = abs(gate.angles[0]); + } } - return theta_max; + return theta_max; } -//TOD0:Return vector of structs -auto Decomposer::transform_to_U3(const std::vector& layers) const - -> std::vector { - //How to sort gates with same qubit - //How to get Matrix Representations?? - std::vector new_layers; - for (const auto& layer: layers) { - std::vector>> gates(this->N_qubits); - SingleQubitGateLayer new_layer; - for (auto gate:layer) { +auto Decomposer::transform_to_U3( + const std::vector& layers) const + -> std::vector> { + // auto u=struct_U3({0,0,0},0); + std::vector> new_layers; + for (const auto& layer : layers) { + std::vector>> gates( + this->N_qubits); + std::vector new_layer; + for (auto gate : layer) { gates[gate.get().getNtargets()].push_back(gate); } - for (auto qubit_gates:gates) { + for (auto qubit_gates : gates) { if (!qubit_gates.empty()) { - - std::array quat = convert_gate_to_quaternion(qubit_gates[0]); - for (auto i=1;i quat = convert_gate_to_quaternion(qubit_gates[0]); + for (auto i = 1; i < qubit_gates.size(); i++) { + quat = combine_quaternions( + quat, convert_gate_to_quaternion(qubit_gates[i])); } - std::array angles=get_U3_angles_from_quaternion(quat); - //TODO: Don't return Op here? - const qc::Operation *new_op=new qc::StandardOperation(qubit_gates[0].get().getTargets().front(),qc::U,{angles[0],angles[1],angles[2]}); - new_layer.emplace_back(*new_op); + std::array angles = get_U3_angles_from_quaternion(quat); + new_layer.emplace_back( + struct_U3(angles, + qubit_gates[0].get().getTargets().front())); } } new_layers.push_back(new_layer); } return new_layers; } +auto Decomposer::get_decomposition_angles(const std::array& angles, + qc::fp theta_max)-> std::array{ + qc::fp alpha, chi, beta; + //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) + if (abs(angles[0]-theta_max) < epsilon) { + alpha=qc::PI_2; + chi=qc::PI; + }else { + qc::fp kappa=sqrt((sin(angles[0]/2)*sin(angles[0]/2))/(sin(theta_max)*sin(theta_max)-(sin(angles[0]/2)*sin(angles[0]/2)))); + alpha=atan(cos(theta_max/2)*kappa); + chi=fmod(2*atan(kappa),qc::TAU); + } + + if (abs(angles[0]) > epsilon) { + beta=theta_max<0?qc::PI_2:-1*qc::PI_2; + }else { + beta=0; + } + qc::fp gamma_plus=fmod(angles[2]-(alpha+beta),qc::TAU); + qc::fp gamma_minus=fmod(angles[1]-(alpha-beta),qc::TAU); + + return {chi,gamma_minus,gamma_plus}; +} auto Decomposer::decompose( const std::pair, - std::vector>& schedule) + std::vector>& schedule) const -> std::pair, std::vector> { - //TODO:make U3Layer vector - std::vector U3Layers=this->transform_to_U3(schedule.first); + std::vector> U3Layers=transform_to_U3(schedule.first); std::vector NewSingleQubitLayers=std::vector{}; for (const auto& layer: U3Layers) { @@ -187,52 +216,23 @@ auto Decomposer::decompose( SingleQubitGateLayer BackLayer; SingleQubitGateLayer NewLayer; - for (auto gate:layer){ - //TODO: ONly ANgles at this point - std::vector params=gate.get().getParameter(); - qc::fp theta=params[0]; - qc::fp phi_minus=params[1]; - qc::fp phi_plus=params[2]; - //TODO: Decide whether to make this a separate function for each gate in rel to theta_max - //TODO: Add mod 2PI/TAU - qc::fp alpha, chi, beta; - if (theta==theta_max) { - alpha=qc::PI_2; - chi=qc::PI; - }else { - qc::fp kappa=sqrt((sin(theta/2)*sin(theta/2))/(sin(theta_max)*sin(theta_max)-(sin(theta/2)*sin(theta/2)))); - alpha=atan(cos(theta_max/2)*kappa); - chi=fmod(2*atan(kappa),qc::TAU); - } - if (theta!=0) { - beta=theta_max<0?qc::PI_2:-1*qc::PI_2; - }else { - beta=0; - } - qc::fp gamma_plus=fmod(phi_plus-(alpha+beta),qc::TAU); - qc::fp gamma_minus=fmod(phi_minus-(alpha-beta),qc::TAU); + std::array decomp_angles=get_decomposition_angles(gate.angles,theta_max); - //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) // GR(theta_max/2, PI_2)==Global Y due to PI_2 - - - //TODO: Does this work?? - auto sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_minus}); + auto sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[1]}); qc::Operation *op=&sop; FrontLayer.emplace_back(std::reference_wrapper(*op)); - sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{chi}); + sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[0]}); op=&sop; MidLayer.emplace_back(std::reference_wrapper(*op)); - sop=qc::StandardOperation(gate.get().getTargets().front(),qc::RZ,{gamma_plus}); + sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[2]}); op=&sop; MidLayer.emplace_back(std::reference_wrapper(*op)); }//gate::layer - - std::vector< std::unique_ptr> GR_plus; std::vector< std::unique_ptr> GR_minus; diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index 771b05853..61ec42027 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -33,7 +33,8 @@ constexpr std::string_view architectureJson = R"({ "aods":[{"id": 0, "site_separation": 2, "r": 20, "c": 20}], "rydberg_range": [[[5, 70], [55, 110]]] })"; -//TODO: Tests for the U3 decomposition + + class DecomposerTest : public ::testing::Test { protected: Decomposer decomposer=Decomposer(4); @@ -64,7 +65,6 @@ TEST(Test,ThreeQuaternionU3Test) { std::array q1={cos(qc::PI_2),0,0,sin(qc::PI_2)}; std::array q2={cos(qc::PI_4/2),0,sin(qc::PI_4/2),0}; std::array q12=Decomposer::combine_quaternions(q1,q2); - //TODO:FIgure this out!!! EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), ::testing::DoubleNear(-1*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(cos(qc::PI_4/2),epsilon))); std::array q3={cos(qc::PI_4),0,0,sin(qc::PI_4)}; @@ -127,11 +127,44 @@ TEST(Test, ThetaZeroAngleTest) { } +//One or Two Decomposition Tests? + + +TEST(Test, RXDecompositionTest) { + size_t n=1; + std::array rx={qc::PI,-qc::PI_2,qc::PI_2}; + //middle entry gamma_minus is -3/2 PI?? + EXPECT_THAT(Decomposer::get_decomposition_angles(rx,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + +} + +TEST(Test,U3DecompositionTest) { + size_t n=1; + std::array u3={qc::PI_4,qc::PI,qc::PI_2}; + // gamm minus i - PI_" not PI_2 and gam_plus is 0 not PI!! + EXPECT_THAT(Decomposer::get_decomposition_angles(u3,qc::PI_4),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(-qc::PI_2,epsilon))); +} + +TEST(Test,DoubleDecompositionTest) { + size_t n=1; + std::array x1={qc::PI,-qc::PI_2,qc::PI_2}; + std::array z2={0,0,qc::PI}; + //gamm_min is - 3/2 PI not 0 and gamm_plus is PI_2 not zero + EXPECT_THAT(Decomposer::get_decomposition_angles(x1,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); + // gamm_min is 0 not PI_2 and gamm_plus is PI not PI_2 + EXPECT_THAT(Decomposer::get_decomposition_angles(z2,qc::PI),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), + ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + +} + TEST_F(DecomposerTest, SingleRXGate) { // ┌───────┐ // q: ┤ Rx(π) ├ // └───────┘ - size_t n=1; + int n=1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); Decomposer decomposer=Decomposer(n); From d45825b3d8e86414e4ebea27af62605cb90d2172 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 22 Jan 2026 14:07:19 +0100 Subject: [PATCH 032/110] Changed --- include/na/zoned/decomposer/Decomposer.hpp | 11 ++-- src/na/zoned/decomposer/Decomposer.cpp | 68 ++++++++++------------ test/na/zoned/test_decomposer.cpp | 22 ++++++- 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index 942881b6a..f9faebf99 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -1,5 +1,6 @@ #pragma once +#include "DecomposerBase.hpp" #include "ir/operations/StandardOperation.hpp" #include "na/zoned/Types.hpp" @@ -7,7 +8,7 @@ namespace na::zoned { - class Decomposer { + class Decomposer : public DecomposerBase{ private: struct struct_U3{ std::array angles; @@ -54,7 +55,7 @@ namespace na::zoned { * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit * @returns a vector of vectors of a struct_U3's representing the single qubit gate layers */ - [[nodiscard]] auto transform_to_U3(const std::vector& layers) const + [[nodiscard]] auto transform_to_U3(const std::vector& layers) const -> std::vector>; /** * Takes a vector of qc::fp's representing the U3-Gate angles of a single qubit hate and the maximal value of theta @@ -71,10 +72,8 @@ namespace na::zoned { Decomposer(int n_qubits); [[nodiscard]] auto - decompose(const std::pair, - std::vector>& schedule) const - -> std::pair, - std::vector>; + decompose(const std::vector& singleQubitGateLayers) const + -> std::vector override; }; diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index 534891fa6..45cee0589 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -145,10 +145,9 @@ auto Decomposer::combine_quaternions(const std::array& q1, } return theta_max; } - -auto Decomposer::transform_to_U3( - const std::vector& layers) const - -> std::vector> { + auto Decomposer::transform_to_U3( + const std::vector& layers) const + -> std::vector> { // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { @@ -156,7 +155,7 @@ auto Decomposer::transform_to_U3( this->N_qubits); std::vector new_layer; for (auto gate : layer) { - gates[gate.get().getNtargets()].push_back(gate); + gates[gate.get().getTargets().front()].push_back(gate); } for (auto qubit_gates : gates) { @@ -181,19 +180,18 @@ auto Decomposer::get_decomposition_angles(const std::array& angles, qc::fp alpha, chi, beta; //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) if (abs(angles[0]-theta_max) < epsilon) { - alpha=qc::PI_2; chi=qc::PI; + if (abs(cos(theta_max/2)) epsilon) { - beta=theta_max<0?qc::PI_2:-1*qc::PI_2; - }else { - beta=0; - } + beta=angles[0]<0?-1*qc::PI_2:qc::PI_2; qc::fp gamma_plus=fmod(angles[2]-(alpha+beta),qc::TAU); qc::fp gamma_minus=fmod(angles[1]-(alpha-beta),qc::TAU); @@ -201,12 +199,10 @@ auto Decomposer::get_decomposition_angles(const std::array& angles, } -auto Decomposer::decompose( - const std::pair, - std::vector>& schedule) const - -> std::pair, - std::vector> { - std::vector> U3Layers=transform_to_U3(schedule.first); +auto Decomposer::decompose(const std::vector& singleQubitGateLayers) const + -> std::vector{ + + std::vector> U3Layers=transform_to_U3(singleQubitGateLayers); std::vector NewSingleQubitLayers=std::vector{}; for (const auto& layer: U3Layers) { @@ -221,16 +217,16 @@ auto Decomposer::decompose( // GR(theta_max/2, PI_2)==Global Y due to PI_2 auto sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[1]}); - qc::Operation *op=&sop; - FrontLayer.emplace_back(std::reference_wrapper(*op)); + std::unique_ptr op=std::make_unique(sop); + FrontLayer.emplace_back(std::move(op)); sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[0]}); - op=&sop; - MidLayer.emplace_back(std::reference_wrapper(*op)); + op=std::make_unique(sop); + MidLayer.emplace_back(std::move(op)); sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[2]}); - op=&sop; - MidLayer.emplace_back(std::reference_wrapper(*op)); + op=std::make_unique(sop); + BackLayer.emplace_back(std::move(op)); }//gate::layer std::vector< std::unique_ptr> GR_plus; @@ -241,26 +237,26 @@ auto Decomposer::decompose( GR_minus.emplace_back(new qc::StandardOperation(i,qc::RY,{-1*theta_max/2})); } - for (auto gate:FrontLayer) { - NewLayer.push_back(gate); + for (auto&& gate:FrontLayer) { + NewLayer.push_back(std::move(gate)); } auto cop= qc::CompoundOperation(std::move(GR_plus),true); - qc::Operation *ryp=&cop; - NewLayer.emplace_back(*ryp); + std::unique_ptr ryp=std::make_unique(cop); + NewLayer.emplace_back(std::move(ryp)); - for (auto gate:MidLayer) { - NewLayer.push_back(gate); + for (auto&& gate:MidLayer) { + NewLayer.push_back(std::move(gate)); } cop=qc::CompoundOperation(std::move(GR_minus),true); - qc::Operation *rym=&cop; - NewLayer.emplace_back(*rym); + std::unique_ptr rym=std::make_unique(cop); + NewLayer.emplace_back(std::move(rym)); - for (auto gate:BackLayer) { - NewLayer.push_back(gate); + for (auto&& gate:BackLayer) { + NewLayer.push_back(std::move(gate)); } - NewSingleQubitLayers.push_back(NewLayer); + NewSingleQubitLayers.push_back(std::move(NewLayer)); }//layer::SingleQubitLayers - return std::pair{NewSingleQubitLayers,schedule.second}; + return NewSingleQubitLayers; } }// namespace na::zoned \ No newline at end of file diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index 61ec42027..e7896f309 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -133,9 +133,8 @@ TEST(Test, ThetaZeroAngleTest) { TEST(Test, RXDecompositionTest) { size_t n=1; std::array rx={qc::PI,-qc::PI_2,qc::PI_2}; - //middle entry gamma_minus is -3/2 PI?? EXPECT_THAT(Decomposer::get_decomposition_angles(rx,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); } @@ -170,7 +169,24 @@ TEST_F(DecomposerTest, SingleRXGate) { Decomposer decomposer=Decomposer(n); const auto& sched = scheduler.schedule(qc); - // auto decomp=decomposer.decompose(sched); + auto decomp=decomposer.decompose(sched.first); + //DEcomposition for (PI,0,PI) NOT (PI,-PI_2,PI_2) due to back calculation!! EQUivalent!! + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 5); + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + } TEST_F(DecomposerTest, SingleU3Gate) { From a5df7ff89dcd3ae97f84b04fd28d4c99c822c7c2 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 27 Jan 2026 13:24:34 +0100 Subject: [PATCH 033/110] Added more Tests --- src/na/zoned/decomposer/Decomposer.cpp | 3 +- test/na/zoned/test_decomposer.cpp | 172 +++++++++++++++++++++---- 2 files changed, 148 insertions(+), 27 deletions(-) diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index 45cee0589..f17c6c793 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -116,7 +116,6 @@ auto Decomposer::combine_quaternions(const std::array& q1, phi = alph_1 + alph_2; // phi lambda = alph_1 - alph_2; } else { - // TODO: Which was set to zero??? phi = 0; lambda = 2 * alph_1; } @@ -126,7 +125,7 @@ auto Decomposer::combine_quaternions(const std::array& q1, if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { phi = 0; lambda = 2 * std::atan2(quat[1], quat[2]); - // 2*tan(q1/q2) = phi-lambda, but can't be disentangled + // atan can give PI instead of 0 Problem? } else { // This should never happen! Exception?? phi = 0.; diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index e7896f309..d8b403bc8 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -127,7 +127,6 @@ TEST(Test, ThetaZeroAngleTest) { } -//One or Two Decomposition Tests? TEST(Test, RXDecompositionTest) { @@ -150,10 +149,8 @@ TEST(Test,DoubleDecompositionTest) { size_t n=1; std::array x1={qc::PI,-qc::PI_2,qc::PI_2}; std::array z2={0,0,qc::PI}; - //gamm_min is - 3/2 PI not 0 and gamm_plus is PI_2 not zero EXPECT_THAT(Decomposer::get_decomposition_angles(x1,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); - // gamm_min is 0 not PI_2 and gamm_plus is PI not PI_2 EXPECT_THAT(Decomposer::get_decomposition_angles(z2,qc::PI),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); @@ -170,7 +167,6 @@ TEST_F(DecomposerTest, SingleRXGate) { const auto& sched = scheduler.schedule(qc); auto decomp=decomposer.decompose(sched.first); - //DEcomposition for (PI,0,PI) NOT (PI,-PI_2,PI_2) due to back calculation!! EQUivalent!! EXPECT_EQ(decomp.size(),1); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); @@ -190,18 +186,38 @@ TEST_F(DecomposerTest, SingleRXGate) { } TEST_F(DecomposerTest, SingleU3Gate) { - // ┌───────────────┐ - // q:─┤ U3(π/4,π,π/2) ├─ - // └───────────────┘ - size_t n=1; + // ┌─────────────┐ + // q: ┤ U3(0,π,π/2) ├ + // └─────────────┘ + int n=1; qc::QuantumComputation qc(n); - qc.u(qc::PI_4,qc::PI,qc::PI_2,0); + qc.u(0.0,qc::PI,qc::PI_2, 0); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 5); + + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); } +//TEST with U3(o,?,?) +//TEST with two Single Qubit Layers + TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ // q: ┤ X ├──┤ Z ├ @@ -211,8 +227,26 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { qc.x(0); qc.z(0); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 5); + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + //TODO: FIgure out i this is always Positive + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(3*qc::PI_2,epsilon))); } @@ -229,27 +263,115 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { qc.x(0); qc.z(1); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = - scheduler.schedule(qc); + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp[0].size(), 8); + + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[0][1]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][1]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_TRUE(decomp[0][2]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][2]->isGlobal(n)); + + EXPECT_EQ(decomp[0][3]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][3]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + + EXPECT_TRUE(decomp[0][5]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][5]->isGlobal(n)); + + EXPECT_EQ(decomp[0][6]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][6]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[0][7]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][7]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); } -TEST_F(DecomposerTest, TwoU3GatesTwoQubits) { - // ┌───────────────┐ - // q_0: ─┤ U3(π/4,π,π/2) ├─ - // └───────────────┘ - // ┌───────────────┐ - // q_1: ─┤ U3(π/2,π/2,π) ├─ - // └───────────────┘ +TEST_F(DecomposerTest, TwoQubitsTwoLayers) { + // ┌───────┐ ┌───────┐ + // q_0: ─┤ X ├───■───┤ Z ├─ + // └───────┘ │ └───────┘ + // │ ┌───────┐ + // q_1: ─────────────■───┤ X ├─ + // └───────┘ + size_t n=2; qc::QuantumComputation qc(n); - qc.u(qc::PI_4,qc::PI,qc::PI_2,0); - qc.u(qc::PI_2,qc::PI_2,qc::PI,1); + qc.x(0); + qc.cz(0, 1); + qc.z(0); + qc.x(1); Decomposer decomposer=Decomposer(n); - const auto& [singleQubitGateLayers, twoQubitGateLayers] = - scheduler.schedule(qc); + const auto& sched = scheduler.schedule(qc); + auto decomp=decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(),2); + EXPECT_EQ(decomp[0].size(), 5); + EXPECT_EQ(decomp[1].size(), 8); -} + //Layer 1 + EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][1]->isGlobal(n)); + EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + + EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp[0][3]->isGlobal(n)); + + EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + //Layer 2 + + EXPECT_EQ(decomp[1][0]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][0]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[1][1]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][1]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_TRUE(decomp[1][2]->isCompoundOperation()); + EXPECT_TRUE(decomp[1][2]->isGlobal(n)); + + EXPECT_EQ(decomp[1][3]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][3]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + + EXPECT_EQ(decomp[1][4]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][4]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + + EXPECT_TRUE(decomp[1][5]->isCompoundOperation()); + EXPECT_TRUE(decomp[1][5]->isGlobal(n)); + + EXPECT_EQ(decomp[1][6]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][6]->getTargets(),::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + + EXPECT_EQ(decomp[1][7]->getType(),qc::RZ); + EXPECT_THAT(decomp[1][7]->getTargets(),::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + +} } // namespace na::zoned \ No newline at end of file From 5abc59ade70fac88485bb8d29b8c268615aa7d1f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 01:06:08 +0000 Subject: [PATCH 034/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=AA=9D=20Update?= =?UTF-8?q?=20patch=20versions=20(#917)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [adhtruong/mirrors-typos](https://redirect.github.com/adhtruong/mirrors-typos) | repository | patch | `v1.42.0` → `v1.42.1` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/adhtruong%2fmirrors-typos/v1.42.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/adhtruong%2fmirrors-typos/v1.42.0/v1.42.1?slim=true) | | [astral-sh/ruff-pre-commit](https://redirect.github.com/astral-sh/ruff-pre-commit) | repository | patch | `v0.14.13` → `v0.14.14` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/astral-sh%2fruff-pre-commit/v0.14.14?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/astral-sh%2fruff-pre-commit/v0.14.13/v0.14.14?slim=true) | | [henryiii/validate-pyproject-schema-store](https://redirect.github.com/henryiii/validate-pyproject-schema-store) | repository | patch | `2026.01.10` → `2026.01.22` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/henryiii%2fvalidate-pyproject-schema-store/2026.01.22?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/henryiii%2fvalidate-pyproject-schema-store/2026.01.10/2026.01.22?slim=true) | | [rbubley/mirrors-prettier](https://redirect.github.com/rbubley/mirrors-prettier) | repository | patch | `v3.8.0` → `v3.8.1` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/rbubley%2fmirrors-prettier/v3.8.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/rbubley%2fmirrors-prettier/v3.8.0/v3.8.1?slim=true) | | [ty](https://redirect.github.com/astral-sh/ty) ([changelog](https://redirect.github.com/astral-sh/ty/blob/main/CHANGELOG.md)) | dependency-groups | patch | `==0.0.12` → `==0.0.13` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/ty/0.0.13?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ty/0.0.12/0.0.13?slim=true) | Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://redirect.github.com/renovatebot/renovate/discussions/new) if you have any questions. --- ### Release Notes
adhtruong/mirrors-typos (adhtruong/mirrors-typos) ### [`v1.42.1`](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.0...v1.42.1) [Compare Source](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.0...v1.42.1)
astral-sh/ruff-pre-commit (astral-sh/ruff-pre-commit) ### [`v0.14.14`](https://redirect.github.com/astral-sh/ruff-pre-commit/releases/tag/v0.14.14) [Compare Source](https://redirect.github.com/astral-sh/ruff-pre-commit/compare/v0.14.13...v0.14.14) See:
henryiii/validate-pyproject-schema-store (henryiii/validate-pyproject-schema-store) ### [`v2026.01.22`](https://redirect.github.com/henryiii/validate-pyproject-schema-store/compare/2026.01.10...2026.01.22) [Compare Source](https://redirect.github.com/henryiii/validate-pyproject-schema-store/compare/2026.01.10...2026.01.22)
rbubley/mirrors-prettier (rbubley/mirrors-prettier) ### [`v3.8.1`](https://redirect.github.com/rbubley/mirrors-prettier/compare/v3.8.0...v3.8.1) [Compare Source](https://redirect.github.com/rbubley/mirrors-prettier/compare/v3.8.0...v3.8.1)
astral-sh/ty (ty) ### [`v0.0.13`](https://redirect.github.com/astral-sh/ty/blob/HEAD/CHANGELOG.md#0013) [Compare Source](https://redirect.github.com/astral-sh/ty/compare/0.0.12...0.0.13) Released on 2026-01-21. ##### Bug fixes - Fix `--force-exclude` when excluding entire directories ([#​22595](https://redirect.github.com/astral-sh/ruff/pull/22595)) - Fix missing syntax highlighting for aliased import names ([#​22675](https://redirect.github.com/astral-sh/ruff/pull/22675)) - Highlight interpolated-parts in t-strings ([#​22674](https://redirect.github.com/astral-sh/ruff/pull/22674)) - Fix the inferred MRO of functional namedtuple classes ([#​22722](https://redirect.github.com/astral-sh/ruff/pull/22722)) - Make special cases for subscript inference exhaustive, ensuring that the special casing for tuple subscripts is applied when a union of tuples or an alias to a tuple type is subscripted ([#​22035](https://redirect.github.com/astral-sh/ruff/pull/22035)) ##### LSP server - Improve completion suggestions inside class definitions ([#​22571](https://redirect.github.com/astral-sh/ruff/pull/22571)) - Improve performance of completions ([#​22630](https://redirect.github.com/astral-sh/ruff/pull/22630)) - Remove completion suggestions for redundant re-exports that share the same top-most module ([#​22581](https://redirect.github.com/astral-sh/ruff/pull/22581)) ##### Core type checking - Add basic support for overloads in `ParamSpec` ([#​21946](https://redirect.github.com/astral-sh/ruff/pull/21946)) - Allow `...` as a default value for any parameter if the function is in an `if TYPE_CHECKING` block ([#​22624](https://redirect.github.com/astral-sh/ruff/pull/22624)) - Allow `if type(x) is Y` narrowing for types other than class-literal types ([#​22729](https://redirect.github.com/astral-sh/ruff/pull/22729)) - Avoid overload errors when detecting dataclass-on-tuple ([#​22687](https://redirect.github.com/astral-sh/ruff/pull/22687)) - Avoid reporting overload errors for successful union variants ([#​22688](https://redirect.github.com/astral-sh/ruff/pull/22688)) - Ban `NewType`s with generic bases ([#​22653](https://redirect.github.com/astral-sh/ruff/pull/22653)) - Fix PEP 695 type aliases not expanding in overload resolution ([#​22589](https://redirect.github.com/astral-sh/ruff/pull/22589)) - Fix the return type for synthesized `NamedTuple.__new__` methods ([#​22625](https://redirect.github.com/astral-sh/ruff/pull/22625)) - Emit diagnostics for `NamedTuple`, `TypedDict`, `Enum` or `Protocol` classes decorated with `@dataclass` ([#​22672](https://redirect.github.com/astral-sh/ruff/pull/22672)) - Emit `invalid-type-form` diagnostics for stringified annotations where the quoted expression is invalid ([#​22752](https://redirect.github.com/astral-sh/ruff/pull/22752)) - Infer the implicit type of `cls` in `__new__` methods ([#​22584](https://redirect.github.com/astral-sh/ruff/pull/22584)) - Make `ModuleType` and `object` attributes available on namespace packages ([#​22606](https://redirect.github.com/astral-sh/ruff/pull/22606)) - Make `NamedTuple(...)` and `namedtuple(...)` calls stricter ([#​22601](https://redirect.github.com/astral-sh/ruff/pull/22601)) - Narrow on bool and byte subscripts ([#​22684](https://redirect.github.com/astral-sh/ruff/pull/22684)) - Narrow on negative subscript indexing ([#​22682](https://redirect.github.com/astral-sh/ruff/pull/22682)) - Override `__file__` to `str` when applicable on imported modules ([#​22333](https://redirect.github.com/astral-sh/ruff/pull/22333)) - Add bidirectional inference for comprehensions ([#​22564](https://redirect.github.com/astral-sh/ruff/pull/22564)) - Recognize string-literal types as subtypes of `Sequence[Literal[chars]]` ([#​22415](https://redirect.github.com/astral-sh/ruff/pull/22415)) - Add right-hand-side narrowing for `if Foo is type(x)` expressions ([#​22608](https://redirect.github.com/astral-sh/ruff/pull/22608)) - Add simple syntactic validation for the right-hand side of PEP-613 type aliases ([#​22652](https://redirect.github.com/astral-sh/ruff/pull/22652)) - Add support for passing `typename` and `field_names` by keyword argument to `collections.namedtuple()` calls ([#​22660](https://redirect.github.com/astral-sh/ruff/pull/22660)) - Add support for starred unpacking in class bases ([#​22591](https://redirect.github.com/astral-sh/ruff/pull/22591)) - Validate constructor arguments when a class is used as a decorator ([#​22377](https://redirect.github.com/astral-sh/ruff/pull/22377)) - Validate field names for `typing.NamedTuple(...)` ([#​22599](https://redirect.github.com/astral-sh/ruff/pull/22599)) - Add diagnostic on overridden `__setattr__` and `__delattr__` in frozen dataclasses ([#​21430](https://redirect.github.com/astral-sh/ruff/pull/21430)) - Fix unary operators on `NewType`s of `float` or `complex` ([#​22605](https://redirect.github.com/astral-sh/ruff/pull/22605)) ##### Configuration - Support overriding `respect-type-ignore-comments` ([#​22615](https://redirect.github.com/astral-sh/ruff/pull/22615)) ##### Diagnostics - Don't add a subdiagnostic pointing to the TypeVar definition if the TypeVar is `Self` ([#​22646](https://redirect.github.com/astral-sh/ruff/pull/22646)) - Show final search path instead of "and 1 more paths" ([#​22776](https://redirect.github.com/astral-sh/ruff/pull/22776)) - Group `type[]` elements together when displaying union types ([#​22592](https://redirect.github.com/astral-sh/ruff/pull/22592)) ##### Performance - Cache `ClassType::nearest_disjoint_base` ([#​22065](https://redirect.github.com/astral-sh/ruff/pull/22065)) ##### Other changes - Sync vendored typeshed stubs ([#​22590](https://redirect.github.com/astral-sh/ruff/pull/22590), [Typeshed diff](https://redirect.github.com/python/typeshed/compare/d1d5fe58664b30a0c2dde3cd5c3dc8091f0f16ae...cd8b26b0ceef26cd84ab614088140d48680ac7f7) ##### Contributors - [@​bxff](https://redirect.github.com/bxff) - [@​jhartum](https://redirect.github.com/jhartum) - [@​thejchap](https://redirect.github.com/thejchap) - [@​AlexWaygood](https://redirect.github.com/AlexWaygood) - [@​charliermarsh](https://redirect.github.com/charliermarsh) - [@​RasmusNygren](https://redirect.github.com/RasmusNygren) - [@​mswart](https://redirect.github.com/mswart) - [@​MatthewMckee4](https://redirect.github.com/MatthewMckee4) - [@​11happy](https://redirect.github.com/11happy) - [@​ibraheemdev](https://redirect.github.com/ibraheemdev) - [@​sinon](https://redirect.github.com/sinon) - [@​MichaReiser](https://redirect.github.com/MichaReiser) - [@​carljm](https://redirect.github.com/carljm) - [@​BurntSushi](https://redirect.github.com/BurntSushi) - [@​dhruvmanila](https://redirect.github.com/dhruvmanila) - [@​oconnor663](https://redirect.github.com/oconnor663) - [@​zanieb](https://redirect.github.com/zanieb)
--- ### Configuration 📅 **Schedule**: Branch creation - "every weekend" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 212 +++--- pyproject.toml | 21 +- uv.lock | 1563 ++++++++++++++++----------------------- 3 files changed, 767 insertions(+), 1029 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 83993ae54..758e9ad64 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,118 +1,114 @@ # To run all pre-commit checks, use: # -# uvx prek run -a +# pre-commit run -a # # To install pre-commit hooks that run every time you commit: # -# uv tool install prek -# prek install +# pre-commit install # ci: autoupdate_commit_msg: "⬆️🪝 update pre-commit hooks" - autoupdate_schedule: quarterly autofix_commit_msg: "🎨 pre-commit fixes" + autoupdate_schedule: quarterly skip: [ty-check] repos: - # Priority 0: Fast validation and independent fixers - - ## Standard hooks + # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: + - id: check-added-large-files + args: ["--maxkb=2048"] + - id: check-case-conflict + - id: check-vcs-permalinks - id: check-merge-conflict - priority: 0 + - id: check-symlinks + - id: check-json + - id: check-toml + - id: check-yaml + - id: debug-statements - id: end-of-file-fixer - priority: 1 + - id: mixed-line-ending - id: trailing-whitespace - priority: 1 - - ## Check the pyproject.toml file - - repo: https://github.com/henryiii/validate-pyproject-schema-store - rev: 2026.02.15 - hooks: - - id: validate-pyproject - priority: 0 - ## Check JSON schemata - - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.36.1 + # Clean jupyter notebooks + - repo: https://github.com/srstevenson/nb-clean + rev: 4.0.1 hooks: - - id: check-github-workflows - priority: 0 - - id: check-readthedocs - priority: 0 - - ## Catch common capitalization mistakes - - repo: local - hooks: - - id: disallow-caps - name: Disallow improper capitalization - language: pygrep - entry: \b(Nanobind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum)\b - exclude: ^(\.pre-commit-config\.yaml)$ - priority: 0 - - ## Check for spelling - - repo: https://github.com/adhtruong/mirrors-typos - rev: v1.43.2 + - id: nb-clean + args: + - --remove-empty-cells + - --preserve-cell-metadata + - raw_mimetype + - -- + + # Handling unwanted unicode characters + - repo: https://github.com/sirosen/texthooks + rev: 0.7.1 hooks: - - id: typos - priority: 0 + - id: fix-ligatures + - id: fix-smartquotes - ## Check best practices for scientific Python code - - repo: https://github.com/scientific-python/cookie - rev: 2025.11.21 + # Check for common mistakes + - repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.10.0 hooks: - - id: sp-repo-review - additional_dependencies: ["repo-review[cli]"] - priority: 0 + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal - ## Check for license headers + # Check for license headers - repo: https://github.com/emzeat/mz-lictools rev: v2.9.0 hooks: - id: license-tools - priority: 0 - ## Ensure uv lock file is up-to-date + # Ensure uv lock file is up-to-date - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.10.0 + rev: 0.9.26 hooks: - id: uv-lock - priority: 0 - ## Tidy up BibTeX files - - repo: https://github.com/FlamingTempura/bibtex-tidy - rev: v1.14.0 + # Python linting using ruff + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.14 hooks: - - id: bibtex-tidy - args: - [ - "--align=20", - "--curly", - "--months", - "--blank-lines", - "--sort", - "--strip-enclosing-braces", - "--sort-fields", - "--trailing-commas", - "--remove-empty-fields", - ] - priority: 0 + - id: ruff-check + - id: ruff-format + + # Also run Black on examples in the documentation + - repo: https://github.com/adamchainz/blacken-docs + rev: 1.20.0 + hooks: + - id: blacken-docs + additional_dependencies: [black==25.*] + + ## Static type checking using ty + - repo: local + hooks: + - id: ty-check + name: ty check + entry: uvx python -c "import subprocess; import sys; r = subprocess.run(['uv', 'sync', '--no-install-project', '--inexact']); sys.exit(r.returncode or subprocess.run(['uv', 'run', '--no-sync', 'ty', 'check']).returncode)" + language: unsupported + require_serial: true + types_or: [python, pyi, jupyter] + exclude: ^(docs/|eval/) - # Priority 1: Second-pass fixers + # Check for spelling + - repo: https://github.com/adhtruong/mirrors-typos + rev: v1.42.1 + hooks: + - id: typos - ## Clang-format the C++ part of the code base automatically + # Clang-format the C++ part of the code base automatically - repo: https://github.com/pre-commit/mirrors-clang-format rev: v21.1.8 hooks: - id: clang-format types_or: [c++, c, cuda] - priority: 1 - ## CMake format and lint the CMakeLists.txt files + # CMake format and lint the CMakeLists.txt files - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 hooks: @@ -120,46 +116,58 @@ repos: additional_dependencies: [pyyaml] types: [file] files: (\.cmake|CMakeLists.txt)(.in)?$ - priority: 1 - ## Format configuration files with prettier + # Format configuration files with prettier - repo: https://github.com/rbubley/mirrors-prettier rev: v3.8.1 hooks: - id: prettier types_or: [yaml, markdown, html, css, scss, javascript, json] - priority: 1 - ## Python linting using ruff - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.0 + # Catch common capitalization mistakes + - repo: local hooks: - - id: ruff-format - priority: 1 - - id: ruff-check - require_serial: true - priority: 2 + - id: disallow-caps + name: Disallow improper capitalization + language: pygrep + entry: Nanobind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum + exclude: .pre-commit-config.yaml - # Priority 2+: Final checks and fixers + # Check best practices for scientific Python code + - repo: https://github.com/scientific-python/cookie + rev: 2025.11.21 + hooks: + - id: sp-repo-review + additional_dependencies: ["repo-review[cli]"] - ## Also run Black on examples in the documentation (needs to run after ruff format) - - repo: https://github.com/adamchainz/blacken-docs - rev: 1.20.0 + # Check JSON schemata + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.36.0 hooks: - - id: blacken-docs - language: python - additional_dependencies: [black==26.*] - priority: 2 + - id: check-dependabot + - id: check-github-workflows + - id: check-readthedocs - ## Static type checking using ty (needs to run after lockfile update/ruff format, and ruff lint) - - repo: local + # Check the pyproject.toml file + - repo: https://github.com/henryiii/validate-pyproject-schema-store + rev: 2026.01.22 hooks: - - id: ty-check - name: ty check - entry: uvx python -c "import subprocess; import sys; r = subprocess.run(['uv', 'sync', '--no-install-project', '--inexact']); sys.exit(r.returncode or subprocess.run(['uv', 'run', '--no-sync', 'ty', 'check']).returncode)" - language: unsupported - require_serial: true - types_or: [python, pyi, jupyter] - exclude: ^(docs/|eval/) - pass_filenames: false - priority: 3 + - id: validate-pyproject + + # Tidy up BibTeX files + - repo: https://github.com/FlamingTempura/bibtex-tidy + rev: v1.14.0 + hooks: + - id: bibtex-tidy + args: + [ + "--align=20", + "--curly", + "--months", + "--blank-lines", + "--sort", + "--strip-enclosing-braces", + "--sort-fields", + "--trailing-commas", + "--remove-empty-fields", + ] diff --git a/pyproject.toml b/pyproject.toml index afb0022fe..377ea18d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,10 +8,10 @@ [build-system] requires = [ - "nanobind~=2.11.0", + "nanobind>=2.10.2", "setuptools-scm>=9.2.2", "scikit-build-core>=0.11.6", - "mqt.core~=3.4.1", + "mqt.core~=3.4.0", ] build-backend = "scikit_build_core.build" @@ -51,7 +51,7 @@ classifiers = [ ] requires-python = ">=3.10, != 3.14.1" dependencies = [ - "mqt.core~=3.4.1", + "mqt.core~=3.4.0", "qiskit[qasm3-import]>=1.0.0", "rustworkx[all]>=0.16.0", "typing_extensions>=4.6; python_version < '3.11'", @@ -96,7 +96,8 @@ build-dir = "build/{wheel_tag}/{build_type}" build.targets = [ "mqt-qmap-clifford_synthesis-bindings", "mqt-qmap-hybrid_mapper-bindings", - "mqt-qmap-na-bindings", + "mqt-qmap-na-zoned-bindings", + "mqt-qmap-na-nasp-bindings", "mqt-qmap-sc-bindings", ] @@ -267,7 +268,7 @@ known-first-party = ["mqt.qmap"] "docs/**" = ["T20"] "eval/**" = ["T20"] "noxfile.py" = ["T20", "TID251"] -"*.pyi" = ["D418", "E501", "PYI021"] +"*.pyi" = ["D418", "PYI021"] # "*.pyi" = ["D418", "DOC202", "PYI011", "PYI021"] "*.ipynb" = [ "D", # pydocstyle "E402", # Allow imports to appear anywhere in Jupyter notebooks @@ -294,7 +295,6 @@ anc = "anc" optin = "optin" aer = "aer" iy = "iy" -iz = "iz" ket = "ket" @@ -304,7 +304,6 @@ ignore = [ "MY100", # We use ty instead of mypy "PC140", # We use ty instead of mypy "PC160", # We use a mirror of crate-ci/typos - "PC170", # We do not use rST files anymore ] @@ -386,10 +385,10 @@ exclude = [ [dependency-groups] build = [ - "nanobind~=2.11.0", + "nanobind>=2.10.2", "setuptools-scm>=9.2.2", "scikit-build-core>=0.11.6", - "mqt.core~=3.4.1", + "mqt.core~=3.4.0", ] docs = [ "distinctipy>=1.3.4", @@ -420,11 +419,11 @@ test = [ "pytest-cov>=7.0.0", "pytest-sugar>=1.1.1", "pytest-xdist>=3.8.0", - "mqt.qcec>=3.5.0", + "mqt.qcec>=3.4.0", ] dev = [ {include-group = "build"}, {include-group = "test"}, "nox>=2025.11.12", - "ty==0.0.15", + "ty==0.0.13", ] diff --git a/uv.lock b/uv.lock index 6076cdce2..805e0c628 100644 --- a/uv.lock +++ b/uv.lock @@ -2,18 +2,10 @@ version = 1 revision = 3 requires-python = ">=3.10, !=3.14.1" resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", "python_full_version < '3.11'", ] @@ -70,9 +62,7 @@ name = "astroid" version = "3.3.11" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*'", "python_full_version < '3.11'", ] dependencies = [ @@ -85,22 +75,16 @@ wheels = [ [[package]] name = "astroid" -version = "4.1.0" +version = "4.0.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", ] -sdist = { url = "https://files.pythonhosted.org/packages/b0/79/f1e971b3700bcc24c09b3f0d47745d8404675a74afc10b32df8e4929dfdc/astroid-4.1.0.tar.gz", hash = "sha256:e2fbab37f205a651e6a168cb1e9a6a10677f6fa6a1c21833d113999855b04259", size = 412160, upload-time = "2026-02-09T02:19:57.705Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/ca/c17d0f83016532a1ad87d1de96837164c99d47a3b6bbba28bd597c25b37a/astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3", size = 406224, upload-time = "2026-01-03T22:14:26.096Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/38/b2becedff0bef4af9ff474b82e2dcaefca608b6d24753d0b460c94003d91/astroid-4.1.0-py3-none-any.whl", hash = "sha256:2f8263bc7a33cbe8fc2bf5a3d37cfa8327a3284bf4afe3f47f5f0debba638e36", size = 279168, upload-time = "2026-02-09T02:19:55.89Z" }, + { url = "https://files.pythonhosted.org/packages/ce/66/686ac4fc6ef48f5bacde625adac698f41d5316a9753c2b20bb0931c9d4e2/astroid-4.0.3-py3-none-any.whl", hash = "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14", size = 276443, upload-time = "2026-01-03T22:14:24.412Z" }, ] [[package]] @@ -123,11 +107,11 @@ wheels = [ [[package]] name = "babel" -version = "2.18.0" +version = "2.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, ] [[package]] @@ -440,21 +424,13 @@ name = "contourpy" version = "1.3.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -533,115 +509,101 @@ wheels = [ [[package]] name = "coverage" -version = "7.13.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91", size = 827239, upload-time = "2026-02-09T12:59:03.86Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/44/d4/7827d9ffa34d5d4d752eec907022aa417120936282fc488306f5da08c292/coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415", size = 219152, upload-time = "2026-02-09T12:56:11.974Z" }, - { url = "https://files.pythonhosted.org/packages/35/b0/d69df26607c64043292644dbb9dc54b0856fabaa2cbb1eeee3331cc9e280/coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b", size = 219667, upload-time = "2026-02-09T12:56:13.33Z" }, - { url = "https://files.pythonhosted.org/packages/82/a4/c1523f7c9e47b2271dbf8c2a097e7a1f89ef0d66f5840bb59b7e8814157b/coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a", size = 246425, upload-time = "2026-02-09T12:56:14.552Z" }, - { url = "https://files.pythonhosted.org/packages/f8/02/aa7ec01d1a5023c4b680ab7257f9bfde9defe8fdddfe40be096ac19e8177/coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f", size = 248229, upload-time = "2026-02-09T12:56:16.31Z" }, - { url = "https://files.pythonhosted.org/packages/35/98/85aba0aed5126d896162087ef3f0e789a225697245256fc6181b95f47207/coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012", size = 250106, upload-time = "2026-02-09T12:56:18.024Z" }, - { url = "https://files.pythonhosted.org/packages/96/72/1db59bd67494bc162e3e4cd5fbc7edba2c7026b22f7c8ef1496d58c2b94c/coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def", size = 252021, upload-time = "2026-02-09T12:56:19.272Z" }, - { url = "https://files.pythonhosted.org/packages/9d/97/72899c59c7066961de6e3daa142d459d47d104956db43e057e034f015c8a/coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256", size = 247114, upload-time = "2026-02-09T12:56:21.051Z" }, - { url = "https://files.pythonhosted.org/packages/39/1f/f1885573b5970235e908da4389176936c8933e86cb316b9620aab1585fa2/coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda", size = 248143, upload-time = "2026-02-09T12:56:22.585Z" }, - { url = "https://files.pythonhosted.org/packages/a8/cf/e80390c5b7480b722fa3e994f8202807799b85bc562aa4f1dde209fbb7be/coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92", size = 246152, upload-time = "2026-02-09T12:56:23.748Z" }, - { url = "https://files.pythonhosted.org/packages/44/bf/f89a8350d85572f95412debb0fb9bb4795b1d5b5232bd652923c759e787b/coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c", size = 249959, upload-time = "2026-02-09T12:56:25.209Z" }, - { url = "https://files.pythonhosted.org/packages/f7/6e/612a02aece8178c818df273e8d1642190c4875402ca2ba74514394b27aba/coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58", size = 246416, upload-time = "2026-02-09T12:56:26.475Z" }, - { url = "https://files.pythonhosted.org/packages/cb/98/b5afc39af67c2fa6786b03c3a7091fc300947387ce8914b096db8a73d67a/coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9", size = 247025, upload-time = "2026-02-09T12:56:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/51/30/2bba8ef0682d5bd210c38fe497e12a06c9f8d663f7025e9f5c2c31ce847d/coverage-7.13.4-cp310-cp310-win32.whl", hash = "sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf", size = 221758, upload-time = "2026-02-09T12:56:29.051Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/331f94934cf6c092b8ea59ff868eb587bc8fe0893f02c55bc6c0183a192e/coverage-7.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95", size = 222693, upload-time = "2026-02-09T12:56:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053", size = 219278, upload-time = "2026-02-09T12:56:31.673Z" }, - { url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11", size = 219783, upload-time = "2026-02-09T12:56:33.104Z" }, - { url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa", size = 250200, upload-time = "2026-02-09T12:56:34.474Z" }, - { url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7", size = 252114, upload-time = "2026-02-09T12:56:35.749Z" }, - { url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00", size = 254220, upload-time = "2026-02-09T12:56:37.796Z" }, - { url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef", size = 256164, upload-time = "2026-02-09T12:56:39.016Z" }, - { url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903", size = 250325, upload-time = "2026-02-09T12:56:40.668Z" }, - { url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f", size = 251913, upload-time = "2026-02-09T12:56:41.97Z" }, - { url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299", size = 249974, upload-time = "2026-02-09T12:56:43.323Z" }, - { url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505", size = 253741, upload-time = "2026-02-09T12:56:45.155Z" }, - { url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6", size = 249695, upload-time = "2026-02-09T12:56:46.636Z" }, - { url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9", size = 250599, upload-time = "2026-02-09T12:56:48.13Z" }, - { url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9", size = 221780, upload-time = "2026-02-09T12:56:50.479Z" }, - { url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f", size = 222715, upload-time = "2026-02-09T12:56:51.815Z" }, - { url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f", size = 221385, upload-time = "2026-02-09T12:56:53.194Z" }, - { url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459", size = 219449, upload-time = "2026-02-09T12:56:54.889Z" }, - { url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3", size = 219810, upload-time = "2026-02-09T12:56:56.33Z" }, - { url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634", size = 251308, upload-time = "2026-02-09T12:56:57.858Z" }, - { url = "https://files.pythonhosted.org/packages/5d/a0/2ea570925524ef4e00bb6c82649f5682a77fac5ab910a65c9284de422600/coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3", size = 254052, upload-time = "2026-02-09T12:56:59.754Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ac/45dc2e19a1939098d783c846e130b8f862fbb50d09e0af663988f2f21973/coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa", size = 255165, upload-time = "2026-02-09T12:57:01.287Z" }, - { url = "https://files.pythonhosted.org/packages/2d/4d/26d236ff35abc3b5e63540d3386e4c3b192168c1d96da5cb2f43c640970f/coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3", size = 257432, upload-time = "2026-02-09T12:57:02.637Z" }, - { url = "https://files.pythonhosted.org/packages/ec/55/14a966c757d1348b2e19caf699415a2a4c4f7feaa4bbc6326a51f5c7dd1b/coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a", size = 251716, upload-time = "2026-02-09T12:57:04.056Z" }, - { url = "https://files.pythonhosted.org/packages/77/33/50116647905837c66d28b2af1321b845d5f5d19be9655cb84d4a0ea806b4/coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7", size = 253089, upload-time = "2026-02-09T12:57:05.503Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b4/8efb11a46e3665d92635a56e4f2d4529de6d33f2cb38afd47d779d15fc99/coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc", size = 251232, upload-time = "2026-02-09T12:57:06.879Z" }, - { url = "https://files.pythonhosted.org/packages/51/24/8cd73dd399b812cc76bb0ac260e671c4163093441847ffe058ac9fda1e32/coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47", size = 255299, upload-time = "2026-02-09T12:57:08.245Z" }, - { url = "https://files.pythonhosted.org/packages/03/94/0a4b12f1d0e029ce1ccc1c800944a9984cbe7d678e470bb6d3c6bc38a0da/coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985", size = 250796, upload-time = "2026-02-09T12:57:10.142Z" }, - { url = "https://files.pythonhosted.org/packages/73/44/6002fbf88f6698ca034360ce474c406be6d5a985b3fdb3401128031eef6b/coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0", size = 252673, upload-time = "2026-02-09T12:57:12.197Z" }, - { url = "https://files.pythonhosted.org/packages/de/c6/a0279f7c00e786be75a749a5674e6fa267bcbd8209cd10c9a450c655dfa7/coverage-7.13.4-cp312-cp312-win32.whl", hash = "sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246", size = 221990, upload-time = "2026-02-09T12:57:14.085Z" }, - { url = "https://files.pythonhosted.org/packages/77/4e/c0a25a425fcf5557d9abd18419c95b63922e897bc86c1f327f155ef234a9/coverage-7.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126", size = 222800, upload-time = "2026-02-09T12:57:15.944Z" }, - { url = "https://files.pythonhosted.org/packages/47/ac/92da44ad9a6f4e3a7debd178949d6f3769bedca33830ce9b1dcdab589a37/coverage-7.13.4-cp312-cp312-win_arm64.whl", hash = "sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d", size = 221415, upload-time = "2026-02-09T12:57:17.497Z" }, - { url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9", size = 219474, upload-time = "2026-02-09T12:57:19.332Z" }, - { url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac", size = 219844, upload-time = "2026-02-09T12:57:20.66Z" }, - { url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea", size = 250832, upload-time = "2026-02-09T12:57:22.007Z" }, - { url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b", size = 253434, upload-time = "2026-02-09T12:57:23.339Z" }, - { url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525", size = 254676, upload-time = "2026-02-09T12:57:24.774Z" }, - { url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242", size = 256807, upload-time = "2026-02-09T12:57:26.125Z" }, - { url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148", size = 251058, upload-time = "2026-02-09T12:57:27.614Z" }, - { url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a", size = 252805, upload-time = "2026-02-09T12:57:29.066Z" }, - { url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23", size = 250766, upload-time = "2026-02-09T12:57:30.522Z" }, - { url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80", size = 254923, upload-time = "2026-02-09T12:57:31.946Z" }, - { url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea", size = 250591, upload-time = "2026-02-09T12:57:33.842Z" }, - { url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a", size = 252364, upload-time = "2026-02-09T12:57:35.743Z" }, - { url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl", hash = "sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d", size = 222010, upload-time = "2026-02-09T12:57:37.25Z" }, - { url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd", size = 222818, upload-time = "2026-02-09T12:57:38.734Z" }, - { url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl", hash = "sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af", size = 221438, upload-time = "2026-02-09T12:57:40.223Z" }, - { url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d", size = 220165, upload-time = "2026-02-09T12:57:41.639Z" }, - { url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12", size = 220516, upload-time = "2026-02-09T12:57:44.215Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b", size = 261804, upload-time = "2026-02-09T12:57:45.989Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9", size = 263885, upload-time = "2026-02-09T12:57:47.42Z" }, - { url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092", size = 266308, upload-time = "2026-02-09T12:57:49.345Z" }, - { url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9", size = 267452, upload-time = "2026-02-09T12:57:50.811Z" }, - { url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26", size = 261057, upload-time = "2026-02-09T12:57:52.447Z" }, - { url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2", size = 263875, upload-time = "2026-02-09T12:57:53.938Z" }, - { url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940", size = 261500, upload-time = "2026-02-09T12:57:56.012Z" }, - { url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c", size = 265212, upload-time = "2026-02-09T12:57:57.5Z" }, - { url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0", size = 260398, upload-time = "2026-02-09T12:57:59.027Z" }, - { url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b", size = 262584, upload-time = "2026-02-09T12:58:01.129Z" }, - { url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl", hash = "sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9", size = 222688, upload-time = "2026-02-09T12:58:02.736Z" }, - { url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl", hash = "sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd", size = 223746, upload-time = "2026-02-09T12:58:05.362Z" }, - { url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl", hash = "sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997", size = 222003, upload-time = "2026-02-09T12:58:06.952Z" }, - { url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601", size = 219522, upload-time = "2026-02-09T12:58:08.623Z" }, - { url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689", size = 219855, upload-time = "2026-02-09T12:58:10.176Z" }, - { url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c", size = 250887, upload-time = "2026-02-09T12:58:12.503Z" }, - { url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129", size = 253396, upload-time = "2026-02-09T12:58:14.615Z" }, - { url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552", size = 254745, upload-time = "2026-02-09T12:58:16.162Z" }, - { url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a", size = 257055, upload-time = "2026-02-09T12:58:17.892Z" }, - { url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356", size = 250911, upload-time = "2026-02-09T12:58:19.495Z" }, - { url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71", size = 252754, upload-time = "2026-02-09T12:58:21.064Z" }, - { url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5", size = 250720, upload-time = "2026-02-09T12:58:22.622Z" }, - { url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98", size = 254994, upload-time = "2026-02-09T12:58:24.548Z" }, - { url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5", size = 250531, upload-time = "2026-02-09T12:58:26.271Z" }, - { url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0", size = 252189, upload-time = "2026-02-09T12:58:27.807Z" }, - { url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl", hash = "sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb", size = 222258, upload-time = "2026-02-09T12:58:29.441Z" }, - { url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505", size = 223073, upload-time = "2026-02-09T12:58:31.026Z" }, - { url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl", hash = "sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2", size = 221638, upload-time = "2026-02-09T12:58:32.599Z" }, - { url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056", size = 220246, upload-time = "2026-02-09T12:58:34.181Z" }, - { url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc", size = 220514, upload-time = "2026-02-09T12:58:35.704Z" }, - { url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9", size = 261877, upload-time = "2026-02-09T12:58:37.864Z" }, - { url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf", size = 264004, upload-time = "2026-02-09T12:58:39.492Z" }, - { url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55", size = 266408, upload-time = "2026-02-09T12:58:41.852Z" }, - { url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72", size = 267544, upload-time = "2026-02-09T12:58:44.093Z" }, - { url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a", size = 260980, upload-time = "2026-02-09T12:58:45.721Z" }, - { url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6", size = 263871, upload-time = "2026-02-09T12:58:47.334Z" }, - { url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3", size = 261472, upload-time = "2026-02-09T12:58:48.995Z" }, - { url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750", size = 265210, upload-time = "2026-02-09T12:58:51.178Z" }, - { url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39", size = 260319, upload-time = "2026-02-09T12:58:53.081Z" }, - { url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0", size = 262638, upload-time = "2026-02-09T12:58:55.258Z" }, - { url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl", hash = "sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea", size = 223040, upload-time = "2026-02-09T12:58:56.936Z" }, - { url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932", size = 224148, upload-time = "2026-02-09T12:58:58.645Z" }, - { url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl", hash = "sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b", size = 222172, upload-time = "2026-02-09T12:59:00.396Z" }, - { url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0", size = 211242, upload-time = "2026-02-09T12:59:02.032Z" }, +version = "7.13.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/f9/e92df5e07f3fc8d4c7f9a0f146ef75446bf870351cd37b788cf5897f8079/coverage-7.13.1.tar.gz", hash = "sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd", size = 825862, upload-time = "2025-12-28T15:42:56.969Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/9a/3742e58fd04b233df95c012ee9f3dfe04708a5e1d32613bd2d47d4e1be0d/coverage-7.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1fa280b3ad78eea5be86f94f461c04943d942697e0dac889fa18fff8f5f9147", size = 218633, upload-time = "2025-12-28T15:40:10.165Z" }, + { url = "https://files.pythonhosted.org/packages/7e/45/7e6bdc94d89cd7c8017ce735cf50478ddfe765d4fbf0c24d71d30ea33d7a/coverage-7.13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c3d8c679607220979434f494b139dfb00131ebf70bb406553d69c1ff01a5c33d", size = 219147, upload-time = "2025-12-28T15:40:12.069Z" }, + { url = "https://files.pythonhosted.org/packages/f7/38/0d6a258625fd7f10773fe94097dc16937a5f0e3e0cdf3adef67d3ac6baef/coverage-7.13.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:339dc63b3eba969067b00f41f15ad161bf2946613156fb131266d8debc8e44d0", size = 245894, upload-time = "2025-12-28T15:40:13.556Z" }, + { url = "https://files.pythonhosted.org/packages/27/58/409d15ea487986994cbd4d06376e9860e9b157cfbfd402b1236770ab8dd2/coverage-7.13.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:db622b999ffe49cb891f2fff3b340cdc2f9797d01a0a202a0973ba2562501d90", size = 247721, upload-time = "2025-12-28T15:40:15.37Z" }, + { url = "https://files.pythonhosted.org/packages/da/bf/6e8056a83fd7a96c93341f1ffe10df636dd89f26d5e7b9ca511ce3bcf0df/coverage-7.13.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1443ba9acbb593fa7c1c29e011d7c9761545fe35e7652e85ce7f51a16f7e08d", size = 249585, upload-time = "2025-12-28T15:40:17.226Z" }, + { url = "https://files.pythonhosted.org/packages/f4/15/e1daff723f9f5959acb63cbe35b11203a9df77ee4b95b45fffd38b318390/coverage-7.13.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c832ec92c4499ac463186af72f9ed4d8daec15499b16f0a879b0d1c8e5cf4a3b", size = 246597, upload-time = "2025-12-28T15:40:19.028Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/1efd31c5433743a6ddbc9d37ac30c196bb07c7eab3d74fbb99b924c93174/coverage-7.13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:562ec27dfa3f311e0db1ba243ec6e5f6ab96b1edfcfc6cf86f28038bc4961ce6", size = 247626, upload-time = "2025-12-28T15:40:20.846Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9f/1609267dd3e749f57fdd66ca6752567d1c13b58a20a809dc409b263d0b5f/coverage-7.13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4de84e71173d4dada2897e5a0e1b7877e5eefbfe0d6a44edee6ce31d9b8ec09e", size = 245629, upload-time = "2025-12-28T15:40:22.397Z" }, + { url = "https://files.pythonhosted.org/packages/e2/f6/6815a220d5ec2466383d7cc36131b9fa6ecbe95c50ec52a631ba733f306a/coverage-7.13.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a5a68357f686f8c4d527a2dc04f52e669c2fc1cbde38f6f7eb6a0e58cbd17cae", size = 245901, upload-time = "2025-12-28T15:40:23.836Z" }, + { url = "https://files.pythonhosted.org/packages/ac/58/40576554cd12e0872faf6d2c0eb3bc85f71d78427946ddd19ad65201e2c0/coverage-7.13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:77cc258aeb29a3417062758975521eae60af6f79e930d6993555eeac6a8eac29", size = 246505, upload-time = "2025-12-28T15:40:25.421Z" }, + { url = "https://files.pythonhosted.org/packages/3b/77/9233a90253fba576b0eee81707b5781d0e21d97478e5377b226c5b096c0f/coverage-7.13.1-cp310-cp310-win32.whl", hash = "sha256:bb4f8c3c9a9f34423dba193f241f617b08ffc63e27f67159f60ae6baf2dcfe0f", size = 221257, upload-time = "2025-12-28T15:40:27.217Z" }, + { url = "https://files.pythonhosted.org/packages/e0/43/e842ff30c1a0a623ec80db89befb84a3a7aad7bfe44a6ea77d5a3e61fedd/coverage-7.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:c8e2706ceb622bc63bac98ebb10ef5da80ed70fbd8a7999a5076de3afaef0fb1", size = 222191, upload-time = "2025-12-28T15:40:28.916Z" }, + { url = "https://files.pythonhosted.org/packages/b4/9b/77baf488516e9ced25fc215a6f75d803493fc3f6a1a1227ac35697910c2a/coverage-7.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a55d509a1dc5a5b708b5dad3b5334e07a16ad4c2185e27b40e4dba796ab7f88", size = 218755, upload-time = "2025-12-28T15:40:30.812Z" }, + { url = "https://files.pythonhosted.org/packages/d7/cd/7ab01154e6eb79ee2fab76bf4d89e94c6648116557307ee4ebbb85e5c1bf/coverage-7.13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d010d080c4888371033baab27e47c9df7d6fb28d0b7b7adf85a4a49be9298b3", size = 219257, upload-time = "2025-12-28T15:40:32.333Z" }, + { url = "https://files.pythonhosted.org/packages/01/d5/b11ef7863ffbbdb509da0023fad1e9eda1c0eaea61a6d2ea5b17d4ac706e/coverage-7.13.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d938b4a840fb1523b9dfbbb454f652967f18e197569c32266d4d13f37244c3d9", size = 249657, upload-time = "2025-12-28T15:40:34.1Z" }, + { url = "https://files.pythonhosted.org/packages/f7/7c/347280982982383621d29b8c544cf497ae07ac41e44b1ca4903024131f55/coverage-7.13.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bf100a3288f9bb7f919b87eb84f87101e197535b9bd0e2c2b5b3179633324fee", size = 251581, upload-time = "2025-12-28T15:40:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/82/f6/ebcfed11036ade4c0d75fa4453a6282bdd225bc073862766eec184a4c643/coverage-7.13.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef6688db9bf91ba111ae734ba6ef1a063304a881749726e0d3575f5c10a9facf", size = 253691, upload-time = "2025-12-28T15:40:37.626Z" }, + { url = "https://files.pythonhosted.org/packages/02/92/af8f5582787f5d1a8b130b2dcba785fa5e9a7a8e121a0bb2220a6fdbdb8a/coverage-7.13.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0b609fc9cdbd1f02e51f67f51e5aee60a841ef58a68d00d5ee2c0faf357481a3", size = 249799, upload-time = "2025-12-28T15:40:39.47Z" }, + { url = "https://files.pythonhosted.org/packages/24/aa/0e39a2a3b16eebf7f193863323edbff38b6daba711abaaf807d4290cf61a/coverage-7.13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c43257717611ff5e9a1d79dce8e47566235ebda63328718d9b65dd640bc832ef", size = 251389, upload-time = "2025-12-28T15:40:40.954Z" }, + { url = "https://files.pythonhosted.org/packages/73/46/7f0c13111154dc5b978900c0ccee2e2ca239b910890e674a77f1363d483e/coverage-7.13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e09fbecc007f7b6afdfb3b07ce5bd9f8494b6856dd4f577d26c66c391b829851", size = 249450, upload-time = "2025-12-28T15:40:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ca/e80da6769e8b669ec3695598c58eef7ad98b0e26e66333996aee6316db23/coverage-7.13.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a03a4f3a19a189919c7055098790285cc5c5b0b3976f8d227aea39dbf9f8bfdb", size = 249170, upload-time = "2025-12-28T15:40:44.279Z" }, + { url = "https://files.pythonhosted.org/packages/af/18/9e29baabdec1a8644157f572541079b4658199cfd372a578f84228e860de/coverage-7.13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3820778ea1387c2b6a818caec01c63adc5b3750211af6447e8dcfb9b6f08dbba", size = 250081, upload-time = "2025-12-28T15:40:45.748Z" }, + { url = "https://files.pythonhosted.org/packages/00/f8/c3021625a71c3b2f516464d322e41636aea381018319050a8114105872ee/coverage-7.13.1-cp311-cp311-win32.whl", hash = "sha256:ff10896fa55167371960c5908150b434b71c876dfab97b69478f22c8b445ea19", size = 221281, upload-time = "2025-12-28T15:40:47.232Z" }, + { url = "https://files.pythonhosted.org/packages/27/56/c216625f453df6e0559ed666d246fcbaaa93f3aa99eaa5080cea1229aa3d/coverage-7.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:a998cc0aeeea4c6d5622a3754da5a493055d2d95186bad877b0a34ea6e6dbe0a", size = 222215, upload-time = "2025-12-28T15:40:49.19Z" }, + { url = "https://files.pythonhosted.org/packages/5c/9a/be342e76f6e531cae6406dc46af0d350586f24d9b67fdfa6daee02df71af/coverage-7.13.1-cp311-cp311-win_arm64.whl", hash = "sha256:fea07c1a39a22614acb762e3fbbb4011f65eedafcb2948feeef641ac78b4ee5c", size = 220886, upload-time = "2025-12-28T15:40:51.067Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8a/87af46cccdfa78f53db747b09f5f9a21d5fc38d796834adac09b30a8ce74/coverage-7.13.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3", size = 218927, upload-time = "2025-12-28T15:40:52.814Z" }, + { url = "https://files.pythonhosted.org/packages/82/a8/6e22fdc67242a4a5a153f9438d05944553121c8f4ba70cb072af4c41362e/coverage-7.13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e", size = 219288, upload-time = "2025-12-28T15:40:54.262Z" }, + { url = "https://files.pythonhosted.org/packages/d0/0a/853a76e03b0f7c4375e2ca025df45c918beb367f3e20a0a8e91967f6e96c/coverage-7.13.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c", size = 250786, upload-time = "2025-12-28T15:40:56.059Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b4/694159c15c52b9f7ec7adf49d50e5f8ee71d3e9ef38adb4445d13dd56c20/coverage-7.13.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62", size = 253543, upload-time = "2025-12-28T15:40:57.585Z" }, + { url = "https://files.pythonhosted.org/packages/96/b2/7f1f0437a5c855f87e17cf5d0dc35920b6440ff2b58b1ba9788c059c26c8/coverage-7.13.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968", size = 254635, upload-time = "2025-12-28T15:40:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/e9/d1/73c3fdb8d7d3bddd9473c9c6a2e0682f09fc3dfbcb9c3f36412a7368bcab/coverage-7.13.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e", size = 251202, upload-time = "2025-12-28T15:41:01.328Z" }, + { url = "https://files.pythonhosted.org/packages/66/3c/f0edf75dcc152f145d5598329e864bbbe04ab78660fe3e8e395f9fff010f/coverage-7.13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f", size = 252566, upload-time = "2025-12-28T15:41:03.319Z" }, + { url = "https://files.pythonhosted.org/packages/17/b3/e64206d3c5f7dcbceafd14941345a754d3dbc78a823a6ed526e23b9cdaab/coverage-7.13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee", size = 250711, upload-time = "2025-12-28T15:41:06.411Z" }, + { url = "https://files.pythonhosted.org/packages/dc/ad/28a3eb970a8ef5b479ee7f0c484a19c34e277479a5b70269dc652b730733/coverage-7.13.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf", size = 250278, upload-time = "2025-12-28T15:41:08.285Z" }, + { url = "https://files.pythonhosted.org/packages/54/e3/c8f0f1a93133e3e1291ca76cbb63565bd4b5c5df63b141f539d747fff348/coverage-7.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c", size = 252154, upload-time = "2025-12-28T15:41:09.969Z" }, + { url = "https://files.pythonhosted.org/packages/d0/bf/9939c5d6859c380e405b19e736321f1c7d402728792f4c752ad1adcce005/coverage-7.13.1-cp312-cp312-win32.whl", hash = "sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7", size = 221487, upload-time = "2025-12-28T15:41:11.468Z" }, + { url = "https://files.pythonhosted.org/packages/fa/dc/7282856a407c621c2aad74021680a01b23010bb8ebf427cf5eacda2e876f/coverage-7.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6", size = 222299, upload-time = "2025-12-28T15:41:13.386Z" }, + { url = "https://files.pythonhosted.org/packages/10/79/176a11203412c350b3e9578620013af35bcdb79b651eb976f4a4b32044fa/coverage-7.13.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c", size = 220941, upload-time = "2025-12-28T15:41:14.975Z" }, + { url = "https://files.pythonhosted.org/packages/a3/a4/e98e689347a1ff1a7f67932ab535cef82eb5e78f32a9e4132e114bbb3a0a/coverage-7.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78", size = 218951, upload-time = "2025-12-28T15:41:16.653Z" }, + { url = "https://files.pythonhosted.org/packages/32/33/7cbfe2bdc6e2f03d6b240d23dc45fdaf3fd270aaf2d640be77b7f16989ab/coverage-7.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b", size = 219325, upload-time = "2025-12-28T15:41:18.609Z" }, + { url = "https://files.pythonhosted.org/packages/59/f6/efdabdb4929487baeb7cb2a9f7dac457d9356f6ad1b255be283d58b16316/coverage-7.13.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd", size = 250309, upload-time = "2025-12-28T15:41:20.629Z" }, + { url = "https://files.pythonhosted.org/packages/12/da/91a52516e9d5aea87d32d1523f9cdcf7a35a3b298e6be05d6509ba3cfab2/coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992", size = 252907, upload-time = "2025-12-28T15:41:22.257Z" }, + { url = "https://files.pythonhosted.org/packages/75/38/f1ea837e3dc1231e086db1638947e00d264e7e8c41aa8ecacf6e1e0c05f4/coverage-7.13.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4", size = 254148, upload-time = "2025-12-28T15:41:23.87Z" }, + { url = "https://files.pythonhosted.org/packages/7f/43/f4f16b881aaa34954ba446318dea6b9ed5405dd725dd8daac2358eda869a/coverage-7.13.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a", size = 250515, upload-time = "2025-12-28T15:41:25.437Z" }, + { url = "https://files.pythonhosted.org/packages/84/34/8cba7f00078bd468ea914134e0144263194ce849ec3baad187ffb6203d1c/coverage-7.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766", size = 252292, upload-time = "2025-12-28T15:41:28.459Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/cffac66c7652d84ee4ac52d3ccb94c015687d3b513f9db04bfcac2ac800d/coverage-7.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4", size = 250242, upload-time = "2025-12-28T15:41:30.02Z" }, + { url = "https://files.pythonhosted.org/packages/f4/78/9a64d462263dde416f3c0067efade7b52b52796f489b1037a95b0dc389c9/coverage-7.13.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398", size = 250068, upload-time = "2025-12-28T15:41:32.007Z" }, + { url = "https://files.pythonhosted.org/packages/69/c8/a8994f5fece06db7c4a97c8fc1973684e178599b42e66280dded0524ef00/coverage-7.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784", size = 251846, upload-time = "2025-12-28T15:41:33.946Z" }, + { url = "https://files.pythonhosted.org/packages/cc/f7/91fa73c4b80305c86598a2d4e54ba22df6bf7d0d97500944af7ef155d9f7/coverage-7.13.1-cp313-cp313-win32.whl", hash = "sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461", size = 221512, upload-time = "2025-12-28T15:41:35.519Z" }, + { url = "https://files.pythonhosted.org/packages/45/0b/0768b4231d5a044da8f75e097a8714ae1041246bb765d6b5563bab456735/coverage-7.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500", size = 222321, upload-time = "2025-12-28T15:41:37.371Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b8/bdcb7253b7e85157282450262008f1366aa04663f3e3e4c30436f596c3e2/coverage-7.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9", size = 220949, upload-time = "2025-12-28T15:41:39.553Z" }, + { url = "https://files.pythonhosted.org/packages/70/52/f2be52cc445ff75ea8397948c96c1b4ee14f7f9086ea62fc929c5ae7b717/coverage-7.13.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc", size = 219643, upload-time = "2025-12-28T15:41:41.567Z" }, + { url = "https://files.pythonhosted.org/packages/47/79/c85e378eaa239e2edec0c5523f71542c7793fe3340954eafb0bc3904d32d/coverage-7.13.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a", size = 219997, upload-time = "2025-12-28T15:41:43.418Z" }, + { url = "https://files.pythonhosted.org/packages/fe/9b/b1ade8bfb653c0bbce2d6d6e90cc6c254cbb99b7248531cc76253cb4da6d/coverage-7.13.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4", size = 261296, upload-time = "2025-12-28T15:41:45.207Z" }, + { url = "https://files.pythonhosted.org/packages/1f/af/ebf91e3e1a2473d523e87e87fd8581e0aa08741b96265730e2d79ce78d8d/coverage-7.13.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6", size = 263363, upload-time = "2025-12-28T15:41:47.163Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8b/fb2423526d446596624ac7fde12ea4262e66f86f5120114c3cfd0bb2befa/coverage-7.13.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1", size = 265783, upload-time = "2025-12-28T15:41:49.03Z" }, + { url = "https://files.pythonhosted.org/packages/9b/26/ef2adb1e22674913b89f0fe7490ecadcef4a71fa96f5ced90c60ec358789/coverage-7.13.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd", size = 260508, upload-time = "2025-12-28T15:41:51.035Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7d/f0f59b3404caf662e7b5346247883887687c074ce67ba453ea08c612b1d5/coverage-7.13.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c", size = 263357, upload-time = "2025-12-28T15:41:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b1/29896492b0b1a047604d35d6fa804f12818fa30cdad660763a5f3159e158/coverage-7.13.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0", size = 260978, upload-time = "2025-12-28T15:41:54.589Z" }, + { url = "https://files.pythonhosted.org/packages/48/f2/971de1238a62e6f0a4128d37adadc8bb882ee96afbe03ff1570291754629/coverage-7.13.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e", size = 259877, upload-time = "2025-12-28T15:41:56.263Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fc/0474efcbb590ff8628830e9aaec5f1831594874360e3251f1fdec31d07a3/coverage-7.13.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53", size = 262069, upload-time = "2025-12-28T15:41:58.093Z" }, + { url = "https://files.pythonhosted.org/packages/88/4f/3c159b7953db37a7b44c0eab8a95c37d1aa4257c47b4602c04022d5cb975/coverage-7.13.1-cp313-cp313t-win32.whl", hash = "sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842", size = 222184, upload-time = "2025-12-28T15:41:59.763Z" }, + { url = "https://files.pythonhosted.org/packages/58/a5/6b57d28f81417f9335774f20679d9d13b9a8fb90cd6160957aa3b54a2379/coverage-7.13.1-cp313-cp313t-win_amd64.whl", hash = "sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2", size = 223250, upload-time = "2025-12-28T15:42:01.52Z" }, + { url = "https://files.pythonhosted.org/packages/81/7c/160796f3b035acfbb58be80e02e484548595aa67e16a6345e7910ace0a38/coverage-7.13.1-cp313-cp313t-win_arm64.whl", hash = "sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09", size = 221521, upload-time = "2025-12-28T15:42:03.275Z" }, + { url = "https://files.pythonhosted.org/packages/aa/8e/ba0e597560c6563fc0adb902fda6526df5d4aa73bb10adf0574d03bd2206/coverage-7.13.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894", size = 218996, upload-time = "2025-12-28T15:42:04.978Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8e/764c6e116f4221dc7aa26c4061181ff92edb9c799adae6433d18eeba7a14/coverage-7.13.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a", size = 219326, upload-time = "2025-12-28T15:42:06.691Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a6/6130dc6d8da28cdcbb0f2bf8865aeca9b157622f7c0031e48c6cf9a0e591/coverage-7.13.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f", size = 250374, upload-time = "2025-12-28T15:42:08.786Z" }, + { url = "https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909", size = 252882, upload-time = "2025-12-28T15:42:10.515Z" }, + { url = "https://files.pythonhosted.org/packages/cd/b2/9808766d082e6a4d59eb0cc881a57fc1600eb2c5882813eefff8254f71b5/coverage-7.13.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4", size = 254218, upload-time = "2025-12-28T15:42:12.208Z" }, + { url = "https://files.pythonhosted.org/packages/44/ea/52a985bb447c871cb4d2e376e401116520991b597c85afdde1ea9ef54f2c/coverage-7.13.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75", size = 250391, upload-time = "2025-12-28T15:42:14.21Z" }, + { url = "https://files.pythonhosted.org/packages/7f/1d/125b36cc12310718873cfc8209ecfbc1008f14f4f5fa0662aa608e579353/coverage-7.13.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9", size = 252239, upload-time = "2025-12-28T15:42:16.292Z" }, + { url = "https://files.pythonhosted.org/packages/6a/16/10c1c164950cade470107f9f14bbac8485f8fb8515f515fca53d337e4a7f/coverage-7.13.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465", size = 250196, upload-time = "2025-12-28T15:42:18.54Z" }, + { url = "https://files.pythonhosted.org/packages/2a/c6/cd860fac08780c6fd659732f6ced1b40b79c35977c1356344e44d72ba6c4/coverage-7.13.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864", size = 250008, upload-time = "2025-12-28T15:42:20.365Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/a8c58d3d38f82a5711e1e0a67268362af48e1a03df27c03072ac30feefcf/coverage-7.13.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9", size = 251671, upload-time = "2025-12-28T15:42:22.114Z" }, + { url = "https://files.pythonhosted.org/packages/f0/bc/fd4c1da651d037a1e3d53e8cb3f8182f4b53271ffa9a95a2e211bacc0349/coverage-7.13.1-cp314-cp314-win32.whl", hash = "sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5", size = 221777, upload-time = "2025-12-28T15:42:23.919Z" }, + { url = "https://files.pythonhosted.org/packages/4b/50/71acabdc8948464c17e90b5ffd92358579bd0910732c2a1c9537d7536aa6/coverage-7.13.1-cp314-cp314-win_amd64.whl", hash = "sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a", size = 222592, upload-time = "2025-12-28T15:42:25.619Z" }, + { url = "https://files.pythonhosted.org/packages/f7/c8/a6fb943081bb0cc926499c7907731a6dc9efc2cbdc76d738c0ab752f1a32/coverage-7.13.1-cp314-cp314-win_arm64.whl", hash = "sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0", size = 221169, upload-time = "2025-12-28T15:42:27.629Z" }, + { url = "https://files.pythonhosted.org/packages/16/61/d5b7a0a0e0e40d62e59bc8c7aa1afbd86280d82728ba97f0673b746b78e2/coverage-7.13.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a", size = 219730, upload-time = "2025-12-28T15:42:29.306Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2c/8881326445fd071bb49514d1ce97d18a46a980712b51fee84f9ab42845b4/coverage-7.13.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6", size = 220001, upload-time = "2025-12-28T15:42:31.319Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d7/50de63af51dfa3a7f91cc37ad8fcc1e244b734232fbc8b9ab0f3c834a5cd/coverage-7.13.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673", size = 261370, upload-time = "2025-12-28T15:42:32.992Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2c/d31722f0ec918fd7453b2758312729f645978d212b410cd0f7c2aed88a94/coverage-7.13.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5", size = 263485, upload-time = "2025-12-28T15:42:34.759Z" }, + { url = "https://files.pythonhosted.org/packages/fa/7a/2c114fa5c5fc08ba0777e4aec4c97e0b4a1afcb69c75f1f54cff78b073ab/coverage-7.13.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d", size = 265890, upload-time = "2025-12-28T15:42:36.517Z" }, + { url = "https://files.pythonhosted.org/packages/65/d9/f0794aa1c74ceabc780fe17f6c338456bbc4e96bd950f2e969f48ac6fb20/coverage-7.13.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8", size = 260445, upload-time = "2025-12-28T15:42:38.646Z" }, + { url = "https://files.pythonhosted.org/packages/49/23/184b22a00d9bb97488863ced9454068c79e413cb23f472da6cbddc6cfc52/coverage-7.13.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486", size = 263357, upload-time = "2025-12-28T15:42:40.788Z" }, + { url = "https://files.pythonhosted.org/packages/7d/bd/58af54c0c9199ea4190284f389005779d7daf7bf3ce40dcd2d2b2f96da69/coverage-7.13.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564", size = 260959, upload-time = "2025-12-28T15:42:42.808Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2a/6839294e8f78a4891bf1df79d69c536880ba2f970d0ff09e7513d6e352e9/coverage-7.13.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7", size = 259792, upload-time = "2025-12-28T15:42:44.818Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c3/528674d4623283310ad676c5af7414b9850ab6d55c2300e8aa4b945ec554/coverage-7.13.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416", size = 262123, upload-time = "2025-12-28T15:42:47.108Z" }, + { url = "https://files.pythonhosted.org/packages/06/c5/8c0515692fb4c73ac379d8dc09b18eaf0214ecb76ea6e62467ba7a1556ff/coverage-7.13.1-cp314-cp314t-win32.whl", hash = "sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f", size = 222562, upload-time = "2025-12-28T15:42:49.144Z" }, + { url = "https://files.pythonhosted.org/packages/05/0e/c0a0c4678cb30dac735811db529b321d7e1c9120b79bd728d4f4d6b010e9/coverage-7.13.1-cp314-cp314t-win_amd64.whl", hash = "sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79", size = 223670, upload-time = "2025-12-28T15:42:51.218Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5f/b177aa0011f354abf03a8f30a85032686d290fdeed4222b27d36b4372a50/coverage-7.13.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4", size = 221707, upload-time = "2025-12-28T15:42:53.034Z" }, + { url = "https://files.pythonhosted.org/packages/cc/48/d9f421cb8da5afaa1a64570d9989e00fb7955e6acddc5a12979f7666ef60/coverage-7.13.1-py3-none-any.whl", hash = "sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573", size = 210722, upload-time = "2025-12-28T15:42:54.901Z" }, ] [package.optional-dependencies] @@ -660,31 +622,31 @@ wheels = [ [[package]] name = "debugpy" -version = "1.8.20" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/71/be/8bd693a0b9d53d48c8978fa5d889e06f3b5b03e45fd1ea1e78267b4887cb/debugpy-1.8.20-cp310-cp310-macosx_15_0_x86_64.whl", hash = "sha256:157e96ffb7f80b3ad36d808646198c90acb46fdcfd8bb1999838f0b6f2b59c64", size = 2099192, upload-time = "2026-01-29T23:03:29.707Z" }, - { url = "https://files.pythonhosted.org/packages/77/1b/85326d07432086a06361d493d2743edd0c4fc2ef62162be7f8618441ac37/debugpy-1.8.20-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:c1178ae571aff42e61801a38b007af504ec8e05fde1c5c12e5a7efef21009642", size = 3088568, upload-time = "2026-01-29T23:03:31.467Z" }, - { url = "https://files.pythonhosted.org/packages/e8/60/3e08462ee3eccd10998853eb35947c416e446bfe2bc37dbb886b9044586c/debugpy-1.8.20-cp310-cp310-win32.whl", hash = "sha256:c29dd9d656c0fbd77906a6e6a82ae4881514aa3294b94c903ff99303e789b4a2", size = 5284399, upload-time = "2026-01-29T23:03:33.678Z" }, - { url = "https://files.pythonhosted.org/packages/72/43/09d49106e770fe558ced5e80df2e3c2ebee10e576eda155dcc5670473663/debugpy-1.8.20-cp310-cp310-win_amd64.whl", hash = "sha256:3ca85463f63b5dd0aa7aaa933d97cbc47c174896dcae8431695872969f981893", size = 5316388, upload-time = "2026-01-29T23:03:35.095Z" }, - { url = "https://files.pythonhosted.org/packages/51/56/c3baf5cbe4dd77427fd9aef99fcdade259ad128feeb8a786c246adb838e5/debugpy-1.8.20-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b", size = 2208318, upload-time = "2026-01-29T23:03:36.481Z" }, - { url = "https://files.pythonhosted.org/packages/9a/7d/4fa79a57a8e69fe0d9763e98d1110320f9ecd7f1f362572e3aafd7417c9d/debugpy-1.8.20-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344", size = 3171493, upload-time = "2026-01-29T23:03:37.775Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f2/1e8f8affe51e12a26f3a8a8a4277d6e60aa89d0a66512f63b1e799d424a4/debugpy-1.8.20-cp311-cp311-win32.whl", hash = "sha256:773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec", size = 5209240, upload-time = "2026-01-29T23:03:39.109Z" }, - { url = "https://files.pythonhosted.org/packages/d5/92/1cb532e88560cbee973396254b21bece8c5d7c2ece958a67afa08c9f10dc/debugpy-1.8.20-cp311-cp311-win_amd64.whl", hash = "sha256:1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb", size = 5233481, upload-time = "2026-01-29T23:03:40.659Z" }, - { url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d", size = 2550686, upload-time = "2026-01-29T23:03:42.023Z" }, - { url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b", size = 4310588, upload-time = "2026-01-29T23:03:43.314Z" }, - { url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390", size = 5331372, upload-time = "2026-01-29T23:03:45.526Z" }, - { url = "https://files.pythonhosted.org/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl", hash = "sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3", size = 5372835, upload-time = "2026-01-29T23:03:47.245Z" }, - { url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a", size = 2539560, upload-time = "2026-01-29T23:03:48.738Z" }, - { url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf", size = 4293272, upload-time = "2026-01-29T23:03:50.169Z" }, - { url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393", size = 5331208, upload-time = "2026-01-29T23:03:51.547Z" }, - { url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7", size = 5372930, upload-time = "2026-01-29T23:03:53.585Z" }, - { url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173", size = 2538066, upload-time = "2026-01-29T23:03:54.999Z" }, - { url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad", size = 4269425, upload-time = "2026-01-29T23:03:56.518Z" }, - { url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f", size = 5331407, upload-time = "2026-01-29T23:03:58.481Z" }, - { url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be", size = 5372521, upload-time = "2026-01-29T23:03:59.864Z" }, - { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" }, +version = "1.8.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/73/75/9e12d4d42349b817cd545b89247696c67917aab907012ae5b64bbfea3199/debugpy-1.8.19.tar.gz", hash = "sha256:eea7e5987445ab0b5ed258093722d5ecb8bb72217c5c9b1e21f64efe23ddebdb", size = 1644590, upload-time = "2025-12-15T21:53:28.044Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/98/d57054371887f37d3c959a7a8dc3c76b763acb65f5e78d849d7db7cadc5b/debugpy-1.8.19-cp310-cp310-macosx_15_0_x86_64.whl", hash = "sha256:fce6da15d73be5935b4438435c53adb512326a3e11e4f90793ea87cd9f018254", size = 2098493, upload-time = "2025-12-15T21:53:30.149Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dd/c517b9aa3500157a30e4f4c4f5149f880026bd039d2b940acd2383a85d8e/debugpy-1.8.19-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:e24b1652a1df1ab04d81e7ead446a91c226de704ff5dde6bd0a0dbaab07aa3f2", size = 3087875, upload-time = "2025-12-15T21:53:31.511Z" }, + { url = "https://files.pythonhosted.org/packages/d8/57/3d5a5b0da9b63445253107ead151eff29190c6ad7440c68d1a59d56613aa/debugpy-1.8.19-cp310-cp310-win32.whl", hash = "sha256:327cb28c3ad9e17bc925efc7f7018195fd4787c2fe4b7af1eec11f1d19bdec62", size = 5239378, upload-time = "2025-12-15T21:53:32.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/36/7f9053c4c549160c87ae7e43800138f2695578c8b65947114c97250983b6/debugpy-1.8.19-cp310-cp310-win_amd64.whl", hash = "sha256:b7dd275cf2c99e53adb9654f5ae015f70415bbe2bacbe24cfee30d54b6aa03c5", size = 5271129, upload-time = "2025-12-15T21:53:35.085Z" }, + { url = "https://files.pythonhosted.org/packages/80/e2/48531a609b5a2aa94c6b6853afdfec8da05630ab9aaa96f1349e772119e9/debugpy-1.8.19-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:c5dcfa21de1f735a4f7ced4556339a109aa0f618d366ede9da0a3600f2516d8b", size = 2207620, upload-time = "2025-12-15T21:53:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/1b/d4/97775c01d56071969f57d93928899e5616a4cfbbf4c8cc75390d3a51c4a4/debugpy-1.8.19-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:806d6800246244004625d5222d7765874ab2d22f3ba5f615416cf1342d61c488", size = 3170796, upload-time = "2025-12-15T21:53:38.513Z" }, + { url = "https://files.pythonhosted.org/packages/8d/7e/8c7681bdb05be9ec972bbb1245eb7c4c7b0679bb6a9e6408d808bc876d3d/debugpy-1.8.19-cp311-cp311-win32.whl", hash = "sha256:783a519e6dfb1f3cd773a9bda592f4887a65040cb0c7bd38dde410f4e53c40d4", size = 5164287, upload-time = "2025-12-15T21:53:40.857Z" }, + { url = "https://files.pythonhosted.org/packages/f2/a8/aaac7ff12ddf5d68a39e13a423a8490426f5f661384f5ad8d9062761bd8e/debugpy-1.8.19-cp311-cp311-win_amd64.whl", hash = "sha256:14035cbdbb1fe4b642babcdcb5935c2da3b1067ac211c5c5a8fdc0bb31adbcaa", size = 5188269, upload-time = "2025-12-15T21:53:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/4a/15/d762e5263d9e25b763b78be72dc084c7a32113a0bac119e2f7acae7700ed/debugpy-1.8.19-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:bccb1540a49cde77edc7ce7d9d075c1dbeb2414751bc0048c7a11e1b597a4c2e", size = 2549995, upload-time = "2025-12-15T21:53:43.773Z" }, + { url = "https://files.pythonhosted.org/packages/a7/88/f7d25c68b18873b7c53d7c156ca7a7ffd8e77073aa0eac170a9b679cf786/debugpy-1.8.19-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:e9c68d9a382ec754dc05ed1d1b4ed5bd824b9f7c1a8cd1083adb84b3c93501de", size = 4309891, upload-time = "2025-12-15T21:53:45.26Z" }, + { url = "https://files.pythonhosted.org/packages/c5/4f/a65e973aba3865794da65f71971dca01ae66666132c7b2647182d5be0c5f/debugpy-1.8.19-cp312-cp312-win32.whl", hash = "sha256:6599cab8a783d1496ae9984c52cb13b7c4a3bd06a8e6c33446832a5d97ce0bee", size = 5286355, upload-time = "2025-12-15T21:53:46.763Z" }, + { url = "https://files.pythonhosted.org/packages/d8/3a/d3d8b48fec96e3d824e404bf428276fb8419dfa766f78f10b08da1cb2986/debugpy-1.8.19-cp312-cp312-win_amd64.whl", hash = "sha256:66e3d2fd8f2035a8f111eb127fa508469dfa40928a89b460b41fd988684dc83d", size = 5328239, upload-time = "2025-12-15T21:53:48.868Z" }, + { url = "https://files.pythonhosted.org/packages/71/3d/388035a31a59c26f1ecc8d86af607d0c42e20ef80074147cd07b180c4349/debugpy-1.8.19-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:91e35db2672a0abaf325f4868fcac9c1674a0d9ad9bb8a8c849c03a5ebba3e6d", size = 2538859, upload-time = "2025-12-15T21:53:50.478Z" }, + { url = "https://files.pythonhosted.org/packages/4a/19/c93a0772d0962294f083dbdb113af1a7427bb632d36e5314297068f55db7/debugpy-1.8.19-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:85016a73ab84dea1c1f1dcd88ec692993bcbe4532d1b49ecb5f3c688ae50c606", size = 4292575, upload-time = "2025-12-15T21:53:51.821Z" }, + { url = "https://files.pythonhosted.org/packages/5c/56/09e48ab796b0a77e3d7dc250f95251832b8bf6838c9632f6100c98bdf426/debugpy-1.8.19-cp313-cp313-win32.whl", hash = "sha256:b605f17e89ba0ecee994391194285fada89cee111cfcd29d6f2ee11cbdc40976", size = 5286209, upload-time = "2025-12-15T21:53:53.602Z" }, + { url = "https://files.pythonhosted.org/packages/fb/4e/931480b9552c7d0feebe40c73725dd7703dcc578ba9efc14fe0e6d31cfd1/debugpy-1.8.19-cp313-cp313-win_amd64.whl", hash = "sha256:c30639998a9f9cd9699b4b621942c0179a6527f083c72351f95c6ab1728d5b73", size = 5328206, upload-time = "2025-12-15T21:53:55.433Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b9/cbec520c3a00508327476c7fce26fbafef98f412707e511eb9d19a2ef467/debugpy-1.8.19-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:1e8c4d1bd230067bf1bbcdbd6032e5a57068638eb28b9153d008ecde288152af", size = 2537372, upload-time = "2025-12-15T21:53:57.318Z" }, + { url = "https://files.pythonhosted.org/packages/88/5e/cf4e4dc712a141e10d58405c58c8268554aec3c35c09cdcda7535ff13f76/debugpy-1.8.19-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:d40c016c1f538dbf1762936e3aeb43a89b965069d9f60f9e39d35d9d25e6b809", size = 4268729, upload-time = "2025-12-15T21:53:58.712Z" }, + { url = "https://files.pythonhosted.org/packages/82/a3/c91a087ab21f1047db328c1d3eb5d1ff0e52de9e74f9f6f6fa14cdd93d58/debugpy-1.8.19-cp314-cp314-win32.whl", hash = "sha256:0601708223fe1cd0e27c6cce67a899d92c7d68e73690211e6788a4b0e1903f5b", size = 5286388, upload-time = "2025-12-15T21:54:00.687Z" }, + { url = "https://files.pythonhosted.org/packages/17/b8/bfdc30b6e94f1eff09f2dc9cc1f9cd1c6cde3d996bcbd36ce2d9a4956e99/debugpy-1.8.19-cp314-cp314-win_amd64.whl", hash = "sha256:8e19a725f5d486f20e53a1dde2ab8bb2c9607c40c00a42ab646def962b41125f", size = 5327741, upload-time = "2025-12-15T21:54:02.148Z" }, + { url = "https://files.pythonhosted.org/packages/25/3e/e27078370414ef35fafad2c06d182110073daaeb5d3bf734b0b1eeefe452/debugpy-1.8.19-py2.py3-none-any.whl", hash = "sha256:360ffd231a780abbc414ba0f005dad409e71c78637efe8f2bd75837132a41d38", size = 5292321, upload-time = "2025-12-15T21:54:16.024Z" }, ] [[package]] @@ -711,11 +673,11 @@ wheels = [ [[package]] name = "dill" -version = "0.4.1" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/81/e1/56027a71e31b02ddc53c7d65b01e68edf64dea2932122fe7746a516f75d5/dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa", size = 187315, upload-time = "2026-01-19T02:36:56.85Z" } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d", size = 120019, upload-time = "2026-01-19T02:36:55.663Z" }, + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, ] [[package]] @@ -724,7 +686,7 @@ version = "1.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8c/3c/e0b90a5bc396e2abaf207d9a41ea8aeab1f41760425262474903bade6a7b/distinctipy-1.3.4.tar.gz", hash = "sha256:fed97afff1afb73ecaa87c85461021f0ba89fae63067c0125b9673526510aac4", size = 29711, upload-time = "2024-01-10T21:32:24.032Z" } wheels = [ @@ -744,37 +706,11 @@ wheels = [ name = "docutils" version = "0.21.2" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, ] -[[package]] -name = "docutils" -version = "0.22.4" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, -] - [[package]] name = "exceptiongroup" version = "1.3.1" @@ -816,11 +752,11 @@ wheels = [ [[package]] name = "filelock" -version = "3.24.1" +version = "3.20.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4f/8a/b24ff2c2d7f20ce930b5efe91e7260247d185d8939707721168ad204e465/filelock-3.24.1.tar.gz", hash = "sha256:3440181dd03f8904c108c8e9f5b11d1663e9fc960f1c837586a11f1c5c041e54", size = 37452, upload-time = "2026-02-15T22:03:16.564Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/65/ce7f1b70157833bf3cb851b556a37d4547ceafc158aa9b34b36782f23696/filelock-3.20.3.tar.gz", hash = "sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1", size = 19485, upload-time = "2026-01-09T17:55:05.421Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/64/3613e89811e79aca8d0d4f2c984fc66336bc9d83529c1cbe02f5df010d0a/filelock-3.24.1-py3-none-any.whl", hash = "sha256:7c59f595e3cf4887dc95b403a896849da49ed183d7c9d7ee855646ca99f10698", size = 24153, upload-time = "2026-02-15T22:03:15.262Z" }, + { url = "https://files.pythonhosted.org/packages/b5/36/7fb70f04bf00bc646cd5bb45aa9eddb15e19437a28b8fb2b4a5249fac770/filelock-3.20.3-py3-none-any.whl", hash = "sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1", size = 16701, upload-time = "2026-01-09T17:55:04.334Z" }, ] [[package]] @@ -889,8 +825,7 @@ dependencies = [ { name = "beautifulsoup4" }, { name = "pygments" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "sphinx-basic-ng" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ec/20/5f5ad4da6a5a27c80f2ed2ee9aee3f9e36c66e56e21c00fde467b2f8f88f/furo-2025.12.19.tar.gz", hash = "sha256:188d1f942037d8b37cd3985b955839fea62baa1730087dc29d157677c857e2a7", size = 1661473, upload-time = "2025-12-19T17:34:40.889Z" } @@ -900,56 +835,51 @@ wheels = [ [[package]] name = "greenlet" -version = "3.3.1" +version = "3.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/99/1cd3411c56a410994669062bd73dd58270c00cc074cac15f385a1fd91f8a/greenlet-3.3.1.tar.gz", hash = "sha256:41848f3230b58c08bb43dee542e74a2a2e34d3c59dc3076cec9151aeeedcae98", size = 184690, upload-time = "2026-01-23T15:31:02.076Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/65/5b235b40581ad75ab97dcd8b4218022ae8e3ab77c13c919f1a1dfe9171fd/greenlet-3.3.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04bee4775f40ecefcdaa9d115ab44736cd4b9c5fba733575bfe9379419582e13", size = 273723, upload-time = "2026-01-23T15:30:37.521Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ad/eb4729b85cba2d29499e0a04ca6fbdd8f540afd7be142fd571eea43d712f/greenlet-3.3.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e1457f4fed12a50e427988a07f0f9df53cf0ee8da23fab16e6732c2ec909d4", size = 574874, upload-time = "2026-01-23T16:00:54.551Z" }, - { url = "https://files.pythonhosted.org/packages/87/32/57cad7fe4c8b82fdaa098c89498ef85ad92dfbb09d5eb713adedfc2ae1f5/greenlet-3.3.1-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:070472cd156f0656f86f92e954591644e158fd65aa415ffbe2d44ca77656a8f5", size = 586309, upload-time = "2026-01-23T16:05:25.18Z" }, - { url = "https://files.pythonhosted.org/packages/87/eb/8a1ec2da4d55824f160594a75a9d8354a5fe0a300fb1c48e7944265217e1/greenlet-3.3.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a300354f27dd86bae5fbf7002e6dd2b3255cd372e9242c933faf5e859b703fe", size = 586985, upload-time = "2026-01-23T15:32:47.968Z" }, - { url = "https://files.pythonhosted.org/packages/15/1c/0621dd4321dd8c351372ee8f9308136acb628600658a49be1b7504208738/greenlet-3.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e84b51cbebf9ae573b5fbd15df88887815e3253fc000a7d0ff95170e8f7e9729", size = 1547271, upload-time = "2026-01-23T16:04:18.977Z" }, - { url = "https://files.pythonhosted.org/packages/9d/53/24047f8924c83bea7a59c8678d9571209c6bfe5f4c17c94a78c06024e9f2/greenlet-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0093bd1a06d899892427217f0ff2a3c8f306182b8c754336d32e2d587c131b4", size = 1613427, upload-time = "2026-01-23T15:33:44.428Z" }, - { url = "https://files.pythonhosted.org/packages/ff/07/ac9bf1ec008916d1a3373cae212884c1dcff4a4ba0d41127ce81a8deb4e9/greenlet-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:7932f5f57609b6a3b82cc11877709aa7a98e3308983ed93552a1c377069b20c8", size = 226100, upload-time = "2026-01-23T15:30:56.957Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e8/2e1462c8fdbe0f210feb5ac7ad2d9029af8be3bf45bd9fa39765f821642f/greenlet-3.3.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5fd23b9bc6d37b563211c6abbb1b3cab27db385a4449af5c32e932f93017080c", size = 274974, upload-time = "2026-01-23T15:31:02.891Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a8/530a401419a6b302af59f67aaf0b9ba1015855ea7e56c036b5928793c5bd/greenlet-3.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f51496a0bfbaa9d74d36a52d2580d1ef5ed4fdfcff0a73730abfbbbe1403dd", size = 577175, upload-time = "2026-01-23T16:00:56.213Z" }, - { url = "https://files.pythonhosted.org/packages/8e/89/7e812bb9c05e1aaef9b597ac1d0962b9021d2c6269354966451e885c4e6b/greenlet-3.3.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb0feb07fe6e6a74615ee62a880007d976cf739b6669cce95daa7373d4fc69c5", size = 590401, upload-time = "2026-01-23T16:05:26.365Z" }, - { url = "https://files.pythonhosted.org/packages/5c/ae/8d472e1f5ac5efe55c563f3eabb38c98a44b832602e12910750a7c025802/greenlet-3.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39eda9ba259cc9801da05351eaa8576e9aa83eb9411e8f0c299e05d712a210f2", size = 590272, upload-time = "2026-01-23T15:32:49.411Z" }, - { url = "https://files.pythonhosted.org/packages/a8/51/0fde34bebfcadc833550717eade64e35ec8738e6b097d5d248274a01258b/greenlet-3.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e2e7e882f83149f0a71ac822ebf156d902e7a5d22c9045e3e0d1daf59cee2cc9", size = 1550729, upload-time = "2026-01-23T16:04:20.867Z" }, - { url = "https://files.pythonhosted.org/packages/16/c9/2fb47bee83b25b119d5a35d580807bb8b92480a54b68fef009a02945629f/greenlet-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80aa4d79eb5564f2e0a6144fcc744b5a37c56c4a92d60920720e99210d88db0f", size = 1615552, upload-time = "2026-01-23T15:33:45.743Z" }, - { url = "https://files.pythonhosted.org/packages/1f/54/dcf9f737b96606f82f8dd05becfb8d238db0633dd7397d542a296fe9cad3/greenlet-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:32e4ca9777c5addcbf42ff3915d99030d8e00173a56f80001fb3875998fe410b", size = 226462, upload-time = "2026-01-23T15:36:50.422Z" }, - { url = "https://files.pythonhosted.org/packages/91/37/61e1015cf944ddd2337447d8e97fb423ac9bc21f9963fb5f206b53d65649/greenlet-3.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:da19609432f353fed186cc1b85e9440db93d489f198b4bdf42ae19cc9d9ac9b4", size = 225715, upload-time = "2026-01-23T15:33:17.298Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c8/9d76a66421d1ae24340dfae7e79c313957f6e3195c144d2c73333b5bfe34/greenlet-3.3.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:7e806ca53acf6d15a888405880766ec84721aa4181261cd11a457dfe9a7a4975", size = 276443, upload-time = "2026-01-23T15:30:10.066Z" }, - { url = "https://files.pythonhosted.org/packages/81/99/401ff34bb3c032d1f10477d199724f5e5f6fbfb59816ad1455c79c1eb8e7/greenlet-3.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d842c94b9155f1c9b3058036c24ffb8ff78b428414a19792b2380be9cecf4f36", size = 597359, upload-time = "2026-01-23T16:00:57.394Z" }, - { url = "https://files.pythonhosted.org/packages/2b/bc/4dcc0871ed557792d304f50be0f7487a14e017952ec689effe2180a6ff35/greenlet-3.3.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20fedaadd422fa02695f82093f9a98bad3dab5fcda793c658b945fcde2ab27ba", size = 607805, upload-time = "2026-01-23T16:05:28.068Z" }, - { url = "https://files.pythonhosted.org/packages/cf/05/821587cf19e2ce1f2b24945d890b164401e5085f9d09cbd969b0c193cd20/greenlet-3.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14194f5f4305800ff329cbf02c5fcc88f01886cadd29941b807668a45f0d2336", size = 609947, upload-time = "2026-01-23T15:32:51.004Z" }, - { url = "https://files.pythonhosted.org/packages/a4/52/ee8c46ed9f8babaa93a19e577f26e3d28a519feac6350ed6f25f1afee7e9/greenlet-3.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7b2fe4150a0cf59f847a67db8c155ac36aed89080a6a639e9f16df5d6c6096f1", size = 1567487, upload-time = "2026-01-23T16:04:22.125Z" }, - { url = "https://files.pythonhosted.org/packages/8f/7c/456a74f07029597626f3a6db71b273a3632aecb9afafeeca452cfa633197/greenlet-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49f4ad195d45f4a66a0eb9c1ba4832bb380570d361912fa3554746830d332149", size = 1636087, upload-time = "2026-01-23T15:33:47.486Z" }, - { url = "https://files.pythonhosted.org/packages/34/2f/5e0e41f33c69655300a5e54aeb637cf8ff57f1786a3aba374eacc0228c1d/greenlet-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:cc98b9c4e4870fa983436afa999d4eb16b12872fab7071423d5262fa7120d57a", size = 227156, upload-time = "2026-01-23T15:34:34.808Z" }, - { url = "https://files.pythonhosted.org/packages/c8/ab/717c58343cf02c5265b531384b248787e04d8160b8afe53d9eec053d7b44/greenlet-3.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:bfb2d1763d777de5ee495c85309460f6fd8146e50ec9d0ae0183dbf6f0a829d1", size = 226403, upload-time = "2026-01-23T15:31:39.372Z" }, - { url = "https://files.pythonhosted.org/packages/ec/ab/d26750f2b7242c2b90ea2ad71de70cfcd73a948a49513188a0fc0d6fc15a/greenlet-3.3.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:7ab327905cabb0622adca5971e488064e35115430cec2c35a50fd36e72a315b3", size = 275205, upload-time = "2026-01-23T15:30:24.556Z" }, - { url = "https://files.pythonhosted.org/packages/10/d3/be7d19e8fad7c5a78eeefb2d896a08cd4643e1e90c605c4be3b46264998f/greenlet-3.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65be2f026ca6a176f88fb935ee23c18333ccea97048076aef4db1ef5bc0713ac", size = 599284, upload-time = "2026-01-23T16:00:58.584Z" }, - { url = "https://files.pythonhosted.org/packages/ae/21/fe703aaa056fdb0f17e5afd4b5c80195bbdab701208918938bd15b00d39b/greenlet-3.3.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a3ae05b3d225b4155bda56b072ceb09d05e974bc74be6c3fc15463cf69f33fd", size = 610274, upload-time = "2026-01-23T16:05:29.312Z" }, - { url = "https://files.pythonhosted.org/packages/cb/86/5c6ab23bb3c28c21ed6bebad006515cfe08b04613eb105ca0041fecca852/greenlet-3.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6423481193bbbe871313de5fd06a082f2649e7ce6e08015d2a76c1e9186ca5b3", size = 612904, upload-time = "2026-01-23T15:32:52.317Z" }, - { url = "https://files.pythonhosted.org/packages/c2/f3/7949994264e22639e40718c2daf6f6df5169bf48fb038c008a489ec53a50/greenlet-3.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:33a956fe78bbbda82bfc95e128d61129b32d66bcf0a20a1f0c08aa4839ffa951", size = 1567316, upload-time = "2026-01-23T16:04:23.316Z" }, - { url = "https://files.pythonhosted.org/packages/8d/6e/d73c94d13b6465e9f7cd6231c68abde838bb22408596c05d9059830b7872/greenlet-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b065d3284be43728dd280f6f9a13990b56470b81be20375a207cdc814a983f2", size = 1636549, upload-time = "2026-01-23T15:33:48.643Z" }, - { url = "https://files.pythonhosted.org/packages/5e/b3/c9c23a6478b3bcc91f979ce4ca50879e4d0b2bd7b9a53d8ecded719b92e2/greenlet-3.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:27289986f4e5b0edec7b5a91063c109f0276abb09a7e9bdab08437525977c946", size = 227042, upload-time = "2026-01-23T15:33:58.216Z" }, - { url = "https://files.pythonhosted.org/packages/90/e7/824beda656097edee36ab15809fd063447b200cc03a7f6a24c34d520bc88/greenlet-3.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:2f080e028001c5273e0b42690eaf359aeef9cb1389da0f171ea51a5dc3c7608d", size = 226294, upload-time = "2026-01-23T15:30:52.73Z" }, - { url = "https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5", size = 275737, upload-time = "2026-01-23T15:32:16.889Z" }, - { url = "https://files.pythonhosted.org/packages/41/2e/a3a417d620363fdbb08a48b1dd582956a46a61bf8fd27ee8164f9dfe87c2/greenlet-3.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b31c05dd84ef6871dd47120386aed35323c944d86c3d91a17c4b8d23df62f15b", size = 646422, upload-time = "2026-01-23T16:01:00.354Z" }, - { url = "https://files.pythonhosted.org/packages/b4/09/c6c4a0db47defafd2d6bab8ddfe47ad19963b4e30f5bed84d75328059f8c/greenlet-3.3.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02925a0bfffc41e542c70aa14c7eda3593e4d7e274bfcccca1827e6c0875902e", size = 658219, upload-time = "2026-01-23T16:05:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f", size = 660237, upload-time = "2026-01-23T15:32:53.967Z" }, - { url = "https://files.pythonhosted.org/packages/96/61/373c30b7197f9e756e4c81ae90a8d55dc3598c17673f91f4d31c3c689c3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aec9ab04e82918e623415947921dea15851b152b822661cce3f8e4393c3df683", size = 1615261, upload-time = "2026-01-23T16:04:25.066Z" }, - { url = "https://files.pythonhosted.org/packages/fd/d3/ca534310343f5945316f9451e953dcd89b36fe7a19de652a1dc5a0eeef3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71c767cf281a80d02b6c1bdc41c9468e1f5a494fb11bc8688c360524e273d7b1", size = 1683719, upload-time = "2026-01-23T15:33:50.61Z" }, - { url = "https://files.pythonhosted.org/packages/52/cb/c21a3fd5d2c9c8b622e7bede6d6d00e00551a5ee474ea6d831b5f567a8b4/greenlet-3.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:96aff77af063b607f2489473484e39a0bbae730f2ea90c9e5606c9b73c44174a", size = 228125, upload-time = "2026-01-23T15:32:45.265Z" }, - { url = "https://files.pythonhosted.org/packages/6a/8e/8a2db6d11491837af1de64b8aff23707c6e85241be13c60ed399a72e2ef8/greenlet-3.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:b066e8b50e28b503f604fa538adc764a638b38cf8e81e025011d26e8a627fa79", size = 227519, upload-time = "2026-01-23T15:31:47.284Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/cbbec49bacdcc9ec652a81d3efef7b59f326697e7edf6ed775a5e08e54c2/greenlet-3.3.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:3e63252943c921b90abb035ebe9de832c436401d9c45f262d80e2d06cc659242", size = 282706, upload-time = "2026-01-23T15:33:05.525Z" }, - { url = "https://files.pythonhosted.org/packages/86/2e/4f2b9323c144c4fe8842a4e0d92121465485c3c2c5b9e9b30a52e80f523f/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76e39058e68eb125de10c92524573924e827927df5d3891fbc97bd55764a8774", size = 651209, upload-time = "2026-01-23T16:01:01.517Z" }, - { url = "https://files.pythonhosted.org/packages/d9/87/50ca60e515f5bb55a2fbc5f0c9b5b156de7d2fc51a0a69abc9d23914a237/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9f9d5e7a9310b7a2f416dd13d2e3fd8b42d803968ea580b7c0f322ccb389b97", size = 654300, upload-time = "2026-01-23T16:05:32.199Z" }, - { url = "https://files.pythonhosted.org/packages/1d/94/74310866dfa2b73dd08659a3d18762f83985ad3281901ba0ee9a815194fb/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92497c78adf3ac703b57f1e3813c2d874f27f71a178f9ea5887855da413cd6d2", size = 653842, upload-time = "2026-01-23T15:32:55.671Z" }, - { url = "https://files.pythonhosted.org/packages/97/43/8bf0ffa3d498eeee4c58c212a3905dd6146c01c8dc0b0a046481ca29b18c/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ed6b402bc74d6557a705e197d47f9063733091ed6357b3de33619d8a8d93ac53", size = 1614917, upload-time = "2026-01-23T16:04:26.276Z" }, - { url = "https://files.pythonhosted.org/packages/89/90/a3be7a5f378fc6e84abe4dcfb2ba32b07786861172e502388b4c90000d1b/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:59913f1e5ada20fde795ba906916aea25d442abcc0593fba7e26c92b7ad76249", size = 1676092, upload-time = "2026-01-23T15:33:52.176Z" }, - { url = "https://files.pythonhosted.org/packages/e1/2b/98c7f93e6db9977aaee07eb1e51ca63bd5f779b900d362791d3252e60558/greenlet-3.3.1-cp314-cp314t-win_amd64.whl", hash = "sha256:301860987846c24cb8964bdec0e31a96ad4a2a801b41b4ef40963c1b44f33451", size = 233181, upload-time = "2026-01-23T15:33:00.29Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/6a/33d1702184d94106d3cdd7bfb788e19723206fce152e303473ca3b946c7b/greenlet-3.3.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:6f8496d434d5cb2dce025773ba5597f71f5410ae499d5dd9533e0653258cdb3d", size = 273658, upload-time = "2025-12-04T14:23:37.494Z" }, + { url = "https://files.pythonhosted.org/packages/d6/b7/2b5805bbf1907c26e434f4e448cd8b696a0b71725204fa21a211ff0c04a7/greenlet-3.3.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b96dc7eef78fd404e022e165ec55327f935b9b52ff355b067eb4a0267fc1cffb", size = 574810, upload-time = "2025-12-04T14:50:04.154Z" }, + { url = "https://files.pythonhosted.org/packages/94/38/343242ec12eddf3d8458c73f555c084359883d4ddc674240d9e61ec51fd6/greenlet-3.3.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73631cd5cccbcfe63e3f9492aaa664d278fda0ce5c3d43aeda8e77317e38efbd", size = 586248, upload-time = "2025-12-04T14:57:39.35Z" }, + { url = "https://files.pythonhosted.org/packages/b6/a8/15d0aa26c0036a15d2659175af00954aaaa5d0d66ba538345bd88013b4d7/greenlet-3.3.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7dee147740789a4632cace364816046e43310b59ff8fb79833ab043aefa72fd5", size = 586910, upload-time = "2025-12-04T14:25:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/e1/9b/68d5e3b7ccaba3907e5532cf8b9bf16f9ef5056a008f195a367db0ff32db/greenlet-3.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:39b28e339fc3c348427560494e28d8a6f3561c8d2bcf7d706e1c624ed8d822b9", size = 1547206, upload-time = "2025-12-04T15:04:21.027Z" }, + { url = "https://files.pythonhosted.org/packages/66/bd/e3086ccedc61e49f91e2cfb5ffad9d8d62e5dc85e512a6200f096875b60c/greenlet-3.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b3c374782c2935cc63b2a27ba8708471de4ad1abaa862ffdb1ef45a643ddbb7d", size = 1613359, upload-time = "2025-12-04T14:27:26.548Z" }, + { url = "https://files.pythonhosted.org/packages/f4/6b/d4e73f5dfa888364bbf02efa85616c6714ae7c631c201349782e5b428925/greenlet-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:b49e7ed51876b459bd645d83db257f0180e345d3f768a35a85437a24d5a49082", size = 300740, upload-time = "2025-12-04T14:47:52.773Z" }, + { url = "https://files.pythonhosted.org/packages/1f/cb/48e964c452ca2b92175a9b2dca037a553036cb053ba69e284650ce755f13/greenlet-3.3.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e29f3018580e8412d6aaf5641bb7745d38c85228dacf51a73bd4e26ddf2a6a8e", size = 274908, upload-time = "2025-12-04T14:23:26.435Z" }, + { url = "https://files.pythonhosted.org/packages/28/da/38d7bff4d0277b594ec557f479d65272a893f1f2a716cad91efeb8680953/greenlet-3.3.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a687205fb22794e838f947e2194c0566d3812966b41c78709554aa883183fb62", size = 577113, upload-time = "2025-12-04T14:50:05.493Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f2/89c5eb0faddc3ff014f1c04467d67dee0d1d334ab81fadbf3744847f8a8a/greenlet-3.3.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4243050a88ba61842186cb9e63c7dfa677ec146160b0efd73b855a3d9c7fcf32", size = 590338, upload-time = "2025-12-04T14:57:41.136Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/e959a127b630a58e23529972dbc868c107f9d583b5a9f878fb858c46bc1a/greenlet-3.3.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cb3a8ec3db4a3b0eb8a3c25436c2d49e3505821802074969db017b87bc6a948", size = 590206, upload-time = "2025-12-04T14:26:01.254Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/29035719feb91798693023608447283b266b12efc576ed013dd9442364bb/greenlet-3.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2de5a0b09eab81fc6a382791b995b1ccf2b172a9fec934747a7a23d2ff291794", size = 1550668, upload-time = "2025-12-04T15:04:22.439Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/783a23754b691bfa86bd72c3033aa107490deac9b2ef190837b860996c9f/greenlet-3.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4449a736606bd30f27f8e1ff4678ee193bc47f6ca810d705981cfffd6ce0d8c5", size = 1615483, upload-time = "2025-12-04T14:27:28.083Z" }, + { url = "https://files.pythonhosted.org/packages/1d/d5/c339b3b4bc8198b7caa4f2bd9fd685ac9f29795816d8db112da3d04175bb/greenlet-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:7652ee180d16d447a683c04e4c5f6441bae7ba7b17ffd9f6b3aff4605e9e6f71", size = 301164, upload-time = "2025-12-04T14:42:51.577Z" }, + { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, + { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, + { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, + { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, + { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, + { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, + { url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" }, + { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" }, + { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" }, + { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" }, + { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" }, + { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" }, + { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" }, + { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, + { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" }, + { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" }, + { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" }, + { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" }, + { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" }, ] [[package]] @@ -1002,14 +932,14 @@ wheels = [ [[package]] name = "ipykernel" -version = "7.2.0" +version = "7.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "appnope", marker = "sys_platform == 'darwin'" }, { name = "comm" }, { name = "debugpy" }, { name = "ipython", version = "8.38.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "9.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyter-client" }, { name = "jupyter-core" }, { name = "matplotlib-inline" }, @@ -1020,9 +950,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046, upload-time = "2026-02-06T16:43:27.403Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/a4/4948be6eb88628505b83a1f2f40d90254cab66abf2043b3c40fa07dfce0f/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db", size = 174579, upload-time = "2025-10-27T09:46:39.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c", size = 117968, upload-time = "2025-10-27T09:46:37.805Z" }, ] [[package]] @@ -1052,21 +982,13 @@ wheels = [ [[package]] name = "ipython" -version = "9.10.0" +version = "9.9.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", ] dependencies = [ { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, @@ -1081,9 +1003,9 @@ dependencies = [ { name = "traitlets", marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/60/2111715ea11f39b1535bed6024b7dec7918b71e5e5d30855a5b503056b50/ipython-9.10.0.tar.gz", hash = "sha256:cd9e656be97618a0676d058134cd44e6dc7012c0e5cb36a9ce96a8c904adaf77", size = 4426526, upload-time = "2026-02-02T10:00:33.594Z" } +sdist = { url = "https://files.pythonhosted.org/packages/46/dd/fb08d22ec0c27e73c8bc8f71810709870d51cadaf27b7ddd3f011236c100/ipython-9.9.0.tar.gz", hash = "sha256:48fbed1b2de5e2c7177eefa144aba7fcb82dac514f09b57e2ac9da34ddb54220", size = 4425043, upload-time = "2026-01-05T12:36:46.233Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl", hash = "sha256:c6ab68cc23bba8c7e18e9b932797014cc61ea7fd6f19de180ab9ba73e65ee58d", size = 622774, upload-time = "2026-02-02T10:00:31.503Z" }, + { url = "https://files.pythonhosted.org/packages/86/92/162cfaee4ccf370465c5af1ce36a9eacec1becb552f2033bb3584e6f640a/ipython-9.9.0-py3-none-any.whl", hash = "sha256:b457fe9165df2b84e8ec909a97abcf2ed88f565970efba16b1f7229c283d252b", size = 621431, upload-time = "2026-01-05T12:36:44.669Z" }, ] [[package]] @@ -1105,7 +1027,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "comm" }, { name = "ipython", version = "8.38.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "9.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyterlab-widgets" }, { name = "traitlets" }, { name = "widgetsnbextension" }, @@ -1360,18 +1282,10 @@ name = "markdown-it-py" version = "4.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", ] dependencies = [ { name = "mdurl", marker = "python_full_version >= '3.11'" }, @@ -1477,7 +1391,7 @@ dependencies = [ { name = "fonttools" }, { name = "kiwisolver" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "packaging" }, { name = "pillow" }, { name = "pyparsing" }, @@ -1586,72 +1500,72 @@ wheels = [ [[package]] name = "mqt-core" -version = "3.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ef/93/41d0e19ab9513b3cc5d78042dfd4e87baefe8a11235e6cd86ff08e8ddd33/mqt_core-3.4.1.tar.gz", hash = "sha256:e2b884b22bf70aa092d8c1fb436065814e4e5763b8be8b9c28a669a6db7470f2", size = 642056, upload-time = "2026-02-01T23:08:03.204Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/df/35/a6496972cd5bf67eced88e322965af080035e241598cffd8904c7d58ff2a/mqt_core-3.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4ada4d2e4de64de1faa8d688fc4be994f17dc94ec66b9386aa6c04fbeb843f9", size = 5150994, upload-time = "2026-02-01T23:07:19.6Z" }, - { url = "https://files.pythonhosted.org/packages/57/39/fb58967f72f07e8f3119735a622cc169a17f2faa03bb7bf614cc575304ec/mqt_core-3.4.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5175b3360cc432da7258fb237c6d7efd1fb5bc4347ac5421e0c8d564abe4d738", size = 5594907, upload-time = "2026-02-01T23:07:21.7Z" }, - { url = "https://files.pythonhosted.org/packages/b8/1c/bd4c71af62d0e95fbff54e51ad4dadc2ac30be7a0c02ff607a90c64ec400/mqt_core-3.4.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb8efb3beef48abcf34340d3277a1aa3c10a4c4f3b55cc8c4bc3e2dfbd78c475", size = 6626517, upload-time = "2026-02-01T23:07:23.682Z" }, - { url = "https://files.pythonhosted.org/packages/a3/7b/1f225942f93718de6acf3e5fa0e9f9e9b441453aa7307b605e2512aaea7b/mqt_core-3.4.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4967845b5840ba212a1843e36d720daa5fb23e4e3f4c3d3315a1893fe0d170c7", size = 7041138, upload-time = "2026-02-01T23:07:25.855Z" }, - { url = "https://files.pythonhosted.org/packages/26/9f/b873bad165c42cd31f51b8a61c2d81d352eb43c420eb69000e519c1a3181/mqt_core-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:a9cd021ac2a97f4eeb60627f3f8710caefe8b31a7791f2ec76ad3cd80636646b", size = 4009303, upload-time = "2026-02-01T23:07:27.369Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c4/3afbef57b4a3e06af7e4e3dc68f10807c6c1b75794922efc8df9088de8f5/mqt_core-3.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:ca7ea0fdf29741e284d3829a6b83875025438334cc7e2d4a6e05cfb844e85cbe", size = 7886204, upload-time = "2026-02-01T23:07:29.525Z" }, - { url = "https://files.pythonhosted.org/packages/18/db/8cc62343413f14bb9e5675397e2514d4d62b6e452319ecb34509450a7e9c/mqt_core-3.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9001bf4584ba0d71a6fdf8d011aa93236d30f048e4b9315bb1e4c06f5ae6f436", size = 5152023, upload-time = "2026-02-01T23:07:31.465Z" }, - { url = "https://files.pythonhosted.org/packages/21/c4/bbfe6a7dd634f3aa2027c3096aaa9233a26d4f23b4bcf987e0f96b5bbaa0/mqt_core-3.4.1-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:61afb495647ace780c55fead97d6432e2f9e4b3d1bd79ea274ff4216a5e7ddfe", size = 5596017, upload-time = "2026-02-01T23:07:32.843Z" }, - { url = "https://files.pythonhosted.org/packages/54/4e/1d19240b39daa9c8f6833eac99ccd6eb3829c10580fdbeab2dca7aea03ed/mqt_core-3.4.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7abd596323fae9905bf58f8f9b65734fca478d640b3e890b19f5cb13036d25c2", size = 6627235, upload-time = "2026-02-01T23:07:35.279Z" }, - { url = "https://files.pythonhosted.org/packages/11/3f/1572d27b596f7324d77de83a26b20d76becd6e8721f8892b9815d1e636b1/mqt_core-3.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:172b8f8ac5132a83df2f1c86961ac74f70f08b5e75229408a182b5b7d2d06cba", size = 7042001, upload-time = "2026-02-01T23:07:36.776Z" }, - { url = "https://files.pythonhosted.org/packages/c4/0a/5ff32fc02b232061630ead78501d30eb703c7edaf719498a5e4f8d397cac/mqt_core-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:76d74fb2fc29b79906294d725a8a7a146706c75ee027624156626ba8521110df", size = 4009854, upload-time = "2026-02-01T23:07:38.304Z" }, - { url = "https://files.pythonhosted.org/packages/af/4a/3cc50bc7f99a41e27a00416a714380106d715af3dad54218f13e1c872a44/mqt_core-3.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:f00e808ca00c40478c007567e7c5dea09bd967f01fb29a47de32b754a59e010e", size = 7886737, upload-time = "2026-02-01T23:07:40.478Z" }, - { url = "https://files.pythonhosted.org/packages/e1/d1/7295a941a0e650abdf3004d8a37e0588b6350c1ce52cb2989d1fccde09b6/mqt_core-3.4.1-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:2124d4fe5722dc5505012acb420de1b0807a3a77150f596926ffe9466994f0e8", size = 5148117, upload-time = "2026-02-01T23:07:42.289Z" }, - { url = "https://files.pythonhosted.org/packages/d4/36/f4dd6632ed75998a29e94dac473806131b3db4abb273c30bc7d99f219986/mqt_core-3.4.1-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:f33dec256d2d21a67f8596187823a1d652e667ebe3ce5135ede8bae97beeb53c", size = 5592616, upload-time = "2026-02-01T23:07:44.285Z" }, - { url = "https://files.pythonhosted.org/packages/d7/16/51ad37c8a5475dc4a9976b392de3d76ad215c60b76f38a2e1029e6a7a80f/mqt_core-3.4.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a9e2bb2e1f23a517229c60ee98ce87efb9e23c265b858caf9d19c3a90c602c4", size = 6612527, upload-time = "2026-02-01T23:07:46.969Z" }, - { url = "https://files.pythonhosted.org/packages/fd/99/36057925a8f140a543da77aa18616780bd8ae6719d5e4f15cb356061ea45/mqt_core-3.4.1-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0a9b88ef737ba1368d7adab82cdea450a4fac6e720646917acbef1b1dab55973", size = 7025048, upload-time = "2026-02-01T23:07:48.866Z" }, - { url = "https://files.pythonhosted.org/packages/44/de/2b12dde1e0e0e9d3776aa2c077be1da9c84d7c4c3c01029b0856c70fd695/mqt_core-3.4.1-cp312-abi3-win_amd64.whl", hash = "sha256:8b5f1cfa130ad70afb272f72927145635abf944bb4a4a6f5f6a9272d57932a2b", size = 4002828, upload-time = "2026-02-01T23:07:50.493Z" }, - { url = "https://files.pythonhosted.org/packages/b9/be/3e2c2589a95b489219ba44e41c45b692d3ed6162d0d39de0e0960f6d6483/mqt_core-3.4.1-cp312-abi3-win_arm64.whl", hash = "sha256:b05649c59db929a3f3738d9e5c0c36d68391877e64cf36c0cefd1ff76cfc068b", size = 7879599, upload-time = "2026-02-01T23:07:52.638Z" }, - { url = "https://files.pythonhosted.org/packages/1b/36/90b9770bf4b3a707df6bbd10f11d6921468ca5eef006dd7a0f5062dc07e8/mqt_core-3.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d96213ba934dd68bc704cca2b92c3a7321383c65e6c1c0250ef06c296d629c8b", size = 5160556, upload-time = "2026-02-01T23:07:54.106Z" }, - { url = "https://files.pythonhosted.org/packages/a2/a3/1ac26fbc86b2f4a057c10edaa8c39568cb2ea40df873fc4c914f1d4b8626/mqt_core-3.4.1-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:40c07a6c08b3f3d7118b1358b4b60f2f7ca1e4e682d5923676fa033ed97af709", size = 5606238, upload-time = "2026-02-01T23:07:55.784Z" }, - { url = "https://files.pythonhosted.org/packages/b8/e8/f4d6279cc17dc077e37138593f1ebdd1f5d4fe32839ff1b5b8e951205a51/mqt_core-3.4.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2615a8ff7ab9b04a5932c4dbe3925bae298315c552d53055cfdd6340089ffd77", size = 6632093, upload-time = "2026-02-01T23:07:57.184Z" }, - { url = "https://files.pythonhosted.org/packages/bc/2b/0b08bbb14e7d7017fc234ff2cd39498d7ec86132198ba09dd8e10f6dbf0c/mqt_core-3.4.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:704f26d9962dd37daf57c31135d262bb4bdbd85500a5637868639ab30e427815", size = 7041688, upload-time = "2026-02-01T23:07:58.693Z" }, - { url = "https://files.pythonhosted.org/packages/f6/f1/fe583d3963a6dadf03a3fabb9d77524ef6c9d8a3cea81c65df39eca574bd/mqt_core-3.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:7531c56c4b357a401082e2693444db1411cc3b44898740551ee834fb1aec278b", size = 4095376, upload-time = "2026-02-01T23:08:00.219Z" }, - { url = "https://files.pythonhosted.org/packages/94/81/dc748367df3a0184d714684d128c9457fad5004afdc2aab6d79119808cb7/mqt_core-3.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:f33549a3445fe5d14d35ec579bf1ca3c75cda6fadddd1321f9ff2be166207014", size = 7958959, upload-time = "2026-02-01T23:08:01.755Z" }, +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/6d/c3b4f17a8e695d715379ad298d0e51790ad7e2a60f0f68f1c08703ca8beb/mqt_core-3.4.0.tar.gz", hash = "sha256:daa752050e1001cb72e7cc1fd0c0aeff8a526aefae29e414b26920739a4aa681", size = 633636, upload-time = "2026-01-08T22:08:41.588Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/9b/960d498f34f88df402a7b76a18eec8113c86f8c233eba7313a9e1530dff6/mqt_core-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c58e5d223d2f59ff9146970b8a5202e07718dd3ce2191291469b347019ced674", size = 5114257, upload-time = "2026-01-08T22:08:01.23Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f0/8bbf1160a26f99799556a73a150873522ccb824cc45f3e9fdac44ecbd6a2/mqt_core-3.4.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30176b938ae76544cf70be31cdddbf2de8c83d8035af7f39ce11d5dd46c77b4c", size = 5547616, upload-time = "2026-01-08T22:08:03.399Z" }, + { url = "https://files.pythonhosted.org/packages/c7/78/19b0395b9568dc2d76056a998516adeed3775f98750a7a9bd988851be194/mqt_core-3.4.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:59fcd0711f49517c612946225c3b588448f8e0683f2a7aca596e7bc0eb48ed03", size = 6572454, upload-time = "2026-01-08T22:08:06.308Z" }, + { url = "https://files.pythonhosted.org/packages/c4/08/ae8859715f9eb6c16b707064fc0ea1171f3bc7804175b642b85571e4ef01/mqt_core-3.4.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bd27347bfd1310e4496c4f79a72076bb2638425968efd0724a3a2cbf0025b9b", size = 6991090, upload-time = "2026-01-08T22:08:08.201Z" }, + { url = "https://files.pythonhosted.org/packages/68/7a/4e413df061c1fa788205abeaff27ec5f40cb786403145fc505bc5a1b8d47/mqt_core-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:e49fd8f7b9ef12e4ebeed98a4bf8347559e938a0caec2f0b952e8a760cc4c60b", size = 3972046, upload-time = "2026-01-08T22:08:10.118Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d7/8b5b7cd47df3bd1191bc58ce78dee23f0b6ac594e499121a984643ea9b55/mqt_core-3.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:e1edc694f169b0f7b2a79b397efa6268349cddf94cbc396586c2cd68457bacfa", size = 3973622, upload-time = "2026-01-08T22:08:11.665Z" }, + { url = "https://files.pythonhosted.org/packages/40/16/4a82f02632d4cc22070490399f37f5a0019d0e669c9c0f610283e0a54b29/mqt_core-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:33cf21ad638892fa2fc6913840dca1e50cc531776c7f6b2fdb3cee0bad6004f1", size = 5115319, upload-time = "2026-01-08T22:08:13.483Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/3bdb720b99764a7ab3da8f103ccdb5d20cc069c893503d11f018716b7d06/mqt_core-3.4.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:226eab23b0b53a0018a435001a5d34b362bed8f7659939155e3ec58042b333d4", size = 5548833, upload-time = "2026-01-08T22:08:15.518Z" }, + { url = "https://files.pythonhosted.org/packages/90/df/e3b6ef95b7181c9455689325da68e5befb7faa1f01cc19106435909ee9a6/mqt_core-3.4.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:31846c555f23b9f7a710f9a70fc1882bd63d3bd19430488912f543debc4e646a", size = 6573090, upload-time = "2026-01-08T22:08:16.992Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/484b9d559263301412bb7da49b5939b15fcef27f3c6c7a743f61ed2fbeb2/mqt_core-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10d2c477c74fc873d442df27434586011d4749a159cb388bb49daf4f89ac4ca5", size = 6991703, upload-time = "2026-01-08T22:08:18.806Z" }, + { url = "https://files.pythonhosted.org/packages/fc/67/4b7929ff1c8d7c127fd2aac0d2d51580a8c177d066d6b7288bedfdaea03e/mqt_core-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d759f38cf09dfdd822f170262b395b76bdd4da2144dc5fd8a4a1d8346f5c0cc2", size = 3972643, upload-time = "2026-01-08T22:08:20.2Z" }, + { url = "https://files.pythonhosted.org/packages/d8/e4/2640e3ae0e1eab43aaf0fca2fc4fdcd098059cf1f86b9b6ddd7a3044c72a/mqt_core-3.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:ba9f687a96f6e42fd019e6098a7e54867d0173727613fbce92a893dd1f8f6950", size = 3974154, upload-time = "2026-01-08T22:08:21.596Z" }, + { url = "https://files.pythonhosted.org/packages/e1/86/0973049ec3f15ae9e47bb3a5d0222110c26ef86da336932575403fe63f77/mqt_core-3.4.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:df2d6cb96de949d90d5051dd8c85354cce308207d655ee2365c92f5adcea135d", size = 5111559, upload-time = "2026-01-08T22:08:23.068Z" }, + { url = "https://files.pythonhosted.org/packages/23/da/eabcece4479a59753ab51a9a259146419d5cb2a7547de7f7fde7214c5900/mqt_core-3.4.0-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:bad7520308ea3dc528305b5e0610bc2053b67a6c7526a69bf69bda62551c4ef9", size = 5545608, upload-time = "2026-01-08T22:08:24.578Z" }, + { url = "https://files.pythonhosted.org/packages/6e/28/39d9bf7563c48a1bb77fc1f489cc757e92fe25dffd931c909ff31dfcecaa/mqt_core-3.4.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f86da5c06dd16e90ecfed2e328e655153e0cf336a6bb75effa74071a85d16f2f", size = 6559438, upload-time = "2026-01-08T22:08:26.058Z" }, + { url = "https://files.pythonhosted.org/packages/ff/a4/c61d64b69d5801d4cd4da23bb20042828e78d4ce9274f13032a5ca838981/mqt_core-3.4.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0b37033ac2a1e8325257d649f7014ccbbe516a2004541008cfca18f89124ff4", size = 6975946, upload-time = "2026-01-08T22:08:27.679Z" }, + { url = "https://files.pythonhosted.org/packages/a3/47/aa597c38630ddcfed4482f381bb7970c3186fe189fdd6463d2171c55554d/mqt_core-3.4.0-cp312-abi3-win_amd64.whl", hash = "sha256:3c67121831eb9a6a82fb857148220d792463893063a6145f347a73d208d2b63c", size = 3965527, upload-time = "2026-01-08T22:08:29.246Z" }, + { url = "https://files.pythonhosted.org/packages/d7/3f/b5970789acb4ac81efbf584c0e71341c61fec6a1fba8a37dffd8fdc6c37e/mqt_core-3.4.0-cp312-abi3-win_arm64.whl", hash = "sha256:dcd597ff11027bdccecb243b9bf9055e7a8bc5f92af51349bd9a3051f6bd3c89", size = 3967823, upload-time = "2026-01-08T22:08:30.593Z" }, + { url = "https://files.pythonhosted.org/packages/84/e5/5f7c5e760446ee0f820425de983c3f3476a5c6ab2fd8909f19941f808895/mqt_core-3.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:545b8fe227d07d9c7c80868392dc9bb5c8902734809c3dafc565fd684dd785b2", size = 5125079, upload-time = "2026-01-08T22:08:32.107Z" }, + { url = "https://files.pythonhosted.org/packages/8a/fb/bafce65cbb74013df50b8c841bcefda9ab436965f7f7257c3c90c69c0b90/mqt_core-3.4.0-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:3068fadbf7512d11f9ecb18e1e1785658657cd7b00759f1bfc67948d4af311fc", size = 5560107, upload-time = "2026-01-08T22:08:33.759Z" }, + { url = "https://files.pythonhosted.org/packages/90/a7/736986cfdc0ebe3a74f2c732156484a6349a02dc389e0b6f7e997dcfbdee/mqt_core-3.4.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8dbf325a30580cf2951774b3ab7fa539b7272a5a173ba25b98c753aac4faff66", size = 6584391, upload-time = "2026-01-08T22:08:35.16Z" }, + { url = "https://files.pythonhosted.org/packages/fc/9b/d16f996c915b23d8a58d74433dc1fbee55dbe0b40515c4a8e70a3c7f64f7/mqt_core-3.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:485a5133698c70c02430170bab46b88d24dd4188d6c63ebb3c91bdd3ccd7f782", size = 7000710, upload-time = "2026-01-08T22:08:36.735Z" }, + { url = "https://files.pythonhosted.org/packages/b6/38/232705301ea975356e06bed18e152424b5f48919961aa862275627689b1c/mqt_core-3.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2f51451a78b8fd4cb55c4a4d9b23f97c806305e699d313178fa3c8b9952fe558", size = 4061549, upload-time = "2026-01-08T22:08:38.884Z" }, + { url = "https://files.pythonhosted.org/packages/24/61/2b6e1ce9f3747d8cd336ff73a084ac1b5771111889467de214dbca3af8c0/mqt_core-3.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e6f1765f3569a533af790fbaee2c7a21a0a4b34611ff914b17a6c4dfdea08120", size = 4048399, upload-time = "2026-01-08T22:08:40.279Z" }, ] [[package]] name = "mqt-qcec" -version = "3.5.0" +version = "3.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mqt-core" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2b/09/a7edff1685238664b048553802dff432f9d726e1fa750a480369c702d389/mqt_qcec-3.5.0.tar.gz", hash = "sha256:700150ce6b96889a19e3081d2883790e7aa20efca7024eb6d0cd6be0331c1670", size = 284464, upload-time = "2026-02-02T17:44:07.223Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/64/b34d40297890b216d6280452b9dbda36d859334c694d72e220b6997a4bc7/mqt_qcec-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eaf086f78b7034ccbc014c73c9a94936700223b022f433ec314e43415274ba1f", size = 222725, upload-time = "2026-02-02T17:43:22.612Z" }, - { url = "https://files.pythonhosted.org/packages/56/b4/70dea5a26ab5127446dafb5ea82de96b5c1239f46e307e7a68ed4f7d24c7/mqt_qcec-3.5.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:9b5680c0926b56a705988a4be8a5161837c3d284f0fa463bff3a20e6c9a11cf3", size = 235513, upload-time = "2026-02-02T17:43:26.357Z" }, - { url = "https://files.pythonhosted.org/packages/7a/4e/c2c47c2b4fd98d9e7cf40017f20e383a93f68d3c82c0d7a90e44b9b9c64d/mqt_qcec-3.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79628f5c732d3df963d2d778d66bfedce58ee3147e61cc2db70a9df338a2f90a", size = 238097, upload-time = "2026-02-02T17:43:29.591Z" }, - { url = "https://files.pythonhosted.org/packages/f2/e6/1cd7ae242cd9bbf5e4abc2763f5f62333ee1e929e8deb41bb9d0846ea938/mqt_qcec-3.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ab2c220a26bdb0d7387b93f0323d36bbfd027ebc7e1376af03d0cff418028cc", size = 248602, upload-time = "2026-02-02T17:43:31.621Z" }, - { url = "https://files.pythonhosted.org/packages/83/47/a495a056d75b8ffdd665079eb16f38f7b87f2440f2a99d17ae8df0ad1d56/mqt_qcec-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:dc598cb99814698e5aa1ed464a233cacd316c4a746f530da78c38d265186ff22", size = 447893, upload-time = "2026-02-02T17:43:33.457Z" }, - { url = "https://files.pythonhosted.org/packages/7c/b0/0efddb52482011a20a44b3cd660441d0f195719417142dedb382dba85fff/mqt_qcec-3.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:436e0cf6314f5a1717d3f9798e9e6e8013d7917610ee7ffd9b27dcfc7f96dbc8", size = 610102, upload-time = "2026-02-02T17:43:35.511Z" }, - { url = "https://files.pythonhosted.org/packages/3b/53/edd4512d19d5e3eaf812a2c5eaa12e338730f38abb211ecc303a91e9b65c/mqt_qcec-3.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5685fadf5bdd6e96dbb35b5978579e80d0af39d6bf91822685b4101a5bad882", size = 223148, upload-time = "2026-02-02T17:43:37.892Z" }, - { url = "https://files.pythonhosted.org/packages/d6/0b/c4a6d90a10de7259f931685c3a155f6c6b211a6338c1d040dd901a88b31a/mqt_qcec-3.5.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:4184847eac148f393899dcbb20a16bc9613e3f640a18d7923e69aa771210bea1", size = 236144, upload-time = "2026-02-02T17:43:39.057Z" }, - { url = "https://files.pythonhosted.org/packages/1c/ff/abc280dc52e0052108fd8ff44523adfb497a6491f28e039df7cb8f3ac2bb/mqt_qcec-3.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c75972994345059a6472f1a6af6e0c6131e70745453ed441ef39f3c8dfb40ce", size = 239055, upload-time = "2026-02-02T17:43:40.254Z" }, - { url = "https://files.pythonhosted.org/packages/71/11/0915fbd3ef13b62a6d50ff98a91370fc45547e3f88d462ef40a60320429f/mqt_qcec-3.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae7554ab523c18b1d39c3bfdb0cac40b6fd21daa366dc09b343c560b1b203226", size = 249795, upload-time = "2026-02-02T17:43:42.481Z" }, - { url = "https://files.pythonhosted.org/packages/11/ae/4d8418074c42666fc2f81c8e3460f80509a6480925447c68223fe5bfa5b7/mqt_qcec-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:47d3ce7f5d7267a03310bb6ef84a874989683c2ee2edc463738b0ec074423cd1", size = 447932, upload-time = "2026-02-02T17:43:43.822Z" }, - { url = "https://files.pythonhosted.org/packages/2a/77/52d3ac96a4b5a55227dbb54048880296587fffd418c6be3f4600e7c294e4/mqt_qcec-3.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:346b63d588a755426c9fa9c0a547c40780ad4728245f4dc90cc1af2919c977aa", size = 610377, upload-time = "2026-02-02T17:43:45.56Z" }, - { url = "https://files.pythonhosted.org/packages/e2/44/17e56c3e5cdb62eba5dadc11d0431f1474016e7c126750a046bb0c0d2cb1/mqt_qcec-3.5.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:0ff3d8fba6ec7b607fb5242a908d09cf5e03be396f61a3d7d3126f08194ade1b", size = 221196, upload-time = "2026-02-02T17:43:46.854Z" }, - { url = "https://files.pythonhosted.org/packages/29/9a/7f20a6239bb5ad82a9086d5bdda679bbcf89936f79c13e0e31925b081b21/mqt_qcec-3.5.0-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:2535dd492aca63435583d63fedce92c444fa2147bbf30fcbd65cd30c87cd8053", size = 234058, upload-time = "2026-02-02T17:43:48.048Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/a4629f61ccd4487b0e017a2f29f94ae7eb65b1294d988975f2470dcc9920/mqt_qcec-3.5.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:864b9bc529b7ae6ac16fda710cf9176f767568647465be6d282d5840fe80a127", size = 235161, upload-time = "2026-02-02T17:43:49.244Z" }, - { url = "https://files.pythonhosted.org/packages/3a/73/b7e29bfae67002f9bbe59b284014da86731c349d703b7ed2f557fe16c99d/mqt_qcec-3.5.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:473df3b4a659a12f638abde91432a48c4d0244f863981ba0260ad45da5ef6c13", size = 245990, upload-time = "2026-02-02T17:43:50.511Z" }, - { url = "https://files.pythonhosted.org/packages/84/73/855bdbe827ce8d2631125d896be4f850a2aa30899a963e3e4133164ebfb6/mqt_qcec-3.5.0-cp312-abi3-win_amd64.whl", hash = "sha256:72d32f2dabe2cda53c45377a4cfea24de4be801058d87d5e8410643654aaf0eb", size = 445464, upload-time = "2026-02-02T17:43:51.961Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/7928488953355217114f8c43f1871c8a68e6915ad3bd7194c621ddf4f5c3/mqt_qcec-3.5.0-cp312-abi3-win_arm64.whl", hash = "sha256:4261a969585ee3a5e3db558ffc86a98c47291c620086ff61084df59c3e4a1ae2", size = 607673, upload-time = "2026-02-02T17:43:53.946Z" }, - { url = "https://files.pythonhosted.org/packages/51/37/41b643851a2319604dd416bd64bf9e686ec624f3922b73293d7d42a0c54c/mqt_qcec-3.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0cc641947b33276a0f8357d34be6f2b8e1048691667d1cd4c144eb565c8953a8", size = 224843, upload-time = "2026-02-02T17:43:56.094Z" }, - { url = "https://files.pythonhosted.org/packages/05/1c/f9d5a03073e14b768361e7640f0db0ccd53c9b4407c9e2b3a36e9042837f/mqt_qcec-3.5.0-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:462730f83962562c94f17eedacee78f9fdd060ffd672745a5759bca116742fcb", size = 238475, upload-time = "2026-02-02T17:43:57.324Z" }, - { url = "https://files.pythonhosted.org/packages/ba/5b/8a59f3868b2d1a13d42bfdd19a1d80bd020c8cd8e1b8c641a7ffe94820d1/mqt_qcec-3.5.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:387c2a6ce27ba28513516c67ddbaca63ddc22d4fa87fdfa77b2bdca584d6c1c0", size = 238625, upload-time = "2026-02-02T17:43:58.596Z" }, - { url = "https://files.pythonhosted.org/packages/fa/66/3ef7d078ef137b61006adcb2e35b52d97644ad185b91aa2e80c4f00a12f5/mqt_qcec-3.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:465156fc8c7921bbb7eb7b6a30dfa5fe04deb72da641a65aed42c76e412a7049", size = 249591, upload-time = "2026-02-02T17:44:00.864Z" }, - { url = "https://files.pythonhosted.org/packages/d8/d2/32ada8e9b0a8fdc665d8b1bb947b01e7b78a945aeba00958fbe5165d0c9e/mqt_qcec-3.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bfff9cb4e044382b0789b97f9d4292633f1733f8fff2b5a030ffd781a5a56c1f", size = 465636, upload-time = "2026-02-02T17:44:03.41Z" }, - { url = "https://files.pythonhosted.org/packages/35/7e/0c27bf2615986a9d821d0cbe95bbd0956ad6de0a5d3b4bd7d36d3a9b8698/mqt_qcec-3.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:d95facd11e299607205887ae0a7c8d93523fe188bf611e7d7bce9b04420d4d63", size = 631582, upload-time = "2026-02-02T17:44:05.247Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/37/7a/5e31dce537e8fa84e135a1b06be0284350f940c4b201026486187d936c4a/mqt_qcec-3.4.0.tar.gz", hash = "sha256:c377adfa58ae5b0ad391fe7d6dca9f77f80d030a54059f804f91075f3be89d88", size = 270579, upload-time = "2026-01-13T00:00:19.214Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/50/457df1f9e85a0a2db3daf3cf995c8dd68c8e25b7a888744b8d175b80ca63/mqt_qcec-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d91955a0416ea1da079d92a7e0a48450ba131e97f6fff48e070b499f10314d85", size = 219757, upload-time = "2026-01-12T23:59:42.811Z" }, + { url = "https://files.pythonhosted.org/packages/a8/dc/6748f4e4dbe1193d7c3f940ecc367e1c369dff150174423c75eaa1d69a84/mqt_qcec-3.4.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:9c45fa5b2aaeb642feffd3e24c26d521c8048bf8d54b36e56b1e74828c7b52b1", size = 230690, upload-time = "2026-01-12T23:59:44.861Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3e/52fa68814db3dbfc881dbe4307f2548c88d4d0c82f80edcaba2927c896fd/mqt_qcec-3.4.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df569179281c246fb575e138fb600789119244827bece5c5cc8243960b6de4b3", size = 232121, upload-time = "2026-01-12T23:59:46.835Z" }, + { url = "https://files.pythonhosted.org/packages/aa/24/62adb9f2c2eae43151f0e53c537251b7fe34cc73dcb29ec9f4115e56e1c9/mqt_qcec-3.4.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeb4cb0e84a53cca6b220dbc5fcafd2ed6566810b0a318bf614410ac130c292", size = 243521, upload-time = "2026-01-12T23:59:48.346Z" }, + { url = "https://files.pythonhosted.org/packages/08/5d/4cf39c229f2c97715560132ccff24e93250d8bbf0d13cd88ba85acf8a677/mqt_qcec-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:595f4bb5f45542bd881bff57c8294903dc01aca2268495aed12129418de39ed2", size = 442535, upload-time = "2026-01-12T23:59:50.021Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/3e7f3ecfcc2977b6ad7da3bbc5fb9e456cb09758306002fb962a5cb02d51/mqt_qcec-3.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:4592d96b4945a48f3f954786f1524a7ce7914d7abc92347f3dc618ba75e93277", size = 604229, upload-time = "2026-01-12T23:59:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6029ae5438390764e18d9b26438baf464a9c110159567d177af2ad5e9dde/mqt_qcec-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:335b7eee0ffc189f5d26c2821f25adcb282740d3e58d4b269906790a7a0cd813", size = 220276, upload-time = "2026-01-12T23:59:53.38Z" }, + { url = "https://files.pythonhosted.org/packages/09/78/b2abede13c32db207826e216a36a2255412b1b67153f69f7346f95a748ef/mqt_qcec-3.4.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:8d31efda94061dabaab9c6e62801785f062fd21ff49d848dced6dbe546293796", size = 231156, upload-time = "2026-01-12T23:59:54.694Z" }, + { url = "https://files.pythonhosted.org/packages/44/0e/48b9b53118e04b156c234c61c385edfeda9910af1f2bed7e6ffae5b87399/mqt_qcec-3.4.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e214a4065283bd08abe9a15080ff1f00cd5e0a3de29596def5d2b5a568816485", size = 232771, upload-time = "2026-01-12T23:59:55.876Z" }, + { url = "https://files.pythonhosted.org/packages/8f/46/8e524a1fd0849a29f2698870384da62941b7c9c79ddb39595f5f424f9e03/mqt_qcec-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b2a91e0028124a8948ee032370e10f3cd9c3c636700f9be1d8d3d1a19c5f0f4a", size = 244215, upload-time = "2026-01-12T23:59:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/4d/0f/4ad73f21a27bbb1abd219999f58793ac4c1f196058faa1e5c8aa63116119/mqt_qcec-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:e8bc94ed705dabf45617559186ff0dc30c9bf9269bedce419d9bffe6b8317fe0", size = 442657, upload-time = "2026-01-12T23:59:58.881Z" }, + { url = "https://files.pythonhosted.org/packages/ed/dc/b2519af45241c8e895f09c686391b03fb1b80ef5148845e7fbe840c3bca8/mqt_qcec-3.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:19369e646ebe5aa5c442ac661d220f68ac4345d74f454d7a9305d3059b30047d", size = 604437, upload-time = "2026-01-13T00:00:00.371Z" }, + { url = "https://files.pythonhosted.org/packages/db/01/d9ce094ad0ca806764be18949625f2f2ab83a7e4eef015485defd790c91c/mqt_qcec-3.4.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:26cfee5ff8598f8e3f6109cae9bf188a142121c08a8e8e936a79035ec2b3c3b1", size = 218244, upload-time = "2026-01-13T00:00:01.932Z" }, + { url = "https://files.pythonhosted.org/packages/65/a0/0006ff22ef4a6798723e70cc5713aeb6ed131855e370ba22ff9d76f3c85f/mqt_qcec-3.4.0-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:8d7586aaebfce3b33a944a9b4cb8245e647a8402f42d361acfd874ccd866df5a", size = 229054, upload-time = "2026-01-13T00:00:03.485Z" }, + { url = "https://files.pythonhosted.org/packages/50/60/f672f83fa405408d70dadd3bc3f6e8cfb222cf3be8a94ddeaa35d199a882/mqt_qcec-3.4.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13369cbec8a97df45287abdb2c5e2aedfa3489c1546aa9d687117ba7c8e9bafd", size = 230128, upload-time = "2026-01-13T00:00:04.934Z" }, + { url = "https://files.pythonhosted.org/packages/c1/71/699b36807dbac841fdff1a0a006dff772684727f310e98df7bcf5943e884/mqt_qcec-3.4.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18fd8a82b21140eedca59ba0f0d7be6ade22dd23be1fb9805ce083eed02b89be", size = 241548, upload-time = "2026-01-13T00:00:06.388Z" }, + { url = "https://files.pythonhosted.org/packages/e7/24/41078231012e94334941b0ead0aad997edbd5f6f6bd073c1c25aaa2dda48/mqt_qcec-3.4.0-cp312-abi3-win_amd64.whl", hash = "sha256:a470e9a36abb81bdc0cecae4611f2b3a829e2cb2f4d9f00f2764e5eac8900baa", size = 439875, upload-time = "2026-01-13T00:00:07.633Z" }, + { url = "https://files.pythonhosted.org/packages/1d/24/01c16a947da77e838ef7795cb1c6cbd0b8b69a5d7a268a36c4a16fdae6e0/mqt_qcec-3.4.0-cp312-abi3-win_arm64.whl", hash = "sha256:aad9029b83b7af24b71ca7ca2c22b1434329d800e97d3042b457db5c5a5b190d", size = 601346, upload-time = "2026-01-13T00:00:09.042Z" }, + { url = "https://files.pythonhosted.org/packages/82/4f/aa17b65b71b2a0b1a2fccec6846a79b84f5db11800b6d77c93a1bee8d657/mqt_qcec-3.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ac40f4e64ee3afea8ca24bc5a492dab620c913a932c4f5b4e18091e3bb9d432", size = 222588, upload-time = "2026-01-13T00:00:10.308Z" }, + { url = "https://files.pythonhosted.org/packages/6a/0e/1add710c71abdf22be358e1355bae85f27877b42df6e67817d0a83c5e4c5/mqt_qcec-3.4.0-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:b969f52876c04356291d4d4f89c9952cd5588f040c24ba6dd591adb5e33cfb5f", size = 233742, upload-time = "2026-01-13T00:00:11.483Z" }, + { url = "https://files.pythonhosted.org/packages/b0/72/cbf82e7bcd07140a88a38adbad7f26c6999f86884716ee87f48f688fec0d/mqt_qcec-3.4.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c3e729e9568445d6d96d5caabb547f2c3786f86bfdb73741d446ea9c06a1fd", size = 232923, upload-time = "2026-01-13T00:00:12.866Z" }, + { url = "https://files.pythonhosted.org/packages/a6/aa/0904ec5fe67a640b0e89bc6f3109565ff877d3f06fd0d35965443b43554f/mqt_qcec-3.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b83542637cb7f34be54db8add598730f4489aa3ef735e4fca5f17a414e79f845", size = 243746, upload-time = "2026-01-13T00:00:14.405Z" }, + { url = "https://files.pythonhosted.org/packages/e1/90/1d03528f51d75d58fe1b91370aa98797503652e620edb2e91a3f5244b41c/mqt_qcec-3.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3e6c8d4b86aac472d1594cc99687a716478bab50c1f183c77bfe447abbc1a389", size = 460307, upload-time = "2026-01-13T00:00:16.109Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/f1859794bb410e3f44572318b58486cb0d329c9ba9f208f5397e383f4e4f/mqt_qcec-3.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:85332159c6bb7a9a595eef7a8cf0a84b39fd7103eb469e49aff31b4f6b293b91", size = 626193, upload-time = "2026-01-13T00:00:17.767Z" }, ] [[package]] @@ -1711,12 +1625,10 @@ docs = [ { name = "qiskit", extra = ["qasm3-import", "visualization"] }, { name = "setuptools-scm" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "sphinx-autoapi" }, { name = "sphinx-copybutton" }, - { name = "sphinx-design", version = "0.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx-design", version = "0.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx-design" }, { name = "sphinxcontrib-bibtex" }, { name = "sphinxcontrib-svg2pdfconverter" }, { name = "sphinxext-opengraph" }, @@ -1740,7 +1652,7 @@ test = [ requires-dist = [ { name = "distinctipy", marker = "extra == 'visualization'", specifier = ">=1.3.4" }, { name = "ipywidgets", marker = "extra == 'visualization'", specifier = ">=8.1.7" }, - { name = "mqt-core", specifier = "~=3.4.1" }, + { name = "mqt-core", specifier = "~=3.4.0" }, { name = "networkx", marker = "extra == 'visualization'", specifier = ">=3.2.1" }, { name = "plotly", marker = "extra == 'visualization'", specifier = ">=6.0.1" }, { name = "qiskit", extras = ["qasm3-import"], specifier = ">=1.0.0" }, @@ -1752,17 +1664,17 @@ provides-extras = ["visualization"] [package.metadata.requires-dev] build = [ - { name = "mqt-core", specifier = "~=3.4.1" }, - { name = "nanobind", specifier = "~=2.11.0" }, + { name = "mqt-core", specifier = "~=3.4.0" }, + { name = "nanobind", specifier = ">=2.10.2" }, { name = "scikit-build-core", specifier = ">=0.11.6" }, { name = "setuptools-scm", specifier = ">=9.2.2" }, ] dev = [ { name = "distinctipy", specifier = ">=1.3.4" }, { name = "ipywidgets", specifier = ">=8.1.7" }, - { name = "mqt-core", specifier = "~=3.4.1" }, - { name = "mqt-qcec", specifier = ">=3.5.0" }, - { name = "nanobind", specifier = "~=2.11.0" }, + { name = "mqt-core", specifier = "~=3.4.0" }, + { name = "mqt-qcec", specifier = ">=3.4.0" }, + { name = "nanobind", specifier = ">=2.10.2" }, { name = "networkx", specifier = ">=3.2.1" }, { name = "nox", specifier = ">=2025.11.12" }, { name = "plotly", specifier = ">=6.0.1" }, @@ -1772,7 +1684,7 @@ dev = [ { name = "pytest-xdist", specifier = ">=3.8.0" }, { name = "scikit-build-core", specifier = ">=0.11.6" }, { name = "setuptools-scm", specifier = ">=9.2.2" }, - { name = "ty", specifier = "==0.0.15" }, + { name = "ty", specifier = "==0.0.13" }, { name = "walkerlayout", specifier = ">=1.0.2" }, ] docs = [ @@ -1797,7 +1709,7 @@ docs = [ test = [ { name = "distinctipy", specifier = ">=1.3.4" }, { name = "ipywidgets", specifier = ">=8.1.7" }, - { name = "mqt-qcec", specifier = ">=3.5.0" }, + { name = "mqt-qcec", specifier = ">=3.4.0" }, { name = "networkx", specifier = ">=3.2.1" }, { name = "plotly", specifier = ">=6.0.1" }, { name = "pytest", specifier = ">=9.0.1" }, @@ -1815,7 +1727,7 @@ dependencies = [ { name = "importlib-metadata" }, { name = "ipykernel" }, { name = "ipython", version = "8.38.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "9.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyter-cache" }, { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "myst-parser", version = "5.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -1823,8 +1735,7 @@ dependencies = [ { name = "nbformat" }, { name = "pyyaml" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/83/a894bd8dea7a6e9f053502ee8413484dcbf75a219013d6a72e971c0fecfd/myst_nb-1.3.0.tar.gz", hash = "sha256:df3cd4680f51a5af673fd46b38b562be3559aef1475e906ed0f2e66e4587ce4b", size = 81963, upload-time = "2025-07-13T22:49:38.493Z" } @@ -1840,7 +1751,7 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "docutils", marker = "python_full_version < '3.11'" }, { name = "jinja2", marker = "python_full_version < '3.11'" }, { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "mdit-py-plugins", marker = "python_full_version < '3.11'" }, @@ -1857,27 +1768,18 @@ name = "myst-parser" version = "5.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "docutils", marker = "python_full_version >= '3.11'" }, { name = "jinja2", marker = "python_full_version >= '3.11'" }, { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "mdit-py-plugins", marker = "python_full_version >= '3.11'" }, { name = "pyyaml", marker = "python_full_version >= '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/fa/7b45eef11b7971f0beb29d27b7bfe0d747d063aa29e170d9edd004733c8a/myst_parser-5.0.0.tar.gz", hash = "sha256:f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a", size = 98535, upload-time = "2026-01-15T09:08:18.036Z" } wheels = [ @@ -1886,20 +1788,20 @@ wheels = [ [[package]] name = "nanobind" -version = "2.11.0" +version = "2.10.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/d6/2d17c0a630fabc05785c0ea57a994bb165b342416bec8e41c96f3fee5add/nanobind-2.11.0.tar.gz", hash = "sha256:6d98d063c61dbbd05a2d903e59be398bfcff9d59c54fbbc9d4488960485d40d0", size = 1001251, upload-time = "2026-01-29T11:24:34.403Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/7b/818fe4f6d1fdd516a14386ba86f2cbbac1b7304930da0f029724e9001658/nanobind-2.10.2.tar.gz", hash = "sha256:08509910ce6d1fadeed69cb0880d4d4fcb77739c6af9bd8fb4419391a3ca4c6b", size = 993651, upload-time = "2025-12-10T10:55:32.335Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/1c/37ae5b9a0d13defd8e27222e4cbfb82e569dbfd12d16ba8c78cab593e56c/nanobind-2.11.0-py3-none-any.whl", hash = "sha256:8097442c3e55d011a67f016ce1d9567ed9e3cdb3ad6749f13a76dbbc2721f0ee", size = 248913, upload-time = "2026-01-29T11:24:32.651Z" }, + { url = "https://files.pythonhosted.org/packages/14/06/cb08965f985a5e1b9cb55ed96337c1f6daaa6b9cbdaeabe6bb3f7a1a11df/nanobind-2.10.2-py3-none-any.whl", hash = "sha256:6976c1b04b90481d2612b346485a3063818c6faa5077fe9d8bbc9b5fbe29c380", size = 246514, upload-time = "2025-12-10T10:55:30.741Z" }, ] [[package]] name = "narwhals" -version = "2.16.0" +version = "2.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/6f/713be67779028d482c6e0f2dde5bc430021b2578a4808c1c9f6d7ad48257/narwhals-2.16.0.tar.gz", hash = "sha256:155bb45132b370941ba0396d123cf9ed192bf25f39c4cea726f2da422ca4e145", size = 618268, upload-time = "2026-02-02T10:31:00.545Z" } +sdist = { url = "https://files.pythonhosted.org/packages/47/6d/b57c64e5038a8cf071bce391bb11551657a74558877ac961e7fa905ece27/narwhals-2.15.0.tar.gz", hash = "sha256:a9585975b99d95084268445a1fdd881311fa26ef1caa18020d959d5b2ff9a965", size = 603479, upload-time = "2026-01-06T08:10:13.27Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/cc/7cb74758e6df95e0c4e1253f203b6dd7f348bf2f29cf89e9210a2416d535/narwhals-2.16.0-py3-none-any.whl", hash = "sha256:846f1fd7093ac69d63526e50732033e86c30ea0026a44d9b23991010c7d1485d", size = 443951, upload-time = "2026-02-02T10:30:58.635Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2e/cf2ffeb386ac3763526151163ad7da9f1b586aac96d2b4f7de1eaebf0c61/narwhals-2.15.0-py3-none-any.whl", hash = "sha256:cbfe21ca19d260d9fd67f995ec75c44592d1f106933b03ddd375df7ac841f9d6", size = 432856, upload-time = "2026-01-06T08:10:11.511Z" }, ] [[package]] @@ -1958,18 +1860,10 @@ name = "networkx" version = "3.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } wheels = [ @@ -1978,7 +1872,7 @@ wheels = [ [[package]] name = "nox" -version = "2026.2.9" +version = "2025.11.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, @@ -1990,9 +1884,9 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/8e/55a9679b31f1efc48facedd2448eb53c7f1e647fb592aa1403c9dd7a4590/nox-2026.2.9.tar.gz", hash = "sha256:1bc8a202ee8cd69be7aaada63b2a7019126899a06fc930a7aee75585bf8ee41b", size = 4031165, upload-time = "2026-02-10T04:38:58.878Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/a8/e169497599266d176832e2232c08557ffba97eef87bf8a18f9f918e0c6aa/nox-2025.11.12.tar.gz", hash = "sha256:3d317f9e61f49d6bde39cf2f59695bb4e1722960457eee3ae19dacfe03c07259", size = 4030561, upload-time = "2025-11-12T18:39:03.319Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/58/0d5e5a044f1868bdc45f38afdc2d90ff9867ce398b4e8fa9e666bfc9bfba/nox-2026.2.9-py3-none-any.whl", hash = "sha256:1b7143bc8ecdf25f2353201326152c5303ae4ae56ca097b1fb6179ad75164c47", size = 74615, upload-time = "2026-02-10T04:38:57.266Z" }, + { url = "https://files.pythonhosted.org/packages/b9/34/434c594e0125a16b05a7bedaea33e63c90abbfbe47e5729a735a8a8a90ea/nox-2025.11.12-py3-none-any.whl", hash = "sha256:707171f9f63bc685da9d00edd8c2ceec8405b8e38b5fb4e46114a860070ef0ff", size = 74447, upload-time = "2025-11-12T18:39:01.575Z" }, ] [[package]] @@ -2062,95 +1956,87 @@ wheels = [ [[package]] name = "numpy" -version = "2.4.2" +version = "2.4.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825", size = 16955478, upload-time = "2026-01-31T23:10:25.623Z" }, - { url = "https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1", size = 14965467, upload-time = "2026-01-31T23:10:28.186Z" }, - { url = "https://files.pythonhosted.org/packages/49/48/fb1ce8136c19452ed15f033f8aee91d5defe515094e330ce368a0647846f/numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7", size = 5475172, upload-time = "2026-01-31T23:10:30.848Z" }, - { url = "https://files.pythonhosted.org/packages/40/a9/3feb49f17bbd1300dd2570432961f5c8a4ffeff1db6f02c7273bd020a4c9/numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73", size = 6805145, upload-time = "2026-01-31T23:10:32.352Z" }, - { url = "https://files.pythonhosted.org/packages/3f/39/fdf35cbd6d6e2fcad42fcf85ac04a85a0d0fbfbf34b30721c98d602fd70a/numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1", size = 15966084, upload-time = "2026-01-31T23:10:34.502Z" }, - { url = "https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32", size = 16899477, upload-time = "2026-01-31T23:10:37.075Z" }, - { url = "https://files.pythonhosted.org/packages/09/a1/2a424e162b1a14a5bd860a464ab4e07513916a64ab1683fae262f735ccd2/numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390", size = 17323429, upload-time = "2026-01-31T23:10:39.704Z" }, - { url = "https://files.pythonhosted.org/packages/ce/a2/73014149ff250628df72c58204822ac01d768697913881aacf839ff78680/numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413", size = 18635109, upload-time = "2026-01-31T23:10:41.924Z" }, - { url = "https://files.pythonhosted.org/packages/6c/0c/73e8be2f1accd56df74abc1c5e18527822067dced5ec0861b5bb882c2ce0/numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda", size = 6237915, upload-time = "2026-01-31T23:10:45.26Z" }, - { url = "https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695", size = 12607972, upload-time = "2026-01-31T23:10:47.021Z" }, - { url = "https://files.pythonhosted.org/packages/29/a5/c43029af9b8014d6ea157f192652c50042e8911f4300f8f6ed3336bf437f/numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3", size = 10485763, upload-time = "2026-01-31T23:10:50.087Z" }, - { url = "https://files.pythonhosted.org/packages/51/6e/6f394c9c77668153e14d4da83bcc247beb5952f6ead7699a1a2992613bea/numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a", size = 16667963, upload-time = "2026-01-31T23:10:52.147Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f8/55483431f2b2fd015ae6ed4fe62288823ce908437ed49db5a03d15151678/numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1", size = 14693571, upload-time = "2026-01-31T23:10:54.789Z" }, - { url = "https://files.pythonhosted.org/packages/2f/20/18026832b1845cdc82248208dd929ca14c9d8f2bac391f67440707fff27c/numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e", size = 5203469, upload-time = "2026-01-31T23:10:57.343Z" }, - { url = "https://files.pythonhosted.org/packages/7d/33/2eb97c8a77daaba34eaa3fa7241a14ac5f51c46a6bd5911361b644c4a1e2/numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27", size = 6550820, upload-time = "2026-01-31T23:10:59.429Z" }, - { url = "https://files.pythonhosted.org/packages/b1/91/b97fdfd12dc75b02c44e26c6638241cc004d4079a0321a69c62f51470c4c/numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548", size = 15663067, upload-time = "2026-01-31T23:11:01.291Z" }, - { url = "https://files.pythonhosted.org/packages/f5/c6/a18e59f3f0b8071cc85cbc8d80cd02d68aa9710170b2553a117203d46936/numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f", size = 16619782, upload-time = "2026-01-31T23:11:03.669Z" }, - { url = "https://files.pythonhosted.org/packages/b7/83/9751502164601a79e18847309f5ceec0b1446d7b6aa12305759b72cf98b2/numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460", size = 17013128, upload-time = "2026-01-31T23:11:05.913Z" }, - { url = "https://files.pythonhosted.org/packages/61/c4/c4066322256ec740acc1c8923a10047818691d2f8aec254798f3dd90f5f2/numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba", size = 18345324, upload-time = "2026-01-31T23:11:08.248Z" }, - { url = "https://files.pythonhosted.org/packages/ab/af/6157aa6da728fa4525a755bfad486ae7e3f76d4c1864138003eb84328497/numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f", size = 5960282, upload-time = "2026-01-31T23:11:10.497Z" }, - { url = "https://files.pythonhosted.org/packages/92/0f/7ceaaeaacb40567071e94dbf2c9480c0ae453d5bb4f52bea3892c39dc83c/numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85", size = 12314210, upload-time = "2026-01-31T23:11:12.176Z" }, - { url = "https://files.pythonhosted.org/packages/2f/a3/56c5c604fae6dd40fa2ed3040d005fca97e91bd320d232ac9931d77ba13c/numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa", size = 10220171, upload-time = "2026-01-31T23:11:14.684Z" }, - { url = "https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c", size = 16663696, upload-time = "2026-01-31T23:11:17.516Z" }, - { url = "https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979", size = 14688322, upload-time = "2026-01-31T23:11:19.883Z" }, - { url = "https://files.pythonhosted.org/packages/da/b4/f805ab79293c728b9a99438775ce51885fd4f31b76178767cfc718701a39/numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98", size = 5198157, upload-time = "2026-01-31T23:11:22.375Z" }, - { url = "https://files.pythonhosted.org/packages/74/09/826e4289844eccdcd64aac27d13b0fd3f32039915dd5b9ba01baae1f436c/numpy-2.4.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:aea4f66ff44dfddf8c2cffd66ba6538c5ec67d389285292fe428cb2c738c8aef", size = 6546330, upload-time = "2026-01-31T23:11:23.958Z" }, - { url = "https://files.pythonhosted.org/packages/19/fb/cbfdbfa3057a10aea5422c558ac57538e6acc87ec1669e666d32ac198da7/numpy-2.4.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3cd545784805de05aafe1dde61752ea49a359ccba9760c1e5d1c88a93bbf2b7", size = 15660968, upload-time = "2026-01-31T23:11:25.713Z" }, - { url = "https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499", size = 16607311, upload-time = "2026-01-31T23:11:28.117Z" }, - { url = "https://files.pythonhosted.org/packages/14/d9/4b5adfc39a43fa6bf918c6d544bc60c05236cc2f6339847fc5b35e6cb5b0/numpy-2.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f74f0f7779cc7ae07d1810aab8ac6b1464c3eafb9e283a40da7309d5e6e48fbb", size = 17012850, upload-time = "2026-01-31T23:11:30.888Z" }, - { url = "https://files.pythonhosted.org/packages/b7/20/adb6e6adde6d0130046e6fdfb7675cc62bc2f6b7b02239a09eb58435753d/numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7", size = 18334210, upload-time = "2026-01-31T23:11:33.214Z" }, - { url = "https://files.pythonhosted.org/packages/78/0e/0a73b3dff26803a8c02baa76398015ea2a5434d9b8265a7898a6028c1591/numpy-2.4.2-cp313-cp313-win32.whl", hash = "sha256:8e9afaeb0beff068b4d9cd20d322ba0ee1cecfb0b08db145e4ab4dd44a6b5110", size = 5958199, upload-time = "2026-01-31T23:11:35.385Z" }, - { url = "https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622", size = 12310848, upload-time = "2026-01-31T23:11:38.001Z" }, - { url = "https://files.pythonhosted.org/packages/6e/8d/6da186483e308da5da1cc6918ce913dcfe14ffde98e710bfeff2a6158d4e/numpy-2.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:0fece1d1f0a89c16b03442eae5c56dc0be0c7883b5d388e0c03f53019a4bfd71", size = 10221082, upload-time = "2026-01-31T23:11:40.392Z" }, - { url = "https://files.pythonhosted.org/packages/25/a1/9510aa43555b44781968935c7548a8926274f815de42ad3997e9e83680dd/numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262", size = 14815866, upload-time = "2026-01-31T23:11:42.495Z" }, - { url = "https://files.pythonhosted.org/packages/36/30/6bbb5e76631a5ae46e7923dd16ca9d3f1c93cfa8d4ed79a129814a9d8db3/numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913", size = 5325631, upload-time = "2026-01-31T23:11:44.7Z" }, - { url = "https://files.pythonhosted.org/packages/46/00/3a490938800c1923b567b3a15cd17896e68052e2145d8662aaf3e1ffc58f/numpy-2.4.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:b21041e8cb6a1eb5312dd1d2f80a94d91efffb7a06b70597d44f1bd2dfc315ab", size = 6646254, upload-time = "2026-01-31T23:11:46.341Z" }, - { url = "https://files.pythonhosted.org/packages/d3/e9/fac0890149898a9b609caa5af7455a948b544746e4b8fe7c212c8edd71f8/numpy-2.4.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82", size = 15720138, upload-time = "2026-01-31T23:11:48.082Z" }, - { url = "https://files.pythonhosted.org/packages/ea/5c/08887c54e68e1e28df53709f1893ce92932cc6f01f7c3d4dc952f61ffd4e/numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f", size = 16655398, upload-time = "2026-01-31T23:11:50.293Z" }, - { url = "https://files.pythonhosted.org/packages/4d/89/253db0fa0e66e9129c745e4ef25631dc37d5f1314dad2b53e907b8538e6d/numpy-2.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66cb9422236317f9d44b67b4d18f44efe6e9c7f8794ac0462978513359461554", size = 17079064, upload-time = "2026-01-31T23:11:52.927Z" }, - { url = "https://files.pythonhosted.org/packages/2a/d5/cbade46ce97c59c6c3da525e8d95b7abe8a42974a1dc5c1d489c10433e88/numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257", size = 18379680, upload-time = "2026-01-31T23:11:55.22Z" }, - { url = "https://files.pythonhosted.org/packages/40/62/48f99ae172a4b63d981babe683685030e8a3df4f246c893ea5c6ef99f018/numpy-2.4.2-cp313-cp313t-win32.whl", hash = "sha256:52b913ec40ff7ae845687b0b34d8d93b60cb66dcee06996dd5c99f2fc9328657", size = 6082433, upload-time = "2026-01-31T23:11:58.096Z" }, - { url = "https://files.pythonhosted.org/packages/07/38/e054a61cfe48ad9f1ed0d188e78b7e26859d0b60ef21cd9de4897cdb5326/numpy-2.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5eea80d908b2c1f91486eb95b3fb6fab187e569ec9752ab7d9333d2e66bf2d6b", size = 12451181, upload-time = "2026-01-31T23:11:59.782Z" }, - { url = "https://files.pythonhosted.org/packages/6e/a4/a05c3a6418575e185dd84d0b9680b6bb2e2dc3e4202f036b7b4e22d6e9dc/numpy-2.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fd49860271d52127d61197bb50b64f58454e9f578cb4b2c001a6de8b1f50b0b1", size = 10290756, upload-time = "2026-01-31T23:12:02.438Z" }, - { url = "https://files.pythonhosted.org/packages/18/88/b7df6050bf18fdcfb7046286c6535cabbdd2064a3440fca3f069d319c16e/numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b", size = 16663092, upload-time = "2026-01-31T23:12:04.521Z" }, - { url = "https://files.pythonhosted.org/packages/25/7a/1fee4329abc705a469a4afe6e69b1ef7e915117747886327104a8493a955/numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000", size = 14698770, upload-time = "2026-01-31T23:12:06.96Z" }, - { url = "https://files.pythonhosted.org/packages/fb/0b/f9e49ba6c923678ad5bc38181c08ac5e53b7a5754dbca8e581aa1a56b1ff/numpy-2.4.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:7cdde6de52fb6664b00b056341265441192d1291c130e99183ec0d4b110ff8b1", size = 5208562, upload-time = "2026-01-31T23:12:09.632Z" }, - { url = "https://files.pythonhosted.org/packages/7d/12/d7de8f6f53f9bb76997e5e4c069eda2051e3fe134e9181671c4391677bb2/numpy-2.4.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:cda077c2e5b780200b6b3e09d0b42205a3d1c68f30c6dceb90401c13bff8fe74", size = 6543710, upload-time = "2026-01-31T23:12:11.969Z" }, - { url = "https://files.pythonhosted.org/packages/09/63/c66418c2e0268a31a4cf8a8b512685748200f8e8e8ec6c507ce14e773529/numpy-2.4.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30291931c915b2ab5717c2974bb95ee891a1cf22ebc16a8006bd59cd210d40a", size = 15677205, upload-time = "2026-01-31T23:12:14.33Z" }, - { url = "https://files.pythonhosted.org/packages/5d/6c/7f237821c9642fb2a04d2f1e88b4295677144ca93285fd76eff3bcba858d/numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325", size = 16611738, upload-time = "2026-01-31T23:12:16.525Z" }, - { url = "https://files.pythonhosted.org/packages/c2/a7/39c4cdda9f019b609b5c473899d87abff092fc908cfe4d1ecb2fcff453b0/numpy-2.4.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b2f0073ed0868db1dcd86e052d37279eef185b9c8db5bf61f30f46adac63c909", size = 17028888, upload-time = "2026-01-31T23:12:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/da/b3/e84bb64bdfea967cc10950d71090ec2d84b49bc691df0025dddb7c26e8e3/numpy-2.4.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f54844851cdb630ceb623dcec4db3240d1ac13d4990532446761baede94996a", size = 18339556, upload-time = "2026-01-31T23:12:21.816Z" }, - { url = "https://files.pythonhosted.org/packages/88/f5/954a291bc1192a27081706862ac62bb5920fbecfbaa302f64682aa90beed/numpy-2.4.2-cp314-cp314-win32.whl", hash = "sha256:12e26134a0331d8dbd9351620f037ec470b7c75929cb8a1537f6bfe411152a1a", size = 6006899, upload-time = "2026-01-31T23:12:24.14Z" }, - { url = "https://files.pythonhosted.org/packages/05/cb/eff72a91b2efdd1bc98b3b8759f6a1654aa87612fc86e3d87d6fe4f948c4/numpy-2.4.2-cp314-cp314-win_amd64.whl", hash = "sha256:068cdb2d0d644cdb45670810894f6a0600797a69c05f1ac478e8d31670b8ee75", size = 12443072, upload-time = "2026-01-31T23:12:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/37/75/62726948db36a56428fce4ba80a115716dc4fad6a3a4352487f8bb950966/numpy-2.4.2-cp314-cp314-win_arm64.whl", hash = "sha256:6ed0be1ee58eef41231a5c943d7d1375f093142702d5723ca2eb07db9b934b05", size = 10494886, upload-time = "2026-01-31T23:12:28.488Z" }, - { url = "https://files.pythonhosted.org/packages/36/2f/ee93744f1e0661dc267e4b21940870cabfae187c092e1433b77b09b50ac4/numpy-2.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:98f16a80e917003a12c0580f97b5f875853ebc33e2eaa4bccfc8201ac6869308", size = 14818567, upload-time = "2026-01-31T23:12:30.709Z" }, - { url = "https://files.pythonhosted.org/packages/a7/24/6535212add7d76ff938d8bdc654f53f88d35cddedf807a599e180dcb8e66/numpy-2.4.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:20abd069b9cda45874498b245c8015b18ace6de8546bf50dfa8cea1696ed06ef", size = 5328372, upload-time = "2026-01-31T23:12:32.962Z" }, - { url = "https://files.pythonhosted.org/packages/5e/9d/c48f0a035725f925634bf6b8994253b43f2047f6778a54147d7e213bc5a7/numpy-2.4.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e98c97502435b53741540a5717a6749ac2ada901056c7db951d33e11c885cc7d", size = 6649306, upload-time = "2026-01-31T23:12:34.797Z" }, - { url = "https://files.pythonhosted.org/packages/81/05/7c73a9574cd4a53a25907bad38b59ac83919c0ddc8234ec157f344d57d9a/numpy-2.4.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da6cad4e82cb893db4b69105c604d805e0c3ce11501a55b5e9f9083b47d2ffe8", size = 15722394, upload-time = "2026-01-31T23:12:36.565Z" }, - { url = "https://files.pythonhosted.org/packages/35/fa/4de10089f21fc7d18442c4a767ab156b25c2a6eaf187c0db6d9ecdaeb43f/numpy-2.4.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e4424677ce4b47fe73c8b5556d876571f7c6945d264201180db2dc34f676ab5", size = 16653343, upload-time = "2026-01-31T23:12:39.188Z" }, - { url = "https://files.pythonhosted.org/packages/b8/f9/d33e4ffc857f3763a57aa85650f2e82486832d7492280ac21ba9efda80da/numpy-2.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2b8f157c8a6f20eb657e240f8985cc135598b2b46985c5bccbde7616dc9c6b1e", size = 17078045, upload-time = "2026-01-31T23:12:42.041Z" }, - { url = "https://files.pythonhosted.org/packages/c8/b8/54bdb43b6225badbea6389fa038c4ef868c44f5890f95dd530a218706da3/numpy-2.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5daf6f3914a733336dab21a05cdec343144600e964d2fcdabaac0c0269874b2a", size = 18380024, upload-time = "2026-01-31T23:12:44.331Z" }, - { url = "https://files.pythonhosted.org/packages/a5/55/6e1a61ded7af8df04016d81b5b02daa59f2ea9252ee0397cb9f631efe9e5/numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443", size = 6153937, upload-time = "2026-01-31T23:12:47.229Z" }, - { url = "https://files.pythonhosted.org/packages/45/aa/fa6118d1ed6d776b0983f3ceac9b1a5558e80df9365b1c3aa6d42bf9eee4/numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236", size = 12631844, upload-time = "2026-01-31T23:12:48.997Z" }, - { url = "https://files.pythonhosted.org/packages/32/0a/2ec5deea6dcd158f254a7b372fb09cfba5719419c8d66343bab35237b3fb/numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181", size = 10565379, upload-time = "2026-01-31T23:12:51.345Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f8/50e14d36d915ef64d8f8bc4a087fc8264d82c785eda6711f80ab7e620335/numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082", size = 16833179, upload-time = "2026-01-31T23:12:53.5Z" }, - { url = "https://files.pythonhosted.org/packages/17/17/809b5cad63812058a8189e91a1e2d55a5a18fd04611dbad244e8aeae465c/numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a", size = 14889755, upload-time = "2026-01-31T23:12:55.933Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ea/181b9bcf7627fc8371720316c24db888dcb9829b1c0270abf3d288b2e29b/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920", size = 5399500, upload-time = "2026-01-31T23:12:58.671Z" }, - { url = "https://files.pythonhosted.org/packages/33/9f/413adf3fc955541ff5536b78fcf0754680b3c6d95103230252a2c9408d23/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821", size = 6714252, upload-time = "2026-01-31T23:13:00.518Z" }, - { url = "https://files.pythonhosted.org/packages/91/da/643aad274e29ccbdf42ecd94dafe524b81c87bcb56b83872d54827f10543/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb", size = 15797142, upload-time = "2026-01-31T23:13:02.219Z" }, - { url = "https://files.pythonhosted.org/packages/66/27/965b8525e9cb5dc16481b30a1b3c21e50c7ebf6e9dbd48d0c4d0d5089c7e/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0", size = 16727979, upload-time = "2026-01-31T23:13:04.62Z" }, - { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", +] +sdist = { url = "https://files.pythonhosted.org/packages/24/62/ae72ff66c0f1fd959925b4c11f8c2dea61f47f6acaea75a08512cdfe3fed/numpy-2.4.1.tar.gz", hash = "sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690", size = 20721320, upload-time = "2026-01-10T06:44:59.619Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/34/2b1bc18424f3ad9af577f6ce23600319968a70575bd7db31ce66731bbef9/numpy-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0cce2a669e3c8ba02ee563c7835f92c153cf02edff1ae05e1823f1dde21b16a5", size = 16944563, upload-time = "2026-01-10T06:42:14.615Z" }, + { url = "https://files.pythonhosted.org/packages/2c/57/26e5f97d075aef3794045a6ca9eada6a4ed70eb9a40e7a4a93f9ac80d704/numpy-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:899d2c18024984814ac7e83f8f49d8e8180e2fbe1b2e252f2e7f1d06bea92425", size = 12645658, upload-time = "2026-01-10T06:42:17.298Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ba/80fc0b1e3cb2fd5c6143f00f42eb67762aa043eaa05ca924ecc3222a7849/numpy-2.4.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:09aa8a87e45b55a1c2c205d42e2808849ece5c484b2aab11fecabec3841cafba", size = 5474132, upload-time = "2026-01-10T06:42:19.637Z" }, + { url = "https://files.pythonhosted.org/packages/40/ae/0a5b9a397f0e865ec171187c78d9b57e5588afc439a04ba9cab1ebb2c945/numpy-2.4.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:edee228f76ee2dab4579fad6f51f6a305de09d444280109e0f75df247ff21501", size = 6804159, upload-time = "2026-01-10T06:42:21.44Z" }, + { url = "https://files.pythonhosted.org/packages/86/9c/841c15e691c7085caa6fd162f063eff494099c8327aeccd509d1ab1e36ab/numpy-2.4.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a92f227dbcdc9e4c3e193add1a189a9909947d4f8504c576f4a732fd0b54240a", size = 14708058, upload-time = "2026-01-10T06:42:23.546Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9d/7862db06743f489e6a502a3b93136d73aea27d97b2cf91504f70a27501d6/numpy-2.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:538bf4ec353709c765ff75ae616c34d3c3dca1a68312727e8f2676ea644f8509", size = 16651501, upload-time = "2026-01-10T06:42:25.909Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9c/6fc34ebcbd4015c6e5f0c0ce38264010ce8a546cb6beacb457b84a75dfc8/numpy-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ac08c63cb7779b85e9d5318e6c3518b424bc1f364ac4cb2c6136f12e5ff2dccc", size = 16492627, upload-time = "2026-01-10T06:42:28.938Z" }, + { url = "https://files.pythonhosted.org/packages/aa/63/2494a8597502dacda439f61b3c0db4da59928150e62be0e99395c3ad23c5/numpy-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f9c360ecef085e5841c539a9a12b883dff005fbd7ce46722f5e9cef52634d82", size = 18585052, upload-time = "2026-01-10T06:42:31.312Z" }, + { url = "https://files.pythonhosted.org/packages/6a/93/098e1162ae7522fc9b618d6272b77404c4656c72432ecee3abc029aa3de0/numpy-2.4.1-cp311-cp311-win32.whl", hash = "sha256:0f118ce6b972080ba0758c6087c3617b5ba243d806268623dc34216d69099ba0", size = 6236575, upload-time = "2026-01-10T06:42:33.872Z" }, + { url = "https://files.pythonhosted.org/packages/8c/de/f5e79650d23d9e12f38a7bc6b03ea0835b9575494f8ec94c11c6e773b1b1/numpy-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:18e14c4d09d55eef39a6ab5b08406e84bc6869c1e34eef45564804f90b7e0574", size = 12604479, upload-time = "2026-01-10T06:42:35.778Z" }, + { url = "https://files.pythonhosted.org/packages/dd/65/e1097a7047cff12ce3369bd003811516b20ba1078dbdec135e1cd7c16c56/numpy-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:6461de5113088b399d655d45c3897fa188766415d0f568f175ab071c8873bd73", size = 10578325, upload-time = "2026-01-10T06:42:38.518Z" }, + { url = "https://files.pythonhosted.org/packages/78/7f/ec53e32bf10c813604edf07a3682616bd931d026fcde7b6d13195dfb684a/numpy-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2", size = 16656888, upload-time = "2026-01-10T06:42:40.913Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e0/1f9585d7dae8f14864e948fd7fa86c6cb72dee2676ca2748e63b1c5acfe0/numpy-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8", size = 12373956, upload-time = "2026-01-10T06:42:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/8e/43/9762e88909ff2326f5e7536fa8cb3c49fb03a7d92705f23e6e7f553d9cb3/numpy-2.4.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a", size = 5202567, upload-time = "2026-01-10T06:42:45.107Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ee/34b7930eb61e79feb4478800a4b95b46566969d837546aa7c034c742ef98/numpy-2.4.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0", size = 6549459, upload-time = "2026-01-10T06:42:48.152Z" }, + { url = "https://files.pythonhosted.org/packages/79/e3/5f115fae982565771be994867c89bcd8d7208dbfe9469185497d70de5ddf/numpy-2.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c", size = 14404859, upload-time = "2026-01-10T06:42:49.947Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7d/9c8a781c88933725445a859cac5d01b5871588a15969ee6aeb618ba99eee/numpy-2.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02", size = 16371419, upload-time = "2026-01-10T06:42:52.409Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d2/8aa084818554543f17cf4162c42f162acbd3bb42688aefdba6628a859f77/numpy-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162", size = 16182131, upload-time = "2026-01-10T06:42:54.694Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/0425216684297c58a8df35f3284ef56ec4a043e6d283f8a59c53562caf1b/numpy-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9", size = 18295342, upload-time = "2026-01-10T06:42:56.991Z" }, + { url = "https://files.pythonhosted.org/packages/31/4c/14cb9d86240bd8c386c881bafbe43f001284b7cce3bc01623ac9475da163/numpy-2.4.1-cp312-cp312-win32.whl", hash = "sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f", size = 5959015, upload-time = "2026-01-10T06:42:59.631Z" }, + { url = "https://files.pythonhosted.org/packages/51/cf/52a703dbeb0c65807540d29699fef5fda073434ff61846a564d5c296420f/numpy-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87", size = 12310730, upload-time = "2026-01-10T06:43:01.627Z" }, + { url = "https://files.pythonhosted.org/packages/69/80/a828b2d0ade5e74a9fe0f4e0a17c30fdc26232ad2bc8c9f8b3197cf7cf18/numpy-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8", size = 10312166, upload-time = "2026-01-10T06:43:03.673Z" }, + { url = "https://files.pythonhosted.org/packages/04/68/732d4b7811c00775f3bd522a21e8dd5a23f77eb11acdeb663e4a4ebf0ef4/numpy-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b", size = 16652495, upload-time = "2026-01-10T06:43:06.283Z" }, + { url = "https://files.pythonhosted.org/packages/20/ca/857722353421a27f1465652b2c66813eeeccea9d76d5f7b74b99f298e60e/numpy-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f", size = 12368657, upload-time = "2026-01-10T06:43:09.094Z" }, + { url = "https://files.pythonhosted.org/packages/81/0d/2377c917513449cc6240031a79d30eb9a163d32a91e79e0da47c43f2c0c8/numpy-2.4.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9", size = 5197256, upload-time = "2026-01-10T06:43:13.634Z" }, + { url = "https://files.pythonhosted.org/packages/17/39/569452228de3f5de9064ac75137082c6214be1f5c532016549a7923ab4b5/numpy-2.4.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e", size = 6545212, upload-time = "2026-01-10T06:43:15.661Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/77333f4d1e4dac4395385482557aeecf4826e6ff517e32ca48e1dafbe42a/numpy-2.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5", size = 14402871, upload-time = "2026-01-10T06:43:17.324Z" }, + { url = "https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8", size = 16359305, upload-time = "2026-01-10T06:43:19.376Z" }, + { url = "https://files.pythonhosted.org/packages/32/91/789132c6666288eaa20ae8066bb99eba1939362e8f1a534949a215246e97/numpy-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c", size = 16181909, upload-time = "2026-01-10T06:43:21.808Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/090b8bd27b82a844bb22ff8fdf7935cb1980b48d6e439ae116f53cdc2143/numpy-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2", size = 18284380, upload-time = "2026-01-10T06:43:23.957Z" }, + { url = "https://files.pythonhosted.org/packages/67/78/722b62bd31842ff029412271556a1a27a98f45359dea78b1548a3a9996aa/numpy-2.4.1-cp313-cp313-win32.whl", hash = "sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d", size = 5957089, upload-time = "2026-01-10T06:43:27.535Z" }, + { url = "https://files.pythonhosted.org/packages/da/a6/cf32198b0b6e18d4fbfa9a21a992a7fca535b9bb2b0cdd217d4a3445b5ca/numpy-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb", size = 12307230, upload-time = "2026-01-10T06:43:29.298Z" }, + { url = "https://files.pythonhosted.org/packages/44/6c/534d692bfb7d0afe30611320c5fb713659dcb5104d7cc182aff2aea092f5/numpy-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5", size = 10313125, upload-time = "2026-01-10T06:43:31.782Z" }, + { url = "https://files.pythonhosted.org/packages/da/a1/354583ac5c4caa566de6ddfbc42744409b515039e085fab6e0ff942e0df5/numpy-2.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7", size = 12496156, upload-time = "2026-01-10T06:43:34.237Z" }, + { url = "https://files.pythonhosted.org/packages/51/b0/42807c6e8cce58c00127b1dc24d365305189991f2a7917aa694a109c8d7d/numpy-2.4.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d", size = 5324663, upload-time = "2026-01-10T06:43:36.211Z" }, + { url = "https://files.pythonhosted.org/packages/fe/55/7a621694010d92375ed82f312b2f28017694ed784775269115323e37f5e2/numpy-2.4.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15", size = 6645224, upload-time = "2026-01-10T06:43:37.884Z" }, + { url = "https://files.pythonhosted.org/packages/50/96/9fa8635ed9d7c847d87e30c834f7109fac5e88549d79ef3324ab5c20919f/numpy-2.4.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9", size = 14462352, upload-time = "2026-01-10T06:43:39.479Z" }, + { url = "https://files.pythonhosted.org/packages/03/d1/8cf62d8bb2062da4fb82dd5d49e47c923f9c0738032f054e0a75342faba7/numpy-2.4.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2", size = 16407279, upload-time = "2026-01-10T06:43:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/86/1c/95c86e17c6b0b31ce6ef219da00f71113b220bcb14938c8d9a05cee0ff53/numpy-2.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505", size = 16248316, upload-time = "2026-01-10T06:43:44.121Z" }, + { url = "https://files.pythonhosted.org/packages/30/b4/e7f5ff8697274c9d0fa82398b6a372a27e5cef069b37df6355ccb1f1db1a/numpy-2.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2", size = 18329884, upload-time = "2026-01-10T06:43:46.613Z" }, + { url = "https://files.pythonhosted.org/packages/37/a4/b073f3e9d77f9aec8debe8ca7f9f6a09e888ad1ba7488f0c3b36a94c03ac/numpy-2.4.1-cp313-cp313t-win32.whl", hash = "sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4", size = 6081138, upload-time = "2026-01-10T06:43:48.854Z" }, + { url = "https://files.pythonhosted.org/packages/16/16/af42337b53844e67752a092481ab869c0523bc95c4e5c98e4dac4e9581ac/numpy-2.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510", size = 12447478, upload-time = "2026-01-10T06:43:50.476Z" }, + { url = "https://files.pythonhosted.org/packages/6c/f8/fa85b2eac68ec631d0b631abc448552cb17d39afd17ec53dcbcc3537681a/numpy-2.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261", size = 10382981, upload-time = "2026-01-10T06:43:52.575Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a7/ef08d25698e0e4b4efbad8d55251d20fe2a15f6d9aa7c9b30cd03c165e6f/numpy-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc", size = 16652046, upload-time = "2026-01-10T06:43:54.797Z" }, + { url = "https://files.pythonhosted.org/packages/8f/39/e378b3e3ca13477e5ac70293ec027c438d1927f18637e396fe90b1addd72/numpy-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3", size = 12378858, upload-time = "2026-01-10T06:43:57.099Z" }, + { url = "https://files.pythonhosted.org/packages/c3/74/7ec6154f0006910ed1fdbb7591cf4432307033102b8a22041599935f8969/numpy-2.4.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220", size = 5207417, upload-time = "2026-01-10T06:43:59.037Z" }, + { url = "https://files.pythonhosted.org/packages/f7/b7/053ac11820d84e42f8feea5cb81cc4fcd1091499b45b1ed8c7415b1bf831/numpy-2.4.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee", size = 6542643, upload-time = "2026-01-10T06:44:01.852Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c4/2e7908915c0e32ca636b92e4e4a3bdec4cb1e7eb0f8aedf1ed3c68a0d8cd/numpy-2.4.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556", size = 14418963, upload-time = "2026-01-10T06:44:04.047Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/3ed5083d94e7ffd7c404e54619c088e11f2e1939a9544f5397f4adb1b8ba/numpy-2.4.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844", size = 16363811, upload-time = "2026-01-10T06:44:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/0e/68/42b66f1852bf525050a67315a4fb94586ab7e9eaa541b1bef530fab0c5dd/numpy-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3", size = 16197643, upload-time = "2026-01-10T06:44:08.33Z" }, + { url = "https://files.pythonhosted.org/packages/d2/40/e8714fc933d85f82c6bfc7b998a0649ad9769a32f3494ba86598aaf18a48/numpy-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205", size = 18289601, upload-time = "2026-01-10T06:44:10.841Z" }, + { url = "https://files.pythonhosted.org/packages/80/9a/0d44b468cad50315127e884802351723daca7cf1c98d102929468c81d439/numpy-2.4.1-cp314-cp314-win32.whl", hash = "sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745", size = 6005722, upload-time = "2026-01-10T06:44:13.332Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bb/c6513edcce5a831810e2dddc0d3452ce84d208af92405a0c2e58fd8e7881/numpy-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d", size = 12438590, upload-time = "2026-01-10T06:44:15.006Z" }, + { url = "https://files.pythonhosted.org/packages/e9/da/a598d5cb260780cf4d255102deba35c1d072dc028c4547832f45dd3323a8/numpy-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df", size = 10596180, upload-time = "2026-01-10T06:44:17.386Z" }, + { url = "https://files.pythonhosted.org/packages/de/bc/ea3f2c96fcb382311827231f911723aeff596364eb6e1b6d1d91128aa29b/numpy-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f", size = 12498774, upload-time = "2026-01-10T06:44:19.467Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ab/ef9d939fe4a812648c7a712610b2ca6140b0853c5efea361301006c02ae5/numpy-2.4.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0", size = 5327274, upload-time = "2026-01-10T06:44:23.189Z" }, + { url = "https://files.pythonhosted.org/packages/bd/31/d381368e2a95c3b08b8cf7faac6004849e960f4a042d920337f71cef0cae/numpy-2.4.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c", size = 6648306, upload-time = "2026-01-10T06:44:25.012Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e5/0989b44ade47430be6323d05c23207636d67d7362a1796ccbccac6773dd2/numpy-2.4.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93", size = 14464653, upload-time = "2026-01-10T06:44:26.706Z" }, + { url = "https://files.pythonhosted.org/packages/10/a7/cfbe475c35371cae1358e61f20c5f075badc18c4797ab4354140e1d283cf/numpy-2.4.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42", size = 16405144, upload-time = "2026-01-10T06:44:29.378Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a3/0c63fe66b534888fa5177cc7cef061541064dbe2b4b60dcc60ffaf0d2157/numpy-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01", size = 16247425, upload-time = "2026-01-10T06:44:31.721Z" }, + { url = "https://files.pythonhosted.org/packages/6b/2b/55d980cfa2c93bd40ff4c290bf824d792bd41d2fe3487b07707559071760/numpy-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b", size = 18330053, upload-time = "2026-01-10T06:44:34.617Z" }, + { url = "https://files.pythonhosted.org/packages/23/12/8b5fc6b9c487a09a7957188e0943c9ff08432c65e34567cabc1623b03a51/numpy-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a", size = 6152482, upload-time = "2026-01-10T06:44:36.798Z" }, + { url = "https://files.pythonhosted.org/packages/00/a5/9f8ca5856b8940492fc24fbe13c1bc34d65ddf4079097cf9e53164d094e1/numpy-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2", size = 12627117, upload-time = "2026-01-10T06:44:38.828Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0d/eca3d962f9eef265f01a8e0d20085c6dd1f443cbffc11b6dede81fd82356/numpy-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295", size = 10667121, upload-time = "2026-01-10T06:44:41.644Z" }, + { url = "https://files.pythonhosted.org/packages/1e/48/d86f97919e79314a1cdee4c832178763e6e98e623e123d0bada19e92c15a/numpy-2.4.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8ad35f20be147a204e28b6a0575fbf3540c5e5f802634d4258d55b1ff5facce1", size = 16822202, upload-time = "2026-01-10T06:44:43.738Z" }, + { url = "https://files.pythonhosted.org/packages/51/e9/1e62a7f77e0f37dcfb0ad6a9744e65df00242b6ea37dfafb55debcbf5b55/numpy-2.4.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8097529164c0f3e32bb89412a0905d9100bf434d9692d9fc275e18dcf53c9344", size = 12569985, upload-time = "2026-01-10T06:44:45.945Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7e/914d54f0c801342306fdcdce3e994a56476f1b818c46c47fc21ae968088c/numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ea66d2b41ca4a1630aae5507ee0a71647d3124d1741980138aa8f28f44dac36e", size = 5398484, upload-time = "2026-01-10T06:44:48.012Z" }, + { url = "https://files.pythonhosted.org/packages/1c/d8/9570b68584e293a33474e7b5a77ca404f1dcc655e40050a600dee81d27fb/numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d3f8f0df9f4b8be57b3bf74a1d087fec68f927a2fab68231fdb442bf2c12e426", size = 6713216, upload-time = "2026-01-10T06:44:49.725Z" }, + { url = "https://files.pythonhosted.org/packages/33/9b/9dd6e2db8d49eb24f86acaaa5258e5f4c8ed38209a4ee9de2d1a0ca25045/numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2023ef86243690c2791fd6353e5b4848eedaa88ca8a2d129f462049f6d484696", size = 14538937, upload-time = "2026-01-10T06:44:51.498Z" }, + { url = "https://files.pythonhosted.org/packages/53/87/d5bd995b0f798a37105b876350d346eea5838bd8f77ea3d7a48392f3812b/numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8361ea4220d763e54cff2fbe7d8c93526b744f7cd9ddab47afeff7e14e8503be", size = 16479830, upload-time = "2026-01-10T06:44:53.931Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c7/b801bf98514b6ae6475e941ac05c58e6411dd863ea92916bfd6d510b08c1/numpy-2.4.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:4f1b68ff47680c2925f8063402a693ede215f0257f02596b1318ecdfb1d79e33", size = 12492579, upload-time = "2026-01-10T06:44:57.094Z" }, ] [[package]] @@ -2169,25 +2055,23 @@ parser = [ [[package]] name = "packaging" -version = "26.0" +version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "pandas" version = "2.3.3" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "python-dateutil", marker = "python_full_version < '3.11'" }, - { name = "pytz", marker = "python_full_version < '3.11'" }, - { name = "tzdata", marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ @@ -2240,96 +2124,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, ] -[[package]] -name = "pandas" -version = "3.0.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, - { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/de/da/b1dc0481ab8d55d0f46e343cfe67d4551a0e14fcee52bd38ca1bd73258d8/pandas-3.0.0.tar.gz", hash = "sha256:0facf7e87d38f721f0af46fe70d97373a37701b1c09f7ed7aeeb292ade5c050f", size = 4633005, upload-time = "2026-01-21T15:52:04.726Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/46/1e/b184654a856e75e975a6ee95d6577b51c271cd92cb2b020c9378f53e0032/pandas-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d64ce01eb9cdca96a15266aa679ae50212ec52757c79204dbc7701a222401850", size = 10313247, upload-time = "2026-01-21T15:50:15.775Z" }, - { url = "https://files.pythonhosted.org/packages/dd/5e/e04a547ad0f0183bf151fd7c7a477468e3b85ff2ad231c566389e6cc9587/pandas-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:613e13426069793aa1ec53bdcc3b86e8d32071daea138bbcf4fa959c9cdaa2e2", size = 9913131, upload-time = "2026-01-21T15:50:18.611Z" }, - { url = "https://files.pythonhosted.org/packages/a2/93/bb77bfa9fc2aba9f7204db807d5d3fb69832ed2854c60ba91b4c65ba9219/pandas-3.0.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0192fee1f1a8e743b464a6607858ee4b071deb0b118eb143d71c2a1d170996d5", size = 10741925, upload-time = "2026-01-21T15:50:21.058Z" }, - { url = "https://files.pythonhosted.org/packages/62/fb/89319812eb1d714bfc04b7f177895caeba8ab4a37ef6712db75ed786e2e0/pandas-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0b853319dec8d5e0c8b875374c078ef17f2269986a78168d9bd57e49bf650ae", size = 11245979, upload-time = "2026-01-21T15:50:23.413Z" }, - { url = "https://files.pythonhosted.org/packages/a9/63/684120486f541fc88da3862ed31165b3b3e12b6a1c7b93be4597bc84e26c/pandas-3.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:707a9a877a876c326ae2cb640fbdc4ef63b0a7b9e2ef55c6df9942dcee8e2af9", size = 11756337, upload-time = "2026-01-21T15:50:25.932Z" }, - { url = "https://files.pythonhosted.org/packages/39/92/7eb0ad232312b59aec61550c3c81ad0743898d10af5df7f80bc5e5065416/pandas-3.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:afd0aa3d0b5cda6e0b8ffc10dbcca3b09ef3cbcd3fe2b27364f85fdc04e1989d", size = 12325517, upload-time = "2026-01-21T15:50:27.952Z" }, - { url = "https://files.pythonhosted.org/packages/51/27/bf9436dd0a4fc3130acec0828951c7ef96a0631969613a9a35744baf27f6/pandas-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:113b4cca2614ff7e5b9fee9b6f066618fe73c5a83e99d721ffc41217b2bf57dd", size = 9881576, upload-time = "2026-01-21T15:50:30.149Z" }, - { url = "https://files.pythonhosted.org/packages/e7/2b/c618b871fce0159fd107516336e82891b404e3f340821853c2fc28c7830f/pandas-3.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c14837eba8e99a8da1527c0280bba29b0eb842f64aa94982c5e21227966e164b", size = 9140807, upload-time = "2026-01-21T15:50:32.308Z" }, - { url = "https://files.pythonhosted.org/packages/0b/38/db33686f4b5fa64d7af40d96361f6a4615b8c6c8f1b3d334eee46ae6160e/pandas-3.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9803b31f5039b3c3b10cc858c5e40054adb4b29b4d81cb2fd789f4121c8efbcd", size = 10334013, upload-time = "2026-01-21T15:50:34.771Z" }, - { url = "https://files.pythonhosted.org/packages/a5/7b/9254310594e9774906bacdd4e732415e1f86ab7dbb4b377ef9ede58cd8ec/pandas-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14c2a4099cd38a1d18ff108168ea417909b2dea3bd1ebff2ccf28ddb6a74d740", size = 9874154, upload-time = "2026-01-21T15:50:36.67Z" }, - { url = "https://files.pythonhosted.org/packages/63/d4/726c5a67a13bc66643e66d2e9ff115cead482a44fc56991d0c4014f15aaf/pandas-3.0.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d257699b9a9960e6125686098d5714ac59d05222bef7a5e6af7a7fd87c650801", size = 10384433, upload-time = "2026-01-21T15:50:39.132Z" }, - { url = "https://files.pythonhosted.org/packages/bf/2e/9211f09bedb04f9832122942de8b051804b31a39cfbad199a819bb88d9f3/pandas-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:69780c98f286076dcafca38d8b8eee1676adf220199c0a39f0ecbf976b68151a", size = 10864519, upload-time = "2026-01-21T15:50:41.043Z" }, - { url = "https://files.pythonhosted.org/packages/00/8d/50858522cdc46ac88b9afdc3015e298959a70a08cd21e008a44e9520180c/pandas-3.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4a66384f017240f3858a4c8a7cf21b0591c3ac885cddb7758a589f0f71e87ebb", size = 11394124, upload-time = "2026-01-21T15:50:43.377Z" }, - { url = "https://files.pythonhosted.org/packages/86/3f/83b2577db02503cd93d8e95b0f794ad9d4be0ba7cb6c8bcdcac964a34a42/pandas-3.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be8c515c9bc33989d97b89db66ea0cececb0f6e3c2a87fcc8b69443a6923e95f", size = 11920444, upload-time = "2026-01-21T15:50:45.932Z" }, - { url = "https://files.pythonhosted.org/packages/64/2d/4f8a2f192ed12c90a0aab47f5557ece0e56b0370c49de9454a09de7381b2/pandas-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a453aad8c4f4e9f166436994a33884442ea62aa8b27d007311e87521b97246e1", size = 9730970, upload-time = "2026-01-21T15:50:47.962Z" }, - { url = "https://files.pythonhosted.org/packages/d4/64/ff571be435cf1e643ca98d0945d76732c0b4e9c37191a89c8550b105eed1/pandas-3.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:da768007b5a33057f6d9053563d6b74dd6d029c337d93c6d0d22a763a5c2ecc0", size = 9041950, upload-time = "2026-01-21T15:50:50.422Z" }, - { url = "https://files.pythonhosted.org/packages/6f/fa/7f0ac4ca8877c57537aaff2a842f8760e630d8e824b730eb2e859ffe96ca/pandas-3.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b78d646249b9a2bc191040988c7bb524c92fa8534fb0898a0741d7e6f2ffafa6", size = 10307129, upload-time = "2026-01-21T15:50:52.877Z" }, - { url = "https://files.pythonhosted.org/packages/6f/11/28a221815dcea4c0c9414dfc845e34a84a6a7dabc6da3194498ed5ba4361/pandas-3.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bc9cba7b355cb4162442a88ce495e01cb605f17ac1e27d6596ac963504e0305f", size = 9850201, upload-time = "2026-01-21T15:50:54.807Z" }, - { url = "https://files.pythonhosted.org/packages/ba/da/53bbc8c5363b7e5bd10f9ae59ab250fc7a382ea6ba08e4d06d8694370354/pandas-3.0.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c9a1a149aed3b6c9bf246033ff91e1b02d529546c5d6fb6b74a28fea0cf4c70", size = 10354031, upload-time = "2026-01-21T15:50:57.463Z" }, - { url = "https://files.pythonhosted.org/packages/f7/a3/51e02ebc2a14974170d51e2410dfdab58870ea9bcd37cda15bd553d24dc4/pandas-3.0.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95683af6175d884ee89471842acfca29172a85031fccdabc35e50c0984470a0e", size = 10861165, upload-time = "2026-01-21T15:50:59.32Z" }, - { url = "https://files.pythonhosted.org/packages/a5/fe/05a51e3cac11d161472b8297bd41723ea98013384dd6d76d115ce3482f9b/pandas-3.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1fbbb5a7288719e36b76b4f18d46ede46e7f916b6c8d9915b756b0a6c3f792b3", size = 11359359, upload-time = "2026-01-21T15:51:02.014Z" }, - { url = "https://files.pythonhosted.org/packages/ee/56/ba620583225f9b85a4d3e69c01df3e3870659cc525f67929b60e9f21dcd1/pandas-3.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e8b9808590fa364416b49b2a35c1f4cf2785a6c156935879e57f826df22038e", size = 11912907, upload-time = "2026-01-21T15:51:05.175Z" }, - { url = "https://files.pythonhosted.org/packages/c9/8c/c6638d9f67e45e07656b3826405c5cc5f57f6fd07c8b2572ade328c86e22/pandas-3.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:98212a38a709feb90ae658cb6227ea3657c22ba8157d4b8f913cd4c950de5e7e", size = 9732138, upload-time = "2026-01-21T15:51:07.569Z" }, - { url = "https://files.pythonhosted.org/packages/7b/bf/bd1335c3bf1770b6d8fed2799993b11c4971af93bb1b729b9ebbc02ca2ec/pandas-3.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:177d9df10b3f43b70307a149d7ec49a1229a653f907aa60a48f1877d0e6be3be", size = 9033568, upload-time = "2026-01-21T15:51:09.484Z" }, - { url = "https://files.pythonhosted.org/packages/8e/c6/f5e2171914d5e29b9171d495344097d54e3ffe41d2d85d8115baba4dc483/pandas-3.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2713810ad3806767b89ad3b7b69ba153e1c6ff6d9c20f9c2140379b2a98b6c98", size = 10741936, upload-time = "2026-01-21T15:51:11.693Z" }, - { url = "https://files.pythonhosted.org/packages/51/88/9a0164f99510a1acb9f548691f022c756c2314aad0d8330a24616c14c462/pandas-3.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:15d59f885ee5011daf8335dff47dcb8a912a27b4ad7826dc6cbe809fd145d327", size = 10393884, upload-time = "2026-01-21T15:51:14.197Z" }, - { url = "https://files.pythonhosted.org/packages/e0/53/b34d78084d88d8ae2b848591229da8826d1e65aacf00b3abe34023467648/pandas-3.0.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24e6547fb64d2c92665dd2adbfa4e85fa4fd70a9c070e7cfb03b629a0bbab5eb", size = 10310740, upload-time = "2026-01-21T15:51:16.093Z" }, - { url = "https://files.pythonhosted.org/packages/5b/d3/bee792e7c3d6930b74468d990604325701412e55d7aaf47460a22311d1a5/pandas-3.0.0-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48ee04b90e2505c693d3f8e8f524dab8cb8aaf7ddcab52c92afa535e717c4812", size = 10700014, upload-time = "2026-01-21T15:51:18.818Z" }, - { url = "https://files.pythonhosted.org/packages/55/db/2570bc40fb13aaed1cbc3fbd725c3a60ee162477982123c3adc8971e7ac1/pandas-3.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66f72fb172959af42a459e27a8d8d2c7e311ff4c1f7db6deb3b643dbc382ae08", size = 11323737, upload-time = "2026-01-21T15:51:20.784Z" }, - { url = "https://files.pythonhosted.org/packages/bc/2e/297ac7f21c8181b62a4cccebad0a70caf679adf3ae5e83cb676194c8acc3/pandas-3.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4a4a400ca18230976724a5066f20878af785f36c6756e498e94c2a5e5d57779c", size = 11771558, upload-time = "2026-01-21T15:51:22.977Z" }, - { url = "https://files.pythonhosted.org/packages/0a/46/e1c6876d71c14332be70239acce9ad435975a80541086e5ffba2f249bcf6/pandas-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:940eebffe55528074341a5a36515f3e4c5e25e958ebbc764c9502cfc35ba3faa", size = 10473771, upload-time = "2026-01-21T15:51:25.285Z" }, - { url = "https://files.pythonhosted.org/packages/c0/db/0270ad9d13c344b7a36fa77f5f8344a46501abf413803e885d22864d10bf/pandas-3.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:597c08fb9fef0edf1e4fa2f9828dd27f3d78f9b8c9b4a748d435ffc55732310b", size = 10312075, upload-time = "2026-01-21T15:51:28.5Z" }, - { url = "https://files.pythonhosted.org/packages/09/9f/c176f5e9717f7c91becfe0f55a52ae445d3f7326b4a2cf355978c51b7913/pandas-3.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:447b2d68ac5edcbf94655fe909113a6dba6ef09ad7f9f60c80477825b6c489fe", size = 9900213, upload-time = "2026-01-21T15:51:30.955Z" }, - { url = "https://files.pythonhosted.org/packages/d9/e7/63ad4cc10b257b143e0a5ebb04304ad806b4e1a61c5da25f55896d2ca0f4/pandas-3.0.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:debb95c77ff3ed3ba0d9aa20c3a2f19165cc7956362f9873fce1ba0a53819d70", size = 10428768, upload-time = "2026-01-21T15:51:33.018Z" }, - { url = "https://files.pythonhosted.org/packages/9e/0e/4e4c2d8210f20149fd2248ef3fff26623604922bd564d915f935a06dd63d/pandas-3.0.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fedabf175e7cd82b69b74c30adbaa616de301291a5231138d7242596fc296a8d", size = 10882954, upload-time = "2026-01-21T15:51:35.287Z" }, - { url = "https://files.pythonhosted.org/packages/c6/60/c9de8ac906ba1f4d2250f8a951abe5135b404227a55858a75ad26f84db47/pandas-3.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:412d1a89aab46889f3033a386912efcdfa0f1131c5705ff5b668dda88305e986", size = 11430293, upload-time = "2026-01-21T15:51:37.57Z" }, - { url = "https://files.pythonhosted.org/packages/a1/69/806e6637c70920e5787a6d6896fd707f8134c2c55cd761e7249a97b7dc5a/pandas-3.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e979d22316f9350c516479dd3a92252be2937a9531ed3a26ec324198a99cdd49", size = 11952452, upload-time = "2026-01-21T15:51:39.618Z" }, - { url = "https://files.pythonhosted.org/packages/cb/de/918621e46af55164c400ab0ef389c9d969ab85a43d59ad1207d4ddbe30a5/pandas-3.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:083b11415b9970b6e7888800c43c82e81a06cd6b06755d84804444f0007d6bb7", size = 9851081, upload-time = "2026-01-21T15:51:41.758Z" }, - { url = "https://files.pythonhosted.org/packages/91/a1/3562a18dd0bd8c73344bfa26ff90c53c72f827df119d6d6b1dacc84d13e3/pandas-3.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:5db1e62cb99e739fa78a28047e861b256d17f88463c76b8dafc7c1338086dca8", size = 9174610, upload-time = "2026-01-21T15:51:44.312Z" }, - { url = "https://files.pythonhosted.org/packages/ce/26/430d91257eaf366f1737d7a1c158677caaf6267f338ec74e3a1ec444111c/pandas-3.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:697b8f7d346c68274b1b93a170a70974cdc7d7354429894d5927c1effdcccd73", size = 10761999, upload-time = "2026-01-21T15:51:46.899Z" }, - { url = "https://files.pythonhosted.org/packages/ec/1a/954eb47736c2b7f7fe6a9d56b0cb6987773c00faa3c6451a43db4beb3254/pandas-3.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8cb3120f0d9467ed95e77f67a75e030b67545bcfa08964e349252d674171def2", size = 10410279, upload-time = "2026-01-21T15:51:48.89Z" }, - { url = "https://files.pythonhosted.org/packages/20/fc/b96f3a5a28b250cd1b366eb0108df2501c0f38314a00847242abab71bb3a/pandas-3.0.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33fd3e6baa72899746b820c31e4b9688c8e1b7864d7aec2de7ab5035c285277a", size = 10330198, upload-time = "2026-01-21T15:51:51.015Z" }, - { url = "https://files.pythonhosted.org/packages/90/b3/d0e2952f103b4fbef1ef22d0c2e314e74fc9064b51cee30890b5e3286ee6/pandas-3.0.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8942e333dc67ceda1095227ad0febb05a3b36535e520154085db632c40ad084", size = 10728513, upload-time = "2026-01-21T15:51:53.387Z" }, - { url = "https://files.pythonhosted.org/packages/76/81/832894f286df828993dc5fd61c63b231b0fb73377e99f6c6c369174cf97e/pandas-3.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:783ac35c4d0fe0effdb0d67161859078618b1b6587a1af15928137525217a721", size = 11345550, upload-time = "2026-01-21T15:51:55.329Z" }, - { url = "https://files.pythonhosted.org/packages/34/a0/ed160a00fb4f37d806406bc0a79a8b62fe67f29d00950f8d16203ff3409b/pandas-3.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:125eb901e233f155b268bbef9abd9afb5819db74f0e677e89a61b246228c71ac", size = 11799386, upload-time = "2026-01-21T15:51:57.457Z" }, - { url = "https://files.pythonhosted.org/packages/36/c8/2ac00d7255252c5e3cf61b35ca92ca25704b0188f7454ca4aec08a33cece/pandas-3.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b86d113b6c109df3ce0ad5abbc259fe86a1bd4adfd4a31a89da42f84f65509bb", size = 10873041, upload-time = "2026-01-21T15:52:00.034Z" }, - { url = "https://files.pythonhosted.org/packages/e6/3f/a80ac00acbc6b35166b42850e98a4f466e2c0d9c64054161ba9620f95680/pandas-3.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1c39eab3ad38f2d7a249095f0a3d8f8c22cc0f847e98ccf5bbe732b272e2d9fa", size = 9441003, upload-time = "2026-01-21T15:52:02.281Z" }, -] - [[package]] name = "parso" -version = "0.8.6" +version = "0.8.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/81/76/a1e769043c0c0c9fe391b702539d594731a4362334cdf4dc25d0c09761e7/parso-0.8.6.tar.gz", hash = "sha256:2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd", size = 401621, upload-time = "2026-02-09T15:45:24.425Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl", hash = "sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff", size = 106894, upload-time = "2026-02-09T15:45:21.391Z" }, + { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, ] [[package]] name = "pathspec" -version = "1.0.4" +version = "1.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645", size = 131200, upload-time = "2026-01-27T03:59:46.938Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" }, ] [[package]] @@ -2346,109 +2156,109 @@ wheels = [ [[package]] name = "pillow" -version = "12.1.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1f/42/5c74462b4fd957fcd7b13b04fb3205ff8349236ea74c7c375766d6c82288/pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4", size = 46980264, upload-time = "2026-02-11T04:23:07.146Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/30/5bd3d794762481f8c8ae9c80e7b76ecea73b916959eb587521358ef0b2f9/pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0", size = 5304099, upload-time = "2026-02-11T04:20:06.13Z" }, - { url = "https://files.pythonhosted.org/packages/bd/c1/aab9e8f3eeb4490180e357955e15c2ef74b31f64790ff356c06fb6cf6d84/pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713", size = 4657880, upload-time = "2026-02-11T04:20:09.291Z" }, - { url = "https://files.pythonhosted.org/packages/f1/0a/9879e30d56815ad529d3985aeff5af4964202425c27261a6ada10f7cbf53/pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b", size = 6222587, upload-time = "2026-02-11T04:20:10.82Z" }, - { url = "https://files.pythonhosted.org/packages/5a/5f/a1b72ff7139e4f89014e8d451442c74a774d5c43cd938fb0a9f878576b37/pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b", size = 8027678, upload-time = "2026-02-11T04:20:12.455Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c2/c7cb187dac79a3d22c3ebeae727abee01e077c8c7d930791dc592f335153/pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4", size = 6335777, upload-time = "2026-02-11T04:20:14.441Z" }, - { url = "https://files.pythonhosted.org/packages/0c/7b/f9b09a7804ec7336effb96c26d37c29d27225783dc1501b7d62dcef6ae25/pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4", size = 7027140, upload-time = "2026-02-11T04:20:16.387Z" }, - { url = "https://files.pythonhosted.org/packages/98/b2/2fa3c391550bd421b10849d1a2144c44abcd966daadd2f7c12e19ea988c4/pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e", size = 6449855, upload-time = "2026-02-11T04:20:18.554Z" }, - { url = "https://files.pythonhosted.org/packages/96/ff/9caf4b5b950c669263c39e96c78c0d74a342c71c4f43fd031bb5cb7ceac9/pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff", size = 7151329, upload-time = "2026-02-11T04:20:20.646Z" }, - { url = "https://files.pythonhosted.org/packages/7b/f8/4b24841f582704da675ca535935bccb32b00a6da1226820845fac4a71136/pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40", size = 6325574, upload-time = "2026-02-11T04:20:22.43Z" }, - { url = "https://files.pythonhosted.org/packages/f8/f9/9f6b01c0881d7036063aa6612ef04c0e2cad96be21325a1e92d0203f8e91/pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23", size = 7032347, upload-time = "2026-02-11T04:20:23.932Z" }, - { url = "https://files.pythonhosted.org/packages/79/13/c7922edded3dcdaf10c59297540b72785620abc0538872c819915746757d/pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9", size = 2453457, upload-time = "2026-02-11T04:20:25.392Z" }, - { url = "https://files.pythonhosted.org/packages/2b/46/5da1ec4a5171ee7bf1a0efa064aba70ba3d6e0788ce3f5acd1375d23c8c0/pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32", size = 5304084, upload-time = "2026-02-11T04:20:27.501Z" }, - { url = "https://files.pythonhosted.org/packages/78/93/a29e9bc02d1cf557a834da780ceccd54e02421627200696fcf805ebdc3fb/pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38", size = 4657866, upload-time = "2026-02-11T04:20:29.827Z" }, - { url = "https://files.pythonhosted.org/packages/13/84/583a4558d492a179d31e4aae32eadce94b9acf49c0337c4ce0b70e0a01f2/pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5", size = 6232148, upload-time = "2026-02-11T04:20:31.329Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e2/53c43334bbbb2d3b938978532fbda8e62bb6e0b23a26ce8592f36bcc4987/pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090", size = 8038007, upload-time = "2026-02-11T04:20:34.225Z" }, - { url = "https://files.pythonhosted.org/packages/b8/a6/3d0e79c8a9d58150dd98e199d7c1c56861027f3829a3a60b3c2784190180/pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af", size = 6345418, upload-time = "2026-02-11T04:20:35.858Z" }, - { url = "https://files.pythonhosted.org/packages/a2/c8/46dfeac5825e600579157eea177be43e2f7ff4a99da9d0d0a49533509ac5/pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b", size = 7034590, upload-time = "2026-02-11T04:20:37.91Z" }, - { url = "https://files.pythonhosted.org/packages/af/bf/e6f65d3db8a8bbfeaf9e13cc0417813f6319863a73de934f14b2229ada18/pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5", size = 6458655, upload-time = "2026-02-11T04:20:39.496Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c2/66091f3f34a25894ca129362e510b956ef26f8fb67a0e6417bc5744e56f1/pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d", size = 7159286, upload-time = "2026-02-11T04:20:41.139Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5a/24bc8eb526a22f957d0cec6243146744966d40857e3d8deb68f7902ca6c1/pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c", size = 6328663, upload-time = "2026-02-11T04:20:43.184Z" }, - { url = "https://files.pythonhosted.org/packages/31/03/bef822e4f2d8f9d7448c133d0a18185d3cce3e70472774fffefe8b0ed562/pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563", size = 7031448, upload-time = "2026-02-11T04:20:44.696Z" }, - { url = "https://files.pythonhosted.org/packages/49/70/f76296f53610bd17b2e7d31728b8b7825e3ac3b5b3688b51f52eab7c0818/pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80", size = 2453651, upload-time = "2026-02-11T04:20:46.243Z" }, - { url = "https://files.pythonhosted.org/packages/07/d3/8df65da0d4df36b094351dce696f2989bec731d4f10e743b1c5f4da4d3bf/pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052", size = 5262803, upload-time = "2026-02-11T04:20:47.653Z" }, - { url = "https://files.pythonhosted.org/packages/d6/71/5026395b290ff404b836e636f51d7297e6c83beceaa87c592718747e670f/pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984", size = 4657601, upload-time = "2026-02-11T04:20:49.328Z" }, - { url = "https://files.pythonhosted.org/packages/b1/2e/1001613d941c67442f745aff0f7cc66dd8df9a9c084eb497e6a543ee6f7e/pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79", size = 6234995, upload-time = "2026-02-11T04:20:51.032Z" }, - { url = "https://files.pythonhosted.org/packages/07/26/246ab11455b2549b9233dbd44d358d033a2f780fa9007b61a913c5b2d24e/pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293", size = 8045012, upload-time = "2026-02-11T04:20:52.882Z" }, - { url = "https://files.pythonhosted.org/packages/b2/8b/07587069c27be7535ac1fe33874e32de118fbd34e2a73b7f83436a88368c/pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397", size = 6349638, upload-time = "2026-02-11T04:20:54.444Z" }, - { url = "https://files.pythonhosted.org/packages/ff/79/6df7b2ee763d619cda2fb4fea498e5f79d984dae304d45a8999b80d6cf5c/pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0", size = 7041540, upload-time = "2026-02-11T04:20:55.97Z" }, - { url = "https://files.pythonhosted.org/packages/2c/5e/2ba19e7e7236d7529f4d873bdaf317a318896bac289abebd4bb00ef247f0/pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3", size = 6462613, upload-time = "2026-02-11T04:20:57.542Z" }, - { url = "https://files.pythonhosted.org/packages/03/03/31216ec124bb5c3dacd74ce8efff4cc7f52643653bad4825f8f08c697743/pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35", size = 7166745, upload-time = "2026-02-11T04:20:59.196Z" }, - { url = "https://files.pythonhosted.org/packages/1f/e7/7c4552d80052337eb28653b617eafdef39adfb137c49dd7e831b8dc13bc5/pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a", size = 6328823, upload-time = "2026-02-11T04:21:01.385Z" }, - { url = "https://files.pythonhosted.org/packages/3d/17/688626d192d7261bbbf98846fc98995726bddc2c945344b65bec3a29d731/pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6", size = 7033367, upload-time = "2026-02-11T04:21:03.536Z" }, - { url = "https://files.pythonhosted.org/packages/ed/fe/a0ef1f73f939b0eca03ee2c108d0043a87468664770612602c63266a43c4/pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523", size = 2453811, upload-time = "2026-02-11T04:21:05.116Z" }, - { url = "https://files.pythonhosted.org/packages/d5/11/6db24d4bd7685583caeae54b7009584e38da3c3d4488ed4cd25b439de486/pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e", size = 4062689, upload-time = "2026-02-11T04:21:06.804Z" }, - { url = "https://files.pythonhosted.org/packages/33/c0/ce6d3b1fe190f0021203e0d9b5b99e57843e345f15f9ef22fcd43842fd21/pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9", size = 4138535, upload-time = "2026-02-11T04:21:08.452Z" }, - { url = "https://files.pythonhosted.org/packages/a0/c6/d5eb6a4fb32a3f9c21a8c7613ec706534ea1cf9f4b3663e99f0d83f6fca8/pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6", size = 3601364, upload-time = "2026-02-11T04:21:10.194Z" }, - { url = "https://files.pythonhosted.org/packages/14/a1/16c4b823838ba4c9c52c0e6bbda903a3fe5a1bdbf1b8eb4fff7156f3e318/pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60", size = 5262561, upload-time = "2026-02-11T04:21:11.742Z" }, - { url = "https://files.pythonhosted.org/packages/bb/ad/ad9dc98ff24f485008aa5cdedaf1a219876f6f6c42a4626c08bc4e80b120/pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2", size = 4657460, upload-time = "2026-02-11T04:21:13.786Z" }, - { url = "https://files.pythonhosted.org/packages/9e/1b/f1a4ea9a895b5732152789326202a82464d5254759fbacae4deea3069334/pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850", size = 6232698, upload-time = "2026-02-11T04:21:15.949Z" }, - { url = "https://files.pythonhosted.org/packages/95/f4/86f51b8745070daf21fd2e5b1fe0eb35d4db9ca26e6d58366562fb56a743/pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289", size = 8041706, upload-time = "2026-02-11T04:21:17.723Z" }, - { url = "https://files.pythonhosted.org/packages/29/9b/d6ecd956bb1266dd1045e995cce9b8d77759e740953a1c9aad9502a0461e/pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e", size = 6346621, upload-time = "2026-02-11T04:21:19.547Z" }, - { url = "https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717", size = 7038069, upload-time = "2026-02-11T04:21:21.378Z" }, - { url = "https://files.pythonhosted.org/packages/94/0e/58cb1a6bc48f746bc4cb3adb8cabff73e2742c92b3bf7a220b7cf69b9177/pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a", size = 6460040, upload-time = "2026-02-11T04:21:23.148Z" }, - { url = "https://files.pythonhosted.org/packages/6c/57/9045cb3ff11eeb6c1adce3b2d60d7d299d7b273a2e6c8381a524abfdc474/pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029", size = 7164523, upload-time = "2026-02-11T04:21:25.01Z" }, - { url = "https://files.pythonhosted.org/packages/73/f2/9be9cb99f2175f0d4dbadd6616ce1bf068ee54a28277ea1bf1fbf729c250/pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b", size = 6332552, upload-time = "2026-02-11T04:21:27.238Z" }, - { url = "https://files.pythonhosted.org/packages/3f/eb/b0834ad8b583d7d9d42b80becff092082a1c3c156bb582590fcc973f1c7c/pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1", size = 7040108, upload-time = "2026-02-11T04:21:29.462Z" }, - { url = "https://files.pythonhosted.org/packages/d5/7d/fc09634e2aabdd0feabaff4a32f4a7d97789223e7c2042fd805ea4b4d2c2/pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a", size = 2453712, upload-time = "2026-02-11T04:21:31.072Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/b9d62794fc8a0dd14c1943df68347badbd5511103e0d04c035ffe5cf2255/pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da", size = 5264880, upload-time = "2026-02-11T04:21:32.865Z" }, - { url = "https://files.pythonhosted.org/packages/26/9d/e03d857d1347fa5ed9247e123fcd2a97b6220e15e9cb73ca0a8d91702c6e/pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc", size = 4660616, upload-time = "2026-02-11T04:21:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/f7/ec/8a6d22afd02570d30954e043f09c32772bfe143ba9285e2fdb11284952cd/pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c", size = 6269008, upload-time = "2026-02-11T04:21:36.623Z" }, - { url = "https://files.pythonhosted.org/packages/3d/1d/6d875422c9f28a4a361f495a5f68d9de4a66941dc2c619103ca335fa6446/pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8", size = 8073226, upload-time = "2026-02-11T04:21:38.585Z" }, - { url = "https://files.pythonhosted.org/packages/a1/cd/134b0b6ee5eda6dc09e25e24b40fdafe11a520bc725c1d0bbaa5e00bf95b/pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20", size = 6380136, upload-time = "2026-02-11T04:21:40.562Z" }, - { url = "https://files.pythonhosted.org/packages/7a/a9/7628f013f18f001c1b98d8fffe3452f306a70dc6aba7d931019e0492f45e/pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13", size = 7067129, upload-time = "2026-02-11T04:21:42.521Z" }, - { url = "https://files.pythonhosted.org/packages/1e/f8/66ab30a2193b277785601e82ee2d49f68ea575d9637e5e234faaa98efa4c/pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf", size = 6491807, upload-time = "2026-02-11T04:21:44.22Z" }, - { url = "https://files.pythonhosted.org/packages/da/0b/a877a6627dc8318fdb84e357c5e1a758c0941ab1ddffdafd231983788579/pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524", size = 7190954, upload-time = "2026-02-11T04:21:46.114Z" }, - { url = "https://files.pythonhosted.org/packages/83/43/6f732ff85743cf746b1361b91665d9f5155e1483817f693f8d57ea93147f/pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986", size = 6336441, upload-time = "2026-02-11T04:21:48.22Z" }, - { url = "https://files.pythonhosted.org/packages/3b/44/e865ef3986611bb75bfabdf94a590016ea327833f434558801122979cd0e/pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c", size = 7045383, upload-time = "2026-02-11T04:21:50.015Z" }, - { url = "https://files.pythonhosted.org/packages/a8/c6/f4fb24268d0c6908b9f04143697ea18b0379490cb74ba9e8d41b898bd005/pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3", size = 2456104, upload-time = "2026-02-11T04:21:51.633Z" }, - { url = "https://files.pythonhosted.org/packages/03/d0/bebb3ffbf31c5a8e97241476c4cf8b9828954693ce6744b4a2326af3e16b/pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af", size = 4062652, upload-time = "2026-02-11T04:21:53.19Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c0/0e16fb0addda4851445c28f8350d8c512f09de27bbb0d6d0bbf8b6709605/pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f", size = 4138823, upload-time = "2026-02-11T04:22:03.088Z" }, - { url = "https://files.pythonhosted.org/packages/6b/fb/6170ec655d6f6bb6630a013dd7cf7bc218423d7b5fa9071bf63dc32175ae/pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642", size = 3601143, upload-time = "2026-02-11T04:22:04.909Z" }, - { url = "https://files.pythonhosted.org/packages/59/04/dc5c3f297510ba9a6837cbb318b87dd2b8f73eb41a43cc63767f65cb599c/pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd", size = 5266254, upload-time = "2026-02-11T04:22:07.656Z" }, - { url = "https://files.pythonhosted.org/packages/05/30/5db1236b0d6313f03ebf97f5e17cda9ca060f524b2fcc875149a8360b21c/pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202", size = 4657499, upload-time = "2026-02-11T04:22:09.613Z" }, - { url = "https://files.pythonhosted.org/packages/6f/18/008d2ca0eb612e81968e8be0bbae5051efba24d52debf930126d7eaacbba/pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f", size = 6232137, upload-time = "2026-02-11T04:22:11.434Z" }, - { url = "https://files.pythonhosted.org/packages/70/f1/f14d5b8eeb4b2cd62b9f9f847eb6605f103df89ef619ac68f92f748614ea/pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f", size = 8042721, upload-time = "2026-02-11T04:22:13.321Z" }, - { url = "https://files.pythonhosted.org/packages/5a/d6/17824509146e4babbdabf04d8171491fa9d776f7061ff6e727522df9bd03/pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f", size = 6347798, upload-time = "2026-02-11T04:22:15.449Z" }, - { url = "https://files.pythonhosted.org/packages/d1/ee/c85a38a9ab92037a75615aba572c85ea51e605265036e00c5b67dfafbfe2/pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e", size = 7039315, upload-time = "2026-02-11T04:22:17.24Z" }, - { url = "https://files.pythonhosted.org/packages/ec/f3/bc8ccc6e08a148290d7523bde4d9a0d6c981db34631390dc6e6ec34cacf6/pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0", size = 6462360, upload-time = "2026-02-11T04:22:19.111Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ab/69a42656adb1d0665ab051eec58a41f169ad295cf81ad45406963105408f/pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb", size = 7165438, upload-time = "2026-02-11T04:22:21.041Z" }, - { url = "https://files.pythonhosted.org/packages/02/46/81f7aa8941873f0f01d4b55cc543b0a3d03ec2ee30d617a0448bf6bd6dec/pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f", size = 6431503, upload-time = "2026-02-11T04:22:22.833Z" }, - { url = "https://files.pythonhosted.org/packages/40/72/4c245f7d1044b67affc7f134a09ea619d4895333d35322b775b928180044/pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15", size = 7176748, upload-time = "2026-02-11T04:22:24.64Z" }, - { url = "https://files.pythonhosted.org/packages/e4/ad/8a87bdbe038c5c698736e3348af5c2194ffb872ea52f11894c95f9305435/pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f", size = 2544314, upload-time = "2026-02-11T04:22:26.685Z" }, - { url = "https://files.pythonhosted.org/packages/6c/9d/efd18493f9de13b87ede7c47e69184b9e859e4427225ea962e32e56a49bc/pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8", size = 5268612, upload-time = "2026-02-11T04:22:29.884Z" }, - { url = "https://files.pythonhosted.org/packages/f8/f1/4f42eb2b388eb2ffc660dcb7f7b556c1015c53ebd5f7f754965ef997585b/pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9", size = 4660567, upload-time = "2026-02-11T04:22:31.799Z" }, - { url = "https://files.pythonhosted.org/packages/01/54/df6ef130fa43e4b82e32624a7b821a2be1c5653a5fdad8469687a7db4e00/pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60", size = 6269951, upload-time = "2026-02-11T04:22:33.921Z" }, - { url = "https://files.pythonhosted.org/packages/a9/48/618752d06cc44bb4aae8ce0cd4e6426871929ed7b46215638088270d9b34/pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7", size = 8074769, upload-time = "2026-02-11T04:22:35.877Z" }, - { url = "https://files.pythonhosted.org/packages/c3/bd/f1d71eb39a72fa088d938655afba3e00b38018d052752f435838961127d8/pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f", size = 6381358, upload-time = "2026-02-11T04:22:37.698Z" }, - { url = "https://files.pythonhosted.org/packages/64/ef/c784e20b96674ed36a5af839305f55616f8b4f8aa8eeccf8531a6e312243/pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586", size = 7068558, upload-time = "2026-02-11T04:22:39.597Z" }, - { url = "https://files.pythonhosted.org/packages/73/cb/8059688b74422ae61278202c4e1ad992e8a2e7375227be0a21c6b87ca8d5/pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce", size = 6493028, upload-time = "2026-02-11T04:22:42.73Z" }, - { url = "https://files.pythonhosted.org/packages/c6/da/e3c008ed7d2dd1f905b15949325934510b9d1931e5df999bb15972756818/pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8", size = 7191940, upload-time = "2026-02-11T04:22:44.543Z" }, - { url = "https://files.pythonhosted.org/packages/01/4a/9202e8d11714c1fc5951f2e1ef362f2d7fbc595e1f6717971d5dd750e969/pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36", size = 6438736, upload-time = "2026-02-11T04:22:46.347Z" }, - { url = "https://files.pythonhosted.org/packages/f3/ca/cbce2327eb9885476b3957b2e82eb12c866a8b16ad77392864ad601022ce/pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b", size = 7182894, upload-time = "2026-02-11T04:22:48.114Z" }, - { url = "https://files.pythonhosted.org/packages/ec/d2/de599c95ba0a973b94410477f8bf0b6f0b5e67360eb89bcb1ad365258beb/pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334", size = 2546446, upload-time = "2026-02-11T04:22:50.342Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/5d43209aa4cb58e0cc80127956ff1796a68b928e6324bbf06ef4db34367b/pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f", size = 5228606, upload-time = "2026-02-11T04:22:52.106Z" }, - { url = "https://files.pythonhosted.org/packages/5f/d5/3b005b4e4fda6698b371fa6c21b097d4707585d7db99e98d9b0b87ac612a/pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9", size = 4622321, upload-time = "2026-02-11T04:22:53.827Z" }, - { url = "https://files.pythonhosted.org/packages/df/36/ed3ea2d594356fd8037e5a01f6156c74bc8d92dbb0fa60746cc96cabb6e8/pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e", size = 5247579, upload-time = "2026-02-11T04:22:56.094Z" }, - { url = "https://files.pythonhosted.org/packages/54/9a/9cc3e029683cf6d20ae5085da0dafc63148e3252c2f13328e553aaa13cfb/pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9", size = 6989094, upload-time = "2026-02-11T04:22:58.288Z" }, - { url = "https://files.pythonhosted.org/packages/00/98/fc53ab36da80b88df0967896b6c4b4cd948a0dc5aa40a754266aa3ae48b3/pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3", size = 5313850, upload-time = "2026-02-11T04:23:00.554Z" }, - { url = "https://files.pythonhosted.org/packages/30/02/00fa585abfd9fe9d73e5f6e554dc36cc2b842898cbfc46d70353dae227f8/pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735", size = 5963343, upload-time = "2026-02-11T04:23:02.934Z" }, - { url = "https://files.pythonhosted.org/packages/f2/26/c56ce33ca856e358d27fda9676c055395abddb82c35ac0f593877ed4562e/pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e", size = 7029880, upload-time = "2026-02-11T04:23:04.783Z" }, +version = "12.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/02/d52c733a2452ef1ffcc123b68e6606d07276b0e358db70eabad7e40042b7/pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9", size = 46977283, upload-time = "2026-01-02T09:13:29.892Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/41/f73d92b6b883a579e79600d391f2e21cb0df767b2714ecbd2952315dfeef/pillow-12.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:fb125d860738a09d363a88daa0f59c4533529a90e564785e20fe875b200b6dbd", size = 5304089, upload-time = "2026-01-02T09:10:24.953Z" }, + { url = "https://files.pythonhosted.org/packages/94/55/7aca2891560188656e4a91ed9adba305e914a4496800da6b5c0a15f09edf/pillow-12.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cad302dc10fac357d3467a74a9561c90609768a6f73a1923b0fd851b6486f8b0", size = 4657815, upload-time = "2026-01-02T09:10:27.063Z" }, + { url = "https://files.pythonhosted.org/packages/e9/d2/b28221abaa7b4c40b7dba948f0f6a708bd7342c4d47ce342f0ea39643974/pillow-12.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a40905599d8079e09f25027423aed94f2823adaf2868940de991e53a449e14a8", size = 6222593, upload-time = "2026-01-02T09:10:29.115Z" }, + { url = "https://files.pythonhosted.org/packages/71/b8/7a61fb234df6a9b0b479f69e66901209d89ff72a435b49933f9122f94cac/pillow-12.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92a7fe4225365c5e3a8e598982269c6d6698d3e783b3b1ae979e7819f9cd55c1", size = 8027579, upload-time = "2026-01-02T09:10:31.182Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/55c751a57cc524a15a0e3db20e5cde517582359508d62305a627e77fd295/pillow-12.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f10c98f49227ed8383d28174ee95155a675c4ed7f85e2e573b04414f7e371bda", size = 6335760, upload-time = "2026-01-02T09:10:33.02Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7c/60e3e6f5e5891a1a06b4c910f742ac862377a6fe842f7184df4a274ce7bf/pillow-12.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8637e29d13f478bc4f153d8daa9ffb16455f0a6cb287da1b432fdad2bfbd66c7", size = 7027127, upload-time = "2026-01-02T09:10:35.009Z" }, + { url = "https://files.pythonhosted.org/packages/06/37/49d47266ba50b00c27ba63a7c898f1bb41a29627ced8c09e25f19ebec0ff/pillow-12.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:21e686a21078b0f9cb8c8a961d99e6a4ddb88e0fc5ea6e130172ddddc2e5221a", size = 6449896, upload-time = "2026-01-02T09:10:36.793Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e5/67fd87d2913902462cd9b79c6211c25bfe95fcf5783d06e1367d6d9a741f/pillow-12.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2415373395a831f53933c23ce051021e79c8cd7979822d8cc478547a3f4da8ef", size = 7151345, upload-time = "2026-01-02T09:10:39.064Z" }, + { url = "https://files.pythonhosted.org/packages/bd/15/f8c7abf82af68b29f50d77c227e7a1f87ce02fdc66ded9bf603bc3b41180/pillow-12.1.0-cp310-cp310-win32.whl", hash = "sha256:e75d3dba8fc1ddfec0cd752108f93b83b4f8d6ab40e524a95d35f016b9683b09", size = 6325568, upload-time = "2026-01-02T09:10:41.035Z" }, + { url = "https://files.pythonhosted.org/packages/d4/24/7d1c0e160b6b5ac2605ef7d8be537e28753c0db5363d035948073f5513d7/pillow-12.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:64efdf00c09e31efd754448a383ea241f55a994fd079866b92d2bbff598aad91", size = 7032367, upload-time = "2026-01-02T09:10:43.09Z" }, + { url = "https://files.pythonhosted.org/packages/f4/03/41c038f0d7a06099254c60f618d0ec7be11e79620fc23b8e85e5b31d9a44/pillow-12.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:f188028b5af6b8fb2e9a76ac0f841a575bd1bd396e46ef0840d9b88a48fdbcea", size = 2452345, upload-time = "2026-01-02T09:10:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/43/c4/bf8328039de6cc22182c3ef007a2abfbbdab153661c0a9aa78af8d706391/pillow-12.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3", size = 5304057, upload-time = "2026-01-02T09:10:46.627Z" }, + { url = "https://files.pythonhosted.org/packages/43/06/7264c0597e676104cc22ca73ee48f752767cd4b1fe084662620b17e10120/pillow-12.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0", size = 4657811, upload-time = "2026-01-02T09:10:49.548Z" }, + { url = "https://files.pythonhosted.org/packages/72/64/f9189e44474610daf83da31145fa56710b627b5c4c0b9c235e34058f6b31/pillow-12.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451", size = 6232243, upload-time = "2026-01-02T09:10:51.62Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/0df458009be6a4caca4ca2c52975e6275c387d4e5c95544e34138b41dc86/pillow-12.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:800429ac32c9b72909c671aaf17ecd13110f823ddb7db4dfef412a5587c2c24e", size = 8037872, upload-time = "2026-01-02T09:10:53.446Z" }, + { url = "https://files.pythonhosted.org/packages/e4/86/95845d4eda4f4f9557e25381d70876aa213560243ac1a6d619c46caaedd9/pillow-12.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b022eaaf709541b391ee069f0022ee5b36c709df71986e3f7be312e46f42c84", size = 6345398, upload-time = "2026-01-02T09:10:55.426Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1f/8e66ab9be3aaf1435bc03edd1ebdf58ffcd17f7349c1d970cafe87af27d9/pillow-12.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f345e7bc9d7f368887c712aa5054558bad44d2a301ddf9248599f4161abc7c0", size = 7034667, upload-time = "2026-01-02T09:10:57.11Z" }, + { url = "https://files.pythonhosted.org/packages/f9/f6/683b83cb9b1db1fb52b87951b1c0b99bdcfceaa75febf11406c19f82cb5e/pillow-12.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d70347c8a5b7ccd803ec0c85c8709f036e6348f1e6a5bf048ecd9c64d3550b8b", size = 6458743, upload-time = "2026-01-02T09:10:59.331Z" }, + { url = "https://files.pythonhosted.org/packages/9a/7d/de833d63622538c1d58ce5395e7c6cb7e7dce80decdd8bde4a484e095d9f/pillow-12.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fcc52d86ce7a34fd17cb04e87cfdb164648a3662a6f20565910a99653d66c18", size = 7159342, upload-time = "2026-01-02T09:11:01.82Z" }, + { url = "https://files.pythonhosted.org/packages/8c/40/50d86571c9e5868c42b81fe7da0c76ca26373f3b95a8dd675425f4a92ec1/pillow-12.1.0-cp311-cp311-win32.whl", hash = "sha256:3ffaa2f0659e2f740473bcf03c702c39a8d4b2b7ffc629052028764324842c64", size = 6328655, upload-time = "2026-01-02T09:11:04.556Z" }, + { url = "https://files.pythonhosted.org/packages/6c/af/b1d7e301c4cd26cd45d4af884d9ee9b6fab893b0ad2450d4746d74a6968c/pillow-12.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:806f3987ffe10e867bab0ddad45df1148a2b98221798457fa097ad85d6e8bc75", size = 7031469, upload-time = "2026-01-02T09:11:06.538Z" }, + { url = "https://files.pythonhosted.org/packages/48/36/d5716586d887fb2a810a4a61518a327a1e21c8b7134c89283af272efe84b/pillow-12.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:9f5fefaca968e700ad1a4a9de98bf0869a94e397fe3524c4c9450c1445252304", size = 2452515, upload-time = "2026-01-02T09:11:08.226Z" }, + { url = "https://files.pythonhosted.org/packages/20/31/dc53fe21a2f2996e1b7d92bf671cdb157079385183ef7c1ae08b485db510/pillow-12.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b", size = 5262642, upload-time = "2026-01-02T09:11:10.138Z" }, + { url = "https://files.pythonhosted.org/packages/ab/c1/10e45ac9cc79419cedf5121b42dcca5a50ad2b601fa080f58c22fb27626e/pillow-12.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551", size = 4657464, upload-time = "2026-01-02T09:11:12.319Z" }, + { url = "https://files.pythonhosted.org/packages/ad/26/7b82c0ab7ef40ebede7a97c72d473bda5950f609f8e0c77b04af574a0ddb/pillow-12.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208", size = 6234878, upload-time = "2026-01-02T09:11:14.096Z" }, + { url = "https://files.pythonhosted.org/packages/76/25/27abc9792615b5e886ca9411ba6637b675f1b77af3104710ac7353fe5605/pillow-12.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5", size = 8044868, upload-time = "2026-01-02T09:11:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ea/f200a4c36d836100e7bc738fc48cd963d3ba6372ebc8298a889e0cfc3359/pillow-12.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661", size = 6349468, upload-time = "2026-01-02T09:11:17.631Z" }, + { url = "https://files.pythonhosted.org/packages/11/8f/48d0b77ab2200374c66d344459b8958c86693be99526450e7aee714e03e4/pillow-12.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17", size = 7041518, upload-time = "2026-01-02T09:11:19.389Z" }, + { url = "https://files.pythonhosted.org/packages/1d/23/c281182eb986b5d31f0a76d2a2c8cd41722d6fb8ed07521e802f9bba52de/pillow-12.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670", size = 6462829, upload-time = "2026-01-02T09:11:21.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ef/7018273e0faac099d7b00982abdcc39142ae6f3bd9ceb06de09779c4a9d6/pillow-12.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616", size = 7166756, upload-time = "2026-01-02T09:11:23.559Z" }, + { url = "https://files.pythonhosted.org/packages/8f/c8/993d4b7ab2e341fe02ceef9576afcf5830cdec640be2ac5bee1820d693d4/pillow-12.1.0-cp312-cp312-win32.whl", hash = "sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7", size = 6328770, upload-time = "2026-01-02T09:11:25.661Z" }, + { url = "https://files.pythonhosted.org/packages/a7/87/90b358775a3f02765d87655237229ba64a997b87efa8ccaca7dd3e36e7a7/pillow-12.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d", size = 7033406, upload-time = "2026-01-02T09:11:27.474Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cf/881b457eccacac9e5b2ddd97d5071fb6d668307c57cbf4e3b5278e06e536/pillow-12.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c", size = 2452612, upload-time = "2026-01-02T09:11:29.309Z" }, + { url = "https://files.pythonhosted.org/packages/dd/c7/2530a4aa28248623e9d7f27316b42e27c32ec410f695929696f2e0e4a778/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1", size = 4062543, upload-time = "2026-01-02T09:11:31.566Z" }, + { url = "https://files.pythonhosted.org/packages/8f/1f/40b8eae823dc1519b87d53c30ed9ef085506b05281d313031755c1705f73/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179", size = 4138373, upload-time = "2026-01-02T09:11:33.367Z" }, + { url = "https://files.pythonhosted.org/packages/d4/77/6fa60634cf06e52139fd0e89e5bbf055e8166c691c42fb162818b7fda31d/pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0", size = 3601241, upload-time = "2026-01-02T09:11:35.011Z" }, + { url = "https://files.pythonhosted.org/packages/4f/bf/28ab865de622e14b747f0cd7877510848252d950e43002e224fb1c9ababf/pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587", size = 5262410, upload-time = "2026-01-02T09:11:36.682Z" }, + { url = "https://files.pythonhosted.org/packages/1c/34/583420a1b55e715937a85bd48c5c0991598247a1fd2eb5423188e765ea02/pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac", size = 4657312, upload-time = "2026-01-02T09:11:38.535Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fd/f5a0896839762885b3376ff04878f86ab2b097c2f9a9cdccf4eda8ba8dc0/pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b", size = 6232605, upload-time = "2026-01-02T09:11:40.602Z" }, + { url = "https://files.pythonhosted.org/packages/98/aa/938a09d127ac1e70e6ed467bd03834350b33ef646b31edb7452d5de43792/pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea", size = 8041617, upload-time = "2026-01-02T09:11:42.721Z" }, + { url = "https://files.pythonhosted.org/packages/17/e8/538b24cb426ac0186e03f80f78bc8dc7246c667f58b540bdd57c71c9f79d/pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c", size = 6346509, upload-time = "2026-01-02T09:11:44.955Z" }, + { url = "https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc", size = 7038117, upload-time = "2026-01-02T09:11:46.736Z" }, + { url = "https://files.pythonhosted.org/packages/c7/a2/d40308cf86eada842ca1f3ffa45d0ca0df7e4ab33c83f81e73f5eaed136d/pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644", size = 6460151, upload-time = "2026-01-02T09:11:48.625Z" }, + { url = "https://files.pythonhosted.org/packages/f1/88/f5b058ad6453a085c5266660a1417bdad590199da1b32fb4efcff9d33b05/pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c", size = 7164534, upload-time = "2026-01-02T09:11:50.445Z" }, + { url = "https://files.pythonhosted.org/packages/19/ce/c17334caea1db789163b5d855a5735e47995b0b5dc8745e9a3605d5f24c0/pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171", size = 6332551, upload-time = "2026-01-02T09:11:52.234Z" }, + { url = "https://files.pythonhosted.org/packages/e5/07/74a9d941fa45c90a0d9465098fe1ec85de3e2afbdc15cc4766622d516056/pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a", size = 7040087, upload-time = "2026-01-02T09:11:54.822Z" }, + { url = "https://files.pythonhosted.org/packages/88/09/c99950c075a0e9053d8e880595926302575bc742b1b47fe1bbcc8d388d50/pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45", size = 2452470, upload-time = "2026-01-02T09:11:56.522Z" }, + { url = "https://files.pythonhosted.org/packages/b5/ba/970b7d85ba01f348dee4d65412476321d40ee04dcb51cd3735b9dc94eb58/pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d", size = 5264816, upload-time = "2026-01-02T09:11:58.227Z" }, + { url = "https://files.pythonhosted.org/packages/10/60/650f2fb55fdba7a510d836202aa52f0baac633e50ab1cf18415d332188fb/pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0", size = 4660472, upload-time = "2026-01-02T09:12:00.798Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/5273a99478956a099d533c4f46cbaa19fd69d606624f4334b85e50987a08/pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554", size = 6268974, upload-time = "2026-01-02T09:12:02.572Z" }, + { url = "https://files.pythonhosted.org/packages/b4/26/0bf714bc2e73d5267887d47931d53c4ceeceea6978148ed2ab2a4e6463c4/pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e", size = 8073070, upload-time = "2026-01-02T09:12:04.75Z" }, + { url = "https://files.pythonhosted.org/packages/43/cf/1ea826200de111a9d65724c54f927f3111dc5ae297f294b370a670c17786/pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82", size = 6380176, upload-time = "2026-01-02T09:12:06.626Z" }, + { url = "https://files.pythonhosted.org/packages/03/e0/7938dd2b2013373fd85d96e0f38d62b7a5a262af21ac274250c7ca7847c9/pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4", size = 7067061, upload-time = "2026-01-02T09:12:08.624Z" }, + { url = "https://files.pythonhosted.org/packages/86/ad/a2aa97d37272a929a98437a8c0ac37b3cf012f4f8721e1bd5154699b2518/pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0", size = 6491824, upload-time = "2026-01-02T09:12:10.488Z" }, + { url = "https://files.pythonhosted.org/packages/a4/44/80e46611b288d51b115826f136fb3465653c28f491068a72d3da49b54cd4/pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b", size = 7190911, upload-time = "2026-01-02T09:12:12.772Z" }, + { url = "https://files.pythonhosted.org/packages/86/77/eacc62356b4cf81abe99ff9dbc7402750044aed02cfd6a503f7c6fc11f3e/pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65", size = 6336445, upload-time = "2026-01-02T09:12:14.775Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3c/57d81d0b74d218706dafccb87a87ea44262c43eef98eb3b164fd000e0491/pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0", size = 7045354, upload-time = "2026-01-02T09:12:16.599Z" }, + { url = "https://files.pythonhosted.org/packages/ac/82/8b9b97bba2e3576a340f93b044a3a3a09841170ab4c1eb0d5c93469fd32f/pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8", size = 2454547, upload-time = "2026-01-02T09:12:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/8c/87/bdf971d8bbcf80a348cc3bacfcb239f5882100fe80534b0ce67a784181d8/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91", size = 4062533, upload-time = "2026-01-02T09:12:20.791Z" }, + { url = "https://files.pythonhosted.org/packages/ff/4f/5eb37a681c68d605eb7034c004875c81f86ec9ef51f5be4a63eadd58859a/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796", size = 4138546, upload-time = "2026-01-02T09:12:23.664Z" }, + { url = "https://files.pythonhosted.org/packages/11/6d/19a95acb2edbace40dcd582d077b991646b7083c41b98da4ed7555b59733/pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd", size = 3601163, upload-time = "2026-01-02T09:12:26.338Z" }, + { url = "https://files.pythonhosted.org/packages/fc/36/2b8138e51cb42e4cc39c3297713455548be855a50558c3ac2beebdc251dd/pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13", size = 5266086, upload-time = "2026-01-02T09:12:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/53/4b/649056e4d22e1caa90816bf99cef0884aed607ed38075bd75f091a607a38/pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e", size = 4657344, upload-time = "2026-01-02T09:12:31.117Z" }, + { url = "https://files.pythonhosted.org/packages/6c/6b/c5742cea0f1ade0cd61485dc3d81f05261fc2276f537fbdc00802de56779/pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643", size = 6232114, upload-time = "2026-01-02T09:12:32.936Z" }, + { url = "https://files.pythonhosted.org/packages/bf/8f/9f521268ce22d63991601aafd3d48d5ff7280a246a1ef62d626d67b44064/pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5", size = 8042708, upload-time = "2026-01-02T09:12:34.78Z" }, + { url = "https://files.pythonhosted.org/packages/1a/eb/257f38542893f021502a1bbe0c2e883c90b5cff26cc33b1584a841a06d30/pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de", size = 6347762, upload-time = "2026-01-02T09:12:36.748Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5a/8ba375025701c09b309e8d5163c5a4ce0102fa86bbf8800eb0d7ac87bc51/pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9", size = 7039265, upload-time = "2026-01-02T09:12:39.082Z" }, + { url = "https://files.pythonhosted.org/packages/cf/dc/cf5e4cdb3db533f539e88a7bbf9f190c64ab8a08a9bc7a4ccf55067872e4/pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a", size = 6462341, upload-time = "2026-01-02T09:12:40.946Z" }, + { url = "https://files.pythonhosted.org/packages/d0/47/0291a25ac9550677e22eda48510cfc4fa4b2ef0396448b7fbdc0a6946309/pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a", size = 7165395, upload-time = "2026-01-02T09:12:42.706Z" }, + { url = "https://files.pythonhosted.org/packages/4f/4c/e005a59393ec4d9416be06e6b45820403bb946a778e39ecec62f5b2b991e/pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030", size = 6431413, upload-time = "2026-01-02T09:12:44.944Z" }, + { url = "https://files.pythonhosted.org/packages/1c/af/f23697f587ac5f9095d67e31b81c95c0249cd461a9798a061ed6709b09b5/pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94", size = 7176779, upload-time = "2026-01-02T09:12:46.727Z" }, + { url = "https://files.pythonhosted.org/packages/b3/36/6a51abf8599232f3e9afbd16d52829376a68909fe14efe29084445db4b73/pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4", size = 2543105, upload-time = "2026-01-02T09:12:49.243Z" }, + { url = "https://files.pythonhosted.org/packages/82/54/2e1dd20c8749ff225080d6ba465a0cab4387f5db0d1c5fb1439e2d99923f/pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2", size = 5268571, upload-time = "2026-01-02T09:12:51.11Z" }, + { url = "https://files.pythonhosted.org/packages/57/61/571163a5ef86ec0cf30d265ac2a70ae6fc9e28413d1dc94fa37fae6bda89/pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61", size = 4660426, upload-time = "2026-01-02T09:12:52.865Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e1/53ee5163f794aef1bf84243f755ee6897a92c708505350dd1923f4afec48/pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51", size = 6269908, upload-time = "2026-01-02T09:12:54.884Z" }, + { url = "https://files.pythonhosted.org/packages/bc/0b/b4b4106ff0ee1afa1dc599fde6ab230417f800279745124f6c50bcffed8e/pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc", size = 8074733, upload-time = "2026-01-02T09:12:56.802Z" }, + { url = "https://files.pythonhosted.org/packages/19/9f/80b411cbac4a732439e629a26ad3ef11907a8c7fc5377b7602f04f6fe4e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14", size = 6381431, upload-time = "2026-01-02T09:12:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b7/d65c45db463b66ecb6abc17c6ba6917a911202a07662247e1355ce1789e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8", size = 7068529, upload-time = "2026-01-02T09:13:00.885Z" }, + { url = "https://files.pythonhosted.org/packages/50/96/dfd4cd726b4a45ae6e3c669fc9e49deb2241312605d33aba50499e9d9bd1/pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924", size = 6492981, upload-time = "2026-01-02T09:13:03.314Z" }, + { url = "https://files.pythonhosted.org/packages/4d/1c/b5dc52cf713ae46033359c5ca920444f18a6359ce1020dd3e9c553ea5bc6/pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef", size = 7191878, upload-time = "2026-01-02T09:13:05.276Z" }, + { url = "https://files.pythonhosted.org/packages/53/26/c4188248bd5edaf543864fe4834aebe9c9cb4968b6f573ce014cc42d0720/pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988", size = 6438703, upload-time = "2026-01-02T09:13:07.491Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0e/69ed296de8ea05cb03ee139cee600f424ca166e632567b2d66727f08c7ed/pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6", size = 7182927, upload-time = "2026-01-02T09:13:09.841Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/68334c015eed9b5cff77814258717dec591ded209ab5b6fb70e2ae873d1d/pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831", size = 2545104, upload-time = "2026-01-02T09:13:12.068Z" }, + { url = "https://files.pythonhosted.org/packages/8b/bc/224b1d98cffd7164b14707c91aac83c07b047fbd8f58eba4066a3e53746a/pillow-12.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377", size = 5228605, upload-time = "2026-01-02T09:13:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ca/49ca7769c4550107de049ed85208240ba0f330b3f2e316f24534795702ce/pillow-12.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72", size = 4622245, upload-time = "2026-01-02T09:13:15.964Z" }, + { url = "https://files.pythonhosted.org/packages/73/48/fac807ce82e5955bcc2718642b94b1bd22a82a6d452aea31cbb678cddf12/pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c", size = 5247593, upload-time = "2026-01-02T09:13:17.913Z" }, + { url = "https://files.pythonhosted.org/packages/d2/95/3e0742fe358c4664aed4fd05d5f5373dcdad0b27af52aa0972568541e3f4/pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84cabc7095dd535ca934d57e9ce2a72ffd216e435a84acb06b2277b1de2689bd", size = 6989008, upload-time = "2026-01-02T09:13:20.083Z" }, + { url = "https://files.pythonhosted.org/packages/5a/74/fe2ac378e4e202e56d50540d92e1ef4ff34ed687f3c60f6a121bcf99437e/pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53d8b764726d3af1a138dd353116f774e3862ec7e3794e0c8781e30db0f35dfc", size = 5313824, upload-time = "2026-01-02T09:13:22.405Z" }, + { url = "https://files.pythonhosted.org/packages/f3/77/2a60dee1adee4e2655ac328dd05c02a955c1cd683b9f1b82ec3feb44727c/pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5da841d81b1a05ef940a8567da92decaa15bc4d7dedb540a8c219ad83d91808a", size = 5963278, upload-time = "2026-01-02T09:13:24.706Z" }, + { url = "https://files.pythonhosted.org/packages/2d/71/64e9b1c7f04ae0027f788a248e6297d7fcc29571371fe7d45495a78172c0/pillow-12.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:75af0b4c229ac519b155028fa1be632d812a519abba9b46b20e50c6caa184f19", size = 7029809, upload-time = "2026-01-02T09:13:26.541Z" }, ] [[package]] name = "platformdirs" -version = "4.9.1" +version = "4.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/d5/763666321efaded11112de8b7a7f2273dd8d1e205168e73c334e54b0ab9a/platformdirs-4.9.1.tar.gz", hash = "sha256:f310f16e89c4e29117805d8328f7c10876eeff36c94eac879532812110f7d39f", size = 28392, upload-time = "2026-02-14T21:02:44.973Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/77/e8c95e95f1d4cdd88c90a96e31980df7e709e51059fac150046ad67fac63/platformdirs-4.9.1-py3-none-any.whl", hash = "sha256:61d8b967d34791c162d30d60737369cbbd77debad5b981c4bfda1842e71e0d66", size = 21307, upload-time = "2026-02-14T21:02:43.492Z" }, + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, ] [[package]] @@ -2487,30 +2297,30 @@ wheels = [ [[package]] name = "psutil" -version = "7.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, - { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, - { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, - { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, - { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, - { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, - { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, - { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, - { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, - { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" }, - { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" }, - { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, - { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, - { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, - { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, - { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, - { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, - { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, - { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, +version = "7.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/73/cb/09e5184fb5fc0358d110fc3ca7f6b1d033800734d34cac10f4136cfac10e/psutil-7.2.1.tar.gz", hash = "sha256:f7583aec590485b43ca601dd9cea0dcd65bd7bb21d30ef4ddbf4ea6b5ed1bdd3", size = 490253, upload-time = "2025-12-29T08:26:00.169Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/8e/f0c242053a368c2aa89584ecd1b054a18683f13d6e5a318fc9ec36582c94/psutil-7.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9f33bb525b14c3ea563b2fd521a84d2fa214ec59e3e6a2858f78d0844dd60d", size = 129624, upload-time = "2025-12-29T08:26:04.255Z" }, + { url = "https://files.pythonhosted.org/packages/26/97/a58a4968f8990617decee234258a2b4fc7cd9e35668387646c1963e69f26/psutil-7.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:81442dac7abfc2f4f4385ea9e12ddf5a796721c0f6133260687fec5c3780fa49", size = 130132, upload-time = "2025-12-29T08:26:06.228Z" }, + { url = "https://files.pythonhosted.org/packages/db/6d/ed44901e830739af5f72a85fa7ec5ff1edea7f81bfbf4875e409007149bd/psutil-7.2.1-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea46c0d060491051d39f0d2cff4f98d5c72b288289f57a21556cc7d504db37fc", size = 180612, upload-time = "2025-12-29T08:26:08.276Z" }, + { url = "https://files.pythonhosted.org/packages/c7/65/b628f8459bca4efbfae50d4bf3feaab803de9a160b9d5f3bd9295a33f0c2/psutil-7.2.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35630d5af80d5d0d49cfc4d64c1c13838baf6717a13effb35869a5919b854cdf", size = 183201, upload-time = "2025-12-29T08:26:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/fb/23/851cadc9764edcc18f0effe7d0bf69f727d4cf2442deb4a9f78d4e4f30f2/psutil-7.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:923f8653416604e356073e6e0bccbe7c09990acef442def2f5640dd0faa9689f", size = 139081, upload-time = "2025-12-29T08:26:12.483Z" }, + { url = "https://files.pythonhosted.org/packages/59/82/d63e8494ec5758029f31c6cb06d7d161175d8281e91d011a4a441c8a43b5/psutil-7.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cfbe6b40ca48019a51827f20d830887b3107a74a79b01ceb8cc8de4ccb17b672", size = 134767, upload-time = "2025-12-29T08:26:14.528Z" }, + { url = "https://files.pythonhosted.org/packages/05/c2/5fb764bd61e40e1fe756a44bd4c21827228394c17414ade348e28f83cd79/psutil-7.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:494c513ccc53225ae23eec7fe6e1482f1b8a44674241b54561f755a898650679", size = 129716, upload-time = "2025-12-29T08:26:16.017Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d2/935039c20e06f615d9ca6ca0ab756cf8408a19d298ffaa08666bc18dc805/psutil-7.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3fce5f92c22b00cdefd1645aa58ab4877a01679e901555067b1bd77039aa589f", size = 130133, upload-time = "2025-12-29T08:26:18.009Z" }, + { url = "https://files.pythonhosted.org/packages/77/69/19f1eb0e01d24c2b3eacbc2f78d3b5add8a89bf0bb69465bc8d563cc33de/psutil-7.2.1-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93f3f7b0bb07711b49626e7940d6fe52aa9940ad86e8f7e74842e73189712129", size = 181518, upload-time = "2025-12-29T08:26:20.241Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6d/7e18b1b4fa13ad370787626c95887b027656ad4829c156bb6569d02f3262/psutil-7.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d34d2ca888208eea2b5c68186841336a7f5e0b990edec929be909353a202768a", size = 184348, upload-time = "2025-12-29T08:26:22.215Z" }, + { url = "https://files.pythonhosted.org/packages/98/60/1672114392dd879586d60dd97896325df47d9a130ac7401318005aab28ec/psutil-7.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2ceae842a78d1603753561132d5ad1b2f8a7979cb0c283f5b52fb4e6e14b1a79", size = 140400, upload-time = "2025-12-29T08:26:23.993Z" }, + { url = "https://files.pythonhosted.org/packages/fb/7b/d0e9d4513c46e46897b46bcfc410d51fc65735837ea57a25170f298326e6/psutil-7.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:08a2f175e48a898c8eb8eace45ce01777f4785bc744c90aa2cc7f2fa5462a266", size = 135430, upload-time = "2025-12-29T08:26:25.999Z" }, + { url = "https://files.pythonhosted.org/packages/c5/cf/5180eb8c8bdf6a503c6919f1da28328bd1e6b3b1b5b9d5b01ae64f019616/psutil-7.2.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b2e953fcfaedcfbc952b44744f22d16575d3aa78eb4f51ae74165b4e96e55f42", size = 128137, upload-time = "2025-12-29T08:26:27.759Z" }, + { url = "https://files.pythonhosted.org/packages/c5/2c/78e4a789306a92ade5000da4f5de3255202c534acdadc3aac7b5458fadef/psutil-7.2.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:05cc68dbb8c174828624062e73078e7e35406f4ca2d0866c272c2410d8ef06d1", size = 128947, upload-time = "2025-12-29T08:26:29.548Z" }, + { url = "https://files.pythonhosted.org/packages/29/f8/40e01c350ad9a2b3cb4e6adbcc8a83b17ee50dd5792102b6142385937db5/psutil-7.2.1-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e38404ca2bb30ed7267a46c02f06ff842e92da3bb8c5bfdadbd35a5722314d8", size = 154694, upload-time = "2025-12-29T08:26:32.147Z" }, + { url = "https://files.pythonhosted.org/packages/06/e4/b751cdf839c011a9714a783f120e6a86b7494eb70044d7d81a25a5cd295f/psutil-7.2.1-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab2b98c9fc19f13f59628d94df5cc4cc4844bc572467d113a8b517d634e362c6", size = 156136, upload-time = "2025-12-29T08:26:34.079Z" }, + { url = "https://files.pythonhosted.org/packages/44/ad/bbf6595a8134ee1e94a4487af3f132cef7fce43aef4a93b49912a48c3af7/psutil-7.2.1-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f78baafb38436d5a128f837fab2d92c276dfb48af01a240b861ae02b2413ada8", size = 148108, upload-time = "2025-12-29T08:26:36.225Z" }, + { url = "https://files.pythonhosted.org/packages/1c/15/dd6fd869753ce82ff64dcbc18356093471a5a5adf4f77ed1f805d473d859/psutil-7.2.1-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:99a4cd17a5fdd1f3d014396502daa70b5ec21bf4ffe38393e152f8e449757d67", size = 147402, upload-time = "2025-12-29T08:26:39.21Z" }, + { url = "https://files.pythonhosted.org/packages/34/68/d9317542e3f2b180c4306e3f45d3c922d7e86d8ce39f941bb9e2e9d8599e/psutil-7.2.1-cp37-abi3-win_amd64.whl", hash = "sha256:b1b0671619343aa71c20ff9767eced0483e4fc9e1f489d50923738caf6a03c17", size = 136938, upload-time = "2025-12-29T08:26:41.036Z" }, + { url = "https://files.pythonhosted.org/packages/3e/73/2ce007f4198c80fcf2cb24c169884f833fe93fbc03d55d302627b094ee91/psutil-7.2.1-cp37-abi3-win_arm64.whl", hash = "sha256:0d67c1822c355aa6f7314d92018fb4268a76668a536f133599b91edd48759442", size = 133836, upload-time = "2025-12-29T08:26:43.086Z" }, ] [[package]] @@ -2549,8 +2359,7 @@ name = "pybtex-docutils" version = "1.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "docutils" }, { name = "pybtex" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7e/84/796ea94d26188a853660f81bded39f8de4cfe595130aef0dea1088705a11/pybtex-docutils-1.0.3.tar.gz", hash = "sha256:3a7ebdf92b593e00e8c1c538aa9a20bca5d92d84231124715acc964d51d93c6b", size = 18348, upload-time = "2023-08-22T18:47:54.833Z" } @@ -2560,11 +2369,11 @@ wheels = [ [[package]] name = "pycparser" -version = "3.0" +version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, ] [[package]] @@ -2596,11 +2405,11 @@ sdist = { url = "https://files.pythonhosted.org/packages/5d/ab/34ec41718af73c001 [[package]] name = "pyparsing" -version = "3.3.2" +version = "3.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/c1/1d9de9aeaa1b89b0186e5fe23294ff6517fce1bc69149185577cd31016b2/pyparsing-3.3.1.tar.gz", hash = "sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c", size = 1550512, upload-time = "2025-12-23T03:14:04.391Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, + { url = "https://files.pythonhosted.org/packages/8b/40/2614036cdd416452f5bf98ec037f38a1afb17f327cb8e6b652d4729e0af8/pyparsing-3.3.1-py3-none-any.whl", hash = "sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82", size = 121793, upload-time = "2025-12-23T03:14:02.103Z" }, ] [[package]] @@ -2826,7 +2635,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "rustworkx" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -2908,6 +2717,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7", size = 7676, upload-time = "2025-12-17T18:25:33.098Z" }, ] +[[package]] +name = "roman-numerals-py" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "roman-numerals", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/b5/de96fca640f4f656eb79bbee0e79aeec52e3e0e359f8a3e6a0d366378b64/roman_numerals_py-4.1.0.tar.gz", hash = "sha256:f5d7b2b4ca52dd855ef7ab8eb3590f428c0b1ea480736ce32b01fef2a5f8daf9", size = 4274, upload-time = "2025-12-17T18:25:41.153Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/2c/daca29684cbe9fd4bc711f8246da3c10adca1ccc4d24436b17572eb2590e/roman_numerals_py-4.1.0-py3-none-any.whl", hash = "sha256:553114c1167141c1283a51743759723ecd05604a1b6b507225e91dc1a6df0780", size = 4547, upload-time = "2025-12-17T18:25:40.136Z" }, +] + [[package]] name = "rpds-py" version = "0.30.0" @@ -3036,7 +2857,7 @@ version = "0.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/b0/66d96f02120f79eeed86b5c5be04029b6821155f31ed4907a4e9f1460671/rustworkx-0.17.1.tar.gz", hash = "sha256:59ea01b4e603daffa4e8827316c1641eef18ae9032f0b1b14aa0181687e3108e", size = 399407, upload-time = "2025-09-15T16:29:46.429Z" } wheels = [ @@ -3138,21 +2959,13 @@ name = "scipy" version = "1.17.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/56/3e/9cca699f3486ce6bc12ff46dc2031f1ec8eb9ccc9a320fdaf925f1417426/scipy-1.17.0.tar.gz", hash = "sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e", size = 30396830, upload-time = "2026-01-10T21:34:23.009Z" } wheels = [ @@ -3225,9 +3038,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "matplotlib" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pandas" }, ] sdist = { url = "https://files.pythonhosted.org/packages/86/59/a451d7420a77ab0b98f7affa3a1d78a313d2f7281a57afb1a34bae8ab412/seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7", size = 1457696, upload-time = "2024-01-25T13:21:52.551Z" } wheels = [ @@ -3236,11 +3048,11 @@ wheels = [ [[package]] name = "setuptools" -version = "82.0.0" +version = "80.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/f3/748f4d6f65d1756b9ae577f329c951cda23fb900e4de9f70900ced962085/setuptools-82.0.0.tar.gz", hash = "sha256:22e0a2d69474c6ae4feb01951cb69d515ed23728cf96d05513d36e42b62b37cb", size = 1144893, upload-time = "2026-02-08T15:08:40.206Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl", hash = "sha256:70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0", size = 1003468, upload-time = "2026-02-08T15:08:38.723Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] [[package]] @@ -3277,11 +3089,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8.3" +version = "2.8.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } +sdist = { url = "https://files.pythonhosted.org/packages/93/f2/21d6ca70c3cf35d01ae9e01be534bf6b6b103c157a728082a5028350c310/soupsieve-2.8.2.tar.gz", hash = "sha256:78a66b0fdee2ab40b7199dc3e747ee6c6e231899feeaae0b9b98a353afd48fd8", size = 118601, upload-time = "2026-01-18T16:21:31.09Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9a/b4450ccce353e2430621b3bb571899ffe1033d5cd72c9e065110f95b1a63/soupsieve-2.8.2-py3-none-any.whl", hash = "sha256:0f4c2f6b5a5fb97a641cf69c0bd163670a0e45e6d6c01a2107f93a6a6f93c51a", size = 37016, upload-time = "2026-01-18T16:21:29.7Z" }, ] [[package]] @@ -3295,7 +3107,7 @@ dependencies = [ { name = "alabaster", marker = "python_full_version < '3.11'" }, { name = "babel", marker = "python_full_version < '3.11'" }, { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "docutils", marker = "python_full_version < '3.11'" }, { name = "imagesize", marker = "python_full_version < '3.11'" }, { name = "jinja2", marker = "python_full_version < '3.11'" }, { name = "packaging", marker = "python_full_version < '3.11'" }, @@ -3317,92 +3129,53 @@ wheels = [ [[package]] name = "sphinx" -version = "9.0.4" +version = "8.2.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version == '3.11.*'" }, - { name = "babel", marker = "python_full_version == '3.11.*'" }, - { name = "colorama", marker = "python_full_version == '3.11.*' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "imagesize", marker = "python_full_version == '3.11.*'" }, - { name = "jinja2", marker = "python_full_version == '3.11.*'" }, - { name = "packaging", marker = "python_full_version == '3.11.*'" }, - { name = "pygments", marker = "python_full_version == '3.11.*'" }, - { name = "requests", marker = "python_full_version == '3.11.*'" }, - { name = "roman-numerals", marker = "python_full_version == '3.11.*'" }, - { name = "snowballstemmer", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*'" }, + { name = "alabaster", marker = "python_full_version >= '3.11'" }, + { name = "babel", marker = "python_full_version >= '3.11'" }, + { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, + { name = "docutils", marker = "python_full_version >= '3.11'" }, + { name = "imagesize", marker = "python_full_version >= '3.11'" }, + { name = "jinja2", marker = "python_full_version >= '3.11'" }, + { name = "packaging", marker = "python_full_version >= '3.11'" }, + { name = "pygments", marker = "python_full_version >= '3.11'" }, + { name = "requests", marker = "python_full_version >= '3.11'" }, + { name = "roman-numerals-py", marker = "python_full_version >= '3.11'" }, + { name = "snowballstemmer", marker = "python_full_version >= '3.11'" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.11'" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.11'" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.11'" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.11'" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.11'" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } +sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl", hash = "sha256:5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb", size = 3917713, upload-time = "2025-12-04T07:45:24.944Z" }, -] - -[[package]] -name = "sphinx" -version = "9.1.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.12'" }, - { name = "babel", marker = "python_full_version >= '3.12'" }, - { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "imagesize", marker = "python_full_version >= '3.12'" }, - { name = "jinja2", marker = "python_full_version >= '3.12'" }, - { name = "packaging", marker = "python_full_version >= '3.12'" }, - { name = "pygments", marker = "python_full_version >= '3.12'" }, - { name = "requests", marker = "python_full_version >= '3.12'" }, - { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978", size = 3921742, upload-time = "2025-12-31T15:09:25.561Z" }, + { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" }, ] [[package]] name = "sphinx-autoapi" -version = "3.7.0" +version = "3.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astroid", version = "3.3.11", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "astroid", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "astroid", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "jinja2" }, { name = "pyyaml" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/47/22/7ea4b660e98ffa271dbec5847b64738127955746d887f9596940279d30bf/sphinx_autoapi-3.7.0.tar.gz", hash = "sha256:5c8a934d788f00d11b8c8092536c7373592cce986820de8dd7daf6dfd79afd91", size = 58136, upload-time = "2026-02-11T05:24:29.86Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/ad/c627976d5f4d812b203ef1136108bbd81ef9bbbfd3f700f1295c322c22e6/sphinx_autoapi-3.6.1.tar.gz", hash = "sha256:1ff2992b7d5e39ccf92413098a376e0f91e7b4ca532c4f3e71298dbc8a4a9900", size = 55456, upload-time = "2025-10-06T16:21:22.888Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d8/11/9825443890d3ef6b6a0db938054e7c806e9911509e0315fe984d00a090c1/sphinx_autoapi-3.7.0-py3-none-any.whl", hash = "sha256:5ea37271b50de08538cf6e33044ef4fb6e981ddb693060ec84f297005014fdfd", size = 36021, upload-time = "2026-02-11T05:24:28.657Z" }, + { url = "https://files.pythonhosted.org/packages/ca/89/aea2f346fcdb44eb72464842e106b6291b2687feec2dd8b2de920ab89f28/sphinx_autoapi-3.6.1-py3-none-any.whl", hash = "sha256:6b7af0d5650f6eac1f4b85c1eb9f9a4911160ec7138bdc4451c77a5e94d5832c", size = 35334, upload-time = "2025-10-06T16:21:21.33Z" }, ] [[package]] @@ -3411,8 +3184,7 @@ version = "1.0.0b2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736, upload-time = "2023-07-08T18:40:54.166Z" } wheels = [ @@ -3425,8 +3197,7 @@ version = "0.5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } wheels = [ @@ -3437,44 +3208,15 @@ wheels = [ name = "sphinx-design" version = "0.6.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689, upload-time = "2024-08-02T13:48:44.277Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338, upload-time = "2024-08-02T13:48:42.106Z" }, ] -[[package]] -name = "sphinx-design" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'emscripten'", - "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/13/7b/804f311da4663a4aecc6cf7abd83443f3d4ded970826d0c958edc77d4527/sphinx_design-0.7.0.tar.gz", hash = "sha256:d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a", size = 2203582, upload-time = "2026-01-19T13:12:53.297Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/30/cf/45dd359f6ca0c3762ce0490f681da242f0530c49c81050c035c016bfdd3a/sphinx_design-0.7.0-py3-none-any.whl", hash = "sha256:f82bf179951d58f55dca78ab3706aeafa496b741a91b1911d371441127d64282", size = 2220350, upload-time = "2026-01-19T13:12:51.077Z" }, -] - [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" @@ -3489,13 +3231,11 @@ name = "sphinxcontrib-bibtex" version = "2.6.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "docutils" }, { name = "pybtex" }, { name = "pybtex-docutils" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/de/83/1488c9879f2fa3c2cbd6f666c7a3a42a1fa9e08462bec73281fa6c092cba/sphinxcontrib_bibtex-2.6.5.tar.gz", hash = "sha256:9b3224dd6fece9268ebd8c905dc0a83ff2f6c54148a9235fe70e9d1e9ff149c0", size = 118462, upload-time = "2025-06-27T10:40:14.061Z" } wheels = [ @@ -3553,8 +3293,7 @@ version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/7a/21930ae148f94c458ca2f8f554d4e737e17c1db8b152238f530fc0c89e32/sphinxcontrib_svg2pdfconverter-2.0.0.tar.gz", hash = "sha256:ab9c8f1080391e231812d20abf2657a69ee35574563b1014414f953964a95fa3", size = 6411, upload-time = "2025-12-01T20:44:21.386Z" } wheels = [ @@ -3567,8 +3306,7 @@ version = "0.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f6/c0/eb6838e3bae624ce6c8b90b245d17e84252863150e95efdb88f92c8aa3fb/sphinxext_opengraph-0.13.0.tar.gz", hash = "sha256:103335d08567ad8468faf1425f575e3b698e9621f9323949a6c8b96d9793e80b", size = 1026875, upload-time = "2025-08-29T12:20:31.066Z" } wheels = [ @@ -3577,58 +3315,51 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.46" +version = "2.0.45" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/aa/9ce0f3e7a9829ead5c8ce549392f33a12c4555a6c0609bb27d882e9c7ddf/sqlalchemy-2.0.46.tar.gz", hash = "sha256:cf36851ee7219c170bb0793dbc3da3e80c582e04a5437bc601bfe8c85c9216d7", size = 9865393, upload-time = "2026-01-21T18:03:45.119Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/26/66ba59328dc25e523bfcb0f8db48bdebe2035e0159d600e1f01c0fc93967/sqlalchemy-2.0.46-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:895296687ad06dc9b11a024cf68e8d9d3943aa0b4964278d2553b86f1b267735", size = 2155051, upload-time = "2026-01-21T18:27:28.965Z" }, - { url = "https://files.pythonhosted.org/packages/21/cd/9336732941df972fbbfa394db9caa8bb0cf9fe03656ec728d12e9cbd6edc/sqlalchemy-2.0.46-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab65cb2885a9f80f979b85aa4e9c9165a31381ca322cbde7c638fe6eefd1ec39", size = 3234666, upload-time = "2026-01-21T18:32:28.72Z" }, - { url = "https://files.pythonhosted.org/packages/38/62/865ae8b739930ec433cd4123760bee7f8dafdc10abefd725a025604fb0de/sqlalchemy-2.0.46-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:52fe29b3817bd191cc20bad564237c808967972c97fa683c04b28ec8979ae36f", size = 3232917, upload-time = "2026-01-21T18:44:54.064Z" }, - { url = "https://files.pythonhosted.org/packages/24/38/805904b911857f2b5e00fdea44e9570df62110f834378706939825579296/sqlalchemy-2.0.46-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:09168817d6c19954d3b7655da6ba87fcb3a62bb575fb396a81a8b6a9fadfe8b5", size = 3185790, upload-time = "2026-01-21T18:32:30.581Z" }, - { url = "https://files.pythonhosted.org/packages/69/4f/3260bb53aabd2d274856337456ea52f6a7eccf6cce208e558f870cec766b/sqlalchemy-2.0.46-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:be6c0466b4c25b44c5d82b0426b5501de3c424d7a3220e86cd32f319ba56798e", size = 3207206, upload-time = "2026-01-21T18:44:55.93Z" }, - { url = "https://files.pythonhosted.org/packages/ce/b3/67c432d7f9d88bb1a61909b67e29f6354d59186c168fb5d381cf438d3b73/sqlalchemy-2.0.46-cp310-cp310-win32.whl", hash = "sha256:1bc3f601f0a818d27bfe139f6766487d9c88502062a2cd3a7ee6c342e81d5047", size = 2115296, upload-time = "2026-01-21T18:33:12.498Z" }, - { url = "https://files.pythonhosted.org/packages/4a/8c/25fb284f570f9d48e6c240f0269a50cec9cf009a7e08be4c0aaaf0654972/sqlalchemy-2.0.46-cp310-cp310-win_amd64.whl", hash = "sha256:e0c05aff5c6b1bb5fb46a87e0f9d2f733f83ef6cbbbcd5c642b6c01678268061", size = 2138540, upload-time = "2026-01-21T18:33:14.22Z" }, - { url = "https://files.pythonhosted.org/packages/69/ac/b42ad16800d0885105b59380ad69aad0cce5a65276e269ce2729a2343b6a/sqlalchemy-2.0.46-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:261c4b1f101b4a411154f1da2b76497d73abbfc42740029205d4d01fa1052684", size = 2154851, upload-time = "2026-01-21T18:27:30.54Z" }, - { url = "https://files.pythonhosted.org/packages/a0/60/d8710068cb79f64d002ebed62a7263c00c8fd95f4ebd4b5be8f7ca93f2bc/sqlalchemy-2.0.46-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:181903fe8c1b9082995325f1b2e84ac078b1189e2819380c2303a5f90e114a62", size = 3311241, upload-time = "2026-01-21T18:32:33.45Z" }, - { url = "https://files.pythonhosted.org/packages/2b/0f/20c71487c7219ab3aa7421c7c62d93824c97c1460f2e8bb72404b0192d13/sqlalchemy-2.0.46-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:590be24e20e2424a4c3c1b0835e9405fa3d0af5823a1a9fc02e5dff56471515f", size = 3310741, upload-time = "2026-01-21T18:44:57.887Z" }, - { url = "https://files.pythonhosted.org/packages/65/80/d26d00b3b249ae000eee4db206fcfc564bf6ca5030e4747adf451f4b5108/sqlalchemy-2.0.46-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7568fe771f974abadce52669ef3a03150ff03186d8eb82613bc8adc435a03f01", size = 3263116, upload-time = "2026-01-21T18:32:35.044Z" }, - { url = "https://files.pythonhosted.org/packages/da/ee/74dda7506640923821340541e8e45bd3edd8df78664f1f2e0aae8077192b/sqlalchemy-2.0.46-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf7e1e78af38047e08836d33502c7a278915698b7c2145d045f780201679999", size = 3285327, upload-time = "2026-01-21T18:44:59.254Z" }, - { url = "https://files.pythonhosted.org/packages/9f/25/6dcf8abafff1389a21c7185364de145107b7394ecdcb05233815b236330d/sqlalchemy-2.0.46-cp311-cp311-win32.whl", hash = "sha256:9d80ea2ac519c364a7286e8d765d6cd08648f5b21ca855a8017d9871f075542d", size = 2114564, upload-time = "2026-01-21T18:33:15.85Z" }, - { url = "https://files.pythonhosted.org/packages/93/5f/e081490f8523adc0088f777e4ebad3cac21e498ec8a3d4067074e21447a1/sqlalchemy-2.0.46-cp311-cp311-win_amd64.whl", hash = "sha256:585af6afe518732d9ccd3aea33af2edaae4a7aa881af5d8f6f4fe3a368699597", size = 2139233, upload-time = "2026-01-21T18:33:17.528Z" }, - { url = "https://files.pythonhosted.org/packages/b6/35/d16bfa235c8b7caba3730bba43e20b1e376d2224f407c178fbf59559f23e/sqlalchemy-2.0.46-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a9a72b0da8387f15d5810f1facca8f879de9b85af8c645138cba61ea147968c", size = 2153405, upload-time = "2026-01-21T19:05:54.143Z" }, - { url = "https://files.pythonhosted.org/packages/06/6c/3192e24486749862f495ddc6584ed730c0c994a67550ec395d872a2ad650/sqlalchemy-2.0.46-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2347c3f0efc4de367ba00218e0ae5c4ba2306e47216ef80d6e31761ac97cb0b9", size = 3334702, upload-time = "2026-01-21T18:46:45.384Z" }, - { url = "https://files.pythonhosted.org/packages/ea/a2/b9f33c8d68a3747d972a0bb758c6b63691f8fb8a49014bc3379ba15d4274/sqlalchemy-2.0.46-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9094c8b3197db12aa6f05c51c05daaad0a92b8c9af5388569847b03b1007fb1b", size = 3347664, upload-time = "2026-01-21T18:40:09.979Z" }, - { url = "https://files.pythonhosted.org/packages/aa/d2/3e59e2a91eaec9db7e8dc6b37b91489b5caeb054f670f32c95bcba98940f/sqlalchemy-2.0.46-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37fee2164cf21417478b6a906adc1a91d69ae9aba8f9533e67ce882f4bb1de53", size = 3277372, upload-time = "2026-01-21T18:46:47.168Z" }, - { url = "https://files.pythonhosted.org/packages/dd/dd/67bc2e368b524e2192c3927b423798deda72c003e73a1e94c21e74b20a85/sqlalchemy-2.0.46-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1e14b2f6965a685c7128bd315e27387205429c2e339eeec55cb75ca4ab0ea2e", size = 3312425, upload-time = "2026-01-21T18:40:11.548Z" }, - { url = "https://files.pythonhosted.org/packages/43/82/0ecd68e172bfe62247e96cb47867c2d68752566811a4e8c9d8f6e7c38a65/sqlalchemy-2.0.46-cp312-cp312-win32.whl", hash = "sha256:412f26bb4ba942d52016edc8d12fb15d91d3cd46b0047ba46e424213ad407bcb", size = 2113155, upload-time = "2026-01-21T18:42:49.748Z" }, - { url = "https://files.pythonhosted.org/packages/bc/2a/2821a45742073fc0331dc132552b30de68ba9563230853437cac54b2b53e/sqlalchemy-2.0.46-cp312-cp312-win_amd64.whl", hash = "sha256:ea3cd46b6713a10216323cda3333514944e510aa691c945334713fca6b5279ff", size = 2140078, upload-time = "2026-01-21T18:42:51.197Z" }, - { url = "https://files.pythonhosted.org/packages/b3/4b/fa7838fe20bb752810feed60e45625a9a8b0102c0c09971e2d1d95362992/sqlalchemy-2.0.46-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:93a12da97cca70cea10d4b4fc602589c4511f96c1f8f6c11817620c021d21d00", size = 2150268, upload-time = "2026-01-21T19:05:56.621Z" }, - { url = "https://files.pythonhosted.org/packages/46/c1/b34dccd712e8ea846edf396e00973dda82d598cb93762e55e43e6835eba9/sqlalchemy-2.0.46-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af865c18752d416798dae13f83f38927c52f085c52e2f32b8ab0fef46fdd02c2", size = 3276511, upload-time = "2026-01-21T18:46:49.022Z" }, - { url = "https://files.pythonhosted.org/packages/96/48/a04d9c94753e5d5d096c628c82a98c4793b9c08ca0e7155c3eb7d7db9f24/sqlalchemy-2.0.46-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8d679b5f318423eacb61f933a9a0f75535bfca7056daeadbf6bd5bcee6183aee", size = 3292881, upload-time = "2026-01-21T18:40:13.089Z" }, - { url = "https://files.pythonhosted.org/packages/be/f4/06eda6e91476f90a7d8058f74311cb65a2fb68d988171aced81707189131/sqlalchemy-2.0.46-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:64901e08c33462acc9ec3bad27fc7a5c2b6491665f2aa57564e57a4f5d7c52ad", size = 3224559, upload-time = "2026-01-21T18:46:50.974Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a2/d2af04095412ca6345ac22b33b89fe8d6f32a481e613ffcb2377d931d8d0/sqlalchemy-2.0.46-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e8ac45e8f4eaac0f9f8043ea0e224158855c6a4329fd4ee37c45c61e3beb518e", size = 3262728, upload-time = "2026-01-21T18:40:14.883Z" }, - { url = "https://files.pythonhosted.org/packages/31/48/1980c7caa5978a3b8225b4d230e69a2a6538a3562b8b31cea679b6933c83/sqlalchemy-2.0.46-cp313-cp313-win32.whl", hash = "sha256:8d3b44b3d0ab2f1319d71d9863d76eeb46766f8cf9e921ac293511804d39813f", size = 2111295, upload-time = "2026-01-21T18:42:52.366Z" }, - { url = "https://files.pythonhosted.org/packages/2d/54/f8d65bbde3d877617c4720f3c9f60e99bb7266df0d5d78b6e25e7c149f35/sqlalchemy-2.0.46-cp313-cp313-win_amd64.whl", hash = "sha256:77f8071d8fbcbb2dd11b7fd40dedd04e8ebe2eb80497916efedba844298065ef", size = 2137076, upload-time = "2026-01-21T18:42:53.924Z" }, - { url = "https://files.pythonhosted.org/packages/56/ba/9be4f97c7eb2b9d5544f2624adfc2853e796ed51d2bb8aec90bc94b7137e/sqlalchemy-2.0.46-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1e8cc6cc01da346dc92d9509a63033b9b1bda4fed7a7a7807ed385c7dccdc10", size = 3556533, upload-time = "2026-01-21T18:33:06.636Z" }, - { url = "https://files.pythonhosted.org/packages/20/a6/b1fc6634564dbb4415b7ed6419cdfeaadefd2c39cdab1e3aa07a5f2474c2/sqlalchemy-2.0.46-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96c7cca1a4babaaf3bfff3e4e606e38578856917e52f0384635a95b226c87764", size = 3523208, upload-time = "2026-01-21T18:45:08.436Z" }, - { url = "https://files.pythonhosted.org/packages/a1/d8/41e0bdfc0f930ff236f86fccd12962d8fa03713f17ed57332d38af6a3782/sqlalchemy-2.0.46-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b2a9f9aee38039cf4755891a1e50e1effcc42ea6ba053743f452c372c3152b1b", size = 3464292, upload-time = "2026-01-21T18:33:08.208Z" }, - { url = "https://files.pythonhosted.org/packages/f0/8b/9dcbec62d95bea85f5ecad9b8d65b78cc30fb0ffceeb3597961f3712549b/sqlalchemy-2.0.46-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:db23b1bf8cfe1f7fda19018e7207b20cdb5168f83c437ff7e95d19e39289c447", size = 3473497, upload-time = "2026-01-21T18:45:10.552Z" }, - { url = "https://files.pythonhosted.org/packages/e9/f8/5ecdfc73383ec496de038ed1614de9e740a82db9ad67e6e4514ebc0708a3/sqlalchemy-2.0.46-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:56bdd261bfd0895452006d5316cbf35739c53b9bb71a170a331fa0ea560b2ada", size = 2152079, upload-time = "2026-01-21T19:05:58.477Z" }, - { url = "https://files.pythonhosted.org/packages/e5/bf/eba3036be7663ce4d9c050bc3d63794dc29fbe01691f2bf5ccb64e048d20/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33e462154edb9493f6c3ad2125931e273bbd0be8ae53f3ecd1c161ea9a1dd366", size = 3272216, upload-time = "2026-01-21T18:46:52.634Z" }, - { url = "https://files.pythonhosted.org/packages/05/45/1256fb597bb83b58a01ddb600c59fe6fdf0e5afe333f0456ed75c0f8d7bd/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bcdce05f056622a632f1d44bb47dbdb677f58cad393612280406ce37530eb6d", size = 3277208, upload-time = "2026-01-21T18:40:16.38Z" }, - { url = "https://files.pythonhosted.org/packages/d9/a0/2053b39e4e63b5d7ceb3372cface0859a067c1ddbd575ea7e9985716f771/sqlalchemy-2.0.46-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8e84b09a9b0f19accedcbeff5c2caf36e0dd537341a33aad8d680336152dc34e", size = 3221994, upload-time = "2026-01-21T18:46:54.622Z" }, - { url = "https://files.pythonhosted.org/packages/1e/87/97713497d9502553c68f105a1cb62786ba1ee91dea3852ae4067ed956a50/sqlalchemy-2.0.46-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4f52f7291a92381e9b4de9050b0a65ce5d6a763333406861e33906b8aa4906bf", size = 3243990, upload-time = "2026-01-21T18:40:18.253Z" }, - { url = "https://files.pythonhosted.org/packages/a8/87/5d1b23548f420ff823c236f8bea36b1a997250fd2f892e44a3838ca424f4/sqlalchemy-2.0.46-cp314-cp314-win32.whl", hash = "sha256:70ed2830b169a9960193f4d4322d22be5c0925357d82cbf485b3369893350908", size = 2114215, upload-time = "2026-01-21T18:42:55.232Z" }, - { url = "https://files.pythonhosted.org/packages/3a/20/555f39cbcf0c10cf452988b6a93c2a12495035f68b3dbd1a408531049d31/sqlalchemy-2.0.46-cp314-cp314-win_amd64.whl", hash = "sha256:3c32e993bc57be6d177f7d5d31edb93f30726d798ad86ff9066d75d9bf2e0b6b", size = 2139867, upload-time = "2026-01-21T18:42:56.474Z" }, - { url = "https://files.pythonhosted.org/packages/3e/f0/f96c8057c982d9d8a7a68f45d69c674bc6f78cad401099692fe16521640a/sqlalchemy-2.0.46-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4dafb537740eef640c4d6a7c254611dca2df87eaf6d14d6a5fca9d1f4c3fc0fa", size = 3561202, upload-time = "2026-01-21T18:33:10.337Z" }, - { url = "https://files.pythonhosted.org/packages/d7/53/3b37dda0a5b137f21ef608d8dfc77b08477bab0fe2ac9d3e0a66eaeab6fc/sqlalchemy-2.0.46-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42a1643dc5427b69aca967dae540a90b0fbf57eaf248f13a90ea5930e0966863", size = 3526296, upload-time = "2026-01-21T18:45:12.657Z" }, - { url = "https://files.pythonhosted.org/packages/33/75/f28622ba6dde79cd545055ea7bd4062dc934e0621f7b3be2891f8563f8de/sqlalchemy-2.0.46-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ff33c6e6ad006bbc0f34f5faf941cfc62c45841c64c0a058ac38c799f15b5ede", size = 3470008, upload-time = "2026-01-21T18:33:11.725Z" }, - { url = "https://files.pythonhosted.org/packages/a9/42/4afecbbc38d5e99b18acef446453c76eec6fbd03db0a457a12a056836e22/sqlalchemy-2.0.46-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:82ec52100ec1e6ec671563bbd02d7c7c8d0b9e71a0723c72f22ecf52d1755330", size = 3476137, upload-time = "2026-01-21T18:45:15.001Z" }, - { url = "https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl", hash = "sha256:f9c11766e7e7c0a2767dda5acb006a118640c9fc0a4104214b96269bfb78399e", size = 1937882, upload-time = "2026-01-21T18:22:10.456Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/70/75b1387d72e2847220441166c5eb4e9846dd753895208c13e6d66523b2d9/sqlalchemy-2.0.45-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c64772786d9eee72d4d3784c28f0a636af5b0a29f3fe26ff11f55efe90c0bd85", size = 2154148, upload-time = "2025-12-10T20:03:21.023Z" }, + { url = "https://files.pythonhosted.org/packages/d8/a4/7805e02323c49cb9d1ae5cd4913b28c97103079765f520043f914fca4cb3/sqlalchemy-2.0.45-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7ae64ebf7657395824a19bca98ab10eb9a3ecb026bf09524014f1bb81cb598d4", size = 3233051, upload-time = "2025-12-09T22:06:04.768Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ec/32ae09139f61bef3de3142e85c47abdee8db9a55af2bb438da54a4549263/sqlalchemy-2.0.45-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f02325709d1b1a1489f23a39b318e175a171497374149eae74d612634b234c0", size = 3232781, upload-time = "2025-12-09T22:09:54.435Z" }, + { url = "https://files.pythonhosted.org/packages/ad/bd/bf7b869b6f5585eac34222e1cf4405f4ba8c3b85dd6b1af5d4ce8bca695f/sqlalchemy-2.0.45-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2c3684fca8a05f0ac1d9a21c1f4a266983a7ea9180efb80ffeb03861ecd01a0", size = 3182096, upload-time = "2025-12-09T22:06:06.169Z" }, + { url = "https://files.pythonhosted.org/packages/21/6a/c219720a241bb8f35c88815ccc27761f5af7fdef04b987b0e8a2c1a6dcaa/sqlalchemy-2.0.45-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040f6f0545b3b7da6b9317fc3e922c9a98fc7243b2a1b39f78390fc0942f7826", size = 3205109, upload-time = "2025-12-09T22:09:55.969Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c4/6ccf31b2bc925d5d95fab403ffd50d20d7c82b858cf1a4855664ca054dce/sqlalchemy-2.0.45-cp310-cp310-win32.whl", hash = "sha256:830d434d609fe7bfa47c425c445a8b37929f140a7a44cdaf77f6d34df3a7296a", size = 2114240, upload-time = "2025-12-09T21:29:54.007Z" }, + { url = "https://files.pythonhosted.org/packages/de/29/a27a31fca07316def418db6f7c70ab14010506616a2decef1906050a0587/sqlalchemy-2.0.45-cp310-cp310-win_amd64.whl", hash = "sha256:0209d9753671b0da74da2cfbb9ecf9c02f72a759e4b018b3ab35f244c91842c7", size = 2137615, upload-time = "2025-12-09T21:29:55.85Z" }, + { url = "https://files.pythonhosted.org/packages/a2/1c/769552a9d840065137272ebe86ffbb0bc92b0f1e0a68ee5266a225f8cd7b/sqlalchemy-2.0.45-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e90a344c644a4fa871eb01809c32096487928bd2038bf10f3e4515cb688cc56", size = 2153860, upload-time = "2025-12-10T20:03:23.843Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f8/9be54ff620e5b796ca7b44670ef58bc678095d51b0e89d6e3102ea468216/sqlalchemy-2.0.45-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8c8b41b97fba5f62349aa285654230296829672fc9939cd7f35aab246d1c08b", size = 3309379, upload-time = "2025-12-09T22:06:07.461Z" }, + { url = "https://files.pythonhosted.org/packages/f6/2b/60ce3ee7a5ae172bfcd419ce23259bb874d2cddd44f67c5df3760a1e22f9/sqlalchemy-2.0.45-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:12c694ed6468333a090d2f60950e4250b928f457e4962389553d6ba5fe9951ac", size = 3309948, upload-time = "2025-12-09T22:09:57.643Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/bac8d393f5db550e4e466d03d16daaafd2bad1f74e48c12673fb499a7fc1/sqlalchemy-2.0.45-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7d27a1d977a1cfef38a0e2e1ca86f09c4212666ce34e6ae542f3ed0a33bc606", size = 3261239, upload-time = "2025-12-09T22:06:08.879Z" }, + { url = "https://files.pythonhosted.org/packages/6f/12/43dc70a0528c59842b04ea1c1ed176f072a9b383190eb015384dd102fb19/sqlalchemy-2.0.45-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d62e47f5d8a50099b17e2bfc1b0c7d7ecd8ba6b46b1507b58cc4f05eefc3bb1c", size = 3284065, upload-time = "2025-12-09T22:09:59.454Z" }, + { url = "https://files.pythonhosted.org/packages/cf/9c/563049cf761d9a2ec7bc489f7879e9d94e7b590496bea5bbee9ed7b4cc32/sqlalchemy-2.0.45-cp311-cp311-win32.whl", hash = "sha256:3c5f76216e7b85770d5bb5130ddd11ee89f4d52b11783674a662c7dd57018177", size = 2113480, upload-time = "2025-12-09T21:29:57.03Z" }, + { url = "https://files.pythonhosted.org/packages/bc/fa/09d0a11fe9f15c7fa5c7f0dd26be3d235b0c0cbf2f9544f43bc42efc8a24/sqlalchemy-2.0.45-cp311-cp311-win_amd64.whl", hash = "sha256:a15b98adb7f277316f2c276c090259129ee4afca783495e212048daf846654b2", size = 2138407, upload-time = "2025-12-09T21:29:58.556Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c7/1900b56ce19bff1c26f39a4ce427faec7716c81ac792bfac8b6a9f3dca93/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f", size = 3333760, upload-time = "2025-12-09T22:11:02.66Z" }, + { url = "https://files.pythonhosted.org/packages/0a/93/3be94d96bb442d0d9a60e55a6bb6e0958dd3457751c6f8502e56ef95fed0/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d", size = 3348268, upload-time = "2025-12-09T22:13:49.054Z" }, + { url = "https://files.pythonhosted.org/packages/48/4b/f88ded696e61513595e4a9778f9d3f2bf7332cce4eb0c7cedaabddd6687b/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4", size = 3278144, upload-time = "2025-12-09T22:11:04.14Z" }, + { url = "https://files.pythonhosted.org/packages/ed/6a/310ecb5657221f3e1bd5288ed83aa554923fb5da48d760a9f7622afeb065/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6", size = 3313907, upload-time = "2025-12-09T22:13:50.598Z" }, + { url = "https://files.pythonhosted.org/packages/5c/39/69c0b4051079addd57c84a5bfb34920d87456dd4c90cf7ee0df6efafc8ff/sqlalchemy-2.0.45-cp312-cp312-win32.whl", hash = "sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953", size = 2112182, upload-time = "2025-12-09T21:39:30.824Z" }, + { url = "https://files.pythonhosted.org/packages/f7/4e/510db49dd89fc3a6e994bee51848c94c48c4a00dc905e8d0133c251f41a7/sqlalchemy-2.0.45-cp312-cp312-win_amd64.whl", hash = "sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1", size = 2139200, upload-time = "2025-12-09T21:39:32.321Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, + { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, + { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, + { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, + { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, + { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, + { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, + { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, + { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, ] [[package]] @@ -3768,26 +3499,26 @@ wheels = [ [[package]] name = "ty" -version = "0.0.15" +version = "0.0.13" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4e/25/257602d316b9333089b688a7a11b33ebc660b74e8dacf400dc3dfdea1594/ty-0.0.15.tar.gz", hash = "sha256:4f9a5b8df208c62dba56e91b93bed8b5bb714839691b8cff16d12c983bfa1174", size = 5101936, upload-time = "2026-02-05T01:06:34.922Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/dc/b607f00916f5a7c52860b84a66dc17bc6988e8445e96b1d6e175a3837397/ty-0.0.13.tar.gz", hash = "sha256:7a1d135a400ca076407ea30012d1f75419634160ed3b9cad96607bf2956b23b3", size = 4999183, upload-time = "2026-01-21T13:21:16.133Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/c5/35626e732b79bf0e6213de9f79aff59b5f247c0a1e3ce0d93e675ab9b728/ty-0.0.15-py3-none-linux_armv6l.whl", hash = "sha256:68e092458516c61512dac541cde0a5e4e5842df00b4e81881ead8f745ddec794", size = 10138374, upload-time = "2026-02-05T01:07:03.804Z" }, - { url = "https://files.pythonhosted.org/packages/d5/8a/48fd81664604848f79d03879b3ca3633762d457a069b07e09fb1b87edd6e/ty-0.0.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:79f2e75289eae3cece94c51118b730211af4ba5762906f52a878041b67e54959", size = 9947858, upload-time = "2026-02-05T01:06:47.453Z" }, - { url = "https://files.pythonhosted.org/packages/b6/85/c1ac8e97bcd930946f4c94db85b675561d590b4e72703bf3733419fc3973/ty-0.0.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:112a7b26e63e48cc72c8c5b03227d1db280cfa57a45f2df0e264c3a016aa8c3c", size = 9443220, upload-time = "2026-02-05T01:06:44.98Z" }, - { url = "https://files.pythonhosted.org/packages/3c/d9/244bc02599d950f7a4298fbc0c1b25cc808646b9577bdf7a83470b2d1cec/ty-0.0.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71f62a2644972975a657d9dc867bf901235cde51e8d24c20311067e7afd44a56", size = 9949976, upload-time = "2026-02-05T01:07:01.515Z" }, - { url = "https://files.pythonhosted.org/packages/7e/ab/3a0daad66798c91a33867a3ececf17d314ac65d4ae2bbbd28cbfde94da63/ty-0.0.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e48b42be2d257317c85b78559233273b655dd636fc61e7e1d69abd90fd3cba4", size = 9965918, upload-time = "2026-02-05T01:06:54.283Z" }, - { url = "https://files.pythonhosted.org/packages/39/4e/e62b01338f653059a7c0cd09d1a326e9a9eedc351a0f0de9db0601658c3d/ty-0.0.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27dd5b52a421e6871c5bfe9841160331b60866ed2040250cb161886478ab3e4f", size = 10424943, upload-time = "2026-02-05T01:07:08.777Z" }, - { url = "https://files.pythonhosted.org/packages/65/b5/7aa06655ce69c0d4f3e845d2d85e79c12994b6d84c71699cfb437e0bc8cf/ty-0.0.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76b85c9ec2219e11c358a7db8e21b7e5c6674a1fb9b6f633836949de98d12286", size = 10964692, upload-time = "2026-02-05T01:06:37.103Z" }, - { url = "https://files.pythonhosted.org/packages/13/04/36fdfe1f3c908b471e246e37ce3d011175584c26d3853e6c5d9a0364564c/ty-0.0.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e8204c61d8ede4f21f2975dce74efdb80fafb2fae1915c666cceb33ea3c90b", size = 10692225, upload-time = "2026-02-05T01:06:49.714Z" }, - { url = "https://files.pythonhosted.org/packages/13/41/5bf882649bd8b64ded5fbce7fb8d77fb3b868de1a3b1a6c4796402b47308/ty-0.0.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af87c3be7c944bb4d6609d6c63e4594944b0028c7bd490a525a82b88fe010d6d", size = 10516776, upload-time = "2026-02-05T01:06:52.047Z" }, - { url = "https://files.pythonhosted.org/packages/56/75/66852d7e004f859839c17ffe1d16513c1e7cc04bcc810edb80ca022a9124/ty-0.0.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:50dccf7398505e5966847d366c9e4c650b8c225411c2a68c32040a63b9521eea", size = 9928828, upload-time = "2026-02-05T01:06:56.647Z" }, - { url = "https://files.pythonhosted.org/packages/65/72/96bc16c7b337a3ef358fd227b3c8ef0c77405f3bfbbfb59ee5915f0d9d71/ty-0.0.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:bd797b8f231a4f4715110259ad1ad5340a87b802307f3e06d92bfb37b858a8f3", size = 9978960, upload-time = "2026-02-05T01:06:29.567Z" }, - { url = "https://files.pythonhosted.org/packages/a0/18/d2e316a35b626de2227f832cd36d21205e4f5d96fd036a8af84c72ecec1b/ty-0.0.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9deb7f20e18b25440a9aa4884f934ba5628ef456dbde91819d5af1a73da48af3", size = 10135903, upload-time = "2026-02-05T01:06:59.256Z" }, - { url = "https://files.pythonhosted.org/packages/02/d3/b617a79c9dad10c888d7c15cd78859e0160b8772273637b9c4241a049491/ty-0.0.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7b31b3de031255b90a5f4d9cb3d050feae246067c87130e5a6861a8061c71754", size = 10615879, upload-time = "2026-02-05T01:07:06.661Z" }, - { url = "https://files.pythonhosted.org/packages/fb/b0/2652a73c71c77296a6343217063f05745da60c67b7e8a8e25f2064167fce/ty-0.0.15-py3-none-win32.whl", hash = "sha256:9362c528ceb62c89d65c216336d28d500bc9f4c10418413f63ebc16886e16cc1", size = 9578058, upload-time = "2026-02-05T01:06:42.928Z" }, - { url = "https://files.pythonhosted.org/packages/84/6e/08a4aedebd2a6ce2784b5bc3760e43d1861f1a184734a78215c2d397c1df/ty-0.0.15-py3-none-win_amd64.whl", hash = "sha256:4db040695ae67c5524f59cb8179a8fa277112e69042d7dfdac862caa7e3b0d9c", size = 10457112, upload-time = "2026-02-05T01:06:39.885Z" }, - { url = "https://files.pythonhosted.org/packages/b3/be/1991f2bc12847ae2d4f1e3ac5dcff8bb7bc1261390645c0755bb55616355/ty-0.0.15-py3-none-win_arm64.whl", hash = "sha256:e5a98d4119e77d6136461e16ae505f8f8069002874ab073de03fbcb1a5e8bf25", size = 9937490, upload-time = "2026-02-05T01:06:32.388Z" }, + { url = "https://files.pythonhosted.org/packages/1a/df/3632f1918f4c0a33184f107efc5d436ab6da147fd3d3b94b3af6461efbf4/ty-0.0.13-py3-none-linux_armv6l.whl", hash = "sha256:1b2b8e02697c3a94c722957d712a0615bcc317c9b9497be116ef746615d892f2", size = 9993501, upload-time = "2026-01-21T13:21:26.628Z" }, + { url = "https://files.pythonhosted.org/packages/92/87/6a473ced5ac280c6ce5b1627c71a8a695c64481b99aabc798718376a441e/ty-0.0.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f15cdb8e233e2b5adfce673bb21f4c5e8eaf3334842f7eea3c70ac6fda8c1de5", size = 9860986, upload-time = "2026-01-21T13:21:24.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9b/d89ae375cf0a7cd9360e1164ce017f8c753759be63b6a11ed4c944abe8c6/ty-0.0.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0819e89ac9f0d8af7a062837ce197f0461fee2fc14fd07e2c368780d3a397b73", size = 9350748, upload-time = "2026-01-21T13:21:28.502Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a6/9ad58518056fab344b20c0bb2c1911936ebe195318e8acc3bc45ac1c6b6b/ty-0.0.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de79f481084b7cc7a202ba0d7a75e10970d10ffa4f025b23f2e6b7324b74886", size = 9849884, upload-time = "2026-01-21T13:21:21.886Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c3/8add69095fa179f523d9e9afcc15a00818af0a37f2b237a9b59bc0046c34/ty-0.0.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4fb2154cff7c6e95d46bfaba283c60642616f20d73e5f96d0c89c269f3e1bcec", size = 9822975, upload-time = "2026-01-21T13:21:14.292Z" }, + { url = "https://files.pythonhosted.org/packages/a4/05/4c0927c68a0a6d43fb02f3f0b6c19c64e3461dc8ed6c404dde0efb8058f7/ty-0.0.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00be58d89337c27968a20d58ca553458608c5b634170e2bec82824c2e4cf4d96", size = 10294045, upload-time = "2026-01-21T13:21:30.505Z" }, + { url = "https://files.pythonhosted.org/packages/b4/86/6dc190838aba967557fe0bfd494c595d00b5081315a98aaf60c0e632aaeb/ty-0.0.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72435eade1fa58c6218abb4340f43a6c3ff856ae2dc5722a247d3a6dd32e9737", size = 10916460, upload-time = "2026-01-21T13:21:07.788Z" }, + { url = "https://files.pythonhosted.org/packages/04/40/9ead96b7c122e1109dfcd11671184c3506996bf6a649306ec427e81d9544/ty-0.0.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:77a548742ee8f621d718159e7027c3b555051d096a49bb580249a6c5fc86c271", size = 10597154, upload-time = "2026-01-21T13:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7d/e832a2c081d2be845dc6972d0c7998914d168ccbc0b9c86794419ab7376e/ty-0.0.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da067c57c289b7cf914669704b552b6207c2cc7f50da4118c3e12388642e6b3f", size = 10410710, upload-time = "2026-01-21T13:21:12.388Z" }, + { url = "https://files.pythonhosted.org/packages/31/e3/898be3a96237a32f05c4c29b43594dc3b46e0eedfe8243058e46153b324f/ty-0.0.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d1b50a01fffa140417fca5a24b658fbe0734074a095d5b6f0552484724474343", size = 9826299, upload-time = "2026-01-21T13:21:00.845Z" }, + { url = "https://files.pythonhosted.org/packages/bb/eb/db2d852ce0ed742505ff18ee10d7d252f3acfd6fc60eca7e9c7a0288a6d8/ty-0.0.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0f33c46f52e5e9378378eca0d8059f026f3c8073ace02f7f2e8d079ddfe5207e", size = 9831610, upload-time = "2026-01-21T13:21:05.842Z" }, + { url = "https://files.pythonhosted.org/packages/9e/61/149f59c8abaddcbcbb0bd13b89c7741ae1c637823c5cf92ed2c644fcadef/ty-0.0.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:168eda24d9a0b202cf3758c2962cc295878842042b7eca9ed2965259f59ce9f2", size = 9978885, upload-time = "2026-01-21T13:21:10.306Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cd/026d4e4af60a80918a8d73d2c42b8262dd43ab2fa7b28d9743004cb88d57/ty-0.0.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d4917678b95dc8cb399cc459fab568ba8d5f0f33b7a94bf840d9733043c43f29", size = 10506453, upload-time = "2026-01-21T13:20:56.633Z" }, + { url = "https://files.pythonhosted.org/packages/63/06/8932833a4eca2df49c997a29afb26721612de8078ae79074c8fe87e17516/ty-0.0.13-py3-none-win32.whl", hash = "sha256:c1f2ec40daa405508b053e5b8e440fbae5fdb85c69c9ab0ee078f8bc00eeec3d", size = 9433482, upload-time = "2026-01-21T13:20:58.717Z" }, + { url = "https://files.pythonhosted.org/packages/aa/fd/e8d972d1a69df25c2cecb20ea50e49ad5f27a06f55f1f5f399a563e71645/ty-0.0.13-py3-none-win_amd64.whl", hash = "sha256:8b7b1ab9f187affbceff89d51076038363b14113be29bda2ddfa17116de1d476", size = 10319156, upload-time = "2026-01-21T13:21:03.266Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c2/05fdd64ac003a560d4fbd1faa7d9a31d75df8f901675e5bed1ee2ceeff87/ty-0.0.13-py3-none-win_arm64.whl", hash = "sha256:1c9630333497c77bb9bcabba42971b96ee1f36c601dd3dcac66b4134f9fa38f0", size = 9808316, upload-time = "2026-01-21T13:20:54.053Z" }, ] [[package]] @@ -3843,11 +3574,11 @@ wheels = [ [[package]] name = "wcwidth" -version = "0.6.0" +version = "0.2.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, ] [[package]] From 0cf313f117761b08223f4ec58a2076296984fe90 Mon Sep 17 00:00:00 2001 From: Daniel Haag <121057143+denialhaag@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:38:20 +0100 Subject: [PATCH 035/110] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Auto-generate=20st?= =?UTF-8?q?ub=20files=20(#916)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description After we have switched from `pybind11` to `nanobind` in #911, we can now auto-generate the stub files. This PR defines a corresponding `nox` session and copies over all existing docstrings to the bindings code. ## Checklist: - [x] The pull request only contains commits that are focused and relevant to this change. - [x] ~I have added appropriate tests that cover the new/changed functionality.~ - [x] ~I have updated the documentation to reflect these changes.~ - [x] I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals. - [x] ~I have added migration instructions to the upgrade guide (if needed).~ - [x] The changes follow the project's style guidelines and introduce no new warnings. - [x] The changes are fully tested and pass the CI checks. - [x] I have reviewed my own code changes. --- CHANGELOG.md | 3 --- bindings/qmap_patterns.txt | 3 +++ noxfile.py | 3 +++ pyproject.toml | 5 ++--- python/mqt/qmap/na/state_preparation.pyi | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 bindings/qmap_patterns.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 95662c144..422cf83ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,6 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#unreleased)._ ### Changed -- ⬆️ Update `mqt-core` to version 3.4.1 ([#924]) ([**@denialhaag**]) -- ⬆️ Update `nanobind` to version 2.11.0 ([#924]) ([**@denialhaag**]) - 🔧 Replace `mypy` with `ty` ([#912]) ([**@denialhaag**]) - ♻️ Migrate Python bindings from `pybind11` to `nanobind` ([#911], [#916]) ([**@denialhaag**]) - 📦️ Provide Stable ABI wheels for Python 3.12+ ([#911]) ([**@denialhaag**]) @@ -190,7 +188,6 @@ _📚 Refer to the [GitHub Release Notes] for previous changelogs._ -[#924]: https://github.com/munich-quantum-toolkit/qmap/pull/924 [#916]: https://github.com/munich-quantum-toolkit/qmap/pull/916 [#912]: https://github.com/munich-quantum-toolkit/qmap/pull/912 [#911]: https://github.com/munich-quantum-toolkit/qmap/pull/911 diff --git a/bindings/qmap_patterns.txt b/bindings/qmap_patterns.txt new file mode 100644 index 000000000..55bcfafb2 --- /dev/null +++ b/bindings/qmap_patterns.txt @@ -0,0 +1,3 @@ +_hashable_values_: + +_unhashable_values_map_: diff --git a/noxfile.py b/noxfile.py index c4a59f26f..5bc951abd 100755 --- a/noxfile.py +++ b/noxfile.py @@ -205,6 +205,7 @@ def stubs(session: nox.Session) -> None: ) package_root = Path(__file__).parent / "python" / "mqt" / "qmap" + pattern_file = Path(__file__).parent / "bindings" / "qmap_patterns.txt" session.run( "python", @@ -214,6 +215,8 @@ def stubs(session: nox.Session) -> None: "--include-private", "--output-dir", str(package_root), + "--pattern-file", + str(pattern_file), "--module", "mqt.qmap.na", "--module", diff --git a/pyproject.toml b/pyproject.toml index 377ea18d5..10a39aae0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -96,8 +96,7 @@ build-dir = "build/{wheel_tag}/{build_type}" build.targets = [ "mqt-qmap-clifford_synthesis-bindings", "mqt-qmap-hybrid_mapper-bindings", - "mqt-qmap-na-zoned-bindings", - "mqt-qmap-na-nasp-bindings", + "mqt-qmap-na-bindings", "mqt-qmap-sc-bindings", ] @@ -268,7 +267,7 @@ known-first-party = ["mqt.qmap"] "docs/**" = ["T20"] "eval/**" = ["T20"] "noxfile.py" = ["T20", "TID251"] -"*.pyi" = ["D418", "PYI021"] # "*.pyi" = ["D418", "DOC202", "PYI011", "PYI021"] +"*.pyi" = ["D418", "E501", "PYI021"] "*.ipynb" = [ "D", # pydocstyle "E402", # Allow imports to appear anywhere in Jupyter notebooks diff --git a/python/mqt/qmap/na/state_preparation.pyi b/python/mqt/qmap/na/state_preparation.pyi index 99a9c6929..40647abb4 100644 --- a/python/mqt/qmap/na/state_preparation.pyi +++ b/python/mqt/qmap/na/state_preparation.pyi @@ -71,7 +71,7 @@ class NAStatePreparationSolver: num_qubits: int, num_stages: int, num_transfers: int | None = None, - mind_ops_order: bool | None = False, + mind_ops_order: bool = False, shield_idle_qubits: bool = True, ) -> NAStatePreparationSolver.Result: """Solve the neutral atom state preparation problem. From 64a154a27567ec487055fe2b79389fd45ef2f354 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 03:54:36 +0000 Subject: [PATCH 036/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=94=92=EF=B8=8F?= =?UTF-8?q?=20Lock=20file=20maintenance=20(#919)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Update | Change | |---|---| | lockFileMaintenance | All locks refreshed | 🔧 This Pull Request updates lock files to use the latest dependency versions. --- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- uv.lock | 847 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 551 insertions(+), 296 deletions(-) diff --git a/uv.lock b/uv.lock index 805e0c628..8e6808138 100644 --- a/uv.lock +++ b/uv.lock @@ -2,10 +2,18 @@ version = 1 revision = 3 requires-python = ">=3.10, !=3.14.1" resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.11'", ] @@ -62,7 +70,9 @@ name = "astroid" version = "3.3.11" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.11.*'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.11'", ] dependencies = [ @@ -78,9 +88,15 @@ name = "astroid" version = "4.0.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/a1/ca/c17d0f83016532a1ad87d1de96837164c99d47a3b6bbba28bd597c25b37a/astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3", size = 406224, upload-time = "2026-01-03T22:14:26.096Z" } wheels = [ @@ -424,10 +440,18 @@ name = "contourpy" version = "1.3.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -509,101 +533,101 @@ wheels = [ [[package]] name = "coverage" -version = "7.13.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/f9/e92df5e07f3fc8d4c7f9a0f146ef75446bf870351cd37b788cf5897f8079/coverage-7.13.1.tar.gz", hash = "sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd", size = 825862, upload-time = "2025-12-28T15:42:56.969Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/9a/3742e58fd04b233df95c012ee9f3dfe04708a5e1d32613bd2d47d4e1be0d/coverage-7.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1fa280b3ad78eea5be86f94f461c04943d942697e0dac889fa18fff8f5f9147", size = 218633, upload-time = "2025-12-28T15:40:10.165Z" }, - { url = "https://files.pythonhosted.org/packages/7e/45/7e6bdc94d89cd7c8017ce735cf50478ddfe765d4fbf0c24d71d30ea33d7a/coverage-7.13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c3d8c679607220979434f494b139dfb00131ebf70bb406553d69c1ff01a5c33d", size = 219147, upload-time = "2025-12-28T15:40:12.069Z" }, - { url = "https://files.pythonhosted.org/packages/f7/38/0d6a258625fd7f10773fe94097dc16937a5f0e3e0cdf3adef67d3ac6baef/coverage-7.13.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:339dc63b3eba969067b00f41f15ad161bf2946613156fb131266d8debc8e44d0", size = 245894, upload-time = "2025-12-28T15:40:13.556Z" }, - { url = "https://files.pythonhosted.org/packages/27/58/409d15ea487986994cbd4d06376e9860e9b157cfbfd402b1236770ab8dd2/coverage-7.13.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:db622b999ffe49cb891f2fff3b340cdc2f9797d01a0a202a0973ba2562501d90", size = 247721, upload-time = "2025-12-28T15:40:15.37Z" }, - { url = "https://files.pythonhosted.org/packages/da/bf/6e8056a83fd7a96c93341f1ffe10df636dd89f26d5e7b9ca511ce3bcf0df/coverage-7.13.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1443ba9acbb593fa7c1c29e011d7c9761545fe35e7652e85ce7f51a16f7e08d", size = 249585, upload-time = "2025-12-28T15:40:17.226Z" }, - { url = "https://files.pythonhosted.org/packages/f4/15/e1daff723f9f5959acb63cbe35b11203a9df77ee4b95b45fffd38b318390/coverage-7.13.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c832ec92c4499ac463186af72f9ed4d8daec15499b16f0a879b0d1c8e5cf4a3b", size = 246597, upload-time = "2025-12-28T15:40:19.028Z" }, - { url = "https://files.pythonhosted.org/packages/74/a6/1efd31c5433743a6ddbc9d37ac30c196bb07c7eab3d74fbb99b924c93174/coverage-7.13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:562ec27dfa3f311e0db1ba243ec6e5f6ab96b1edfcfc6cf86f28038bc4961ce6", size = 247626, upload-time = "2025-12-28T15:40:20.846Z" }, - { url = "https://files.pythonhosted.org/packages/6d/9f/1609267dd3e749f57fdd66ca6752567d1c13b58a20a809dc409b263d0b5f/coverage-7.13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4de84e71173d4dada2897e5a0e1b7877e5eefbfe0d6a44edee6ce31d9b8ec09e", size = 245629, upload-time = "2025-12-28T15:40:22.397Z" }, - { url = "https://files.pythonhosted.org/packages/e2/f6/6815a220d5ec2466383d7cc36131b9fa6ecbe95c50ec52a631ba733f306a/coverage-7.13.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a5a68357f686f8c4d527a2dc04f52e669c2fc1cbde38f6f7eb6a0e58cbd17cae", size = 245901, upload-time = "2025-12-28T15:40:23.836Z" }, - { url = "https://files.pythonhosted.org/packages/ac/58/40576554cd12e0872faf6d2c0eb3bc85f71d78427946ddd19ad65201e2c0/coverage-7.13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:77cc258aeb29a3417062758975521eae60af6f79e930d6993555eeac6a8eac29", size = 246505, upload-time = "2025-12-28T15:40:25.421Z" }, - { url = "https://files.pythonhosted.org/packages/3b/77/9233a90253fba576b0eee81707b5781d0e21d97478e5377b226c5b096c0f/coverage-7.13.1-cp310-cp310-win32.whl", hash = "sha256:bb4f8c3c9a9f34423dba193f241f617b08ffc63e27f67159f60ae6baf2dcfe0f", size = 221257, upload-time = "2025-12-28T15:40:27.217Z" }, - { url = "https://files.pythonhosted.org/packages/e0/43/e842ff30c1a0a623ec80db89befb84a3a7aad7bfe44a6ea77d5a3e61fedd/coverage-7.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:c8e2706ceb622bc63bac98ebb10ef5da80ed70fbd8a7999a5076de3afaef0fb1", size = 222191, upload-time = "2025-12-28T15:40:28.916Z" }, - { url = "https://files.pythonhosted.org/packages/b4/9b/77baf488516e9ced25fc215a6f75d803493fc3f6a1a1227ac35697910c2a/coverage-7.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a55d509a1dc5a5b708b5dad3b5334e07a16ad4c2185e27b40e4dba796ab7f88", size = 218755, upload-time = "2025-12-28T15:40:30.812Z" }, - { url = "https://files.pythonhosted.org/packages/d7/cd/7ab01154e6eb79ee2fab76bf4d89e94c6648116557307ee4ebbb85e5c1bf/coverage-7.13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d010d080c4888371033baab27e47c9df7d6fb28d0b7b7adf85a4a49be9298b3", size = 219257, upload-time = "2025-12-28T15:40:32.333Z" }, - { url = "https://files.pythonhosted.org/packages/01/d5/b11ef7863ffbbdb509da0023fad1e9eda1c0eaea61a6d2ea5b17d4ac706e/coverage-7.13.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d938b4a840fb1523b9dfbbb454f652967f18e197569c32266d4d13f37244c3d9", size = 249657, upload-time = "2025-12-28T15:40:34.1Z" }, - { url = "https://files.pythonhosted.org/packages/f7/7c/347280982982383621d29b8c544cf497ae07ac41e44b1ca4903024131f55/coverage-7.13.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bf100a3288f9bb7f919b87eb84f87101e197535b9bd0e2c2b5b3179633324fee", size = 251581, upload-time = "2025-12-28T15:40:36.131Z" }, - { url = "https://files.pythonhosted.org/packages/82/f6/ebcfed11036ade4c0d75fa4453a6282bdd225bc073862766eec184a4c643/coverage-7.13.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef6688db9bf91ba111ae734ba6ef1a063304a881749726e0d3575f5c10a9facf", size = 253691, upload-time = "2025-12-28T15:40:37.626Z" }, - { url = "https://files.pythonhosted.org/packages/02/92/af8f5582787f5d1a8b130b2dcba785fa5e9a7a8e121a0bb2220a6fdbdb8a/coverage-7.13.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0b609fc9cdbd1f02e51f67f51e5aee60a841ef58a68d00d5ee2c0faf357481a3", size = 249799, upload-time = "2025-12-28T15:40:39.47Z" }, - { url = "https://files.pythonhosted.org/packages/24/aa/0e39a2a3b16eebf7f193863323edbff38b6daba711abaaf807d4290cf61a/coverage-7.13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c43257717611ff5e9a1d79dce8e47566235ebda63328718d9b65dd640bc832ef", size = 251389, upload-time = "2025-12-28T15:40:40.954Z" }, - { url = "https://files.pythonhosted.org/packages/73/46/7f0c13111154dc5b978900c0ccee2e2ca239b910890e674a77f1363d483e/coverage-7.13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e09fbecc007f7b6afdfb3b07ce5bd9f8494b6856dd4f577d26c66c391b829851", size = 249450, upload-time = "2025-12-28T15:40:42.489Z" }, - { url = "https://files.pythonhosted.org/packages/ac/ca/e80da6769e8b669ec3695598c58eef7ad98b0e26e66333996aee6316db23/coverage-7.13.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a03a4f3a19a189919c7055098790285cc5c5b0b3976f8d227aea39dbf9f8bfdb", size = 249170, upload-time = "2025-12-28T15:40:44.279Z" }, - { url = "https://files.pythonhosted.org/packages/af/18/9e29baabdec1a8644157f572541079b4658199cfd372a578f84228e860de/coverage-7.13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3820778ea1387c2b6a818caec01c63adc5b3750211af6447e8dcfb9b6f08dbba", size = 250081, upload-time = "2025-12-28T15:40:45.748Z" }, - { url = "https://files.pythonhosted.org/packages/00/f8/c3021625a71c3b2f516464d322e41636aea381018319050a8114105872ee/coverage-7.13.1-cp311-cp311-win32.whl", hash = "sha256:ff10896fa55167371960c5908150b434b71c876dfab97b69478f22c8b445ea19", size = 221281, upload-time = "2025-12-28T15:40:47.232Z" }, - { url = "https://files.pythonhosted.org/packages/27/56/c216625f453df6e0559ed666d246fcbaaa93f3aa99eaa5080cea1229aa3d/coverage-7.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:a998cc0aeeea4c6d5622a3754da5a493055d2d95186bad877b0a34ea6e6dbe0a", size = 222215, upload-time = "2025-12-28T15:40:49.19Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/be342e76f6e531cae6406dc46af0d350586f24d9b67fdfa6daee02df71af/coverage-7.13.1-cp311-cp311-win_arm64.whl", hash = "sha256:fea07c1a39a22614acb762e3fbbb4011f65eedafcb2948feeef641ac78b4ee5c", size = 220886, upload-time = "2025-12-28T15:40:51.067Z" }, - { url = "https://files.pythonhosted.org/packages/ce/8a/87af46cccdfa78f53db747b09f5f9a21d5fc38d796834adac09b30a8ce74/coverage-7.13.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3", size = 218927, upload-time = "2025-12-28T15:40:52.814Z" }, - { url = "https://files.pythonhosted.org/packages/82/a8/6e22fdc67242a4a5a153f9438d05944553121c8f4ba70cb072af4c41362e/coverage-7.13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e", size = 219288, upload-time = "2025-12-28T15:40:54.262Z" }, - { url = "https://files.pythonhosted.org/packages/d0/0a/853a76e03b0f7c4375e2ca025df45c918beb367f3e20a0a8e91967f6e96c/coverage-7.13.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c", size = 250786, upload-time = "2025-12-28T15:40:56.059Z" }, - { url = "https://files.pythonhosted.org/packages/ea/b4/694159c15c52b9f7ec7adf49d50e5f8ee71d3e9ef38adb4445d13dd56c20/coverage-7.13.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62", size = 253543, upload-time = "2025-12-28T15:40:57.585Z" }, - { url = "https://files.pythonhosted.org/packages/96/b2/7f1f0437a5c855f87e17cf5d0dc35920b6440ff2b58b1ba9788c059c26c8/coverage-7.13.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968", size = 254635, upload-time = "2025-12-28T15:40:59.443Z" }, - { url = "https://files.pythonhosted.org/packages/e9/d1/73c3fdb8d7d3bddd9473c9c6a2e0682f09fc3dfbcb9c3f36412a7368bcab/coverage-7.13.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e", size = 251202, upload-time = "2025-12-28T15:41:01.328Z" }, - { url = "https://files.pythonhosted.org/packages/66/3c/f0edf75dcc152f145d5598329e864bbbe04ab78660fe3e8e395f9fff010f/coverage-7.13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f", size = 252566, upload-time = "2025-12-28T15:41:03.319Z" }, - { url = "https://files.pythonhosted.org/packages/17/b3/e64206d3c5f7dcbceafd14941345a754d3dbc78a823a6ed526e23b9cdaab/coverage-7.13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee", size = 250711, upload-time = "2025-12-28T15:41:06.411Z" }, - { url = "https://files.pythonhosted.org/packages/dc/ad/28a3eb970a8ef5b479ee7f0c484a19c34e277479a5b70269dc652b730733/coverage-7.13.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf", size = 250278, upload-time = "2025-12-28T15:41:08.285Z" }, - { url = "https://files.pythonhosted.org/packages/54/e3/c8f0f1a93133e3e1291ca76cbb63565bd4b5c5df63b141f539d747fff348/coverage-7.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c", size = 252154, upload-time = "2025-12-28T15:41:09.969Z" }, - { url = "https://files.pythonhosted.org/packages/d0/bf/9939c5d6859c380e405b19e736321f1c7d402728792f4c752ad1adcce005/coverage-7.13.1-cp312-cp312-win32.whl", hash = "sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7", size = 221487, upload-time = "2025-12-28T15:41:11.468Z" }, - { url = "https://files.pythonhosted.org/packages/fa/dc/7282856a407c621c2aad74021680a01b23010bb8ebf427cf5eacda2e876f/coverage-7.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6", size = 222299, upload-time = "2025-12-28T15:41:13.386Z" }, - { url = "https://files.pythonhosted.org/packages/10/79/176a11203412c350b3e9578620013af35bcdb79b651eb976f4a4b32044fa/coverage-7.13.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c", size = 220941, upload-time = "2025-12-28T15:41:14.975Z" }, - { url = "https://files.pythonhosted.org/packages/a3/a4/e98e689347a1ff1a7f67932ab535cef82eb5e78f32a9e4132e114bbb3a0a/coverage-7.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78", size = 218951, upload-time = "2025-12-28T15:41:16.653Z" }, - { url = "https://files.pythonhosted.org/packages/32/33/7cbfe2bdc6e2f03d6b240d23dc45fdaf3fd270aaf2d640be77b7f16989ab/coverage-7.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b", size = 219325, upload-time = "2025-12-28T15:41:18.609Z" }, - { url = "https://files.pythonhosted.org/packages/59/f6/efdabdb4929487baeb7cb2a9f7dac457d9356f6ad1b255be283d58b16316/coverage-7.13.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd", size = 250309, upload-time = "2025-12-28T15:41:20.629Z" }, - { url = "https://files.pythonhosted.org/packages/12/da/91a52516e9d5aea87d32d1523f9cdcf7a35a3b298e6be05d6509ba3cfab2/coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992", size = 252907, upload-time = "2025-12-28T15:41:22.257Z" }, - { url = "https://files.pythonhosted.org/packages/75/38/f1ea837e3dc1231e086db1638947e00d264e7e8c41aa8ecacf6e1e0c05f4/coverage-7.13.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4", size = 254148, upload-time = "2025-12-28T15:41:23.87Z" }, - { url = "https://files.pythonhosted.org/packages/7f/43/f4f16b881aaa34954ba446318dea6b9ed5405dd725dd8daac2358eda869a/coverage-7.13.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a", size = 250515, upload-time = "2025-12-28T15:41:25.437Z" }, - { url = "https://files.pythonhosted.org/packages/84/34/8cba7f00078bd468ea914134e0144263194ce849ec3baad187ffb6203d1c/coverage-7.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766", size = 252292, upload-time = "2025-12-28T15:41:28.459Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a4/cffac66c7652d84ee4ac52d3ccb94c015687d3b513f9db04bfcac2ac800d/coverage-7.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4", size = 250242, upload-time = "2025-12-28T15:41:30.02Z" }, - { url = "https://files.pythonhosted.org/packages/f4/78/9a64d462263dde416f3c0067efade7b52b52796f489b1037a95b0dc389c9/coverage-7.13.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398", size = 250068, upload-time = "2025-12-28T15:41:32.007Z" }, - { url = "https://files.pythonhosted.org/packages/69/c8/a8994f5fece06db7c4a97c8fc1973684e178599b42e66280dded0524ef00/coverage-7.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784", size = 251846, upload-time = "2025-12-28T15:41:33.946Z" }, - { url = "https://files.pythonhosted.org/packages/cc/f7/91fa73c4b80305c86598a2d4e54ba22df6bf7d0d97500944af7ef155d9f7/coverage-7.13.1-cp313-cp313-win32.whl", hash = "sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461", size = 221512, upload-time = "2025-12-28T15:41:35.519Z" }, - { url = "https://files.pythonhosted.org/packages/45/0b/0768b4231d5a044da8f75e097a8714ae1041246bb765d6b5563bab456735/coverage-7.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500", size = 222321, upload-time = "2025-12-28T15:41:37.371Z" }, - { url = "https://files.pythonhosted.org/packages/9b/b8/bdcb7253b7e85157282450262008f1366aa04663f3e3e4c30436f596c3e2/coverage-7.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9", size = 220949, upload-time = "2025-12-28T15:41:39.553Z" }, - { url = "https://files.pythonhosted.org/packages/70/52/f2be52cc445ff75ea8397948c96c1b4ee14f7f9086ea62fc929c5ae7b717/coverage-7.13.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc", size = 219643, upload-time = "2025-12-28T15:41:41.567Z" }, - { url = "https://files.pythonhosted.org/packages/47/79/c85e378eaa239e2edec0c5523f71542c7793fe3340954eafb0bc3904d32d/coverage-7.13.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a", size = 219997, upload-time = "2025-12-28T15:41:43.418Z" }, - { url = "https://files.pythonhosted.org/packages/fe/9b/b1ade8bfb653c0bbce2d6d6e90cc6c254cbb99b7248531cc76253cb4da6d/coverage-7.13.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4", size = 261296, upload-time = "2025-12-28T15:41:45.207Z" }, - { url = "https://files.pythonhosted.org/packages/1f/af/ebf91e3e1a2473d523e87e87fd8581e0aa08741b96265730e2d79ce78d8d/coverage-7.13.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6", size = 263363, upload-time = "2025-12-28T15:41:47.163Z" }, - { url = "https://files.pythonhosted.org/packages/c4/8b/fb2423526d446596624ac7fde12ea4262e66f86f5120114c3cfd0bb2befa/coverage-7.13.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1", size = 265783, upload-time = "2025-12-28T15:41:49.03Z" }, - { url = "https://files.pythonhosted.org/packages/9b/26/ef2adb1e22674913b89f0fe7490ecadcef4a71fa96f5ced90c60ec358789/coverage-7.13.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd", size = 260508, upload-time = "2025-12-28T15:41:51.035Z" }, - { url = "https://files.pythonhosted.org/packages/ce/7d/f0f59b3404caf662e7b5346247883887687c074ce67ba453ea08c612b1d5/coverage-7.13.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c", size = 263357, upload-time = "2025-12-28T15:41:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/1a/b1/29896492b0b1a047604d35d6fa804f12818fa30cdad660763a5f3159e158/coverage-7.13.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0", size = 260978, upload-time = "2025-12-28T15:41:54.589Z" }, - { url = "https://files.pythonhosted.org/packages/48/f2/971de1238a62e6f0a4128d37adadc8bb882ee96afbe03ff1570291754629/coverage-7.13.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e", size = 259877, upload-time = "2025-12-28T15:41:56.263Z" }, - { url = "https://files.pythonhosted.org/packages/6a/fc/0474efcbb590ff8628830e9aaec5f1831594874360e3251f1fdec31d07a3/coverage-7.13.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53", size = 262069, upload-time = "2025-12-28T15:41:58.093Z" }, - { url = "https://files.pythonhosted.org/packages/88/4f/3c159b7953db37a7b44c0eab8a95c37d1aa4257c47b4602c04022d5cb975/coverage-7.13.1-cp313-cp313t-win32.whl", hash = "sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842", size = 222184, upload-time = "2025-12-28T15:41:59.763Z" }, - { url = "https://files.pythonhosted.org/packages/58/a5/6b57d28f81417f9335774f20679d9d13b9a8fb90cd6160957aa3b54a2379/coverage-7.13.1-cp313-cp313t-win_amd64.whl", hash = "sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2", size = 223250, upload-time = "2025-12-28T15:42:01.52Z" }, - { url = "https://files.pythonhosted.org/packages/81/7c/160796f3b035acfbb58be80e02e484548595aa67e16a6345e7910ace0a38/coverage-7.13.1-cp313-cp313t-win_arm64.whl", hash = "sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09", size = 221521, upload-time = "2025-12-28T15:42:03.275Z" }, - { url = "https://files.pythonhosted.org/packages/aa/8e/ba0e597560c6563fc0adb902fda6526df5d4aa73bb10adf0574d03bd2206/coverage-7.13.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894", size = 218996, upload-time = "2025-12-28T15:42:04.978Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8e/764c6e116f4221dc7aa26c4061181ff92edb9c799adae6433d18eeba7a14/coverage-7.13.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a", size = 219326, upload-time = "2025-12-28T15:42:06.691Z" }, - { url = "https://files.pythonhosted.org/packages/4f/a6/6130dc6d8da28cdcbb0f2bf8865aeca9b157622f7c0031e48c6cf9a0e591/coverage-7.13.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f", size = 250374, upload-time = "2025-12-28T15:42:08.786Z" }, - { url = "https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909", size = 252882, upload-time = "2025-12-28T15:42:10.515Z" }, - { url = "https://files.pythonhosted.org/packages/cd/b2/9808766d082e6a4d59eb0cc881a57fc1600eb2c5882813eefff8254f71b5/coverage-7.13.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4", size = 254218, upload-time = "2025-12-28T15:42:12.208Z" }, - { url = "https://files.pythonhosted.org/packages/44/ea/52a985bb447c871cb4d2e376e401116520991b597c85afdde1ea9ef54f2c/coverage-7.13.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75", size = 250391, upload-time = "2025-12-28T15:42:14.21Z" }, - { url = "https://files.pythonhosted.org/packages/7f/1d/125b36cc12310718873cfc8209ecfbc1008f14f4f5fa0662aa608e579353/coverage-7.13.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9", size = 252239, upload-time = "2025-12-28T15:42:16.292Z" }, - { url = "https://files.pythonhosted.org/packages/6a/16/10c1c164950cade470107f9f14bbac8485f8fb8515f515fca53d337e4a7f/coverage-7.13.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465", size = 250196, upload-time = "2025-12-28T15:42:18.54Z" }, - { url = "https://files.pythonhosted.org/packages/2a/c6/cd860fac08780c6fd659732f6ced1b40b79c35977c1356344e44d72ba6c4/coverage-7.13.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864", size = 250008, upload-time = "2025-12-28T15:42:20.365Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3a/a8c58d3d38f82a5711e1e0a67268362af48e1a03df27c03072ac30feefcf/coverage-7.13.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9", size = 251671, upload-time = "2025-12-28T15:42:22.114Z" }, - { url = "https://files.pythonhosted.org/packages/f0/bc/fd4c1da651d037a1e3d53e8cb3f8182f4b53271ffa9a95a2e211bacc0349/coverage-7.13.1-cp314-cp314-win32.whl", hash = "sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5", size = 221777, upload-time = "2025-12-28T15:42:23.919Z" }, - { url = "https://files.pythonhosted.org/packages/4b/50/71acabdc8948464c17e90b5ffd92358579bd0910732c2a1c9537d7536aa6/coverage-7.13.1-cp314-cp314-win_amd64.whl", hash = "sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a", size = 222592, upload-time = "2025-12-28T15:42:25.619Z" }, - { url = "https://files.pythonhosted.org/packages/f7/c8/a6fb943081bb0cc926499c7907731a6dc9efc2cbdc76d738c0ab752f1a32/coverage-7.13.1-cp314-cp314-win_arm64.whl", hash = "sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0", size = 221169, upload-time = "2025-12-28T15:42:27.629Z" }, - { url = "https://files.pythonhosted.org/packages/16/61/d5b7a0a0e0e40d62e59bc8c7aa1afbd86280d82728ba97f0673b746b78e2/coverage-7.13.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a", size = 219730, upload-time = "2025-12-28T15:42:29.306Z" }, - { url = "https://files.pythonhosted.org/packages/a3/2c/8881326445fd071bb49514d1ce97d18a46a980712b51fee84f9ab42845b4/coverage-7.13.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6", size = 220001, upload-time = "2025-12-28T15:42:31.319Z" }, - { url = "https://files.pythonhosted.org/packages/b5/d7/50de63af51dfa3a7f91cc37ad8fcc1e244b734232fbc8b9ab0f3c834a5cd/coverage-7.13.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673", size = 261370, upload-time = "2025-12-28T15:42:32.992Z" }, - { url = "https://files.pythonhosted.org/packages/e1/2c/d31722f0ec918fd7453b2758312729f645978d212b410cd0f7c2aed88a94/coverage-7.13.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5", size = 263485, upload-time = "2025-12-28T15:42:34.759Z" }, - { url = "https://files.pythonhosted.org/packages/fa/7a/2c114fa5c5fc08ba0777e4aec4c97e0b4a1afcb69c75f1f54cff78b073ab/coverage-7.13.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d", size = 265890, upload-time = "2025-12-28T15:42:36.517Z" }, - { url = "https://files.pythonhosted.org/packages/65/d9/f0794aa1c74ceabc780fe17f6c338456bbc4e96bd950f2e969f48ac6fb20/coverage-7.13.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8", size = 260445, upload-time = "2025-12-28T15:42:38.646Z" }, - { url = "https://files.pythonhosted.org/packages/49/23/184b22a00d9bb97488863ced9454068c79e413cb23f472da6cbddc6cfc52/coverage-7.13.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486", size = 263357, upload-time = "2025-12-28T15:42:40.788Z" }, - { url = "https://files.pythonhosted.org/packages/7d/bd/58af54c0c9199ea4190284f389005779d7daf7bf3ce40dcd2d2b2f96da69/coverage-7.13.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564", size = 260959, upload-time = "2025-12-28T15:42:42.808Z" }, - { url = "https://files.pythonhosted.org/packages/4b/2a/6839294e8f78a4891bf1df79d69c536880ba2f970d0ff09e7513d6e352e9/coverage-7.13.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7", size = 259792, upload-time = "2025-12-28T15:42:44.818Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c3/528674d4623283310ad676c5af7414b9850ab6d55c2300e8aa4b945ec554/coverage-7.13.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416", size = 262123, upload-time = "2025-12-28T15:42:47.108Z" }, - { url = "https://files.pythonhosted.org/packages/06/c5/8c0515692fb4c73ac379d8dc09b18eaf0214ecb76ea6e62467ba7a1556ff/coverage-7.13.1-cp314-cp314t-win32.whl", hash = "sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f", size = 222562, upload-time = "2025-12-28T15:42:49.144Z" }, - { url = "https://files.pythonhosted.org/packages/05/0e/c0a0c4678cb30dac735811db529b321d7e1c9120b79bd728d4f4d6b010e9/coverage-7.13.1-cp314-cp314t-win_amd64.whl", hash = "sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79", size = 223670, upload-time = "2025-12-28T15:42:51.218Z" }, - { url = "https://files.pythonhosted.org/packages/f5/5f/b177aa0011f354abf03a8f30a85032686d290fdeed4222b27d36b4372a50/coverage-7.13.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4", size = 221707, upload-time = "2025-12-28T15:42:53.034Z" }, - { url = "https://files.pythonhosted.org/packages/cc/48/d9f421cb8da5afaa1a64570d9989e00fb7955e6acddc5a12979f7666ef60/coverage-7.13.1-py3-none-any.whl", hash = "sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573", size = 210722, upload-time = "2025-12-28T15:42:54.901Z" }, +version = "7.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/49/349848445b0e53660e258acbcc9b0d014895b6739237920886672240f84b/coverage-7.13.2.tar.gz", hash = "sha256:044c6951ec37146b72a50cc81ef02217d27d4c3640efd2640311393cbbf143d3", size = 826523, upload-time = "2026-01-25T13:00:04.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/2d/63e37369c8e81a643afe54f76073b020f7b97ddbe698c5c944b51b0a2bc5/coverage-7.13.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4af3b01763909f477ea17c962e2cca8f39b350a4e46e3a30838b2c12e31b81b", size = 218842, upload-time = "2026-01-25T12:57:15.3Z" }, + { url = "https://files.pythonhosted.org/packages/57/06/86ce882a8d58cbcb3030e298788988e618da35420d16a8c66dac34f138d0/coverage-7.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:36393bd2841fa0b59498f75466ee9bdec4f770d3254f031f23e8fd8e140ffdd2", size = 219360, upload-time = "2026-01-25T12:57:17.572Z" }, + { url = "https://files.pythonhosted.org/packages/cd/84/70b0eb1ee19ca4ef559c559054c59e5b2ae4ec9af61398670189e5d276e9/coverage-7.13.2-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9cc7573518b7e2186bd229b1a0fe24a807273798832c27032c4510f47ffdb896", size = 246123, upload-time = "2026-01-25T12:57:19.087Z" }, + { url = "https://files.pythonhosted.org/packages/35/fb/05b9830c2e8275ebc031e0019387cda99113e62bb500ab328bb72578183b/coverage-7.13.2-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ca9566769b69a5e216a4e176d54b9df88f29d750c5b78dbb899e379b4e14b30c", size = 247930, upload-time = "2026-01-25T12:57:20.929Z" }, + { url = "https://files.pythonhosted.org/packages/81/aa/3f37858ca2eed4f09b10ca3c6ddc9041be0a475626cd7fd2712f4a2d526f/coverage-7.13.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c9bdea644e94fd66d75a6f7e9a97bb822371e1fe7eadae2cacd50fcbc28e4dc", size = 249804, upload-time = "2026-01-25T12:57:22.904Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b3/c904f40c56e60a2d9678a5ee8df3d906d297d15fb8bec5756c3b0a67e2df/coverage-7.13.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5bd447332ec4f45838c1ad42268ce21ca87c40deb86eabd59888859b66be22a5", size = 246815, upload-time = "2026-01-25T12:57:24.314Z" }, + { url = "https://files.pythonhosted.org/packages/41/91/ddc1c5394ca7fd086342486440bfdd6b9e9bda512bf774599c7c7a0081e0/coverage-7.13.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7c79ad5c28a16a1277e1187cf83ea8dafdcc689a784228a7d390f19776db7c31", size = 247843, upload-time = "2026-01-25T12:57:26.544Z" }, + { url = "https://files.pythonhosted.org/packages/87/d2/cdff8f4cd33697883c224ea8e003e9c77c0f1a837dc41d95a94dd26aad67/coverage-7.13.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:76e06ccacd1fb6ada5d076ed98a8c6f66e2e6acd3df02819e2ee29fd637b76ad", size = 245850, upload-time = "2026-01-25T12:57:28.507Z" }, + { url = "https://files.pythonhosted.org/packages/f5/42/e837febb7866bf2553ab53dd62ed52f9bb36d60c7e017c55376ad21fbb05/coverage-7.13.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:49d49e9a5e9f4dc3d3dac95278a020afa6d6bdd41f63608a76fa05a719d5b66f", size = 246116, upload-time = "2026-01-25T12:57:30.16Z" }, + { url = "https://files.pythonhosted.org/packages/09/b1/4a3f935d7df154df02ff4f71af8d61298d713a7ba305d050ae475bfbdde2/coverage-7.13.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ed2bce0e7bfa53f7b0b01c722da289ef6ad4c18ebd52b1f93704c21f116360c8", size = 246720, upload-time = "2026-01-25T12:57:32.165Z" }, + { url = "https://files.pythonhosted.org/packages/e1/fe/538a6fd44c515f1c5197a3f078094cbaf2ce9f945df5b44e29d95c864bff/coverage-7.13.2-cp310-cp310-win32.whl", hash = "sha256:1574983178b35b9af4db4a9f7328a18a14a0a0ce76ffaa1c1bacb4cc82089a7c", size = 221465, upload-time = "2026-01-25T12:57:33.511Z" }, + { url = "https://files.pythonhosted.org/packages/5e/09/4b63a024295f326ec1a40ec8def27799300ce8775b1cbf0d33b1790605c4/coverage-7.13.2-cp310-cp310-win_amd64.whl", hash = "sha256:a360a8baeb038928ceb996f5623a4cd508728f8f13e08d4e96ce161702f3dd99", size = 222397, upload-time = "2026-01-25T12:57:34.927Z" }, + { url = "https://files.pythonhosted.org/packages/6c/01/abca50583a8975bb6e1c59eff67ed8e48bb127c07dad5c28d9e96ccc09ec/coverage-7.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:060ebf6f2c51aff5ba38e1f43a2095e087389b1c69d559fde6049a4b0001320e", size = 218971, upload-time = "2026-01-25T12:57:36.953Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0e/b6489f344d99cd1e5b4d5e1be52dfd3f8a3dc5112aa6c33948da8cabad4e/coverage-7.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1ea8ca9db5e7469cd364552985e15911548ea5b69c48a17291f0cac70484b2e", size = 219473, upload-time = "2026-01-25T12:57:38.934Z" }, + { url = "https://files.pythonhosted.org/packages/17/11/db2f414915a8e4ec53f60b17956c27f21fb68fcf20f8a455ce7c2ccec638/coverage-7.13.2-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b780090d15fd58f07cf2011943e25a5f0c1c894384b13a216b6c86c8a8a7c508", size = 249896, upload-time = "2026-01-25T12:57:40.365Z" }, + { url = "https://files.pythonhosted.org/packages/80/06/0823fe93913663c017e508e8810c998c8ebd3ec2a5a85d2c3754297bdede/coverage-7.13.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:88a800258d83acb803c38175b4495d293656d5fac48659c953c18e5f539a274b", size = 251810, upload-time = "2026-01-25T12:57:42.045Z" }, + { url = "https://files.pythonhosted.org/packages/61/dc/b151c3cc41b28cdf7f0166c5fa1271cbc305a8ec0124cce4b04f74791a18/coverage-7.13.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6326e18e9a553e674d948536a04a80d850a5eeefe2aae2e6d7cf05d54046c01b", size = 253920, upload-time = "2026-01-25T12:57:44.026Z" }, + { url = "https://files.pythonhosted.org/packages/2d/35/e83de0556e54a4729a2b94ea816f74ce08732e81945024adee46851c2264/coverage-7.13.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:59562de3f797979e1ff07c587e2ac36ba60ca59d16c211eceaa579c266c5022f", size = 250025, upload-time = "2026-01-25T12:57:45.624Z" }, + { url = "https://files.pythonhosted.org/packages/39/67/af2eb9c3926ce3ea0d58a0d2516fcbdacf7a9fc9559fe63076beaf3f2596/coverage-7.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:27ba1ed6f66b0e2d61bfa78874dffd4f8c3a12f8e2b5410e515ab345ba7bc9c3", size = 251612, upload-time = "2026-01-25T12:57:47.713Z" }, + { url = "https://files.pythonhosted.org/packages/26/62/5be2e25f3d6c711d23b71296f8b44c978d4c8b4e5b26871abfc164297502/coverage-7.13.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8be48da4d47cc68754ce643ea50b3234557cbefe47c2f120495e7bd0a2756f2b", size = 249670, upload-time = "2026-01-25T12:57:49.378Z" }, + { url = "https://files.pythonhosted.org/packages/b3/51/400d1b09a8344199f9b6a6fc1868005d766b7ea95e7882e494fa862ca69c/coverage-7.13.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2a47a4223d3361b91176aedd9d4e05844ca67d7188456227b6bf5e436630c9a1", size = 249395, upload-time = "2026-01-25T12:57:50.86Z" }, + { url = "https://files.pythonhosted.org/packages/e0/36/f02234bc6e5230e2f0a63fd125d0a2093c73ef20fdf681c7af62a140e4e7/coverage-7.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c6f141b468740197d6bd38f2b26ade124363228cc3f9858bd9924ab059e00059", size = 250298, upload-time = "2026-01-25T12:57:52.287Z" }, + { url = "https://files.pythonhosted.org/packages/b0/06/713110d3dd3151b93611c9cbfc65c15b4156b44f927fced49ac0b20b32a4/coverage-7.13.2-cp311-cp311-win32.whl", hash = "sha256:89567798404af067604246e01a49ef907d112edf2b75ef814b1364d5ce267031", size = 221485, upload-time = "2026-01-25T12:57:53.876Z" }, + { url = "https://files.pythonhosted.org/packages/16/0c/3ae6255fa1ebcb7dec19c9a59e85ef5f34566d1265c70af5b2fc981da834/coverage-7.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:21dd57941804ae2ac7e921771a5e21bbf9aabec317a041d164853ad0a96ce31e", size = 222421, upload-time = "2026-01-25T12:57:55.433Z" }, + { url = "https://files.pythonhosted.org/packages/b5/37/fabc3179af4d61d89ea47bd04333fec735cd5e8b59baad44fed9fc4170d7/coverage-7.13.2-cp311-cp311-win_arm64.whl", hash = "sha256:10758e0586c134a0bafa28f2d37dd2cdb5e4a90de25c0fc0c77dabbad46eca28", size = 221088, upload-time = "2026-01-25T12:57:57.41Z" }, + { url = "https://files.pythonhosted.org/packages/46/39/e92a35f7800222d3f7b2cbb7bbc3b65672ae8d501cb31801b2d2bd7acdf1/coverage-7.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f106b2af193f965d0d3234f3f83fc35278c7fb935dfbde56ae2da3dd2c03b84d", size = 219142, upload-time = "2026-01-25T12:58:00.448Z" }, + { url = "https://files.pythonhosted.org/packages/45/7a/8bf9e9309c4c996e65c52a7c5a112707ecdd9fbaf49e10b5a705a402bbb4/coverage-7.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78f45d21dc4d5d6bd29323f0320089ef7eae16e4bef712dff79d184fa7330af3", size = 219503, upload-time = "2026-01-25T12:58:02.451Z" }, + { url = "https://files.pythonhosted.org/packages/87/93/17661e06b7b37580923f3f12406ac91d78aeed293fb6da0b69cc7957582f/coverage-7.13.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fae91dfecd816444c74531a9c3d6ded17a504767e97aa674d44f638107265b99", size = 251006, upload-time = "2026-01-25T12:58:04.059Z" }, + { url = "https://files.pythonhosted.org/packages/12/f0/f9e59fb8c310171497f379e25db060abef9fa605e09d63157eebec102676/coverage-7.13.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:264657171406c114787b441484de620e03d8f7202f113d62fcd3d9688baa3e6f", size = 253750, upload-time = "2026-01-25T12:58:05.574Z" }, + { url = "https://files.pythonhosted.org/packages/e5/b1/1935e31add2232663cf7edd8269548b122a7d100047ff93475dbaaae673e/coverage-7.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae47d8dcd3ded0155afbb59c62bd8ab07ea0fd4902e1c40567439e6db9dcaf2f", size = 254862, upload-time = "2026-01-25T12:58:07.647Z" }, + { url = "https://files.pythonhosted.org/packages/af/59/b5e97071ec13df5f45da2b3391b6cdbec78ba20757bc92580a5b3d5fa53c/coverage-7.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8a0b33e9fd838220b007ce8f299114d406c1e8edb21336af4c97a26ecfd185aa", size = 251420, upload-time = "2026-01-25T12:58:09.309Z" }, + { url = "https://files.pythonhosted.org/packages/3f/75/9495932f87469d013dc515fb0ce1aac5fa97766f38f6b1a1deb1ee7b7f3a/coverage-7.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b3becbea7f3ce9a2d4d430f223ec15888e4deb31395840a79e916368d6004cce", size = 252786, upload-time = "2026-01-25T12:58:10.909Z" }, + { url = "https://files.pythonhosted.org/packages/6a/59/af550721f0eb62f46f7b8cb7e6f1860592189267b1c411a4e3a057caacee/coverage-7.13.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f819c727a6e6eeb8711e4ce63d78c620f69630a2e9d53bc95ca5379f57b6ba94", size = 250928, upload-time = "2026-01-25T12:58:12.449Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b1/21b4445709aae500be4ab43bbcfb4e53dc0811c3396dcb11bf9f23fd0226/coverage-7.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:4f7b71757a3ab19f7ba286e04c181004c1d61be921795ee8ba6970fd0ec91da5", size = 250496, upload-time = "2026-01-25T12:58:14.047Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b1/0f5d89dfe0392990e4f3980adbde3eb34885bc1effb2dc369e0bf385e389/coverage-7.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b7fc50d2afd2e6b4f6f2f403b70103d280a8e0cb35320cbbe6debcda02a1030b", size = 252373, upload-time = "2026-01-25T12:58:15.976Z" }, + { url = "https://files.pythonhosted.org/packages/01/c9/0cf1a6a57a9968cc049a6b896693faa523c638a5314b1fc374eb2b2ac904/coverage-7.13.2-cp312-cp312-win32.whl", hash = "sha256:292250282cf9bcf206b543d7608bda17ca6fc151f4cbae949fc7e115112fbd41", size = 221696, upload-time = "2026-01-25T12:58:17.517Z" }, + { url = "https://files.pythonhosted.org/packages/4d/05/d7540bf983f09d32803911afed135524570f8c47bb394bf6206c1dc3a786/coverage-7.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:eeea10169fac01549a7921d27a3e517194ae254b542102267bef7a93ed38c40e", size = 222504, upload-time = "2026-01-25T12:58:19.115Z" }, + { url = "https://files.pythonhosted.org/packages/15/8b/1a9f037a736ced0a12aacf6330cdaad5008081142a7070bc58b0f7930cbc/coverage-7.13.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a5b567f0b635b592c917f96b9a9cb3dbd4c320d03f4bf94e9084e494f2e8894", size = 221120, upload-time = "2026-01-25T12:58:21.334Z" }, + { url = "https://files.pythonhosted.org/packages/a7/f0/3d3eac7568ab6096ff23791a526b0048a1ff3f49d0e236b2af6fb6558e88/coverage-7.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ed75de7d1217cf3b99365d110975f83af0528c849ef5180a12fd91b5064df9d6", size = 219168, upload-time = "2026-01-25T12:58:23.376Z" }, + { url = "https://files.pythonhosted.org/packages/a3/a6/f8b5cfeddbab95fdef4dcd682d82e5dcff7a112ced57a959f89537ee9995/coverage-7.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:97e596de8fa9bada4d88fde64a3f4d37f1b6131e4faa32bad7808abc79887ddc", size = 219537, upload-time = "2026-01-25T12:58:24.932Z" }, + { url = "https://files.pythonhosted.org/packages/7b/e6/8d8e6e0c516c838229d1e41cadcec91745f4b1031d4db17ce0043a0423b4/coverage-7.13.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:68c86173562ed4413345410c9480a8d64864ac5e54a5cda236748031e094229f", size = 250528, upload-time = "2026-01-25T12:58:26.567Z" }, + { url = "https://files.pythonhosted.org/packages/8e/78/befa6640f74092b86961f957f26504c8fba3d7da57cc2ab7407391870495/coverage-7.13.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7be4d613638d678b2b3773b8f687537b284d7074695a43fe2fbbfc0e31ceaed1", size = 253132, upload-time = "2026-01-25T12:58:28.251Z" }, + { url = "https://files.pythonhosted.org/packages/9d/10/1630db1edd8ce675124a2ee0f7becc603d2bb7b345c2387b4b95c6907094/coverage-7.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d7f63ce526a96acd0e16c4af8b50b64334239550402fb1607ce6a584a6d62ce9", size = 254374, upload-time = "2026-01-25T12:58:30.294Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1d/0d9381647b1e8e6d310ac4140be9c428a0277330991e0c35bdd751e338a4/coverage-7.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:406821f37f864f968e29ac14c3fccae0fec9fdeba48327f0341decf4daf92d7c", size = 250762, upload-time = "2026-01-25T12:58:32.036Z" }, + { url = "https://files.pythonhosted.org/packages/43/e4/5636dfc9a7c871ee8776af83ee33b4c26bc508ad6cee1e89b6419a366582/coverage-7.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ee68e5a4e3e5443623406b905db447dceddffee0dceb39f4e0cd9ec2a35004b5", size = 252502, upload-time = "2026-01-25T12:58:33.961Z" }, + { url = "https://files.pythonhosted.org/packages/02/2a/7ff2884d79d420cbb2d12fed6fff727b6d0ef27253140d3cdbbd03187ee0/coverage-7.13.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2ee0e58cca0c17dd9c6c1cdde02bb705c7b3fbfa5f3b0b5afeda20d4ebff8ef4", size = 250463, upload-time = "2026-01-25T12:58:35.529Z" }, + { url = "https://files.pythonhosted.org/packages/91/c0/ba51087db645b6c7261570400fc62c89a16278763f36ba618dc8657a187b/coverage-7.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6e5bbb5018bf76a56aabdb64246b5288d5ae1b7d0dd4d0534fe86df2c2992d1c", size = 250288, upload-time = "2026-01-25T12:58:37.226Z" }, + { url = "https://files.pythonhosted.org/packages/03/07/44e6f428551c4d9faf63ebcefe49b30e5c89d1be96f6a3abd86a52da9d15/coverage-7.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a55516c68ef3e08e134e818d5e308ffa6b1337cc8b092b69b24287bf07d38e31", size = 252063, upload-time = "2026-01-25T12:58:38.821Z" }, + { url = "https://files.pythonhosted.org/packages/c2/67/35b730ad7e1859dd57e834d1bc06080d22d2f87457d53f692fce3f24a5a9/coverage-7.13.2-cp313-cp313-win32.whl", hash = "sha256:5b20211c47a8abf4abc3319d8ce2464864fa9f30c5fcaf958a3eed92f4f1fef8", size = 221716, upload-time = "2026-01-25T12:58:40.484Z" }, + { url = "https://files.pythonhosted.org/packages/0d/82/e5fcf5a97c72f45fc14829237a6550bf49d0ab882ac90e04b12a69db76b4/coverage-7.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:14f500232e521201cf031549fb1ebdfc0a40f401cf519157f76c397e586c3beb", size = 222522, upload-time = "2026-01-25T12:58:43.247Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f1/25d7b2f946d239dd2d6644ca2cc060d24f97551e2af13b6c24c722ae5f97/coverage-7.13.2-cp313-cp313-win_arm64.whl", hash = "sha256:9779310cb5a9778a60c899f075a8514c89fa6d10131445c2207fc893e0b14557", size = 221145, upload-time = "2026-01-25T12:58:45Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f7/080376c029c8f76fadfe43911d0daffa0cbdc9f9418a0eead70c56fb7f4b/coverage-7.13.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e64fa5a1e41ce5df6b547cbc3d3699381c9e2c2c369c67837e716ed0f549d48e", size = 219861, upload-time = "2026-01-25T12:58:46.586Z" }, + { url = "https://files.pythonhosted.org/packages/42/11/0b5e315af5ab35f4c4a70e64d3314e4eec25eefc6dec13be3a7d5ffe8ac5/coverage-7.13.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b01899e82a04085b6561eb233fd688474f57455e8ad35cd82286463ba06332b7", size = 220207, upload-time = "2026-01-25T12:58:48.277Z" }, + { url = "https://files.pythonhosted.org/packages/b2/0c/0874d0318fb1062117acbef06a09cf8b63f3060c22265adaad24b36306b7/coverage-7.13.2-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:838943bea48be0e2768b0cf7819544cdedc1bbb2f28427eabb6eb8c9eb2285d3", size = 261504, upload-time = "2026-01-25T12:58:49.904Z" }, + { url = "https://files.pythonhosted.org/packages/83/5e/1cd72c22ecb30751e43a72f40ba50fcef1b7e93e3ea823bd9feda8e51f9a/coverage-7.13.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:93d1d25ec2b27e90bcfef7012992d1f5121b51161b8bffcda756a816cf13c2c3", size = 263582, upload-time = "2026-01-25T12:58:51.582Z" }, + { url = "https://files.pythonhosted.org/packages/9b/da/8acf356707c7a42df4d0657020308e23e5a07397e81492640c186268497c/coverage-7.13.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93b57142f9621b0d12349c43fc7741fe578e4bc914c1e5a54142856cfc0bf421", size = 266008, upload-time = "2026-01-25T12:58:53.234Z" }, + { url = "https://files.pythonhosted.org/packages/41/41/ea1730af99960309423c6ea8d6a4f1fa5564b2d97bd1d29dda4b42611f04/coverage-7.13.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f06799ae1bdfff7ccb8665d75f8291c69110ba9585253de254688aa8a1ccc6c5", size = 260762, upload-time = "2026-01-25T12:58:55.372Z" }, + { url = "https://files.pythonhosted.org/packages/22/fa/02884d2080ba71db64fdc127b311db60e01fe6ba797d9c8363725e39f4d5/coverage-7.13.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7f9405ab4f81d490811b1d91c7a20361135a2df4c170e7f0b747a794da5b7f23", size = 263571, upload-time = "2026-01-25T12:58:57.52Z" }, + { url = "https://files.pythonhosted.org/packages/d2/6b/4083aaaeba9b3112f55ac57c2ce7001dc4d8fa3fcc228a39f09cc84ede27/coverage-7.13.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f9ab1d5b86f8fbc97a5b3cd6280a3fd85fef3b028689d8a2c00918f0d82c728c", size = 261200, upload-time = "2026-01-25T12:58:59.255Z" }, + { url = "https://files.pythonhosted.org/packages/e9/d2/aea92fa36d61955e8c416ede9cf9bf142aa196f3aea214bb67f85235a050/coverage-7.13.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:f674f59712d67e841525b99e5e2b595250e39b529c3bda14764e4f625a3fa01f", size = 260095, upload-time = "2026-01-25T12:59:01.066Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ae/04ffe96a80f107ea21b22b2367175c621da920063260a1c22f9452fd7866/coverage-7.13.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c6cadac7b8ace1ba9144feb1ae3cb787a6065ba6d23ffc59a934b16406c26573", size = 262284, upload-time = "2026-01-25T12:59:02.802Z" }, + { url = "https://files.pythonhosted.org/packages/1c/7a/6f354dcd7dfc41297791d6fb4e0d618acb55810bde2c1fd14b3939e05c2b/coverage-7.13.2-cp313-cp313t-win32.whl", hash = "sha256:14ae4146465f8e6e6253eba0cccd57423e598a4cb925958b240c805300918343", size = 222389, upload-time = "2026-01-25T12:59:04.563Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d5/080ad292a4a3d3daf411574be0a1f56d6dee2c4fdf6b005342be9fac807f/coverage-7.13.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9074896edd705a05769e3de0eac0a8388484b503b68863dd06d5e473f874fd47", size = 223450, upload-time = "2026-01-25T12:59:06.677Z" }, + { url = "https://files.pythonhosted.org/packages/88/96/df576fbacc522e9fb8d1c4b7a7fc62eb734be56e2cba1d88d2eabe08ea3f/coverage-7.13.2-cp313-cp313t-win_arm64.whl", hash = "sha256:69e526e14f3f854eda573d3cf40cffd29a1a91c684743d904c33dbdcd0e0f3e7", size = 221707, upload-time = "2026-01-25T12:59:08.363Z" }, + { url = "https://files.pythonhosted.org/packages/55/53/1da9e51a0775634b04fcc11eb25c002fc58ee4f92ce2e8512f94ac5fc5bf/coverage-7.13.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:387a825f43d680e7310e6f325b2167dd093bc8ffd933b83e9aa0983cf6e0a2ef", size = 219213, upload-time = "2026-01-25T12:59:11.909Z" }, + { url = "https://files.pythonhosted.org/packages/46/35/b3caac3ebbd10230fea5a33012b27d19e999a17c9285c4228b4b2e35b7da/coverage-7.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f0d7fea9d8e5d778cd5a9e8fc38308ad688f02040e883cdc13311ef2748cb40f", size = 219549, upload-time = "2026-01-25T12:59:13.638Z" }, + { url = "https://files.pythonhosted.org/packages/76/9c/e1cf7def1bdc72c1907e60703983a588f9558434a2ff94615747bd73c192/coverage-7.13.2-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e080afb413be106c95c4ee96b4fffdc9e2fa56a8bbf90b5c0918e5c4449412f5", size = 250586, upload-time = "2026-01-25T12:59:15.808Z" }, + { url = "https://files.pythonhosted.org/packages/ba/49/f54ec02ed12be66c8d8897270505759e057b0c68564a65c429ccdd1f139e/coverage-7.13.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a7fc042ba3c7ce25b8a9f097eb0f32a5ce1ccdb639d9eec114e26def98e1f8a4", size = 253093, upload-time = "2026-01-25T12:59:17.491Z" }, + { url = "https://files.pythonhosted.org/packages/fb/5e/aaf86be3e181d907e23c0f61fccaeb38de8e6f6b47aed92bf57d8fc9c034/coverage-7.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d0ba505e021557f7f8173ee8cd6b926373d8653e5ff7581ae2efce1b11ef4c27", size = 254446, upload-time = "2026-01-25T12:59:19.752Z" }, + { url = "https://files.pythonhosted.org/packages/28/c8/a5fa01460e2d75b0c853b392080d6829d3ca8b5ab31e158fa0501bc7c708/coverage-7.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7de326f80e3451bd5cc7239ab46c73ddb658fe0b7649476bc7413572d36cd548", size = 250615, upload-time = "2026-01-25T12:59:21.928Z" }, + { url = "https://files.pythonhosted.org/packages/86/0b/6d56315a55f7062bb66410732c24879ccb2ec527ab6630246de5fe45a1df/coverage-7.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:abaea04f1e7e34841d4a7b343904a3f59481f62f9df39e2cd399d69a187a9660", size = 252452, upload-time = "2026-01-25T12:59:23.592Z" }, + { url = "https://files.pythonhosted.org/packages/30/19/9bc550363ebc6b0ea121977ee44d05ecd1e8bf79018b8444f1028701c563/coverage-7.13.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9f93959ee0c604bccd8e0697be21de0887b1f73efcc3aa73a3ec0fd13feace92", size = 250418, upload-time = "2026-01-25T12:59:25.392Z" }, + { url = "https://files.pythonhosted.org/packages/1f/53/580530a31ca2f0cc6f07a8f2ab5460785b02bb11bdf815d4c4d37a4c5169/coverage-7.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:13fe81ead04e34e105bf1b3c9f9cdf32ce31736ee5d90a8d2de02b9d3e1bcb82", size = 250231, upload-time = "2026-01-25T12:59:27.888Z" }, + { url = "https://files.pythonhosted.org/packages/e2/42/dd9093f919dc3088cb472893651884bd675e3df3d38a43f9053656dca9a2/coverage-7.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d6d16b0f71120e365741bca2cb473ca6fe38930bc5431c5e850ba949f708f892", size = 251888, upload-time = "2026-01-25T12:59:29.636Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a6/0af4053e6e819774626e133c3d6f70fae4d44884bfc4b126cb647baee8d3/coverage-7.13.2-cp314-cp314-win32.whl", hash = "sha256:9b2f4714bb7d99ba3790ee095b3b4ac94767e1347fe424278a0b10acb3ff04fe", size = 221968, upload-time = "2026-01-25T12:59:31.424Z" }, + { url = "https://files.pythonhosted.org/packages/c4/cc/5aff1e1f80d55862442855517bb8ad8ad3a68639441ff6287dde6a58558b/coverage-7.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:e4121a90823a063d717a96e0a0529c727fb31ea889369a0ee3ec00ed99bf6859", size = 222783, upload-time = "2026-01-25T12:59:33.118Z" }, + { url = "https://files.pythonhosted.org/packages/de/20/09abafb24f84b3292cc658728803416c15b79f9ee5e68d25238a895b07d9/coverage-7.13.2-cp314-cp314-win_arm64.whl", hash = "sha256:6873f0271b4a15a33e7590f338d823f6f66f91ed147a03938d7ce26efd04eee6", size = 221348, upload-time = "2026-01-25T12:59:34.939Z" }, + { url = "https://files.pythonhosted.org/packages/b6/60/a3820c7232db63be060e4019017cd3426751c2699dab3c62819cdbcea387/coverage-7.13.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f61d349f5b7cd95c34017f1927ee379bfbe9884300d74e07cf630ccf7a610c1b", size = 219950, upload-time = "2026-01-25T12:59:36.624Z" }, + { url = "https://files.pythonhosted.org/packages/fd/37/e4ef5975fdeb86b1e56db9a82f41b032e3d93a840ebaf4064f39e770d5c5/coverage-7.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a43d34ce714f4ca674c0d90beb760eb05aad906f2c47580ccee9da8fe8bfb417", size = 220209, upload-time = "2026-01-25T12:59:38.339Z" }, + { url = "https://files.pythonhosted.org/packages/54/df/d40e091d00c51adca1e251d3b60a8b464112efa3004949e96a74d7c19a64/coverage-7.13.2-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bff1b04cb9d4900ce5c56c4942f047dc7efe57e2608cb7c3c8936e9970ccdbee", size = 261576, upload-time = "2026-01-25T12:59:40.446Z" }, + { url = "https://files.pythonhosted.org/packages/c5/44/5259c4bed54e3392e5c176121af9f71919d96dde853386e7730e705f3520/coverage-7.13.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6ae99e4560963ad8e163e819e5d77d413d331fd00566c1e0856aa252303552c1", size = 263704, upload-time = "2026-01-25T12:59:42.346Z" }, + { url = "https://files.pythonhosted.org/packages/16/bd/ae9f005827abcbe2c70157459ae86053971c9fa14617b63903abbdce26d9/coverage-7.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e79a8c7d461820257d9aa43716c4efc55366d7b292e46b5b37165be1d377405d", size = 266109, upload-time = "2026-01-25T12:59:44.073Z" }, + { url = "https://files.pythonhosted.org/packages/a2/c0/8e279c1c0f5b1eaa3ad9b0fb7a5637fc0379ea7d85a781c0fe0bb3cfc2ab/coverage-7.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:060ee84f6a769d40c492711911a76811b4befb6fba50abb450371abb720f5bd6", size = 260686, upload-time = "2026-01-25T12:59:45.804Z" }, + { url = "https://files.pythonhosted.org/packages/b2/47/3a8112627e9d863e7cddd72894171c929e94491a597811725befdcd76bce/coverage-7.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bca209d001fd03ea2d978f8a4985093240a355c93078aee3f799852c23f561a", size = 263568, upload-time = "2026-01-25T12:59:47.929Z" }, + { url = "https://files.pythonhosted.org/packages/92/bc/7ea367d84afa3120afc3ce6de294fd2dcd33b51e2e7fbe4bbfd200f2cb8c/coverage-7.13.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:6b8092aa38d72f091db61ef83cb66076f18f02da3e1a75039a4f218629600e04", size = 261174, upload-time = "2026-01-25T12:59:49.717Z" }, + { url = "https://files.pythonhosted.org/packages/33/b7/f1092dcecb6637e31cc2db099581ee5c61a17647849bae6b8261a2b78430/coverage-7.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4a3158dc2dcce5200d91ec28cd315c999eebff355437d2765840555d765a6e5f", size = 260017, upload-time = "2026-01-25T12:59:51.463Z" }, + { url = "https://files.pythonhosted.org/packages/2b/cd/f3d07d4b95fbe1a2ef0958c15da614f7e4f557720132de34d2dc3aa7e911/coverage-7.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3973f353b2d70bd9796cc12f532a05945232ccae966456c8ed7034cb96bbfd6f", size = 262337, upload-time = "2026-01-25T12:59:53.407Z" }, + { url = "https://files.pythonhosted.org/packages/e0/db/b0d5b2873a07cb1e06a55d998697c0a5a540dcefbf353774c99eb3874513/coverage-7.13.2-cp314-cp314t-win32.whl", hash = "sha256:79f6506a678a59d4ded048dc72f1859ebede8ec2b9a2d509ebe161f01c2879d3", size = 222749, upload-time = "2026-01-25T12:59:56.316Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2f/838a5394c082ac57d85f57f6aba53093b30d9089781df72412126505716f/coverage-7.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:196bfeabdccc5a020a57d5a368c681e3a6ceb0447d153aeccc1ab4d70a5032ba", size = 223857, upload-time = "2026-01-25T12:59:58.201Z" }, + { url = "https://files.pythonhosted.org/packages/44/d4/b608243e76ead3a4298824b50922b89ef793e50069ce30316a65c1b4d7ef/coverage-7.13.2-cp314-cp314t-win_arm64.whl", hash = "sha256:69269ab58783e090bfbf5b916ab3d188126e22d6070bbfc93098fdd474ef937c", size = 221881, upload-time = "2026-01-25T13:00:00.449Z" }, + { url = "https://files.pythonhosted.org/packages/d2/db/d291e30fdf7ea617a335531e72294e0c723356d7fdde8fba00610a76bda9/coverage-7.13.2-py3-none-any.whl", hash = "sha256:40ce1ea1e25125556d8e76bd0b61500839a07944cc287ac21d5626f3e620cad5", size = 210943, upload-time = "2026-01-25T13:00:02.388Z" }, ] [package.optional-dependencies] @@ -673,11 +697,11 @@ wheels = [ [[package]] name = "dill" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/e1/56027a71e31b02ddc53c7d65b01e68edf64dea2932122fe7746a516f75d5/dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa", size = 187315, upload-time = "2026-01-19T02:36:56.85Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, + { url = "https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d", size = 120019, upload-time = "2026-01-19T02:36:55.663Z" }, ] [[package]] @@ -706,11 +730,37 @@ wheels = [ name = "docutils" version = "0.21.2" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, ] +[[package]] +name = "docutils" +version = "0.22.4" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, +] + [[package]] name = "exceptiongroup" version = "1.3.1" @@ -825,7 +875,8 @@ dependencies = [ { name = "beautifulsoup4" }, { name = "pygments" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "sphinx-basic-ng" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ec/20/5f5ad4da6a5a27c80f2ed2ee9aee3f9e36c66e56e21c00fde467b2f8f88f/furo-2025.12.19.tar.gz", hash = "sha256:188d1f942037d8b37cd3985b955839fea62baa1730087dc29d157677c857e2a7", size = 1661473, upload-time = "2025-12-19T17:34:40.889Z" } @@ -835,51 +886,56 @@ wheels = [ [[package]] name = "greenlet" -version = "3.3.0" +version = "3.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/6a/33d1702184d94106d3cdd7bfb788e19723206fce152e303473ca3b946c7b/greenlet-3.3.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:6f8496d434d5cb2dce025773ba5597f71f5410ae499d5dd9533e0653258cdb3d", size = 273658, upload-time = "2025-12-04T14:23:37.494Z" }, - { url = "https://files.pythonhosted.org/packages/d6/b7/2b5805bbf1907c26e434f4e448cd8b696a0b71725204fa21a211ff0c04a7/greenlet-3.3.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b96dc7eef78fd404e022e165ec55327f935b9b52ff355b067eb4a0267fc1cffb", size = 574810, upload-time = "2025-12-04T14:50:04.154Z" }, - { url = "https://files.pythonhosted.org/packages/94/38/343242ec12eddf3d8458c73f555c084359883d4ddc674240d9e61ec51fd6/greenlet-3.3.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73631cd5cccbcfe63e3f9492aaa664d278fda0ce5c3d43aeda8e77317e38efbd", size = 586248, upload-time = "2025-12-04T14:57:39.35Z" }, - { url = "https://files.pythonhosted.org/packages/b6/a8/15d0aa26c0036a15d2659175af00954aaaa5d0d66ba538345bd88013b4d7/greenlet-3.3.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7dee147740789a4632cace364816046e43310b59ff8fb79833ab043aefa72fd5", size = 586910, upload-time = "2025-12-04T14:25:59.705Z" }, - { url = "https://files.pythonhosted.org/packages/e1/9b/68d5e3b7ccaba3907e5532cf8b9bf16f9ef5056a008f195a367db0ff32db/greenlet-3.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:39b28e339fc3c348427560494e28d8a6f3561c8d2bcf7d706e1c624ed8d822b9", size = 1547206, upload-time = "2025-12-04T15:04:21.027Z" }, - { url = "https://files.pythonhosted.org/packages/66/bd/e3086ccedc61e49f91e2cfb5ffad9d8d62e5dc85e512a6200f096875b60c/greenlet-3.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b3c374782c2935cc63b2a27ba8708471de4ad1abaa862ffdb1ef45a643ddbb7d", size = 1613359, upload-time = "2025-12-04T14:27:26.548Z" }, - { url = "https://files.pythonhosted.org/packages/f4/6b/d4e73f5dfa888364bbf02efa85616c6714ae7c631c201349782e5b428925/greenlet-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:b49e7ed51876b459bd645d83db257f0180e345d3f768a35a85437a24d5a49082", size = 300740, upload-time = "2025-12-04T14:47:52.773Z" }, - { url = "https://files.pythonhosted.org/packages/1f/cb/48e964c452ca2b92175a9b2dca037a553036cb053ba69e284650ce755f13/greenlet-3.3.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e29f3018580e8412d6aaf5641bb7745d38c85228dacf51a73bd4e26ddf2a6a8e", size = 274908, upload-time = "2025-12-04T14:23:26.435Z" }, - { url = "https://files.pythonhosted.org/packages/28/da/38d7bff4d0277b594ec557f479d65272a893f1f2a716cad91efeb8680953/greenlet-3.3.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a687205fb22794e838f947e2194c0566d3812966b41c78709554aa883183fb62", size = 577113, upload-time = "2025-12-04T14:50:05.493Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f2/89c5eb0faddc3ff014f1c04467d67dee0d1d334ab81fadbf3744847f8a8a/greenlet-3.3.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4243050a88ba61842186cb9e63c7dfa677ec146160b0efd73b855a3d9c7fcf32", size = 590338, upload-time = "2025-12-04T14:57:41.136Z" }, - { url = "https://files.pythonhosted.org/packages/dc/a6/e959a127b630a58e23529972dbc868c107f9d583b5a9f878fb858c46bc1a/greenlet-3.3.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cb3a8ec3db4a3b0eb8a3c25436c2d49e3505821802074969db017b87bc6a948", size = 590206, upload-time = "2025-12-04T14:26:01.254Z" }, - { url = "https://files.pythonhosted.org/packages/48/60/29035719feb91798693023608447283b266b12efc576ed013dd9442364bb/greenlet-3.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2de5a0b09eab81fc6a382791b995b1ccf2b172a9fec934747a7a23d2ff291794", size = 1550668, upload-time = "2025-12-04T15:04:22.439Z" }, - { url = "https://files.pythonhosted.org/packages/0a/5f/783a23754b691bfa86bd72c3033aa107490deac9b2ef190837b860996c9f/greenlet-3.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4449a736606bd30f27f8e1ff4678ee193bc47f6ca810d705981cfffd6ce0d8c5", size = 1615483, upload-time = "2025-12-04T14:27:28.083Z" }, - { url = "https://files.pythonhosted.org/packages/1d/d5/c339b3b4bc8198b7caa4f2bd9fd685ac9f29795816d8db112da3d04175bb/greenlet-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:7652ee180d16d447a683c04e4c5f6441bae7ba7b17ffd9f6b3aff4605e9e6f71", size = 301164, upload-time = "2025-12-04T14:42:51.577Z" }, - { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, - { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, - { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, - { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, - { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, - { url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" }, - { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" }, - { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" }, - { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" }, - { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" }, - { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" }, - { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, - { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" }, - { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" }, - { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" }, - { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" }, - { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" }, - { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, - { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" }, - { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" }, - { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" }, - { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" }, - { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" }, - { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/8a/99/1cd3411c56a410994669062bd73dd58270c00cc074cac15f385a1fd91f8a/greenlet-3.3.1.tar.gz", hash = "sha256:41848f3230b58c08bb43dee542e74a2a2e34d3c59dc3076cec9151aeeedcae98", size = 184690, upload-time = "2026-01-23T15:31:02.076Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/65/5b235b40581ad75ab97dcd8b4218022ae8e3ab77c13c919f1a1dfe9171fd/greenlet-3.3.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04bee4775f40ecefcdaa9d115ab44736cd4b9c5fba733575bfe9379419582e13", size = 273723, upload-time = "2026-01-23T15:30:37.521Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ad/eb4729b85cba2d29499e0a04ca6fbdd8f540afd7be142fd571eea43d712f/greenlet-3.3.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e1457f4fed12a50e427988a07f0f9df53cf0ee8da23fab16e6732c2ec909d4", size = 574874, upload-time = "2026-01-23T16:00:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/87/32/57cad7fe4c8b82fdaa098c89498ef85ad92dfbb09d5eb713adedfc2ae1f5/greenlet-3.3.1-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:070472cd156f0656f86f92e954591644e158fd65aa415ffbe2d44ca77656a8f5", size = 586309, upload-time = "2026-01-23T16:05:25.18Z" }, + { url = "https://files.pythonhosted.org/packages/87/eb/8a1ec2da4d55824f160594a75a9d8354a5fe0a300fb1c48e7944265217e1/greenlet-3.3.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a300354f27dd86bae5fbf7002e6dd2b3255cd372e9242c933faf5e859b703fe", size = 586985, upload-time = "2026-01-23T15:32:47.968Z" }, + { url = "https://files.pythonhosted.org/packages/15/1c/0621dd4321dd8c351372ee8f9308136acb628600658a49be1b7504208738/greenlet-3.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e84b51cbebf9ae573b5fbd15df88887815e3253fc000a7d0ff95170e8f7e9729", size = 1547271, upload-time = "2026-01-23T16:04:18.977Z" }, + { url = "https://files.pythonhosted.org/packages/9d/53/24047f8924c83bea7a59c8678d9571209c6bfe5f4c17c94a78c06024e9f2/greenlet-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0093bd1a06d899892427217f0ff2a3c8f306182b8c754336d32e2d587c131b4", size = 1613427, upload-time = "2026-01-23T15:33:44.428Z" }, + { url = "https://files.pythonhosted.org/packages/ff/07/ac9bf1ec008916d1a3373cae212884c1dcff4a4ba0d41127ce81a8deb4e9/greenlet-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:7932f5f57609b6a3b82cc11877709aa7a98e3308983ed93552a1c377069b20c8", size = 226100, upload-time = "2026-01-23T15:30:56.957Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e8/2e1462c8fdbe0f210feb5ac7ad2d9029af8be3bf45bd9fa39765f821642f/greenlet-3.3.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5fd23b9bc6d37b563211c6abbb1b3cab27db385a4449af5c32e932f93017080c", size = 274974, upload-time = "2026-01-23T15:31:02.891Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a8/530a401419a6b302af59f67aaf0b9ba1015855ea7e56c036b5928793c5bd/greenlet-3.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f51496a0bfbaa9d74d36a52d2580d1ef5ed4fdfcff0a73730abfbbbe1403dd", size = 577175, upload-time = "2026-01-23T16:00:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/8e/89/7e812bb9c05e1aaef9b597ac1d0962b9021d2c6269354966451e885c4e6b/greenlet-3.3.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb0feb07fe6e6a74615ee62a880007d976cf739b6669cce95daa7373d4fc69c5", size = 590401, upload-time = "2026-01-23T16:05:26.365Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ae/8d472e1f5ac5efe55c563f3eabb38c98a44b832602e12910750a7c025802/greenlet-3.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39eda9ba259cc9801da05351eaa8576e9aa83eb9411e8f0c299e05d712a210f2", size = 590272, upload-time = "2026-01-23T15:32:49.411Z" }, + { url = "https://files.pythonhosted.org/packages/a8/51/0fde34bebfcadc833550717eade64e35ec8738e6b097d5d248274a01258b/greenlet-3.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e2e7e882f83149f0a71ac822ebf156d902e7a5d22c9045e3e0d1daf59cee2cc9", size = 1550729, upload-time = "2026-01-23T16:04:20.867Z" }, + { url = "https://files.pythonhosted.org/packages/16/c9/2fb47bee83b25b119d5a35d580807bb8b92480a54b68fef009a02945629f/greenlet-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80aa4d79eb5564f2e0a6144fcc744b5a37c56c4a92d60920720e99210d88db0f", size = 1615552, upload-time = "2026-01-23T15:33:45.743Z" }, + { url = "https://files.pythonhosted.org/packages/1f/54/dcf9f737b96606f82f8dd05becfb8d238db0633dd7397d542a296fe9cad3/greenlet-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:32e4ca9777c5addcbf42ff3915d99030d8e00173a56f80001fb3875998fe410b", size = 226462, upload-time = "2026-01-23T15:36:50.422Z" }, + { url = "https://files.pythonhosted.org/packages/91/37/61e1015cf944ddd2337447d8e97fb423ac9bc21f9963fb5f206b53d65649/greenlet-3.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:da19609432f353fed186cc1b85e9440db93d489f198b4bdf42ae19cc9d9ac9b4", size = 225715, upload-time = "2026-01-23T15:33:17.298Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c8/9d76a66421d1ae24340dfae7e79c313957f6e3195c144d2c73333b5bfe34/greenlet-3.3.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:7e806ca53acf6d15a888405880766ec84721aa4181261cd11a457dfe9a7a4975", size = 276443, upload-time = "2026-01-23T15:30:10.066Z" }, + { url = "https://files.pythonhosted.org/packages/81/99/401ff34bb3c032d1f10477d199724f5e5f6fbfb59816ad1455c79c1eb8e7/greenlet-3.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d842c94b9155f1c9b3058036c24ffb8ff78b428414a19792b2380be9cecf4f36", size = 597359, upload-time = "2026-01-23T16:00:57.394Z" }, + { url = "https://files.pythonhosted.org/packages/2b/bc/4dcc0871ed557792d304f50be0f7487a14e017952ec689effe2180a6ff35/greenlet-3.3.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20fedaadd422fa02695f82093f9a98bad3dab5fcda793c658b945fcde2ab27ba", size = 607805, upload-time = "2026-01-23T16:05:28.068Z" }, + { url = "https://files.pythonhosted.org/packages/cf/05/821587cf19e2ce1f2b24945d890b164401e5085f9d09cbd969b0c193cd20/greenlet-3.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14194f5f4305800ff329cbf02c5fcc88f01886cadd29941b807668a45f0d2336", size = 609947, upload-time = "2026-01-23T15:32:51.004Z" }, + { url = "https://files.pythonhosted.org/packages/a4/52/ee8c46ed9f8babaa93a19e577f26e3d28a519feac6350ed6f25f1afee7e9/greenlet-3.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7b2fe4150a0cf59f847a67db8c155ac36aed89080a6a639e9f16df5d6c6096f1", size = 1567487, upload-time = "2026-01-23T16:04:22.125Z" }, + { url = "https://files.pythonhosted.org/packages/8f/7c/456a74f07029597626f3a6db71b273a3632aecb9afafeeca452cfa633197/greenlet-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49f4ad195d45f4a66a0eb9c1ba4832bb380570d361912fa3554746830d332149", size = 1636087, upload-time = "2026-01-23T15:33:47.486Z" }, + { url = "https://files.pythonhosted.org/packages/34/2f/5e0e41f33c69655300a5e54aeb637cf8ff57f1786a3aba374eacc0228c1d/greenlet-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:cc98b9c4e4870fa983436afa999d4eb16b12872fab7071423d5262fa7120d57a", size = 227156, upload-time = "2026-01-23T15:34:34.808Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ab/717c58343cf02c5265b531384b248787e04d8160b8afe53d9eec053d7b44/greenlet-3.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:bfb2d1763d777de5ee495c85309460f6fd8146e50ec9d0ae0183dbf6f0a829d1", size = 226403, upload-time = "2026-01-23T15:31:39.372Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ab/d26750f2b7242c2b90ea2ad71de70cfcd73a948a49513188a0fc0d6fc15a/greenlet-3.3.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:7ab327905cabb0622adca5971e488064e35115430cec2c35a50fd36e72a315b3", size = 275205, upload-time = "2026-01-23T15:30:24.556Z" }, + { url = "https://files.pythonhosted.org/packages/10/d3/be7d19e8fad7c5a78eeefb2d896a08cd4643e1e90c605c4be3b46264998f/greenlet-3.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65be2f026ca6a176f88fb935ee23c18333ccea97048076aef4db1ef5bc0713ac", size = 599284, upload-time = "2026-01-23T16:00:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/ae/21/fe703aaa056fdb0f17e5afd4b5c80195bbdab701208918938bd15b00d39b/greenlet-3.3.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a3ae05b3d225b4155bda56b072ceb09d05e974bc74be6c3fc15463cf69f33fd", size = 610274, upload-time = "2026-01-23T16:05:29.312Z" }, + { url = "https://files.pythonhosted.org/packages/cb/86/5c6ab23bb3c28c21ed6bebad006515cfe08b04613eb105ca0041fecca852/greenlet-3.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6423481193bbbe871313de5fd06a082f2649e7ce6e08015d2a76c1e9186ca5b3", size = 612904, upload-time = "2026-01-23T15:32:52.317Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f3/7949994264e22639e40718c2daf6f6df5169bf48fb038c008a489ec53a50/greenlet-3.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:33a956fe78bbbda82bfc95e128d61129b32d66bcf0a20a1f0c08aa4839ffa951", size = 1567316, upload-time = "2026-01-23T16:04:23.316Z" }, + { url = "https://files.pythonhosted.org/packages/8d/6e/d73c94d13b6465e9f7cd6231c68abde838bb22408596c05d9059830b7872/greenlet-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b065d3284be43728dd280f6f9a13990b56470b81be20375a207cdc814a983f2", size = 1636549, upload-time = "2026-01-23T15:33:48.643Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b3/c9c23a6478b3bcc91f979ce4ca50879e4d0b2bd7b9a53d8ecded719b92e2/greenlet-3.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:27289986f4e5b0edec7b5a91063c109f0276abb09a7e9bdab08437525977c946", size = 227042, upload-time = "2026-01-23T15:33:58.216Z" }, + { url = "https://files.pythonhosted.org/packages/90/e7/824beda656097edee36ab15809fd063447b200cc03a7f6a24c34d520bc88/greenlet-3.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:2f080e028001c5273e0b42690eaf359aeef9cb1389da0f171ea51a5dc3c7608d", size = 226294, upload-time = "2026-01-23T15:30:52.73Z" }, + { url = "https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5", size = 275737, upload-time = "2026-01-23T15:32:16.889Z" }, + { url = "https://files.pythonhosted.org/packages/41/2e/a3a417d620363fdbb08a48b1dd582956a46a61bf8fd27ee8164f9dfe87c2/greenlet-3.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b31c05dd84ef6871dd47120386aed35323c944d86c3d91a17c4b8d23df62f15b", size = 646422, upload-time = "2026-01-23T16:01:00.354Z" }, + { url = "https://files.pythonhosted.org/packages/b4/09/c6c4a0db47defafd2d6bab8ddfe47ad19963b4e30f5bed84d75328059f8c/greenlet-3.3.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02925a0bfffc41e542c70aa14c7eda3593e4d7e274bfcccca1827e6c0875902e", size = 658219, upload-time = "2026-01-23T16:05:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f", size = 660237, upload-time = "2026-01-23T15:32:53.967Z" }, + { url = "https://files.pythonhosted.org/packages/96/61/373c30b7197f9e756e4c81ae90a8d55dc3598c17673f91f4d31c3c689c3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aec9ab04e82918e623415947921dea15851b152b822661cce3f8e4393c3df683", size = 1615261, upload-time = "2026-01-23T16:04:25.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d3/ca534310343f5945316f9451e953dcd89b36fe7a19de652a1dc5a0eeef3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71c767cf281a80d02b6c1bdc41c9468e1f5a494fb11bc8688c360524e273d7b1", size = 1683719, upload-time = "2026-01-23T15:33:50.61Z" }, + { url = "https://files.pythonhosted.org/packages/52/cb/c21a3fd5d2c9c8b622e7bede6d6d00e00551a5ee474ea6d831b5f567a8b4/greenlet-3.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:96aff77af063b607f2489473484e39a0bbae730f2ea90c9e5606c9b73c44174a", size = 228125, upload-time = "2026-01-23T15:32:45.265Z" }, + { url = "https://files.pythonhosted.org/packages/6a/8e/8a2db6d11491837af1de64b8aff23707c6e85241be13c60ed399a72e2ef8/greenlet-3.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:b066e8b50e28b503f604fa538adc764a638b38cf8e81e025011d26e8a627fa79", size = 227519, upload-time = "2026-01-23T15:31:47.284Z" }, + { url = "https://files.pythonhosted.org/packages/28/24/cbbec49bacdcc9ec652a81d3efef7b59f326697e7edf6ed775a5e08e54c2/greenlet-3.3.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:3e63252943c921b90abb035ebe9de832c436401d9c45f262d80e2d06cc659242", size = 282706, upload-time = "2026-01-23T15:33:05.525Z" }, + { url = "https://files.pythonhosted.org/packages/86/2e/4f2b9323c144c4fe8842a4e0d92121465485c3c2c5b9e9b30a52e80f523f/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76e39058e68eb125de10c92524573924e827927df5d3891fbc97bd55764a8774", size = 651209, upload-time = "2026-01-23T16:01:01.517Z" }, + { url = "https://files.pythonhosted.org/packages/d9/87/50ca60e515f5bb55a2fbc5f0c9b5b156de7d2fc51a0a69abc9d23914a237/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9f9d5e7a9310b7a2f416dd13d2e3fd8b42d803968ea580b7c0f322ccb389b97", size = 654300, upload-time = "2026-01-23T16:05:32.199Z" }, + { url = "https://files.pythonhosted.org/packages/1d/94/74310866dfa2b73dd08659a3d18762f83985ad3281901ba0ee9a815194fb/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92497c78adf3ac703b57f1e3813c2d874f27f71a178f9ea5887855da413cd6d2", size = 653842, upload-time = "2026-01-23T15:32:55.671Z" }, + { url = "https://files.pythonhosted.org/packages/97/43/8bf0ffa3d498eeee4c58c212a3905dd6146c01c8dc0b0a046481ca29b18c/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ed6b402bc74d6557a705e197d47f9063733091ed6357b3de33619d8a8d93ac53", size = 1614917, upload-time = "2026-01-23T16:04:26.276Z" }, + { url = "https://files.pythonhosted.org/packages/89/90/a3be7a5f378fc6e84abe4dcfb2ba32b07786861172e502388b4c90000d1b/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:59913f1e5ada20fde795ba906916aea25d442abcc0593fba7e26c92b7ad76249", size = 1676092, upload-time = "2026-01-23T15:33:52.176Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2b/98c7f93e6db9977aaee07eb1e51ca63bd5f779b900d362791d3252e60558/greenlet-3.3.1-cp314-cp314t-win_amd64.whl", hash = "sha256:301860987846c24cb8964bdec0e31a96ad4a2a801b41b4ef40963c1b44f33451", size = 233181, upload-time = "2026-01-23T15:33:00.29Z" }, ] [[package]] @@ -985,10 +1041,18 @@ name = "ipython" version = "9.9.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, @@ -1282,10 +1346,18 @@ name = "markdown-it-py" version = "4.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "mdurl", marker = "python_full_version >= '3.11'" }, @@ -1625,10 +1697,12 @@ docs = [ { name = "qiskit", extra = ["qasm3-import", "visualization"] }, { name = "setuptools-scm" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "sphinx-autoapi" }, { name = "sphinx-copybutton" }, - { name = "sphinx-design" }, + { name = "sphinx-design", version = "0.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "sphinx-design", version = "0.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "sphinxcontrib-bibtex" }, { name = "sphinxcontrib-svg2pdfconverter" }, { name = "sphinxext-opengraph" }, @@ -1735,7 +1809,8 @@ dependencies = [ { name = "nbformat" }, { name = "pyyaml" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/83/a894bd8dea7a6e9f053502ee8413484dcbf75a219013d6a72e971c0fecfd/myst_nb-1.3.0.tar.gz", hash = "sha256:df3cd4680f51a5af673fd46b38b562be3559aef1475e906ed0f2e66e4587ce4b", size = 81963, upload-time = "2025-07-13T22:49:38.493Z" } @@ -1751,7 +1826,7 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "docutils", marker = "python_full_version < '3.11'" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "jinja2", marker = "python_full_version < '3.11'" }, { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "mdit-py-plugins", marker = "python_full_version < '3.11'" }, @@ -1768,18 +1843,27 @@ name = "myst-parser" version = "5.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", -] -dependencies = [ - { name = "docutils", marker = "python_full_version >= '3.11'" }, + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jinja2", marker = "python_full_version >= '3.11'" }, { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "mdit-py-plugins", marker = "python_full_version >= '3.11'" }, { name = "pyyaml", marker = "python_full_version >= '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/fa/7b45eef11b7971f0beb29d27b7bfe0d747d063aa29e170d9edd004733c8a/myst_parser-5.0.0.tar.gz", hash = "sha256:f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a", size = 98535, upload-time = "2026-01-15T09:08:18.036Z" } wheels = [ @@ -1860,10 +1944,18 @@ name = "networkx" version = "3.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } wheels = [ @@ -1959,10 +2051,18 @@ name = "numpy" version = "2.4.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/24/62/ae72ff66c0f1fd959925b4c11f8c2dea61f47f6acaea75a08512cdfe3fed/numpy-2.4.1.tar.gz", hash = "sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690", size = 20721320, upload-time = "2026-01-10T06:44:59.619Z" } wheels = [ @@ -2055,23 +2155,25 @@ parser = [ [[package]] name = "packaging" -version = "25.0" +version = "26.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] [[package]] name = "pandas" version = "2.3.3" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, + { name = "python-dateutil", marker = "python_full_version < '3.11'" }, + { name = "pytz", marker = "python_full_version < '3.11'" }, + { name = "tzdata", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ @@ -2124,6 +2226,80 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, ] +[[package]] +name = "pandas" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, + { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/da/b1dc0481ab8d55d0f46e343cfe67d4551a0e14fcee52bd38ca1bd73258d8/pandas-3.0.0.tar.gz", hash = "sha256:0facf7e87d38f721f0af46fe70d97373a37701b1c09f7ed7aeeb292ade5c050f", size = 4633005, upload-time = "2026-01-21T15:52:04.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/1e/b184654a856e75e975a6ee95d6577b51c271cd92cb2b020c9378f53e0032/pandas-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d64ce01eb9cdca96a15266aa679ae50212ec52757c79204dbc7701a222401850", size = 10313247, upload-time = "2026-01-21T15:50:15.775Z" }, + { url = "https://files.pythonhosted.org/packages/dd/5e/e04a547ad0f0183bf151fd7c7a477468e3b85ff2ad231c566389e6cc9587/pandas-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:613e13426069793aa1ec53bdcc3b86e8d32071daea138bbcf4fa959c9cdaa2e2", size = 9913131, upload-time = "2026-01-21T15:50:18.611Z" }, + { url = "https://files.pythonhosted.org/packages/a2/93/bb77bfa9fc2aba9f7204db807d5d3fb69832ed2854c60ba91b4c65ba9219/pandas-3.0.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0192fee1f1a8e743b464a6607858ee4b071deb0b118eb143d71c2a1d170996d5", size = 10741925, upload-time = "2026-01-21T15:50:21.058Z" }, + { url = "https://files.pythonhosted.org/packages/62/fb/89319812eb1d714bfc04b7f177895caeba8ab4a37ef6712db75ed786e2e0/pandas-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0b853319dec8d5e0c8b875374c078ef17f2269986a78168d9bd57e49bf650ae", size = 11245979, upload-time = "2026-01-21T15:50:23.413Z" }, + { url = "https://files.pythonhosted.org/packages/a9/63/684120486f541fc88da3862ed31165b3b3e12b6a1c7b93be4597bc84e26c/pandas-3.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:707a9a877a876c326ae2cb640fbdc4ef63b0a7b9e2ef55c6df9942dcee8e2af9", size = 11756337, upload-time = "2026-01-21T15:50:25.932Z" }, + { url = "https://files.pythonhosted.org/packages/39/92/7eb0ad232312b59aec61550c3c81ad0743898d10af5df7f80bc5e5065416/pandas-3.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:afd0aa3d0b5cda6e0b8ffc10dbcca3b09ef3cbcd3fe2b27364f85fdc04e1989d", size = 12325517, upload-time = "2026-01-21T15:50:27.952Z" }, + { url = "https://files.pythonhosted.org/packages/51/27/bf9436dd0a4fc3130acec0828951c7ef96a0631969613a9a35744baf27f6/pandas-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:113b4cca2614ff7e5b9fee9b6f066618fe73c5a83e99d721ffc41217b2bf57dd", size = 9881576, upload-time = "2026-01-21T15:50:30.149Z" }, + { url = "https://files.pythonhosted.org/packages/e7/2b/c618b871fce0159fd107516336e82891b404e3f340821853c2fc28c7830f/pandas-3.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c14837eba8e99a8da1527c0280bba29b0eb842f64aa94982c5e21227966e164b", size = 9140807, upload-time = "2026-01-21T15:50:32.308Z" }, + { url = "https://files.pythonhosted.org/packages/0b/38/db33686f4b5fa64d7af40d96361f6a4615b8c6c8f1b3d334eee46ae6160e/pandas-3.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9803b31f5039b3c3b10cc858c5e40054adb4b29b4d81cb2fd789f4121c8efbcd", size = 10334013, upload-time = "2026-01-21T15:50:34.771Z" }, + { url = "https://files.pythonhosted.org/packages/a5/7b/9254310594e9774906bacdd4e732415e1f86ab7dbb4b377ef9ede58cd8ec/pandas-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14c2a4099cd38a1d18ff108168ea417909b2dea3bd1ebff2ccf28ddb6a74d740", size = 9874154, upload-time = "2026-01-21T15:50:36.67Z" }, + { url = "https://files.pythonhosted.org/packages/63/d4/726c5a67a13bc66643e66d2e9ff115cead482a44fc56991d0c4014f15aaf/pandas-3.0.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d257699b9a9960e6125686098d5714ac59d05222bef7a5e6af7a7fd87c650801", size = 10384433, upload-time = "2026-01-21T15:50:39.132Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2e/9211f09bedb04f9832122942de8b051804b31a39cfbad199a819bb88d9f3/pandas-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:69780c98f286076dcafca38d8b8eee1676adf220199c0a39f0ecbf976b68151a", size = 10864519, upload-time = "2026-01-21T15:50:41.043Z" }, + { url = "https://files.pythonhosted.org/packages/00/8d/50858522cdc46ac88b9afdc3015e298959a70a08cd21e008a44e9520180c/pandas-3.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4a66384f017240f3858a4c8a7cf21b0591c3ac885cddb7758a589f0f71e87ebb", size = 11394124, upload-time = "2026-01-21T15:50:43.377Z" }, + { url = "https://files.pythonhosted.org/packages/86/3f/83b2577db02503cd93d8e95b0f794ad9d4be0ba7cb6c8bcdcac964a34a42/pandas-3.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be8c515c9bc33989d97b89db66ea0cececb0f6e3c2a87fcc8b69443a6923e95f", size = 11920444, upload-time = "2026-01-21T15:50:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/64/2d/4f8a2f192ed12c90a0aab47f5557ece0e56b0370c49de9454a09de7381b2/pandas-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a453aad8c4f4e9f166436994a33884442ea62aa8b27d007311e87521b97246e1", size = 9730970, upload-time = "2026-01-21T15:50:47.962Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/ff571be435cf1e643ca98d0945d76732c0b4e9c37191a89c8550b105eed1/pandas-3.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:da768007b5a33057f6d9053563d6b74dd6d029c337d93c6d0d22a763a5c2ecc0", size = 9041950, upload-time = "2026-01-21T15:50:50.422Z" }, + { url = "https://files.pythonhosted.org/packages/6f/fa/7f0ac4ca8877c57537aaff2a842f8760e630d8e824b730eb2e859ffe96ca/pandas-3.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b78d646249b9a2bc191040988c7bb524c92fa8534fb0898a0741d7e6f2ffafa6", size = 10307129, upload-time = "2026-01-21T15:50:52.877Z" }, + { url = "https://files.pythonhosted.org/packages/6f/11/28a221815dcea4c0c9414dfc845e34a84a6a7dabc6da3194498ed5ba4361/pandas-3.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bc9cba7b355cb4162442a88ce495e01cb605f17ac1e27d6596ac963504e0305f", size = 9850201, upload-time = "2026-01-21T15:50:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/ba/da/53bbc8c5363b7e5bd10f9ae59ab250fc7a382ea6ba08e4d06d8694370354/pandas-3.0.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c9a1a149aed3b6c9bf246033ff91e1b02d529546c5d6fb6b74a28fea0cf4c70", size = 10354031, upload-time = "2026-01-21T15:50:57.463Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a3/51e02ebc2a14974170d51e2410dfdab58870ea9bcd37cda15bd553d24dc4/pandas-3.0.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95683af6175d884ee89471842acfca29172a85031fccdabc35e50c0984470a0e", size = 10861165, upload-time = "2026-01-21T15:50:59.32Z" }, + { url = "https://files.pythonhosted.org/packages/a5/fe/05a51e3cac11d161472b8297bd41723ea98013384dd6d76d115ce3482f9b/pandas-3.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1fbbb5a7288719e36b76b4f18d46ede46e7f916b6c8d9915b756b0a6c3f792b3", size = 11359359, upload-time = "2026-01-21T15:51:02.014Z" }, + { url = "https://files.pythonhosted.org/packages/ee/56/ba620583225f9b85a4d3e69c01df3e3870659cc525f67929b60e9f21dcd1/pandas-3.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e8b9808590fa364416b49b2a35c1f4cf2785a6c156935879e57f826df22038e", size = 11912907, upload-time = "2026-01-21T15:51:05.175Z" }, + { url = "https://files.pythonhosted.org/packages/c9/8c/c6638d9f67e45e07656b3826405c5cc5f57f6fd07c8b2572ade328c86e22/pandas-3.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:98212a38a709feb90ae658cb6227ea3657c22ba8157d4b8f913cd4c950de5e7e", size = 9732138, upload-time = "2026-01-21T15:51:07.569Z" }, + { url = "https://files.pythonhosted.org/packages/7b/bf/bd1335c3bf1770b6d8fed2799993b11c4971af93bb1b729b9ebbc02ca2ec/pandas-3.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:177d9df10b3f43b70307a149d7ec49a1229a653f907aa60a48f1877d0e6be3be", size = 9033568, upload-time = "2026-01-21T15:51:09.484Z" }, + { url = "https://files.pythonhosted.org/packages/8e/c6/f5e2171914d5e29b9171d495344097d54e3ffe41d2d85d8115baba4dc483/pandas-3.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2713810ad3806767b89ad3b7b69ba153e1c6ff6d9c20f9c2140379b2a98b6c98", size = 10741936, upload-time = "2026-01-21T15:51:11.693Z" }, + { url = "https://files.pythonhosted.org/packages/51/88/9a0164f99510a1acb9f548691f022c756c2314aad0d8330a24616c14c462/pandas-3.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:15d59f885ee5011daf8335dff47dcb8a912a27b4ad7826dc6cbe809fd145d327", size = 10393884, upload-time = "2026-01-21T15:51:14.197Z" }, + { url = "https://files.pythonhosted.org/packages/e0/53/b34d78084d88d8ae2b848591229da8826d1e65aacf00b3abe34023467648/pandas-3.0.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24e6547fb64d2c92665dd2adbfa4e85fa4fd70a9c070e7cfb03b629a0bbab5eb", size = 10310740, upload-time = "2026-01-21T15:51:16.093Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d3/bee792e7c3d6930b74468d990604325701412e55d7aaf47460a22311d1a5/pandas-3.0.0-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48ee04b90e2505c693d3f8e8f524dab8cb8aaf7ddcab52c92afa535e717c4812", size = 10700014, upload-time = "2026-01-21T15:51:18.818Z" }, + { url = "https://files.pythonhosted.org/packages/55/db/2570bc40fb13aaed1cbc3fbd725c3a60ee162477982123c3adc8971e7ac1/pandas-3.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66f72fb172959af42a459e27a8d8d2c7e311ff4c1f7db6deb3b643dbc382ae08", size = 11323737, upload-time = "2026-01-21T15:51:20.784Z" }, + { url = "https://files.pythonhosted.org/packages/bc/2e/297ac7f21c8181b62a4cccebad0a70caf679adf3ae5e83cb676194c8acc3/pandas-3.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4a4a400ca18230976724a5066f20878af785f36c6756e498e94c2a5e5d57779c", size = 11771558, upload-time = "2026-01-21T15:51:22.977Z" }, + { url = "https://files.pythonhosted.org/packages/0a/46/e1c6876d71c14332be70239acce9ad435975a80541086e5ffba2f249bcf6/pandas-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:940eebffe55528074341a5a36515f3e4c5e25e958ebbc764c9502cfc35ba3faa", size = 10473771, upload-time = "2026-01-21T15:51:25.285Z" }, + { url = "https://files.pythonhosted.org/packages/c0/db/0270ad9d13c344b7a36fa77f5f8344a46501abf413803e885d22864d10bf/pandas-3.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:597c08fb9fef0edf1e4fa2f9828dd27f3d78f9b8c9b4a748d435ffc55732310b", size = 10312075, upload-time = "2026-01-21T15:51:28.5Z" }, + { url = "https://files.pythonhosted.org/packages/09/9f/c176f5e9717f7c91becfe0f55a52ae445d3f7326b4a2cf355978c51b7913/pandas-3.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:447b2d68ac5edcbf94655fe909113a6dba6ef09ad7f9f60c80477825b6c489fe", size = 9900213, upload-time = "2026-01-21T15:51:30.955Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e7/63ad4cc10b257b143e0a5ebb04304ad806b4e1a61c5da25f55896d2ca0f4/pandas-3.0.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:debb95c77ff3ed3ba0d9aa20c3a2f19165cc7956362f9873fce1ba0a53819d70", size = 10428768, upload-time = "2026-01-21T15:51:33.018Z" }, + { url = "https://files.pythonhosted.org/packages/9e/0e/4e4c2d8210f20149fd2248ef3fff26623604922bd564d915f935a06dd63d/pandas-3.0.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fedabf175e7cd82b69b74c30adbaa616de301291a5231138d7242596fc296a8d", size = 10882954, upload-time = "2026-01-21T15:51:35.287Z" }, + { url = "https://files.pythonhosted.org/packages/c6/60/c9de8ac906ba1f4d2250f8a951abe5135b404227a55858a75ad26f84db47/pandas-3.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:412d1a89aab46889f3033a386912efcdfa0f1131c5705ff5b668dda88305e986", size = 11430293, upload-time = "2026-01-21T15:51:37.57Z" }, + { url = "https://files.pythonhosted.org/packages/a1/69/806e6637c70920e5787a6d6896fd707f8134c2c55cd761e7249a97b7dc5a/pandas-3.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e979d22316f9350c516479dd3a92252be2937a9531ed3a26ec324198a99cdd49", size = 11952452, upload-time = "2026-01-21T15:51:39.618Z" }, + { url = "https://files.pythonhosted.org/packages/cb/de/918621e46af55164c400ab0ef389c9d969ab85a43d59ad1207d4ddbe30a5/pandas-3.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:083b11415b9970b6e7888800c43c82e81a06cd6b06755d84804444f0007d6bb7", size = 9851081, upload-time = "2026-01-21T15:51:41.758Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/3562a18dd0bd8c73344bfa26ff90c53c72f827df119d6d6b1dacc84d13e3/pandas-3.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:5db1e62cb99e739fa78a28047e861b256d17f88463c76b8dafc7c1338086dca8", size = 9174610, upload-time = "2026-01-21T15:51:44.312Z" }, + { url = "https://files.pythonhosted.org/packages/ce/26/430d91257eaf366f1737d7a1c158677caaf6267f338ec74e3a1ec444111c/pandas-3.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:697b8f7d346c68274b1b93a170a70974cdc7d7354429894d5927c1effdcccd73", size = 10761999, upload-time = "2026-01-21T15:51:46.899Z" }, + { url = "https://files.pythonhosted.org/packages/ec/1a/954eb47736c2b7f7fe6a9d56b0cb6987773c00faa3c6451a43db4beb3254/pandas-3.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8cb3120f0d9467ed95e77f67a75e030b67545bcfa08964e349252d674171def2", size = 10410279, upload-time = "2026-01-21T15:51:48.89Z" }, + { url = "https://files.pythonhosted.org/packages/20/fc/b96f3a5a28b250cd1b366eb0108df2501c0f38314a00847242abab71bb3a/pandas-3.0.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33fd3e6baa72899746b820c31e4b9688c8e1b7864d7aec2de7ab5035c285277a", size = 10330198, upload-time = "2026-01-21T15:51:51.015Z" }, + { url = "https://files.pythonhosted.org/packages/90/b3/d0e2952f103b4fbef1ef22d0c2e314e74fc9064b51cee30890b5e3286ee6/pandas-3.0.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8942e333dc67ceda1095227ad0febb05a3b36535e520154085db632c40ad084", size = 10728513, upload-time = "2026-01-21T15:51:53.387Z" }, + { url = "https://files.pythonhosted.org/packages/76/81/832894f286df828993dc5fd61c63b231b0fb73377e99f6c6c369174cf97e/pandas-3.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:783ac35c4d0fe0effdb0d67161859078618b1b6587a1af15928137525217a721", size = 11345550, upload-time = "2026-01-21T15:51:55.329Z" }, + { url = "https://files.pythonhosted.org/packages/34/a0/ed160a00fb4f37d806406bc0a79a8b62fe67f29d00950f8d16203ff3409b/pandas-3.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:125eb901e233f155b268bbef9abd9afb5819db74f0e677e89a61b246228c71ac", size = 11799386, upload-time = "2026-01-21T15:51:57.457Z" }, + { url = "https://files.pythonhosted.org/packages/36/c8/2ac00d7255252c5e3cf61b35ca92ca25704b0188f7454ca4aec08a33cece/pandas-3.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b86d113b6c109df3ce0ad5abbc259fe86a1bd4adfd4a31a89da42f84f65509bb", size = 10873041, upload-time = "2026-01-21T15:52:00.034Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3f/a80ac00acbc6b35166b42850e98a4f466e2c0d9c64054161ba9620f95680/pandas-3.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1c39eab3ad38f2d7a249095f0a3d8f8c22cc0f847e98ccf5bbe732b272e2d9fa", size = 9441003, upload-time = "2026-01-21T15:52:02.281Z" }, +] + [[package]] name = "parso" version = "0.8.5" @@ -2359,7 +2535,8 @@ name = "pybtex-docutils" version = "1.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "docutils" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pybtex" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7e/84/796ea94d26188a853660f81bded39f8de4cfe595130aef0dea1088705a11/pybtex-docutils-1.0.3.tar.gz", hash = "sha256:3a7ebdf92b593e00e8c1c538aa9a20bca5d92d84231124715acc964d51d93c6b", size = 18348, upload-time = "2023-08-22T18:47:54.833Z" } @@ -2369,11 +2546,11 @@ wheels = [ [[package]] name = "pycparser" -version = "2.23" +version = "3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, ] [[package]] @@ -2405,11 +2582,11 @@ sdist = { url = "https://files.pythonhosted.org/packages/5d/ab/34ec41718af73c001 [[package]] name = "pyparsing" -version = "3.3.1" +version = "3.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/33/c1/1d9de9aeaa1b89b0186e5fe23294ff6517fce1bc69149185577cd31016b2/pyparsing-3.3.1.tar.gz", hash = "sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c", size = 1550512, upload-time = "2025-12-23T03:14:04.391Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/40/2614036cdd416452f5bf98ec037f38a1afb17f327cb8e6b652d4729e0af8/pyparsing-3.3.1-py3-none-any.whl", hash = "sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82", size = 121793, upload-time = "2025-12-23T03:14:02.103Z" }, + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, ] [[package]] @@ -2717,18 +2894,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7", size = 7676, upload-time = "2025-12-17T18:25:33.098Z" }, ] -[[package]] -name = "roman-numerals-py" -version = "4.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "roman-numerals", marker = "python_full_version >= '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cb/b5/de96fca640f4f656eb79bbee0e79aeec52e3e0e359f8a3e6a0d366378b64/roman_numerals_py-4.1.0.tar.gz", hash = "sha256:f5d7b2b4ca52dd855ef7ab8eb3590f428c0b1ea480736ce32b01fef2a5f8daf9", size = 4274, upload-time = "2025-12-17T18:25:41.153Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/27/2c/daca29684cbe9fd4bc711f8246da3c10adca1ccc4d24436b17572eb2590e/roman_numerals_py-4.1.0-py3-none-any.whl", hash = "sha256:553114c1167141c1283a51743759723ecd05604a1b6b507225e91dc1a6df0780", size = 4547, upload-time = "2025-12-17T18:25:40.136Z" }, -] - [[package]] name = "rpds-py" version = "0.30.0" @@ -2959,10 +3124,18 @@ name = "scipy" version = "1.17.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -3039,7 +3212,8 @@ dependencies = [ { name = "matplotlib" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pandas" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/86/59/a451d7420a77ab0b98f7affa3a1d78a313d2f7281a57afb1a34bae8ab412/seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7", size = 1457696, upload-time = "2024-01-25T13:21:52.551Z" } wheels = [ @@ -3048,11 +3222,11 @@ wheels = [ [[package]] name = "setuptools" -version = "80.9.0" +version = "80.10.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, + { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, ] [[package]] @@ -3089,11 +3263,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8.2" +version = "2.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/93/f2/21d6ca70c3cf35d01ae9e01be534bf6b6b103c157a728082a5028350c310/soupsieve-2.8.2.tar.gz", hash = "sha256:78a66b0fdee2ab40b7199dc3e747ee6c6e231899feeaae0b9b98a353afd48fd8", size = 118601, upload-time = "2026-01-18T16:21:31.09Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/9a/b4450ccce353e2430621b3bb571899ffe1033d5cd72c9e065110f95b1a63/soupsieve-2.8.2-py3-none-any.whl", hash = "sha256:0f4c2f6b5a5fb97a641cf69c0bd163670a0e45e6d6c01a2107f93a6a6f93c51a", size = 37016, upload-time = "2026-01-18T16:21:29.7Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, ] [[package]] @@ -3107,7 +3281,7 @@ dependencies = [ { name = "alabaster", marker = "python_full_version < '3.11'" }, { name = "babel", marker = "python_full_version < '3.11'" }, { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version < '3.11'" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "imagesize", marker = "python_full_version < '3.11'" }, { name = "jinja2", marker = "python_full_version < '3.11'" }, { name = "packaging", marker = "python_full_version < '3.11'" }, @@ -3129,36 +3303,74 @@ wheels = [ [[package]] name = "sphinx" -version = "8.2.3" +version = "9.0.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.14'", - "python_full_version == '3.13.*'", - "python_full_version == '3.12.*'", - "python_full_version == '3.11.*'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.11'" }, - { name = "babel", marker = "python_full_version >= '3.11'" }, - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version >= '3.11'" }, - { name = "imagesize", marker = "python_full_version >= '3.11'" }, - { name = "jinja2", marker = "python_full_version >= '3.11'" }, - { name = "packaging", marker = "python_full_version >= '3.11'" }, - { name = "pygments", marker = "python_full_version >= '3.11'" }, - { name = "requests", marker = "python_full_version >= '3.11'" }, - { name = "roman-numerals-py", marker = "python_full_version >= '3.11'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.11'" }, + { name = "alabaster", marker = "python_full_version == '3.11.*'" }, + { name = "babel", marker = "python_full_version == '3.11.*'" }, + { name = "colorama", marker = "python_full_version == '3.11.*' and sys_platform == 'win32'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "imagesize", marker = "python_full_version == '3.11.*'" }, + { name = "jinja2", marker = "python_full_version == '3.11.*'" }, + { name = "packaging", marker = "python_full_version == '3.11.*'" }, + { name = "pygments", marker = "python_full_version == '3.11.*'" }, + { name = "requests", marker = "python_full_version == '3.11.*'" }, + { name = "roman-numerals", marker = "python_full_version == '3.11.*'" }, + { name = "snowballstemmer", marker = "python_full_version == '3.11.*'" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*'" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*'" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*'" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*'" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*'" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl", hash = "sha256:5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb", size = 3917713, upload-time = "2025-12-04T07:45:24.944Z" }, +] + +[[package]] +name = "sphinx" +version = "9.1.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "alabaster", marker = "python_full_version >= '3.12'" }, + { name = "babel", marker = "python_full_version >= '3.12'" }, + { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "imagesize", marker = "python_full_version >= '3.12'" }, + { name = "jinja2", marker = "python_full_version >= '3.12'" }, + { name = "packaging", marker = "python_full_version >= '3.12'" }, + { name = "pygments", marker = "python_full_version >= '3.12'" }, + { name = "requests", marker = "python_full_version >= '3.12'" }, + { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, + { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978", size = 3921742, upload-time = "2025-12-31T15:09:25.561Z" }, ] [[package]] @@ -3171,7 +3383,8 @@ dependencies = [ { name = "jinja2" }, { name = "pyyaml" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a9/ad/c627976d5f4d812b203ef1136108bbd81ef9bbbfd3f700f1295c322c22e6/sphinx_autoapi-3.6.1.tar.gz", hash = "sha256:1ff2992b7d5e39ccf92413098a376e0f91e7b4ca532c4f3e71298dbc8a4a9900", size = 55456, upload-time = "2025-10-06T16:21:22.888Z" } wheels = [ @@ -3184,7 +3397,8 @@ version = "1.0.0b2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736, upload-time = "2023-07-08T18:40:54.166Z" } wheels = [ @@ -3197,7 +3411,8 @@ version = "0.5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } wheels = [ @@ -3208,15 +3423,44 @@ wheels = [ name = "sphinx-design" version = "0.6.1" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689, upload-time = "2024-08-02T13:48:44.277Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338, upload-time = "2024-08-02T13:48:42.106Z" }, ] +[[package]] +name = "sphinx-design" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'emscripten'", + "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/13/7b/804f311da4663a4aecc6cf7abd83443f3d4ded970826d0c958edc77d4527/sphinx_design-0.7.0.tar.gz", hash = "sha256:d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a", size = 2203582, upload-time = "2026-01-19T13:12:53.297Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/cf/45dd359f6ca0c3762ce0490f681da242f0530c49c81050c035c016bfdd3a/sphinx_design-0.7.0-py3-none-any.whl", hash = "sha256:f82bf179951d58f55dca78ab3706aeafa496b741a91b1911d371441127d64282", size = 2220350, upload-time = "2026-01-19T13:12:51.077Z" }, +] + [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" @@ -3231,11 +3475,13 @@ name = "sphinxcontrib-bibtex" version = "2.6.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "docutils" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pybtex" }, { name = "pybtex-docutils" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/de/83/1488c9879f2fa3c2cbd6f666c7a3a42a1fa9e08462bec73281fa6c092cba/sphinxcontrib_bibtex-2.6.5.tar.gz", hash = "sha256:9b3224dd6fece9268ebd8c905dc0a83ff2f6c54148a9235fe70e9d1e9ff149c0", size = 118462, upload-time = "2025-06-27T10:40:14.061Z" } wheels = [ @@ -3293,7 +3539,8 @@ version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/7a/21930ae148f94c458ca2f8f554d4e737e17c1db8b152238f530fc0c89e32/sphinxcontrib_svg2pdfconverter-2.0.0.tar.gz", hash = "sha256:ab9c8f1080391e231812d20abf2657a69ee35574563b1014414f953964a95fa3", size = 6411, upload-time = "2025-12-01T20:44:21.386Z" } wheels = [ @@ -3306,7 +3553,8 @@ version = "0.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f6/c0/eb6838e3bae624ce6c8b90b245d17e84252863150e95efdb88f92c8aa3fb/sphinxext_opengraph-0.13.0.tar.gz", hash = "sha256:103335d08567ad8468faf1425f575e3b698e9621f9323949a6c8b96d9793e80b", size = 1026875, upload-time = "2025-08-29T12:20:31.066Z" } wheels = [ @@ -3315,51 +3563,58 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.45" +version = "2.0.46" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/70/75b1387d72e2847220441166c5eb4e9846dd753895208c13e6d66523b2d9/sqlalchemy-2.0.45-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c64772786d9eee72d4d3784c28f0a636af5b0a29f3fe26ff11f55efe90c0bd85", size = 2154148, upload-time = "2025-12-10T20:03:21.023Z" }, - { url = "https://files.pythonhosted.org/packages/d8/a4/7805e02323c49cb9d1ae5cd4913b28c97103079765f520043f914fca4cb3/sqlalchemy-2.0.45-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7ae64ebf7657395824a19bca98ab10eb9a3ecb026bf09524014f1bb81cb598d4", size = 3233051, upload-time = "2025-12-09T22:06:04.768Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ec/32ae09139f61bef3de3142e85c47abdee8db9a55af2bb438da54a4549263/sqlalchemy-2.0.45-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f02325709d1b1a1489f23a39b318e175a171497374149eae74d612634b234c0", size = 3232781, upload-time = "2025-12-09T22:09:54.435Z" }, - { url = "https://files.pythonhosted.org/packages/ad/bd/bf7b869b6f5585eac34222e1cf4405f4ba8c3b85dd6b1af5d4ce8bca695f/sqlalchemy-2.0.45-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2c3684fca8a05f0ac1d9a21c1f4a266983a7ea9180efb80ffeb03861ecd01a0", size = 3182096, upload-time = "2025-12-09T22:06:06.169Z" }, - { url = "https://files.pythonhosted.org/packages/21/6a/c219720a241bb8f35c88815ccc27761f5af7fdef04b987b0e8a2c1a6dcaa/sqlalchemy-2.0.45-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040f6f0545b3b7da6b9317fc3e922c9a98fc7243b2a1b39f78390fc0942f7826", size = 3205109, upload-time = "2025-12-09T22:09:55.969Z" }, - { url = "https://files.pythonhosted.org/packages/bd/c4/6ccf31b2bc925d5d95fab403ffd50d20d7c82b858cf1a4855664ca054dce/sqlalchemy-2.0.45-cp310-cp310-win32.whl", hash = "sha256:830d434d609fe7bfa47c425c445a8b37929f140a7a44cdaf77f6d34df3a7296a", size = 2114240, upload-time = "2025-12-09T21:29:54.007Z" }, - { url = "https://files.pythonhosted.org/packages/de/29/a27a31fca07316def418db6f7c70ab14010506616a2decef1906050a0587/sqlalchemy-2.0.45-cp310-cp310-win_amd64.whl", hash = "sha256:0209d9753671b0da74da2cfbb9ecf9c02f72a759e4b018b3ab35f244c91842c7", size = 2137615, upload-time = "2025-12-09T21:29:55.85Z" }, - { url = "https://files.pythonhosted.org/packages/a2/1c/769552a9d840065137272ebe86ffbb0bc92b0f1e0a68ee5266a225f8cd7b/sqlalchemy-2.0.45-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e90a344c644a4fa871eb01809c32096487928bd2038bf10f3e4515cb688cc56", size = 2153860, upload-time = "2025-12-10T20:03:23.843Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f8/9be54ff620e5b796ca7b44670ef58bc678095d51b0e89d6e3102ea468216/sqlalchemy-2.0.45-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8c8b41b97fba5f62349aa285654230296829672fc9939cd7f35aab246d1c08b", size = 3309379, upload-time = "2025-12-09T22:06:07.461Z" }, - { url = "https://files.pythonhosted.org/packages/f6/2b/60ce3ee7a5ae172bfcd419ce23259bb874d2cddd44f67c5df3760a1e22f9/sqlalchemy-2.0.45-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:12c694ed6468333a090d2f60950e4250b928f457e4962389553d6ba5fe9951ac", size = 3309948, upload-time = "2025-12-09T22:09:57.643Z" }, - { url = "https://files.pythonhosted.org/packages/a3/42/bac8d393f5db550e4e466d03d16daaafd2bad1f74e48c12673fb499a7fc1/sqlalchemy-2.0.45-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7d27a1d977a1cfef38a0e2e1ca86f09c4212666ce34e6ae542f3ed0a33bc606", size = 3261239, upload-time = "2025-12-09T22:06:08.879Z" }, - { url = "https://files.pythonhosted.org/packages/6f/12/43dc70a0528c59842b04ea1c1ed176f072a9b383190eb015384dd102fb19/sqlalchemy-2.0.45-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d62e47f5d8a50099b17e2bfc1b0c7d7ecd8ba6b46b1507b58cc4f05eefc3bb1c", size = 3284065, upload-time = "2025-12-09T22:09:59.454Z" }, - { url = "https://files.pythonhosted.org/packages/cf/9c/563049cf761d9a2ec7bc489f7879e9d94e7b590496bea5bbee9ed7b4cc32/sqlalchemy-2.0.45-cp311-cp311-win32.whl", hash = "sha256:3c5f76216e7b85770d5bb5130ddd11ee89f4d52b11783674a662c7dd57018177", size = 2113480, upload-time = "2025-12-09T21:29:57.03Z" }, - { url = "https://files.pythonhosted.org/packages/bc/fa/09d0a11fe9f15c7fa5c7f0dd26be3d235b0c0cbf2f9544f43bc42efc8a24/sqlalchemy-2.0.45-cp311-cp311-win_amd64.whl", hash = "sha256:a15b98adb7f277316f2c276c090259129ee4afca783495e212048daf846654b2", size = 2138407, upload-time = "2025-12-09T21:29:58.556Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c7/1900b56ce19bff1c26f39a4ce427faec7716c81ac792bfac8b6a9f3dca93/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f", size = 3333760, upload-time = "2025-12-09T22:11:02.66Z" }, - { url = "https://files.pythonhosted.org/packages/0a/93/3be94d96bb442d0d9a60e55a6bb6e0958dd3457751c6f8502e56ef95fed0/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d", size = 3348268, upload-time = "2025-12-09T22:13:49.054Z" }, - { url = "https://files.pythonhosted.org/packages/48/4b/f88ded696e61513595e4a9778f9d3f2bf7332cce4eb0c7cedaabddd6687b/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4", size = 3278144, upload-time = "2025-12-09T22:11:04.14Z" }, - { url = "https://files.pythonhosted.org/packages/ed/6a/310ecb5657221f3e1bd5288ed83aa554923fb5da48d760a9f7622afeb065/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6", size = 3313907, upload-time = "2025-12-09T22:13:50.598Z" }, - { url = "https://files.pythonhosted.org/packages/5c/39/69c0b4051079addd57c84a5bfb34920d87456dd4c90cf7ee0df6efafc8ff/sqlalchemy-2.0.45-cp312-cp312-win32.whl", hash = "sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953", size = 2112182, upload-time = "2025-12-09T21:39:30.824Z" }, - { url = "https://files.pythonhosted.org/packages/f7/4e/510db49dd89fc3a6e994bee51848c94c48c4a00dc905e8d0133c251f41a7/sqlalchemy-2.0.45-cp312-cp312-win_amd64.whl", hash = "sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1", size = 2139200, upload-time = "2025-12-09T21:39:32.321Z" }, - { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, - { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, - { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, - { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, - { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, - { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, - { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, - { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, - { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, - { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, - { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, - { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, - { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, - { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, - { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/06/aa/9ce0f3e7a9829ead5c8ce549392f33a12c4555a6c0609bb27d882e9c7ddf/sqlalchemy-2.0.46.tar.gz", hash = "sha256:cf36851ee7219c170bb0793dbc3da3e80c582e04a5437bc601bfe8c85c9216d7", size = 9865393, upload-time = "2026-01-21T18:03:45.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/26/66ba59328dc25e523bfcb0f8db48bdebe2035e0159d600e1f01c0fc93967/sqlalchemy-2.0.46-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:895296687ad06dc9b11a024cf68e8d9d3943aa0b4964278d2553b86f1b267735", size = 2155051, upload-time = "2026-01-21T18:27:28.965Z" }, + { url = "https://files.pythonhosted.org/packages/21/cd/9336732941df972fbbfa394db9caa8bb0cf9fe03656ec728d12e9cbd6edc/sqlalchemy-2.0.46-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab65cb2885a9f80f979b85aa4e9c9165a31381ca322cbde7c638fe6eefd1ec39", size = 3234666, upload-time = "2026-01-21T18:32:28.72Z" }, + { url = "https://files.pythonhosted.org/packages/38/62/865ae8b739930ec433cd4123760bee7f8dafdc10abefd725a025604fb0de/sqlalchemy-2.0.46-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:52fe29b3817bd191cc20bad564237c808967972c97fa683c04b28ec8979ae36f", size = 3232917, upload-time = "2026-01-21T18:44:54.064Z" }, + { url = "https://files.pythonhosted.org/packages/24/38/805904b911857f2b5e00fdea44e9570df62110f834378706939825579296/sqlalchemy-2.0.46-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:09168817d6c19954d3b7655da6ba87fcb3a62bb575fb396a81a8b6a9fadfe8b5", size = 3185790, upload-time = "2026-01-21T18:32:30.581Z" }, + { url = "https://files.pythonhosted.org/packages/69/4f/3260bb53aabd2d274856337456ea52f6a7eccf6cce208e558f870cec766b/sqlalchemy-2.0.46-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:be6c0466b4c25b44c5d82b0426b5501de3c424d7a3220e86cd32f319ba56798e", size = 3207206, upload-time = "2026-01-21T18:44:55.93Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b3/67c432d7f9d88bb1a61909b67e29f6354d59186c168fb5d381cf438d3b73/sqlalchemy-2.0.46-cp310-cp310-win32.whl", hash = "sha256:1bc3f601f0a818d27bfe139f6766487d9c88502062a2cd3a7ee6c342e81d5047", size = 2115296, upload-time = "2026-01-21T18:33:12.498Z" }, + { url = "https://files.pythonhosted.org/packages/4a/8c/25fb284f570f9d48e6c240f0269a50cec9cf009a7e08be4c0aaaf0654972/sqlalchemy-2.0.46-cp310-cp310-win_amd64.whl", hash = "sha256:e0c05aff5c6b1bb5fb46a87e0f9d2f733f83ef6cbbbcd5c642b6c01678268061", size = 2138540, upload-time = "2026-01-21T18:33:14.22Z" }, + { url = "https://files.pythonhosted.org/packages/69/ac/b42ad16800d0885105b59380ad69aad0cce5a65276e269ce2729a2343b6a/sqlalchemy-2.0.46-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:261c4b1f101b4a411154f1da2b76497d73abbfc42740029205d4d01fa1052684", size = 2154851, upload-time = "2026-01-21T18:27:30.54Z" }, + { url = "https://files.pythonhosted.org/packages/a0/60/d8710068cb79f64d002ebed62a7263c00c8fd95f4ebd4b5be8f7ca93f2bc/sqlalchemy-2.0.46-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:181903fe8c1b9082995325f1b2e84ac078b1189e2819380c2303a5f90e114a62", size = 3311241, upload-time = "2026-01-21T18:32:33.45Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/20c71487c7219ab3aa7421c7c62d93824c97c1460f2e8bb72404b0192d13/sqlalchemy-2.0.46-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:590be24e20e2424a4c3c1b0835e9405fa3d0af5823a1a9fc02e5dff56471515f", size = 3310741, upload-time = "2026-01-21T18:44:57.887Z" }, + { url = "https://files.pythonhosted.org/packages/65/80/d26d00b3b249ae000eee4db206fcfc564bf6ca5030e4747adf451f4b5108/sqlalchemy-2.0.46-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7568fe771f974abadce52669ef3a03150ff03186d8eb82613bc8adc435a03f01", size = 3263116, upload-time = "2026-01-21T18:32:35.044Z" }, + { url = "https://files.pythonhosted.org/packages/da/ee/74dda7506640923821340541e8e45bd3edd8df78664f1f2e0aae8077192b/sqlalchemy-2.0.46-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf7e1e78af38047e08836d33502c7a278915698b7c2145d045f780201679999", size = 3285327, upload-time = "2026-01-21T18:44:59.254Z" }, + { url = "https://files.pythonhosted.org/packages/9f/25/6dcf8abafff1389a21c7185364de145107b7394ecdcb05233815b236330d/sqlalchemy-2.0.46-cp311-cp311-win32.whl", hash = "sha256:9d80ea2ac519c364a7286e8d765d6cd08648f5b21ca855a8017d9871f075542d", size = 2114564, upload-time = "2026-01-21T18:33:15.85Z" }, + { url = "https://files.pythonhosted.org/packages/93/5f/e081490f8523adc0088f777e4ebad3cac21e498ec8a3d4067074e21447a1/sqlalchemy-2.0.46-cp311-cp311-win_amd64.whl", hash = "sha256:585af6afe518732d9ccd3aea33af2edaae4a7aa881af5d8f6f4fe3a368699597", size = 2139233, upload-time = "2026-01-21T18:33:17.528Z" }, + { url = "https://files.pythonhosted.org/packages/b6/35/d16bfa235c8b7caba3730bba43e20b1e376d2224f407c178fbf59559f23e/sqlalchemy-2.0.46-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a9a72b0da8387f15d5810f1facca8f879de9b85af8c645138cba61ea147968c", size = 2153405, upload-time = "2026-01-21T19:05:54.143Z" }, + { url = "https://files.pythonhosted.org/packages/06/6c/3192e24486749862f495ddc6584ed730c0c994a67550ec395d872a2ad650/sqlalchemy-2.0.46-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2347c3f0efc4de367ba00218e0ae5c4ba2306e47216ef80d6e31761ac97cb0b9", size = 3334702, upload-time = "2026-01-21T18:46:45.384Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a2/b9f33c8d68a3747d972a0bb758c6b63691f8fb8a49014bc3379ba15d4274/sqlalchemy-2.0.46-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9094c8b3197db12aa6f05c51c05daaad0a92b8c9af5388569847b03b1007fb1b", size = 3347664, upload-time = "2026-01-21T18:40:09.979Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d2/3e59e2a91eaec9db7e8dc6b37b91489b5caeb054f670f32c95bcba98940f/sqlalchemy-2.0.46-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37fee2164cf21417478b6a906adc1a91d69ae9aba8f9533e67ce882f4bb1de53", size = 3277372, upload-time = "2026-01-21T18:46:47.168Z" }, + { url = "https://files.pythonhosted.org/packages/dd/dd/67bc2e368b524e2192c3927b423798deda72c003e73a1e94c21e74b20a85/sqlalchemy-2.0.46-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1e14b2f6965a685c7128bd315e27387205429c2e339eeec55cb75ca4ab0ea2e", size = 3312425, upload-time = "2026-01-21T18:40:11.548Z" }, + { url = "https://files.pythonhosted.org/packages/43/82/0ecd68e172bfe62247e96cb47867c2d68752566811a4e8c9d8f6e7c38a65/sqlalchemy-2.0.46-cp312-cp312-win32.whl", hash = "sha256:412f26bb4ba942d52016edc8d12fb15d91d3cd46b0047ba46e424213ad407bcb", size = 2113155, upload-time = "2026-01-21T18:42:49.748Z" }, + { url = "https://files.pythonhosted.org/packages/bc/2a/2821a45742073fc0331dc132552b30de68ba9563230853437cac54b2b53e/sqlalchemy-2.0.46-cp312-cp312-win_amd64.whl", hash = "sha256:ea3cd46b6713a10216323cda3333514944e510aa691c945334713fca6b5279ff", size = 2140078, upload-time = "2026-01-21T18:42:51.197Z" }, + { url = "https://files.pythonhosted.org/packages/b3/4b/fa7838fe20bb752810feed60e45625a9a8b0102c0c09971e2d1d95362992/sqlalchemy-2.0.46-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:93a12da97cca70cea10d4b4fc602589c4511f96c1f8f6c11817620c021d21d00", size = 2150268, upload-time = "2026-01-21T19:05:56.621Z" }, + { url = "https://files.pythonhosted.org/packages/46/c1/b34dccd712e8ea846edf396e00973dda82d598cb93762e55e43e6835eba9/sqlalchemy-2.0.46-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af865c18752d416798dae13f83f38927c52f085c52e2f32b8ab0fef46fdd02c2", size = 3276511, upload-time = "2026-01-21T18:46:49.022Z" }, + { url = "https://files.pythonhosted.org/packages/96/48/a04d9c94753e5d5d096c628c82a98c4793b9c08ca0e7155c3eb7d7db9f24/sqlalchemy-2.0.46-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8d679b5f318423eacb61f933a9a0f75535bfca7056daeadbf6bd5bcee6183aee", size = 3292881, upload-time = "2026-01-21T18:40:13.089Z" }, + { url = "https://files.pythonhosted.org/packages/be/f4/06eda6e91476f90a7d8058f74311cb65a2fb68d988171aced81707189131/sqlalchemy-2.0.46-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:64901e08c33462acc9ec3bad27fc7a5c2b6491665f2aa57564e57a4f5d7c52ad", size = 3224559, upload-time = "2026-01-21T18:46:50.974Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a2/d2af04095412ca6345ac22b33b89fe8d6f32a481e613ffcb2377d931d8d0/sqlalchemy-2.0.46-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e8ac45e8f4eaac0f9f8043ea0e224158855c6a4329fd4ee37c45c61e3beb518e", size = 3262728, upload-time = "2026-01-21T18:40:14.883Z" }, + { url = "https://files.pythonhosted.org/packages/31/48/1980c7caa5978a3b8225b4d230e69a2a6538a3562b8b31cea679b6933c83/sqlalchemy-2.0.46-cp313-cp313-win32.whl", hash = "sha256:8d3b44b3d0ab2f1319d71d9863d76eeb46766f8cf9e921ac293511804d39813f", size = 2111295, upload-time = "2026-01-21T18:42:52.366Z" }, + { url = "https://files.pythonhosted.org/packages/2d/54/f8d65bbde3d877617c4720f3c9f60e99bb7266df0d5d78b6e25e7c149f35/sqlalchemy-2.0.46-cp313-cp313-win_amd64.whl", hash = "sha256:77f8071d8fbcbb2dd11b7fd40dedd04e8ebe2eb80497916efedba844298065ef", size = 2137076, upload-time = "2026-01-21T18:42:53.924Z" }, + { url = "https://files.pythonhosted.org/packages/56/ba/9be4f97c7eb2b9d5544f2624adfc2853e796ed51d2bb8aec90bc94b7137e/sqlalchemy-2.0.46-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1e8cc6cc01da346dc92d9509a63033b9b1bda4fed7a7a7807ed385c7dccdc10", size = 3556533, upload-time = "2026-01-21T18:33:06.636Z" }, + { url = "https://files.pythonhosted.org/packages/20/a6/b1fc6634564dbb4415b7ed6419cdfeaadefd2c39cdab1e3aa07a5f2474c2/sqlalchemy-2.0.46-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96c7cca1a4babaaf3bfff3e4e606e38578856917e52f0384635a95b226c87764", size = 3523208, upload-time = "2026-01-21T18:45:08.436Z" }, + { url = "https://files.pythonhosted.org/packages/a1/d8/41e0bdfc0f930ff236f86fccd12962d8fa03713f17ed57332d38af6a3782/sqlalchemy-2.0.46-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b2a9f9aee38039cf4755891a1e50e1effcc42ea6ba053743f452c372c3152b1b", size = 3464292, upload-time = "2026-01-21T18:33:08.208Z" }, + { url = "https://files.pythonhosted.org/packages/f0/8b/9dcbec62d95bea85f5ecad9b8d65b78cc30fb0ffceeb3597961f3712549b/sqlalchemy-2.0.46-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:db23b1bf8cfe1f7fda19018e7207b20cdb5168f83c437ff7e95d19e39289c447", size = 3473497, upload-time = "2026-01-21T18:45:10.552Z" }, + { url = "https://files.pythonhosted.org/packages/e9/f8/5ecdfc73383ec496de038ed1614de9e740a82db9ad67e6e4514ebc0708a3/sqlalchemy-2.0.46-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:56bdd261bfd0895452006d5316cbf35739c53b9bb71a170a331fa0ea560b2ada", size = 2152079, upload-time = "2026-01-21T19:05:58.477Z" }, + { url = "https://files.pythonhosted.org/packages/e5/bf/eba3036be7663ce4d9c050bc3d63794dc29fbe01691f2bf5ccb64e048d20/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33e462154edb9493f6c3ad2125931e273bbd0be8ae53f3ecd1c161ea9a1dd366", size = 3272216, upload-time = "2026-01-21T18:46:52.634Z" }, + { url = "https://files.pythonhosted.org/packages/05/45/1256fb597bb83b58a01ddb600c59fe6fdf0e5afe333f0456ed75c0f8d7bd/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bcdce05f056622a632f1d44bb47dbdb677f58cad393612280406ce37530eb6d", size = 3277208, upload-time = "2026-01-21T18:40:16.38Z" }, + { url = "https://files.pythonhosted.org/packages/d9/a0/2053b39e4e63b5d7ceb3372cface0859a067c1ddbd575ea7e9985716f771/sqlalchemy-2.0.46-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8e84b09a9b0f19accedcbeff5c2caf36e0dd537341a33aad8d680336152dc34e", size = 3221994, upload-time = "2026-01-21T18:46:54.622Z" }, + { url = "https://files.pythonhosted.org/packages/1e/87/97713497d9502553c68f105a1cb62786ba1ee91dea3852ae4067ed956a50/sqlalchemy-2.0.46-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4f52f7291a92381e9b4de9050b0a65ce5d6a763333406861e33906b8aa4906bf", size = 3243990, upload-time = "2026-01-21T18:40:18.253Z" }, + { url = "https://files.pythonhosted.org/packages/a8/87/5d1b23548f420ff823c236f8bea36b1a997250fd2f892e44a3838ca424f4/sqlalchemy-2.0.46-cp314-cp314-win32.whl", hash = "sha256:70ed2830b169a9960193f4d4322d22be5c0925357d82cbf485b3369893350908", size = 2114215, upload-time = "2026-01-21T18:42:55.232Z" }, + { url = "https://files.pythonhosted.org/packages/3a/20/555f39cbcf0c10cf452988b6a93c2a12495035f68b3dbd1a408531049d31/sqlalchemy-2.0.46-cp314-cp314-win_amd64.whl", hash = "sha256:3c32e993bc57be6d177f7d5d31edb93f30726d798ad86ff9066d75d9bf2e0b6b", size = 2139867, upload-time = "2026-01-21T18:42:56.474Z" }, + { url = "https://files.pythonhosted.org/packages/3e/f0/f96c8057c982d9d8a7a68f45d69c674bc6f78cad401099692fe16521640a/sqlalchemy-2.0.46-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4dafb537740eef640c4d6a7c254611dca2df87eaf6d14d6a5fca9d1f4c3fc0fa", size = 3561202, upload-time = "2026-01-21T18:33:10.337Z" }, + { url = "https://files.pythonhosted.org/packages/d7/53/3b37dda0a5b137f21ef608d8dfc77b08477bab0fe2ac9d3e0a66eaeab6fc/sqlalchemy-2.0.46-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42a1643dc5427b69aca967dae540a90b0fbf57eaf248f13a90ea5930e0966863", size = 3526296, upload-time = "2026-01-21T18:45:12.657Z" }, + { url = "https://files.pythonhosted.org/packages/33/75/f28622ba6dde79cd545055ea7bd4062dc934e0621f7b3be2891f8563f8de/sqlalchemy-2.0.46-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ff33c6e6ad006bbc0f34f5faf941cfc62c45841c64c0a058ac38c799f15b5ede", size = 3470008, upload-time = "2026-01-21T18:33:11.725Z" }, + { url = "https://files.pythonhosted.org/packages/a9/42/4afecbbc38d5e99b18acef446453c76eec6fbd03db0a457a12a056836e22/sqlalchemy-2.0.46-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:82ec52100ec1e6ec671563bbd02d7c7c8d0b9e71a0723c72f22ecf52d1755330", size = 3476137, upload-time = "2026-01-21T18:45:15.001Z" }, + { url = "https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl", hash = "sha256:f9c11766e7e7c0a2767dda5acb006a118640c9fc0a4104214b96269bfb78399e", size = 1937882, upload-time = "2026-01-21T18:22:10.456Z" }, ] [[package]] @@ -3574,11 +3829,11 @@ wheels = [ [[package]] name = "wcwidth" -version = "0.2.14" +version = "0.3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/fc/44799c4a51ff0da0de0ff27e68c9dea3454f3d9bf15ffb606aeb6943e672/wcwidth-0.3.5.tar.gz", hash = "sha256:7c3463f312540cf21ddd527ea34f3ae95c057fa191aa7a9e043898d20d636e59", size = 234185, upload-time = "2026-01-25T04:37:23.942Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, + { url = "https://files.pythonhosted.org/packages/7a/86/7f461495625145a99d60f14cdac142a11db5d501c86d48aad165575d1e06/wcwidth-0.3.5-py3-none-any.whl", hash = "sha256:b0a0245130566939a24ab8432e625b38272fbc62ecbe5aecbdcb50b8f02ce993", size = 86681, upload-time = "2026-01-25T04:37:22.585Z" }, ] [[package]] From 604bc22868f5b3b55dc8fd23e2eee84b88009b84 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 08:50:54 +0000 Subject: [PATCH 037/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/decomposer/Decomposer.hpp | 156 ++++--- src/na/zoned/decomposer/Decomposer.cpp | 153 +++---- test/na/zoned/test_decomposer.cpp | 452 ++++++++++++--------- 3 files changed, 432 insertions(+), 329 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index f9faebf99..c9b6bd8bc 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + #pragma once #include "DecomposerBase.hpp" @@ -8,74 +18,90 @@ namespace na::zoned { - class Decomposer : public DecomposerBase{ - private: - struct struct_U3{ - std::array angles; - int qubit; - } ; - static inline constexpr qc::fp epsilon=1e-5; - int N_qubits; +class Decomposer : public DecomposerBase { +private: + struct struct_U3 { + std::array angles; + int qubit; + }; + static inline constexpr qc::fp epsilon = 1e-5; + int N_qubits; - public: - /** - * Converts commonly used single qubit gates into their Quaternion representation - * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) with X,Y,Z Pauli Matrices - * @param op a reference_wrapper to the operation to be converted - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the quaternion - */ - static auto convert_gate_to_quaternion(std::reference_wrapper op) -> std::array; - /** - * Merges the quaternions representing two gates as in a Matrix multiplication of the gates - * @param q1 the first Quaternion to be combined - * @param q2 the second Quaternion to be combined - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the components of the combined quaternion - */ - static auto combine_quaternions(const std::array& q1, - const std::array& q2) -> std::array; - /** - * Calculates the values of the U3-Gate parameters theta, phi and lambda - * @param quat is a quaternion representing a single qubit gate - * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ gate angles - */ - static auto get_U3_angles_from_quaternion(const std::array& quat) -> std::array; +public: + /** + * Converts commonly used single qubit gates into their Quaternion + * representation + * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) + * with X,Y,Z Pauli Matrices + * @param op a reference_wrapper to the operation to be converted + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the + * components of the quaternion + */ + static auto + convert_gate_to_quaternion(std::reference_wrapper op) + -> std::array; + /** + * Merges the quaternions representing two gates as in a Matrix multiplication + * of the gates + * @param q1 the first Quaternion to be combined + * @param q2 the second Quaternion to be combined + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the + * components of the combined quaternion + */ + static auto combine_quaternions(const std::array& q1, + const std::array& q2) + -> std::array; + /** + * Calculates the values of the U3-Gate parameters theta, phi and lambda + * @param quat is a quaternion representing a single qubit gate + * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ + * gate angles + */ + static auto get_U3_angles_from_quaternion(const std::array& quat) + -> std::array; - /** - * Calculates the largest value of the U3-Gate parameter theta from a vector - * of Operations. Fails when provided gates aren't all U3-Gates. - * @param layer is a SingleQubitGateLayers of a scheduled - * @returns the maximal value of theta in the given layer - */ - static auto calc_theta_max(const std::vector& layer)->qc::fp; + /** + * Calculates the largest value of the U3-Gate parameter theta from a vector + * of Operations. Fails when provided gates aren't all U3-Gates. + * @param layer is a SingleQubitGateLayers of a scheduled + * @returns the maximal value of theta in the given layer + */ + static auto calc_theta_max(const std::vector& layer) -> qc::fp; - /** - * Takes a vector of SingleQubitGateLayer's and, for each layer - * , transforms all gates into U3 gates represented by struct_U3's - * , combining all gates acting on the same qubit into a single U3 gate - * @param layers is a std::vector of SingleQubitGateLayers of a scheduled circuit - * @returns a vector of vectors of a struct_U3's representing the single qubit gate layers - */ - [[nodiscard]] auto transform_to_U3(const std::vector& layers) const - -> std::vector>; - /** - * Takes a vector of qc::fp's representing the U3-Gate angles of a single qubit hate and the maximal value of theta - * for the single qubit gate layer and calculates the transversal decomposition angles as in Nottingham et. al. 2024 - * @param angles is a std::array of qc::fp representing (theta,phi, lambda) - * @param theta_max the maximal theta value of the single-qubit qate layer - * @returns an array of qc::fp values giving the angles (chi, gamma_minus, gamma_plus) - */ - auto static get_decomposition_angles (const std::array& angles,qc::fp theta_max )-> std::array; - /** - * Create a new Decomposer. - * @param n_qubits is the number of qubits in the circuit to be decomposed - */ - Decomposer(int n_qubits); + /** + * Takes a vector of SingleQubitGateLayer's and, for each layer + * , transforms all gates into U3 gates represented by struct_U3's + * , combining all gates acting on the same qubit into a single U3 gate + * @param layers is a std::vector of SingleQubitGateLayers of a scheduled + * circuit + * @returns a vector of vectors of a struct_U3's representing the single qubit + * gate layers + */ + [[nodiscard]] auto + transform_to_U3(const std::vector& layers) const + -> std::vector>; + /** + * Takes a vector of qc::fp's representing the U3-Gate angles of a single + * qubit hate and the maximal value of theta for the single qubit gate layer + * and calculates the transversal decomposition angles as in Nottingham et. + * al. 2024 + * @param angles is a std::array of qc::fp representing (theta,phi, lambda) + * @param theta_max the maximal theta value of the single-qubit qate layer + * @returns an array of qc::fp values giving the angles (chi, gamma_minus, + * gamma_plus) + */ + auto static get_decomposition_angles(const std::array& angles, + qc::fp theta_max) + -> std::array; + /** + * Create a new Decomposer. + * @param n_qubits is the number of qubits in the circuit to be decomposed + */ + Decomposer(int n_qubits); - [[nodiscard]] auto - decompose(const std::vector& singleQubitGateLayers) const + [[nodiscard]] auto decompose( + const std::vector& singleQubitGateLayers) const -> std::vector override; +}; - - }; - -} // namespace na::zoned \ No newline at end of file +} // namespace na::zoned diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp index f17c6c793..f44761054 100644 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ b/src/na/zoned/decomposer/Decomposer.cpp @@ -1,19 +1,26 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + // // Created by cpsch on 11.12.2025. // #include "na/zoned/decomposer/decomposer.hpp" -//#include "ir/operations/StandardOperation.hpp" +// #include "ir/operations/StandardOperation.hpp" #include "ir/operations/CompoundOperation.hpp" #include #include namespace na::zoned { -Decomposer::Decomposer(int n_qubits) { - N_qubits=n_qubits; -}; - +Decomposer::Decomposer(int n_qubits) { N_qubits = n_qubits; }; auto Decomposer::convert_gate_to_quaternion( std::reference_wrapper op) -> std::array { @@ -99,9 +106,8 @@ auto Decomposer::combine_quaternions(const std::array& q1, return new_quat; } - auto Decomposer::get_U3_angles_from_quaternion( - const std::array& quat) - -> std::array { +auto Decomposer::get_U3_angles_from_quaternion( + const std::array& quat) -> std::array { // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be // defined qc::fp theta; @@ -110,14 +116,14 @@ auto Decomposer::combine_quaternions(const std::array& q1, if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); - qc::fp alph_1 = std::atan2(quat[3], quat[0]); // phi+ lambda + qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // phi+ lambda if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { - qc::fp alph_2 = -1 * std::atan2(quat[1], quat[2]); - phi = alph_1 + alph_2; // phi - lambda = alph_1 - alph_2; + qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); + phi = alpha_1 + alpha_2; // phi + lambda = alpha_1 - alpha_2; } else { phi = 0; - lambda = 2 * alph_1; + lambda = 2 * alpha_1; } } else { theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= @@ -135,18 +141,18 @@ auto Decomposer::combine_quaternions(const std::array& q1, return {theta, phi, lambda}; } - auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { +auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { - if (abs(gate.angles[0]) > theta_max) { - theta_max = abs(gate.angles[0]); - } + if (abs(gate.angles[0]) > theta_max) { + theta_max = abs(gate.angles[0]); + } } return theta_max; } - auto Decomposer::transform_to_U3( - const std::vector& layers) const - -> std::vector> { +auto Decomposer::transform_to_U3( + const std::vector& layers) const + -> std::vector> { // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { @@ -166,8 +172,7 @@ auto Decomposer::combine_quaternions(const std::array& q1, } std::array angles = get_U3_angles_from_quaternion(quat); new_layer.emplace_back( - struct_U3(angles, - qubit_gates[0].get().getTargets().front())); + struct_U3(angles, qubit_gates[0].get().getTargets().front())); } } new_layers.push_back(new_layer); @@ -175,87 +180,99 @@ auto Decomposer::combine_quaternions(const std::array& q1, return new_layers; } auto Decomposer::get_decomposition_angles(const std::array& angles, - qc::fp theta_max)-> std::array{ + qc::fp theta_max) + -> std::array { qc::fp alpha, chi, beta; - //U3(theta,phi_min(phi),phi_plus(lamda)->Rz(gamma_minus)GR(theta_max/2, PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - if (abs(angles[0]-theta_max) < epsilon) { - chi=qc::PI; - if (abs(cos(theta_max/2))Rz(gamma_minus)GR(theta_max/2, + // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) + if (abs(angles[0] - theta_max) < epsilon) { + chi = qc::PI; + if (abs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? + alpha = 0; + } else { + alpha = qc::PI_2; } - }else { - qc::fp kappa=sqrt((sin(angles[0]/2)*sin(angles[0]/2))/(sin(theta_max)*sin(theta_max)-(sin(angles[0]/2)*sin(angles[0]/2)))); - alpha=atan(cos(theta_max/2)*kappa); - chi=fmod(2*atan(kappa),qc::TAU); + } else { + qc::fp kappa = sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / + (sin(theta_max) * sin(theta_max) - + (sin(angles[0] / 2) * sin(angles[0] / 2)))); + alpha = atan(cos(theta_max / 2) * kappa); + chi = fmod(2 * atan(kappa), qc::TAU); } - beta=angles[0]<0?-1*qc::PI_2:qc::PI_2; - qc::fp gamma_plus=fmod(angles[2]-(alpha+beta),qc::TAU); - qc::fp gamma_minus=fmod(angles[1]-(alpha-beta),qc::TAU); + beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; + qc::fp gamma_plus = fmod(angles[2] - (alpha + beta), qc::TAU); + qc::fp gamma_minus = fmod(angles[1] - (alpha - beta), qc::TAU); - return {chi,gamma_minus,gamma_plus}; + return {chi, gamma_minus, gamma_plus}; } +auto Decomposer::decompose( + const std::vector& singleQubitGateLayers) const + -> std::vector { -auto Decomposer::decompose(const std::vector& singleQubitGateLayers) const - -> std::vector{ + std::vector> U3Layers = + transform_to_U3(singleQubitGateLayers); + std::vector NewSingleQubitLayers = + std::vector{}; - std::vector> U3Layers=transform_to_U3(singleQubitGateLayers); - std::vector NewSingleQubitLayers=std::vector{}; - - for (const auto& layer: U3Layers) { - qc::fp theta_max=calc_theta_max(layer); + for (const auto& layer : U3Layers) { + qc::fp theta_max = calc_theta_max(layer); SingleQubitGateLayer FrontLayer; SingleQubitGateLayer MidLayer; SingleQubitGateLayer BackLayer; SingleQubitGateLayer NewLayer; - for (auto gate:layer){ - std::array decomp_angles=get_decomposition_angles(gate.angles,theta_max); + for (auto gate : layer) { + std::array decomp_angles = + get_decomposition_angles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - auto sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[1]}); - std::unique_ptr op=std::make_unique(sop); + auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); + std::unique_ptr op = + std::make_unique(sop); FrontLayer.emplace_back(std::move(op)); - sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[0]}); - op=std::make_unique(sop); + sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}); + op = std::make_unique(sop); MidLayer.emplace_back(std::move(op)); - sop=qc::StandardOperation(gate.qubit,qc::RZ,{decomp_angles[2]}); - op=std::make_unique(sop); + sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}); + op = std::make_unique(sop); BackLayer.emplace_back(std::move(op)); - }//gate::layer + } // gate::layer - std::vector< std::unique_ptr> GR_plus; - std::vector< std::unique_ptr> GR_minus; + std::vector> GR_plus; + std::vector> GR_minus; - for (auto i=0; iN_qubits; ++i) { - GR_plus.emplace_back(new qc::StandardOperation(i,qc::RY,{theta_max/2})); - GR_minus.emplace_back(new qc::StandardOperation(i,qc::RY,{-1*theta_max/2})); + for (auto i = 0; i < this->N_qubits; ++i) { + GR_plus.emplace_back( + new qc::StandardOperation(i, qc::RY, {theta_max / 2})); + GR_minus.emplace_back( + new qc::StandardOperation(i, qc::RY, {-1 * theta_max / 2})); } - for (auto&& gate:FrontLayer) { + for (auto&& gate : FrontLayer) { NewLayer.push_back(std::move(gate)); } - auto cop= qc::CompoundOperation(std::move(GR_plus),true); - std::unique_ptr ryp=std::make_unique(cop); + auto cop = qc::CompoundOperation(std::move(GR_plus), true); + std::unique_ptr ryp = + std::make_unique(cop); NewLayer.emplace_back(std::move(ryp)); - for (auto&& gate:MidLayer) { + for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - cop=qc::CompoundOperation(std::move(GR_minus),true); - std::unique_ptr rym=std::make_unique(cop); + cop = qc::CompoundOperation(std::move(GR_minus), true); + std::unique_ptr rym = + std::make_unique(cop); NewLayer.emplace_back(std::move(rym)); - for (auto&& gate:BackLayer) { + for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); } NewSingleQubitLayers.push_back(std::move(NewLayer)); - }//layer::SingleQubitLayers + } // layer::SingleQubitLayers return NewSingleQubitLayers; } -}// namespace na::zoned \ No newline at end of file +} // namespace na::zoned diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp index d8b403bc8..f2ed429c7 100644 --- a/test/na/zoned/test_decomposer.cpp +++ b/test/na/zoned/test_decomposer.cpp @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + // // Created by cpsch on 16.12.2025. // @@ -34,10 +44,9 @@ constexpr std::string_view architectureJson = R"({ "rydberg_range": [[[5, 70], [55, 110]]] })"; - class DecomposerTest : public ::testing::Test { protected: - Decomposer decomposer=Decomposer(4); + Decomposer decomposer = Decomposer(4); Architecture architecture; ASAPScheduler::Config config{.maxFillingFactor = .8}; ASAPScheduler scheduler; @@ -46,208 +55,246 @@ class DecomposerTest : public ::testing::Test { scheduler(architecture, config) {} }; -qc::fp epsilon=1e-5; - -TEST(Test,ThreeQuaternionCombiTest) { - std::array q1={cos(qc::PI_4),0,0,sin(qc::PI_4)}; - std::array q2={cos(qc::PI_2),0,sin(qc::PI_2),0}; - std::array q12=Decomposer::combine_quaternions(q1,q2); - EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(-1*cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); - std::array q3={cos(qc::PI_2),0,0,sin(qc::PI_2)}; - std::array q13=Decomposer::combine_quaternions(q12,q3); - EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(cos(qc::PI_4),epsilon),::testing::DoubleNear(0,epsilon))); - +qc::fp epsilon = 1e-5; + +TEST(Test, ThreeQuaternionCombiTest) { + std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; + std::array q12 = Decomposer::combine_quaternions(q1, q2); + EXPECT_THAT(q12, ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), + ::testing::DoubleNear(cos(qc::PI_4), epsilon), + ::testing::DoubleNear(0, epsilon))); + std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; + std::array q13 = Decomposer::combine_quaternions(q12, q3); + EXPECT_THAT( + q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(cos(qc::PI_4), epsilon), + ::testing::DoubleNear(cos(qc::PI_4), epsilon), + ::testing::DoubleNear(0, epsilon))); } -TEST(Test,ThreeQuaternionU3Test) { - std::array q1={cos(qc::PI_2),0,0,sin(qc::PI_2)}; - std::array q2={cos(qc::PI_4/2),0,sin(qc::PI_4/2),0}; - std::array q12=Decomposer::combine_quaternions(q1,q2); - EXPECT_THAT(q12,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(-1*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(cos(qc::PI_4/2),epsilon))); - std::array q3={cos(qc::PI_4),0,0,sin(qc::PI_4)}; - std::array q13=Decomposer::combine_quaternions(q12,q3); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q13,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), - ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); - +TEST(Test, ThreeQuaternionU3Test) { + std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; + std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; + std::array q12 = Decomposer::combine_quaternions(q1, q2); + EXPECT_THAT(q12, ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); + std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + std::array q13 = Decomposer::combine_quaternions(q12, q3); + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q13, ::testing::ElementsAre( + ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); } -TEST(Test,SingleXGateAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::X); +TEST(Test, SingleXGateAngleTest) { + size_t n = 1; + const qc::Operation* op = new qc::StandardOperation(0, qc::X); qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - std::array q=Decomposer::convert_gate_to_quaternion( + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(-1*qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_THAT( + Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(-1 * qc::PI_2, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon))); } -TEST(Test,SingleU3GateAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI_4,qc::PI,qc::PI_2}); - std::array q=Decomposer::convert_gate_to_quaternion( +TEST(Test, SingleU3GateAngleTest) { + size_t n = 1; + const qc::Operation* op = + new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2*cos(qc::PI_4/2),epsilon), - ::testing::DoubleNear(-r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*sin(qc::PI_4/2),epsilon),::testing::DoubleNear(r2*cos(qc::PI_4/2),epsilon))); - - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI_4,epsilon), - ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q, ::testing::ElementsAre( + ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), + ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); + + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), + ::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, ThetaPiAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::U,{qc::PI,qc::PI,qc::PI_2}); - std::array q=Decomposer::convert_gate_to_quaternion( + size_t n = 1; + const qc::Operation* op = + new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(-r2,epsilon),::testing::DoubleNear(r2,epsilon),::testing::DoubleNear(0,epsilon))); - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(-1*qc::PI_2,epsilon))); - + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-r2, epsilon), + ::testing::DoubleNear(r2, epsilon), + ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); } TEST(Test, ThetaZeroAngleTest) { - size_t n=1; - const qc::Operation *op=new qc::StandardOperation(0,qc::U,{0,qc::PI,qc::PI_2}); - std::array q=Decomposer::convert_gate_to_quaternion( + size_t n = 1; + const qc::Operation* op = + new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - qc::fp r2=1/sqrt(2); - EXPECT_THAT(q,::testing::ElementsAre(::testing::DoubleNear(-r2,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon),::testing::DoubleNear(r2,epsilon))); - - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(3*qc::PI_2,epsilon))); - + qc::fp r2 = 1 / sqrt(2); + EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(r2, epsilon))); + + EXPECT_THAT( + Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(3 * qc::PI_2, epsilon))); } - - TEST(Test, RXDecompositionTest) { - size_t n=1; - std::array rx={qc::PI,-qc::PI_2,qc::PI_2}; - EXPECT_THAT(Decomposer::get_decomposition_angles(rx,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); - + size_t n = 1; + std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; + EXPECT_THAT(Decomposer::get_decomposition_angles(rx, qc::PI), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); } -TEST(Test,U3DecompositionTest) { - size_t n=1; - std::array u3={qc::PI_4,qc::PI,qc::PI_2}; - // gamm minus i - PI_" not PI_2 and gam_plus is 0 not PI!! - EXPECT_THAT(Decomposer::get_decomposition_angles(u3,qc::PI_4),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(qc::PI,epsilon),::testing::DoubleNear(-qc::PI_2,epsilon))); +TEST(Test, U3DecompositionTest) { + size_t n = 1; + std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; + // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! + EXPECT_THAT( + Decomposer::get_decomposition_angles(u3, qc::PI_4), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(-qc::PI_2, epsilon))); } -TEST(Test,DoubleDecompositionTest) { - size_t n=1; - std::array x1={qc::PI,-qc::PI_2,qc::PI_2}; - std::array z2={0,0,qc::PI}; - EXPECT_THAT(Decomposer::get_decomposition_angles(x1,qc::PI),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon), - ::testing::DoubleNear(0,epsilon),::testing::DoubleNear(0,epsilon))); - EXPECT_THAT(Decomposer::get_decomposition_angles(z2,qc::PI),::testing::ElementsAre(::testing::DoubleNear(0,epsilon), - ::testing::DoubleNear(qc::PI_2,epsilon),::testing::DoubleNear(qc::PI_2,epsilon))); - +TEST(Test, DoubleDecompositionTest) { + size_t n = 1; + std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; + std::array z2 = {0, 0, qc::PI}; + EXPECT_THAT(Decomposer::get_decomposition_angles(x1, qc::PI), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT(Decomposer::get_decomposition_angles(z2, qc::PI), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST_F(DecomposerTest, SingleRXGate) { // ┌───────┐ // q: ┤ Rx(π) ├ // └───────┘ - int n=1; + int n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - Decomposer decomposer=Decomposer(n); - const auto& sched = - scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } TEST_F(DecomposerTest, SingleU3Gate) { // ┌─────────────┐ // q: ┤ U3(0,π,π/2) ├ // └─────────────┘ - int n=1; + int n = 1; qc::QuantumComputation qc(n); - qc.u(0.0,qc::PI,qc::PI_2, 0); - Decomposer decomposer=Decomposer(n); - const auto& sched = - scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + qc.u(0.0, qc::PI, qc::PI_2, 0); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } -//TEST with U3(o,?,?) -//TEST with two Single Qubit Layers +// TEST with U3(o,?,?) +// TEST with two Single Qubit Layers TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ // q: ┤ X ├──┤ Z ├ // └───────┘ └───────┘ - size_t n=1; + size_t n = 1; qc::QuantumComputation qc(n); qc.x(0); qc.z(0); - Decomposer decomposer=Decomposer(n); - const auto& sched = - scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - //TODO: FIgure out i this is always Positive - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(3*qc::PI_2,epsilon))); - + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + // TODO: FIgure out i this is always Positive + EXPECT_THAT( + decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(3 * qc::PI_2, epsilon))); } TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { @@ -258,46 +305,51 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { // q_1: ─┤ Z ├─ // └───────┘ - size_t n=2; + size_t n = 2; qc::QuantumComputation qc(n); qc.x(0); qc.z(1); - Decomposer decomposer=Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),1); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 8); - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_EQ(decomp[0][1]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][1]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][1]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][1]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][1]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][2]->isCompoundOperation()); EXPECT_TRUE(decomp[0][2]->isGlobal(n)); - EXPECT_EQ(decomp[0][3]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][3]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][3]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][3]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][3]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); EXPECT_TRUE(decomp[0][5]->isCompoundOperation()); EXPECT_TRUE(decomp[0][5]->isGlobal(n)); - EXPECT_EQ(decomp[0][6]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][6]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - - EXPECT_EQ(decomp[0][7]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][7]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][6]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][6]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][6]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); + EXPECT_EQ(decomp[0][7]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][7]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[0][7]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } TEST_F(DecomposerTest, TwoQubitsTwoLayers) { @@ -308,70 +360,78 @@ TEST_F(DecomposerTest, TwoQubitsTwoLayers) { // q_1: ─────────────■───┤ X ├─ // └───────┘ - size_t n=2; + size_t n = 2; qc::QuantumComputation qc(n); qc.x(0); qc.cz(0, 1); qc.z(0); qc.x(1); - Decomposer decomposer=Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp=decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(),2); + Decomposer decomposer = Decomposer(n); + const auto& sched = scheduler.schedule(qc); + auto decomp = decomposer.decompose(sched.first); + EXPECT_EQ(decomp.size(), 2); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[1].size(), 8); - //Layer 1 - EXPECT_EQ(decomp[0][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + // Layer 1 + EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][2]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[0][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - //Layer 2 + // Layer 2 - EXPECT_EQ(decomp[1][0]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][0]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][0]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[1][0]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][0]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_EQ(decomp[1][1]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][1]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][1]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[1][1]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][1]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][1]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); EXPECT_TRUE(decomp[1][2]->isCompoundOperation()); EXPECT_TRUE(decomp[1][2]->isGlobal(n)); - EXPECT_EQ(decomp[1][3]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][3]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][3]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(0,epsilon))); + EXPECT_EQ(decomp[1][3]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][3]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][3]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); - EXPECT_EQ(decomp[1][4]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][4]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][4]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI,epsilon))); + EXPECT_EQ(decomp[1][4]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][4]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][4]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); EXPECT_TRUE(decomp[1][5]->isCompoundOperation()); EXPECT_TRUE(decomp[1][5]->isGlobal(n)); - EXPECT_EQ(decomp[1][6]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][6]->getTargets(),::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][6]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); - - EXPECT_EQ(decomp[1][7]->getType(),qc::RZ); - EXPECT_THAT(decomp[1][7]->getTargets(),::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][7]->getParameter(),::testing::ElementsAre(::testing::DoubleNear(qc::PI_2,epsilon))); + EXPECT_EQ(decomp[1][6]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][6]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp[1][6]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); + EXPECT_EQ(decomp[1][7]->getType(), qc::RZ); + EXPECT_THAT(decomp[1][7]->getTargets(), ::testing::ElementsAre(1)); + EXPECT_THAT(decomp[1][7]->getParameter(), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } -} // namespace na::zoned \ No newline at end of file +} // namespace na::zoned From 78041d91fa644a93c707e2381283ef3adb72b4db Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:13:09 +0100 Subject: [PATCH 038/110] =?UTF-8?q?=F0=9F=8E=A8=20Adjust=20to=20naming=20c?= =?UTF-8?q?onvention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/decomposer/Decomposer.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp index c9b6bd8bc..310a560c1 100644 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ b/include/na/zoned/decomposer/Decomposer.hpp @@ -19,13 +19,11 @@ namespace na::zoned { class Decomposer : public DecomposerBase { -private: - struct struct_U3 { + struct StructU3 { std::array angles; - int qubit; + qc::Qubit qubit; }; - static inline constexpr qc::fp epsilon = 1e-5; - int N_qubits; + size_t nQubits; public: /** From f8c962bfa61796a1d56be0682a4053e487033264 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:22:14 +0100 Subject: [PATCH 039/110] =?UTF-8?q?=F0=9F=8E=A8=20Rename=20to=20NativeGate?= =?UTF-8?q?Decomposer=20and=20include=20in=20Compiler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/Compiler.hpp | 8 +- include/na/zoned/decomposer/Decomposer.hpp | 105 ----- .../zoned/decomposer/NativeGateDecomposer.hpp | 131 +++--- src/na/zoned/decomposer/Decomposer.cpp | 278 ----------- .../zoned/decomposer/NativeGateDecomposer.cpp | 187 ++++---- test/na/zoned/test_decomposer.cpp | 437 ------------------ test/na/zoned/test_native_gate_decomposer.cpp | 292 +++--------- 7 files changed, 208 insertions(+), 1230 deletions(-) delete mode 100644 include/na/zoned/decomposer/Decomposer.hpp delete mode 100644 src/na/zoned/decomposer/Decomposer.cpp delete mode 100644 test/na/zoned/test_decomposer.cpp diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index ce37b3414..f9c084eaa 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -204,7 +204,7 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Decomposing..."); const auto decomposingStart = std::chrono::system_clock::now(); const auto& decomposedSingleQubitGateLayers = - SELF.decompose(qComp.getNqubits(), singleQubitGateLayers); + SELF.decompose(singleQubitGateLayers); const auto decomposingEnd = std::chrono::system_clock::now(); statistics_.decomposingTime = std::chrono::duration_cast(decomposingEnd - @@ -314,9 +314,9 @@ class RoutingAwareCompiler final }; class RoutingAwareNativeGateCompiler final - : public Compiler { + : public Compiler { public: RoutingAwareNativeGateCompiler(const Architecture& architecture, const Config& config) diff --git a/include/na/zoned/decomposer/Decomposer.hpp b/include/na/zoned/decomposer/Decomposer.hpp deleted file mode 100644 index 310a560c1..000000000 --- a/include/na/zoned/decomposer/Decomposer.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM - * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH - * All rights reserved. - * - * SPDX-License-Identifier: MIT - * - * Licensed under the MIT License - */ - -#pragma once - -#include "DecomposerBase.hpp" -#include "ir/operations/StandardOperation.hpp" -#include "na/zoned/Types.hpp" - -#include - -namespace na::zoned { - -class Decomposer : public DecomposerBase { - struct StructU3 { - std::array angles; - qc::Qubit qubit; - }; - size_t nQubits; - -public: - /** - * Converts commonly used single qubit gates into their Quaternion - * representation - * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) - * with X,Y,Z Pauli Matrices - * @param op a reference_wrapper to the operation to be converted - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the - * components of the quaternion - */ - static auto - convert_gate_to_quaternion(std::reference_wrapper op) - -> std::array; - /** - * Merges the quaternions representing two gates as in a Matrix multiplication - * of the gates - * @param q1 the first Quaternion to be combined - * @param q2 the second Quaternion to be combined - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the - * components of the combined quaternion - */ - static auto combine_quaternions(const std::array& q1, - const std::array& q2) - -> std::array; - /** - * Calculates the values of the U3-Gate parameters theta, phi and lambda - * @param quat is a quaternion representing a single qubit gate - * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ - * gate angles - */ - static auto get_U3_angles_from_quaternion(const std::array& quat) - -> std::array; - - /** - * Calculates the largest value of the U3-Gate parameter theta from a vector - * of Operations. Fails when provided gates aren't all U3-Gates. - * @param layer is a SingleQubitGateLayers of a scheduled - * @returns the maximal value of theta in the given layer - */ - static auto calc_theta_max(const std::vector& layer) -> qc::fp; - - /** - * Takes a vector of SingleQubitGateLayer's and, for each layer - * , transforms all gates into U3 gates represented by struct_U3's - * , combining all gates acting on the same qubit into a single U3 gate - * @param layers is a std::vector of SingleQubitGateLayers of a scheduled - * circuit - * @returns a vector of vectors of a struct_U3's representing the single qubit - * gate layers - */ - [[nodiscard]] auto - transform_to_U3(const std::vector& layers) const - -> std::vector>; - /** - * Takes a vector of qc::fp's representing the U3-Gate angles of a single - * qubit hate and the maximal value of theta for the single qubit gate layer - * and calculates the transversal decomposition angles as in Nottingham et. - * al. 2024 - * @param angles is a std::array of qc::fp representing (theta,phi, lambda) - * @param theta_max the maximal theta value of the single-qubit qate layer - * @returns an array of qc::fp values giving the angles (chi, gamma_minus, - * gamma_plus) - */ - auto static get_decomposition_angles(const std::array& angles, - qc::fp theta_max) - -> std::array; - /** - * Create a new Decomposer. - * @param n_qubits is the number of qubits in the circuit to be decomposed - */ - Decomposer(int n_qubits); - - [[nodiscard]] auto decompose( - const std::vector& singleQubitGateLayers) const - -> std::vector override; -}; - -} // namespace na::zoned diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index a81cca4e4..1f453f0e5 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -19,109 +19,86 @@ namespace na::zoned { class NativeGateDecomposer : public DecomposerBase { - /** - * A minimal struct to store the parameters of a U3 gate along with the qubit - * it acts on. - */ struct StructU3 { std::array angles; qc::Qubit qubit; }; - /** - * A quaternion is represented by an array of four `qc::fp` values `{q0, q1, - * q2, q3}` denoting the components of the quaternion. - */ - using Quaternion = std::array; - size_t nQubits_ = 0; - - constexpr static qc::fp epsilon = - std::numeric_limits::epsilon() * 1024; + size_t nQubits; public: - /// The configuration of the NativeGateDecomposer - struct Config { - template - friend void to_json(BasicJsonType& /* unused */, - const Config& /* unused */) {} - template - friend void from_json(const BasicJsonType& /* unused */, - Config& /* unused */) {} - }; - - /// Create a new NativeGateDecomposer. - NativeGateDecomposer(const Architecture& /* unused */, - const Config& /* unused */) {} - /** - * @brief Converts commonly used single qubit gates into their Quaternion - * representation. - * @details A single qubit gate R_v(phi) with rotation axis v=(v0,v1,v2) - * and rotation angle phi can be represented as a quaternion: - * @code quaternion(R_v(phi)) = (cos(phi/2) * I, v0 * sin(phi/2) * X, v1 * - * sin(phi/2) * Y, v2 * sin(phi/2) * Z)@endcode with X, Y, Z Pauli Matrices. + * Converts commonly used single qubit gates into their Quaternion + * representation + * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) + * with X,Y,Z Pauli Matrices * @param op a reference_wrapper to the operation to be converted - * @returns a quaternion. + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the + * components of the quaternion */ static auto - convertGateToQuaternion(std::reference_wrapper op) - -> Quaternion; + convert_gate_to_quaternion(std::reference_wrapper op) + -> std::array; /** - * @brief Merges the quaternions representing two gates as in a matrix - * multiplication of the gates. - * @param q1 the first quaternion to be combined. - * @param q2 the second quaternion to be combined. - * @returns an quaternion. + * Merges the quaternions representing two gates as in a Matrix multiplication + * of the gates + * @param q1 the first Quaternion to be combined + * @param q2 the second Quaternion to be combined + * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the + * components of the combined quaternion */ - static auto combineQuaternions(const Quaternion& q1, const Quaternion& q2) - -> Quaternion; + static auto combine_quaternions(const std::array& q1, + const std::array& q2) + -> std::array; /** - * @brief Calculates the values of the U3-gate parameters theta, phi, and - * lambda. - * @param quat is a quaternion representing a single qubit gate. - * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving - * the U3 gate angles. + * Calculates the values of the U3-Gate parameters theta, phi and lambda + * @param quat is a quaternion representing a single qubit gate + * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ + * gate angles */ - static auto getU3AnglesFromQuaternion(const Quaternion& quat) + static auto get_U3_angles_from_quaternion(const std::array& quat) -> std::array; /** - * @brief Calculates the largest value of the U3-gate parameter theta from a - * vector of operations. - * @param layer is a vector of U3 parameters. - * @returns the maximal value of theta in the given layer. + * Calculates the largest value of the U3-Gate parameter theta from a vector + * of Operations. Fails when provided gates aren't all U3-Gates. + * @param layer is a SingleQubitGateLayers of a scheduled + * @returns the maximal value of theta in the given layer */ - static auto calcThetaMax(const std::vector& layer) -> qc::fp; + static auto calc_theta_max(const std::vector& layer) -> qc::fp; /** - * @brief Takes a vector of SingleQubitGateLayers and, for each layer, - * transforms all gates into U3 gates represented by `StructU3` objects. - * @details It combines all gates acting on the same qubit into a single U3 - * gate. + * Takes a vector of SingleQubitGateLayer's and, for each layer + * , transforms all gates into U3 gates represented by struct_U3's + * , combining all gates acting on the same qubit into a single U3 gate * @param layers is a std::vector of SingleQubitGateLayers of a scheduled - * circuit. - * @returns a vector of vectors of StructU3 objects representing the single - * qubit gate layers. + * circuit + * @returns a vector of vectors of a struct_U3's representing the single qubit + * gate layers */ [[nodiscard]] auto - transformToU3(const std::vector& layers) const - -> std::vector>; + transform_to_U3(const std::vector& layers) const + -> std::vector>; + /** + * Takes a vector of qc::fp's representing the U3-Gate angles of a single + * qubit hate and the maximal value of theta for the single qubit gate layer + * and calculates the transversal decomposition angles as in Nottingham et. + * al. 2024 + * @param angles is a std::array of qc::fp representing (theta,phi, lambda) + * @param theta_max the maximal theta value of the single-qubit qate layer + * @returns an array of qc::fp values giving the angles (chi, gamma_minus, + * gamma_plus) + */ + auto static get_decomposition_angles(const std::array& angles, + qc::fp theta_max) + -> std::array; /** - * @brief Takes a vector of `qc::fp` representing the U3-gate angles of a - * single-qubit gate and the maximal value of theta for the single qubit gate - * layer and calculates the transversal decomposition angles as in Nottingham - * et. al. 2024. - * @param angles is a `std::array` of `qc::fp` representing (theta, phi, - * lambda). - * @param theta_max the maximal theta value of the single-qubit gate layer. - * @returns an array of `qc::fp` values giving the angles (chi, gamma_minus, - * gamma_plus). + * Create a new Decomposer. + * @param n_qubits is the number of qubits in the circuit to be decomposed */ - auto static getDecompositionAngles(const std::array& angles, - qc::fp theta_max) -> std::array; + NativeGateDecomposer(int n_qubits); - [[nodiscard]] auto - decompose(size_t nQubits, - const std::vector& singleQubitGateLayers) + [[nodiscard]] auto decompose( + const std::vector& singleQubitGateLayers) const -> std::vector override; }; diff --git a/src/na/zoned/decomposer/Decomposer.cpp b/src/na/zoned/decomposer/Decomposer.cpp deleted file mode 100644 index f44761054..000000000 --- a/src/na/zoned/decomposer/Decomposer.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM - * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH - * All rights reserved. - * - * SPDX-License-Identifier: MIT - * - * Licensed under the MIT License - */ - -// -// Created by cpsch on 11.12.2025. -// -#include "na/zoned/decomposer/decomposer.hpp" - -// #include "ir/operations/StandardOperation.hpp" -#include "ir/operations/CompoundOperation.hpp" - -#include -#include - -namespace na::zoned { -Decomposer::Decomposer(int n_qubits) { N_qubits = n_qubits; }; - -auto Decomposer::convert_gate_to_quaternion( - std::reference_wrapper op) -> std::array { - assert(op.get().getNqubits() == 1); - std::array quat{}; - // TODO: Phase? - if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front()), 0, 0, - sin(op.get().getParameter().front())}; - } else if (op.get().getType() == qc::Z) { - quat = {0, 0, 0, 1}; - } else if (op.get().getType() == qc::S) { - quat = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - } else if (op.get().getType() == qc::Sdg) { - quat = {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}; - } else if (op.get().getType() == qc::T) { - quat = {cos(qc::PI_4 / 2), 0, 0, sin(qc::PI_4 / 2)}; - } else if (op.get().getType() == qc::Tdg) { - quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; - } else if (op.get().getType() == qc::U) { - quat = combine_quaternions( - combine_quaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, - sin(op.get().getParameter().at(1) / 2)}, - {cos(op.get().getParameter().front() / 2), 0, - sin(op.get().getParameter().front() / 2), 0}), - {cos(op.get().getParameter().at(2) / 2), 0, 0, - sin(op.get().getParameter().at(2) / 2)}); - } else if (op.get().getType() == qc::U2) { - quat = combine_quaternions( - combine_quaternions({cos(op.get().getParameter().front() / 2), 0, 0, - sin(op.get().getParameter().front() / 2)}, - {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), - {cos(op.get().getParameter().at(1) / 2), 0, 0, - sin(op.get().getParameter().at(1) / 2)}); - } else if (op.get().getType() == qc::RX) { - quat = {cos(op.get().getParameter().front() / 2), - sin(op.get().getParameter().front() / 2), 0, 0}; - } else if (op.get().getType() == qc::RY) { - quat = {cos(op.get().getParameter().front() / 2), 0, - sin(op.get().getParameter().front() / 2), 0}; - } else if (op.get().getType() == qc::H) { - quat = combine_quaternions( - combine_quaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), - {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); - } else if (op.get().getType() == qc::X) { - quat = {0, 1, 0, 0}; - } else if (op.get().getType() == qc::Y) { - quat = {0, 1, 0, 0}; - } else if (op.get().getType() == qc::Vdg) { - quat = combine_quaternions( - combine_quaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), - {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); - } else if (op.get().getType() == qc::SX) { - quat = combine_quaternions( - combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), - {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); - } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { - quat = combine_quaternions( - combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), - {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); - } else { - // if the gate type is not recognized, an error is printed and the - // gate is not included in the output. - std::ostringstream oss; - oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " - << op.get().getType() << "\n"; - throw std::invalid_argument(oss.str()); - } - return quat; -} - -auto Decomposer::combine_quaternions(const std::array& q1, - const std::array& q2) - -> std::array { - std::array new_quat{}; - new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; - new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; - new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; - new_quat[3] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]; - return new_quat; -} - -auto Decomposer::get_U3_angles_from_quaternion( - const std::array& quat) -> std::array { - // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be - // defined - qc::fp theta; - qc::fp phi; - qc::fp lambda; - if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { - theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), - std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); - qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // phi+ lambda - if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { - qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); - phi = alpha_1 + alpha_2; // phi - lambda = alpha_1 - alpha_2; - } else { - phi = 0; - lambda = 2 * alpha_1; - } - } else { - theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= - // exp(i*pi) just global phase - if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { - phi = 0; - lambda = 2 * std::atan2(quat[1], quat[2]); - // atan can give PI instead of 0 Problem? - } else { - // This should never happen! Exception?? - phi = 0.; - lambda = 0.; - } - } - return {theta, phi, lambda}; -} - -auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { - qc::fp theta_max = 0; - for (auto gate : layer) { - if (abs(gate.angles[0]) > theta_max) { - theta_max = abs(gate.angles[0]); - } - } - return theta_max; -} -auto Decomposer::transform_to_U3( - const std::vector& layers) const - -> std::vector> { - // auto u=struct_U3({0,0,0},0); - std::vector> new_layers; - for (const auto& layer : layers) { - std::vector>> gates( - this->N_qubits); - std::vector new_layer; - for (auto gate : layer) { - gates[gate.get().getTargets().front()].push_back(gate); - } - - for (auto qubit_gates : gates) { - if (!qubit_gates.empty()) { - std::array quat = convert_gate_to_quaternion(qubit_gates[0]); - for (auto i = 1; i < qubit_gates.size(); i++) { - quat = combine_quaternions( - quat, convert_gate_to_quaternion(qubit_gates[i])); - } - std::array angles = get_U3_angles_from_quaternion(quat); - new_layer.emplace_back( - struct_U3(angles, qubit_gates[0].get().getTargets().front())); - } - } - new_layers.push_back(new_layer); - } - return new_layers; -} -auto Decomposer::get_decomposition_angles(const std::array& angles, - qc::fp theta_max) - -> std::array { - qc::fp alpha, chi, beta; - // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, - // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - if (abs(angles[0] - theta_max) < epsilon) { - chi = qc::PI; - if (abs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? - alpha = 0; - } else { - alpha = qc::PI_2; - } - } else { - qc::fp kappa = sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / - (sin(theta_max) * sin(theta_max) - - (sin(angles[0] / 2) * sin(angles[0] / 2)))); - alpha = atan(cos(theta_max / 2) * kappa); - chi = fmod(2 * atan(kappa), qc::TAU); - } - beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; - qc::fp gamma_plus = fmod(angles[2] - (alpha + beta), qc::TAU); - qc::fp gamma_minus = fmod(angles[1] - (alpha - beta), qc::TAU); - - return {chi, gamma_minus, gamma_plus}; -} - -auto Decomposer::decompose( - const std::vector& singleQubitGateLayers) const - -> std::vector { - - std::vector> U3Layers = - transform_to_U3(singleQubitGateLayers); - std::vector NewSingleQubitLayers = - std::vector{}; - - for (const auto& layer : U3Layers) { - qc::fp theta_max = calc_theta_max(layer); - SingleQubitGateLayer FrontLayer; - SingleQubitGateLayer MidLayer; - SingleQubitGateLayer BackLayer; - SingleQubitGateLayer NewLayer; - - for (auto gate : layer) { - std::array decomp_angles = - get_decomposition_angles(gate.angles, theta_max); - - // GR(theta_max/2, PI_2)==Global Y due to PI_2 - auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); - std::unique_ptr op = - std::make_unique(sop); - FrontLayer.emplace_back(std::move(op)); - - sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}); - op = std::make_unique(sop); - MidLayer.emplace_back(std::move(op)); - - sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}); - op = std::make_unique(sop); - BackLayer.emplace_back(std::move(op)); - } // gate::layer - - std::vector> GR_plus; - std::vector> GR_minus; - - for (auto i = 0; i < this->N_qubits; ++i) { - GR_plus.emplace_back( - new qc::StandardOperation(i, qc::RY, {theta_max / 2})); - GR_minus.emplace_back( - new qc::StandardOperation(i, qc::RY, {-1 * theta_max / 2})); - } - - for (auto&& gate : FrontLayer) { - NewLayer.push_back(std::move(gate)); - } - - auto cop = qc::CompoundOperation(std::move(GR_plus), true); - std::unique_ptr ryp = - std::make_unique(cop); - NewLayer.emplace_back(std::move(ryp)); - - for (auto&& gate : MidLayer) { - NewLayer.push_back(std::move(gate)); - } - cop = qc::CompoundOperation(std::move(GR_minus), true); - std::unique_ptr rym = - std::make_unique(cop); - NewLayer.emplace_back(std::move(rym)); - - for (auto&& gate : BackLayer) { - NewLayer.push_back(std::move(gate)); - } - NewSingleQubitLayers.push_back(std::move(NewLayer)); - } // layer::SingleQubitLayers - return NewSingleQubitLayers; -} -} // namespace na::zoned diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 01312aa3d..f44761054 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -11,22 +11,25 @@ // // Created by cpsch on 11.12.2025. // -#include "na/zoned/decomposer/NativeGateDecomposer.hpp" +#include "na/zoned/decomposer/decomposer.hpp" +// #include "ir/operations/StandardOperation.hpp" #include "ir/operations/CompoundOperation.hpp" #include #include namespace na::zoned { +Decomposer::Decomposer(int n_qubits) { N_qubits = n_qubits; }; -auto NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper op) -> Quaternion { +auto Decomposer::convert_gate_to_quaternion( + std::reference_wrapper op) -> std::array { assert(op.get().getNqubits() == 1); - Quaternion quat{}; + std::array quat{}; + // TODO: Phase? if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front() / 2), 0, 0, - sin(op.get().getParameter().front() / 2)}; + quat = {cos(op.get().getParameter().front()), 0, 0, + sin(op.get().getParameter().front())}; } else if (op.get().getType() == qc::Z) { quat = {0, 0, 0, 1}; } else if (op.get().getType() == qc::S) { @@ -38,18 +41,18 @@ auto NativeGateDecomposer::convertGateToQuaternion( } else if (op.get().getType() == qc::Tdg) { quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; } else if (op.get().getType() == qc::U) { - quat = combineQuaternions( - combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, - sin(op.get().getParameter().at(1) / 2)}, - {cos(op.get().getParameter().front() / 2), 0, - sin(op.get().getParameter().front() / 2), 0}), + quat = combine_quaternions( + combine_quaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, + sin(op.get().getParameter().at(1) / 2)}, + {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}), {cos(op.get().getParameter().at(2) / 2), 0, 0, sin(op.get().getParameter().at(2) / 2)}); } else if (op.get().getType() == qc::U2) { - quat = combineQuaternions( - combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, - sin(op.get().getParameter().front() / 2)}, - {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + quat = combine_quaternions( + combine_quaternions({cos(op.get().getParameter().front() / 2), 0, 0, + sin(op.get().getParameter().front() / 2)}, + {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}); } else if (op.get().getType() == qc::RX) { @@ -59,43 +62,43 @@ auto NativeGateDecomposer::convertGateToQuaternion( quat = {cos(op.get().getParameter().front() / 2), 0, sin(op.get().getParameter().front() / 2), 0}; } else if (op.get().getType() == qc::H) { - quat = combineQuaternions( - combineQuaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + quat = combine_quaternions( + combine_quaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); } else if (op.get().getType() == qc::X) { quat = {0, 1, 0, 0}; } else if (op.get().getType() == qc::Y) { - quat = {0, 0, 1, 0}; + quat = {0, 1, 0, 0}; } else if (op.get().getType() == qc::Vdg) { - quat = combineQuaternions( - combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + quat = combine_quaternions( + combine_quaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); } else if (op.get().getType() == qc::SX) { - quat = combineQuaternions( - combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + quat = combine_quaternions( + combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { - quat = combineQuaternions( - combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + quat = combine_quaternions( + combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else { // if the gate type is not recognized, an error is printed and the // gate is not included in the output. std::ostringstream oss; - oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() - << "\n"; + oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + << op.get().getType() << "\n"; throw std::invalid_argument(oss.str()); } return quat; } -auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, - const Quaternion& q2) - -> Quaternion { - Quaternion new_quat{}; +auto Decomposer::combine_quaternions(const std::array& q1, + const std::array& q2) + -> std::array { + std::array new_quat{}; new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; @@ -103,16 +106,18 @@ auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, return new_quat; } -auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) - -> std::array { +auto Decomposer::get_U3_angles_from_quaternion( + const std::array& quat) -> std::array { + // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be + // defined qc::fp theta; qc::fp phi; qc::fp lambda; - if (std::fabs(quat[0]) > epsilon || std::fabs(quat[3]) > epsilon) { + if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // phi+ lambda - if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { + if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); phi = alpha_1 + alpha_2; // phi lambda = alpha_1 - alpha_2; @@ -123,7 +128,7 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) } else { theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= // exp(i*pi) just global phase - if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { + if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { phi = 0; lambda = 2 * std::atan2(quat[1], quat[2]); // atan can give PI instead of 0 Problem? @@ -136,88 +141,82 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) return {theta, phi, lambda}; } -auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) - -> qc::fp { +auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { - if (std::fabs(gate.angles[0]) > theta_max) { - theta_max = std::fabs(gate.angles[0]); + if (abs(gate.angles[0]) > theta_max) { + theta_max = abs(gate.angles[0]); } } return theta_max; } -auto NativeGateDecomposer::transformToU3( +auto Decomposer::transform_to_U3( const std::vector& layers) const - -> std::vector> { - std::vector> new_layers; + -> std::vector> { + // auto u=struct_U3({0,0,0},0); + std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( - this->nQubits_); - std::vector new_layer; + this->N_qubits); + std::vector new_layer; for (auto gate : layer) { - // WHat are operations with empty targets doing?? - if (!gate.get().getTargets().empty()) { - gates[gate.get().getTargets().front()].push_back(gate); - } + gates[gate.get().getTargets().front()].push_back(gate); } for (auto qubit_gates : gates) { if (!qubit_gates.empty()) { - std::array quat = convertGateToQuaternion(qubit_gates[0]); - for (size_t i = 1; i < qubit_gates.size(); i++) { - quat = - combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); + std::array quat = convert_gate_to_quaternion(qubit_gates[0]); + for (auto i = 1; i < qubit_gates.size(); i++) { + quat = combine_quaternions( + quat, convert_gate_to_quaternion(qubit_gates[i])); } - std::array angles = getU3AnglesFromQuaternion(quat); + std::array angles = get_U3_angles_from_quaternion(quat); new_layer.emplace_back( - StructU3{angles, qubit_gates[0].get().getTargets().front()}); + struct_U3(angles, qubit_gates[0].get().getTargets().front())); } } new_layers.push_back(new_layer); } return new_layers; } -auto NativeGateDecomposer::getDecompositionAngles( - const std::array& angles, qc::fp theta_max) +auto Decomposer::get_decomposition_angles(const std::array& angles, + qc::fp theta_max) -> std::array { - qc::fp alpha, chi; + qc::fp alpha, chi, beta; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - qc::fp sin_sq_diff = (sin(theta_max / 2) * sin(theta_max / 2) - - (sin(angles[0] / 2) * sin(angles[0] / 2))); - if (std::fabs(sin_sq_diff) < epsilon) { + if (abs(angles[0] - theta_max) < epsilon) { chi = qc::PI; - if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? + if (abs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; } else { alpha = qc::PI_2; } } else { - qc::fp kappa = - std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / sin_sq_diff); + qc::fp kappa = sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / + (sin(theta_max) * sin(theta_max) - + (sin(angles[0] / 2) * sin(angles[0] / 2)))); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } - qc::fp beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; + beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; qc::fp gamma_plus = fmod(angles[2] - (alpha + beta), qc::TAU); qc::fp gamma_minus = fmod(angles[1] - (alpha - beta), qc::TAU); return {chi, gamma_minus, gamma_plus}; } -auto NativeGateDecomposer::decompose( - const size_t nQubits, - const std::vector& singleQubitGateLayers) +auto Decomposer::decompose( + const std::vector& singleQubitGateLayers) const -> std::vector { - nQubits_ = nQubits; - std::vector> U3Layers = - transformToU3(singleQubitGateLayers); + std::vector> U3Layers = + transform_to_U3(singleQubitGateLayers); std::vector NewSingleQubitLayers = std::vector{}; for (const auto& layer : U3Layers) { - qc::fp theta_max = calcThetaMax(layer); + qc::fp theta_max = calc_theta_max(layer); SingleQubitGateLayer FrontLayer; SingleQubitGateLayer MidLayer; SingleQubitGateLayer BackLayer; @@ -225,41 +224,49 @@ auto NativeGateDecomposer::decompose( for (auto gate : layer) { std::array decomp_angles = - getDecompositionAngles(gate.angles, theta_max); + get_decomposition_angles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - FrontLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); + auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); + std::unique_ptr op = + std::make_unique(sop); + FrontLayer.emplace_back(std::move(op)); - MidLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); + sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}); + op = std::make_unique(sop); + MidLayer.emplace_back(std::move(op)); - BackLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); + sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}); + op = std::make_unique(sop); + BackLayer.emplace_back(std::move(op)); } // gate::layer std::vector> GR_plus; std::vector> GR_minus; - for (size_t i = 0; i < this->nQubits_; ++i) { - GR_plus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{theta_max / 2})); - GR_minus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{-1 * theta_max / 2})); + for (auto i = 0; i < this->N_qubits; ++i) { + GR_plus.emplace_back( + new qc::StandardOperation(i, qc::RY, {theta_max / 2})); + GR_minus.emplace_back( + new qc::StandardOperation(i, qc::RY, {-1 * theta_max / 2})); } for (auto&& gate : FrontLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_plus), true))); + auto cop = qc::CompoundOperation(std::move(GR_plus), true); + std::unique_ptr ryp = + std::make_unique(cop); + NewLayer.emplace_back(std::move(ryp)); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_minus), true))); + cop = qc::CompoundOperation(std::move(GR_minus), true); + std::unique_ptr rym = + std::make_unique(cop); + NewLayer.emplace_back(std::move(rym)); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); diff --git a/test/na/zoned/test_decomposer.cpp b/test/na/zoned/test_decomposer.cpp deleted file mode 100644 index f2ed429c7..000000000 --- a/test/na/zoned/test_decomposer.cpp +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM - * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH - * All rights reserved. - * - * SPDX-License-Identifier: MIT - * - * Licensed under the MIT License - */ - -// -// Created by cpsch on 16.12.2025. -// - -#include "ir/QuantumComputation.hpp" -#include "na/zoned/decomposer/Decomposer.hpp" -#include "na/zoned/scheduler/ASAPScheduler.hpp" - -#include -#include -#include -#include -#include - -namespace na::zoned { -constexpr std::string_view architectureJson = R"({ - "name": "asap_scheduler_architecture", - "storage_zones": [{ - "zone_id": 0, - "slms": [{"id": 0, "site_separation": [3, 3], "r": 20, "c": 20, "location": [0, 0]}], - "offset": [0, 0], - "dimension": [60, 60] - }], - "entanglement_zones": [{ - "zone_id": 0, - "slms": [ - {"id": 1, "site_separation": [12, 10], "r": 4, "c": 4, "location": [5, 70]}, - {"id": 2, "site_separation": [12, 10], "r": 4, "c": 4, "location": [7, 70]} - ], - "offset": [5, 70], - "dimension": [50, 40] - }], - "aods":[{"id": 0, "site_separation": 2, "r": 20, "c": 20}], - "rydberg_range": [[[5, 70], [55, 110]]] -})"; - -class DecomposerTest : public ::testing::Test { -protected: - Decomposer decomposer = Decomposer(4); - Architecture architecture; - ASAPScheduler::Config config{.maxFillingFactor = .8}; - ASAPScheduler scheduler; - DecomposerTest() - : architecture(Architecture::fromJSONString(architectureJson)), - scheduler(architecture, config) {} -}; - -qc::fp epsilon = 1e-5; - -TEST(Test, ThreeQuaternionCombiTest) { - std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; - std::array q12 = Decomposer::combine_quaternions(q1, q2); - EXPECT_THAT(q12, ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), - ::testing::DoubleNear(cos(qc::PI_4), epsilon), - ::testing::DoubleNear(0, epsilon))); - std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; - std::array q13 = Decomposer::combine_quaternions(q12, q3); - EXPECT_THAT( - q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(cos(qc::PI_4), epsilon), - ::testing::DoubleNear(cos(qc::PI_4), epsilon), - ::testing::DoubleNear(0, epsilon))); -} - -TEST(Test, ThreeQuaternionU3Test) { - std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; - std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; - std::array q12 = Decomposer::combine_quaternions(q1, q2); - EXPECT_THAT(q12, ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); - std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - std::array q13 = Decomposer::combine_quaternions(q12, q3); - qc::fp r2 = 1 / sqrt(2); - EXPECT_THAT(q13, ::testing::ElementsAre( - ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), - ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), - ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), - ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); -} - -TEST(Test, SingleXGateAngleTest) { - size_t n = 1; - const qc::Operation* op = new qc::StandardOperation(0, qc::X); - - qc::QuantumComputation qc(n); - qc.rx(qc::PI, 0); - std::array q = Decomposer::convert_gate_to_quaternion( - std::reference_wrapper(*op)); - EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(-1 * qc::PI_2, epsilon), - ::testing::DoubleNear(qc::PI_2, epsilon))); -} - -TEST(Test, SingleU3GateAngleTest) { - size_t n = 1; - const qc::Operation* op = - new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( - std::reference_wrapper(*op)); - qc::fp r2 = 1 / sqrt(2); - EXPECT_THAT(q, ::testing::ElementsAre( - ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), - ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), - ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), - ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); - - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), - ::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(qc::PI_2, epsilon))); -} - -TEST(Test, ThetaPiAngleTest) { - size_t n = 1; - const qc::Operation* op = - new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( - std::reference_wrapper(*op)); - qc::fp r2 = 1 / sqrt(2); - EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-r2, epsilon), - ::testing::DoubleNear(r2, epsilon), - ::testing::DoubleNear(0, epsilon))); - EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); -} - -TEST(Test, ThetaZeroAngleTest) { - size_t n = 1; - const qc::Operation* op = - new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( - std::reference_wrapper(*op)); - qc::fp r2 = 1 / sqrt(2); - EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(r2, epsilon))); - - EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(3 * qc::PI_2, epsilon))); -} - -TEST(Test, RXDecompositionTest) { - size_t n = 1; - std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; - EXPECT_THAT(Decomposer::get_decomposition_angles(rx, qc::PI), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); -} - -TEST(Test, U3DecompositionTest) { - size_t n = 1; - std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; - // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! - EXPECT_THAT( - Decomposer::get_decomposition_angles(u3, qc::PI_4), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(-qc::PI_2, epsilon))); -} - -TEST(Test, DoubleDecompositionTest) { - size_t n = 1; - std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; - std::array z2 = {0, 0, qc::PI}; - EXPECT_THAT(Decomposer::get_decomposition_angles(x1, qc::PI), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); - EXPECT_THAT(Decomposer::get_decomposition_angles(z2, qc::PI), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(qc::PI_2, epsilon), - ::testing::DoubleNear(qc::PI_2, epsilon))); -} - -TEST_F(DecomposerTest, SingleRXGate) { - // ┌───────┐ - // q: ┤ Rx(π) ├ - // └───────┘ - int n = 1; - qc::QuantumComputation qc(n); - qc.rx(qc::PI, 0); - Decomposer decomposer = Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(), 1); - EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); -} - -TEST_F(DecomposerTest, SingleU3Gate) { - // ┌─────────────┐ - // q: ┤ U3(0,π,π/2) ├ - // └─────────────┘ - int n = 1; - qc::QuantumComputation qc(n); - qc.u(0.0, qc::PI, qc::PI_2, 0); - Decomposer decomposer = Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(), 1); - EXPECT_EQ(decomp[0].size(), 5); - - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); - EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); -} - -// TEST with U3(o,?,?) -// TEST with two Single Qubit Layers - -TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { - // ┌───────┐ ┌───────┐ - // q: ┤ X ├──┤ Z ├ - // └───────┘ └───────┘ - size_t n = 1; - qc::QuantumComputation qc(n); - qc.x(0); - qc.z(0); - Decomposer decomposer = Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); - - EXPECT_EQ(decomp.size(), 1); - EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - // TODO: FIgure out i this is always Positive - EXPECT_THAT( - decomp[0][4]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(3 * qc::PI_2, epsilon))); -} - -TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { - // ┌───────┐ - // q_0: ─┤ X ├─ - // └───────┘ - // ┌───────┐ - // q_1: ─┤ Z ├─ - // └───────┘ - - size_t n = 2; - qc::QuantumComputation qc(n); - qc.x(0); - qc.z(1); - Decomposer decomposer = Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(), 1); - EXPECT_EQ(decomp[0].size(), 8); - - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - EXPECT_EQ(decomp[0][1]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][1]->getTargets(), ::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][1]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - EXPECT_TRUE(decomp[0][2]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][2]->isGlobal(n)); - - EXPECT_EQ(decomp[0][3]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][3]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][3]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][4]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); - - EXPECT_TRUE(decomp[0][5]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][5]->isGlobal(n)); - - EXPECT_EQ(decomp[0][6]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][6]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][6]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - EXPECT_EQ(decomp[0][7]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][7]->getTargets(), ::testing::ElementsAre(1)); - EXPECT_THAT(decomp[0][7]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); -} - -TEST_F(DecomposerTest, TwoQubitsTwoLayers) { - // ┌───────┐ ┌───────┐ - // q_0: ─┤ X ├───■───┤ Z ├─ - // └───────┘ │ └───────┘ - // │ ┌───────┐ - // q_1: ─────────────■───┤ X ├─ - // └───────┘ - - size_t n = 2; - qc::QuantumComputation qc(n); - qc.x(0); - qc.cz(0, 1); - qc.z(0); - qc.x(1); - Decomposer decomposer = Decomposer(n); - const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); - EXPECT_EQ(decomp.size(), 2); - EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[1].size(), 8); - - // Layer 1 - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - - EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - - EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - // Layer 2 - - EXPECT_EQ(decomp[1][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[1][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][0]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - EXPECT_EQ(decomp[1][1]->getType(), qc::RZ); - EXPECT_THAT(decomp[1][1]->getTargets(), ::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][1]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - EXPECT_TRUE(decomp[1][2]->isCompoundOperation()); - EXPECT_TRUE(decomp[1][2]->isGlobal(n)); - - EXPECT_EQ(decomp[1][3]->getType(), qc::RZ); - EXPECT_THAT(decomp[1][3]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][3]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); - - EXPECT_EQ(decomp[1][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[1][4]->getTargets(), ::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][4]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - - EXPECT_TRUE(decomp[1][5]->isCompoundOperation()); - EXPECT_TRUE(decomp[1][5]->isGlobal(n)); - - EXPECT_EQ(decomp[1][6]->getType(), qc::RZ); - EXPECT_THAT(decomp[1][6]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[1][6]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - - EXPECT_EQ(decomp[1][7]->getType(), qc::RZ); - EXPECT_THAT(decomp[1][7]->getTargets(), ::testing::ElementsAre(1)); - EXPECT_THAT(decomp[1][7]->getParameter(), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); -} - -} // namespace na::zoned diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 85c19d1ee..f2ed429c7 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -13,7 +13,7 @@ // #include "ir/QuantumComputation.hpp" -#include "na/zoned/decomposer/NativeGateDecomposer.hpp" +#include "na/zoned/decomposer/Decomposer.hpp" #include "na/zoned/scheduler/ASAPScheduler.hpp" #include @@ -46,235 +46,28 @@ constexpr std::string_view architectureJson = R"({ class DecomposerTest : public ::testing::Test { protected: + Decomposer decomposer = Decomposer(4); Architecture architecture; - ASAPScheduler::Config schedulerConfig{.maxFillingFactor = .8}; + ASAPScheduler::Config config{.maxFillingFactor = .8}; ASAPScheduler scheduler; - NativeGateDecomposer::Config decomposerConfig{}; - NativeGateDecomposer decomposer; DecomposerTest() : architecture(Architecture::fromJSONString(architectureJson)), - scheduler(architecture, schedulerConfig), - decomposer(architecture, decomposerConfig) {} + scheduler(architecture, config) {} }; -constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; - -// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, -// SX, Sxdg, Unrecognized, H _>Just do them all? - -TEST(Test, ZRotGateTranslationTest) { - - qc::StandardOperation op = qc::StandardOperation(0, qc::Z); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon))); - - op = qc::StandardOperation(0, qc::RZ, {qc::PI_2}); - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); - op = qc::StandardOperation(0, qc::P, {qc::PI_2}); - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); - - op = qc::StandardOperation(0, qc::S); - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); - - op = qc::StandardOperation(0, qc::Sdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre( - ::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-1 / std::sqrt(2), epsilon))); - op = qc::StandardOperation(0, qc::T); - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre( - ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); - - op = qc::StandardOperation(0, qc::Tdg); - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre( - ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); -} - -TEST(Test, XYRotGateTranslationTest) { - qc::StandardOperation op = qc::StandardOperation(0, qc::X); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); - - op = qc::StandardOperation(0, qc::RX, {qc::PI_2}); - - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); - - op = qc::StandardOperation(0, qc::Y); - - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon))); - - op = qc::StandardOperation(0, qc::RY, {qc::PI_2}); - - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon))); - - op = qc::StandardOperation(0, qc::SX); - - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); - - op = qc::StandardOperation(0, qc::SXdg); - - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(-1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); -} - -TEST(Test, UGateTranslationTest) { - qc::fp p = qc::PI_2; - qc::fp t = qc::PI_4; - qc::fp l = qc::PI_4; - qc::StandardOperation op = qc::StandardOperation(0, qc::U, {t, p, l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre( - ::testing::DoubleNear( - (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - - (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - - std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + - std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + - std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), - epsilon))); - - t = qc::PI_2; - op = qc::StandardOperation(0, qc::U2, {p, l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre( - ::testing::DoubleNear( - (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - - (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - - std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + - std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + - std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), - epsilon))); - - t = -1 * qc::PI_2; - l = -1 * qc::PI_2; - - op = qc::StandardOperation(0, qc::Vdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre( - ::testing::DoubleNear( - (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - - (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - - std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + - std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), - epsilon), - ::testing::DoubleNear( - std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + - std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), - epsilon))); - op = qc::StandardOperation(0, qc::H); - EXPECT_THAT( - NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper(op)), - ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); -} +qc::fp epsilon = 1e-5; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; - std::array q12 = NativeGateDecomposer::combineQuaternions(q1, q2); + std::array q12 = Decomposer::combine_quaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), ::testing::DoubleNear(0, epsilon))); std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; - std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); + std::array q13 = Decomposer::combine_quaternions(q12, q3); EXPECT_THAT( q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), @@ -285,15 +78,15 @@ TEST(Test, ThreeQuaternionCombiTest) { TEST(Test, ThreeQuaternionU3Test) { std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; - std::array q12 = NativeGateDecomposer::combineQuaternions(q1, q2); + std::array q12 = Decomposer::combine_quaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); - qc::fp r2 = 1 / std::sqrt(2); + std::array q13 = Decomposer::combine_quaternions(q12, q3); + qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), @@ -302,19 +95,25 @@ TEST(Test, ThreeQuaternionU3Test) { } TEST(Test, SingleXGateAngleTest) { + size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::X); - std::array q = NativeGateDecomposer::convertGateToQuaternion( + + qc::QuantumComputation qc(n); + qc.rx(qc::PI, 0); + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); - EXPECT_THAT(NativeGateDecomposer::getU3AnglesFromQuaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(qc::PI, epsilon))); + EXPECT_THAT( + Decomposer::get_U3_angles_from_quaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(-1 * qc::PI_2, epsilon), + ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, SingleU3GateAngleTest) { + size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convertGateToQuaternion( + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre( @@ -323,16 +122,17 @@ TEST(Test, SingleU3GateAngleTest) { ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); - EXPECT_THAT(NativeGateDecomposer::getU3AnglesFromQuaternion(q), + EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, ThetaPiAngleTest) { + size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convertGateToQuaternion( + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), @@ -340,16 +140,17 @@ TEST(Test, ThetaPiAngleTest) { ::testing::DoubleNear(r2, epsilon), ::testing::DoubleNear(0, epsilon))); EXPECT_THAT( - NativeGateDecomposer::getU3AnglesFromQuaternion(q), + Decomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); } TEST(Test, ThetaZeroAngleTest) { + size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convertGateToQuaternion( + std::array q = Decomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), @@ -358,37 +159,41 @@ TEST(Test, ThetaZeroAngleTest) { ::testing::DoubleNear(r2, epsilon))); EXPECT_THAT( - NativeGateDecomposer::getU3AnglesFromQuaternion(q), + Decomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(3 * qc::PI_2, epsilon))); } TEST(Test, RXDecompositionTest) { + size_t n = 1; std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; - EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(rx, qc::PI), + EXPECT_THAT(Decomposer::get_decomposition_angles(rx, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); } TEST(Test, U3DecompositionTest) { + size_t n = 1; std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; + // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! EXPECT_THAT( - NativeGateDecomposer::getDecompositionAngles(u3, qc::PI_4), + Decomposer::get_decomposition_angles(u3, qc::PI_4), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-qc::PI_2, epsilon))); } TEST(Test, DoubleDecompositionTest) { + size_t n = 1; std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; std::array z2 = {0, 0, qc::PI}; - EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(x1, qc::PI), + EXPECT_THAT(Decomposer::get_decomposition_angles(x1, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); - EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(z2, qc::PI), + EXPECT_THAT(Decomposer::get_decomposition_angles(z2, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -398,11 +203,12 @@ TEST_F(DecomposerTest, SingleRXGate) { // ┌───────┐ // q: ┤ Rx(π) ├ // └───────┘ - size_t n = 1; + int n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); + Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); @@ -427,11 +233,12 @@ TEST_F(DecomposerTest, SingleU3Gate) { // ┌─────────────┐ // q: ┤ U3(0,π,π/2) ├ // └─────────────┘ - size_t n = 1; + int n = 1; qc::QuantumComputation qc(n); qc.u(0.0, qc::PI, qc::PI_2, 0); + Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); @@ -453,6 +260,9 @@ TEST_F(DecomposerTest, SingleU3Gate) { ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } +// TEST with U3(o,?,?) +// TEST with two Single Qubit Layers + TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ // q: ┤ X ├──┤ Z ├ @@ -461,8 +271,9 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { qc::QuantumComputation qc(n); qc.x(0); qc.z(0); + Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); @@ -480,6 +291,7 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { EXPECT_TRUE(decomp[0][3]->isGlobal(n)); EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + // TODO: FIgure out i this is always Positive EXPECT_THAT( decomp[0][4]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(3 * qc::PI_2, epsilon))); @@ -497,8 +309,9 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { qc::QuantumComputation qc(n); qc.x(0); qc.z(1); + Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 8); @@ -553,8 +366,9 @@ TEST_F(DecomposerTest, TwoQubitsTwoLayers) { qc.cz(0, 1); qc.z(0); qc.x(1); + Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(sched.first); EXPECT_EQ(decomp.size(), 2); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[1].size(), 8); From 12ced4c31c6296da7fda2fee1d6ed3a26ae86766 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:27:28 +0100 Subject: [PATCH 040/110] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20newly=20introduced?= =?UTF-8?q?=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 5 +++- .../zoned/decomposer/NativeGateDecomposer.cpp | 29 ++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 1f453f0e5..7b9250d3d 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -23,7 +23,10 @@ class NativeGateDecomposer : public DecomposerBase { std::array angles; qc::Qubit qubit; }; - size_t nQubits; + size_t nQubits_; + + constexpr static qc::fp epsilon = + std::numeric_limits::epsilon() * 1024; public: /** diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index f44761054..8a2d85fe9 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -11,7 +11,7 @@ // // Created by cpsch on 11.12.2025. // -#include "na/zoned/decomposer/decomposer.hpp" +#include "na/zoned/decomposer/NativeGateDecomposer.hpp" // #include "ir/operations/StandardOperation.hpp" #include "ir/operations/CompoundOperation.hpp" @@ -20,9 +20,11 @@ #include namespace na::zoned { -Decomposer::Decomposer(int n_qubits) { N_qubits = n_qubits; }; +NativeGateDecomposer::NativeGateDecomposer(int n_qubits) { + nQubits_ = n_qubits; +}; -auto Decomposer::convert_gate_to_quaternion( +auto NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper op) -> std::array { assert(op.get().getNqubits() == 1); std::array quat{}; @@ -95,8 +97,8 @@ auto Decomposer::convert_gate_to_quaternion( return quat; } -auto Decomposer::combine_quaternions(const std::array& q1, - const std::array& q2) +auto NativeGateDecomposer::combine_quaternions(const std::array& q1, + const std::array& q2) -> std::array { std::array new_quat{}; new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; @@ -106,7 +108,7 @@ auto Decomposer::combine_quaternions(const std::array& q1, return new_quat; } -auto Decomposer::get_U3_angles_from_quaternion( +auto NativeGateDecomposer::get_U3_angles_from_quaternion( const std::array& quat) -> std::array { // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be // defined @@ -141,7 +143,8 @@ auto Decomposer::get_U3_angles_from_quaternion( return {theta, phi, lambda}; } -auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { +auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) + -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { if (abs(gate.angles[0]) > theta_max) { @@ -150,14 +153,14 @@ auto Decomposer::calc_theta_max(const std::vector& layer) -> qc::fp { } return theta_max; } -auto Decomposer::transform_to_U3( +auto NativeGateDecomposer::transform_to_U3( const std::vector& layers) const -> std::vector> { // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( - this->N_qubits); + this->nQubits_); std::vector new_layer; for (auto gate : layer) { gates[gate.get().getTargets().front()].push_back(gate); @@ -179,8 +182,8 @@ auto Decomposer::transform_to_U3( } return new_layers; } -auto Decomposer::get_decomposition_angles(const std::array& angles, - qc::fp theta_max) +auto NativeGateDecomposer::get_decomposition_angles( + const std::array& angles, qc::fp theta_max) -> std::array { qc::fp alpha, chi, beta; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, @@ -206,7 +209,7 @@ auto Decomposer::get_decomposition_angles(const std::array& angles, return {chi, gamma_minus, gamma_plus}; } -auto Decomposer::decompose( +auto NativeGateDecomposer::decompose( const std::vector& singleQubitGateLayers) const -> std::vector { @@ -244,7 +247,7 @@ auto Decomposer::decompose( std::vector> GR_plus; std::vector> GR_minus; - for (auto i = 0; i < this->N_qubits; ++i) { + for (auto i = 0; i < this->nQubits_; ++i) { GR_plus.emplace_back( new qc::StandardOperation(i, qc::RY, {theta_max / 2})); GR_minus.emplace_back( From e08023b239879009534ff2b450f2c3f78d535860 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:43:51 +0100 Subject: [PATCH 041/110] =?UTF-8?q?=F0=9F=8E=A8=20Add=20nQubits=20to=20dec?= =?UTF-8?q?ompose=20interface=20and=20fix=20resulting=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 30 ++++++---- .../zoned/decomposer/NativeGateDecomposer.cpp | 19 +++--- test/na/zoned/test_native_gate_decomposer.cpp | 59 +++++++++---------- 3 files changed, 58 insertions(+), 50 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 7b9250d3d..118605a1f 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -23,12 +23,26 @@ class NativeGateDecomposer : public DecomposerBase { std::array angles; qc::Qubit qubit; }; - size_t nQubits_; + size_t nQubits_ = 0; constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; public: + /// The configuration of the NativeGateDecomposer + struct Config { + template + friend void to_json(BasicJsonType& /* unused */, + const Config& /* unused */) {} + template + friend void from_json(const BasicJsonType& /* unused */, + Config& /* unused */) {} + }; + + /// Create a new NativeGateDecomposer. + NativeGateDecomposer(const Architecture& /* unused */, + const Config& /* unused */) {} + /** * Converts commonly used single qubit gates into their Quaternion * representation @@ -67,7 +81,7 @@ class NativeGateDecomposer : public DecomposerBase { * @param layer is a SingleQubitGateLayers of a scheduled * @returns the maximal value of theta in the given layer */ - static auto calc_theta_max(const std::vector& layer) -> qc::fp; + static auto calc_theta_max(const std::vector& layer) -> qc::fp; /** * Takes a vector of SingleQubitGateLayer's and, for each layer @@ -80,7 +94,7 @@ class NativeGateDecomposer : public DecomposerBase { */ [[nodiscard]] auto transform_to_U3(const std::vector& layers) const - -> std::vector>; + -> std::vector>; /** * Takes a vector of qc::fp's representing the U3-Gate angles of a single * qubit hate and the maximal value of theta for the single qubit gate layer @@ -94,14 +108,10 @@ class NativeGateDecomposer : public DecomposerBase { auto static get_decomposition_angles(const std::array& angles, qc::fp theta_max) -> std::array; - /** - * Create a new Decomposer. - * @param n_qubits is the number of qubits in the circuit to be decomposed - */ - NativeGateDecomposer(int n_qubits); - [[nodiscard]] auto decompose( - const std::vector& singleQubitGateLayers) const + [[nodiscard]] auto + decompose(size_t nQubits, + const std::vector& singleQubitGateLayers) -> std::vector override; }; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 8a2d85fe9..24833d402 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -20,9 +20,6 @@ #include namespace na::zoned { -NativeGateDecomposer::NativeGateDecomposer(int n_qubits) { - nQubits_ = n_qubits; -}; auto NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper op) -> std::array { @@ -143,7 +140,7 @@ auto NativeGateDecomposer::get_U3_angles_from_quaternion( return {theta, phi, lambda}; } -auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) +auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { @@ -155,13 +152,13 @@ auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) } auto NativeGateDecomposer::transform_to_U3( const std::vector& layers) const - -> std::vector> { + -> std::vector> { // auto u=struct_U3({0,0,0},0); - std::vector> new_layers; + std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( this->nQubits_); - std::vector new_layer; + std::vector new_layer; for (auto gate : layer) { gates[gate.get().getTargets().front()].push_back(gate); } @@ -175,7 +172,7 @@ auto NativeGateDecomposer::transform_to_U3( } std::array angles = get_U3_angles_from_quaternion(quat); new_layer.emplace_back( - struct_U3(angles, qubit_gates[0].get().getTargets().front())); + StructU3(angles, qubit_gates[0].get().getTargets().front())); } } new_layers.push_back(new_layer); @@ -210,10 +207,12 @@ auto NativeGateDecomposer::get_decomposition_angles( } auto NativeGateDecomposer::decompose( - const std::vector& singleQubitGateLayers) const + const size_t nQubits, + const std::vector& singleQubitGateLayers) -> std::vector { + nQubits_ = nQubits; - std::vector> U3Layers = + std::vector> U3Layers = transform_to_U3(singleQubitGateLayers); std::vector NewSingleQubitLayers = std::vector{}; diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index f2ed429c7..428500b04 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -13,7 +13,7 @@ // #include "ir/QuantumComputation.hpp" -#include "na/zoned/decomposer/Decomposer.hpp" +#include "na/zoned/decomposer/NativeGateDecomposer.hpp" #include "na/zoned/scheduler/ASAPScheduler.hpp" #include @@ -46,13 +46,15 @@ constexpr std::string_view architectureJson = R"({ class DecomposerTest : public ::testing::Test { protected: - Decomposer decomposer = Decomposer(4); Architecture architecture; - ASAPScheduler::Config config{.maxFillingFactor = .8}; + ASAPScheduler::Config schedulerConfig{.maxFillingFactor = .8}; ASAPScheduler scheduler; + NativeGateDecomposer::Config decomposerConfig{}; + NativeGateDecomposer decomposer; DecomposerTest() : architecture(Architecture::fromJSONString(architectureJson)), - scheduler(architecture, config) {} + scheduler(architecture, schedulerConfig), + decomposer(architecture, decomposerConfig) {} }; qc::fp epsilon = 1e-5; @@ -60,14 +62,15 @@ qc::fp epsilon = 1e-5; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; - std::array q12 = Decomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), ::testing::DoubleNear(0, epsilon))); std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; - std::array q13 = Decomposer::combine_quaternions(q12, q3); + std::array q13 = + NativeGateDecomposer::combine_quaternions(q12, q3); EXPECT_THAT( q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), @@ -78,14 +81,15 @@ TEST(Test, ThreeQuaternionCombiTest) { TEST(Test, ThreeQuaternionU3Test) { std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; - std::array q12 = Decomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - std::array q13 = Decomposer::combine_quaternions(q12, q3); + std::array q13 = + NativeGateDecomposer::combine_quaternions(q12, q3); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), @@ -100,10 +104,10 @@ TEST(Test, SingleXGateAngleTest) { qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -113,7 +117,7 @@ TEST(Test, SingleU3GateAngleTest) { size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre( @@ -122,7 +126,7 @@ TEST(Test, SingleU3GateAngleTest) { ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); - EXPECT_THAT(Decomposer::get_U3_angles_from_quaternion(q), + EXPECT_THAT(NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -132,7 +136,7 @@ TEST(Test, ThetaPiAngleTest) { size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), @@ -140,7 +144,7 @@ TEST(Test, ThetaPiAngleTest) { ::testing::DoubleNear(r2, epsilon), ::testing::DoubleNear(0, epsilon))); EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); @@ -150,7 +154,7 @@ TEST(Test, ThetaZeroAngleTest) { size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); - std::array q = Decomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convert_gate_to_quaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), @@ -159,7 +163,7 @@ TEST(Test, ThetaZeroAngleTest) { ::testing::DoubleNear(r2, epsilon))); EXPECT_THAT( - Decomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::get_U3_angles_from_quaternion(q), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(3 * qc::PI_2, epsilon))); @@ -168,7 +172,7 @@ TEST(Test, ThetaZeroAngleTest) { TEST(Test, RXDecompositionTest) { size_t n = 1; std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; - EXPECT_THAT(Decomposer::get_decomposition_angles(rx, qc::PI), + EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(rx, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); @@ -179,7 +183,7 @@ TEST(Test, U3DecompositionTest) { std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! EXPECT_THAT( - Decomposer::get_decomposition_angles(u3, qc::PI_4), + NativeGateDecomposer::get_decomposition_angles(u3, qc::PI_4), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-qc::PI_2, epsilon))); @@ -189,11 +193,11 @@ TEST(Test, DoubleDecompositionTest) { size_t n = 1; std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; std::array z2 = {0, 0, qc::PI}; - EXPECT_THAT(Decomposer::get_decomposition_angles(x1, qc::PI), + EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(x1, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); - EXPECT_THAT(Decomposer::get_decomposition_angles(z2, qc::PI), + EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(z2, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -206,9 +210,8 @@ TEST_F(DecomposerTest, SingleRXGate) { int n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); @@ -236,9 +239,8 @@ TEST_F(DecomposerTest, SingleU3Gate) { int n = 1; qc::QuantumComputation qc(n); qc.u(0.0, qc::PI, qc::PI_2, 0); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); @@ -271,9 +273,8 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { qc::QuantumComputation qc(n); qc.x(0); qc.z(0); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 5); @@ -309,9 +310,8 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { qc::QuantumComputation qc(n); qc.x(0); qc.z(1); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 8); @@ -366,9 +366,8 @@ TEST_F(DecomposerTest, TwoQubitsTwoLayers) { qc.cz(0, 1); qc.z(0); qc.x(1); - Decomposer decomposer = Decomposer(n); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); EXPECT_EQ(decomp.size(), 2); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[1].size(), 8); From 21e7c6c4784f496b95c05fcd85859363a037351c Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:47:16 +0100 Subject: [PATCH 042/110] =?UTF-8?q?=F0=9F=8E=A8=20Improve=20docstring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../na/zoned/decomposer/NativeGateDecomposer.hpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 118605a1f..16fc7189c 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -44,13 +44,15 @@ class NativeGateDecomposer : public DecomposerBase { const Config& /* unused */) {} /** - * Converts commonly used single qubit gates into their Quaternion - * representation - * quaternion(R_v(phi))=(cos(phi/2)*I,v0*sin(phi/2)*X,v1*sin(phi/2)*Y,v2*sin(phi/2)*Z) - * with X,Y,Z Pauli Matrices + * @brief Converts commonly used single qubit gates into their Quaternion + * representation. + * @details A single qubit gate R_v(phi) with rotation axis v=(v0,v1,v2) + * and rotation angle phi can be represented as a quaternion: + * @code quaternion(R_v(phi)) = (cos(phi/2) * I, v0 * sin(phi/2) * X, v1 * + * sin(phi/2) * Y, v2 * sin(phi/2) * Z)@endcode with X, Y, Z Pauli Matrices. * @param op a reference_wrapper to the operation to be converted - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the - * components of the quaternion + * @returns an array of four `qc::fp` values `{q0, q1, q2, q3}` denoting the + * components of the quaternion. */ static auto convert_gate_to_quaternion(std::reference_wrapper op) From f1b778e8cc90c4802e32b3c7949545c5c4641880 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:56:42 +0100 Subject: [PATCH 043/110] =?UTF-8?q?=F0=9F=8E=A8=20Improve=20docstrings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 16fc7189c..effedb6dc 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -19,10 +19,19 @@ namespace na::zoned { class NativeGateDecomposer : public DecomposerBase { + /** + * A minimal struct to store the parameters of a U3 gate along with the qubit + * it acts on. + */ struct StructU3 { std::array angles; qc::Qubit qubit; }; + /** + * A quaternion is represented by an array of four `qc::fp` values `{q0, q1, + * q2, q3}` denoting the components of the quaternion. + */ + using Quaternion = std::array; size_t nQubits_ = 0; constexpr static qc::fp epsilon = @@ -51,61 +60,61 @@ class NativeGateDecomposer : public DecomposerBase { * @code quaternion(R_v(phi)) = (cos(phi/2) * I, v0 * sin(phi/2) * X, v1 * * sin(phi/2) * Y, v2 * sin(phi/2) * Z)@endcode with X, Y, Z Pauli Matrices. * @param op a reference_wrapper to the operation to be converted - * @returns an array of four `qc::fp` values `{q0, q1, q2, q3}` denoting the - * components of the quaternion. + * @returns a quaternion. */ static auto convert_gate_to_quaternion(std::reference_wrapper op) - -> std::array; + -> Quaternion; /** - * Merges the quaternions representing two gates as in a Matrix multiplication - * of the gates - * @param q1 the first Quaternion to be combined - * @param q2 the second Quaternion to be combined - * @returns an array of four qc::fp values [q0,q1,q2,q3] denoting the - * components of the combined quaternion + * @brief Merges the quaternions representing two gates as in a matrix + * multiplication of the gates. + * @param q1 the first quaternion to be combined. + * @param q2 the second quaternion to be combined. + * @returns an quaternion. */ - static auto combine_quaternions(const std::array& q1, - const std::array& q2) - -> std::array; + static auto combine_quaternions(const Quaternion& q1, const Quaternion& q2) + -> Quaternion; /** - * Calculates the values of the U3-Gate parameters theta, phi and lambda - * @param quat is a quaternion representing a single qubit gate - * @returns an array of three qc::fp values [theta, phi, lambda] giving the U§ - * gate angles + * @brief Calculates the values of the U3-gate parameters theta, phi, and + * lambda. + * @param quat is a quaternion representing a single qubit gate. + * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving + * the U3 gate angles. */ - static auto get_U3_angles_from_quaternion(const std::array& quat) + static auto get_U3_angles_from_quaternion(const Quaternion& quat) -> std::array; /** - * Calculates the largest value of the U3-Gate parameter theta from a vector - * of Operations. Fails when provided gates aren't all U3-Gates. - * @param layer is a SingleQubitGateLayers of a scheduled - * @returns the maximal value of theta in the given layer + * @brief Calculates the largest value of the U3-gate parameter theta from a + * vector of operations. + * @param layer is a vector of U3 parameters. + * @returns the maximal value of theta in the given layer. */ static auto calc_theta_max(const std::vector& layer) -> qc::fp; /** - * Takes a vector of SingleQubitGateLayer's and, for each layer - * , transforms all gates into U3 gates represented by struct_U3's - * , combining all gates acting on the same qubit into a single U3 gate + * @brief Takes a vector of SingleQubitGateLayers and, for each layer, + * transforms all gates into U3 gates represented by `StructU3` objects. + * @details It combines all gates acting on the same qubit into a single U3 + * gate. * @param layers is a std::vector of SingleQubitGateLayers of a scheduled - * circuit - * @returns a vector of vectors of a struct_U3's representing the single qubit - * gate layers + * circuit. + * @returns a vector of vectors of StructU3 objects representing the single + * qubit gate layers. */ [[nodiscard]] auto transform_to_U3(const std::vector& layers) const -> std::vector>; /** - * Takes a vector of qc::fp's representing the U3-Gate angles of a single - * qubit hate and the maximal value of theta for the single qubit gate layer - * and calculates the transversal decomposition angles as in Nottingham et. - * al. 2024 - * @param angles is a std::array of qc::fp representing (theta,phi, lambda) - * @param theta_max the maximal theta value of the single-qubit qate layer - * @returns an array of qc::fp values giving the angles (chi, gamma_minus, - * gamma_plus) + * @brief Takes a vector of `qc::fp` representing the U3-gate angles of a + * single-qubit gate and the maximal value of theta for the single qubit gate + * layer and calculates the transversal decomposition angles as in Nottingham + * et. al. 2024. + * @param angles is a `std::array` of `qc::fp` representing (theta, phi, + * lambda). + * @param theta_max the maximal theta value of the single-qubit qate layer. + * @returns an array of `qc::fp` values giving the angles (chi, gamma_minus, + * gamma_plus). */ auto static get_decomposition_angles(const std::array& angles, qc::fp theta_max) From ca6f971a722c2d371324bdcbf3c43a7d443bde70 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 3 Feb 2026 18:01:57 +0100 Subject: [PATCH 044/110] Fixed errors translating gates into Quaternions Small fixes --- .../zoned/decomposer/NativeGateDecomposer.hpp | 14 ++-- .../zoned/decomposer/NativeGateDecomposer.cpp | 76 +++++++++---------- test/na/zoned/test_native_gate_decomposer.cpp | 42 +++++----- 3 files changed, 60 insertions(+), 72 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index effedb6dc..c2cd5bd5c 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -63,7 +63,7 @@ class NativeGateDecomposer : public DecomposerBase { * @returns a quaternion. */ static auto - convert_gate_to_quaternion(std::reference_wrapper op) + convertGateToQuaternion(std::reference_wrapper op) -> Quaternion; /** * @brief Merges the quaternions representing two gates as in a matrix @@ -72,7 +72,7 @@ class NativeGateDecomposer : public DecomposerBase { * @param q2 the second quaternion to be combined. * @returns an quaternion. */ - static auto combine_quaternions(const Quaternion& q1, const Quaternion& q2) + static auto combineQuaternions(const Quaternion& q1, const Quaternion& q2) -> Quaternion; /** * @brief Calculates the values of the U3-gate parameters theta, phi, and @@ -81,7 +81,7 @@ class NativeGateDecomposer : public DecomposerBase { * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving * the U3 gate angles. */ - static auto get_U3_angles_from_quaternion(const Quaternion& quat) + static auto getU3AnglesFromQuaternion(const Quaternion& quat) -> std::array; /** @@ -90,7 +90,7 @@ class NativeGateDecomposer : public DecomposerBase { * @param layer is a vector of U3 parameters. * @returns the maximal value of theta in the given layer. */ - static auto calc_theta_max(const std::vector& layer) -> qc::fp; + static auto calcThetaMax(const std::vector& layer) -> qc::fp; /** * @brief Takes a vector of SingleQubitGateLayers and, for each layer, @@ -103,7 +103,7 @@ class NativeGateDecomposer : public DecomposerBase { * qubit gate layers. */ [[nodiscard]] auto - transform_to_U3(const std::vector& layers) const + transformToU3(const std::vector& layers) const -> std::vector>; /** * @brief Takes a vector of `qc::fp` representing the U3-gate angles of a @@ -112,11 +112,11 @@ class NativeGateDecomposer : public DecomposerBase { * et. al. 2024. * @param angles is a `std::array` of `qc::fp` representing (theta, phi, * lambda). - * @param theta_max the maximal theta value of the single-qubit qate layer. + * @param theta_max the maximal theta value of the single-qubit gate layer. * @returns an array of `qc::fp` values giving the angles (chi, gamma_minus, * gamma_plus). */ - auto static get_decomposition_angles(const std::array& angles, + auto static getDecompositionAngles(const std::array& angles, qc::fp theta_max) -> std::array; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 24833d402..28eab666b 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -21,14 +21,13 @@ namespace na::zoned { -auto NativeGateDecomposer::convert_gate_to_quaternion( - std::reference_wrapper op) -> std::array { +auto NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper op) -> Quaternion { assert(op.get().getNqubits() == 1); - std::array quat{}; - // TODO: Phase? + Quaternion quat{}; if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front()), 0, 0, - sin(op.get().getParameter().front())}; + quat = {cos(op.get().getParameter().front()/2), 0, 0, + sin(op.get().getParameter().front()/2)}; } else if (op.get().getType() == qc::Z) { quat = {0, 0, 0, 1}; } else if (op.get().getType() == qc::S) { @@ -40,16 +39,16 @@ auto NativeGateDecomposer::convert_gate_to_quaternion( } else if (op.get().getType() == qc::Tdg) { quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; } else if (op.get().getType() == qc::U) { - quat = combine_quaternions( - combine_quaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, + quat = combineQuaternions( + combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}, {cos(op.get().getParameter().front() / 2), 0, sin(op.get().getParameter().front() / 2), 0}), {cos(op.get().getParameter().at(2) / 2), 0, 0, sin(op.get().getParameter().at(2) / 2)}); } else if (op.get().getType() == qc::U2) { - quat = combine_quaternions( - combine_quaternions({cos(op.get().getParameter().front() / 2), 0, 0, + quat = combineQuaternions( + combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, sin(op.get().getParameter().front() / 2)}, {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, @@ -61,26 +60,26 @@ auto NativeGateDecomposer::convert_gate_to_quaternion( quat = {cos(op.get().getParameter().front() / 2), 0, sin(op.get().getParameter().front() / 2), 0}; } else if (op.get().getType() == qc::H) { - quat = combine_quaternions( - combine_quaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + quat = combineQuaternions( + combineQuaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); } else if (op.get().getType() == qc::X) { quat = {0, 1, 0, 0}; } else if (op.get().getType() == qc::Y) { - quat = {0, 1, 0, 0}; + quat = {0, 0, 1, 0}; } else if (op.get().getType() == qc::Vdg) { - quat = combine_quaternions( - combine_quaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, + quat = combineQuaternions( + combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); } else if (op.get().getType() == qc::SX) { - quat = combine_quaternions( - combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + quat = combineQuaternions( + combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { - quat = combine_quaternions( - combine_quaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + quat = combineQuaternions( + combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else { @@ -94,10 +93,10 @@ auto NativeGateDecomposer::convert_gate_to_quaternion( return quat; } -auto NativeGateDecomposer::combine_quaternions(const std::array& q1, - const std::array& q2) - -> std::array { - std::array new_quat{}; +auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, + const Quaternion& q2) + -> Quaternion { + Quaternion new_quat{}; new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; @@ -105,10 +104,8 @@ auto NativeGateDecomposer::combine_quaternions(const std::array& q1, return new_quat; } -auto NativeGateDecomposer::get_U3_angles_from_quaternion( - const std::array& quat) -> std::array { - // TODO: Is there a prescribed eps somewhere? Else where should THIS eps be - // defined +auto NativeGateDecomposer::getU3AnglesFromQuaternion( + const Quaternion& quat) -> std::array { qc::fp theta; qc::fp phi; qc::fp lambda; @@ -140,7 +137,7 @@ auto NativeGateDecomposer::get_U3_angles_from_quaternion( return {theta, phi, lambda}; } -auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) +auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { @@ -150,10 +147,9 @@ auto NativeGateDecomposer::calc_theta_max(const std::vector& layer) } return theta_max; } -auto NativeGateDecomposer::transform_to_U3( +auto NativeGateDecomposer::transformToU3( const std::vector& layers) const -> std::vector> { - // auto u=struct_U3({0,0,0},0); std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( @@ -165,12 +161,12 @@ auto NativeGateDecomposer::transform_to_U3( for (auto qubit_gates : gates) { if (!qubit_gates.empty()) { - std::array quat = convert_gate_to_quaternion(qubit_gates[0]); + std::array quat = convertGateToQuaternion(qubit_gates[0]); for (auto i = 1; i < qubit_gates.size(); i++) { - quat = combine_quaternions( - quat, convert_gate_to_quaternion(qubit_gates[i])); + quat = combineQuaternions( + quat, convertGateToQuaternion(qubit_gates[i])); } - std::array angles = get_U3_angles_from_quaternion(quat); + std::array angles = getU3AnglesFromQuaternion(quat); new_layer.emplace_back( StructU3(angles, qubit_gates[0].get().getTargets().front())); } @@ -179,10 +175,10 @@ auto NativeGateDecomposer::transform_to_U3( } return new_layers; } -auto NativeGateDecomposer::get_decomposition_angles( +auto NativeGateDecomposer::getDecompositionAngles( const std::array& angles, qc::fp theta_max) -> std::array { - qc::fp alpha, chi, beta; + qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) if (abs(angles[0] - theta_max) < epsilon) { @@ -199,7 +195,7 @@ auto NativeGateDecomposer::get_decomposition_angles( alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } - beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; + qc::fp beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; qc::fp gamma_plus = fmod(angles[2] - (alpha + beta), qc::TAU); qc::fp gamma_minus = fmod(angles[1] - (alpha - beta), qc::TAU); @@ -213,12 +209,12 @@ auto NativeGateDecomposer::decompose( nQubits_ = nQubits; std::vector> U3Layers = - transform_to_U3(singleQubitGateLayers); + transformToU3(singleQubitGateLayers); std::vector NewSingleQubitLayers = std::vector{}; for (const auto& layer : U3Layers) { - qc::fp theta_max = calc_theta_max(layer); + qc::fp theta_max = calcThetaMax(layer); SingleQubitGateLayer FrontLayer; SingleQubitGateLayer MidLayer; SingleQubitGateLayer BackLayer; @@ -226,7 +222,7 @@ auto NativeGateDecomposer::decompose( for (auto gate : layer) { std::array decomp_angles = - get_decomposition_angles(gate.angles, theta_max); + getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 428500b04..0d807cf03 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -62,7 +62,7 @@ qc::fp epsilon = 1e-5; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; - std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combineQuaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * cos(qc::PI_4), epsilon), @@ -70,7 +70,7 @@ TEST(Test, ThreeQuaternionCombiTest) { ::testing::DoubleNear(0, epsilon))); std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; std::array q13 = - NativeGateDecomposer::combine_quaternions(q12, q3); + NativeGateDecomposer::combineQuaternions(q12, q3); EXPECT_THAT( q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), @@ -81,7 +81,7 @@ TEST(Test, ThreeQuaternionCombiTest) { TEST(Test, ThreeQuaternionU3Test) { std::array q1 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; std::array q2 = {cos(qc::PI_4 / 2), 0, sin(qc::PI_4 / 2), 0}; - std::array q12 = NativeGateDecomposer::combine_quaternions(q1, q2); + std::array q12 = NativeGateDecomposer::combineQuaternions(q1, q2); EXPECT_THAT(q12, ::testing::ElementsAre( ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * sin(qc::PI_4 / 2), epsilon), @@ -89,7 +89,7 @@ TEST(Test, ThreeQuaternionU3Test) { ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q13 = - NativeGateDecomposer::combine_quaternions(q12, q3); + NativeGateDecomposer::combineQuaternions(q12, q3); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), @@ -99,25 +99,23 @@ TEST(Test, ThreeQuaternionU3Test) { } TEST(Test, SingleXGateAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::X); - qc::QuantumComputation qc(n); + qc::QuantumComputation qc(1); qc.rx(qc::PI, 0); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); EXPECT_THAT( - NativeGateDecomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, SingleU3GateAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI_4, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre( @@ -126,17 +124,16 @@ TEST(Test, SingleU3GateAngleTest) { ::testing::DoubleNear(r2 * sin(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(r2 * cos(qc::PI_4 / 2), epsilon))); - EXPECT_THAT(NativeGateDecomposer::get_U3_angles_from_quaternion(q), + EXPECT_THAT(NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_4, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); } TEST(Test, ThetaPiAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {qc::PI, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), @@ -144,17 +141,16 @@ TEST(Test, ThetaPiAngleTest) { ::testing::DoubleNear(r2, epsilon), ::testing::DoubleNear(0, epsilon))); EXPECT_THAT( - NativeGateDecomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(-1 * qc::PI_2, epsilon))); } TEST(Test, ThetaZeroAngleTest) { - size_t n = 1; const qc::Operation* op = new qc::StandardOperation(0, qc::U, {0, qc::PI, qc::PI_2}); - std::array q = NativeGateDecomposer::convert_gate_to_quaternion( + std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q, ::testing::ElementsAre(::testing::DoubleNear(-r2, epsilon), @@ -163,41 +159,38 @@ TEST(Test, ThetaZeroAngleTest) { ::testing::DoubleNear(r2, epsilon))); EXPECT_THAT( - NativeGateDecomposer::get_U3_angles_from_quaternion(q), + NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(3 * qc::PI_2, epsilon))); } TEST(Test, RXDecompositionTest) { - size_t n = 1; std::array rx = {qc::PI, -qc::PI_2, qc::PI_2}; - EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(rx, qc::PI), + EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(rx, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); } TEST(Test, U3DecompositionTest) { - size_t n = 1; std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! EXPECT_THAT( - NativeGateDecomposer::get_decomposition_angles(u3, qc::PI_4), + NativeGateDecomposer::getDecompositionAngles(u3, qc::PI_4), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(-qc::PI_2, epsilon))); } TEST(Test, DoubleDecompositionTest) { - size_t n = 1; std::array x1 = {qc::PI, -qc::PI_2, qc::PI_2}; std::array z2 = {0, 0, qc::PI}; - EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(x1, qc::PI), + EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(x1, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon))); - EXPECT_THAT(NativeGateDecomposer::get_decomposition_angles(z2, qc::PI), + EXPECT_THAT(NativeGateDecomposer::getDecompositionAngles(z2, qc::PI), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon), ::testing::DoubleNear(qc::PI_2, epsilon))); @@ -292,7 +285,6 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { EXPECT_TRUE(decomp[0][3]->isGlobal(n)); EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - // TODO: FIgure out i this is always Positive EXPECT_THAT( decomp[0][4]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(3 * qc::PI_2, epsilon))); From f1e211cbe2a1014b207500a969d95189c9fa2a84 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 5 Feb 2026 14:12:59 +0100 Subject: [PATCH 045/110] Fixed errors translating gates into Quaternions Small fixes --- include/na/zoned/Compiler.hpp | 4 ++-- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index f9c084eaa..4a66f01ed 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -204,7 +204,7 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Decomposing..."); const auto decomposingStart = std::chrono::system_clock::now(); const auto& decomposedSingleQubitGateLayers = - SELF.decompose(singleQubitGateLayers); + SELF.decompose(qComp.getNqubits(), singleQubitGateLayers); const auto decomposingEnd = std::chrono::system_clock::now(); statistics_.decomposingTime = std::chrono::duration_cast(decomposingEnd - @@ -314,7 +314,7 @@ class RoutingAwareCompiler final }; class RoutingAwareNativeGateCompiler final - : public Compiler { public: diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 28eab666b..c5be54bbc 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -242,7 +242,7 @@ auto NativeGateDecomposer::decompose( std::vector> GR_plus; std::vector> GR_minus; - for (auto i = 0; i < this->nQubits_; ++i) { + for (size_t i = 0; i < this->nQubits_; ++i) { GR_plus.emplace_back( new qc::StandardOperation(i, qc::RY, {theta_max / 2})); GR_minus.emplace_back( From accf7275d01aa56470baa10ffb31beff72bd465a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 17:02:48 +0000 Subject: [PATCH 046/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 3 +- .../zoned/decomposer/NativeGateDecomposer.cpp | 30 +++++++++---------- test/na/zoned/test_native_gate_decomposer.cpp | 6 ++-- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index c2cd5bd5c..a81cca4e4 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -117,8 +117,7 @@ class NativeGateDecomposer : public DecomposerBase { * gamma_plus). */ auto static getDecompositionAngles(const std::array& angles, - qc::fp theta_max) - -> std::array; + qc::fp theta_max) -> std::array; [[nodiscard]] auto decompose(size_t nQubits, diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index c5be54bbc..9a441656a 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -26,8 +26,8 @@ auto NativeGateDecomposer::convertGateToQuaternion( assert(op.get().getNqubits() == 1); Quaternion quat{}; if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front()/2), 0, 0, - sin(op.get().getParameter().front()/2)}; + quat = {cos(op.get().getParameter().front() / 2), 0, 0, + sin(op.get().getParameter().front() / 2)}; } else if (op.get().getType() == qc::Z) { quat = {0, 0, 0, 1}; } else if (op.get().getType() == qc::S) { @@ -41,16 +41,16 @@ auto NativeGateDecomposer::convertGateToQuaternion( } else if (op.get().getType() == qc::U) { quat = combineQuaternions( combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, - sin(op.get().getParameter().at(1) / 2)}, - {cos(op.get().getParameter().front() / 2), 0, - sin(op.get().getParameter().front() / 2), 0}), + sin(op.get().getParameter().at(1) / 2)}, + {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}), {cos(op.get().getParameter().at(2) / 2), 0, 0, sin(op.get().getParameter().at(2) / 2)}); } else if (op.get().getType() == qc::U2) { quat = combineQuaternions( combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, - sin(op.get().getParameter().front() / 2)}, - {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), + sin(op.get().getParameter().front() / 2)}, + {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}); } else if (op.get().getType() == qc::RX) { @@ -70,17 +70,17 @@ auto NativeGateDecomposer::convertGateToQuaternion( } else if (op.get().getType() == qc::Vdg) { quat = combineQuaternions( combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); } else if (op.get().getType() == qc::SX) { quat = combineQuaternions( combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { quat = combineQuaternions( combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); } else { // if the gate type is not recognized, an error is printed and the @@ -94,7 +94,7 @@ auto NativeGateDecomposer::convertGateToQuaternion( } auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, - const Quaternion& q2) + const Quaternion& q2) -> Quaternion { Quaternion new_quat{}; new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; @@ -104,8 +104,8 @@ auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, return new_quat; } -auto NativeGateDecomposer::getU3AnglesFromQuaternion( - const Quaternion& quat) -> std::array { +auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) + -> std::array { qc::fp theta; qc::fp phi; qc::fp lambda; @@ -163,8 +163,8 @@ auto NativeGateDecomposer::transformToU3( if (!qubit_gates.empty()) { std::array quat = convertGateToQuaternion(qubit_gates[0]); for (auto i = 1; i < qubit_gates.size(); i++) { - quat = combineQuaternions( - quat, convertGateToQuaternion(qubit_gates[i])); + quat = + combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); } std::array angles = getU3AnglesFromQuaternion(quat); new_layer.emplace_back( diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 0d807cf03..821a72fe8 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -69,8 +69,7 @@ TEST(Test, ThreeQuaternionCombiTest) { ::testing::DoubleNear(cos(qc::PI_4), epsilon), ::testing::DoubleNear(0, epsilon))); std::array q3 = {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}; - std::array q13 = - NativeGateDecomposer::combineQuaternions(q12, q3); + std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); EXPECT_THAT( q13, ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4), epsilon), @@ -88,8 +87,7 @@ TEST(Test, ThreeQuaternionU3Test) { ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - std::array q13 = - NativeGateDecomposer::combineQuaternions(q12, q3); + std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); qc::fp r2 = 1 / sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), From 917ae75501ebde2fc58b17392b37c7f583061142 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sat, 7 Feb 2026 15:59:08 +0100 Subject: [PATCH 047/110] Adressed an outdated Test and some signed/unsigned type issues --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 4 ++-- test/na/zoned/test_native_gate_decomposer.cpp | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 9a441656a..ab479a200 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -162,13 +162,13 @@ auto NativeGateDecomposer::transformToU3( for (auto qubit_gates : gates) { if (!qubit_gates.empty()) { std::array quat = convertGateToQuaternion(qubit_gates[0]); - for (auto i = 1; i < qubit_gates.size(); i++) { + for (size_t i = 1; i < qubit_gates.size(); i++) { quat = combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); } std::array angles = getU3AnglesFromQuaternion(quat); new_layer.emplace_back( - StructU3(angles, qubit_gates[0].get().getTargets().front())); + StructU3{angles, qubit_gates[0].get().getTargets().front()}); } } new_layers.push_back(new_layer); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 821a72fe8..1e3cb2154 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -98,16 +98,13 @@ TEST(Test, ThreeQuaternionU3Test) { TEST(Test, SingleXGateAngleTest) { const qc::Operation* op = new qc::StandardOperation(0, qc::X); - - qc::QuantumComputation qc(1); - qc.rx(qc::PI, 0); std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); EXPECT_THAT( NativeGateDecomposer::getU3AnglesFromQuaternion(q), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(-1 * qc::PI_2, epsilon), - ::testing::DoubleNear(qc::PI_2, epsilon))); + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(qc::PI, epsilon))); } TEST(Test, SingleU3GateAngleTest) { From 49136f1b39a34ef2215225487a9ca756a845f99b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:15:24 +0000 Subject: [PATCH 048/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/Compiler.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index 4a66f01ed..ce37b3414 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -314,9 +314,9 @@ class RoutingAwareCompiler final }; class RoutingAwareNativeGateCompiler final - : public Compiler { + : public Compiler { public: RoutingAwareNativeGateCompiler(const Architecture& architecture, const Config& config) From a42674eba2830040bd2a1b2ad8b96a65601c9662 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sat, 7 Feb 2026 17:19:59 +0100 Subject: [PATCH 049/110] switched abs with fabs --- .../zoned/decomposer/NativeGateDecomposer.cpp | 23 +++++++++---------- test/na/zoned/test_native_gate_decomposer.cpp | 3 ++- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index ab479a200..5575c746a 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -12,8 +12,6 @@ // Created by cpsch on 11.12.2025. // #include "na/zoned/decomposer/NativeGateDecomposer.hpp" - -// #include "ir/operations/StandardOperation.hpp" #include "ir/operations/CompoundOperation.hpp" #include @@ -50,7 +48,7 @@ auto NativeGateDecomposer::convertGateToQuaternion( quat = combineQuaternions( combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, sin(op.get().getParameter().front() / 2)}, - {cos(qc::PI_2), 0, sin(qc::PI_2), 0}), + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}); } else if (op.get().getType() == qc::RX) { @@ -86,7 +84,7 @@ auto NativeGateDecomposer::convertGateToQuaternion( // if the gate type is not recognized, an error is printed and the // gate is not included in the output. std::ostringstream oss; - oss << "\033[1;31m[ERROR]\033[0m Unsupported single-qubit gate: " + oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() << "\n"; throw std::invalid_argument(oss.str()); } @@ -109,11 +107,11 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) qc::fp theta; qc::fp phi; qc::fp lambda; - if (abs(quat[0]) > epsilon || abs(quat[3]) > epsilon) { + if (std::fabs(quat[0]) > epsilon || std::fabs(quat[3]) > epsilon) { theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // phi+ lambda - if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); phi = alpha_1 + alpha_2; // phi lambda = alpha_1 - alpha_2; @@ -124,7 +122,7 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) } else { theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= // exp(i*pi) just global phase - if (abs(quat[1]) > epsilon || abs(quat[2]) > epsilon) { + if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { phi = 0; lambda = 2 * std::atan2(quat[1], quat[2]); // atan can give PI instead of 0 Problem? @@ -141,7 +139,7 @@ auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) -> qc::fp { qc::fp theta_max = 0; for (auto gate : layer) { - if (abs(gate.angles[0]) > theta_max) { + if (std::fabs(gate.angles[0]) > theta_max) { theta_max = abs(gate.angles[0]); } } @@ -181,9 +179,9 @@ auto NativeGateDecomposer::getDecompositionAngles( qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - if (abs(angles[0] - theta_max) < epsilon) { + if (std::fabs(angles[0] - theta_max) < epsilon) { chi = qc::PI; - if (abs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? + if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; } else { alpha = qc::PI_2; @@ -244,9 +242,10 @@ auto NativeGateDecomposer::decompose( for (size_t i = 0; i < this->nQubits_; ++i) { GR_plus.emplace_back( - new qc::StandardOperation(i, qc::RY, {theta_max / 2})); + std::make_unique(i, qc::RY, std::initializer_list{theta_max / 2})); GR_minus.emplace_back( - new qc::StandardOperation(i, qc::RY, {-1 * theta_max / 2})); + std::make_unique(i, qc::RY, std::initializer_list{-1 * theta_max / 2})); + } for (auto&& gate : FrontLayer) { diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 1e3cb2154..c4a9905d6 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -57,7 +57,8 @@ class DecomposerTest : public ::testing::Test { decomposer(architecture, decomposerConfig) {} }; -qc::fp epsilon = 1e-5; +constexpr static qc::fp epsilon = + std::numeric_limits::epsilon() * 1024; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; From dfc4030f0071123e0eab1339cc0972d34d8b07a1 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sat, 7 Feb 2026 17:35:36 +0100 Subject: [PATCH 050/110] switched abs with fabs --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 14 +++++++------- test/na/zoned/test_native_gate_decomposer.cpp | 12 +++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 5575c746a..42c43460d 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -12,6 +12,7 @@ // Created by cpsch on 11.12.2025. // #include "na/zoned/decomposer/NativeGateDecomposer.hpp" + #include "ir/operations/CompoundOperation.hpp" #include @@ -84,8 +85,8 @@ auto NativeGateDecomposer::convertGateToQuaternion( // if the gate type is not recognized, an error is printed and the // gate is not included in the output. std::ostringstream oss; - oss << "ERROR: Unsupported single-qubit gate: " - << op.get().getType() << "\n"; + oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() + << "\n"; throw std::invalid_argument(oss.str()); } return quat; @@ -241,11 +242,10 @@ auto NativeGateDecomposer::decompose( std::vector> GR_minus; for (size_t i = 0; i < this->nQubits_; ++i) { - GR_plus.emplace_back( - std::make_unique(i, qc::RY, std::initializer_list{theta_max / 2})); - GR_minus.emplace_back( - std::make_unique(i, qc::RY, std::initializer_list{-1 * theta_max / 2})); - + GR_plus.emplace_back(std::make_unique( + i, qc::RY, std::initializer_list{theta_max / 2})); + GR_minus.emplace_back(std::make_unique( + i, qc::RY, std::initializer_list{-1 * theta_max / 2})); } for (auto&& gate : FrontLayer) { diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index c4a9905d6..f1aa12bce 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -57,8 +57,7 @@ class DecomposerTest : public ::testing::Test { decomposer(architecture, decomposerConfig) {} }; -constexpr static qc::fp epsilon = - std::numeric_limits::epsilon() * 1024; +constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; @@ -101,11 +100,10 @@ TEST(Test, SingleXGateAngleTest) { const qc::Operation* op = new qc::StandardOperation(0, qc::X); std::array q = NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper(*op)); - EXPECT_THAT( - NativeGateDecomposer::getU3AnglesFromQuaternion(q), - ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(qc::PI, epsilon))); + EXPECT_THAT(NativeGateDecomposer::getU3AnglesFromQuaternion(q), + ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(qc::PI, epsilon))); } TEST(Test, SingleU3GateAngleTest) { From 1047c352aaf35ec5f3256c913b1fe75668a0ebae Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 9 Feb 2026 17:36:06 +0100 Subject: [PATCH 051/110] made some changes to pushing decomposed operations into layers changed check for calculation of decomposition angles for sin/theta_m) near sin(theta) --- .../zoned/decomposer/NativeGateDecomposer.cpp | 32 ++++++------------- test/na/zoned/test_native_gate_decomposer.cpp | 4 +-- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 42c43460d..6013115d5 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -141,7 +141,7 @@ auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) qc::fp theta_max = 0; for (auto gate : layer) { if (std::fabs(gate.angles[0]) > theta_max) { - theta_max = abs(gate.angles[0]); + theta_max = std::fabs(gate.angles[0]); } } return theta_max; @@ -180,7 +180,8 @@ auto NativeGateDecomposer::getDecompositionAngles( qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - if (std::fabs(angles[0] - theta_max) < epsilon) { + qc::fp sin_sq_diff= (sin(theta_max/2) * sin(theta_max/2) - (sin(angles[0] / 2) * sin(angles[0] / 2))); + if (std::fabs(sin_sq_diff) < epsilon ) { chi = qc::PI; if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; @@ -188,9 +189,7 @@ auto NativeGateDecomposer::getDecompositionAngles( alpha = qc::PI_2; } } else { - qc::fp kappa = sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / - (sin(theta_max) * sin(theta_max) - - (sin(angles[0] / 2) * sin(angles[0] / 2)))); + qc::fp kappa = std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } @@ -224,18 +223,11 @@ auto NativeGateDecomposer::decompose( getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - auto sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}); - std::unique_ptr op = - std::make_unique(sop); - FrontLayer.emplace_back(std::move(op)); + FrontLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}); - op = std::make_unique(sop); - MidLayer.emplace_back(std::move(op)); + MidLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - sop = qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}); - op = std::make_unique(sop); - BackLayer.emplace_back(std::move(op)); + BackLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer std::vector> GR_plus; @@ -252,18 +244,12 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - auto cop = qc::CompoundOperation(std::move(GR_plus), true); - std::unique_ptr ryp = - std::make_unique(cop); - NewLayer.emplace_back(std::move(ryp)); + NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - cop = qc::CompoundOperation(std::move(GR_minus), true); - std::unique_ptr rym = - std::make_unique(cop); - NewLayer.emplace_back(std::move(rym)); + NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index f1aa12bce..fa4e8a7c1 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -88,7 +88,7 @@ TEST(Test, ThreeQuaternionU3Test) { ::testing::DoubleNear(cos(qc::PI_4 / 2), epsilon))); std::array q3 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q13 = NativeGateDecomposer::combineQuaternions(q12, q3); - qc::fp r2 = 1 / sqrt(2); + qc::fp r2 = 1 / std::sqrt(2); EXPECT_THAT(q13, ::testing::ElementsAre( ::testing::DoubleNear(-r2 * cos(qc::PI_4 / 2), epsilon), ::testing::DoubleNear(-r2 * sin(qc::PI_4 / 2), epsilon), @@ -249,8 +249,6 @@ TEST_F(DecomposerTest, SingleU3Gate) { ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } -// TEST with U3(o,?,?) -// TEST with two Single Qubit Layers TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ From 96b84f91f9ef3f780cff7ab278800954041d3e4e Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 9 Feb 2026 17:41:39 +0100 Subject: [PATCH 052/110] made some changes to pushing decomposed operations into layers changed check for calculation of decomposition angles for sin/theta_m) near sin(theta) --- .../zoned/decomposer/NativeGateDecomposer.cpp | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 6013115d5..1be86f718 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -180,8 +180,9 @@ auto NativeGateDecomposer::getDecompositionAngles( qc::fp alpha, chi; // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - qc::fp sin_sq_diff= (sin(theta_max/2) * sin(theta_max/2) - (sin(angles[0] / 2) * sin(angles[0] / 2))); - if (std::fabs(sin_sq_diff) < epsilon ) { + qc::fp sin_sq_diff = (sin(theta_max / 2) * sin(theta_max / 2) - + (sin(angles[0] / 2) * sin(angles[0] / 2))); + if (std::fabs(sin_sq_diff) < epsilon) { chi = qc::PI; if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? alpha = 0; @@ -189,7 +190,8 @@ auto NativeGateDecomposer::getDecompositionAngles( alpha = qc::PI_2; } } else { - qc::fp kappa = std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); + qc::fp kappa = + std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } @@ -223,11 +225,14 @@ auto NativeGateDecomposer::decompose( getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - FrontLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); + FrontLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - MidLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); + MidLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - BackLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); + BackLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer std::vector> GR_plus; @@ -244,12 +249,14 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); + NewLayer.emplace_back( + std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); + NewLayer.emplace_back( + std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); From 9fefb28426b6a746baa3e8318f050d361023f6aa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:41:51 +0000 Subject: [PATCH 053/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.cpp | 18 ++++++------------ test/na/zoned/test_native_gate_decomposer.cpp | 1 - 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 1be86f718..42f64eb1c 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -190,8 +190,7 @@ auto NativeGateDecomposer::getDecompositionAngles( alpha = qc::PI_2; } } else { - qc::fp kappa = - std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); + qc::fp kappa = std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } @@ -225,14 +224,11 @@ auto NativeGateDecomposer::decompose( getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - FrontLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); + FrontLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - MidLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); + MidLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - BackLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); + BackLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer std::vector> GR_plus; @@ -249,14 +245,12 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back( - std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); + NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back( - std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); + NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index fa4e8a7c1..4e89d598a 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -249,7 +249,6 @@ TEST_F(DecomposerTest, SingleU3Gate) { ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } - TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { // ┌───────┐ ┌───────┐ // q: ┤ X ├──┤ Z ├ From abf556407749cfb4b7b8eae3f86ccf2997ef4d0a Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 9 Feb 2026 17:52:02 +0100 Subject: [PATCH 054/110] minor comment change --- test/na/zoned/test_native_gate_decomposer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 4e89d598a..61f969281 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -169,7 +169,6 @@ TEST(Test, RXDecompositionTest) { TEST(Test, U3DecompositionTest) { std::array u3 = {qc::PI_4, qc::PI, qc::PI_2}; - // gamm minus i - PI_" not PI_2 and game_plus is 0 not PI!! EXPECT_THAT( NativeGateDecomposer::getDecompositionAngles(u3, qc::PI_4), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon), From 5710c28f0ecbfb77c3d0e5a80c028f23b9538516 Mon Sep 17 00:00:00 2001 From: Daniel Haag <121057143+denialhaag@users.noreply.github.com> Date: Mon, 2 Feb 2026 01:51:53 +0100 Subject: [PATCH 055/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20`prek`=20?= =?UTF-8?q?checks=20(#925)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This PR updates `.pre-commit-config.yml` to make use of `prek`'s priority feature. The commits were initially part of #921, which is blocked due to a CD issue. ## Checklist: - [x] The pull request only contains commits that are focused and relevant to this change. - [x] ~I have added appropriate tests that cover the new/changed functionality.~ - [x] ~I have updated the documentation to reflect these changes.~ - [x] ~I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.~ - [x] ~I have added migration instructions to the upgrade guide (if needed).~ - [x] The changes follow the project's style guidelines and introduce no new warnings. - [x] The changes are fully tested and pass the CI checks. - [x] I have reviewed my own code changes. --- .pre-commit-config.yaml | 209 ++++++++++++++-------------- pyproject.toml | 11 +- uv.lock | 298 ++++++++++++++++++++-------------------- 3 files changed, 258 insertions(+), 260 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 758e9ad64..1a7655beb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,114 +1,118 @@ # To run all pre-commit checks, use: # -# pre-commit run -a +# uvx prek run -a # # To install pre-commit hooks that run every time you commit: # -# pre-commit install +# uv tool install prek +# prek install # ci: autoupdate_commit_msg: "⬆️🪝 update pre-commit hooks" - autofix_commit_msg: "🎨 pre-commit fixes" autoupdate_schedule: quarterly + autofix_commit_msg: "🎨 pre-commit fixes" skip: [ty-check] repos: - # Standard hooks + # Priority 0: Fast validation and independent fixers + + ## Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - - id: check-added-large-files - args: ["--maxkb=2048"] - - id: check-case-conflict - - id: check-vcs-permalinks - id: check-merge-conflict - - id: check-symlinks - - id: check-json - - id: check-toml - - id: check-yaml - - id: debug-statements + priority: 0 - id: end-of-file-fixer - - id: mixed-line-ending + priority: 1 - id: trailing-whitespace + priority: 1 - # Clean jupyter notebooks - - repo: https://github.com/srstevenson/nb-clean - rev: 4.0.1 + ## Check the pyproject.toml file + - repo: https://github.com/henryiii/validate-pyproject-schema-store + rev: 2026.01.22 hooks: - - id: nb-clean - args: - - --remove-empty-cells - - --preserve-cell-metadata - - raw_mimetype - - -- - - # Handling unwanted unicode characters - - repo: https://github.com/sirosen/texthooks - rev: 0.7.1 + - id: validate-pyproject + priority: 0 + + ## Check JSON schemata + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.36.0 + hooks: + - id: check-github-workflows + priority: 0 + - id: check-readthedocs + priority: 0 + + ## Catch common capitalization mistakes + - repo: local hooks: - - id: fix-ligatures - - id: fix-smartquotes + - id: disallow-caps + name: Disallow improper capitalization + language: pygrep + entry: Nanobind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum + exclude: .pre-commit-config.yaml + priority: 0 - # Check for common mistakes - - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 + ## Check for spelling + - repo: https://github.com/adhtruong/mirrors-typos + rev: v1.42.1 hooks: - - id: rst-backticks - - id: rst-directive-colons - - id: rst-inline-touching-normal + - id: typos + priority: 0 - # Check for license headers + ## Check best practices for scientific Python code + - repo: https://github.com/scientific-python/cookie + rev: 2025.11.21 + hooks: + - id: sp-repo-review + additional_dependencies: ["repo-review[cli]"] + priority: 0 + + ## Check for license headers - repo: https://github.com/emzeat/mz-lictools rev: v2.9.0 hooks: - id: license-tools + priority: 0 - # Ensure uv lock file is up-to-date + ## Ensure uv lock file is up-to-date - repo: https://github.com/astral-sh/uv-pre-commit rev: 0.9.26 hooks: - id: uv-lock + priority: 0 - # Python linting using ruff - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.14 - hooks: - - id: ruff-check - - id: ruff-format - - # Also run Black on examples in the documentation - - repo: https://github.com/adamchainz/blacken-docs - rev: 1.20.0 - hooks: - - id: blacken-docs - additional_dependencies: [black==25.*] - - ## Static type checking using ty - - repo: local + ## Tidy up BibTeX files + - repo: https://github.com/FlamingTempura/bibtex-tidy + rev: v1.14.0 hooks: - - id: ty-check - name: ty check - entry: uvx python -c "import subprocess; import sys; r = subprocess.run(['uv', 'sync', '--no-install-project', '--inexact']); sys.exit(r.returncode or subprocess.run(['uv', 'run', '--no-sync', 'ty', 'check']).returncode)" - language: unsupported - require_serial: true - types_or: [python, pyi, jupyter] - exclude: ^(docs/|eval/) + - id: bibtex-tidy + args: + [ + "--align=20", + "--curly", + "--months", + "--blank-lines", + "--sort", + "--strip-enclosing-braces", + "--sort-fields", + "--trailing-commas", + "--remove-empty-fields", + ] + priority: 0 - # Check for spelling - - repo: https://github.com/adhtruong/mirrors-typos - rev: v1.42.1 - hooks: - - id: typos + # Priority 1: Second-pass fixers - # Clang-format the C++ part of the code base automatically + ## Clang-format the C++ part of the code base automatically - repo: https://github.com/pre-commit/mirrors-clang-format rev: v21.1.8 hooks: - id: clang-format types_or: [c++, c, cuda] + priority: 1 - # CMake format and lint the CMakeLists.txt files + ## CMake format and lint the CMakeLists.txt files - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 hooks: @@ -116,58 +120,45 @@ repos: additional_dependencies: [pyyaml] types: [file] files: (\.cmake|CMakeLists.txt)(.in)?$ + priority: 1 - # Format configuration files with prettier + ## Format configuration files with prettier - repo: https://github.com/rbubley/mirrors-prettier rev: v3.8.1 hooks: - id: prettier types_or: [yaml, markdown, html, css, scss, javascript, json] + priority: 1 - # Catch common capitalization mistakes - - repo: local - hooks: - - id: disallow-caps - name: Disallow improper capitalization - language: pygrep - entry: Nanobind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum - exclude: .pre-commit-config.yaml - - # Check best practices for scientific Python code - - repo: https://github.com/scientific-python/cookie - rev: 2025.11.21 + ## Python linting using ruff + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.14 hooks: - - id: sp-repo-review - additional_dependencies: ["repo-review[cli]"] + - id: ruff-format + priority: 1 + - id: ruff-check + require_serial: true + priority: 2 - # Check JSON schemata - - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.36.0 - hooks: - - id: check-dependabot - - id: check-github-workflows - - id: check-readthedocs + # Priority 2+: Final checks and fixers - # Check the pyproject.toml file - - repo: https://github.com/henryiii/validate-pyproject-schema-store - rev: 2026.01.22 + ## Also run Black on examples in the documentation (needs to run after ruff format) + - repo: https://github.com/adamchainz/blacken-docs + rev: 1.20.0 hooks: - - id: validate-pyproject + - id: blacken-docs + language: python + additional_dependencies: [black==26.*] + priority: 2 - # Tidy up BibTeX files - - repo: https://github.com/FlamingTempura/bibtex-tidy - rev: v1.14.0 + ## Static type checking using ty (needs to run after lockfile update/ruff format, and ruff lint) + - repo: local hooks: - - id: bibtex-tidy - args: - [ - "--align=20", - "--curly", - "--months", - "--blank-lines", - "--sort", - "--strip-enclosing-braces", - "--sort-fields", - "--trailing-commas", - "--remove-empty-fields", - ] + - id: ty-check + name: ty check + entry: uvx python -c "import subprocess; import sys; r = subprocess.run(['uv', 'sync', '--no-install-project', '--inexact']); sys.exit(r.returncode or subprocess.run(['uv', 'run', '--no-sync', 'ty', 'check']).returncode)" + language: unsupported + require_serial: true + types_or: [python, pyi, jupyter] + exclude: ^(docs/|eval/) + priority: 3 diff --git a/pyproject.toml b/pyproject.toml index 10a39aae0..68bf03f62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,10 +8,10 @@ [build-system] requires = [ - "nanobind>=2.10.2", + "nanobind~=2.10.2", "setuptools-scm>=9.2.2", "scikit-build-core>=0.11.6", - "mqt.core~=3.4.0", + "mqt.core==3.4.0", ] build-backend = "scikit_build_core.build" @@ -51,7 +51,7 @@ classifiers = [ ] requires-python = ">=3.10, != 3.14.1" dependencies = [ - "mqt.core~=3.4.0", + "mqt.core==3.4.0", "qiskit[qasm3-import]>=1.0.0", "rustworkx[all]>=0.16.0", "typing_extensions>=4.6; python_version < '3.11'", @@ -303,6 +303,7 @@ ignore = [ "MY100", # We use ty instead of mypy "PC140", # We use ty instead of mypy "PC160", # We use a mirror of crate-ci/typos + "PC170", # We do not use rST files anymore ] @@ -384,10 +385,10 @@ exclude = [ [dependency-groups] build = [ - "nanobind>=2.10.2", + "nanobind~=2.10.2", "setuptools-scm>=9.2.2", "scikit-build-core>=0.11.6", - "mqt.core~=3.4.0", + "mqt.core==3.4.0", ] docs = [ "distinctipy>=1.3.4", diff --git a/uv.lock b/uv.lock index 8e6808138..85d79a4a7 100644 --- a/uv.lock +++ b/uv.lock @@ -123,11 +123,11 @@ wheels = [ [[package]] name = "babel" -version = "2.17.0" +version = "2.18.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, ] [[package]] @@ -454,7 +454,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -646,31 +646,31 @@ wheels = [ [[package]] name = "debugpy" -version = "1.8.19" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/73/75/9e12d4d42349b817cd545b89247696c67917aab907012ae5b64bbfea3199/debugpy-1.8.19.tar.gz", hash = "sha256:eea7e5987445ab0b5ed258093722d5ecb8bb72217c5c9b1e21f64efe23ddebdb", size = 1644590, upload-time = "2025-12-15T21:53:28.044Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/98/d57054371887f37d3c959a7a8dc3c76b763acb65f5e78d849d7db7cadc5b/debugpy-1.8.19-cp310-cp310-macosx_15_0_x86_64.whl", hash = "sha256:fce6da15d73be5935b4438435c53adb512326a3e11e4f90793ea87cd9f018254", size = 2098493, upload-time = "2025-12-15T21:53:30.149Z" }, - { url = "https://files.pythonhosted.org/packages/ee/dd/c517b9aa3500157a30e4f4c4f5149f880026bd039d2b940acd2383a85d8e/debugpy-1.8.19-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:e24b1652a1df1ab04d81e7ead446a91c226de704ff5dde6bd0a0dbaab07aa3f2", size = 3087875, upload-time = "2025-12-15T21:53:31.511Z" }, - { url = "https://files.pythonhosted.org/packages/d8/57/3d5a5b0da9b63445253107ead151eff29190c6ad7440c68d1a59d56613aa/debugpy-1.8.19-cp310-cp310-win32.whl", hash = "sha256:327cb28c3ad9e17bc925efc7f7018195fd4787c2fe4b7af1eec11f1d19bdec62", size = 5239378, upload-time = "2025-12-15T21:53:32.979Z" }, - { url = "https://files.pythonhosted.org/packages/a6/36/7f9053c4c549160c87ae7e43800138f2695578c8b65947114c97250983b6/debugpy-1.8.19-cp310-cp310-win_amd64.whl", hash = "sha256:b7dd275cf2c99e53adb9654f5ae015f70415bbe2bacbe24cfee30d54b6aa03c5", size = 5271129, upload-time = "2025-12-15T21:53:35.085Z" }, - { url = "https://files.pythonhosted.org/packages/80/e2/48531a609b5a2aa94c6b6853afdfec8da05630ab9aaa96f1349e772119e9/debugpy-1.8.19-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:c5dcfa21de1f735a4f7ced4556339a109aa0f618d366ede9da0a3600f2516d8b", size = 2207620, upload-time = "2025-12-15T21:53:37.1Z" }, - { url = "https://files.pythonhosted.org/packages/1b/d4/97775c01d56071969f57d93928899e5616a4cfbbf4c8cc75390d3a51c4a4/debugpy-1.8.19-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:806d6800246244004625d5222d7765874ab2d22f3ba5f615416cf1342d61c488", size = 3170796, upload-time = "2025-12-15T21:53:38.513Z" }, - { url = "https://files.pythonhosted.org/packages/8d/7e/8c7681bdb05be9ec972bbb1245eb7c4c7b0679bb6a9e6408d808bc876d3d/debugpy-1.8.19-cp311-cp311-win32.whl", hash = "sha256:783a519e6dfb1f3cd773a9bda592f4887a65040cb0c7bd38dde410f4e53c40d4", size = 5164287, upload-time = "2025-12-15T21:53:40.857Z" }, - { url = "https://files.pythonhosted.org/packages/f2/a8/aaac7ff12ddf5d68a39e13a423a8490426f5f661384f5ad8d9062761bd8e/debugpy-1.8.19-cp311-cp311-win_amd64.whl", hash = "sha256:14035cbdbb1fe4b642babcdcb5935c2da3b1067ac211c5c5a8fdc0bb31adbcaa", size = 5188269, upload-time = "2025-12-15T21:53:42.359Z" }, - { url = "https://files.pythonhosted.org/packages/4a/15/d762e5263d9e25b763b78be72dc084c7a32113a0bac119e2f7acae7700ed/debugpy-1.8.19-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:bccb1540a49cde77edc7ce7d9d075c1dbeb2414751bc0048c7a11e1b597a4c2e", size = 2549995, upload-time = "2025-12-15T21:53:43.773Z" }, - { url = "https://files.pythonhosted.org/packages/a7/88/f7d25c68b18873b7c53d7c156ca7a7ffd8e77073aa0eac170a9b679cf786/debugpy-1.8.19-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:e9c68d9a382ec754dc05ed1d1b4ed5bd824b9f7c1a8cd1083adb84b3c93501de", size = 4309891, upload-time = "2025-12-15T21:53:45.26Z" }, - { url = "https://files.pythonhosted.org/packages/c5/4f/a65e973aba3865794da65f71971dca01ae66666132c7b2647182d5be0c5f/debugpy-1.8.19-cp312-cp312-win32.whl", hash = "sha256:6599cab8a783d1496ae9984c52cb13b7c4a3bd06a8e6c33446832a5d97ce0bee", size = 5286355, upload-time = "2025-12-15T21:53:46.763Z" }, - { url = "https://files.pythonhosted.org/packages/d8/3a/d3d8b48fec96e3d824e404bf428276fb8419dfa766f78f10b08da1cb2986/debugpy-1.8.19-cp312-cp312-win_amd64.whl", hash = "sha256:66e3d2fd8f2035a8f111eb127fa508469dfa40928a89b460b41fd988684dc83d", size = 5328239, upload-time = "2025-12-15T21:53:48.868Z" }, - { url = "https://files.pythonhosted.org/packages/71/3d/388035a31a59c26f1ecc8d86af607d0c42e20ef80074147cd07b180c4349/debugpy-1.8.19-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:91e35db2672a0abaf325f4868fcac9c1674a0d9ad9bb8a8c849c03a5ebba3e6d", size = 2538859, upload-time = "2025-12-15T21:53:50.478Z" }, - { url = "https://files.pythonhosted.org/packages/4a/19/c93a0772d0962294f083dbdb113af1a7427bb632d36e5314297068f55db7/debugpy-1.8.19-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:85016a73ab84dea1c1f1dcd88ec692993bcbe4532d1b49ecb5f3c688ae50c606", size = 4292575, upload-time = "2025-12-15T21:53:51.821Z" }, - { url = "https://files.pythonhosted.org/packages/5c/56/09e48ab796b0a77e3d7dc250f95251832b8bf6838c9632f6100c98bdf426/debugpy-1.8.19-cp313-cp313-win32.whl", hash = "sha256:b605f17e89ba0ecee994391194285fada89cee111cfcd29d6f2ee11cbdc40976", size = 5286209, upload-time = "2025-12-15T21:53:53.602Z" }, - { url = "https://files.pythonhosted.org/packages/fb/4e/931480b9552c7d0feebe40c73725dd7703dcc578ba9efc14fe0e6d31cfd1/debugpy-1.8.19-cp313-cp313-win_amd64.whl", hash = "sha256:c30639998a9f9cd9699b4b621942c0179a6527f083c72351f95c6ab1728d5b73", size = 5328206, upload-time = "2025-12-15T21:53:55.433Z" }, - { url = "https://files.pythonhosted.org/packages/f6/b9/cbec520c3a00508327476c7fce26fbafef98f412707e511eb9d19a2ef467/debugpy-1.8.19-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:1e8c4d1bd230067bf1bbcdbd6032e5a57068638eb28b9153d008ecde288152af", size = 2537372, upload-time = "2025-12-15T21:53:57.318Z" }, - { url = "https://files.pythonhosted.org/packages/88/5e/cf4e4dc712a141e10d58405c58c8268554aec3c35c09cdcda7535ff13f76/debugpy-1.8.19-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:d40c016c1f538dbf1762936e3aeb43a89b965069d9f60f9e39d35d9d25e6b809", size = 4268729, upload-time = "2025-12-15T21:53:58.712Z" }, - { url = "https://files.pythonhosted.org/packages/82/a3/c91a087ab21f1047db328c1d3eb5d1ff0e52de9e74f9f6f6fa14cdd93d58/debugpy-1.8.19-cp314-cp314-win32.whl", hash = "sha256:0601708223fe1cd0e27c6cce67a899d92c7d68e73690211e6788a4b0e1903f5b", size = 5286388, upload-time = "2025-12-15T21:54:00.687Z" }, - { url = "https://files.pythonhosted.org/packages/17/b8/bfdc30b6e94f1eff09f2dc9cc1f9cd1c6cde3d996bcbd36ce2d9a4956e99/debugpy-1.8.19-cp314-cp314-win_amd64.whl", hash = "sha256:8e19a725f5d486f20e53a1dde2ab8bb2c9607c40c00a42ab646def962b41125f", size = 5327741, upload-time = "2025-12-15T21:54:02.148Z" }, - { url = "https://files.pythonhosted.org/packages/25/3e/e27078370414ef35fafad2c06d182110073daaeb5d3bf734b0b1eeefe452/debugpy-1.8.19-py2.py3-none-any.whl", hash = "sha256:360ffd231a780abbc414ba0f005dad409e71c78637efe8f2bd75837132a41d38", size = 5292321, upload-time = "2025-12-15T21:54:16.024Z" }, +version = "1.8.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/be/8bd693a0b9d53d48c8978fa5d889e06f3b5b03e45fd1ea1e78267b4887cb/debugpy-1.8.20-cp310-cp310-macosx_15_0_x86_64.whl", hash = "sha256:157e96ffb7f80b3ad36d808646198c90acb46fdcfd8bb1999838f0b6f2b59c64", size = 2099192, upload-time = "2026-01-29T23:03:29.707Z" }, + { url = "https://files.pythonhosted.org/packages/77/1b/85326d07432086a06361d493d2743edd0c4fc2ef62162be7f8618441ac37/debugpy-1.8.20-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:c1178ae571aff42e61801a38b007af504ec8e05fde1c5c12e5a7efef21009642", size = 3088568, upload-time = "2026-01-29T23:03:31.467Z" }, + { url = "https://files.pythonhosted.org/packages/e8/60/3e08462ee3eccd10998853eb35947c416e446bfe2bc37dbb886b9044586c/debugpy-1.8.20-cp310-cp310-win32.whl", hash = "sha256:c29dd9d656c0fbd77906a6e6a82ae4881514aa3294b94c903ff99303e789b4a2", size = 5284399, upload-time = "2026-01-29T23:03:33.678Z" }, + { url = "https://files.pythonhosted.org/packages/72/43/09d49106e770fe558ced5e80df2e3c2ebee10e576eda155dcc5670473663/debugpy-1.8.20-cp310-cp310-win_amd64.whl", hash = "sha256:3ca85463f63b5dd0aa7aaa933d97cbc47c174896dcae8431695872969f981893", size = 5316388, upload-time = "2026-01-29T23:03:35.095Z" }, + { url = "https://files.pythonhosted.org/packages/51/56/c3baf5cbe4dd77427fd9aef99fcdade259ad128feeb8a786c246adb838e5/debugpy-1.8.20-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b", size = 2208318, upload-time = "2026-01-29T23:03:36.481Z" }, + { url = "https://files.pythonhosted.org/packages/9a/7d/4fa79a57a8e69fe0d9763e98d1110320f9ecd7f1f362572e3aafd7417c9d/debugpy-1.8.20-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344", size = 3171493, upload-time = "2026-01-29T23:03:37.775Z" }, + { url = "https://files.pythonhosted.org/packages/7d/f2/1e8f8affe51e12a26f3a8a8a4277d6e60aa89d0a66512f63b1e799d424a4/debugpy-1.8.20-cp311-cp311-win32.whl", hash = "sha256:773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec", size = 5209240, upload-time = "2026-01-29T23:03:39.109Z" }, + { url = "https://files.pythonhosted.org/packages/d5/92/1cb532e88560cbee973396254b21bece8c5d7c2ece958a67afa08c9f10dc/debugpy-1.8.20-cp311-cp311-win_amd64.whl", hash = "sha256:1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb", size = 5233481, upload-time = "2026-01-29T23:03:40.659Z" }, + { url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d", size = 2550686, upload-time = "2026-01-29T23:03:42.023Z" }, + { url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b", size = 4310588, upload-time = "2026-01-29T23:03:43.314Z" }, + { url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390", size = 5331372, upload-time = "2026-01-29T23:03:45.526Z" }, + { url = "https://files.pythonhosted.org/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl", hash = "sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3", size = 5372835, upload-time = "2026-01-29T23:03:47.245Z" }, + { url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a", size = 2539560, upload-time = "2026-01-29T23:03:48.738Z" }, + { url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf", size = 4293272, upload-time = "2026-01-29T23:03:50.169Z" }, + { url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393", size = 5331208, upload-time = "2026-01-29T23:03:51.547Z" }, + { url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7", size = 5372930, upload-time = "2026-01-29T23:03:53.585Z" }, + { url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173", size = 2538066, upload-time = "2026-01-29T23:03:54.999Z" }, + { url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad", size = 4269425, upload-time = "2026-01-29T23:03:56.518Z" }, + { url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f", size = 5331407, upload-time = "2026-01-29T23:03:58.481Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be", size = 5372521, upload-time = "2026-01-29T23:03:59.864Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" }, ] [[package]] @@ -710,7 +710,7 @@ version = "1.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8c/3c/e0b90a5bc396e2abaf207d9a41ea8aeab1f41760425262474903bade6a7b/distinctipy-1.3.4.tar.gz", hash = "sha256:fed97afff1afb73ecaa87c85461021f0ba89fae63067c0125b9673526510aac4", size = 29711, upload-time = "2024-01-10T21:32:24.032Z" } wheels = [ @@ -893,6 +893,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/65/5b235b40581ad75ab97dcd8b4218022ae8e3ab77c13c919f1a1dfe9171fd/greenlet-3.3.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04bee4775f40ecefcdaa9d115ab44736cd4b9c5fba733575bfe9379419582e13", size = 273723, upload-time = "2026-01-23T15:30:37.521Z" }, { url = "https://files.pythonhosted.org/packages/ce/ad/eb4729b85cba2d29499e0a04ca6fbdd8f540afd7be142fd571eea43d712f/greenlet-3.3.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e1457f4fed12a50e427988a07f0f9df53cf0ee8da23fab16e6732c2ec909d4", size = 574874, upload-time = "2026-01-23T16:00:54.551Z" }, { url = "https://files.pythonhosted.org/packages/87/32/57cad7fe4c8b82fdaa098c89498ef85ad92dfbb09d5eb713adedfc2ae1f5/greenlet-3.3.1-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:070472cd156f0656f86f92e954591644e158fd65aa415ffbe2d44ca77656a8f5", size = 586309, upload-time = "2026-01-23T16:05:25.18Z" }, + { url = "https://files.pythonhosted.org/packages/66/66/f041005cb87055e62b0d68680e88ec1a57f4688523d5e2fb305841bc8307/greenlet-3.3.1-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1108b61b06b5224656121c3c8ee8876161c491cbe74e5c519e0634c837cf93d5", size = 597461, upload-time = "2026-01-23T16:15:51.943Z" }, { url = "https://files.pythonhosted.org/packages/87/eb/8a1ec2da4d55824f160594a75a9d8354a5fe0a300fb1c48e7944265217e1/greenlet-3.3.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a300354f27dd86bae5fbf7002e6dd2b3255cd372e9242c933faf5e859b703fe", size = 586985, upload-time = "2026-01-23T15:32:47.968Z" }, { url = "https://files.pythonhosted.org/packages/15/1c/0621dd4321dd8c351372ee8f9308136acb628600658a49be1b7504208738/greenlet-3.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e84b51cbebf9ae573b5fbd15df88887815e3253fc000a7d0ff95170e8f7e9729", size = 1547271, upload-time = "2026-01-23T16:04:18.977Z" }, { url = "https://files.pythonhosted.org/packages/9d/53/24047f8924c83bea7a59c8678d9571209c6bfe5f4c17c94a78c06024e9f2/greenlet-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0093bd1a06d899892427217f0ff2a3c8f306182b8c754336d32e2d587c131b4", size = 1613427, upload-time = "2026-01-23T15:33:44.428Z" }, @@ -900,6 +901,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/e8/2e1462c8fdbe0f210feb5ac7ad2d9029af8be3bf45bd9fa39765f821642f/greenlet-3.3.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5fd23b9bc6d37b563211c6abbb1b3cab27db385a4449af5c32e932f93017080c", size = 274974, upload-time = "2026-01-23T15:31:02.891Z" }, { url = "https://files.pythonhosted.org/packages/7e/a8/530a401419a6b302af59f67aaf0b9ba1015855ea7e56c036b5928793c5bd/greenlet-3.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f51496a0bfbaa9d74d36a52d2580d1ef5ed4fdfcff0a73730abfbbbe1403dd", size = 577175, upload-time = "2026-01-23T16:00:56.213Z" }, { url = "https://files.pythonhosted.org/packages/8e/89/7e812bb9c05e1aaef9b597ac1d0962b9021d2c6269354966451e885c4e6b/greenlet-3.3.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb0feb07fe6e6a74615ee62a880007d976cf739b6669cce95daa7373d4fc69c5", size = 590401, upload-time = "2026-01-23T16:05:26.365Z" }, + { url = "https://files.pythonhosted.org/packages/70/ae/e2d5f0e59b94a2269b68a629173263fa40b63da32f5c231307c349315871/greenlet-3.3.1-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:67ea3fc73c8cd92f42467a72b75e8f05ed51a0e9b1d15398c913416f2dafd49f", size = 601161, upload-time = "2026-01-23T16:15:53.456Z" }, { url = "https://files.pythonhosted.org/packages/5c/ae/8d472e1f5ac5efe55c563f3eabb38c98a44b832602e12910750a7c025802/greenlet-3.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39eda9ba259cc9801da05351eaa8576e9aa83eb9411e8f0c299e05d712a210f2", size = 590272, upload-time = "2026-01-23T15:32:49.411Z" }, { url = "https://files.pythonhosted.org/packages/a8/51/0fde34bebfcadc833550717eade64e35ec8738e6b097d5d248274a01258b/greenlet-3.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e2e7e882f83149f0a71ac822ebf156d902e7a5d22c9045e3e0d1daf59cee2cc9", size = 1550729, upload-time = "2026-01-23T16:04:20.867Z" }, { url = "https://files.pythonhosted.org/packages/16/c9/2fb47bee83b25b119d5a35d580807bb8b92480a54b68fef009a02945629f/greenlet-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80aa4d79eb5564f2e0a6144fcc744b5a37c56c4a92d60920720e99210d88db0f", size = 1615552, upload-time = "2026-01-23T15:33:45.743Z" }, @@ -908,6 +910,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/c8/9d76a66421d1ae24340dfae7e79c313957f6e3195c144d2c73333b5bfe34/greenlet-3.3.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:7e806ca53acf6d15a888405880766ec84721aa4181261cd11a457dfe9a7a4975", size = 276443, upload-time = "2026-01-23T15:30:10.066Z" }, { url = "https://files.pythonhosted.org/packages/81/99/401ff34bb3c032d1f10477d199724f5e5f6fbfb59816ad1455c79c1eb8e7/greenlet-3.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d842c94b9155f1c9b3058036c24ffb8ff78b428414a19792b2380be9cecf4f36", size = 597359, upload-time = "2026-01-23T16:00:57.394Z" }, { url = "https://files.pythonhosted.org/packages/2b/bc/4dcc0871ed557792d304f50be0f7487a14e017952ec689effe2180a6ff35/greenlet-3.3.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20fedaadd422fa02695f82093f9a98bad3dab5fcda793c658b945fcde2ab27ba", size = 607805, upload-time = "2026-01-23T16:05:28.068Z" }, + { url = "https://files.pythonhosted.org/packages/3b/cd/7a7ca57588dac3389e97f7c9521cb6641fd8b6602faf1eaa4188384757df/greenlet-3.3.1-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c620051669fd04ac6b60ebc70478210119c56e2d5d5df848baec4312e260e4ca", size = 622363, upload-time = "2026-01-23T16:15:54.754Z" }, { url = "https://files.pythonhosted.org/packages/cf/05/821587cf19e2ce1f2b24945d890b164401e5085f9d09cbd969b0c193cd20/greenlet-3.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14194f5f4305800ff329cbf02c5fcc88f01886cadd29941b807668a45f0d2336", size = 609947, upload-time = "2026-01-23T15:32:51.004Z" }, { url = "https://files.pythonhosted.org/packages/a4/52/ee8c46ed9f8babaa93a19e577f26e3d28a519feac6350ed6f25f1afee7e9/greenlet-3.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7b2fe4150a0cf59f847a67db8c155ac36aed89080a6a639e9f16df5d6c6096f1", size = 1567487, upload-time = "2026-01-23T16:04:22.125Z" }, { url = "https://files.pythonhosted.org/packages/8f/7c/456a74f07029597626f3a6db71b273a3632aecb9afafeeca452cfa633197/greenlet-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49f4ad195d45f4a66a0eb9c1ba4832bb380570d361912fa3554746830d332149", size = 1636087, upload-time = "2026-01-23T15:33:47.486Z" }, @@ -916,6 +919,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/ab/d26750f2b7242c2b90ea2ad71de70cfcd73a948a49513188a0fc0d6fc15a/greenlet-3.3.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:7ab327905cabb0622adca5971e488064e35115430cec2c35a50fd36e72a315b3", size = 275205, upload-time = "2026-01-23T15:30:24.556Z" }, { url = "https://files.pythonhosted.org/packages/10/d3/be7d19e8fad7c5a78eeefb2d896a08cd4643e1e90c605c4be3b46264998f/greenlet-3.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65be2f026ca6a176f88fb935ee23c18333ccea97048076aef4db1ef5bc0713ac", size = 599284, upload-time = "2026-01-23T16:00:58.584Z" }, { url = "https://files.pythonhosted.org/packages/ae/21/fe703aaa056fdb0f17e5afd4b5c80195bbdab701208918938bd15b00d39b/greenlet-3.3.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a3ae05b3d225b4155bda56b072ceb09d05e974bc74be6c3fc15463cf69f33fd", size = 610274, upload-time = "2026-01-23T16:05:29.312Z" }, + { url = "https://files.pythonhosted.org/packages/06/00/95df0b6a935103c0452dad2203f5be8377e551b8466a29650c4c5a5af6cc/greenlet-3.3.1-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:12184c61e5d64268a160226fb4818af4df02cfead8379d7f8b99a56c3a54ff3e", size = 624375, upload-time = "2026-01-23T16:15:55.915Z" }, { url = "https://files.pythonhosted.org/packages/cb/86/5c6ab23bb3c28c21ed6bebad006515cfe08b04613eb105ca0041fecca852/greenlet-3.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6423481193bbbe871313de5fd06a082f2649e7ce6e08015d2a76c1e9186ca5b3", size = 612904, upload-time = "2026-01-23T15:32:52.317Z" }, { url = "https://files.pythonhosted.org/packages/c2/f3/7949994264e22639e40718c2daf6f6df5169bf48fb038c008a489ec53a50/greenlet-3.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:33a956fe78bbbda82bfc95e128d61129b32d66bcf0a20a1f0c08aa4839ffa951", size = 1567316, upload-time = "2026-01-23T16:04:23.316Z" }, { url = "https://files.pythonhosted.org/packages/8d/6e/d73c94d13b6465e9f7cd6231c68abde838bb22408596c05d9059830b7872/greenlet-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b065d3284be43728dd280f6f9a13990b56470b81be20375a207cdc814a983f2", size = 1636549, upload-time = "2026-01-23T15:33:48.643Z" }, @@ -924,6 +928,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5", size = 275737, upload-time = "2026-01-23T15:32:16.889Z" }, { url = "https://files.pythonhosted.org/packages/41/2e/a3a417d620363fdbb08a48b1dd582956a46a61bf8fd27ee8164f9dfe87c2/greenlet-3.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b31c05dd84ef6871dd47120386aed35323c944d86c3d91a17c4b8d23df62f15b", size = 646422, upload-time = "2026-01-23T16:01:00.354Z" }, { url = "https://files.pythonhosted.org/packages/b4/09/c6c4a0db47defafd2d6bab8ddfe47ad19963b4e30f5bed84d75328059f8c/greenlet-3.3.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02925a0bfffc41e542c70aa14c7eda3593e4d7e274bfcccca1827e6c0875902e", size = 658219, upload-time = "2026-01-23T16:05:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/e2/89/b95f2ddcc5f3c2bc09c8ee8d77be312df7f9e7175703ab780f2014a0e781/greenlet-3.3.1-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3e0f3878ca3a3ff63ab4ea478585942b53df66ddde327b59ecb191b19dbbd62d", size = 671455, upload-time = "2026-01-23T16:15:57.232Z" }, { url = "https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f", size = 660237, upload-time = "2026-01-23T15:32:53.967Z" }, { url = "https://files.pythonhosted.org/packages/96/61/373c30b7197f9e756e4c81ae90a8d55dc3598c17673f91f4d31c3c689c3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aec9ab04e82918e623415947921dea15851b152b822661cce3f8e4393c3df683", size = 1615261, upload-time = "2026-01-23T16:04:25.066Z" }, { url = "https://files.pythonhosted.org/packages/fd/d3/ca534310343f5945316f9451e953dcd89b36fe7a19de652a1dc5a0eeef3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71c767cf281a80d02b6c1bdc41c9468e1f5a494fb11bc8688c360524e273d7b1", size = 1683719, upload-time = "2026-01-23T15:33:50.61Z" }, @@ -932,6 +937,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/28/24/cbbec49bacdcc9ec652a81d3efef7b59f326697e7edf6ed775a5e08e54c2/greenlet-3.3.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:3e63252943c921b90abb035ebe9de832c436401d9c45f262d80e2d06cc659242", size = 282706, upload-time = "2026-01-23T15:33:05.525Z" }, { url = "https://files.pythonhosted.org/packages/86/2e/4f2b9323c144c4fe8842a4e0d92121465485c3c2c5b9e9b30a52e80f523f/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76e39058e68eb125de10c92524573924e827927df5d3891fbc97bd55764a8774", size = 651209, upload-time = "2026-01-23T16:01:01.517Z" }, { url = "https://files.pythonhosted.org/packages/d9/87/50ca60e515f5bb55a2fbc5f0c9b5b156de7d2fc51a0a69abc9d23914a237/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9f9d5e7a9310b7a2f416dd13d2e3fd8b42d803968ea580b7c0f322ccb389b97", size = 654300, upload-time = "2026-01-23T16:05:32.199Z" }, + { url = "https://files.pythonhosted.org/packages/7c/25/c51a63f3f463171e09cb586eb64db0861eb06667ab01a7968371a24c4f3b/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b9721549a95db96689458a1e0ae32412ca18776ed004463df3a9299c1b257ab", size = 662574, upload-time = "2026-01-23T16:15:58.364Z" }, { url = "https://files.pythonhosted.org/packages/1d/94/74310866dfa2b73dd08659a3d18762f83985ad3281901ba0ee9a815194fb/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92497c78adf3ac703b57f1e3813c2d874f27f71a178f9ea5887855da413cd6d2", size = 653842, upload-time = "2026-01-23T15:32:55.671Z" }, { url = "https://files.pythonhosted.org/packages/97/43/8bf0ffa3d498eeee4c58c212a3905dd6146c01c8dc0b0a046481ca29b18c/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ed6b402bc74d6557a705e197d47f9063733091ed6357b3de33619d8a8d93ac53", size = 1614917, upload-time = "2026-01-23T16:04:26.276Z" }, { url = "https://files.pythonhosted.org/packages/89/90/a3be7a5f378fc6e84abe4dcfb2ba32b07786861172e502388b4c90000d1b/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:59913f1e5ada20fde795ba906916aea25d442abcc0593fba7e26c92b7ad76249", size = 1676092, upload-time = "2026-01-23T15:33:52.176Z" }, @@ -1463,7 +1469,7 @@ dependencies = [ { name = "fonttools" }, { name = "kiwisolver" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "packaging" }, { name = "pillow" }, { name = "pyparsing" }, @@ -1609,7 +1615,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mqt-core" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/37/7a/5e31dce537e8fa84e135a1b06be0284350f940c4b201026486187d936c4a/mqt_qcec-3.4.0.tar.gz", hash = "sha256:c377adfa58ae5b0ad391fe7d6dca9f77f80d030a54059f804f91075f3be89d88", size = 270579, upload-time = "2026-01-13T00:00:19.214Z" } @@ -1726,7 +1732,7 @@ test = [ requires-dist = [ { name = "distinctipy", marker = "extra == 'visualization'", specifier = ">=1.3.4" }, { name = "ipywidgets", marker = "extra == 'visualization'", specifier = ">=8.1.7" }, - { name = "mqt-core", specifier = "~=3.4.0" }, + { name = "mqt-core", specifier = "==3.4.0" }, { name = "networkx", marker = "extra == 'visualization'", specifier = ">=3.2.1" }, { name = "plotly", marker = "extra == 'visualization'", specifier = ">=6.0.1" }, { name = "qiskit", extras = ["qasm3-import"], specifier = ">=1.0.0" }, @@ -1738,17 +1744,17 @@ provides-extras = ["visualization"] [package.metadata.requires-dev] build = [ - { name = "mqt-core", specifier = "~=3.4.0" }, - { name = "nanobind", specifier = ">=2.10.2" }, + { name = "mqt-core", specifier = "==3.4.0" }, + { name = "nanobind", specifier = "~=2.10.2" }, { name = "scikit-build-core", specifier = ">=0.11.6" }, { name = "setuptools-scm", specifier = ">=9.2.2" }, ] dev = [ { name = "distinctipy", specifier = ">=1.3.4" }, { name = "ipywidgets", specifier = ">=8.1.7" }, - { name = "mqt-core", specifier = "~=3.4.0" }, + { name = "mqt-core", specifier = "==3.4.0" }, { name = "mqt-qcec", specifier = ">=3.4.0" }, - { name = "nanobind", specifier = ">=2.10.2" }, + { name = "nanobind", specifier = "~=2.10.2" }, { name = "networkx", specifier = ">=3.2.1" }, { name = "nox", specifier = ">=2025.11.12" }, { name = "plotly", specifier = ">=6.0.1" }, @@ -2048,7 +2054,7 @@ wheels = [ [[package]] name = "numpy" -version = "2.4.1" +version = "2.4.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -2064,79 +2070,79 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform == 'emscripten'", "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] -sdist = { url = "https://files.pythonhosted.org/packages/24/62/ae72ff66c0f1fd959925b4c11f8c2dea61f47f6acaea75a08512cdfe3fed/numpy-2.4.1.tar.gz", hash = "sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690", size = 20721320, upload-time = "2026-01-10T06:44:59.619Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/34/2b1bc18424f3ad9af577f6ce23600319968a70575bd7db31ce66731bbef9/numpy-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0cce2a669e3c8ba02ee563c7835f92c153cf02edff1ae05e1823f1dde21b16a5", size = 16944563, upload-time = "2026-01-10T06:42:14.615Z" }, - { url = "https://files.pythonhosted.org/packages/2c/57/26e5f97d075aef3794045a6ca9eada6a4ed70eb9a40e7a4a93f9ac80d704/numpy-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:899d2c18024984814ac7e83f8f49d8e8180e2fbe1b2e252f2e7f1d06bea92425", size = 12645658, upload-time = "2026-01-10T06:42:17.298Z" }, - { url = "https://files.pythonhosted.org/packages/8e/ba/80fc0b1e3cb2fd5c6143f00f42eb67762aa043eaa05ca924ecc3222a7849/numpy-2.4.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:09aa8a87e45b55a1c2c205d42e2808849ece5c484b2aab11fecabec3841cafba", size = 5474132, upload-time = "2026-01-10T06:42:19.637Z" }, - { url = "https://files.pythonhosted.org/packages/40/ae/0a5b9a397f0e865ec171187c78d9b57e5588afc439a04ba9cab1ebb2c945/numpy-2.4.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:edee228f76ee2dab4579fad6f51f6a305de09d444280109e0f75df247ff21501", size = 6804159, upload-time = "2026-01-10T06:42:21.44Z" }, - { url = "https://files.pythonhosted.org/packages/86/9c/841c15e691c7085caa6fd162f063eff494099c8327aeccd509d1ab1e36ab/numpy-2.4.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a92f227dbcdc9e4c3e193add1a189a9909947d4f8504c576f4a732fd0b54240a", size = 14708058, upload-time = "2026-01-10T06:42:23.546Z" }, - { url = "https://files.pythonhosted.org/packages/5d/9d/7862db06743f489e6a502a3b93136d73aea27d97b2cf91504f70a27501d6/numpy-2.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:538bf4ec353709c765ff75ae616c34d3c3dca1a68312727e8f2676ea644f8509", size = 16651501, upload-time = "2026-01-10T06:42:25.909Z" }, - { url = "https://files.pythonhosted.org/packages/a6/9c/6fc34ebcbd4015c6e5f0c0ce38264010ce8a546cb6beacb457b84a75dfc8/numpy-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ac08c63cb7779b85e9d5318e6c3518b424bc1f364ac4cb2c6136f12e5ff2dccc", size = 16492627, upload-time = "2026-01-10T06:42:28.938Z" }, - { url = "https://files.pythonhosted.org/packages/aa/63/2494a8597502dacda439f61b3c0db4da59928150e62be0e99395c3ad23c5/numpy-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f9c360ecef085e5841c539a9a12b883dff005fbd7ce46722f5e9cef52634d82", size = 18585052, upload-time = "2026-01-10T06:42:31.312Z" }, - { url = "https://files.pythonhosted.org/packages/6a/93/098e1162ae7522fc9b618d6272b77404c4656c72432ecee3abc029aa3de0/numpy-2.4.1-cp311-cp311-win32.whl", hash = "sha256:0f118ce6b972080ba0758c6087c3617b5ba243d806268623dc34216d69099ba0", size = 6236575, upload-time = "2026-01-10T06:42:33.872Z" }, - { url = "https://files.pythonhosted.org/packages/8c/de/f5e79650d23d9e12f38a7bc6b03ea0835b9575494f8ec94c11c6e773b1b1/numpy-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:18e14c4d09d55eef39a6ab5b08406e84bc6869c1e34eef45564804f90b7e0574", size = 12604479, upload-time = "2026-01-10T06:42:35.778Z" }, - { url = "https://files.pythonhosted.org/packages/dd/65/e1097a7047cff12ce3369bd003811516b20ba1078dbdec135e1cd7c16c56/numpy-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:6461de5113088b399d655d45c3897fa188766415d0f568f175ab071c8873bd73", size = 10578325, upload-time = "2026-01-10T06:42:38.518Z" }, - { url = "https://files.pythonhosted.org/packages/78/7f/ec53e32bf10c813604edf07a3682616bd931d026fcde7b6d13195dfb684a/numpy-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2", size = 16656888, upload-time = "2026-01-10T06:42:40.913Z" }, - { url = "https://files.pythonhosted.org/packages/b8/e0/1f9585d7dae8f14864e948fd7fa86c6cb72dee2676ca2748e63b1c5acfe0/numpy-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8", size = 12373956, upload-time = "2026-01-10T06:42:43.091Z" }, - { url = "https://files.pythonhosted.org/packages/8e/43/9762e88909ff2326f5e7536fa8cb3c49fb03a7d92705f23e6e7f553d9cb3/numpy-2.4.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a", size = 5202567, upload-time = "2026-01-10T06:42:45.107Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ee/34b7930eb61e79feb4478800a4b95b46566969d837546aa7c034c742ef98/numpy-2.4.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0", size = 6549459, upload-time = "2026-01-10T06:42:48.152Z" }, - { url = "https://files.pythonhosted.org/packages/79/e3/5f115fae982565771be994867c89bcd8d7208dbfe9469185497d70de5ddf/numpy-2.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c", size = 14404859, upload-time = "2026-01-10T06:42:49.947Z" }, - { url = "https://files.pythonhosted.org/packages/d9/7d/9c8a781c88933725445a859cac5d01b5871588a15969ee6aeb618ba99eee/numpy-2.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02", size = 16371419, upload-time = "2026-01-10T06:42:52.409Z" }, - { url = "https://files.pythonhosted.org/packages/a6/d2/8aa084818554543f17cf4162c42f162acbd3bb42688aefdba6628a859f77/numpy-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162", size = 16182131, upload-time = "2026-01-10T06:42:54.694Z" }, - { url = "https://files.pythonhosted.org/packages/60/db/0425216684297c58a8df35f3284ef56ec4a043e6d283f8a59c53562caf1b/numpy-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9", size = 18295342, upload-time = "2026-01-10T06:42:56.991Z" }, - { url = "https://files.pythonhosted.org/packages/31/4c/14cb9d86240bd8c386c881bafbe43f001284b7cce3bc01623ac9475da163/numpy-2.4.1-cp312-cp312-win32.whl", hash = "sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f", size = 5959015, upload-time = "2026-01-10T06:42:59.631Z" }, - { url = "https://files.pythonhosted.org/packages/51/cf/52a703dbeb0c65807540d29699fef5fda073434ff61846a564d5c296420f/numpy-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87", size = 12310730, upload-time = "2026-01-10T06:43:01.627Z" }, - { url = "https://files.pythonhosted.org/packages/69/80/a828b2d0ade5e74a9fe0f4e0a17c30fdc26232ad2bc8c9f8b3197cf7cf18/numpy-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8", size = 10312166, upload-time = "2026-01-10T06:43:03.673Z" }, - { url = "https://files.pythonhosted.org/packages/04/68/732d4b7811c00775f3bd522a21e8dd5a23f77eb11acdeb663e4a4ebf0ef4/numpy-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b", size = 16652495, upload-time = "2026-01-10T06:43:06.283Z" }, - { url = "https://files.pythonhosted.org/packages/20/ca/857722353421a27f1465652b2c66813eeeccea9d76d5f7b74b99f298e60e/numpy-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f", size = 12368657, upload-time = "2026-01-10T06:43:09.094Z" }, - { url = "https://files.pythonhosted.org/packages/81/0d/2377c917513449cc6240031a79d30eb9a163d32a91e79e0da47c43f2c0c8/numpy-2.4.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9", size = 5197256, upload-time = "2026-01-10T06:43:13.634Z" }, - { url = "https://files.pythonhosted.org/packages/17/39/569452228de3f5de9064ac75137082c6214be1f5c532016549a7923ab4b5/numpy-2.4.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e", size = 6545212, upload-time = "2026-01-10T06:43:15.661Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a4/77333f4d1e4dac4395385482557aeecf4826e6ff517e32ca48e1dafbe42a/numpy-2.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5", size = 14402871, upload-time = "2026-01-10T06:43:17.324Z" }, - { url = "https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8", size = 16359305, upload-time = "2026-01-10T06:43:19.376Z" }, - { url = "https://files.pythonhosted.org/packages/32/91/789132c6666288eaa20ae8066bb99eba1939362e8f1a534949a215246e97/numpy-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c", size = 16181909, upload-time = "2026-01-10T06:43:21.808Z" }, - { url = "https://files.pythonhosted.org/packages/cf/b8/090b8bd27b82a844bb22ff8fdf7935cb1980b48d6e439ae116f53cdc2143/numpy-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2", size = 18284380, upload-time = "2026-01-10T06:43:23.957Z" }, - { url = "https://files.pythonhosted.org/packages/67/78/722b62bd31842ff029412271556a1a27a98f45359dea78b1548a3a9996aa/numpy-2.4.1-cp313-cp313-win32.whl", hash = "sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d", size = 5957089, upload-time = "2026-01-10T06:43:27.535Z" }, - { url = "https://files.pythonhosted.org/packages/da/a6/cf32198b0b6e18d4fbfa9a21a992a7fca535b9bb2b0cdd217d4a3445b5ca/numpy-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb", size = 12307230, upload-time = "2026-01-10T06:43:29.298Z" }, - { url = "https://files.pythonhosted.org/packages/44/6c/534d692bfb7d0afe30611320c5fb713659dcb5104d7cc182aff2aea092f5/numpy-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5", size = 10313125, upload-time = "2026-01-10T06:43:31.782Z" }, - { url = "https://files.pythonhosted.org/packages/da/a1/354583ac5c4caa566de6ddfbc42744409b515039e085fab6e0ff942e0df5/numpy-2.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7", size = 12496156, upload-time = "2026-01-10T06:43:34.237Z" }, - { url = "https://files.pythonhosted.org/packages/51/b0/42807c6e8cce58c00127b1dc24d365305189991f2a7917aa694a109c8d7d/numpy-2.4.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d", size = 5324663, upload-time = "2026-01-10T06:43:36.211Z" }, - { url = "https://files.pythonhosted.org/packages/fe/55/7a621694010d92375ed82f312b2f28017694ed784775269115323e37f5e2/numpy-2.4.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15", size = 6645224, upload-time = "2026-01-10T06:43:37.884Z" }, - { url = "https://files.pythonhosted.org/packages/50/96/9fa8635ed9d7c847d87e30c834f7109fac5e88549d79ef3324ab5c20919f/numpy-2.4.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9", size = 14462352, upload-time = "2026-01-10T06:43:39.479Z" }, - { url = "https://files.pythonhosted.org/packages/03/d1/8cf62d8bb2062da4fb82dd5d49e47c923f9c0738032f054e0a75342faba7/numpy-2.4.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2", size = 16407279, upload-time = "2026-01-10T06:43:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/86/1c/95c86e17c6b0b31ce6ef219da00f71113b220bcb14938c8d9a05cee0ff53/numpy-2.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505", size = 16248316, upload-time = "2026-01-10T06:43:44.121Z" }, - { url = "https://files.pythonhosted.org/packages/30/b4/e7f5ff8697274c9d0fa82398b6a372a27e5cef069b37df6355ccb1f1db1a/numpy-2.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2", size = 18329884, upload-time = "2026-01-10T06:43:46.613Z" }, - { url = "https://files.pythonhosted.org/packages/37/a4/b073f3e9d77f9aec8debe8ca7f9f6a09e888ad1ba7488f0c3b36a94c03ac/numpy-2.4.1-cp313-cp313t-win32.whl", hash = "sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4", size = 6081138, upload-time = "2026-01-10T06:43:48.854Z" }, - { url = "https://files.pythonhosted.org/packages/16/16/af42337b53844e67752a092481ab869c0523bc95c4e5c98e4dac4e9581ac/numpy-2.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510", size = 12447478, upload-time = "2026-01-10T06:43:50.476Z" }, - { url = "https://files.pythonhosted.org/packages/6c/f8/fa85b2eac68ec631d0b631abc448552cb17d39afd17ec53dcbcc3537681a/numpy-2.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261", size = 10382981, upload-time = "2026-01-10T06:43:52.575Z" }, - { url = "https://files.pythonhosted.org/packages/1b/a7/ef08d25698e0e4b4efbad8d55251d20fe2a15f6d9aa7c9b30cd03c165e6f/numpy-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc", size = 16652046, upload-time = "2026-01-10T06:43:54.797Z" }, - { url = "https://files.pythonhosted.org/packages/8f/39/e378b3e3ca13477e5ac70293ec027c438d1927f18637e396fe90b1addd72/numpy-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3", size = 12378858, upload-time = "2026-01-10T06:43:57.099Z" }, - { url = "https://files.pythonhosted.org/packages/c3/74/7ec6154f0006910ed1fdbb7591cf4432307033102b8a22041599935f8969/numpy-2.4.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220", size = 5207417, upload-time = "2026-01-10T06:43:59.037Z" }, - { url = "https://files.pythonhosted.org/packages/f7/b7/053ac11820d84e42f8feea5cb81cc4fcd1091499b45b1ed8c7415b1bf831/numpy-2.4.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee", size = 6542643, upload-time = "2026-01-10T06:44:01.852Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c4/2e7908915c0e32ca636b92e4e4a3bdec4cb1e7eb0f8aedf1ed3c68a0d8cd/numpy-2.4.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556", size = 14418963, upload-time = "2026-01-10T06:44:04.047Z" }, - { url = "https://files.pythonhosted.org/packages/eb/c0/3ed5083d94e7ffd7c404e54619c088e11f2e1939a9544f5397f4adb1b8ba/numpy-2.4.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844", size = 16363811, upload-time = "2026-01-10T06:44:06.207Z" }, - { url = "https://files.pythonhosted.org/packages/0e/68/42b66f1852bf525050a67315a4fb94586ab7e9eaa541b1bef530fab0c5dd/numpy-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3", size = 16197643, upload-time = "2026-01-10T06:44:08.33Z" }, - { url = "https://files.pythonhosted.org/packages/d2/40/e8714fc933d85f82c6bfc7b998a0649ad9769a32f3494ba86598aaf18a48/numpy-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205", size = 18289601, upload-time = "2026-01-10T06:44:10.841Z" }, - { url = "https://files.pythonhosted.org/packages/80/9a/0d44b468cad50315127e884802351723daca7cf1c98d102929468c81d439/numpy-2.4.1-cp314-cp314-win32.whl", hash = "sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745", size = 6005722, upload-time = "2026-01-10T06:44:13.332Z" }, - { url = "https://files.pythonhosted.org/packages/7e/bb/c6513edcce5a831810e2dddc0d3452ce84d208af92405a0c2e58fd8e7881/numpy-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d", size = 12438590, upload-time = "2026-01-10T06:44:15.006Z" }, - { url = "https://files.pythonhosted.org/packages/e9/da/a598d5cb260780cf4d255102deba35c1d072dc028c4547832f45dd3323a8/numpy-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df", size = 10596180, upload-time = "2026-01-10T06:44:17.386Z" }, - { url = "https://files.pythonhosted.org/packages/de/bc/ea3f2c96fcb382311827231f911723aeff596364eb6e1b6d1d91128aa29b/numpy-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f", size = 12498774, upload-time = "2026-01-10T06:44:19.467Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ab/ef9d939fe4a812648c7a712610b2ca6140b0853c5efea361301006c02ae5/numpy-2.4.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0", size = 5327274, upload-time = "2026-01-10T06:44:23.189Z" }, - { url = "https://files.pythonhosted.org/packages/bd/31/d381368e2a95c3b08b8cf7faac6004849e960f4a042d920337f71cef0cae/numpy-2.4.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c", size = 6648306, upload-time = "2026-01-10T06:44:25.012Z" }, - { url = "https://files.pythonhosted.org/packages/c8/e5/0989b44ade47430be6323d05c23207636d67d7362a1796ccbccac6773dd2/numpy-2.4.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93", size = 14464653, upload-time = "2026-01-10T06:44:26.706Z" }, - { url = "https://files.pythonhosted.org/packages/10/a7/cfbe475c35371cae1358e61f20c5f075badc18c4797ab4354140e1d283cf/numpy-2.4.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42", size = 16405144, upload-time = "2026-01-10T06:44:29.378Z" }, - { url = "https://files.pythonhosted.org/packages/f8/a3/0c63fe66b534888fa5177cc7cef061541064dbe2b4b60dcc60ffaf0d2157/numpy-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01", size = 16247425, upload-time = "2026-01-10T06:44:31.721Z" }, - { url = "https://files.pythonhosted.org/packages/6b/2b/55d980cfa2c93bd40ff4c290bf824d792bd41d2fe3487b07707559071760/numpy-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b", size = 18330053, upload-time = "2026-01-10T06:44:34.617Z" }, - { url = "https://files.pythonhosted.org/packages/23/12/8b5fc6b9c487a09a7957188e0943c9ff08432c65e34567cabc1623b03a51/numpy-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a", size = 6152482, upload-time = "2026-01-10T06:44:36.798Z" }, - { url = "https://files.pythonhosted.org/packages/00/a5/9f8ca5856b8940492fc24fbe13c1bc34d65ddf4079097cf9e53164d094e1/numpy-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2", size = 12627117, upload-time = "2026-01-10T06:44:38.828Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0d/eca3d962f9eef265f01a8e0d20085c6dd1f443cbffc11b6dede81fd82356/numpy-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295", size = 10667121, upload-time = "2026-01-10T06:44:41.644Z" }, - { url = "https://files.pythonhosted.org/packages/1e/48/d86f97919e79314a1cdee4c832178763e6e98e623e123d0bada19e92c15a/numpy-2.4.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8ad35f20be147a204e28b6a0575fbf3540c5e5f802634d4258d55b1ff5facce1", size = 16822202, upload-time = "2026-01-10T06:44:43.738Z" }, - { url = "https://files.pythonhosted.org/packages/51/e9/1e62a7f77e0f37dcfb0ad6a9744e65df00242b6ea37dfafb55debcbf5b55/numpy-2.4.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8097529164c0f3e32bb89412a0905d9100bf434d9692d9fc275e18dcf53c9344", size = 12569985, upload-time = "2026-01-10T06:44:45.945Z" }, - { url = "https://files.pythonhosted.org/packages/c7/7e/914d54f0c801342306fdcdce3e994a56476f1b818c46c47fc21ae968088c/numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ea66d2b41ca4a1630aae5507ee0a71647d3124d1741980138aa8f28f44dac36e", size = 5398484, upload-time = "2026-01-10T06:44:48.012Z" }, - { url = "https://files.pythonhosted.org/packages/1c/d8/9570b68584e293a33474e7b5a77ca404f1dcc655e40050a600dee81d27fb/numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d3f8f0df9f4b8be57b3bf74a1d087fec68f927a2fab68231fdb442bf2c12e426", size = 6713216, upload-time = "2026-01-10T06:44:49.725Z" }, - { url = "https://files.pythonhosted.org/packages/33/9b/9dd6e2db8d49eb24f86acaaa5258e5f4c8ed38209a4ee9de2d1a0ca25045/numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2023ef86243690c2791fd6353e5b4848eedaa88ca8a2d129f462049f6d484696", size = 14538937, upload-time = "2026-01-10T06:44:51.498Z" }, - { url = "https://files.pythonhosted.org/packages/53/87/d5bd995b0f798a37105b876350d346eea5838bd8f77ea3d7a48392f3812b/numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8361ea4220d763e54cff2fbe7d8c93526b744f7cd9ddab47afeff7e14e8503be", size = 16479830, upload-time = "2026-01-10T06:44:53.931Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c7/b801bf98514b6ae6475e941ac05c58e6411dd863ea92916bfd6d510b08c1/numpy-2.4.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:4f1b68ff47680c2925f8063402a693ede215f0257f02596b1318ecdfb1d79e33", size = 12492579, upload-time = "2026-01-10T06:44:57.094Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825", size = 16955478, upload-time = "2026-01-31T23:10:25.623Z" }, + { url = "https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1", size = 14965467, upload-time = "2026-01-31T23:10:28.186Z" }, + { url = "https://files.pythonhosted.org/packages/49/48/fb1ce8136c19452ed15f033f8aee91d5defe515094e330ce368a0647846f/numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7", size = 5475172, upload-time = "2026-01-31T23:10:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/40/a9/3feb49f17bbd1300dd2570432961f5c8a4ffeff1db6f02c7273bd020a4c9/numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73", size = 6805145, upload-time = "2026-01-31T23:10:32.352Z" }, + { url = "https://files.pythonhosted.org/packages/3f/39/fdf35cbd6d6e2fcad42fcf85ac04a85a0d0fbfbf34b30721c98d602fd70a/numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1", size = 15966084, upload-time = "2026-01-31T23:10:34.502Z" }, + { url = "https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32", size = 16899477, upload-time = "2026-01-31T23:10:37.075Z" }, + { url = "https://files.pythonhosted.org/packages/09/a1/2a424e162b1a14a5bd860a464ab4e07513916a64ab1683fae262f735ccd2/numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390", size = 17323429, upload-time = "2026-01-31T23:10:39.704Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a2/73014149ff250628df72c58204822ac01d768697913881aacf839ff78680/numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413", size = 18635109, upload-time = "2026-01-31T23:10:41.924Z" }, + { url = "https://files.pythonhosted.org/packages/6c/0c/73e8be2f1accd56df74abc1c5e18527822067dced5ec0861b5bb882c2ce0/numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda", size = 6237915, upload-time = "2026-01-31T23:10:45.26Z" }, + { url = "https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695", size = 12607972, upload-time = "2026-01-31T23:10:47.021Z" }, + { url = "https://files.pythonhosted.org/packages/29/a5/c43029af9b8014d6ea157f192652c50042e8911f4300f8f6ed3336bf437f/numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3", size = 10485763, upload-time = "2026-01-31T23:10:50.087Z" }, + { url = "https://files.pythonhosted.org/packages/51/6e/6f394c9c77668153e14d4da83bcc247beb5952f6ead7699a1a2992613bea/numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a", size = 16667963, upload-time = "2026-01-31T23:10:52.147Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f8/55483431f2b2fd015ae6ed4fe62288823ce908437ed49db5a03d15151678/numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1", size = 14693571, upload-time = "2026-01-31T23:10:54.789Z" }, + { url = "https://files.pythonhosted.org/packages/2f/20/18026832b1845cdc82248208dd929ca14c9d8f2bac391f67440707fff27c/numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e", size = 5203469, upload-time = "2026-01-31T23:10:57.343Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/2eb97c8a77daaba34eaa3fa7241a14ac5f51c46a6bd5911361b644c4a1e2/numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27", size = 6550820, upload-time = "2026-01-31T23:10:59.429Z" }, + { url = "https://files.pythonhosted.org/packages/b1/91/b97fdfd12dc75b02c44e26c6638241cc004d4079a0321a69c62f51470c4c/numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548", size = 15663067, upload-time = "2026-01-31T23:11:01.291Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c6/a18e59f3f0b8071cc85cbc8d80cd02d68aa9710170b2553a117203d46936/numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f", size = 16619782, upload-time = "2026-01-31T23:11:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b7/83/9751502164601a79e18847309f5ceec0b1446d7b6aa12305759b72cf98b2/numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460", size = 17013128, upload-time = "2026-01-31T23:11:05.913Z" }, + { url = "https://files.pythonhosted.org/packages/61/c4/c4066322256ec740acc1c8923a10047818691d2f8aec254798f3dd90f5f2/numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba", size = 18345324, upload-time = "2026-01-31T23:11:08.248Z" }, + { url = "https://files.pythonhosted.org/packages/ab/af/6157aa6da728fa4525a755bfad486ae7e3f76d4c1864138003eb84328497/numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f", size = 5960282, upload-time = "2026-01-31T23:11:10.497Z" }, + { url = "https://files.pythonhosted.org/packages/92/0f/7ceaaeaacb40567071e94dbf2c9480c0ae453d5bb4f52bea3892c39dc83c/numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85", size = 12314210, upload-time = "2026-01-31T23:11:12.176Z" }, + { url = "https://files.pythonhosted.org/packages/2f/a3/56c5c604fae6dd40fa2ed3040d005fca97e91bd320d232ac9931d77ba13c/numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa", size = 10220171, upload-time = "2026-01-31T23:11:14.684Z" }, + { url = "https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c", size = 16663696, upload-time = "2026-01-31T23:11:17.516Z" }, + { url = "https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979", size = 14688322, upload-time = "2026-01-31T23:11:19.883Z" }, + { url = "https://files.pythonhosted.org/packages/da/b4/f805ab79293c728b9a99438775ce51885fd4f31b76178767cfc718701a39/numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98", size = 5198157, upload-time = "2026-01-31T23:11:22.375Z" }, + { url = "https://files.pythonhosted.org/packages/74/09/826e4289844eccdcd64aac27d13b0fd3f32039915dd5b9ba01baae1f436c/numpy-2.4.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:aea4f66ff44dfddf8c2cffd66ba6538c5ec67d389285292fe428cb2c738c8aef", size = 6546330, upload-time = "2026-01-31T23:11:23.958Z" }, + { url = "https://files.pythonhosted.org/packages/19/fb/cbfdbfa3057a10aea5422c558ac57538e6acc87ec1669e666d32ac198da7/numpy-2.4.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3cd545784805de05aafe1dde61752ea49a359ccba9760c1e5d1c88a93bbf2b7", size = 15660968, upload-time = "2026-01-31T23:11:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499", size = 16607311, upload-time = "2026-01-31T23:11:28.117Z" }, + { url = "https://files.pythonhosted.org/packages/14/d9/4b5adfc39a43fa6bf918c6d544bc60c05236cc2f6339847fc5b35e6cb5b0/numpy-2.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f74f0f7779cc7ae07d1810aab8ac6b1464c3eafb9e283a40da7309d5e6e48fbb", size = 17012850, upload-time = "2026-01-31T23:11:30.888Z" }, + { url = "https://files.pythonhosted.org/packages/b7/20/adb6e6adde6d0130046e6fdfb7675cc62bc2f6b7b02239a09eb58435753d/numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7", size = 18334210, upload-time = "2026-01-31T23:11:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/78/0e/0a73b3dff26803a8c02baa76398015ea2a5434d9b8265a7898a6028c1591/numpy-2.4.2-cp313-cp313-win32.whl", hash = "sha256:8e9afaeb0beff068b4d9cd20d322ba0ee1cecfb0b08db145e4ab4dd44a6b5110", size = 5958199, upload-time = "2026-01-31T23:11:35.385Z" }, + { url = "https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622", size = 12310848, upload-time = "2026-01-31T23:11:38.001Z" }, + { url = "https://files.pythonhosted.org/packages/6e/8d/6da186483e308da5da1cc6918ce913dcfe14ffde98e710bfeff2a6158d4e/numpy-2.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:0fece1d1f0a89c16b03442eae5c56dc0be0c7883b5d388e0c03f53019a4bfd71", size = 10221082, upload-time = "2026-01-31T23:11:40.392Z" }, + { url = "https://files.pythonhosted.org/packages/25/a1/9510aa43555b44781968935c7548a8926274f815de42ad3997e9e83680dd/numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262", size = 14815866, upload-time = "2026-01-31T23:11:42.495Z" }, + { url = "https://files.pythonhosted.org/packages/36/30/6bbb5e76631a5ae46e7923dd16ca9d3f1c93cfa8d4ed79a129814a9d8db3/numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913", size = 5325631, upload-time = "2026-01-31T23:11:44.7Z" }, + { url = "https://files.pythonhosted.org/packages/46/00/3a490938800c1923b567b3a15cd17896e68052e2145d8662aaf3e1ffc58f/numpy-2.4.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:b21041e8cb6a1eb5312dd1d2f80a94d91efffb7a06b70597d44f1bd2dfc315ab", size = 6646254, upload-time = "2026-01-31T23:11:46.341Z" }, + { url = "https://files.pythonhosted.org/packages/d3/e9/fac0890149898a9b609caa5af7455a948b544746e4b8fe7c212c8edd71f8/numpy-2.4.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82", size = 15720138, upload-time = "2026-01-31T23:11:48.082Z" }, + { url = "https://files.pythonhosted.org/packages/ea/5c/08887c54e68e1e28df53709f1893ce92932cc6f01f7c3d4dc952f61ffd4e/numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f", size = 16655398, upload-time = "2026-01-31T23:11:50.293Z" }, + { url = "https://files.pythonhosted.org/packages/4d/89/253db0fa0e66e9129c745e4ef25631dc37d5f1314dad2b53e907b8538e6d/numpy-2.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66cb9422236317f9d44b67b4d18f44efe6e9c7f8794ac0462978513359461554", size = 17079064, upload-time = "2026-01-31T23:11:52.927Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d5/cbade46ce97c59c6c3da525e8d95b7abe8a42974a1dc5c1d489c10433e88/numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257", size = 18379680, upload-time = "2026-01-31T23:11:55.22Z" }, + { url = "https://files.pythonhosted.org/packages/40/62/48f99ae172a4b63d981babe683685030e8a3df4f246c893ea5c6ef99f018/numpy-2.4.2-cp313-cp313t-win32.whl", hash = "sha256:52b913ec40ff7ae845687b0b34d8d93b60cb66dcee06996dd5c99f2fc9328657", size = 6082433, upload-time = "2026-01-31T23:11:58.096Z" }, + { url = "https://files.pythonhosted.org/packages/07/38/e054a61cfe48ad9f1ed0d188e78b7e26859d0b60ef21cd9de4897cdb5326/numpy-2.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5eea80d908b2c1f91486eb95b3fb6fab187e569ec9752ab7d9333d2e66bf2d6b", size = 12451181, upload-time = "2026-01-31T23:11:59.782Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a4/a05c3a6418575e185dd84d0b9680b6bb2e2dc3e4202f036b7b4e22d6e9dc/numpy-2.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fd49860271d52127d61197bb50b64f58454e9f578cb4b2c001a6de8b1f50b0b1", size = 10290756, upload-time = "2026-01-31T23:12:02.438Z" }, + { url = "https://files.pythonhosted.org/packages/18/88/b7df6050bf18fdcfb7046286c6535cabbdd2064a3440fca3f069d319c16e/numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b", size = 16663092, upload-time = "2026-01-31T23:12:04.521Z" }, + { url = "https://files.pythonhosted.org/packages/25/7a/1fee4329abc705a469a4afe6e69b1ef7e915117747886327104a8493a955/numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000", size = 14698770, upload-time = "2026-01-31T23:12:06.96Z" }, + { url = "https://files.pythonhosted.org/packages/fb/0b/f9e49ba6c923678ad5bc38181c08ac5e53b7a5754dbca8e581aa1a56b1ff/numpy-2.4.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:7cdde6de52fb6664b00b056341265441192d1291c130e99183ec0d4b110ff8b1", size = 5208562, upload-time = "2026-01-31T23:12:09.632Z" }, + { url = "https://files.pythonhosted.org/packages/7d/12/d7de8f6f53f9bb76997e5e4c069eda2051e3fe134e9181671c4391677bb2/numpy-2.4.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:cda077c2e5b780200b6b3e09d0b42205a3d1c68f30c6dceb90401c13bff8fe74", size = 6543710, upload-time = "2026-01-31T23:12:11.969Z" }, + { url = "https://files.pythonhosted.org/packages/09/63/c66418c2e0268a31a4cf8a8b512685748200f8e8e8ec6c507ce14e773529/numpy-2.4.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30291931c915b2ab5717c2974bb95ee891a1cf22ebc16a8006bd59cd210d40a", size = 15677205, upload-time = "2026-01-31T23:12:14.33Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6c/7f237821c9642fb2a04d2f1e88b4295677144ca93285fd76eff3bcba858d/numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325", size = 16611738, upload-time = "2026-01-31T23:12:16.525Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/39c4cdda9f019b609b5c473899d87abff092fc908cfe4d1ecb2fcff453b0/numpy-2.4.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b2f0073ed0868db1dcd86e052d37279eef185b9c8db5bf61f30f46adac63c909", size = 17028888, upload-time = "2026-01-31T23:12:19.306Z" }, + { url = "https://files.pythonhosted.org/packages/da/b3/e84bb64bdfea967cc10950d71090ec2d84b49bc691df0025dddb7c26e8e3/numpy-2.4.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f54844851cdb630ceb623dcec4db3240d1ac13d4990532446761baede94996a", size = 18339556, upload-time = "2026-01-31T23:12:21.816Z" }, + { url = "https://files.pythonhosted.org/packages/88/f5/954a291bc1192a27081706862ac62bb5920fbecfbaa302f64682aa90beed/numpy-2.4.2-cp314-cp314-win32.whl", hash = "sha256:12e26134a0331d8dbd9351620f037ec470b7c75929cb8a1537f6bfe411152a1a", size = 6006899, upload-time = "2026-01-31T23:12:24.14Z" }, + { url = "https://files.pythonhosted.org/packages/05/cb/eff72a91b2efdd1bc98b3b8759f6a1654aa87612fc86e3d87d6fe4f948c4/numpy-2.4.2-cp314-cp314-win_amd64.whl", hash = "sha256:068cdb2d0d644cdb45670810894f6a0600797a69c05f1ac478e8d31670b8ee75", size = 12443072, upload-time = "2026-01-31T23:12:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/37/75/62726948db36a56428fce4ba80a115716dc4fad6a3a4352487f8bb950966/numpy-2.4.2-cp314-cp314-win_arm64.whl", hash = "sha256:6ed0be1ee58eef41231a5c943d7d1375f093142702d5723ca2eb07db9b934b05", size = 10494886, upload-time = "2026-01-31T23:12:28.488Z" }, + { url = "https://files.pythonhosted.org/packages/36/2f/ee93744f1e0661dc267e4b21940870cabfae187c092e1433b77b09b50ac4/numpy-2.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:98f16a80e917003a12c0580f97b5f875853ebc33e2eaa4bccfc8201ac6869308", size = 14818567, upload-time = "2026-01-31T23:12:30.709Z" }, + { url = "https://files.pythonhosted.org/packages/a7/24/6535212add7d76ff938d8bdc654f53f88d35cddedf807a599e180dcb8e66/numpy-2.4.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:20abd069b9cda45874498b245c8015b18ace6de8546bf50dfa8cea1696ed06ef", size = 5328372, upload-time = "2026-01-31T23:12:32.962Z" }, + { url = "https://files.pythonhosted.org/packages/5e/9d/c48f0a035725f925634bf6b8994253b43f2047f6778a54147d7e213bc5a7/numpy-2.4.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e98c97502435b53741540a5717a6749ac2ada901056c7db951d33e11c885cc7d", size = 6649306, upload-time = "2026-01-31T23:12:34.797Z" }, + { url = "https://files.pythonhosted.org/packages/81/05/7c73a9574cd4a53a25907bad38b59ac83919c0ddc8234ec157f344d57d9a/numpy-2.4.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da6cad4e82cb893db4b69105c604d805e0c3ce11501a55b5e9f9083b47d2ffe8", size = 15722394, upload-time = "2026-01-31T23:12:36.565Z" }, + { url = "https://files.pythonhosted.org/packages/35/fa/4de10089f21fc7d18442c4a767ab156b25c2a6eaf187c0db6d9ecdaeb43f/numpy-2.4.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e4424677ce4b47fe73c8b5556d876571f7c6945d264201180db2dc34f676ab5", size = 16653343, upload-time = "2026-01-31T23:12:39.188Z" }, + { url = "https://files.pythonhosted.org/packages/b8/f9/d33e4ffc857f3763a57aa85650f2e82486832d7492280ac21ba9efda80da/numpy-2.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2b8f157c8a6f20eb657e240f8985cc135598b2b46985c5bccbde7616dc9c6b1e", size = 17078045, upload-time = "2026-01-31T23:12:42.041Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b8/54bdb43b6225badbea6389fa038c4ef868c44f5890f95dd530a218706da3/numpy-2.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5daf6f3914a733336dab21a05cdec343144600e964d2fcdabaac0c0269874b2a", size = 18380024, upload-time = "2026-01-31T23:12:44.331Z" }, + { url = "https://files.pythonhosted.org/packages/a5/55/6e1a61ded7af8df04016d81b5b02daa59f2ea9252ee0397cb9f631efe9e5/numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443", size = 6153937, upload-time = "2026-01-31T23:12:47.229Z" }, + { url = "https://files.pythonhosted.org/packages/45/aa/fa6118d1ed6d776b0983f3ceac9b1a5558e80df9365b1c3aa6d42bf9eee4/numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236", size = 12631844, upload-time = "2026-01-31T23:12:48.997Z" }, + { url = "https://files.pythonhosted.org/packages/32/0a/2ec5deea6dcd158f254a7b372fb09cfba5719419c8d66343bab35237b3fb/numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181", size = 10565379, upload-time = "2026-01-31T23:12:51.345Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f8/50e14d36d915ef64d8f8bc4a087fc8264d82c785eda6711f80ab7e620335/numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082", size = 16833179, upload-time = "2026-01-31T23:12:53.5Z" }, + { url = "https://files.pythonhosted.org/packages/17/17/809b5cad63812058a8189e91a1e2d55a5a18fd04611dbad244e8aeae465c/numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a", size = 14889755, upload-time = "2026-01-31T23:12:55.933Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ea/181b9bcf7627fc8371720316c24db888dcb9829b1c0270abf3d288b2e29b/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920", size = 5399500, upload-time = "2026-01-31T23:12:58.671Z" }, + { url = "https://files.pythonhosted.org/packages/33/9f/413adf3fc955541ff5536b78fcf0754680b3c6d95103230252a2c9408d23/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821", size = 6714252, upload-time = "2026-01-31T23:13:00.518Z" }, + { url = "https://files.pythonhosted.org/packages/91/da/643aad274e29ccbdf42ecd94dafe524b81c87bcb56b83872d54827f10543/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb", size = 15797142, upload-time = "2026-01-31T23:13:02.219Z" }, + { url = "https://files.pythonhosted.org/packages/66/27/965b8525e9cb5dc16481b30a1b3c21e50c7ebf6e9dbd48d0c4d0d5089c7e/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0", size = 16727979, upload-time = "2026-01-31T23:13:04.62Z" }, + { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, ] [[package]] @@ -2245,7 +2251,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, ] @@ -2311,11 +2317,11 @@ wheels = [ [[package]] name = "pathspec" -version = "1.0.3" +version = "1.0.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645", size = 131200, upload-time = "2026-01-27T03:59:46.938Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" }, + { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, ] [[package]] @@ -2473,30 +2479,30 @@ wheels = [ [[package]] name = "psutil" -version = "7.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/73/cb/09e5184fb5fc0358d110fc3ca7f6b1d033800734d34cac10f4136cfac10e/psutil-7.2.1.tar.gz", hash = "sha256:f7583aec590485b43ca601dd9cea0dcd65bd7bb21d30ef4ddbf4ea6b5ed1bdd3", size = 490253, upload-time = "2025-12-29T08:26:00.169Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/77/8e/f0c242053a368c2aa89584ecd1b054a18683f13d6e5a318fc9ec36582c94/psutil-7.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9f33bb525b14c3ea563b2fd521a84d2fa214ec59e3e6a2858f78d0844dd60d", size = 129624, upload-time = "2025-12-29T08:26:04.255Z" }, - { url = "https://files.pythonhosted.org/packages/26/97/a58a4968f8990617decee234258a2b4fc7cd9e35668387646c1963e69f26/psutil-7.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:81442dac7abfc2f4f4385ea9e12ddf5a796721c0f6133260687fec5c3780fa49", size = 130132, upload-time = "2025-12-29T08:26:06.228Z" }, - { url = "https://files.pythonhosted.org/packages/db/6d/ed44901e830739af5f72a85fa7ec5ff1edea7f81bfbf4875e409007149bd/psutil-7.2.1-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea46c0d060491051d39f0d2cff4f98d5c72b288289f57a21556cc7d504db37fc", size = 180612, upload-time = "2025-12-29T08:26:08.276Z" }, - { url = "https://files.pythonhosted.org/packages/c7/65/b628f8459bca4efbfae50d4bf3feaab803de9a160b9d5f3bd9295a33f0c2/psutil-7.2.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35630d5af80d5d0d49cfc4d64c1c13838baf6717a13effb35869a5919b854cdf", size = 183201, upload-time = "2025-12-29T08:26:10.622Z" }, - { url = "https://files.pythonhosted.org/packages/fb/23/851cadc9764edcc18f0effe7d0bf69f727d4cf2442deb4a9f78d4e4f30f2/psutil-7.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:923f8653416604e356073e6e0bccbe7c09990acef442def2f5640dd0faa9689f", size = 139081, upload-time = "2025-12-29T08:26:12.483Z" }, - { url = "https://files.pythonhosted.org/packages/59/82/d63e8494ec5758029f31c6cb06d7d161175d8281e91d011a4a441c8a43b5/psutil-7.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cfbe6b40ca48019a51827f20d830887b3107a74a79b01ceb8cc8de4ccb17b672", size = 134767, upload-time = "2025-12-29T08:26:14.528Z" }, - { url = "https://files.pythonhosted.org/packages/05/c2/5fb764bd61e40e1fe756a44bd4c21827228394c17414ade348e28f83cd79/psutil-7.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:494c513ccc53225ae23eec7fe6e1482f1b8a44674241b54561f755a898650679", size = 129716, upload-time = "2025-12-29T08:26:16.017Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d2/935039c20e06f615d9ca6ca0ab756cf8408a19d298ffaa08666bc18dc805/psutil-7.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3fce5f92c22b00cdefd1645aa58ab4877a01679e901555067b1bd77039aa589f", size = 130133, upload-time = "2025-12-29T08:26:18.009Z" }, - { url = "https://files.pythonhosted.org/packages/77/69/19f1eb0e01d24c2b3eacbc2f78d3b5add8a89bf0bb69465bc8d563cc33de/psutil-7.2.1-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93f3f7b0bb07711b49626e7940d6fe52aa9940ad86e8f7e74842e73189712129", size = 181518, upload-time = "2025-12-29T08:26:20.241Z" }, - { url = "https://files.pythonhosted.org/packages/e1/6d/7e18b1b4fa13ad370787626c95887b027656ad4829c156bb6569d02f3262/psutil-7.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d34d2ca888208eea2b5c68186841336a7f5e0b990edec929be909353a202768a", size = 184348, upload-time = "2025-12-29T08:26:22.215Z" }, - { url = "https://files.pythonhosted.org/packages/98/60/1672114392dd879586d60dd97896325df47d9a130ac7401318005aab28ec/psutil-7.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2ceae842a78d1603753561132d5ad1b2f8a7979cb0c283f5b52fb4e6e14b1a79", size = 140400, upload-time = "2025-12-29T08:26:23.993Z" }, - { url = "https://files.pythonhosted.org/packages/fb/7b/d0e9d4513c46e46897b46bcfc410d51fc65735837ea57a25170f298326e6/psutil-7.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:08a2f175e48a898c8eb8eace45ce01777f4785bc744c90aa2cc7f2fa5462a266", size = 135430, upload-time = "2025-12-29T08:26:25.999Z" }, - { url = "https://files.pythonhosted.org/packages/c5/cf/5180eb8c8bdf6a503c6919f1da28328bd1e6b3b1b5b9d5b01ae64f019616/psutil-7.2.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b2e953fcfaedcfbc952b44744f22d16575d3aa78eb4f51ae74165b4e96e55f42", size = 128137, upload-time = "2025-12-29T08:26:27.759Z" }, - { url = "https://files.pythonhosted.org/packages/c5/2c/78e4a789306a92ade5000da4f5de3255202c534acdadc3aac7b5458fadef/psutil-7.2.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:05cc68dbb8c174828624062e73078e7e35406f4ca2d0866c272c2410d8ef06d1", size = 128947, upload-time = "2025-12-29T08:26:29.548Z" }, - { url = "https://files.pythonhosted.org/packages/29/f8/40e01c350ad9a2b3cb4e6adbcc8a83b17ee50dd5792102b6142385937db5/psutil-7.2.1-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e38404ca2bb30ed7267a46c02f06ff842e92da3bb8c5bfdadbd35a5722314d8", size = 154694, upload-time = "2025-12-29T08:26:32.147Z" }, - { url = "https://files.pythonhosted.org/packages/06/e4/b751cdf839c011a9714a783f120e6a86b7494eb70044d7d81a25a5cd295f/psutil-7.2.1-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab2b98c9fc19f13f59628d94df5cc4cc4844bc572467d113a8b517d634e362c6", size = 156136, upload-time = "2025-12-29T08:26:34.079Z" }, - { url = "https://files.pythonhosted.org/packages/44/ad/bbf6595a8134ee1e94a4487af3f132cef7fce43aef4a93b49912a48c3af7/psutil-7.2.1-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f78baafb38436d5a128f837fab2d92c276dfb48af01a240b861ae02b2413ada8", size = 148108, upload-time = "2025-12-29T08:26:36.225Z" }, - { url = "https://files.pythonhosted.org/packages/1c/15/dd6fd869753ce82ff64dcbc18356093471a5a5adf4f77ed1f805d473d859/psutil-7.2.1-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:99a4cd17a5fdd1f3d014396502daa70b5ec21bf4ffe38393e152f8e449757d67", size = 147402, upload-time = "2025-12-29T08:26:39.21Z" }, - { url = "https://files.pythonhosted.org/packages/34/68/d9317542e3f2b180c4306e3f45d3c922d7e86d8ce39f941bb9e2e9d8599e/psutil-7.2.1-cp37-abi3-win_amd64.whl", hash = "sha256:b1b0671619343aa71c20ff9767eced0483e4fc9e1f489d50923738caf6a03c17", size = 136938, upload-time = "2025-12-29T08:26:41.036Z" }, - { url = "https://files.pythonhosted.org/packages/3e/73/2ce007f4198c80fcf2cb24c169884f833fe93fbc03d55d302627b094ee91/psutil-7.2.1-cp37-abi3-win_arm64.whl", hash = "sha256:0d67c1822c355aa6f7314d92018fb4268a76668a536f133599b91edd48759442", size = 133836, upload-time = "2025-12-29T08:26:43.086Z" }, +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, + { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, + { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, + { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, + { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, + { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" }, + { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" }, + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, ] [[package]] @@ -2812,7 +2818,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "rustworkx" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "scipy", version = "1.17.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -3022,7 +3028,7 @@ version = "0.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/b0/66d96f02120f79eeed86b5c5be04029b6821155f31ed4907a4e9f1460671/rustworkx-0.17.1.tar.gz", hash = "sha256:59ea01b4e603daffa4e8827316c1641eef18ae9032f0b1b14aa0181687e3108e", size = 399407, upload-time = "2025-09-15T16:29:46.429Z" } wheels = [ @@ -3138,7 +3144,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/56/3e/9cca699f3486ce6bc12ff46dc2031f1ec8eb9ccc9a320fdaf925f1417426/scipy-1.17.0.tar.gz", hash = "sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e", size = 30396830, upload-time = "2026-01-10T21:34:23.009Z" } wheels = [ @@ -3211,7 +3217,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "matplotlib" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] @@ -3829,11 +3835,11 @@ wheels = [ [[package]] name = "wcwidth" -version = "0.3.5" +version = "0.5.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/fc/44799c4a51ff0da0de0ff27e68c9dea3454f3d9bf15ffb606aeb6943e672/wcwidth-0.3.5.tar.gz", hash = "sha256:7c3463f312540cf21ddd527ea34f3ae95c057fa191aa7a9e043898d20d636e59", size = 234185, upload-time = "2026-01-25T04:37:23.942Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c2/62/a7c072fbfefb2980a00f99ca994279cb9ecf310cb2e6b2a4d2a28fe192b3/wcwidth-0.5.3.tar.gz", hash = "sha256:53123b7af053c74e9fe2e92ac810301f6139e64379031f7124574212fb3b4091", size = 157587, upload-time = "2026-01-31T03:52:10.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/86/7f461495625145a99d60f14cdac142a11db5d501c86d48aad165575d1e06/wcwidth-0.3.5-py3-none-any.whl", hash = "sha256:b0a0245130566939a24ab8432e625b38272fbc62ecbe5aecbdcb50b8f02ce993", size = 86681, upload-time = "2026-01-25T04:37:22.585Z" }, + { url = "https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl", hash = "sha256:d584eff31cd4753e1e5ff6c12e1edfdb324c995713f75d26c29807bb84bf649e", size = 92981, upload-time = "2026-01-31T03:52:09.14Z" }, ] [[package]] From 6a30a7c763d32877e008701fff691eeb099be6b3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 02:17:40 +0000 Subject: [PATCH 056/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=94=92=EF=B8=8F?= =?UTF-8?q?=20Lock=20file=20maintenance=20(#926)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Update | Change | |---|---| | lockFileMaintenance | All locks refreshed | 🔧 This Pull Request updates lock files to use the latest dependency versions. --- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- uv.lock | 6 ------ 1 file changed, 6 deletions(-) diff --git a/uv.lock b/uv.lock index 85d79a4a7..a32a2235f 100644 --- a/uv.lock +++ b/uv.lock @@ -893,7 +893,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/65/5b235b40581ad75ab97dcd8b4218022ae8e3ab77c13c919f1a1dfe9171fd/greenlet-3.3.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04bee4775f40ecefcdaa9d115ab44736cd4b9c5fba733575bfe9379419582e13", size = 273723, upload-time = "2026-01-23T15:30:37.521Z" }, { url = "https://files.pythonhosted.org/packages/ce/ad/eb4729b85cba2d29499e0a04ca6fbdd8f540afd7be142fd571eea43d712f/greenlet-3.3.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e1457f4fed12a50e427988a07f0f9df53cf0ee8da23fab16e6732c2ec909d4", size = 574874, upload-time = "2026-01-23T16:00:54.551Z" }, { url = "https://files.pythonhosted.org/packages/87/32/57cad7fe4c8b82fdaa098c89498ef85ad92dfbb09d5eb713adedfc2ae1f5/greenlet-3.3.1-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:070472cd156f0656f86f92e954591644e158fd65aa415ffbe2d44ca77656a8f5", size = 586309, upload-time = "2026-01-23T16:05:25.18Z" }, - { url = "https://files.pythonhosted.org/packages/66/66/f041005cb87055e62b0d68680e88ec1a57f4688523d5e2fb305841bc8307/greenlet-3.3.1-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1108b61b06b5224656121c3c8ee8876161c491cbe74e5c519e0634c837cf93d5", size = 597461, upload-time = "2026-01-23T16:15:51.943Z" }, { url = "https://files.pythonhosted.org/packages/87/eb/8a1ec2da4d55824f160594a75a9d8354a5fe0a300fb1c48e7944265217e1/greenlet-3.3.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a300354f27dd86bae5fbf7002e6dd2b3255cd372e9242c933faf5e859b703fe", size = 586985, upload-time = "2026-01-23T15:32:47.968Z" }, { url = "https://files.pythonhosted.org/packages/15/1c/0621dd4321dd8c351372ee8f9308136acb628600658a49be1b7504208738/greenlet-3.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e84b51cbebf9ae573b5fbd15df88887815e3253fc000a7d0ff95170e8f7e9729", size = 1547271, upload-time = "2026-01-23T16:04:18.977Z" }, { url = "https://files.pythonhosted.org/packages/9d/53/24047f8924c83bea7a59c8678d9571209c6bfe5f4c17c94a78c06024e9f2/greenlet-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0093bd1a06d899892427217f0ff2a3c8f306182b8c754336d32e2d587c131b4", size = 1613427, upload-time = "2026-01-23T15:33:44.428Z" }, @@ -901,7 +900,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/e8/2e1462c8fdbe0f210feb5ac7ad2d9029af8be3bf45bd9fa39765f821642f/greenlet-3.3.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5fd23b9bc6d37b563211c6abbb1b3cab27db385a4449af5c32e932f93017080c", size = 274974, upload-time = "2026-01-23T15:31:02.891Z" }, { url = "https://files.pythonhosted.org/packages/7e/a8/530a401419a6b302af59f67aaf0b9ba1015855ea7e56c036b5928793c5bd/greenlet-3.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f51496a0bfbaa9d74d36a52d2580d1ef5ed4fdfcff0a73730abfbbbe1403dd", size = 577175, upload-time = "2026-01-23T16:00:56.213Z" }, { url = "https://files.pythonhosted.org/packages/8e/89/7e812bb9c05e1aaef9b597ac1d0962b9021d2c6269354966451e885c4e6b/greenlet-3.3.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb0feb07fe6e6a74615ee62a880007d976cf739b6669cce95daa7373d4fc69c5", size = 590401, upload-time = "2026-01-23T16:05:26.365Z" }, - { url = "https://files.pythonhosted.org/packages/70/ae/e2d5f0e59b94a2269b68a629173263fa40b63da32f5c231307c349315871/greenlet-3.3.1-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:67ea3fc73c8cd92f42467a72b75e8f05ed51a0e9b1d15398c913416f2dafd49f", size = 601161, upload-time = "2026-01-23T16:15:53.456Z" }, { url = "https://files.pythonhosted.org/packages/5c/ae/8d472e1f5ac5efe55c563f3eabb38c98a44b832602e12910750a7c025802/greenlet-3.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39eda9ba259cc9801da05351eaa8576e9aa83eb9411e8f0c299e05d712a210f2", size = 590272, upload-time = "2026-01-23T15:32:49.411Z" }, { url = "https://files.pythonhosted.org/packages/a8/51/0fde34bebfcadc833550717eade64e35ec8738e6b097d5d248274a01258b/greenlet-3.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e2e7e882f83149f0a71ac822ebf156d902e7a5d22c9045e3e0d1daf59cee2cc9", size = 1550729, upload-time = "2026-01-23T16:04:20.867Z" }, { url = "https://files.pythonhosted.org/packages/16/c9/2fb47bee83b25b119d5a35d580807bb8b92480a54b68fef009a02945629f/greenlet-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80aa4d79eb5564f2e0a6144fcc744b5a37c56c4a92d60920720e99210d88db0f", size = 1615552, upload-time = "2026-01-23T15:33:45.743Z" }, @@ -910,7 +908,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/c8/9d76a66421d1ae24340dfae7e79c313957f6e3195c144d2c73333b5bfe34/greenlet-3.3.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:7e806ca53acf6d15a888405880766ec84721aa4181261cd11a457dfe9a7a4975", size = 276443, upload-time = "2026-01-23T15:30:10.066Z" }, { url = "https://files.pythonhosted.org/packages/81/99/401ff34bb3c032d1f10477d199724f5e5f6fbfb59816ad1455c79c1eb8e7/greenlet-3.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d842c94b9155f1c9b3058036c24ffb8ff78b428414a19792b2380be9cecf4f36", size = 597359, upload-time = "2026-01-23T16:00:57.394Z" }, { url = "https://files.pythonhosted.org/packages/2b/bc/4dcc0871ed557792d304f50be0f7487a14e017952ec689effe2180a6ff35/greenlet-3.3.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20fedaadd422fa02695f82093f9a98bad3dab5fcda793c658b945fcde2ab27ba", size = 607805, upload-time = "2026-01-23T16:05:28.068Z" }, - { url = "https://files.pythonhosted.org/packages/3b/cd/7a7ca57588dac3389e97f7c9521cb6641fd8b6602faf1eaa4188384757df/greenlet-3.3.1-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c620051669fd04ac6b60ebc70478210119c56e2d5d5df848baec4312e260e4ca", size = 622363, upload-time = "2026-01-23T16:15:54.754Z" }, { url = "https://files.pythonhosted.org/packages/cf/05/821587cf19e2ce1f2b24945d890b164401e5085f9d09cbd969b0c193cd20/greenlet-3.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14194f5f4305800ff329cbf02c5fcc88f01886cadd29941b807668a45f0d2336", size = 609947, upload-time = "2026-01-23T15:32:51.004Z" }, { url = "https://files.pythonhosted.org/packages/a4/52/ee8c46ed9f8babaa93a19e577f26e3d28a519feac6350ed6f25f1afee7e9/greenlet-3.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7b2fe4150a0cf59f847a67db8c155ac36aed89080a6a639e9f16df5d6c6096f1", size = 1567487, upload-time = "2026-01-23T16:04:22.125Z" }, { url = "https://files.pythonhosted.org/packages/8f/7c/456a74f07029597626f3a6db71b273a3632aecb9afafeeca452cfa633197/greenlet-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49f4ad195d45f4a66a0eb9c1ba4832bb380570d361912fa3554746830d332149", size = 1636087, upload-time = "2026-01-23T15:33:47.486Z" }, @@ -919,7 +916,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/ab/d26750f2b7242c2b90ea2ad71de70cfcd73a948a49513188a0fc0d6fc15a/greenlet-3.3.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:7ab327905cabb0622adca5971e488064e35115430cec2c35a50fd36e72a315b3", size = 275205, upload-time = "2026-01-23T15:30:24.556Z" }, { url = "https://files.pythonhosted.org/packages/10/d3/be7d19e8fad7c5a78eeefb2d896a08cd4643e1e90c605c4be3b46264998f/greenlet-3.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65be2f026ca6a176f88fb935ee23c18333ccea97048076aef4db1ef5bc0713ac", size = 599284, upload-time = "2026-01-23T16:00:58.584Z" }, { url = "https://files.pythonhosted.org/packages/ae/21/fe703aaa056fdb0f17e5afd4b5c80195bbdab701208918938bd15b00d39b/greenlet-3.3.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a3ae05b3d225b4155bda56b072ceb09d05e974bc74be6c3fc15463cf69f33fd", size = 610274, upload-time = "2026-01-23T16:05:29.312Z" }, - { url = "https://files.pythonhosted.org/packages/06/00/95df0b6a935103c0452dad2203f5be8377e551b8466a29650c4c5a5af6cc/greenlet-3.3.1-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:12184c61e5d64268a160226fb4818af4df02cfead8379d7f8b99a56c3a54ff3e", size = 624375, upload-time = "2026-01-23T16:15:55.915Z" }, { url = "https://files.pythonhosted.org/packages/cb/86/5c6ab23bb3c28c21ed6bebad006515cfe08b04613eb105ca0041fecca852/greenlet-3.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6423481193bbbe871313de5fd06a082f2649e7ce6e08015d2a76c1e9186ca5b3", size = 612904, upload-time = "2026-01-23T15:32:52.317Z" }, { url = "https://files.pythonhosted.org/packages/c2/f3/7949994264e22639e40718c2daf6f6df5169bf48fb038c008a489ec53a50/greenlet-3.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:33a956fe78bbbda82bfc95e128d61129b32d66bcf0a20a1f0c08aa4839ffa951", size = 1567316, upload-time = "2026-01-23T16:04:23.316Z" }, { url = "https://files.pythonhosted.org/packages/8d/6e/d73c94d13b6465e9f7cd6231c68abde838bb22408596c05d9059830b7872/greenlet-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b065d3284be43728dd280f6f9a13990b56470b81be20375a207cdc814a983f2", size = 1636549, upload-time = "2026-01-23T15:33:48.643Z" }, @@ -928,7 +924,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5", size = 275737, upload-time = "2026-01-23T15:32:16.889Z" }, { url = "https://files.pythonhosted.org/packages/41/2e/a3a417d620363fdbb08a48b1dd582956a46a61bf8fd27ee8164f9dfe87c2/greenlet-3.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b31c05dd84ef6871dd47120386aed35323c944d86c3d91a17c4b8d23df62f15b", size = 646422, upload-time = "2026-01-23T16:01:00.354Z" }, { url = "https://files.pythonhosted.org/packages/b4/09/c6c4a0db47defafd2d6bab8ddfe47ad19963b4e30f5bed84d75328059f8c/greenlet-3.3.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02925a0bfffc41e542c70aa14c7eda3593e4d7e274bfcccca1827e6c0875902e", size = 658219, upload-time = "2026-01-23T16:05:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/e2/89/b95f2ddcc5f3c2bc09c8ee8d77be312df7f9e7175703ab780f2014a0e781/greenlet-3.3.1-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3e0f3878ca3a3ff63ab4ea478585942b53df66ddde327b59ecb191b19dbbd62d", size = 671455, upload-time = "2026-01-23T16:15:57.232Z" }, { url = "https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f", size = 660237, upload-time = "2026-01-23T15:32:53.967Z" }, { url = "https://files.pythonhosted.org/packages/96/61/373c30b7197f9e756e4c81ae90a8d55dc3598c17673f91f4d31c3c689c3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aec9ab04e82918e623415947921dea15851b152b822661cce3f8e4393c3df683", size = 1615261, upload-time = "2026-01-23T16:04:25.066Z" }, { url = "https://files.pythonhosted.org/packages/fd/d3/ca534310343f5945316f9451e953dcd89b36fe7a19de652a1dc5a0eeef3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71c767cf281a80d02b6c1bdc41c9468e1f5a494fb11bc8688c360524e273d7b1", size = 1683719, upload-time = "2026-01-23T15:33:50.61Z" }, @@ -937,7 +932,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/28/24/cbbec49bacdcc9ec652a81d3efef7b59f326697e7edf6ed775a5e08e54c2/greenlet-3.3.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:3e63252943c921b90abb035ebe9de832c436401d9c45f262d80e2d06cc659242", size = 282706, upload-time = "2026-01-23T15:33:05.525Z" }, { url = "https://files.pythonhosted.org/packages/86/2e/4f2b9323c144c4fe8842a4e0d92121465485c3c2c5b9e9b30a52e80f523f/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76e39058e68eb125de10c92524573924e827927df5d3891fbc97bd55764a8774", size = 651209, upload-time = "2026-01-23T16:01:01.517Z" }, { url = "https://files.pythonhosted.org/packages/d9/87/50ca60e515f5bb55a2fbc5f0c9b5b156de7d2fc51a0a69abc9d23914a237/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9f9d5e7a9310b7a2f416dd13d2e3fd8b42d803968ea580b7c0f322ccb389b97", size = 654300, upload-time = "2026-01-23T16:05:32.199Z" }, - { url = "https://files.pythonhosted.org/packages/7c/25/c51a63f3f463171e09cb586eb64db0861eb06667ab01a7968371a24c4f3b/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b9721549a95db96689458a1e0ae32412ca18776ed004463df3a9299c1b257ab", size = 662574, upload-time = "2026-01-23T16:15:58.364Z" }, { url = "https://files.pythonhosted.org/packages/1d/94/74310866dfa2b73dd08659a3d18762f83985ad3281901ba0ee9a815194fb/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92497c78adf3ac703b57f1e3813c2d874f27f71a178f9ea5887855da413cd6d2", size = 653842, upload-time = "2026-01-23T15:32:55.671Z" }, { url = "https://files.pythonhosted.org/packages/97/43/8bf0ffa3d498eeee4c58c212a3905dd6146c01c8dc0b0a046481ca29b18c/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ed6b402bc74d6557a705e197d47f9063733091ed6357b3de33619d8a8d93ac53", size = 1614917, upload-time = "2026-01-23T16:04:26.276Z" }, { url = "https://files.pythonhosted.org/packages/89/90/a3be7a5f378fc6e84abe4dcfb2ba32b07786861172e502388b4c90000d1b/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:59913f1e5ada20fde795ba906916aea25d442abcc0593fba7e26c92b7ad76249", size = 1676092, upload-time = "2026-01-23T15:33:52.176Z" }, From 7d1d343ea01caec6d6594b6f6aa053d249ed115b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 02:21:21 +0000 Subject: [PATCH 057/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=AA=9D=20Update?= =?UTF-8?q?=20patch=20versions=20(#922)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [adhtruong/mirrors-typos](https://redirect.github.com/adhtruong/mirrors-typos) | repository | patch | `v1.42.1` → `v1.42.3` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/adhtruong%2fmirrors-typos/v1.42.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/adhtruong%2fmirrors-typos/v1.42.1/v1.42.3?slim=true) | | [astral-sh/uv-pre-commit](https://redirect.github.com/astral-sh/uv-pre-commit) | repository | patch | `0.9.26` → `0.9.28` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/astral-sh%2fuv-pre-commit/0.9.28?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/astral-sh%2fuv-pre-commit/0.9.26/0.9.28?slim=true) | | [mqt-core](https://redirect.github.com/munich-quantum-toolkit/core) ([changelog](https://redirect.github.com/munich-quantum-toolkit/core/blob/main/CHANGELOG.md)) | dependency-groups | patch | `==3.4.0` → `==3.4.1` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/mqt-core/3.4.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/mqt-core/3.4.0/3.4.1?slim=true) | | [mqt.core](https://redirect.github.com/munich-quantum-toolkit/core) ([changelog](https://redirect.github.com/munich-quantum-toolkit/core/blob/main/CHANGELOG.md)) | build-system.requires | patch | `==3.4.0` → `==3.4.1` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/mqt-core/3.4.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/mqt-core/3.4.0/3.4.1?slim=true) | | [mqt.core](https://redirect.github.com/munich-quantum-toolkit/core) ([changelog](https://redirect.github.com/munich-quantum-toolkit/core/blob/main/CHANGELOG.md)) | project.dependencies | patch | `==3.4.0` → `==3.4.1` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/mqt-core/3.4.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/mqt-core/3.4.0/3.4.1?slim=true) | | [python-jsonschema/check-jsonschema](https://redirect.github.com/python-jsonschema/check-jsonschema) | repository | patch | `0.36.0` → `0.36.1` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/python-jsonschema%2fcheck-jsonschema/0.36.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/python-jsonschema%2fcheck-jsonschema/0.36.0/0.36.1?slim=true) | | [ty](https://redirect.github.com/astral-sh/ty) ([changelog](https://redirect.github.com/astral-sh/ty/blob/main/CHANGELOG.md)) | dependency-groups | patch | `==0.0.13` → `==0.0.14` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/ty/0.0.14?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ty/0.0.13/0.0.14?slim=true) | Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://redirect.github.com/renovatebot/renovate/discussions/new) if you have any questions. --- ### Release Notes
adhtruong/mirrors-typos (adhtruong/mirrors-typos) ### [`v1.42.3`](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.2...v1.42.3) [Compare Source](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.2...v1.42.3) ### [`v1.42.2`](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.1...v1.42.2) [Compare Source](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.1...v1.42.2)
astral-sh/uv-pre-commit (astral-sh/uv-pre-commit) ### [`v0.9.28`](https://redirect.github.com/astral-sh/uv-pre-commit/releases/tag/0.9.28) [Compare Source](https://redirect.github.com/astral-sh/uv-pre-commit/compare/0.9.27...0.9.28) See: ### [`v0.9.27`](https://redirect.github.com/astral-sh/uv-pre-commit/releases/tag/0.9.27) [Compare Source](https://redirect.github.com/astral-sh/uv-pre-commit/compare/0.9.26...0.9.27) See:
munich-quantum-toolkit/core (mqt-core) ### [`v3.4.1`](https://redirect.github.com/munich-quantum-toolkit/core/releases/tag/v3.4.1): MQT Core 3.4.1 Release [Compare Source](https://redirect.github.com/munich-quantum-toolkit/core/compare/v3.4.0...v3.4.1) ##### 👀 What Changed *Please refer to the [changelog](https://redirect.github.com/munich-quantum-toolkit/core/blob/main/CHANGELOG.md) and the [upgrade guide](https://redirect.github.com/munich-quantum-toolkit/core/blob/main/UPGRADING.md) for a structured overview of the changes.* ##### ⚛️ MQT Core IR - 🎨 Reorganize QDMI Codebase (backport [#​1444](https://redirect.github.com/munich-quantum-toolkit/core/issues/1444)) ([#​1449](https://redirect.github.com/munich-quantum-toolkit/core/pull/1449)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) ##### 🐉 MQT Core MLIR - 🔧 Allow C++ standards newer than 20 (backport [#​1480](https://redirect.github.com/munich-quantum-toolkit/core/issues/1480)) ([#​1482](https://redirect.github.com/munich-quantum-toolkit/core/pull/1482)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) ##### 🐲 MQT Core QIR - ♻️ Use `llc` instead of random `clang` for compiling QIR test circuits to improve robustness and handle opaque pointers correctly across LLVM versions (backport [#​1447](https://redirect.github.com/munich-quantum-toolkit/core/issues/1447)) ([#​1450](https://redirect.github.com/munich-quantum-toolkit/core/pull/1450)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) ##### 🚀 Features and Enhancements - 🎨 Reorganize QDMI Codebase (backport [#​1444](https://redirect.github.com/munich-quantum-toolkit/core/issues/1444)) ([#​1449](https://redirect.github.com/munich-quantum-toolkit/core/pull/1449)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) ##### 🐛 Bug Fixes - 🔧 Allow C++ standards newer than 20 (backport [#​1480](https://redirect.github.com/munich-quantum-toolkit/core/issues/1480)) ([#​1482](https://redirect.github.com/munich-quantum-toolkit/core/pull/1482)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ♻️ Use `llc` instead of random `clang` for compiling QIR test circuits to improve robustness and handle opaque pointers correctly across LLVM versions (backport [#​1447](https://redirect.github.com/munich-quantum-toolkit/core/issues/1447)) ([#​1450](https://redirect.github.com/munich-quantum-toolkit/core/pull/1450)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) ##### 📄 Documentation - 🔖 Prepare release of `v3.4.1` ([#​1495](https://redirect.github.com/munich-quantum-toolkit/core/pull/1495)) ([**@​denialhaag**](https://redirect.github.com/denialhaag)) - 📝 Update templated files (backport [#​1454](https://redirect.github.com/munich-quantum-toolkit/core/issues/1454)) ([#​1457](https://redirect.github.com/munich-quantum-toolkit/core/pull/1457)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - 📝 Update templated files (backport [#​1439](https://redirect.github.com/munich-quantum-toolkit/core/issues/1439)) ([#​1448](https://redirect.github.com/munich-quantum-toolkit/core/pull/1448)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) ##### 🤖 CI - 👷 Improve `stubs` session (backport [#​1461](https://redirect.github.com/munich-quantum-toolkit/core/issues/1461)) ([#​1462](https://redirect.github.com/munich-quantum-toolkit/core/pull/1462)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️ Update external dependencies and prek checks (backport [#​1453](https://redirect.github.com/munich-quantum-toolkit/core/issues/1453)) ([#​1455](https://redirect.github.com/munich-quantum-toolkit/core/pull/1455)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) ##### 🧹 Code Quality - 🔙 Backport switch from mypy to ty ([#​1451](https://redirect.github.com/munich-quantum-toolkit/core/pull/1451)) ([**@​burgholzer**](https://redirect.github.com/burgholzer)) ##### ⬆️ Dependencies
11 changes - ⬆️🪝 Update patch versions (backport [#​1493](https://redirect.github.com/munich-quantum-toolkit/core/issues/1493)) ([#​1494](https://redirect.github.com/munich-quantum-toolkit/core/pull/1494)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️ Update `nanobind` to 2.11.0 (backport [#​1481](https://redirect.github.com/munich-quantum-toolkit/core/issues/1481)) ([#​1488](https://redirect.github.com/munich-quantum-toolkit/core/pull/1488)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️👨‍💻 Update actions/attest-build-provenance action to v3.2.0 (backport [#​1491](https://redirect.github.com/munich-quantum-toolkit/core/issues/1491)) ([#​1492](https://redirect.github.com/munich-quantum-toolkit/core/pull/1492)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️🔒️ Lock file maintenance (backport [#​1478](https://redirect.github.com/munich-quantum-toolkit/core/issues/1478)) ([#​1490](https://redirect.github.com/munich-quantum-toolkit/core/pull/1490)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️👨‍💻 Update patch versions (backport [#​1476](https://redirect.github.com/munich-quantum-toolkit/core/issues/1476)) ([#​1489](https://redirect.github.com/munich-quantum-toolkit/core/pull/1489)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️🔒️ Lock file maintenance (backport [#​1473](https://redirect.github.com/munich-quantum-toolkit/core/issues/1473)) ([#​1486](https://redirect.github.com/munich-quantum-toolkit/core/pull/1486)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️🪝 Update patch versions (backport [#​1467](https://redirect.github.com/munich-quantum-toolkit/core/issues/1467)) ([#​1484](https://redirect.github.com/munich-quantum-toolkit/core/pull/1484)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️👨‍💻 Update release-drafter/release-drafter action to v6.2.0 (backport [#​1477](https://redirect.github.com/munich-quantum-toolkit/core/issues/1477)) ([#​1487](https://redirect.github.com/munich-quantum-toolkit/core/pull/1487)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️🪝 Update pre-commit hook black to v26 (backport [#​1469](https://redirect.github.com/munich-quantum-toolkit/core/issues/1469)) ([#​1485](https://redirect.github.com/munich-quantum-toolkit/core/pull/1485)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️🪝 Update pre-commit hook rbubley/mirrors-prettier to v3.8.0 (backport [#​1468](https://redirect.github.com/munich-quantum-toolkit/core/issues/1468)) ([#​1483](https://redirect.github.com/munich-quantum-toolkit/core/pull/1483)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\())) - ⬆️ Update external dependencies and prek checks (backport [#​1453](https://redirect.github.com/munich-quantum-toolkit/core/issues/1453)) ([#​1455](https://redirect.github.com/munich-quantum-toolkit/core/pull/1455)) (\[**@​[mergify\[bot\]](https://redirect.github.com/apps/mergify)**]\(]]\()))
**Full Changelog**:
python-jsonschema/check-jsonschema (python-jsonschema/check-jsonschema) ### [`v0.36.1`](https://redirect.github.com/python-jsonschema/check-jsonschema/blob/HEAD/CHANGELOG.rst#0361) [Compare Source](https://redirect.github.com/python-jsonschema/check-jsonschema/compare/0.36.0...0.36.1) - Update vendored schemas: buildkite, circle-ci, dependabot, github-issue-forms, github-workflows, gitlab-ci, mergify, readthedocs, renovate, snapcraft, taskfile (2026-01-25)
astral-sh/ty (ty) ### [`v0.0.14`](https://redirect.github.com/astral-sh/ty/blob/HEAD/CHANGELOG.md#0014) [Compare Source](https://redirect.github.com/astral-sh/ty/compare/0.0.13...0.0.14) Released on 2026-01-26. ##### Bug fixes - Consider keyword arguments when unpacking a variadic argument ([#​22796](https://redirect.github.com/astral-sh/ruff/pull/22796)) - Fix binary operator false-positive for constrained TypeVars ([#​22782](https://redirect.github.com/astral-sh/ruff/pull/22782)) - Fix docstring rendering for literal blocks after doctests ([#​22676](https://redirect.github.com/astral-sh/ruff/pull/22676)) - Fix false-positive `unsupported-operator` for "symmetric" TypeVars ([#​22756](https://redirect.github.com/astral-sh/ruff/pull/22756)) - Fix panic when overriding a final method using an assignment ([#​22831](https://redirect.github.com/astral-sh/ruff/pull/22831)) - Fix unary operator false-positive for constrained TypeVars ([#​22783](https://redirect.github.com/astral-sh/ruff/pull/22783)) - Fix generic functions with a generic (ParamSpec) decorator ([#​22544](https://redirect.github.com/astral-sh/ruff/pull/22544)) - Fix `memo.changed_at` assertion panics ([#​22498](https://redirect.github.com/astral-sh/ruff/pull/22498)) ##### LSP server - Look up attributes on metaclasses for Go to Definition ([#​22758](https://redirect.github.com/astral-sh/ruff/pull/22758)) - Suppress type inlay hints for leading-underscore assignments ([#​22855](https://redirect.github.com/astral-sh/ruff/pull/22855)) ##### Configuration - Add `allowed-unresolved-imports` setting ([#​22800](https://redirect.github.com/astral-sh/ruff/pull/22800)) ##### Other changes - Add `assert-type-unspellable-subtype` diagnostic, for failed `assert_type()` where the actual type is a subtype of the named type that can't be spelled in a type expression ([#​22815](https://redirect.github.com/astral-sh/ruff/pull/22815)) - Add a new `empty-body` return code for functions with stub bodies that have non-`None` return annotations ([#​22846](https://redirect.github.com/astral-sh/ruff/pull/22846)) - Add diagnostic disambiguation for different type aliases with the same name ([#​22852](https://redirect.github.com/astral-sh/ruff/pull/22852)) - Add support for dict literals and dict() calls as default values for parameters with TypedDict types ([#​22161](https://redirect.github.com/astral-sh/ruff/pull/22161)) - Add support for subscripts on intersections ([#​22654](https://redirect.github.com/astral-sh/ruff/pull/22654)) - Avoid duplicate syntax errors for `await` outside functions ([#​22826](https://redirect.github.com/astral-sh/ruff/pull/22826)) - Emit an error if the same type parameter appears more than once in a `Generic[]` subscript ([#​22738](https://redirect.github.com/astral-sh/ruff/pull/22738)) - Emit diagnostic for unimplemented abstract method on [@​final](https://redirect.github.com/final) class ([#​22753](https://redirect.github.com/astral-sh/ruff/pull/22753)) - Fix GitLab Code Quality output format for empty diagnostics ([#​22833](https://redirect.github.com/astral-sh/ruff/pull/22833)) - Fix assignment in decorated method causing `Unknown` fallback ([#​22778](https://redirect.github.com/astral-sh/ruff/pull/22778)) - Fix false negative when using a non-runtime-checkable protocol in a `match` class pattern ([#​22836](https://redirect.github.com/astral-sh/ruff/pull/22836)) - Improve completion rankings for raise-from/except contexts ([#​22775](https://redirect.github.com/astral-sh/ruff/pull/22775)) - Improve invalid assignment diagnostics with type context ([#​22643](https://redirect.github.com/astral-sh/ruff/pull/22643)) - Improve support for kwarg splats in dictionary literals ([#​22781](https://redirect.github.com/astral-sh/ruff/pull/22781)) - Infer `TypedDict` types with >=1 required key as being always truthy ([#​22808](https://redirect.github.com/astral-sh/ruff/pull/22808)) - Point to an overload with an invalid `@final` decoator when emitting `invalid-overload` errors for invalid `@final` decorators ([#​22812](https://redirect.github.com/astral-sh/ruff/pull/22812)) - Require both `*args` and `**kwargs` when calling a `ParamSpec` callable ([#​22820](https://redirect.github.com/astral-sh/ruff/pull/22820)) - Stricter validation of `TypedDict` definitions ([#​22811](https://redirect.github.com/astral-sh/ruff/pull/22811)) - Support recursive and stringified annotations in functional `typing.NamedTuple`s ([#​22718](https://redirect.github.com/astral-sh/ruff/pull/22718)) - Support solving generics involving PEP 695 type aliases ([#​22678](https://redirect.github.com/astral-sh/ruff/pull/22678)) - Use a more lenient fallback type for failed `namedtuple()` and `NamedTuple` calls ([#​22765](https://redirect.github.com/astral-sh/ruff/pull/22765)) - Use type context from augmented assignment dunder calls ([#​22540](https://redirect.github.com/astral-sh/ruff/pull/22540)) - Check that starred arguments in function calls are iterable ([#​22805](https://redirect.github.com/astral-sh/ruff/pull/22805)) ##### Contributors - [@​AlexWaygood](https://redirect.github.com/AlexWaygood) - [@​maifeeulasad](https://redirect.github.com/maifeeulasad) - [@​RasmusNygren](https://redirect.github.com/RasmusNygren) - [@​ntBre](https://redirect.github.com/ntBre) - [@​Imbuzi](https://redirect.github.com/Imbuzi) - [@​dhruvmanila](https://redirect.github.com/dhruvmanila) - [@​ibraheemdev](https://redirect.github.com/ibraheemdev) - [@​carljm](https://redirect.github.com/carljm) - [@​Hugo-Polloli](https://redirect.github.com/Hugo-Polloli) - [@​charliermarsh](https://redirect.github.com/charliermarsh) - [@​MichaReiser](https://redirect.github.com/MichaReiser) - [@​bxff](https://redirect.github.com/bxff) - [@​felixscherz](https://redirect.github.com/felixscherz) - [@​denyszhak](https://redirect.github.com/denyszhak)
--- ### Configuration 📅 **Schedule**: Branch creation - "every weekend" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). --------- Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel Haag <121057143+denialhaag@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- pyproject.toml | 2 +- uv.lock | 42 ++++++++++++++++++++--------------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1a7655beb..6ebfe2d49 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: ## Check JSON schemata - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.36.0 + rev: 0.36.1 hooks: - id: check-github-workflows priority: 0 @@ -56,7 +56,7 @@ repos: ## Check for spelling - repo: https://github.com/adhtruong/mirrors-typos - rev: v1.42.1 + rev: v1.42.3 hooks: - id: typos priority: 0 @@ -78,7 +78,7 @@ repos: ## Ensure uv lock file is up-to-date - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.26 + rev: 0.9.28 hooks: - id: uv-lock priority: 0 diff --git a/pyproject.toml b/pyproject.toml index 68bf03f62..77b2f686f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -425,5 +425,5 @@ dev = [ {include-group = "build"}, {include-group = "test"}, "nox>=2025.11.12", - "ty==0.0.13", + "ty==0.0.14", ] diff --git a/uv.lock b/uv.lock index a32a2235f..c472a7eab 100644 --- a/uv.lock +++ b/uv.lock @@ -1758,7 +1758,7 @@ dev = [ { name = "pytest-xdist", specifier = ">=3.8.0" }, { name = "scikit-build-core", specifier = ">=0.11.6" }, { name = "setuptools-scm", specifier = ">=9.2.2" }, - { name = "ty", specifier = "==0.0.13" }, + { name = "ty", specifier = "==0.0.14" }, { name = "walkerlayout", specifier = ">=1.0.2" }, ] docs = [ @@ -3754,26 +3754,26 @@ wheels = [ [[package]] name = "ty" -version = "0.0.13" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/dc/b607f00916f5a7c52860b84a66dc17bc6988e8445e96b1d6e175a3837397/ty-0.0.13.tar.gz", hash = "sha256:7a1d135a400ca076407ea30012d1f75419634160ed3b9cad96607bf2956b23b3", size = 4999183, upload-time = "2026-01-21T13:21:16.133Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1a/df/3632f1918f4c0a33184f107efc5d436ab6da147fd3d3b94b3af6461efbf4/ty-0.0.13-py3-none-linux_armv6l.whl", hash = "sha256:1b2b8e02697c3a94c722957d712a0615bcc317c9b9497be116ef746615d892f2", size = 9993501, upload-time = "2026-01-21T13:21:26.628Z" }, - { url = "https://files.pythonhosted.org/packages/92/87/6a473ced5ac280c6ce5b1627c71a8a695c64481b99aabc798718376a441e/ty-0.0.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f15cdb8e233e2b5adfce673bb21f4c5e8eaf3334842f7eea3c70ac6fda8c1de5", size = 9860986, upload-time = "2026-01-21T13:21:24.425Z" }, - { url = "https://files.pythonhosted.org/packages/5d/9b/d89ae375cf0a7cd9360e1164ce017f8c753759be63b6a11ed4c944abe8c6/ty-0.0.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0819e89ac9f0d8af7a062837ce197f0461fee2fc14fd07e2c368780d3a397b73", size = 9350748, upload-time = "2026-01-21T13:21:28.502Z" }, - { url = "https://files.pythonhosted.org/packages/a8/a6/9ad58518056fab344b20c0bb2c1911936ebe195318e8acc3bc45ac1c6b6b/ty-0.0.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de79f481084b7cc7a202ba0d7a75e10970d10ffa4f025b23f2e6b7324b74886", size = 9849884, upload-time = "2026-01-21T13:21:21.886Z" }, - { url = "https://files.pythonhosted.org/packages/b1/c3/8add69095fa179f523d9e9afcc15a00818af0a37f2b237a9b59bc0046c34/ty-0.0.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4fb2154cff7c6e95d46bfaba283c60642616f20d73e5f96d0c89c269f3e1bcec", size = 9822975, upload-time = "2026-01-21T13:21:14.292Z" }, - { url = "https://files.pythonhosted.org/packages/a4/05/4c0927c68a0a6d43fb02f3f0b6c19c64e3461dc8ed6c404dde0efb8058f7/ty-0.0.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00be58d89337c27968a20d58ca553458608c5b634170e2bec82824c2e4cf4d96", size = 10294045, upload-time = "2026-01-21T13:21:30.505Z" }, - { url = "https://files.pythonhosted.org/packages/b4/86/6dc190838aba967557fe0bfd494c595d00b5081315a98aaf60c0e632aaeb/ty-0.0.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72435eade1fa58c6218abb4340f43a6c3ff856ae2dc5722a247d3a6dd32e9737", size = 10916460, upload-time = "2026-01-21T13:21:07.788Z" }, - { url = "https://files.pythonhosted.org/packages/04/40/9ead96b7c122e1109dfcd11671184c3506996bf6a649306ec427e81d9544/ty-0.0.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:77a548742ee8f621d718159e7027c3b555051d096a49bb580249a6c5fc86c271", size = 10597154, upload-time = "2026-01-21T13:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/aa/7d/e832a2c081d2be845dc6972d0c7998914d168ccbc0b9c86794419ab7376e/ty-0.0.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da067c57c289b7cf914669704b552b6207c2cc7f50da4118c3e12388642e6b3f", size = 10410710, upload-time = "2026-01-21T13:21:12.388Z" }, - { url = "https://files.pythonhosted.org/packages/31/e3/898be3a96237a32f05c4c29b43594dc3b46e0eedfe8243058e46153b324f/ty-0.0.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d1b50a01fffa140417fca5a24b658fbe0734074a095d5b6f0552484724474343", size = 9826299, upload-time = "2026-01-21T13:21:00.845Z" }, - { url = "https://files.pythonhosted.org/packages/bb/eb/db2d852ce0ed742505ff18ee10d7d252f3acfd6fc60eca7e9c7a0288a6d8/ty-0.0.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0f33c46f52e5e9378378eca0d8059f026f3c8073ace02f7f2e8d079ddfe5207e", size = 9831610, upload-time = "2026-01-21T13:21:05.842Z" }, - { url = "https://files.pythonhosted.org/packages/9e/61/149f59c8abaddcbcbb0bd13b89c7741ae1c637823c5cf92ed2c644fcadef/ty-0.0.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:168eda24d9a0b202cf3758c2962cc295878842042b7eca9ed2965259f59ce9f2", size = 9978885, upload-time = "2026-01-21T13:21:10.306Z" }, - { url = "https://files.pythonhosted.org/packages/a0/cd/026d4e4af60a80918a8d73d2c42b8262dd43ab2fa7b28d9743004cb88d57/ty-0.0.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d4917678b95dc8cb399cc459fab568ba8d5f0f33b7a94bf840d9733043c43f29", size = 10506453, upload-time = "2026-01-21T13:20:56.633Z" }, - { url = "https://files.pythonhosted.org/packages/63/06/8932833a4eca2df49c997a29afb26721612de8078ae79074c8fe87e17516/ty-0.0.13-py3-none-win32.whl", hash = "sha256:c1f2ec40daa405508b053e5b8e440fbae5fdb85c69c9ab0ee078f8bc00eeec3d", size = 9433482, upload-time = "2026-01-21T13:20:58.717Z" }, - { url = "https://files.pythonhosted.org/packages/aa/fd/e8d972d1a69df25c2cecb20ea50e49ad5f27a06f55f1f5f399a563e71645/ty-0.0.13-py3-none-win_amd64.whl", hash = "sha256:8b7b1ab9f187affbceff89d51076038363b14113be29bda2ddfa17116de1d476", size = 10319156, upload-time = "2026-01-21T13:21:03.266Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c2/05fdd64ac003a560d4fbd1faa7d9a31d75df8f901675e5bed1ee2ceeff87/ty-0.0.13-py3-none-win_arm64.whl", hash = "sha256:1c9630333497c77bb9bcabba42971b96ee1f36c601dd3dcac66b4134f9fa38f0", size = 9808316, upload-time = "2026-01-21T13:20:54.053Z" }, +version = "0.0.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/57/22c3d6bf95c2229120c49ffc2f0da8d9e8823755a1c3194da56e51f1cc31/ty-0.0.14.tar.gz", hash = "sha256:a691010565f59dd7f15cf324cdcd1d9065e010c77a04f887e1ea070ba34a7de2", size = 5036573, upload-time = "2026-01-27T00:57:31.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/cb/cc6d1d8de59beb17a41f9a614585f884ec2d95450306c173b3b7cc090d2e/ty-0.0.14-py3-none-linux_armv6l.whl", hash = "sha256:32cf2a7596e693094621d3ae568d7ee16707dce28c34d1762947874060fdddaa", size = 10034228, upload-time = "2026-01-27T00:57:53.133Z" }, + { url = "https://files.pythonhosted.org/packages/f3/96/dd42816a2075a8f31542296ae687483a8d047f86a6538dfba573223eaf9a/ty-0.0.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f971bf9805f49ce8c0968ad53e29624d80b970b9eb597b7cbaba25d8a18ce9a2", size = 9939162, upload-time = "2026-01-27T00:57:43.857Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b4/73c4859004e0f0a9eead9ecb67021438b2e8e5fdd8d03e7f5aca77623992/ty-0.0.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:45448b9e4806423523268bc15e9208c4f3f2ead7c344f615549d2e2354d6e924", size = 9418661, upload-time = "2026-01-27T00:58:03.411Z" }, + { url = "https://files.pythonhosted.org/packages/58/35/839c4551b94613db4afa20ee555dd4f33bfa7352d5da74c5fa416ffa0fd2/ty-0.0.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee94a9b747ff40114085206bdb3205a631ef19a4d3fb89e302a88754cbbae54c", size = 9837872, upload-time = "2026-01-27T00:57:23.718Z" }, + { url = "https://files.pythonhosted.org/packages/41/2b/bbecf7e2faa20c04bebd35fc478668953ca50ee5847ce23e08acf20ea119/ty-0.0.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6756715a3c33182e9ab8ffca2bb314d3c99b9c410b171736e145773ee0ae41c3", size = 9848819, upload-time = "2026-01-27T00:57:58.501Z" }, + { url = "https://files.pythonhosted.org/packages/be/60/3c0ba0f19c0f647ad9d2b5b5ac68c0f0b4dc899001bd53b3a7537fb247a2/ty-0.0.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89d0038a2f698ba8b6fec5cf216a4e44e2f95e4a5095a8c0f57fe549f87087c2", size = 10324371, upload-time = "2026-01-27T00:57:29.291Z" }, + { url = "https://files.pythonhosted.org/packages/24/32/99d0a0b37d0397b0a989ffc2682493286aa3bc252b24004a6714368c2c3d/ty-0.0.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c64a83a2d669b77f50a4957039ca1450626fb474619f18f6f8a3eb885bf7544", size = 10865898, upload-time = "2026-01-27T00:57:33.542Z" }, + { url = "https://files.pythonhosted.org/packages/1a/88/30b583a9e0311bb474269cfa91db53350557ebec09002bfc3fb3fc364e8c/ty-0.0.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:242488bfb547ef080199f6fd81369ab9cb638a778bb161511d091ffd49c12129", size = 10555777, upload-time = "2026-01-27T00:58:05.853Z" }, + { url = "https://files.pythonhosted.org/packages/cd/a2/cb53fb6325dcf3d40f2b1d0457a25d55bfbae633c8e337bde8ec01a190eb/ty-0.0.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4790c3866f6c83a4f424fc7d09ebdb225c1f1131647ba8bdc6fcdc28f09ed0ff", size = 10412913, upload-time = "2026-01-27T00:57:38.834Z" }, + { url = "https://files.pythonhosted.org/packages/42/8f/f2f5202d725ed1e6a4e5ffaa32b190a1fe70c0b1a2503d38515da4130b4c/ty-0.0.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:950f320437f96d4ea9a2332bbfb5b68f1c1acd269ebfa4c09b6970cc1565bd9d", size = 9837608, upload-time = "2026-01-27T00:57:55.898Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ba/59a2a0521640c489dafa2c546ae1f8465f92956fede18660653cce73b4c5/ty-0.0.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4a0ec3ee70d83887f86925bbc1c56f4628bd58a0f47f6f32ddfe04e1f05466df", size = 9884324, upload-time = "2026-01-27T00:57:46.786Z" }, + { url = "https://files.pythonhosted.org/packages/03/95/8d2a49880f47b638743212f011088552ecc454dd7a665ddcbdabea25772a/ty-0.0.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1a4e6b6da0c58b34415955279eff754d6206b35af56a18bb70eb519d8d139ef", size = 10033537, upload-time = "2026-01-27T00:58:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/e9/40/4523b36f2ce69f92ccf783855a9e0ebbbd0f0bb5cdce6211ee1737159ed3/ty-0.0.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dc04384e874c5de4c5d743369c277c8aa73d1edea3c7fc646b2064b637db4db3", size = 10495910, upload-time = "2026-01-27T00:57:26.691Z" }, + { url = "https://files.pythonhosted.org/packages/08/d5/655beb51224d1bfd4f9ddc0bb209659bfe71ff141bcf05c418ab670698f0/ty-0.0.14-py3-none-win32.whl", hash = "sha256:b20e22cf54c66b3e37e87377635da412d9a552c9bf4ad9fc449fed8b2e19dad2", size = 9507626, upload-time = "2026-01-27T00:57:41.43Z" }, + { url = "https://files.pythonhosted.org/packages/b6/d9/c569c9961760e20e0a4bc008eeb1415754564304fd53997a371b7cf3f864/ty-0.0.14-py3-none-win_amd64.whl", hash = "sha256:e312ff9475522d1a33186657fe74d1ec98e4a13e016d66f5758a452c90ff6409", size = 10437980, upload-time = "2026-01-27T00:57:36.422Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/186829654f5bfd9a028f6648e9caeb11271960a61de97484627d24443f91/ty-0.0.14-py3-none-win_arm64.whl", hash = "sha256:b6facdbe9b740cb2c15293a1d178e22ffc600653646452632541d01c36d5e378", size = 9885831, upload-time = "2026-01-27T00:57:49.747Z" }, ] [[package]] From 5961eecd5ffb8c04724ad6ebf857029330c48179 Mon Sep 17 00:00:00 2001 From: "mqt-app[bot]" <219534693+mqt-app[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 00:04:49 +0100 Subject: [PATCH 058/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20`munich-q?= =?UTF-8?q?uantum-toolkit/core`=20(#924)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request updates the [munich-quantum-toolkit/core](https://github.com/munich-quantum-toolkit/core) dependency from munich-quantum-toolkit/core@6bcc01e7d135058c6439c64fdd5f14b65ab88816 (version v3.4.0) to munich-quantum-toolkit/core@8747a89766dfb943d62ed100d383cd1823d2356c (version v3.4.1). **Full Changelog**: https://github.com/munich-quantum-toolkit/core/compare/6bcc01e7d135058c6439c64fdd5f14b65ab88816...8747a89766dfb943d62ed100d383cd1823d2356c --------- Co-authored-by: mqt-app[bot] <219534693+mqt-app[bot]@users.noreply.github.com> Co-authored-by: Daniel Haag <121057143+denialhaag@users.noreply.github.com> --- .pre-commit-config.yaml | 5 +- CHANGELOG.md | 3 + bindings/qmap_patterns.txt | 3 - noxfile.py | 3 - pyproject.toml | 12 +- python/mqt/qmap/na/state_preparation.pyi | 2 +- uv.lock | 148 +++++++++++------------ 7 files changed, 87 insertions(+), 89 deletions(-) delete mode 100644 bindings/qmap_patterns.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ebfe2d49..fbcd455c6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -50,8 +50,8 @@ repos: - id: disallow-caps name: Disallow improper capitalization language: pygrep - entry: Nanobind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum - exclude: .pre-commit-config.yaml + entry: \b(Nanobind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum)\b + exclude: ^(\.pre-commit-config\.yaml)$ priority: 0 ## Check for spelling @@ -161,4 +161,5 @@ repos: require_serial: true types_or: [python, pyi, jupyter] exclude: ^(docs/|eval/) + pass_filenames: false priority: 3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 422cf83ed..95662c144 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#unreleased)._ ### Changed +- ⬆️ Update `mqt-core` to version 3.4.1 ([#924]) ([**@denialhaag**]) +- ⬆️ Update `nanobind` to version 2.11.0 ([#924]) ([**@denialhaag**]) - 🔧 Replace `mypy` with `ty` ([#912]) ([**@denialhaag**]) - ♻️ Migrate Python bindings from `pybind11` to `nanobind` ([#911], [#916]) ([**@denialhaag**]) - 📦️ Provide Stable ABI wheels for Python 3.12+ ([#911]) ([**@denialhaag**]) @@ -188,6 +190,7 @@ _📚 Refer to the [GitHub Release Notes] for previous changelogs._ +[#924]: https://github.com/munich-quantum-toolkit/qmap/pull/924 [#916]: https://github.com/munich-quantum-toolkit/qmap/pull/916 [#912]: https://github.com/munich-quantum-toolkit/qmap/pull/912 [#911]: https://github.com/munich-quantum-toolkit/qmap/pull/911 diff --git a/bindings/qmap_patterns.txt b/bindings/qmap_patterns.txt deleted file mode 100644 index 55bcfafb2..000000000 --- a/bindings/qmap_patterns.txt +++ /dev/null @@ -1,3 +0,0 @@ -_hashable_values_: - -_unhashable_values_map_: diff --git a/noxfile.py b/noxfile.py index 5bc951abd..c4a59f26f 100755 --- a/noxfile.py +++ b/noxfile.py @@ -205,7 +205,6 @@ def stubs(session: nox.Session) -> None: ) package_root = Path(__file__).parent / "python" / "mqt" / "qmap" - pattern_file = Path(__file__).parent / "bindings" / "qmap_patterns.txt" session.run( "python", @@ -215,8 +214,6 @@ def stubs(session: nox.Session) -> None: "--include-private", "--output-dir", str(package_root), - "--pattern-file", - str(pattern_file), "--module", "mqt.qmap.na", "--module", diff --git a/pyproject.toml b/pyproject.toml index 77b2f686f..f6257bddb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,10 +8,10 @@ [build-system] requires = [ - "nanobind~=2.10.2", + "nanobind~=2.11.0", "setuptools-scm>=9.2.2", "scikit-build-core>=0.11.6", - "mqt.core==3.4.0", + "mqt.core~=3.4.1", ] build-backend = "scikit_build_core.build" @@ -51,7 +51,7 @@ classifiers = [ ] requires-python = ">=3.10, != 3.14.1" dependencies = [ - "mqt.core==3.4.0", + "mqt.core~=3.4.1", "qiskit[qasm3-import]>=1.0.0", "rustworkx[all]>=0.16.0", "typing_extensions>=4.6; python_version < '3.11'", @@ -385,10 +385,10 @@ exclude = [ [dependency-groups] build = [ - "nanobind~=2.10.2", + "nanobind~=2.11.0", "setuptools-scm>=9.2.2", "scikit-build-core>=0.11.6", - "mqt.core==3.4.0", + "mqt.core~=3.4.1", ] docs = [ "distinctipy>=1.3.4", @@ -419,7 +419,7 @@ test = [ "pytest-cov>=7.0.0", "pytest-sugar>=1.1.1", "pytest-xdist>=3.8.0", - "mqt.qcec>=3.4.0", + "mqt.qcec>=3.5.0", ] dev = [ {include-group = "build"}, diff --git a/python/mqt/qmap/na/state_preparation.pyi b/python/mqt/qmap/na/state_preparation.pyi index 40647abb4..99a9c6929 100644 --- a/python/mqt/qmap/na/state_preparation.pyi +++ b/python/mqt/qmap/na/state_preparation.pyi @@ -71,7 +71,7 @@ class NAStatePreparationSolver: num_qubits: int, num_stages: int, num_transfers: int | None = None, - mind_ops_order: bool = False, + mind_ops_order: bool | None = False, shield_idle_qubits: bool = True, ) -> NAStatePreparationSolver.Result: """Solve the neutral atom state preparation problem. diff --git a/uv.lock b/uv.lock index c472a7eab..5f539d758 100644 --- a/uv.lock +++ b/uv.lock @@ -995,7 +995,7 @@ dependencies = [ { name = "comm" }, { name = "debugpy" }, { name = "ipython", version = "8.38.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ipython", version = "9.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyter-client" }, { name = "jupyter-core" }, { name = "matplotlib-inline" }, @@ -1038,7 +1038,7 @@ wheels = [ [[package]] name = "ipython" -version = "9.9.0" +version = "9.10.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -1067,9 +1067,9 @@ dependencies = [ { name = "traitlets", marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/46/dd/fb08d22ec0c27e73c8bc8f71810709870d51cadaf27b7ddd3f011236c100/ipython-9.9.0.tar.gz", hash = "sha256:48fbed1b2de5e2c7177eefa144aba7fcb82dac514f09b57e2ac9da34ddb54220", size = 4425043, upload-time = "2026-01-05T12:36:46.233Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/60/2111715ea11f39b1535bed6024b7dec7918b71e5e5d30855a5b503056b50/ipython-9.10.0.tar.gz", hash = "sha256:cd9e656be97618a0676d058134cd44e6dc7012c0e5cb36a9ce96a8c904adaf77", size = 4426526, upload-time = "2026-02-02T10:00:33.594Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/92/162cfaee4ccf370465c5af1ce36a9eacec1becb552f2033bb3584e6f640a/ipython-9.9.0-py3-none-any.whl", hash = "sha256:b457fe9165df2b84e8ec909a97abcf2ed88f565970efba16b1f7229c283d252b", size = 621431, upload-time = "2026-01-05T12:36:44.669Z" }, + { url = "https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl", hash = "sha256:c6ab68cc23bba8c7e18e9b932797014cc61ea7fd6f19de180ab9ba73e65ee58d", size = 622774, upload-time = "2026-02-02T10:00:31.503Z" }, ] [[package]] @@ -1091,7 +1091,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "comm" }, { name = "ipython", version = "8.38.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ipython", version = "9.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyterlab-widgets" }, { name = "traitlets" }, { name = "widgetsnbextension" }, @@ -1572,39 +1572,39 @@ wheels = [ [[package]] name = "mqt-core" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/6d/c3b4f17a8e695d715379ad298d0e51790ad7e2a60f0f68f1c08703ca8beb/mqt_core-3.4.0.tar.gz", hash = "sha256:daa752050e1001cb72e7cc1fd0c0aeff8a526aefae29e414b26920739a4aa681", size = 633636, upload-time = "2026-01-08T22:08:41.588Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/9b/960d498f34f88df402a7b76a18eec8113c86f8c233eba7313a9e1530dff6/mqt_core-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c58e5d223d2f59ff9146970b8a5202e07718dd3ce2191291469b347019ced674", size = 5114257, upload-time = "2026-01-08T22:08:01.23Z" }, - { url = "https://files.pythonhosted.org/packages/b7/f0/8bbf1160a26f99799556a73a150873522ccb824cc45f3e9fdac44ecbd6a2/mqt_core-3.4.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30176b938ae76544cf70be31cdddbf2de8c83d8035af7f39ce11d5dd46c77b4c", size = 5547616, upload-time = "2026-01-08T22:08:03.399Z" }, - { url = "https://files.pythonhosted.org/packages/c7/78/19b0395b9568dc2d76056a998516adeed3775f98750a7a9bd988851be194/mqt_core-3.4.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:59fcd0711f49517c612946225c3b588448f8e0683f2a7aca596e7bc0eb48ed03", size = 6572454, upload-time = "2026-01-08T22:08:06.308Z" }, - { url = "https://files.pythonhosted.org/packages/c4/08/ae8859715f9eb6c16b707064fc0ea1171f3bc7804175b642b85571e4ef01/mqt_core-3.4.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bd27347bfd1310e4496c4f79a72076bb2638425968efd0724a3a2cbf0025b9b", size = 6991090, upload-time = "2026-01-08T22:08:08.201Z" }, - { url = "https://files.pythonhosted.org/packages/68/7a/4e413df061c1fa788205abeaff27ec5f40cb786403145fc505bc5a1b8d47/mqt_core-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:e49fd8f7b9ef12e4ebeed98a4bf8347559e938a0caec2f0b952e8a760cc4c60b", size = 3972046, upload-time = "2026-01-08T22:08:10.118Z" }, - { url = "https://files.pythonhosted.org/packages/eb/d7/8b5b7cd47df3bd1191bc58ce78dee23f0b6ac594e499121a984643ea9b55/mqt_core-3.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:e1edc694f169b0f7b2a79b397efa6268349cddf94cbc396586c2cd68457bacfa", size = 3973622, upload-time = "2026-01-08T22:08:11.665Z" }, - { url = "https://files.pythonhosted.org/packages/40/16/4a82f02632d4cc22070490399f37f5a0019d0e669c9c0f610283e0a54b29/mqt_core-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:33cf21ad638892fa2fc6913840dca1e50cc531776c7f6b2fdb3cee0bad6004f1", size = 5115319, upload-time = "2026-01-08T22:08:13.483Z" }, - { url = "https://files.pythonhosted.org/packages/60/d9/3bdb720b99764a7ab3da8f103ccdb5d20cc069c893503d11f018716b7d06/mqt_core-3.4.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:226eab23b0b53a0018a435001a5d34b362bed8f7659939155e3ec58042b333d4", size = 5548833, upload-time = "2026-01-08T22:08:15.518Z" }, - { url = "https://files.pythonhosted.org/packages/90/df/e3b6ef95b7181c9455689325da68e5befb7faa1f01cc19106435909ee9a6/mqt_core-3.4.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:31846c555f23b9f7a710f9a70fc1882bd63d3bd19430488912f543debc4e646a", size = 6573090, upload-time = "2026-01-08T22:08:16.992Z" }, - { url = "https://files.pythonhosted.org/packages/e1/2e/484b9d559263301412bb7da49b5939b15fcef27f3c6c7a743f61ed2fbeb2/mqt_core-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10d2c477c74fc873d442df27434586011d4749a159cb388bb49daf4f89ac4ca5", size = 6991703, upload-time = "2026-01-08T22:08:18.806Z" }, - { url = "https://files.pythonhosted.org/packages/fc/67/4b7929ff1c8d7c127fd2aac0d2d51580a8c177d066d6b7288bedfdaea03e/mqt_core-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d759f38cf09dfdd822f170262b395b76bdd4da2144dc5fd8a4a1d8346f5c0cc2", size = 3972643, upload-time = "2026-01-08T22:08:20.2Z" }, - { url = "https://files.pythonhosted.org/packages/d8/e4/2640e3ae0e1eab43aaf0fca2fc4fdcd098059cf1f86b9b6ddd7a3044c72a/mqt_core-3.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:ba9f687a96f6e42fd019e6098a7e54867d0173727613fbce92a893dd1f8f6950", size = 3974154, upload-time = "2026-01-08T22:08:21.596Z" }, - { url = "https://files.pythonhosted.org/packages/e1/86/0973049ec3f15ae9e47bb3a5d0222110c26ef86da336932575403fe63f77/mqt_core-3.4.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:df2d6cb96de949d90d5051dd8c85354cce308207d655ee2365c92f5adcea135d", size = 5111559, upload-time = "2026-01-08T22:08:23.068Z" }, - { url = "https://files.pythonhosted.org/packages/23/da/eabcece4479a59753ab51a9a259146419d5cb2a7547de7f7fde7214c5900/mqt_core-3.4.0-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:bad7520308ea3dc528305b5e0610bc2053b67a6c7526a69bf69bda62551c4ef9", size = 5545608, upload-time = "2026-01-08T22:08:24.578Z" }, - { url = "https://files.pythonhosted.org/packages/6e/28/39d9bf7563c48a1bb77fc1f489cc757e92fe25dffd931c909ff31dfcecaa/mqt_core-3.4.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f86da5c06dd16e90ecfed2e328e655153e0cf336a6bb75effa74071a85d16f2f", size = 6559438, upload-time = "2026-01-08T22:08:26.058Z" }, - { url = "https://files.pythonhosted.org/packages/ff/a4/c61d64b69d5801d4cd4da23bb20042828e78d4ce9274f13032a5ca838981/mqt_core-3.4.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0b37033ac2a1e8325257d649f7014ccbbe516a2004541008cfca18f89124ff4", size = 6975946, upload-time = "2026-01-08T22:08:27.679Z" }, - { url = "https://files.pythonhosted.org/packages/a3/47/aa597c38630ddcfed4482f381bb7970c3186fe189fdd6463d2171c55554d/mqt_core-3.4.0-cp312-abi3-win_amd64.whl", hash = "sha256:3c67121831eb9a6a82fb857148220d792463893063a6145f347a73d208d2b63c", size = 3965527, upload-time = "2026-01-08T22:08:29.246Z" }, - { url = "https://files.pythonhosted.org/packages/d7/3f/b5970789acb4ac81efbf584c0e71341c61fec6a1fba8a37dffd8fdc6c37e/mqt_core-3.4.0-cp312-abi3-win_arm64.whl", hash = "sha256:dcd597ff11027bdccecb243b9bf9055e7a8bc5f92af51349bd9a3051f6bd3c89", size = 3967823, upload-time = "2026-01-08T22:08:30.593Z" }, - { url = "https://files.pythonhosted.org/packages/84/e5/5f7c5e760446ee0f820425de983c3f3476a5c6ab2fd8909f19941f808895/mqt_core-3.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:545b8fe227d07d9c7c80868392dc9bb5c8902734809c3dafc565fd684dd785b2", size = 5125079, upload-time = "2026-01-08T22:08:32.107Z" }, - { url = "https://files.pythonhosted.org/packages/8a/fb/bafce65cbb74013df50b8c841bcefda9ab436965f7f7257c3c90c69c0b90/mqt_core-3.4.0-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:3068fadbf7512d11f9ecb18e1e1785658657cd7b00759f1bfc67948d4af311fc", size = 5560107, upload-time = "2026-01-08T22:08:33.759Z" }, - { url = "https://files.pythonhosted.org/packages/90/a7/736986cfdc0ebe3a74f2c732156484a6349a02dc389e0b6f7e997dcfbdee/mqt_core-3.4.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8dbf325a30580cf2951774b3ab7fa539b7272a5a173ba25b98c753aac4faff66", size = 6584391, upload-time = "2026-01-08T22:08:35.16Z" }, - { url = "https://files.pythonhosted.org/packages/fc/9b/d16f996c915b23d8a58d74433dc1fbee55dbe0b40515c4a8e70a3c7f64f7/mqt_core-3.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:485a5133698c70c02430170bab46b88d24dd4188d6c63ebb3c91bdd3ccd7f782", size = 7000710, upload-time = "2026-01-08T22:08:36.735Z" }, - { url = "https://files.pythonhosted.org/packages/b6/38/232705301ea975356e06bed18e152424b5f48919961aa862275627689b1c/mqt_core-3.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2f51451a78b8fd4cb55c4a4d9b23f97c806305e699d313178fa3c8b9952fe558", size = 4061549, upload-time = "2026-01-08T22:08:38.884Z" }, - { url = "https://files.pythonhosted.org/packages/24/61/2b6e1ce9f3747d8cd336ff73a084ac1b5771111889467de214dbca3af8c0/mqt_core-3.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e6f1765f3569a533af790fbaee2c7a21a0a4b34611ff914b17a6c4dfdea08120", size = 4048399, upload-time = "2026-01-08T22:08:40.279Z" }, +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/93/41d0e19ab9513b3cc5d78042dfd4e87baefe8a11235e6cd86ff08e8ddd33/mqt_core-3.4.1.tar.gz", hash = "sha256:e2b884b22bf70aa092d8c1fb436065814e4e5763b8be8b9c28a669a6db7470f2", size = 642056, upload-time = "2026-02-01T23:08:03.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/35/a6496972cd5bf67eced88e322965af080035e241598cffd8904c7d58ff2a/mqt_core-3.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4ada4d2e4de64de1faa8d688fc4be994f17dc94ec66b9386aa6c04fbeb843f9", size = 5150994, upload-time = "2026-02-01T23:07:19.6Z" }, + { url = "https://files.pythonhosted.org/packages/57/39/fb58967f72f07e8f3119735a622cc169a17f2faa03bb7bf614cc575304ec/mqt_core-3.4.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5175b3360cc432da7258fb237c6d7efd1fb5bc4347ac5421e0c8d564abe4d738", size = 5594907, upload-time = "2026-02-01T23:07:21.7Z" }, + { url = "https://files.pythonhosted.org/packages/b8/1c/bd4c71af62d0e95fbff54e51ad4dadc2ac30be7a0c02ff607a90c64ec400/mqt_core-3.4.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb8efb3beef48abcf34340d3277a1aa3c10a4c4f3b55cc8c4bc3e2dfbd78c475", size = 6626517, upload-time = "2026-02-01T23:07:23.682Z" }, + { url = "https://files.pythonhosted.org/packages/a3/7b/1f225942f93718de6acf3e5fa0e9f9e9b441453aa7307b605e2512aaea7b/mqt_core-3.4.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4967845b5840ba212a1843e36d720daa5fb23e4e3f4c3d3315a1893fe0d170c7", size = 7041138, upload-time = "2026-02-01T23:07:25.855Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/b873bad165c42cd31f51b8a61c2d81d352eb43c420eb69000e519c1a3181/mqt_core-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:a9cd021ac2a97f4eeb60627f3f8710caefe8b31a7791f2ec76ad3cd80636646b", size = 4009303, upload-time = "2026-02-01T23:07:27.369Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c4/3afbef57b4a3e06af7e4e3dc68f10807c6c1b75794922efc8df9088de8f5/mqt_core-3.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:ca7ea0fdf29741e284d3829a6b83875025438334cc7e2d4a6e05cfb844e85cbe", size = 7886204, upload-time = "2026-02-01T23:07:29.525Z" }, + { url = "https://files.pythonhosted.org/packages/18/db/8cc62343413f14bb9e5675397e2514d4d62b6e452319ecb34509450a7e9c/mqt_core-3.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9001bf4584ba0d71a6fdf8d011aa93236d30f048e4b9315bb1e4c06f5ae6f436", size = 5152023, upload-time = "2026-02-01T23:07:31.465Z" }, + { url = "https://files.pythonhosted.org/packages/21/c4/bbfe6a7dd634f3aa2027c3096aaa9233a26d4f23b4bcf987e0f96b5bbaa0/mqt_core-3.4.1-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:61afb495647ace780c55fead97d6432e2f9e4b3d1bd79ea274ff4216a5e7ddfe", size = 5596017, upload-time = "2026-02-01T23:07:32.843Z" }, + { url = "https://files.pythonhosted.org/packages/54/4e/1d19240b39daa9c8f6833eac99ccd6eb3829c10580fdbeab2dca7aea03ed/mqt_core-3.4.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7abd596323fae9905bf58f8f9b65734fca478d640b3e890b19f5cb13036d25c2", size = 6627235, upload-time = "2026-02-01T23:07:35.279Z" }, + { url = "https://files.pythonhosted.org/packages/11/3f/1572d27b596f7324d77de83a26b20d76becd6e8721f8892b9815d1e636b1/mqt_core-3.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:172b8f8ac5132a83df2f1c86961ac74f70f08b5e75229408a182b5b7d2d06cba", size = 7042001, upload-time = "2026-02-01T23:07:36.776Z" }, + { url = "https://files.pythonhosted.org/packages/c4/0a/5ff32fc02b232061630ead78501d30eb703c7edaf719498a5e4f8d397cac/mqt_core-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:76d74fb2fc29b79906294d725a8a7a146706c75ee027624156626ba8521110df", size = 4009854, upload-time = "2026-02-01T23:07:38.304Z" }, + { url = "https://files.pythonhosted.org/packages/af/4a/3cc50bc7f99a41e27a00416a714380106d715af3dad54218f13e1c872a44/mqt_core-3.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:f00e808ca00c40478c007567e7c5dea09bd967f01fb29a47de32b754a59e010e", size = 7886737, upload-time = "2026-02-01T23:07:40.478Z" }, + { url = "https://files.pythonhosted.org/packages/e1/d1/7295a941a0e650abdf3004d8a37e0588b6350c1ce52cb2989d1fccde09b6/mqt_core-3.4.1-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:2124d4fe5722dc5505012acb420de1b0807a3a77150f596926ffe9466994f0e8", size = 5148117, upload-time = "2026-02-01T23:07:42.289Z" }, + { url = "https://files.pythonhosted.org/packages/d4/36/f4dd6632ed75998a29e94dac473806131b3db4abb273c30bc7d99f219986/mqt_core-3.4.1-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:f33dec256d2d21a67f8596187823a1d652e667ebe3ce5135ede8bae97beeb53c", size = 5592616, upload-time = "2026-02-01T23:07:44.285Z" }, + { url = "https://files.pythonhosted.org/packages/d7/16/51ad37c8a5475dc4a9976b392de3d76ad215c60b76f38a2e1029e6a7a80f/mqt_core-3.4.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a9e2bb2e1f23a517229c60ee98ce87efb9e23c265b858caf9d19c3a90c602c4", size = 6612527, upload-time = "2026-02-01T23:07:46.969Z" }, + { url = "https://files.pythonhosted.org/packages/fd/99/36057925a8f140a543da77aa18616780bd8ae6719d5e4f15cb356061ea45/mqt_core-3.4.1-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0a9b88ef737ba1368d7adab82cdea450a4fac6e720646917acbef1b1dab55973", size = 7025048, upload-time = "2026-02-01T23:07:48.866Z" }, + { url = "https://files.pythonhosted.org/packages/44/de/2b12dde1e0e0e9d3776aa2c077be1da9c84d7c4c3c01029b0856c70fd695/mqt_core-3.4.1-cp312-abi3-win_amd64.whl", hash = "sha256:8b5f1cfa130ad70afb272f72927145635abf944bb4a4a6f5f6a9272d57932a2b", size = 4002828, upload-time = "2026-02-01T23:07:50.493Z" }, + { url = "https://files.pythonhosted.org/packages/b9/be/3e2c2589a95b489219ba44e41c45b692d3ed6162d0d39de0e0960f6d6483/mqt_core-3.4.1-cp312-abi3-win_arm64.whl", hash = "sha256:b05649c59db929a3f3738d9e5c0c36d68391877e64cf36c0cefd1ff76cfc068b", size = 7879599, upload-time = "2026-02-01T23:07:52.638Z" }, + { url = "https://files.pythonhosted.org/packages/1b/36/90b9770bf4b3a707df6bbd10f11d6921468ca5eef006dd7a0f5062dc07e8/mqt_core-3.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d96213ba934dd68bc704cca2b92c3a7321383c65e6c1c0250ef06c296d629c8b", size = 5160556, upload-time = "2026-02-01T23:07:54.106Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a3/1ac26fbc86b2f4a057c10edaa8c39568cb2ea40df873fc4c914f1d4b8626/mqt_core-3.4.1-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:40c07a6c08b3f3d7118b1358b4b60f2f7ca1e4e682d5923676fa033ed97af709", size = 5606238, upload-time = "2026-02-01T23:07:55.784Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e8/f4d6279cc17dc077e37138593f1ebdd1f5d4fe32839ff1b5b8e951205a51/mqt_core-3.4.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2615a8ff7ab9b04a5932c4dbe3925bae298315c552d53055cfdd6340089ffd77", size = 6632093, upload-time = "2026-02-01T23:07:57.184Z" }, + { url = "https://files.pythonhosted.org/packages/bc/2b/0b08bbb14e7d7017fc234ff2cd39498d7ec86132198ba09dd8e10f6dbf0c/mqt_core-3.4.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:704f26d9962dd37daf57c31135d262bb4bdbd85500a5637868639ab30e427815", size = 7041688, upload-time = "2026-02-01T23:07:58.693Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f1/fe583d3963a6dadf03a3fabb9d77524ef6c9d8a3cea81c65df39eca574bd/mqt_core-3.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:7531c56c4b357a401082e2693444db1411cc3b44898740551ee834fb1aec278b", size = 4095376, upload-time = "2026-02-01T23:08:00.219Z" }, + { url = "https://files.pythonhosted.org/packages/94/81/dc748367df3a0184d714684d128c9457fad5004afdc2aab6d79119808cb7/mqt_core-3.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:f33549a3445fe5d14d35ec579bf1ca3c75cda6fadddd1321f9ff2be166207014", size = 7958959, upload-time = "2026-02-01T23:08:01.755Z" }, ] [[package]] name = "mqt-qcec" -version = "3.4.0" +version = "3.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mqt-core" }, @@ -1612,32 +1612,32 @@ dependencies = [ { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/37/7a/5e31dce537e8fa84e135a1b06be0284350f940c4b201026486187d936c4a/mqt_qcec-3.4.0.tar.gz", hash = "sha256:c377adfa58ae5b0ad391fe7d6dca9f77f80d030a54059f804f91075f3be89d88", size = 270579, upload-time = "2026-01-13T00:00:19.214Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/50/457df1f9e85a0a2db3daf3cf995c8dd68c8e25b7a888744b8d175b80ca63/mqt_qcec-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d91955a0416ea1da079d92a7e0a48450ba131e97f6fff48e070b499f10314d85", size = 219757, upload-time = "2026-01-12T23:59:42.811Z" }, - { url = "https://files.pythonhosted.org/packages/a8/dc/6748f4e4dbe1193d7c3f940ecc367e1c369dff150174423c75eaa1d69a84/mqt_qcec-3.4.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:9c45fa5b2aaeb642feffd3e24c26d521c8048bf8d54b36e56b1e74828c7b52b1", size = 230690, upload-time = "2026-01-12T23:59:44.861Z" }, - { url = "https://files.pythonhosted.org/packages/a2/3e/52fa68814db3dbfc881dbe4307f2548c88d4d0c82f80edcaba2927c896fd/mqt_qcec-3.4.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df569179281c246fb575e138fb600789119244827bece5c5cc8243960b6de4b3", size = 232121, upload-time = "2026-01-12T23:59:46.835Z" }, - { url = "https://files.pythonhosted.org/packages/aa/24/62adb9f2c2eae43151f0e53c537251b7fe34cc73dcb29ec9f4115e56e1c9/mqt_qcec-3.4.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeb4cb0e84a53cca6b220dbc5fcafd2ed6566810b0a318bf614410ac130c292", size = 243521, upload-time = "2026-01-12T23:59:48.346Z" }, - { url = "https://files.pythonhosted.org/packages/08/5d/4cf39c229f2c97715560132ccff24e93250d8bbf0d13cd88ba85acf8a677/mqt_qcec-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:595f4bb5f45542bd881bff57c8294903dc01aca2268495aed12129418de39ed2", size = 442535, upload-time = "2026-01-12T23:59:50.021Z" }, - { url = "https://files.pythonhosted.org/packages/0c/2a/3e7f3ecfcc2977b6ad7da3bbc5fb9e456cb09758306002fb962a5cb02d51/mqt_qcec-3.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:4592d96b4945a48f3f954786f1524a7ce7914d7abc92347f3dc618ba75e93277", size = 604229, upload-time = "2026-01-12T23:59:51.828Z" }, - { url = "https://files.pythonhosted.org/packages/f1/d8/6029ae5438390764e18d9b26438baf464a9c110159567d177af2ad5e9dde/mqt_qcec-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:335b7eee0ffc189f5d26c2821f25adcb282740d3e58d4b269906790a7a0cd813", size = 220276, upload-time = "2026-01-12T23:59:53.38Z" }, - { url = "https://files.pythonhosted.org/packages/09/78/b2abede13c32db207826e216a36a2255412b1b67153f69f7346f95a748ef/mqt_qcec-3.4.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:8d31efda94061dabaab9c6e62801785f062fd21ff49d848dced6dbe546293796", size = 231156, upload-time = "2026-01-12T23:59:54.694Z" }, - { url = "https://files.pythonhosted.org/packages/44/0e/48b9b53118e04b156c234c61c385edfeda9910af1f2bed7e6ffae5b87399/mqt_qcec-3.4.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e214a4065283bd08abe9a15080ff1f00cd5e0a3de29596def5d2b5a568816485", size = 232771, upload-time = "2026-01-12T23:59:55.876Z" }, - { url = "https://files.pythonhosted.org/packages/8f/46/8e524a1fd0849a29f2698870384da62941b7c9c79ddb39595f5f424f9e03/mqt_qcec-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b2a91e0028124a8948ee032370e10f3cd9c3c636700f9be1d8d3d1a19c5f0f4a", size = 244215, upload-time = "2026-01-12T23:59:57.371Z" }, - { url = "https://files.pythonhosted.org/packages/4d/0f/4ad73f21a27bbb1abd219999f58793ac4c1f196058faa1e5c8aa63116119/mqt_qcec-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:e8bc94ed705dabf45617559186ff0dc30c9bf9269bedce419d9bffe6b8317fe0", size = 442657, upload-time = "2026-01-12T23:59:58.881Z" }, - { url = "https://files.pythonhosted.org/packages/ed/dc/b2519af45241c8e895f09c686391b03fb1b80ef5148845e7fbe840c3bca8/mqt_qcec-3.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:19369e646ebe5aa5c442ac661d220f68ac4345d74f454d7a9305d3059b30047d", size = 604437, upload-time = "2026-01-13T00:00:00.371Z" }, - { url = "https://files.pythonhosted.org/packages/db/01/d9ce094ad0ca806764be18949625f2f2ab83a7e4eef015485defd790c91c/mqt_qcec-3.4.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:26cfee5ff8598f8e3f6109cae9bf188a142121c08a8e8e936a79035ec2b3c3b1", size = 218244, upload-time = "2026-01-13T00:00:01.932Z" }, - { url = "https://files.pythonhosted.org/packages/65/a0/0006ff22ef4a6798723e70cc5713aeb6ed131855e370ba22ff9d76f3c85f/mqt_qcec-3.4.0-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:8d7586aaebfce3b33a944a9b4cb8245e647a8402f42d361acfd874ccd866df5a", size = 229054, upload-time = "2026-01-13T00:00:03.485Z" }, - { url = "https://files.pythonhosted.org/packages/50/60/f672f83fa405408d70dadd3bc3f6e8cfb222cf3be8a94ddeaa35d199a882/mqt_qcec-3.4.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13369cbec8a97df45287abdb2c5e2aedfa3489c1546aa9d687117ba7c8e9bafd", size = 230128, upload-time = "2026-01-13T00:00:04.934Z" }, - { url = "https://files.pythonhosted.org/packages/c1/71/699b36807dbac841fdff1a0a006dff772684727f310e98df7bcf5943e884/mqt_qcec-3.4.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18fd8a82b21140eedca59ba0f0d7be6ade22dd23be1fb9805ce083eed02b89be", size = 241548, upload-time = "2026-01-13T00:00:06.388Z" }, - { url = "https://files.pythonhosted.org/packages/e7/24/41078231012e94334941b0ead0aad997edbd5f6f6bd073c1c25aaa2dda48/mqt_qcec-3.4.0-cp312-abi3-win_amd64.whl", hash = "sha256:a470e9a36abb81bdc0cecae4611f2b3a829e2cb2f4d9f00f2764e5eac8900baa", size = 439875, upload-time = "2026-01-13T00:00:07.633Z" }, - { url = "https://files.pythonhosted.org/packages/1d/24/01c16a947da77e838ef7795cb1c6cbd0b8b69a5d7a268a36c4a16fdae6e0/mqt_qcec-3.4.0-cp312-abi3-win_arm64.whl", hash = "sha256:aad9029b83b7af24b71ca7ca2c22b1434329d800e97d3042b457db5c5a5b190d", size = 601346, upload-time = "2026-01-13T00:00:09.042Z" }, - { url = "https://files.pythonhosted.org/packages/82/4f/aa17b65b71b2a0b1a2fccec6846a79b84f5db11800b6d77c93a1bee8d657/mqt_qcec-3.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ac40f4e64ee3afea8ca24bc5a492dab620c913a932c4f5b4e18091e3bb9d432", size = 222588, upload-time = "2026-01-13T00:00:10.308Z" }, - { url = "https://files.pythonhosted.org/packages/6a/0e/1add710c71abdf22be358e1355bae85f27877b42df6e67817d0a83c5e4c5/mqt_qcec-3.4.0-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:b969f52876c04356291d4d4f89c9952cd5588f040c24ba6dd591adb5e33cfb5f", size = 233742, upload-time = "2026-01-13T00:00:11.483Z" }, - { url = "https://files.pythonhosted.org/packages/b0/72/cbf82e7bcd07140a88a38adbad7f26c6999f86884716ee87f48f688fec0d/mqt_qcec-3.4.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c3e729e9568445d6d96d5caabb547f2c3786f86bfdb73741d446ea9c06a1fd", size = 232923, upload-time = "2026-01-13T00:00:12.866Z" }, - { url = "https://files.pythonhosted.org/packages/a6/aa/0904ec5fe67a640b0e89bc6f3109565ff877d3f06fd0d35965443b43554f/mqt_qcec-3.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b83542637cb7f34be54db8add598730f4489aa3ef735e4fca5f17a414e79f845", size = 243746, upload-time = "2026-01-13T00:00:14.405Z" }, - { url = "https://files.pythonhosted.org/packages/e1/90/1d03528f51d75d58fe1b91370aa98797503652e620edb2e91a3f5244b41c/mqt_qcec-3.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3e6c8d4b86aac472d1594cc99687a716478bab50c1f183c77bfe447abbc1a389", size = 460307, upload-time = "2026-01-13T00:00:16.109Z" }, - { url = "https://files.pythonhosted.org/packages/6f/18/f1859794bb410e3f44572318b58486cb0d329c9ba9f208f5397e383f4e4f/mqt_qcec-3.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:85332159c6bb7a9a595eef7a8cf0a84b39fd7103eb469e49aff31b4f6b293b91", size = 626193, upload-time = "2026-01-13T00:00:17.767Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/2b/09/a7edff1685238664b048553802dff432f9d726e1fa750a480369c702d389/mqt_qcec-3.5.0.tar.gz", hash = "sha256:700150ce6b96889a19e3081d2883790e7aa20efca7024eb6d0cd6be0331c1670", size = 284464, upload-time = "2026-02-02T17:44:07.223Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/64/b34d40297890b216d6280452b9dbda36d859334c694d72e220b6997a4bc7/mqt_qcec-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eaf086f78b7034ccbc014c73c9a94936700223b022f433ec314e43415274ba1f", size = 222725, upload-time = "2026-02-02T17:43:22.612Z" }, + { url = "https://files.pythonhosted.org/packages/56/b4/70dea5a26ab5127446dafb5ea82de96b5c1239f46e307e7a68ed4f7d24c7/mqt_qcec-3.5.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:9b5680c0926b56a705988a4be8a5161837c3d284f0fa463bff3a20e6c9a11cf3", size = 235513, upload-time = "2026-02-02T17:43:26.357Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4e/c2c47c2b4fd98d9e7cf40017f20e383a93f68d3c82c0d7a90e44b9b9c64d/mqt_qcec-3.5.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79628f5c732d3df963d2d778d66bfedce58ee3147e61cc2db70a9df338a2f90a", size = 238097, upload-time = "2026-02-02T17:43:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e6/1cd7ae242cd9bbf5e4abc2763f5f62333ee1e929e8deb41bb9d0846ea938/mqt_qcec-3.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ab2c220a26bdb0d7387b93f0323d36bbfd027ebc7e1376af03d0cff418028cc", size = 248602, upload-time = "2026-02-02T17:43:31.621Z" }, + { url = "https://files.pythonhosted.org/packages/83/47/a495a056d75b8ffdd665079eb16f38f7b87f2440f2a99d17ae8df0ad1d56/mqt_qcec-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:dc598cb99814698e5aa1ed464a233cacd316c4a746f530da78c38d265186ff22", size = 447893, upload-time = "2026-02-02T17:43:33.457Z" }, + { url = "https://files.pythonhosted.org/packages/7c/b0/0efddb52482011a20a44b3cd660441d0f195719417142dedb382dba85fff/mqt_qcec-3.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:436e0cf6314f5a1717d3f9798e9e6e8013d7917610ee7ffd9b27dcfc7f96dbc8", size = 610102, upload-time = "2026-02-02T17:43:35.511Z" }, + { url = "https://files.pythonhosted.org/packages/3b/53/edd4512d19d5e3eaf812a2c5eaa12e338730f38abb211ecc303a91e9b65c/mqt_qcec-3.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5685fadf5bdd6e96dbb35b5978579e80d0af39d6bf91822685b4101a5bad882", size = 223148, upload-time = "2026-02-02T17:43:37.892Z" }, + { url = "https://files.pythonhosted.org/packages/d6/0b/c4a6d90a10de7259f931685c3a155f6c6b211a6338c1d040dd901a88b31a/mqt_qcec-3.5.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:4184847eac148f393899dcbb20a16bc9613e3f640a18d7923e69aa771210bea1", size = 236144, upload-time = "2026-02-02T17:43:39.057Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ff/abc280dc52e0052108fd8ff44523adfb497a6491f28e039df7cb8f3ac2bb/mqt_qcec-3.5.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c75972994345059a6472f1a6af6e0c6131e70745453ed441ef39f3c8dfb40ce", size = 239055, upload-time = "2026-02-02T17:43:40.254Z" }, + { url = "https://files.pythonhosted.org/packages/71/11/0915fbd3ef13b62a6d50ff98a91370fc45547e3f88d462ef40a60320429f/mqt_qcec-3.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae7554ab523c18b1d39c3bfdb0cac40b6fd21daa366dc09b343c560b1b203226", size = 249795, upload-time = "2026-02-02T17:43:42.481Z" }, + { url = "https://files.pythonhosted.org/packages/11/ae/4d8418074c42666fc2f81c8e3460f80509a6480925447c68223fe5bfa5b7/mqt_qcec-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:47d3ce7f5d7267a03310bb6ef84a874989683c2ee2edc463738b0ec074423cd1", size = 447932, upload-time = "2026-02-02T17:43:43.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/77/52d3ac96a4b5a55227dbb54048880296587fffd418c6be3f4600e7c294e4/mqt_qcec-3.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:346b63d588a755426c9fa9c0a547c40780ad4728245f4dc90cc1af2919c977aa", size = 610377, upload-time = "2026-02-02T17:43:45.56Z" }, + { url = "https://files.pythonhosted.org/packages/e2/44/17e56c3e5cdb62eba5dadc11d0431f1474016e7c126750a046bb0c0d2cb1/mqt_qcec-3.5.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:0ff3d8fba6ec7b607fb5242a908d09cf5e03be396f61a3d7d3126f08194ade1b", size = 221196, upload-time = "2026-02-02T17:43:46.854Z" }, + { url = "https://files.pythonhosted.org/packages/29/9a/7f20a6239bb5ad82a9086d5bdda679bbcf89936f79c13e0e31925b081b21/mqt_qcec-3.5.0-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:2535dd492aca63435583d63fedce92c444fa2147bbf30fcbd65cd30c87cd8053", size = 234058, upload-time = "2026-02-02T17:43:48.048Z" }, + { url = "https://files.pythonhosted.org/packages/29/a6/a4629f61ccd4487b0e017a2f29f94ae7eb65b1294d988975f2470dcc9920/mqt_qcec-3.5.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:864b9bc529b7ae6ac16fda710cf9176f767568647465be6d282d5840fe80a127", size = 235161, upload-time = "2026-02-02T17:43:49.244Z" }, + { url = "https://files.pythonhosted.org/packages/3a/73/b7e29bfae67002f9bbe59b284014da86731c349d703b7ed2f557fe16c99d/mqt_qcec-3.5.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:473df3b4a659a12f638abde91432a48c4d0244f863981ba0260ad45da5ef6c13", size = 245990, upload-time = "2026-02-02T17:43:50.511Z" }, + { url = "https://files.pythonhosted.org/packages/84/73/855bdbe827ce8d2631125d896be4f850a2aa30899a963e3e4133164ebfb6/mqt_qcec-3.5.0-cp312-abi3-win_amd64.whl", hash = "sha256:72d32f2dabe2cda53c45377a4cfea24de4be801058d87d5e8410643654aaf0eb", size = 445464, upload-time = "2026-02-02T17:43:51.961Z" }, + { url = "https://files.pythonhosted.org/packages/2d/86/7928488953355217114f8c43f1871c8a68e6915ad3bd7194c621ddf4f5c3/mqt_qcec-3.5.0-cp312-abi3-win_arm64.whl", hash = "sha256:4261a969585ee3a5e3db558ffc86a98c47291c620086ff61084df59c3e4a1ae2", size = 607673, upload-time = "2026-02-02T17:43:53.946Z" }, + { url = "https://files.pythonhosted.org/packages/51/37/41b643851a2319604dd416bd64bf9e686ec624f3922b73293d7d42a0c54c/mqt_qcec-3.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0cc641947b33276a0f8357d34be6f2b8e1048691667d1cd4c144eb565c8953a8", size = 224843, upload-time = "2026-02-02T17:43:56.094Z" }, + { url = "https://files.pythonhosted.org/packages/05/1c/f9d5a03073e14b768361e7640f0db0ccd53c9b4407c9e2b3a36e9042837f/mqt_qcec-3.5.0-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:462730f83962562c94f17eedacee78f9fdd060ffd672745a5759bca116742fcb", size = 238475, upload-time = "2026-02-02T17:43:57.324Z" }, + { url = "https://files.pythonhosted.org/packages/ba/5b/8a59f3868b2d1a13d42bfdd19a1d80bd020c8cd8e1b8c641a7ffe94820d1/mqt_qcec-3.5.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:387c2a6ce27ba28513516c67ddbaca63ddc22d4fa87fdfa77b2bdca584d6c1c0", size = 238625, upload-time = "2026-02-02T17:43:58.596Z" }, + { url = "https://files.pythonhosted.org/packages/fa/66/3ef7d078ef137b61006adcb2e35b52d97644ad185b91aa2e80c4f00a12f5/mqt_qcec-3.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:465156fc8c7921bbb7eb7b6a30dfa5fe04deb72da641a65aed42c76e412a7049", size = 249591, upload-time = "2026-02-02T17:44:00.864Z" }, + { url = "https://files.pythonhosted.org/packages/d8/d2/32ada8e9b0a8fdc665d8b1bb947b01e7b78a945aeba00958fbe5165d0c9e/mqt_qcec-3.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bfff9cb4e044382b0789b97f9d4292633f1733f8fff2b5a030ffd781a5a56c1f", size = 465636, upload-time = "2026-02-02T17:44:03.41Z" }, + { url = "https://files.pythonhosted.org/packages/35/7e/0c27bf2615986a9d821d0cbe95bbd0956ad6de0a5d3b4bd7d36d3a9b8698/mqt_qcec-3.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:d95facd11e299607205887ae0a7c8d93523fe188bf611e7d7bce9b04420d4d63", size = 631582, upload-time = "2026-02-02T17:44:05.247Z" }, ] [[package]] @@ -1726,7 +1726,7 @@ test = [ requires-dist = [ { name = "distinctipy", marker = "extra == 'visualization'", specifier = ">=1.3.4" }, { name = "ipywidgets", marker = "extra == 'visualization'", specifier = ">=8.1.7" }, - { name = "mqt-core", specifier = "==3.4.0" }, + { name = "mqt-core", specifier = "~=3.4.1" }, { name = "networkx", marker = "extra == 'visualization'", specifier = ">=3.2.1" }, { name = "plotly", marker = "extra == 'visualization'", specifier = ">=6.0.1" }, { name = "qiskit", extras = ["qasm3-import"], specifier = ">=1.0.0" }, @@ -1738,17 +1738,17 @@ provides-extras = ["visualization"] [package.metadata.requires-dev] build = [ - { name = "mqt-core", specifier = "==3.4.0" }, - { name = "nanobind", specifier = "~=2.10.2" }, + { name = "mqt-core", specifier = "~=3.4.1" }, + { name = "nanobind", specifier = "~=2.11.0" }, { name = "scikit-build-core", specifier = ">=0.11.6" }, { name = "setuptools-scm", specifier = ">=9.2.2" }, ] dev = [ { name = "distinctipy", specifier = ">=1.3.4" }, { name = "ipywidgets", specifier = ">=8.1.7" }, - { name = "mqt-core", specifier = "==3.4.0" }, - { name = "mqt-qcec", specifier = ">=3.4.0" }, - { name = "nanobind", specifier = "~=2.10.2" }, + { name = "mqt-core", specifier = "~=3.4.1" }, + { name = "mqt-qcec", specifier = ">=3.5.0" }, + { name = "nanobind", specifier = "~=2.11.0" }, { name = "networkx", specifier = ">=3.2.1" }, { name = "nox", specifier = ">=2025.11.12" }, { name = "plotly", specifier = ">=6.0.1" }, @@ -1783,7 +1783,7 @@ docs = [ test = [ { name = "distinctipy", specifier = ">=1.3.4" }, { name = "ipywidgets", specifier = ">=8.1.7" }, - { name = "mqt-qcec", specifier = ">=3.4.0" }, + { name = "mqt-qcec", specifier = ">=3.5.0" }, { name = "networkx", specifier = ">=3.2.1" }, { name = "plotly", specifier = ">=6.0.1" }, { name = "pytest", specifier = ">=9.0.1" }, @@ -1801,7 +1801,7 @@ dependencies = [ { name = "importlib-metadata" }, { name = "ipykernel" }, { name = "ipython", version = "8.38.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ipython", version = "9.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyter-cache" }, { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "myst-parser", version = "5.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -1872,20 +1872,20 @@ wheels = [ [[package]] name = "nanobind" -version = "2.10.2" +version = "2.11.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d1/7b/818fe4f6d1fdd516a14386ba86f2cbbac1b7304930da0f029724e9001658/nanobind-2.10.2.tar.gz", hash = "sha256:08509910ce6d1fadeed69cb0880d4d4fcb77739c6af9bd8fb4419391a3ca4c6b", size = 993651, upload-time = "2025-12-10T10:55:32.335Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/d6/2d17c0a630fabc05785c0ea57a994bb165b342416bec8e41c96f3fee5add/nanobind-2.11.0.tar.gz", hash = "sha256:6d98d063c61dbbd05a2d903e59be398bfcff9d59c54fbbc9d4488960485d40d0", size = 1001251, upload-time = "2026-01-29T11:24:34.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/06/cb08965f985a5e1b9cb55ed96337c1f6daaa6b9cbdaeabe6bb3f7a1a11df/nanobind-2.10.2-py3-none-any.whl", hash = "sha256:6976c1b04b90481d2612b346485a3063818c6faa5077fe9d8bbc9b5fbe29c380", size = 246514, upload-time = "2025-12-10T10:55:30.741Z" }, + { url = "https://files.pythonhosted.org/packages/e8/1c/37ae5b9a0d13defd8e27222e4cbfb82e569dbfd12d16ba8c78cab593e56c/nanobind-2.11.0-py3-none-any.whl", hash = "sha256:8097442c3e55d011a67f016ce1d9567ed9e3cdb3ad6749f13a76dbbc2721f0ee", size = 248913, upload-time = "2026-01-29T11:24:32.651Z" }, ] [[package]] name = "narwhals" -version = "2.15.0" +version = "2.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/47/6d/b57c64e5038a8cf071bce391bb11551657a74558877ac961e7fa905ece27/narwhals-2.15.0.tar.gz", hash = "sha256:a9585975b99d95084268445a1fdd881311fa26ef1caa18020d959d5b2ff9a965", size = 603479, upload-time = "2026-01-06T08:10:13.27Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/6f/713be67779028d482c6e0f2dde5bc430021b2578a4808c1c9f6d7ad48257/narwhals-2.16.0.tar.gz", hash = "sha256:155bb45132b370941ba0396d123cf9ed192bf25f39c4cea726f2da422ca4e145", size = 618268, upload-time = "2026-02-02T10:31:00.545Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/2e/cf2ffeb386ac3763526151163ad7da9f1b586aac96d2b4f7de1eaebf0c61/narwhals-2.15.0-py3-none-any.whl", hash = "sha256:cbfe21ca19d260d9fd67f995ec75c44592d1f106933b03ddd375df7ac841f9d6", size = 432856, upload-time = "2026-01-06T08:10:11.511Z" }, + { url = "https://files.pythonhosted.org/packages/03/cc/7cb74758e6df95e0c4e1253f203b6dd7f348bf2f29cf89e9210a2416d535/narwhals-2.16.0-py3-none-any.whl", hash = "sha256:846f1fd7093ac69d63526e50732033e86c30ea0026a44d9b23991010c7d1485d", size = 443951, upload-time = "2026-02-02T10:30:58.635Z" }, ] [[package]] From 7ab6b3bd47c40991894f059346a6c89ea4693f39 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 02:28:24 +0000 Subject: [PATCH 059/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=AA=9D=20Update?= =?UTF-8?q?=20pre-commit=20hook=20astral-sh/ruff-pre-commit=20to=20v0.15.0?= =?UTF-8?q?=20(#929)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [astral-sh/ruff-pre-commit](https://redirect.github.com/astral-sh/ruff-pre-commit) | repository | minor | `v0.14.14` → `v0.15.0` | Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://redirect.github.com/renovatebot/renovate/discussions/new) if you have any questions. --- ### Release Notes
astral-sh/ruff-pre-commit (astral-sh/ruff-pre-commit) ### [`v0.15.0`](https://redirect.github.com/astral-sh/ruff-pre-commit/releases/tag/v0.15.0) [Compare Source](https://redirect.github.com/astral-sh/ruff-pre-commit/compare/v0.14.14...v0.15.0) See:
--- ### Configuration 📅 **Schedule**: Branch creation - "every weekend" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fbcd455c6..e4d4f5980 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -132,7 +132,7 @@ repos: ## Python linting using ruff - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.14 + rev: v0.15.0 hooks: - id: ruff-format priority: 1 From 5b539577f2b3a8ae0f752a4b70a0864712906b10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 02:30:33 +0000 Subject: [PATCH 060/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=90=8D=20Update?= =?UTF-8?q?=20dependency=20ty=20to=20v0.0.15=20(#927)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [ty](https://redirect.github.com/astral-sh/ty) ([changelog](https://redirect.github.com/astral-sh/ty/blob/main/CHANGELOG.md)) | `==0.0.14` → `==0.0.15` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/ty/0.0.15?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ty/0.0.14/0.0.15?slim=true) | --- ### Release Notes
astral-sh/ty (ty) ### [`v0.0.15`](https://redirect.github.com/astral-sh/ty/blob/HEAD/CHANGELOG.md#0015) [Compare Source](https://redirect.github.com/astral-sh/ty/compare/0.0.14...0.0.15) Released on 2026-02-04. ##### Bug fixes - Add support for resolving imports of packages installed into Debian/Ubuntu `dist-packages` directories ([#​22466](https://redirect.github.com/astral-sh/ruff/pull/22466)) - Avoid `not-iterable` false positives when iterating over an instance of an intersection type with only negated elements ([#​22089](https://redirect.github.com/astral-sh/ruff/pull/22089)) - Fix support for stringized annotations in very large files ([#​22913](https://redirect.github.com/astral-sh/ruff/pull/22913)) - Don't emit Liskov diagnostics for methods with mangled names ([#​23062](https://redirect.github.com/astral-sh/ruff/pull/23062)) - Enforce that a `Final` symbol cannot be reassigned even after a conditional binding ([#​22986](https://redirect.github.com/astral-sh/ruff/pull/22986)) - Fix TypedDict construction from existing TypedDict values ([#​22904](https://redirect.github.com/astral-sh/ruff/pull/22904)) - Fix `Self` resolution for classes nested within methods ([#​22964](https://redirect.github.com/astral-sh/ruff/pull/22964)) - Fix bidirectional inference with PEP 695 union type aliases ([#​22988](https://redirect.github.com/astral-sh/ruff/pull/22988)) - Fix edge-case bugs when narrowing tagged unions in `match` statements ([#​22870](https://redirect.github.com/astral-sh/ruff/pull/22870)) - Fix false-positive diagnostics when iterating over an instance of an intersection that includes a TypeVar of which the upper bound is a union where the union includes a non-iterable type ([#​22117](https://redirect.github.com/astral-sh/ruff/pull/22117)) - Fix lookup of `__contains__` to respect descriptors ([#​23056](https://redirect.github.com/astral-sh/ruff/pull/23056)) - Fix narrowing of `nonlocal` variables with conditional assignments ([#​22966](https://redirect.github.com/astral-sh/ruff/pull/22966)) - Fix several bugs that could affect `NewType`s of `NewType`s of `float` ([#​22997](https://redirect.github.com/astral-sh/ruff/pull/22997)) - Fix several type narrowing bugs involving PEP-695 type aliases ([#​22894](https://redirect.github.com/astral-sh/ruff/pull/22894)) - Fix spurious query cycles in decorated functions with parameter defaults, for improved performance and improved determinism ([#​23014](https://redirect.github.com/astral-sh/ruff/pull/23014)) - Fix unary and comparison operators for TypeVars with union bounds ([#​22925](https://redirect.github.com/astral-sh/ruff/pull/22925)) - Understand functions as method descriptors even if they are decorated with a decorator annotated as returning a PEP-695 alias to a `Callable` type ([#​22902](https://redirect.github.com/astral-sh/ruff/pull/22902)) - `dataclass_transform`: Fix visibility of field specifiers when models are nested inside methods ([#​23069](https://redirect.github.com/astral-sh/ruff/pull/23069)) ##### LSP server - Fix hover showing `Unknown` for bare `Final` instance attributes ([#​23003](https://redirect.github.com/astral-sh/ruff/pull/23003)) - Improve support for goto-type, goto-declaration, hover, and highlighting of string annotations ([#​22878](https://redirect.github.com/astral-sh/ruff/pull/22878)) - Include setters and deleters when renaming properties ([#​22999](https://redirect.github.com/astral-sh/ruff/pull/22999)) - Show type qualifiers like `Final` in on-hover hints ([#​23005](https://redirect.github.com/astral-sh/ruff/pull/23005)) ##### Configuration - Add new `unused-type-ignore-comment` rule ([#​22790](https://redirect.github.com/astral-sh/ruff/pull/22790)) - Add a mechanism to ignore/warn/select all rules ([#​22832](https://redirect.github.com/astral-sh/ruff/pull/22832)) - Support multiple workspace folders in a single ty LSP server instance ([#​22953](https://redirect.github.com/astral-sh/ruff/pull/22953)) - Only add `./src` as a search path if `./src/__init__.py(i)` does not exist ([#​22851](https://redirect.github.com/astral-sh/ruff/pull/22851)) ##### Type checking - Add a diagnostic detecting if a variable is declared as `Final` but never has any bindings ([#​23001](https://redirect.github.com/astral-sh/ruff/pull/23001)) - Add a diagnostic detecting overridden comparison dunder methods on `order=True` dataclasses ([#​22689](https://redirect.github.com/astral-sh/ruff/pull/22689)) - Add a hint to `invalid-argument-type` and `invalid-assignment` diagnostics if a variable is annotated with a type from the `numbers` module ([#​22931](https://redirect.github.com/astral-sh/ruff/pull/22931), [#​22938](https://redirect.github.com/astral-sh/ruff/pull/22938)) - Add diagnostic hint on `unresolved-reference` to suggest using "list" instead of "List" ([#​22827](https://redirect.github.com/astral-sh/ruff/pull/22827)) - Add new diagnostic for invalid dataclass field orders ([#​19825](https://redirect.github.com/astral-sh/ruff/pull/19825)) - Allow a subclass method with a positional-only parameter to override a superclass method without that parameter if the parameter in the subclass method has a default value ([#​23037](https://redirect.github.com/astral-sh/ruff/pull/23037)) - Allow self-referential imports outside the global scope ([#​22963](https://redirect.github.com/astral-sh/ruff/pull/22963)) - Ban `...` in odd places inside tuple specializations ([#​22889](https://redirect.github.com/astral-sh/ruff/pull/22889)) - Ban `Required`, `NotRequired` and `ReadOnly` in parameter annotations ([#​22888](https://redirect.github.com/astral-sh/ruff/pull/22888)) - Ban legacy `TypeVar` bounds or constraints from containing type variables ([#​22949](https://redirect.github.com/astral-sh/ruff/pull/22949)) - Ban multiple unpacked variadic tuples in a `tuple` specialization ([#​22884](https://redirect.github.com/astral-sh/ruff/pull/22884)) - Detect generic `Callable`s in the return type of function signatures ([#​22954](https://redirect.github.com/astral-sh/ruff/pull/22954)) - Detect invalid `isinstance()` and `issubclass()` calls against `TypedDict` classes ([#​22887](https://redirect.github.com/astral-sh/ruff/pull/22887)) - Detect invalid `issubclass()` calls against `Protocol` classes with non-method members ([#​22896](https://redirect.github.com/astral-sh/ruff/pull/22896)) - Detect invalid attempts to subclass `Protocol[]` and `Generic[]` simultaneously ([#​22948](https://redirect.github.com/astral-sh/ruff/pull/22948)) - Emit a diagnostic on incorrect applications of the legacy convention for specifying positional-only parameters ([#​22943](https://redirect.github.com/astral-sh/ruff/pull/22943)) - Emit an error if a `TypeVarTuple` is used to subscript `Generic` or `Protocol` without being unpacked ([#​22952](https://redirect.github.com/astral-sh/ruff/pull/22952)) - Fallback to metaclass `__getattr__` or `__getattribute__` when looking up attributes on class objects ([#​22985](https://redirect.github.com/astral-sh/ruff/pull/22985)) - Fix a bug where an overridden type in a dataclass subclass would not be respected if the dataclass subclass field had a default value but the superclass field did not ([#​22965](https://redirect.github.com/astral-sh/ruff/pull/22965)) - Improve bidirectional type inference involving PEP-695 type aliases ([#​22989](https://redirect.github.com/astral-sh/ruff/pull/22989)) - Improve detection of invalid `NewType`s with generic bases ([#​22961](https://redirect.github.com/astral-sh/ruff/pull/22961)) - Improve reachability analysis when evaluating the truthiness of expressions that involve variables that may not be bound in all code paths ([#​22971](https://redirect.github.com/astral-sh/ruff/pull/22971)) - Improve the error message if `**` is used with a non-mapping in the context of a call to an overloaded function ([#​22921](https://redirect.github.com/astral-sh/ruff/pull/22921)) - Infer `ParamSpec` from class constructors for callable protocols ([#​22853](https://redirect.github.com/astral-sh/ruff/pull/22853)) - Move the location of some `invalid-overload` diagnostics ([#​22933](https://redirect.github.com/astral-sh/ruff/pull/22933)) - Point to an overload with an invalid `@final` decorator when emitting `invalid-overload` errors for invalid `@final` decorators ([#​22893](https://redirect.github.com/astral-sh/ruff/pull/22893)) - Avoid false positives when iterating over an instance of an intersection with only negated elements by preserving "pure negation" types in descriptor lookups ([#​22907](https://redirect.github.com/astral-sh/ruff/pull/22907)) - Promote `Literal` types when inferring elements for very large unannotated tuples, for improved performance ([#​22841](https://redirect.github.com/astral-sh/ruff/pull/22841)) - Recognize functions with stub bodies in `Protocol` classes as implicitly abstract ([#​22838](https://redirect.github.com/astral-sh/ruff/pull/22838)) - Reduce false positives involving heterogeneous dicts by tracking dictionary literal keys as individual places ([#​22882](https://redirect.github.com/astral-sh/ruff/pull/22882)) - Reduce false positives when subscripting classes generic over `TypeVarTuple`s ([#​22950](https://redirect.github.com/astral-sh/ruff/pull/22950)) - Remove special handling for `Any()` in `match` class patterns ([#​23011](https://redirect.github.com/astral-sh/ruff/pull/23011)) - Support `type[None]` in type expressions ([#​22892](https://redirect.github.com/astral-sh/ruff/pull/22892)) - Support legacy namespace packages declared using `pkg_resources.declare_namespace` ([#​22987](https://redirect.github.com/astral-sh/ruff/pull/22987)) - Sync vendored typeshed stubs ([#​23006](https://redirect.github.com/astral-sh/ruff/pull/23006)), [Typeshed diff](https://redirect.github.com/python/typeshed/compare/cd8b26b0ceef26cd84ab614088140d48680ac7f7...fa659b1def704dea3dc8e25c7857b23eac69df4d) - Validate signatures of dataclass `__post_init__` methods ([#​22730](https://redirect.github.com/astral-sh/ruff/pull/22730)) ##### Contributors - [@​charliermarsh](https://redirect.github.com/charliermarsh) - [@​stefanvanburen](https://redirect.github.com/stefanvanburen) - [@​ibraheemdev](https://redirect.github.com/ibraheemdev) - [@​abhijeetbodas2001](https://redirect.github.com/abhijeetbodas2001) - [@​MichaReiser](https://redirect.github.com/MichaReiser) - [@​dcreager](https://redirect.github.com/dcreager) - [@​PrettyWood](https://redirect.github.com/PrettyWood) - [@​sharkdp](https://redirect.github.com/sharkdp) - [@​oconnor663](https://redirect.github.com/oconnor663) - [@​Feiyang472](https://redirect.github.com/Feiyang472) - [@​denyszhak](https://redirect.github.com/denyszhak) - [@​mtshiba](https://redirect.github.com/mtshiba) - [@​AlexWaygood](https://redirect.github.com/AlexWaygood) - [@​11happy](https://redirect.github.com/11happy) - [@​BurntSushi](https://redirect.github.com/BurntSushi) - [@​carljm](https://redirect.github.com/carljm) - [@​Gankra](https://redirect.github.com/Gankra) - [@​MentalMegalodon](https://redirect.github.com/MentalMegalodon) - [@​thejchap](https://redirect.github.com/thejchap)
--- ### Configuration 📅 **Schedule**: Branch creation - "every weekend" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 44 ++++++++++++++++++++++---------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f6257bddb..ae5c901f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -425,5 +425,5 @@ dev = [ {include-group = "build"}, {include-group = "test"}, "nox>=2025.11.12", - "ty==0.0.14", + "ty==0.0.15", ] diff --git a/uv.lock b/uv.lock index 5f539d758..5ea31dd23 100644 --- a/uv.lock +++ b/uv.lock @@ -1758,7 +1758,7 @@ dev = [ { name = "pytest-xdist", specifier = ">=3.8.0" }, { name = "scikit-build-core", specifier = ">=0.11.6" }, { name = "setuptools-scm", specifier = ">=9.2.2" }, - { name = "ty", specifier = "==0.0.14" }, + { name = "ty", specifier = "==0.0.15" }, { name = "walkerlayout", specifier = ">=1.0.2" }, ] docs = [ @@ -2323,7 +2323,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess" }, + { name = "ptyprocess", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -3754,26 +3754,26 @@ wheels = [ [[package]] name = "ty" -version = "0.0.14" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/57/22c3d6bf95c2229120c49ffc2f0da8d9e8823755a1c3194da56e51f1cc31/ty-0.0.14.tar.gz", hash = "sha256:a691010565f59dd7f15cf324cdcd1d9065e010c77a04f887e1ea070ba34a7de2", size = 5036573, upload-time = "2026-01-27T00:57:31.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/99/cb/cc6d1d8de59beb17a41f9a614585f884ec2d95450306c173b3b7cc090d2e/ty-0.0.14-py3-none-linux_armv6l.whl", hash = "sha256:32cf2a7596e693094621d3ae568d7ee16707dce28c34d1762947874060fdddaa", size = 10034228, upload-time = "2026-01-27T00:57:53.133Z" }, - { url = "https://files.pythonhosted.org/packages/f3/96/dd42816a2075a8f31542296ae687483a8d047f86a6538dfba573223eaf9a/ty-0.0.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f971bf9805f49ce8c0968ad53e29624d80b970b9eb597b7cbaba25d8a18ce9a2", size = 9939162, upload-time = "2026-01-27T00:57:43.857Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b4/73c4859004e0f0a9eead9ecb67021438b2e8e5fdd8d03e7f5aca77623992/ty-0.0.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:45448b9e4806423523268bc15e9208c4f3f2ead7c344f615549d2e2354d6e924", size = 9418661, upload-time = "2026-01-27T00:58:03.411Z" }, - { url = "https://files.pythonhosted.org/packages/58/35/839c4551b94613db4afa20ee555dd4f33bfa7352d5da74c5fa416ffa0fd2/ty-0.0.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee94a9b747ff40114085206bdb3205a631ef19a4d3fb89e302a88754cbbae54c", size = 9837872, upload-time = "2026-01-27T00:57:23.718Z" }, - { url = "https://files.pythonhosted.org/packages/41/2b/bbecf7e2faa20c04bebd35fc478668953ca50ee5847ce23e08acf20ea119/ty-0.0.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6756715a3c33182e9ab8ffca2bb314d3c99b9c410b171736e145773ee0ae41c3", size = 9848819, upload-time = "2026-01-27T00:57:58.501Z" }, - { url = "https://files.pythonhosted.org/packages/be/60/3c0ba0f19c0f647ad9d2b5b5ac68c0f0b4dc899001bd53b3a7537fb247a2/ty-0.0.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89d0038a2f698ba8b6fec5cf216a4e44e2f95e4a5095a8c0f57fe549f87087c2", size = 10324371, upload-time = "2026-01-27T00:57:29.291Z" }, - { url = "https://files.pythonhosted.org/packages/24/32/99d0a0b37d0397b0a989ffc2682493286aa3bc252b24004a6714368c2c3d/ty-0.0.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c64a83a2d669b77f50a4957039ca1450626fb474619f18f6f8a3eb885bf7544", size = 10865898, upload-time = "2026-01-27T00:57:33.542Z" }, - { url = "https://files.pythonhosted.org/packages/1a/88/30b583a9e0311bb474269cfa91db53350557ebec09002bfc3fb3fc364e8c/ty-0.0.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:242488bfb547ef080199f6fd81369ab9cb638a778bb161511d091ffd49c12129", size = 10555777, upload-time = "2026-01-27T00:58:05.853Z" }, - { url = "https://files.pythonhosted.org/packages/cd/a2/cb53fb6325dcf3d40f2b1d0457a25d55bfbae633c8e337bde8ec01a190eb/ty-0.0.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4790c3866f6c83a4f424fc7d09ebdb225c1f1131647ba8bdc6fcdc28f09ed0ff", size = 10412913, upload-time = "2026-01-27T00:57:38.834Z" }, - { url = "https://files.pythonhosted.org/packages/42/8f/f2f5202d725ed1e6a4e5ffaa32b190a1fe70c0b1a2503d38515da4130b4c/ty-0.0.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:950f320437f96d4ea9a2332bbfb5b68f1c1acd269ebfa4c09b6970cc1565bd9d", size = 9837608, upload-time = "2026-01-27T00:57:55.898Z" }, - { url = "https://files.pythonhosted.org/packages/f7/ba/59a2a0521640c489dafa2c546ae1f8465f92956fede18660653cce73b4c5/ty-0.0.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4a0ec3ee70d83887f86925bbc1c56f4628bd58a0f47f6f32ddfe04e1f05466df", size = 9884324, upload-time = "2026-01-27T00:57:46.786Z" }, - { url = "https://files.pythonhosted.org/packages/03/95/8d2a49880f47b638743212f011088552ecc454dd7a665ddcbdabea25772a/ty-0.0.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1a4e6b6da0c58b34415955279eff754d6206b35af56a18bb70eb519d8d139ef", size = 10033537, upload-time = "2026-01-27T00:58:01.149Z" }, - { url = "https://files.pythonhosted.org/packages/e9/40/4523b36f2ce69f92ccf783855a9e0ebbbd0f0bb5cdce6211ee1737159ed3/ty-0.0.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dc04384e874c5de4c5d743369c277c8aa73d1edea3c7fc646b2064b637db4db3", size = 10495910, upload-time = "2026-01-27T00:57:26.691Z" }, - { url = "https://files.pythonhosted.org/packages/08/d5/655beb51224d1bfd4f9ddc0bb209659bfe71ff141bcf05c418ab670698f0/ty-0.0.14-py3-none-win32.whl", hash = "sha256:b20e22cf54c66b3e37e87377635da412d9a552c9bf4ad9fc449fed8b2e19dad2", size = 9507626, upload-time = "2026-01-27T00:57:41.43Z" }, - { url = "https://files.pythonhosted.org/packages/b6/d9/c569c9961760e20e0a4bc008eeb1415754564304fd53997a371b7cf3f864/ty-0.0.14-py3-none-win_amd64.whl", hash = "sha256:e312ff9475522d1a33186657fe74d1ec98e4a13e016d66f5758a452c90ff6409", size = 10437980, upload-time = "2026-01-27T00:57:36.422Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/186829654f5bfd9a028f6648e9caeb11271960a61de97484627d24443f91/ty-0.0.14-py3-none-win_arm64.whl", hash = "sha256:b6facdbe9b740cb2c15293a1d178e22ffc600653646452632541d01c36d5e378", size = 9885831, upload-time = "2026-01-27T00:57:49.747Z" }, +version = "0.0.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/25/257602d316b9333089b688a7a11b33ebc660b74e8dacf400dc3dfdea1594/ty-0.0.15.tar.gz", hash = "sha256:4f9a5b8df208c62dba56e91b93bed8b5bb714839691b8cff16d12c983bfa1174", size = 5101936, upload-time = "2026-02-05T01:06:34.922Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/c5/35626e732b79bf0e6213de9f79aff59b5f247c0a1e3ce0d93e675ab9b728/ty-0.0.15-py3-none-linux_armv6l.whl", hash = "sha256:68e092458516c61512dac541cde0a5e4e5842df00b4e81881ead8f745ddec794", size = 10138374, upload-time = "2026-02-05T01:07:03.804Z" }, + { url = "https://files.pythonhosted.org/packages/d5/8a/48fd81664604848f79d03879b3ca3633762d457a069b07e09fb1b87edd6e/ty-0.0.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:79f2e75289eae3cece94c51118b730211af4ba5762906f52a878041b67e54959", size = 9947858, upload-time = "2026-02-05T01:06:47.453Z" }, + { url = "https://files.pythonhosted.org/packages/b6/85/c1ac8e97bcd930946f4c94db85b675561d590b4e72703bf3733419fc3973/ty-0.0.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:112a7b26e63e48cc72c8c5b03227d1db280cfa57a45f2df0e264c3a016aa8c3c", size = 9443220, upload-time = "2026-02-05T01:06:44.98Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d9/244bc02599d950f7a4298fbc0c1b25cc808646b9577bdf7a83470b2d1cec/ty-0.0.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71f62a2644972975a657d9dc867bf901235cde51e8d24c20311067e7afd44a56", size = 9949976, upload-time = "2026-02-05T01:07:01.515Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ab/3a0daad66798c91a33867a3ececf17d314ac65d4ae2bbbd28cbfde94da63/ty-0.0.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e48b42be2d257317c85b78559233273b655dd636fc61e7e1d69abd90fd3cba4", size = 9965918, upload-time = "2026-02-05T01:06:54.283Z" }, + { url = "https://files.pythonhosted.org/packages/39/4e/e62b01338f653059a7c0cd09d1a326e9a9eedc351a0f0de9db0601658c3d/ty-0.0.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27dd5b52a421e6871c5bfe9841160331b60866ed2040250cb161886478ab3e4f", size = 10424943, upload-time = "2026-02-05T01:07:08.777Z" }, + { url = "https://files.pythonhosted.org/packages/65/b5/7aa06655ce69c0d4f3e845d2d85e79c12994b6d84c71699cfb437e0bc8cf/ty-0.0.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76b85c9ec2219e11c358a7db8e21b7e5c6674a1fb9b6f633836949de98d12286", size = 10964692, upload-time = "2026-02-05T01:06:37.103Z" }, + { url = "https://files.pythonhosted.org/packages/13/04/36fdfe1f3c908b471e246e37ce3d011175584c26d3853e6c5d9a0364564c/ty-0.0.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e8204c61d8ede4f21f2975dce74efdb80fafb2fae1915c666cceb33ea3c90b", size = 10692225, upload-time = "2026-02-05T01:06:49.714Z" }, + { url = "https://files.pythonhosted.org/packages/13/41/5bf882649bd8b64ded5fbce7fb8d77fb3b868de1a3b1a6c4796402b47308/ty-0.0.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af87c3be7c944bb4d6609d6c63e4594944b0028c7bd490a525a82b88fe010d6d", size = 10516776, upload-time = "2026-02-05T01:06:52.047Z" }, + { url = "https://files.pythonhosted.org/packages/56/75/66852d7e004f859839c17ffe1d16513c1e7cc04bcc810edb80ca022a9124/ty-0.0.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:50dccf7398505e5966847d366c9e4c650b8c225411c2a68c32040a63b9521eea", size = 9928828, upload-time = "2026-02-05T01:06:56.647Z" }, + { url = "https://files.pythonhosted.org/packages/65/72/96bc16c7b337a3ef358fd227b3c8ef0c77405f3bfbbfb59ee5915f0d9d71/ty-0.0.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:bd797b8f231a4f4715110259ad1ad5340a87b802307f3e06d92bfb37b858a8f3", size = 9978960, upload-time = "2026-02-05T01:06:29.567Z" }, + { url = "https://files.pythonhosted.org/packages/a0/18/d2e316a35b626de2227f832cd36d21205e4f5d96fd036a8af84c72ecec1b/ty-0.0.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9deb7f20e18b25440a9aa4884f934ba5628ef456dbde91819d5af1a73da48af3", size = 10135903, upload-time = "2026-02-05T01:06:59.256Z" }, + { url = "https://files.pythonhosted.org/packages/02/d3/b617a79c9dad10c888d7c15cd78859e0160b8772273637b9c4241a049491/ty-0.0.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7b31b3de031255b90a5f4d9cb3d050feae246067c87130e5a6861a8061c71754", size = 10615879, upload-time = "2026-02-05T01:07:06.661Z" }, + { url = "https://files.pythonhosted.org/packages/fb/b0/2652a73c71c77296a6343217063f05745da60c67b7e8a8e25f2064167fce/ty-0.0.15-py3-none-win32.whl", hash = "sha256:9362c528ceb62c89d65c216336d28d500bc9f4c10418413f63ebc16886e16cc1", size = 9578058, upload-time = "2026-02-05T01:06:42.928Z" }, + { url = "https://files.pythonhosted.org/packages/84/6e/08a4aedebd2a6ce2784b5bc3760e43d1861f1a184734a78215c2d397c1df/ty-0.0.15-py3-none-win_amd64.whl", hash = "sha256:4db040695ae67c5524f59cb8179a8fa277112e69042d7dfdac862caa7e3b0d9c", size = 10457112, upload-time = "2026-02-05T01:06:39.885Z" }, + { url = "https://files.pythonhosted.org/packages/b3/be/1991f2bc12847ae2d4f1e3ac5dcff8bb7bc1261390645c0755bb55616355/ty-0.0.15-py3-none-win_arm64.whl", hash = "sha256:e5a98d4119e77d6136461e16ae505f8f8069002874ab073de03fbcb1a5e8bf25", size = 9937490, upload-time = "2026-02-05T01:06:32.388Z" }, ] [[package]] From 93ec9732092aea99e5efe0a74cbb3607be43b7e7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Feb 2026 11:43:43 +0100 Subject: [PATCH 061/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=AA=9D=20Update?= =?UTF-8?q?=20pre-commit=20hook=20astral-sh/uv-pre-commit=20to=20v0.10.0?= =?UTF-8?q?=20(#930)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e4d4f5980..0fff5f84b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -78,7 +78,7 @@ repos: ## Ensure uv lock file is up-to-date - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.28 + rev: 0.10.0 hooks: - id: uv-lock priority: 0 From 18b3c2051f887481b5e7eef04c3ca511a665a48e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 02:29:14 +0000 Subject: [PATCH 062/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=94=92=EF=B8=8F?= =?UTF-8?q?=20Lock=20file=20maintenance=20(#931)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Update | Change | |---|---| | lockFileMaintenance | All locks refreshed | 🔧 This Pull Request updates lock files to use the latest dependency versions. --- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- uv.lock | 218 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 109 insertions(+), 109 deletions(-) diff --git a/uv.lock b/uv.lock index 5ea31dd23..ba8d75898 100644 --- a/uv.lock +++ b/uv.lock @@ -85,7 +85,7 @@ wheels = [ [[package]] name = "astroid" -version = "4.0.3" +version = "4.0.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -98,9 +98,9 @@ resolution-markers = [ "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/ca/c17d0f83016532a1ad87d1de96837164c99d47a3b6bbba28bd597c25b37a/astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3", size = 406224, upload-time = "2026-01-03T22:14:26.096Z" } +sdist = { url = "https://files.pythonhosted.org/packages/07/63/0adf26577da5eff6eb7a177876c1cfa213856be9926a000f65c4add9692b/astroid-4.0.4.tar.gz", hash = "sha256:986fed8bcf79fb82c78b18a53352a0b287a73817d6dbcfba3162da36667c49a0", size = 406358, upload-time = "2026-02-07T23:35:07.509Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/66/686ac4fc6ef48f5bacde625adac698f41d5316a9753c2b20bb0931c9d4e2/astroid-4.0.3-py3-none-any.whl", hash = "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14", size = 276443, upload-time = "2026-01-03T22:14:24.412Z" }, + { url = "https://files.pythonhosted.org/packages/b0/cf/1c5f42b110e57bc5502eb80dbc3b03d256926062519224835ef08134f1f9/astroid-4.0.4-py3-none-any.whl", hash = "sha256:52f39653876c7dec3e3afd4c2696920e05c83832b9737afc21928f2d2eb7a753", size = 276445, upload-time = "2026-02-07T23:35:05.344Z" }, ] [[package]] @@ -533,101 +533,101 @@ wheels = [ [[package]] name = "coverage" -version = "7.13.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ad/49/349848445b0e53660e258acbcc9b0d014895b6739237920886672240f84b/coverage-7.13.2.tar.gz", hash = "sha256:044c6951ec37146b72a50cc81ef02217d27d4c3640efd2640311393cbbf143d3", size = 826523, upload-time = "2026-01-25T13:00:04.889Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/2d/63e37369c8e81a643afe54f76073b020f7b97ddbe698c5c944b51b0a2bc5/coverage-7.13.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4af3b01763909f477ea17c962e2cca8f39b350a4e46e3a30838b2c12e31b81b", size = 218842, upload-time = "2026-01-25T12:57:15.3Z" }, - { url = "https://files.pythonhosted.org/packages/57/06/86ce882a8d58cbcb3030e298788988e618da35420d16a8c66dac34f138d0/coverage-7.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:36393bd2841fa0b59498f75466ee9bdec4f770d3254f031f23e8fd8e140ffdd2", size = 219360, upload-time = "2026-01-25T12:57:17.572Z" }, - { url = "https://files.pythonhosted.org/packages/cd/84/70b0eb1ee19ca4ef559c559054c59e5b2ae4ec9af61398670189e5d276e9/coverage-7.13.2-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9cc7573518b7e2186bd229b1a0fe24a807273798832c27032c4510f47ffdb896", size = 246123, upload-time = "2026-01-25T12:57:19.087Z" }, - { url = "https://files.pythonhosted.org/packages/35/fb/05b9830c2e8275ebc031e0019387cda99113e62bb500ab328bb72578183b/coverage-7.13.2-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ca9566769b69a5e216a4e176d54b9df88f29d750c5b78dbb899e379b4e14b30c", size = 247930, upload-time = "2026-01-25T12:57:20.929Z" }, - { url = "https://files.pythonhosted.org/packages/81/aa/3f37858ca2eed4f09b10ca3c6ddc9041be0a475626cd7fd2712f4a2d526f/coverage-7.13.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c9bdea644e94fd66d75a6f7e9a97bb822371e1fe7eadae2cacd50fcbc28e4dc", size = 249804, upload-time = "2026-01-25T12:57:22.904Z" }, - { url = "https://files.pythonhosted.org/packages/b6/b3/c904f40c56e60a2d9678a5ee8df3d906d297d15fb8bec5756c3b0a67e2df/coverage-7.13.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5bd447332ec4f45838c1ad42268ce21ca87c40deb86eabd59888859b66be22a5", size = 246815, upload-time = "2026-01-25T12:57:24.314Z" }, - { url = "https://files.pythonhosted.org/packages/41/91/ddc1c5394ca7fd086342486440bfdd6b9e9bda512bf774599c7c7a0081e0/coverage-7.13.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7c79ad5c28a16a1277e1187cf83ea8dafdcc689a784228a7d390f19776db7c31", size = 247843, upload-time = "2026-01-25T12:57:26.544Z" }, - { url = "https://files.pythonhosted.org/packages/87/d2/cdff8f4cd33697883c224ea8e003e9c77c0f1a837dc41d95a94dd26aad67/coverage-7.13.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:76e06ccacd1fb6ada5d076ed98a8c6f66e2e6acd3df02819e2ee29fd637b76ad", size = 245850, upload-time = "2026-01-25T12:57:28.507Z" }, - { url = "https://files.pythonhosted.org/packages/f5/42/e837febb7866bf2553ab53dd62ed52f9bb36d60c7e017c55376ad21fbb05/coverage-7.13.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:49d49e9a5e9f4dc3d3dac95278a020afa6d6bdd41f63608a76fa05a719d5b66f", size = 246116, upload-time = "2026-01-25T12:57:30.16Z" }, - { url = "https://files.pythonhosted.org/packages/09/b1/4a3f935d7df154df02ff4f71af8d61298d713a7ba305d050ae475bfbdde2/coverage-7.13.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ed2bce0e7bfa53f7b0b01c722da289ef6ad4c18ebd52b1f93704c21f116360c8", size = 246720, upload-time = "2026-01-25T12:57:32.165Z" }, - { url = "https://files.pythonhosted.org/packages/e1/fe/538a6fd44c515f1c5197a3f078094cbaf2ce9f945df5b44e29d95c864bff/coverage-7.13.2-cp310-cp310-win32.whl", hash = "sha256:1574983178b35b9af4db4a9f7328a18a14a0a0ce76ffaa1c1bacb4cc82089a7c", size = 221465, upload-time = "2026-01-25T12:57:33.511Z" }, - { url = "https://files.pythonhosted.org/packages/5e/09/4b63a024295f326ec1a40ec8def27799300ce8775b1cbf0d33b1790605c4/coverage-7.13.2-cp310-cp310-win_amd64.whl", hash = "sha256:a360a8baeb038928ceb996f5623a4cd508728f8f13e08d4e96ce161702f3dd99", size = 222397, upload-time = "2026-01-25T12:57:34.927Z" }, - { url = "https://files.pythonhosted.org/packages/6c/01/abca50583a8975bb6e1c59eff67ed8e48bb127c07dad5c28d9e96ccc09ec/coverage-7.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:060ebf6f2c51aff5ba38e1f43a2095e087389b1c69d559fde6049a4b0001320e", size = 218971, upload-time = "2026-01-25T12:57:36.953Z" }, - { url = "https://files.pythonhosted.org/packages/eb/0e/b6489f344d99cd1e5b4d5e1be52dfd3f8a3dc5112aa6c33948da8cabad4e/coverage-7.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1ea8ca9db5e7469cd364552985e15911548ea5b69c48a17291f0cac70484b2e", size = 219473, upload-time = "2026-01-25T12:57:38.934Z" }, - { url = "https://files.pythonhosted.org/packages/17/11/db2f414915a8e4ec53f60b17956c27f21fb68fcf20f8a455ce7c2ccec638/coverage-7.13.2-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b780090d15fd58f07cf2011943e25a5f0c1c894384b13a216b6c86c8a8a7c508", size = 249896, upload-time = "2026-01-25T12:57:40.365Z" }, - { url = "https://files.pythonhosted.org/packages/80/06/0823fe93913663c017e508e8810c998c8ebd3ec2a5a85d2c3754297bdede/coverage-7.13.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:88a800258d83acb803c38175b4495d293656d5fac48659c953c18e5f539a274b", size = 251810, upload-time = "2026-01-25T12:57:42.045Z" }, - { url = "https://files.pythonhosted.org/packages/61/dc/b151c3cc41b28cdf7f0166c5fa1271cbc305a8ec0124cce4b04f74791a18/coverage-7.13.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6326e18e9a553e674d948536a04a80d850a5eeefe2aae2e6d7cf05d54046c01b", size = 253920, upload-time = "2026-01-25T12:57:44.026Z" }, - { url = "https://files.pythonhosted.org/packages/2d/35/e83de0556e54a4729a2b94ea816f74ce08732e81945024adee46851c2264/coverage-7.13.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:59562de3f797979e1ff07c587e2ac36ba60ca59d16c211eceaa579c266c5022f", size = 250025, upload-time = "2026-01-25T12:57:45.624Z" }, - { url = "https://files.pythonhosted.org/packages/39/67/af2eb9c3926ce3ea0d58a0d2516fcbdacf7a9fc9559fe63076beaf3f2596/coverage-7.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:27ba1ed6f66b0e2d61bfa78874dffd4f8c3a12f8e2b5410e515ab345ba7bc9c3", size = 251612, upload-time = "2026-01-25T12:57:47.713Z" }, - { url = "https://files.pythonhosted.org/packages/26/62/5be2e25f3d6c711d23b71296f8b44c978d4c8b4e5b26871abfc164297502/coverage-7.13.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8be48da4d47cc68754ce643ea50b3234557cbefe47c2f120495e7bd0a2756f2b", size = 249670, upload-time = "2026-01-25T12:57:49.378Z" }, - { url = "https://files.pythonhosted.org/packages/b3/51/400d1b09a8344199f9b6a6fc1868005d766b7ea95e7882e494fa862ca69c/coverage-7.13.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2a47a4223d3361b91176aedd9d4e05844ca67d7188456227b6bf5e436630c9a1", size = 249395, upload-time = "2026-01-25T12:57:50.86Z" }, - { url = "https://files.pythonhosted.org/packages/e0/36/f02234bc6e5230e2f0a63fd125d0a2093c73ef20fdf681c7af62a140e4e7/coverage-7.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c6f141b468740197d6bd38f2b26ade124363228cc3f9858bd9924ab059e00059", size = 250298, upload-time = "2026-01-25T12:57:52.287Z" }, - { url = "https://files.pythonhosted.org/packages/b0/06/713110d3dd3151b93611c9cbfc65c15b4156b44f927fced49ac0b20b32a4/coverage-7.13.2-cp311-cp311-win32.whl", hash = "sha256:89567798404af067604246e01a49ef907d112edf2b75ef814b1364d5ce267031", size = 221485, upload-time = "2026-01-25T12:57:53.876Z" }, - { url = "https://files.pythonhosted.org/packages/16/0c/3ae6255fa1ebcb7dec19c9a59e85ef5f34566d1265c70af5b2fc981da834/coverage-7.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:21dd57941804ae2ac7e921771a5e21bbf9aabec317a041d164853ad0a96ce31e", size = 222421, upload-time = "2026-01-25T12:57:55.433Z" }, - { url = "https://files.pythonhosted.org/packages/b5/37/fabc3179af4d61d89ea47bd04333fec735cd5e8b59baad44fed9fc4170d7/coverage-7.13.2-cp311-cp311-win_arm64.whl", hash = "sha256:10758e0586c134a0bafa28f2d37dd2cdb5e4a90de25c0fc0c77dabbad46eca28", size = 221088, upload-time = "2026-01-25T12:57:57.41Z" }, - { url = "https://files.pythonhosted.org/packages/46/39/e92a35f7800222d3f7b2cbb7bbc3b65672ae8d501cb31801b2d2bd7acdf1/coverage-7.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f106b2af193f965d0d3234f3f83fc35278c7fb935dfbde56ae2da3dd2c03b84d", size = 219142, upload-time = "2026-01-25T12:58:00.448Z" }, - { url = "https://files.pythonhosted.org/packages/45/7a/8bf9e9309c4c996e65c52a7c5a112707ecdd9fbaf49e10b5a705a402bbb4/coverage-7.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78f45d21dc4d5d6bd29323f0320089ef7eae16e4bef712dff79d184fa7330af3", size = 219503, upload-time = "2026-01-25T12:58:02.451Z" }, - { url = "https://files.pythonhosted.org/packages/87/93/17661e06b7b37580923f3f12406ac91d78aeed293fb6da0b69cc7957582f/coverage-7.13.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fae91dfecd816444c74531a9c3d6ded17a504767e97aa674d44f638107265b99", size = 251006, upload-time = "2026-01-25T12:58:04.059Z" }, - { url = "https://files.pythonhosted.org/packages/12/f0/f9e59fb8c310171497f379e25db060abef9fa605e09d63157eebec102676/coverage-7.13.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:264657171406c114787b441484de620e03d8f7202f113d62fcd3d9688baa3e6f", size = 253750, upload-time = "2026-01-25T12:58:05.574Z" }, - { url = "https://files.pythonhosted.org/packages/e5/b1/1935e31add2232663cf7edd8269548b122a7d100047ff93475dbaaae673e/coverage-7.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae47d8dcd3ded0155afbb59c62bd8ab07ea0fd4902e1c40567439e6db9dcaf2f", size = 254862, upload-time = "2026-01-25T12:58:07.647Z" }, - { url = "https://files.pythonhosted.org/packages/af/59/b5e97071ec13df5f45da2b3391b6cdbec78ba20757bc92580a5b3d5fa53c/coverage-7.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8a0b33e9fd838220b007ce8f299114d406c1e8edb21336af4c97a26ecfd185aa", size = 251420, upload-time = "2026-01-25T12:58:09.309Z" }, - { url = "https://files.pythonhosted.org/packages/3f/75/9495932f87469d013dc515fb0ce1aac5fa97766f38f6b1a1deb1ee7b7f3a/coverage-7.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b3becbea7f3ce9a2d4d430f223ec15888e4deb31395840a79e916368d6004cce", size = 252786, upload-time = "2026-01-25T12:58:10.909Z" }, - { url = "https://files.pythonhosted.org/packages/6a/59/af550721f0eb62f46f7b8cb7e6f1860592189267b1c411a4e3a057caacee/coverage-7.13.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f819c727a6e6eeb8711e4ce63d78c620f69630a2e9d53bc95ca5379f57b6ba94", size = 250928, upload-time = "2026-01-25T12:58:12.449Z" }, - { url = "https://files.pythonhosted.org/packages/9b/b1/21b4445709aae500be4ab43bbcfb4e53dc0811c3396dcb11bf9f23fd0226/coverage-7.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:4f7b71757a3ab19f7ba286e04c181004c1d61be921795ee8ba6970fd0ec91da5", size = 250496, upload-time = "2026-01-25T12:58:14.047Z" }, - { url = "https://files.pythonhosted.org/packages/ba/b1/0f5d89dfe0392990e4f3980adbde3eb34885bc1effb2dc369e0bf385e389/coverage-7.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b7fc50d2afd2e6b4f6f2f403b70103d280a8e0cb35320cbbe6debcda02a1030b", size = 252373, upload-time = "2026-01-25T12:58:15.976Z" }, - { url = "https://files.pythonhosted.org/packages/01/c9/0cf1a6a57a9968cc049a6b896693faa523c638a5314b1fc374eb2b2ac904/coverage-7.13.2-cp312-cp312-win32.whl", hash = "sha256:292250282cf9bcf206b543d7608bda17ca6fc151f4cbae949fc7e115112fbd41", size = 221696, upload-time = "2026-01-25T12:58:17.517Z" }, - { url = "https://files.pythonhosted.org/packages/4d/05/d7540bf983f09d32803911afed135524570f8c47bb394bf6206c1dc3a786/coverage-7.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:eeea10169fac01549a7921d27a3e517194ae254b542102267bef7a93ed38c40e", size = 222504, upload-time = "2026-01-25T12:58:19.115Z" }, - { url = "https://files.pythonhosted.org/packages/15/8b/1a9f037a736ced0a12aacf6330cdaad5008081142a7070bc58b0f7930cbc/coverage-7.13.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a5b567f0b635b592c917f96b9a9cb3dbd4c320d03f4bf94e9084e494f2e8894", size = 221120, upload-time = "2026-01-25T12:58:21.334Z" }, - { url = "https://files.pythonhosted.org/packages/a7/f0/3d3eac7568ab6096ff23791a526b0048a1ff3f49d0e236b2af6fb6558e88/coverage-7.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ed75de7d1217cf3b99365d110975f83af0528c849ef5180a12fd91b5064df9d6", size = 219168, upload-time = "2026-01-25T12:58:23.376Z" }, - { url = "https://files.pythonhosted.org/packages/a3/a6/f8b5cfeddbab95fdef4dcd682d82e5dcff7a112ced57a959f89537ee9995/coverage-7.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:97e596de8fa9bada4d88fde64a3f4d37f1b6131e4faa32bad7808abc79887ddc", size = 219537, upload-time = "2026-01-25T12:58:24.932Z" }, - { url = "https://files.pythonhosted.org/packages/7b/e6/8d8e6e0c516c838229d1e41cadcec91745f4b1031d4db17ce0043a0423b4/coverage-7.13.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:68c86173562ed4413345410c9480a8d64864ac5e54a5cda236748031e094229f", size = 250528, upload-time = "2026-01-25T12:58:26.567Z" }, - { url = "https://files.pythonhosted.org/packages/8e/78/befa6640f74092b86961f957f26504c8fba3d7da57cc2ab7407391870495/coverage-7.13.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7be4d613638d678b2b3773b8f687537b284d7074695a43fe2fbbfc0e31ceaed1", size = 253132, upload-time = "2026-01-25T12:58:28.251Z" }, - { url = "https://files.pythonhosted.org/packages/9d/10/1630db1edd8ce675124a2ee0f7becc603d2bb7b345c2387b4b95c6907094/coverage-7.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d7f63ce526a96acd0e16c4af8b50b64334239550402fb1607ce6a584a6d62ce9", size = 254374, upload-time = "2026-01-25T12:58:30.294Z" }, - { url = "https://files.pythonhosted.org/packages/ed/1d/0d9381647b1e8e6d310ac4140be9c428a0277330991e0c35bdd751e338a4/coverage-7.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:406821f37f864f968e29ac14c3fccae0fec9fdeba48327f0341decf4daf92d7c", size = 250762, upload-time = "2026-01-25T12:58:32.036Z" }, - { url = "https://files.pythonhosted.org/packages/43/e4/5636dfc9a7c871ee8776af83ee33b4c26bc508ad6cee1e89b6419a366582/coverage-7.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ee68e5a4e3e5443623406b905db447dceddffee0dceb39f4e0cd9ec2a35004b5", size = 252502, upload-time = "2026-01-25T12:58:33.961Z" }, - { url = "https://files.pythonhosted.org/packages/02/2a/7ff2884d79d420cbb2d12fed6fff727b6d0ef27253140d3cdbbd03187ee0/coverage-7.13.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2ee0e58cca0c17dd9c6c1cdde02bb705c7b3fbfa5f3b0b5afeda20d4ebff8ef4", size = 250463, upload-time = "2026-01-25T12:58:35.529Z" }, - { url = "https://files.pythonhosted.org/packages/91/c0/ba51087db645b6c7261570400fc62c89a16278763f36ba618dc8657a187b/coverage-7.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6e5bbb5018bf76a56aabdb64246b5288d5ae1b7d0dd4d0534fe86df2c2992d1c", size = 250288, upload-time = "2026-01-25T12:58:37.226Z" }, - { url = "https://files.pythonhosted.org/packages/03/07/44e6f428551c4d9faf63ebcefe49b30e5c89d1be96f6a3abd86a52da9d15/coverage-7.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a55516c68ef3e08e134e818d5e308ffa6b1337cc8b092b69b24287bf07d38e31", size = 252063, upload-time = "2026-01-25T12:58:38.821Z" }, - { url = "https://files.pythonhosted.org/packages/c2/67/35b730ad7e1859dd57e834d1bc06080d22d2f87457d53f692fce3f24a5a9/coverage-7.13.2-cp313-cp313-win32.whl", hash = "sha256:5b20211c47a8abf4abc3319d8ce2464864fa9f30c5fcaf958a3eed92f4f1fef8", size = 221716, upload-time = "2026-01-25T12:58:40.484Z" }, - { url = "https://files.pythonhosted.org/packages/0d/82/e5fcf5a97c72f45fc14829237a6550bf49d0ab882ac90e04b12a69db76b4/coverage-7.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:14f500232e521201cf031549fb1ebdfc0a40f401cf519157f76c397e586c3beb", size = 222522, upload-time = "2026-01-25T12:58:43.247Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f1/25d7b2f946d239dd2d6644ca2cc060d24f97551e2af13b6c24c722ae5f97/coverage-7.13.2-cp313-cp313-win_arm64.whl", hash = "sha256:9779310cb5a9778a60c899f075a8514c89fa6d10131445c2207fc893e0b14557", size = 221145, upload-time = "2026-01-25T12:58:45Z" }, - { url = "https://files.pythonhosted.org/packages/9e/f7/080376c029c8f76fadfe43911d0daffa0cbdc9f9418a0eead70c56fb7f4b/coverage-7.13.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e64fa5a1e41ce5df6b547cbc3d3699381c9e2c2c369c67837e716ed0f549d48e", size = 219861, upload-time = "2026-01-25T12:58:46.586Z" }, - { url = "https://files.pythonhosted.org/packages/42/11/0b5e315af5ab35f4c4a70e64d3314e4eec25eefc6dec13be3a7d5ffe8ac5/coverage-7.13.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b01899e82a04085b6561eb233fd688474f57455e8ad35cd82286463ba06332b7", size = 220207, upload-time = "2026-01-25T12:58:48.277Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0c/0874d0318fb1062117acbef06a09cf8b63f3060c22265adaad24b36306b7/coverage-7.13.2-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:838943bea48be0e2768b0cf7819544cdedc1bbb2f28427eabb6eb8c9eb2285d3", size = 261504, upload-time = "2026-01-25T12:58:49.904Z" }, - { url = "https://files.pythonhosted.org/packages/83/5e/1cd72c22ecb30751e43a72f40ba50fcef1b7e93e3ea823bd9feda8e51f9a/coverage-7.13.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:93d1d25ec2b27e90bcfef7012992d1f5121b51161b8bffcda756a816cf13c2c3", size = 263582, upload-time = "2026-01-25T12:58:51.582Z" }, - { url = "https://files.pythonhosted.org/packages/9b/da/8acf356707c7a42df4d0657020308e23e5a07397e81492640c186268497c/coverage-7.13.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93b57142f9621b0d12349c43fc7741fe578e4bc914c1e5a54142856cfc0bf421", size = 266008, upload-time = "2026-01-25T12:58:53.234Z" }, - { url = "https://files.pythonhosted.org/packages/41/41/ea1730af99960309423c6ea8d6a4f1fa5564b2d97bd1d29dda4b42611f04/coverage-7.13.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f06799ae1bdfff7ccb8665d75f8291c69110ba9585253de254688aa8a1ccc6c5", size = 260762, upload-time = "2026-01-25T12:58:55.372Z" }, - { url = "https://files.pythonhosted.org/packages/22/fa/02884d2080ba71db64fdc127b311db60e01fe6ba797d9c8363725e39f4d5/coverage-7.13.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7f9405ab4f81d490811b1d91c7a20361135a2df4c170e7f0b747a794da5b7f23", size = 263571, upload-time = "2026-01-25T12:58:57.52Z" }, - { url = "https://files.pythonhosted.org/packages/d2/6b/4083aaaeba9b3112f55ac57c2ce7001dc4d8fa3fcc228a39f09cc84ede27/coverage-7.13.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f9ab1d5b86f8fbc97a5b3cd6280a3fd85fef3b028689d8a2c00918f0d82c728c", size = 261200, upload-time = "2026-01-25T12:58:59.255Z" }, - { url = "https://files.pythonhosted.org/packages/e9/d2/aea92fa36d61955e8c416ede9cf9bf142aa196f3aea214bb67f85235a050/coverage-7.13.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:f674f59712d67e841525b99e5e2b595250e39b529c3bda14764e4f625a3fa01f", size = 260095, upload-time = "2026-01-25T12:59:01.066Z" }, - { url = "https://files.pythonhosted.org/packages/0d/ae/04ffe96a80f107ea21b22b2367175c621da920063260a1c22f9452fd7866/coverage-7.13.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c6cadac7b8ace1ba9144feb1ae3cb787a6065ba6d23ffc59a934b16406c26573", size = 262284, upload-time = "2026-01-25T12:59:02.802Z" }, - { url = "https://files.pythonhosted.org/packages/1c/7a/6f354dcd7dfc41297791d6fb4e0d618acb55810bde2c1fd14b3939e05c2b/coverage-7.13.2-cp313-cp313t-win32.whl", hash = "sha256:14ae4146465f8e6e6253eba0cccd57423e598a4cb925958b240c805300918343", size = 222389, upload-time = "2026-01-25T12:59:04.563Z" }, - { url = "https://files.pythonhosted.org/packages/8d/d5/080ad292a4a3d3daf411574be0a1f56d6dee2c4fdf6b005342be9fac807f/coverage-7.13.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9074896edd705a05769e3de0eac0a8388484b503b68863dd06d5e473f874fd47", size = 223450, upload-time = "2026-01-25T12:59:06.677Z" }, - { url = "https://files.pythonhosted.org/packages/88/96/df576fbacc522e9fb8d1c4b7a7fc62eb734be56e2cba1d88d2eabe08ea3f/coverage-7.13.2-cp313-cp313t-win_arm64.whl", hash = "sha256:69e526e14f3f854eda573d3cf40cffd29a1a91c684743d904c33dbdcd0e0f3e7", size = 221707, upload-time = "2026-01-25T12:59:08.363Z" }, - { url = "https://files.pythonhosted.org/packages/55/53/1da9e51a0775634b04fcc11eb25c002fc58ee4f92ce2e8512f94ac5fc5bf/coverage-7.13.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:387a825f43d680e7310e6f325b2167dd093bc8ffd933b83e9aa0983cf6e0a2ef", size = 219213, upload-time = "2026-01-25T12:59:11.909Z" }, - { url = "https://files.pythonhosted.org/packages/46/35/b3caac3ebbd10230fea5a33012b27d19e999a17c9285c4228b4b2e35b7da/coverage-7.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f0d7fea9d8e5d778cd5a9e8fc38308ad688f02040e883cdc13311ef2748cb40f", size = 219549, upload-time = "2026-01-25T12:59:13.638Z" }, - { url = "https://files.pythonhosted.org/packages/76/9c/e1cf7def1bdc72c1907e60703983a588f9558434a2ff94615747bd73c192/coverage-7.13.2-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e080afb413be106c95c4ee96b4fffdc9e2fa56a8bbf90b5c0918e5c4449412f5", size = 250586, upload-time = "2026-01-25T12:59:15.808Z" }, - { url = "https://files.pythonhosted.org/packages/ba/49/f54ec02ed12be66c8d8897270505759e057b0c68564a65c429ccdd1f139e/coverage-7.13.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a7fc042ba3c7ce25b8a9f097eb0f32a5ce1ccdb639d9eec114e26def98e1f8a4", size = 253093, upload-time = "2026-01-25T12:59:17.491Z" }, - { url = "https://files.pythonhosted.org/packages/fb/5e/aaf86be3e181d907e23c0f61fccaeb38de8e6f6b47aed92bf57d8fc9c034/coverage-7.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d0ba505e021557f7f8173ee8cd6b926373d8653e5ff7581ae2efce1b11ef4c27", size = 254446, upload-time = "2026-01-25T12:59:19.752Z" }, - { url = "https://files.pythonhosted.org/packages/28/c8/a5fa01460e2d75b0c853b392080d6829d3ca8b5ab31e158fa0501bc7c708/coverage-7.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7de326f80e3451bd5cc7239ab46c73ddb658fe0b7649476bc7413572d36cd548", size = 250615, upload-time = "2026-01-25T12:59:21.928Z" }, - { url = "https://files.pythonhosted.org/packages/86/0b/6d56315a55f7062bb66410732c24879ccb2ec527ab6630246de5fe45a1df/coverage-7.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:abaea04f1e7e34841d4a7b343904a3f59481f62f9df39e2cd399d69a187a9660", size = 252452, upload-time = "2026-01-25T12:59:23.592Z" }, - { url = "https://files.pythonhosted.org/packages/30/19/9bc550363ebc6b0ea121977ee44d05ecd1e8bf79018b8444f1028701c563/coverage-7.13.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9f93959ee0c604bccd8e0697be21de0887b1f73efcc3aa73a3ec0fd13feace92", size = 250418, upload-time = "2026-01-25T12:59:25.392Z" }, - { url = "https://files.pythonhosted.org/packages/1f/53/580530a31ca2f0cc6f07a8f2ab5460785b02bb11bdf815d4c4d37a4c5169/coverage-7.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:13fe81ead04e34e105bf1b3c9f9cdf32ce31736ee5d90a8d2de02b9d3e1bcb82", size = 250231, upload-time = "2026-01-25T12:59:27.888Z" }, - { url = "https://files.pythonhosted.org/packages/e2/42/dd9093f919dc3088cb472893651884bd675e3df3d38a43f9053656dca9a2/coverage-7.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d6d16b0f71120e365741bca2cb473ca6fe38930bc5431c5e850ba949f708f892", size = 251888, upload-time = "2026-01-25T12:59:29.636Z" }, - { url = "https://files.pythonhosted.org/packages/fa/a6/0af4053e6e819774626e133c3d6f70fae4d44884bfc4b126cb647baee8d3/coverage-7.13.2-cp314-cp314-win32.whl", hash = "sha256:9b2f4714bb7d99ba3790ee095b3b4ac94767e1347fe424278a0b10acb3ff04fe", size = 221968, upload-time = "2026-01-25T12:59:31.424Z" }, - { url = "https://files.pythonhosted.org/packages/c4/cc/5aff1e1f80d55862442855517bb8ad8ad3a68639441ff6287dde6a58558b/coverage-7.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:e4121a90823a063d717a96e0a0529c727fb31ea889369a0ee3ec00ed99bf6859", size = 222783, upload-time = "2026-01-25T12:59:33.118Z" }, - { url = "https://files.pythonhosted.org/packages/de/20/09abafb24f84b3292cc658728803416c15b79f9ee5e68d25238a895b07d9/coverage-7.13.2-cp314-cp314-win_arm64.whl", hash = "sha256:6873f0271b4a15a33e7590f338d823f6f66f91ed147a03938d7ce26efd04eee6", size = 221348, upload-time = "2026-01-25T12:59:34.939Z" }, - { url = "https://files.pythonhosted.org/packages/b6/60/a3820c7232db63be060e4019017cd3426751c2699dab3c62819cdbcea387/coverage-7.13.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f61d349f5b7cd95c34017f1927ee379bfbe9884300d74e07cf630ccf7a610c1b", size = 219950, upload-time = "2026-01-25T12:59:36.624Z" }, - { url = "https://files.pythonhosted.org/packages/fd/37/e4ef5975fdeb86b1e56db9a82f41b032e3d93a840ebaf4064f39e770d5c5/coverage-7.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a43d34ce714f4ca674c0d90beb760eb05aad906f2c47580ccee9da8fe8bfb417", size = 220209, upload-time = "2026-01-25T12:59:38.339Z" }, - { url = "https://files.pythonhosted.org/packages/54/df/d40e091d00c51adca1e251d3b60a8b464112efa3004949e96a74d7c19a64/coverage-7.13.2-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bff1b04cb9d4900ce5c56c4942f047dc7efe57e2608cb7c3c8936e9970ccdbee", size = 261576, upload-time = "2026-01-25T12:59:40.446Z" }, - { url = "https://files.pythonhosted.org/packages/c5/44/5259c4bed54e3392e5c176121af9f71919d96dde853386e7730e705f3520/coverage-7.13.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6ae99e4560963ad8e163e819e5d77d413d331fd00566c1e0856aa252303552c1", size = 263704, upload-time = "2026-01-25T12:59:42.346Z" }, - { url = "https://files.pythonhosted.org/packages/16/bd/ae9f005827abcbe2c70157459ae86053971c9fa14617b63903abbdce26d9/coverage-7.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e79a8c7d461820257d9aa43716c4efc55366d7b292e46b5b37165be1d377405d", size = 266109, upload-time = "2026-01-25T12:59:44.073Z" }, - { url = "https://files.pythonhosted.org/packages/a2/c0/8e279c1c0f5b1eaa3ad9b0fb7a5637fc0379ea7d85a781c0fe0bb3cfc2ab/coverage-7.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:060ee84f6a769d40c492711911a76811b4befb6fba50abb450371abb720f5bd6", size = 260686, upload-time = "2026-01-25T12:59:45.804Z" }, - { url = "https://files.pythonhosted.org/packages/b2/47/3a8112627e9d863e7cddd72894171c929e94491a597811725befdcd76bce/coverage-7.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bca209d001fd03ea2d978f8a4985093240a355c93078aee3f799852c23f561a", size = 263568, upload-time = "2026-01-25T12:59:47.929Z" }, - { url = "https://files.pythonhosted.org/packages/92/bc/7ea367d84afa3120afc3ce6de294fd2dcd33b51e2e7fbe4bbfd200f2cb8c/coverage-7.13.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:6b8092aa38d72f091db61ef83cb66076f18f02da3e1a75039a4f218629600e04", size = 261174, upload-time = "2026-01-25T12:59:49.717Z" }, - { url = "https://files.pythonhosted.org/packages/33/b7/f1092dcecb6637e31cc2db099581ee5c61a17647849bae6b8261a2b78430/coverage-7.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4a3158dc2dcce5200d91ec28cd315c999eebff355437d2765840555d765a6e5f", size = 260017, upload-time = "2026-01-25T12:59:51.463Z" }, - { url = "https://files.pythonhosted.org/packages/2b/cd/f3d07d4b95fbe1a2ef0958c15da614f7e4f557720132de34d2dc3aa7e911/coverage-7.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3973f353b2d70bd9796cc12f532a05945232ccae966456c8ed7034cb96bbfd6f", size = 262337, upload-time = "2026-01-25T12:59:53.407Z" }, - { url = "https://files.pythonhosted.org/packages/e0/db/b0d5b2873a07cb1e06a55d998697c0a5a540dcefbf353774c99eb3874513/coverage-7.13.2-cp314-cp314t-win32.whl", hash = "sha256:79f6506a678a59d4ded048dc72f1859ebede8ec2b9a2d509ebe161f01c2879d3", size = 222749, upload-time = "2026-01-25T12:59:56.316Z" }, - { url = "https://files.pythonhosted.org/packages/e5/2f/838a5394c082ac57d85f57f6aba53093b30d9089781df72412126505716f/coverage-7.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:196bfeabdccc5a020a57d5a368c681e3a6ceb0447d153aeccc1ab4d70a5032ba", size = 223857, upload-time = "2026-01-25T12:59:58.201Z" }, - { url = "https://files.pythonhosted.org/packages/44/d4/b608243e76ead3a4298824b50922b89ef793e50069ce30316a65c1b4d7ef/coverage-7.13.2-cp314-cp314t-win_arm64.whl", hash = "sha256:69269ab58783e090bfbf5b916ab3d188126e22d6070bbfc93098fdd474ef937c", size = 221881, upload-time = "2026-01-25T13:00:00.449Z" }, - { url = "https://files.pythonhosted.org/packages/d2/db/d291e30fdf7ea617a335531e72294e0c723356d7fdde8fba00610a76bda9/coverage-7.13.2-py3-none-any.whl", hash = "sha256:40ce1ea1e25125556d8e76bd0b61500839a07944cc287ac21d5626f3e620cad5", size = 210943, upload-time = "2026-01-25T13:00:02.388Z" }, +version = "7.13.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/43/3e4ac666cc35f231fa70c94e9f38459299de1a152813f9d2f60fc5f3ecaf/coverage-7.13.3.tar.gz", hash = "sha256:f7f6182d3dfb8802c1747eacbfe611b669455b69b7c037484bb1efbbb56711ac", size = 826832, upload-time = "2026-02-03T14:02:30.944Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/07/1c8099563a8a6c389a31c2d0aa1497cee86d6248bb4b9ba5e779215db9f9/coverage-7.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b4f345f7265cdbdb5ec2521ffff15fa49de6d6c39abf89fc7ad68aa9e3a55f0", size = 219143, upload-time = "2026-02-03T13:59:40.459Z" }, + { url = "https://files.pythonhosted.org/packages/69/39/a892d44af7aa092cab70e0cc5cdbba18eeccfe1d6930695dab1742eef9e9/coverage-7.13.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96c3be8bae9d0333e403cc1a8eb078a7f928b5650bae94a18fb4820cc993fb9b", size = 219663, upload-time = "2026-02-03T13:59:41.951Z" }, + { url = "https://files.pythonhosted.org/packages/9a/25/9669dcf4c2bb4c3861469e6db20e52e8c11908cf53c14ec9b12e9fd4d602/coverage-7.13.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d6f4a21328ea49d38565b55599e1c02834e76583a6953e5586d65cb1efebd8f8", size = 246424, upload-time = "2026-02-03T13:59:43.418Z" }, + { url = "https://files.pythonhosted.org/packages/f3/68/d9766c4e298aca62ea5d9543e1dd1e4e1439d7284815244d8b7db1840bfb/coverage-7.13.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fc970575799a9d17d5c3fafd83a0f6ccf5d5117cdc9ad6fbd791e9ead82418b0", size = 248228, upload-time = "2026-02-03T13:59:44.816Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e2/eea6cb4a4bd443741adf008d4cccec83a1f75401df59b6559aca2bdd9710/coverage-7.13.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:87ff33b652b3556b05e204ae20793d1f872161b0fa5ec8a9ac76f8430e152ed6", size = 250103, upload-time = "2026-02-03T13:59:46.271Z" }, + { url = "https://files.pythonhosted.org/packages/db/77/664280ecd666c2191610842177e2fab9e5dbdeef97178e2078fed46a3d2c/coverage-7.13.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7df8759ee57b9f3f7b66799b7660c282f4375bef620ade1686d6a7b03699e75f", size = 247107, upload-time = "2026-02-03T13:59:48.53Z" }, + { url = "https://files.pythonhosted.org/packages/2b/df/2a672eab99e0d0eba52d8a63e47dc92245eee26954d1b2d3c8f7d372151f/coverage-7.13.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f45c9bcb16bee25a798ccba8a2f6a1251b19de6a0d617bb365d7d2f386c4e20e", size = 248143, upload-time = "2026-02-03T13:59:50.027Z" }, + { url = "https://files.pythonhosted.org/packages/a5/dc/a104e7a87c13e57a358b8b9199a8955676e1703bb372d79722b54978ae45/coverage-7.13.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:318b2e4753cbf611061e01b6cc81477e1cdfeb69c36c4a14e6595e674caadb56", size = 246148, upload-time = "2026-02-03T13:59:52.025Z" }, + { url = "https://files.pythonhosted.org/packages/2b/89/e113d3a58dc20b03b7e59aed1e53ebc9ca6167f961876443e002b10e3ae9/coverage-7.13.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:24db3959de8ee394eeeca89ccb8ba25305c2da9a668dd44173394cbd5aa0777f", size = 246414, upload-time = "2026-02-03T13:59:53.859Z" }, + { url = "https://files.pythonhosted.org/packages/3f/60/a3fd0a6e8d89b488396019a2268b6a1f25ab56d6d18f3be50f35d77b47dc/coverage-7.13.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:be14d0622125edef21b3a4d8cd2d138c4872bf6e38adc90fd92385e3312f406a", size = 247023, upload-time = "2026-02-03T13:59:55.454Z" }, + { url = "https://files.pythonhosted.org/packages/19/fa/de4840bb939dbb22ba0648a6d8069fa91c9cf3b3fca8b0d1df461e885b3d/coverage-7.13.3-cp310-cp310-win32.whl", hash = "sha256:53be4aab8ddef18beb6188f3a3fdbf4d1af2277d098d4e618be3a8e6c88e74be", size = 221751, upload-time = "2026-02-03T13:59:57.383Z" }, + { url = "https://files.pythonhosted.org/packages/de/87/233ff8b7ef62fb63f58c78623b50bef69681111e0c4d43504f422d88cda4/coverage-7.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:bfeee64ad8b4aae3233abb77eb6b52b51b05fa89da9645518671b9939a78732b", size = 222686, upload-time = "2026-02-03T13:59:58.825Z" }, + { url = "https://files.pythonhosted.org/packages/ec/09/1ac74e37cf45f17eb41e11a21854f7f92a4c2d6c6098ef4a1becb0c6d8d3/coverage-7.13.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5907605ee20e126eeee2abe14aae137043c2c8af2fa9b38d2ab3b7a6b8137f73", size = 219276, upload-time = "2026-02-03T14:00:00.296Z" }, + { url = "https://files.pythonhosted.org/packages/2e/cb/71908b08b21beb2c437d0d5870c4ec129c570ca1b386a8427fcdb11cf89c/coverage-7.13.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a88705500988c8acad8b8fd86c2a933d3aa96bec1ddc4bc5cb256360db7bbd00", size = 219776, upload-time = "2026-02-03T14:00:02.414Z" }, + { url = "https://files.pythonhosted.org/packages/09/85/c4f3dd69232887666a2c0394d4be21c60ea934d404db068e6c96aa59cd87/coverage-7.13.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bbb5aa9016c4c29e3432e087aa29ebee3f8fda089cfbfb4e6d64bd292dcd1c2", size = 250196, upload-time = "2026-02-03T14:00:04.197Z" }, + { url = "https://files.pythonhosted.org/packages/9c/cc/560ad6f12010344d0778e268df5ba9aa990aacccc310d478bf82bf3d302c/coverage-7.13.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0c2be202a83dde768937a61cdc5d06bf9fb204048ca199d93479488e6247656c", size = 252111, upload-time = "2026-02-03T14:00:05.639Z" }, + { url = "https://files.pythonhosted.org/packages/f0/66/3193985fb2c58e91f94cfbe9e21a6fdf941e9301fe2be9e92c072e9c8f8c/coverage-7.13.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f45e32ef383ce56e0ca099b2e02fcdf7950be4b1b56afaab27b4ad790befe5b", size = 254217, upload-time = "2026-02-03T14:00:07.738Z" }, + { url = "https://files.pythonhosted.org/packages/c5/78/f0f91556bf1faa416792e537c523c5ef9db9b1d32a50572c102b3d7c45b3/coverage-7.13.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6ed2e787249b922a93cd95c671cc9f4c9797a106e81b455c83a9ddb9d34590c0", size = 250318, upload-time = "2026-02-03T14:00:09.224Z" }, + { url = "https://files.pythonhosted.org/packages/6f/aa/fc654e45e837d137b2c1f3a2cc09b4aea1e8b015acd2f774fa0f3d2ddeba/coverage-7.13.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:05dd25b21afffe545e808265897c35f32d3e4437663923e0d256d9ab5031fb14", size = 251909, upload-time = "2026-02-03T14:00:10.712Z" }, + { url = "https://files.pythonhosted.org/packages/73/4d/ab53063992add8a9ca0463c9d92cce5994a29e17affd1c2daa091b922a93/coverage-7.13.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:46d29926349b5c4f1ea4fca95e8c892835515f3600995a383fa9a923b5739ea4", size = 249971, upload-time = "2026-02-03T14:00:12.402Z" }, + { url = "https://files.pythonhosted.org/packages/29/25/83694b81e46fcff9899694a1b6f57573429cdd82b57932f09a698f03eea5/coverage-7.13.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:fae6a21537519c2af00245e834e5bf2884699cc7c1055738fd0f9dc37a3644ad", size = 249692, upload-time = "2026-02-03T14:00:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/d4/ef/d68fc304301f4cb4bf6aefa0045310520789ca38dabdfba9dbecd3f37919/coverage-7.13.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c672d4e2f0575a4ca2bf2aa0c5ced5188220ab806c1bb6d7179f70a11a017222", size = 250597, upload-time = "2026-02-03T14:00:15.461Z" }, + { url = "https://files.pythonhosted.org/packages/8d/85/240ad396f914df361d0f71e912ddcedb48130c71b88dc4193fe3c0306f00/coverage-7.13.3-cp311-cp311-win32.whl", hash = "sha256:fcda51c918c7a13ad93b5f89a58d56e3a072c9e0ba5c231b0ed81404bf2648fb", size = 221773, upload-time = "2026-02-03T14:00:17.462Z" }, + { url = "https://files.pythonhosted.org/packages/2f/71/165b3a6d3d052704a9ab52d11ea64ef3426745de517dda44d872716213a7/coverage-7.13.3-cp311-cp311-win_amd64.whl", hash = "sha256:d1a049b5c51b3b679928dd35e47c4a2235e0b6128b479a7596d0ef5b42fa6301", size = 222711, upload-time = "2026-02-03T14:00:19.449Z" }, + { url = "https://files.pythonhosted.org/packages/51/d0/0ddc9c5934cdd52639c5df1f1eb0fdab51bb52348f3a8d1c7db9c600d93a/coverage-7.13.3-cp311-cp311-win_arm64.whl", hash = "sha256:79f2670c7e772f4917895c3d89aad59e01f3dbe68a4ed2d0373b431fad1dcfba", size = 221377, upload-time = "2026-02-03T14:00:20.968Z" }, + { url = "https://files.pythonhosted.org/packages/94/44/330f8e83b143f6668778ed61d17ece9dc48459e9e74669177de02f45fec5/coverage-7.13.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ed48b4170caa2c4420e0cd27dc977caaffc7eecc317355751df8373dddcef595", size = 219441, upload-time = "2026-02-03T14:00:22.585Z" }, + { url = "https://files.pythonhosted.org/packages/08/e7/29db05693562c2e65bdf6910c0af2fd6f9325b8f43caf7a258413f369e30/coverage-7.13.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8f2adf4bcffbbec41f366f2e6dffb9d24e8172d16e91da5799c9b7ed6b5716e6", size = 219801, upload-time = "2026-02-03T14:00:24.186Z" }, + { url = "https://files.pythonhosted.org/packages/90/ae/7f8a78249b02b0818db46220795f8ac8312ea4abd1d37d79ea81db5cae81/coverage-7.13.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:01119735c690786b6966a1e9f098da4cd7ca9174c4cfe076d04e653105488395", size = 251306, upload-time = "2026-02-03T14:00:25.798Z" }, + { url = "https://files.pythonhosted.org/packages/62/71/a18a53d1808e09b2e9ebd6b47dad5e92daf4c38b0686b4c4d1b2f3e42b7f/coverage-7.13.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8bb09e83c603f152d855f666d70a71765ca8e67332e5829e62cb9466c176af23", size = 254051, upload-time = "2026-02-03T14:00:27.474Z" }, + { url = "https://files.pythonhosted.org/packages/4a/0a/eb30f6455d04c5a3396d0696cad2df0269ae7444bb322f86ffe3376f7bf9/coverage-7.13.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b607a40cba795cfac6d130220d25962931ce101f2f478a29822b19755377fb34", size = 255160, upload-time = "2026-02-03T14:00:29.024Z" }, + { url = "https://files.pythonhosted.org/packages/7b/7e/a45baac86274ce3ed842dbb84f14560c673ad30535f397d89164ec56c5df/coverage-7.13.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:44f14a62f5da2e9aedf9080e01d2cda61df39197d48e323538ec037336d68da8", size = 251709, upload-time = "2026-02-03T14:00:30.641Z" }, + { url = "https://files.pythonhosted.org/packages/c0/df/dd0dc12f30da11349993f3e218901fdf82f45ee44773596050c8f5a1fb25/coverage-7.13.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:debf29e0b157769843dff0981cc76f79e0ed04e36bb773c6cac5f6029054bd8a", size = 253083, upload-time = "2026-02-03T14:00:32.14Z" }, + { url = "https://files.pythonhosted.org/packages/ab/32/fc764c8389a8ce95cb90eb97af4c32f392ab0ac23ec57cadeefb887188d3/coverage-7.13.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:824bb95cd71604031ae9a48edb91fd6effde669522f960375668ed21b36e3ec4", size = 251227, upload-time = "2026-02-03T14:00:34.721Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ca/d025e9da8f06f24c34d2da9873957cfc5f7e0d67802c3e34d0caa8452130/coverage-7.13.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8f1010029a5b52dc427c8e2a8dbddb2303ddd180b806687d1acd1bb1d06649e7", size = 250794, upload-time = "2026-02-03T14:00:36.278Z" }, + { url = "https://files.pythonhosted.org/packages/45/c7/76bf35d5d488ec8f68682eb8e7671acc50a6d2d1c1182de1d2b6d4ffad3b/coverage-7.13.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cd5dee4fd7659d8306ffa79eeaaafd91fa30a302dac3af723b9b469e549247e0", size = 252671, upload-time = "2026-02-03T14:00:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/bf/10/1921f1a03a7c209e1cb374f81a6b9b68b03cdb3ecc3433c189bc90e2a3d5/coverage-7.13.3-cp312-cp312-win32.whl", hash = "sha256:f7f153d0184d45f3873b3ad3ad22694fd73aadcb8cdbc4337ab4b41ea6b4dff1", size = 221986, upload-time = "2026-02-03T14:00:40.442Z" }, + { url = "https://files.pythonhosted.org/packages/3c/7c/f5d93297f8e125a80c15545edc754d93e0ed8ba255b65e609b185296af01/coverage-7.13.3-cp312-cp312-win_amd64.whl", hash = "sha256:03a6e5e1e50819d6d7436f5bc40c92ded7e484e400716886ac921e35c133149d", size = 222793, upload-time = "2026-02-03T14:00:42.106Z" }, + { url = "https://files.pythonhosted.org/packages/43/59/c86b84170015b4555ebabca8649bdf9f4a1f737a73168088385ed0f947c4/coverage-7.13.3-cp312-cp312-win_arm64.whl", hash = "sha256:51c4c42c0e7d09a822b08b6cf79b3c4db8333fffde7450da946719ba0d45730f", size = 221410, upload-time = "2026-02-03T14:00:43.726Z" }, + { url = "https://files.pythonhosted.org/packages/81/f3/4c333da7b373e8c8bfb62517e8174a01dcc373d7a9083698e3b39d50d59c/coverage-7.13.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:853c3d3c79ff0db65797aad79dee6be020efd218ac4510f15a205f1e8d13ce25", size = 219468, upload-time = "2026-02-03T14:00:45.829Z" }, + { url = "https://files.pythonhosted.org/packages/d6/31/0714337b7d23630c8de2f4d56acf43c65f8728a45ed529b34410683f7217/coverage-7.13.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f75695e157c83d374f88dcc646a60cb94173304a9258b2e74ba5a66b7614a51a", size = 219839, upload-time = "2026-02-03T14:00:47.407Z" }, + { url = "https://files.pythonhosted.org/packages/12/99/bd6f2a2738144c98945666f90cae446ed870cecf0421c767475fcf42cdbe/coverage-7.13.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2d098709621d0819039f3f1e471ee554f55a0b2ac0d816883c765b14129b5627", size = 250828, upload-time = "2026-02-03T14:00:49.029Z" }, + { url = "https://files.pythonhosted.org/packages/6f/99/97b600225fbf631e6f5bfd3ad5bcaf87fbb9e34ff87492e5a572ff01bbe2/coverage-7.13.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:16d23d6579cf80a474ad160ca14d8b319abaa6db62759d6eef53b2fc979b58c8", size = 253432, upload-time = "2026-02-03T14:00:50.655Z" }, + { url = "https://files.pythonhosted.org/packages/5f/5c/abe2b3490bda26bd4f5e3e799be0bdf00bd81edebedc2c9da8d3ef288fa8/coverage-7.13.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00d34b29a59d2076e6f318b30a00a69bf63687e30cd882984ed444e753990cc1", size = 254672, upload-time = "2026-02-03T14:00:52.757Z" }, + { url = "https://files.pythonhosted.org/packages/31/ba/5d1957c76b40daff53971fe0adb84d9c2162b614280031d1d0653dd010c1/coverage-7.13.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ab6d72bffac9deb6e6cb0f61042e748de3f9f8e98afb0375a8e64b0b6e11746b", size = 251050, upload-time = "2026-02-03T14:00:54.332Z" }, + { url = "https://files.pythonhosted.org/packages/69/dc/dffdf3bfe9d32090f047d3c3085378558cb4eb6778cda7de414ad74581ed/coverage-7.13.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e129328ad1258e49cae0123a3b5fcb93d6c2fa90d540f0b4c7cdcdc019aaa3dc", size = 252801, upload-time = "2026-02-03T14:00:56.121Z" }, + { url = "https://files.pythonhosted.org/packages/87/51/cdf6198b0f2746e04511a30dc9185d7b8cdd895276c07bdb538e37f1cd50/coverage-7.13.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2213a8d88ed35459bda71597599d4eec7c2ebad201c88f0bfc2c26fd9b0dd2ea", size = 250763, upload-time = "2026-02-03T14:00:58.719Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1a/596b7d62218c1d69f2475b69cc6b211e33c83c902f38ee6ae9766dd422da/coverage-7.13.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:00dd3f02de6d5f5c9c3d95e3e036c3c2e2a669f8bf2d3ceb92505c4ce7838f67", size = 250587, upload-time = "2026-02-03T14:01:01.197Z" }, + { url = "https://files.pythonhosted.org/packages/f7/46/52330d5841ff660f22c130b75f5e1dd3e352c8e7baef5e5fef6b14e3e991/coverage-7.13.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f9bada7bc660d20b23d7d312ebe29e927b655cf414dadcdb6335a2075695bd86", size = 252358, upload-time = "2026-02-03T14:01:02.824Z" }, + { url = "https://files.pythonhosted.org/packages/36/8a/e69a5be51923097ba7d5cff9724466e74fe486e9232020ba97c809a8b42b/coverage-7.13.3-cp313-cp313-win32.whl", hash = "sha256:75b3c0300f3fa15809bd62d9ca8b170eb21fcf0100eb4b4154d6dc8b3a5bbd43", size = 222007, upload-time = "2026-02-03T14:01:04.876Z" }, + { url = "https://files.pythonhosted.org/packages/0a/09/a5a069bcee0d613bdd48ee7637fa73bc09e7ed4342b26890f2df97cc9682/coverage-7.13.3-cp313-cp313-win_amd64.whl", hash = "sha256:a2f7589c6132c44c53f6e705e1a6677e2b7821378c22f7703b2cf5388d0d4587", size = 222812, upload-time = "2026-02-03T14:01:07.296Z" }, + { url = "https://files.pythonhosted.org/packages/3d/4f/d62ad7dfe32f9e3d4a10c178bb6f98b10b083d6e0530ca202b399371f6c1/coverage-7.13.3-cp313-cp313-win_arm64.whl", hash = "sha256:123ceaf2b9d8c614f01110f908a341e05b1b305d6b2ada98763b9a5a59756051", size = 221433, upload-time = "2026-02-03T14:01:09.156Z" }, + { url = "https://files.pythonhosted.org/packages/04/b2/4876c46d723d80b9c5b695f1a11bf5f7c3dabf540ec00d6edc076ff025e6/coverage-7.13.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc7fd0f726795420f3678ac82ff882c7fc33770bd0074463b5aef7293285ace9", size = 220162, upload-time = "2026-02-03T14:01:11.409Z" }, + { url = "https://files.pythonhosted.org/packages/fc/04/9942b64a0e0bdda2c109f56bda42b2a59d9d3df4c94b85a323c1cae9fc77/coverage-7.13.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d358dc408edc28730aed5477a69338e444e62fba0b7e9e4a131c505fadad691e", size = 220510, upload-time = "2026-02-03T14:01:13.038Z" }, + { url = "https://files.pythonhosted.org/packages/5a/82/5cfe1e81eae525b74669f9795f37eb3edd4679b873d79d1e6c1c14ee6c1c/coverage-7.13.3-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5d67b9ed6f7b5527b209b24b3df9f2e5bf0198c1bbf99c6971b0e2dcb7e2a107", size = 261801, upload-time = "2026-02-03T14:01:14.674Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ec/a553d7f742fd2cd12e36a16a7b4b3582d5934b496ef2b5ea8abeb10903d4/coverage-7.13.3-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:59224bfb2e9b37c1335ae35d00daa3a5b4e0b1a20f530be208fff1ecfa436f43", size = 263882, upload-time = "2026-02-03T14:01:16.343Z" }, + { url = "https://files.pythonhosted.org/packages/e1/58/8f54a2a93e3d675635bc406de1c9ac8d551312142ff52c9d71b5e533ad45/coverage-7.13.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9306b5299e31e31e0d3b908c66bcb6e7e3ddca143dea0266e9ce6c667346d3", size = 266306, upload-time = "2026-02-03T14:01:18.02Z" }, + { url = "https://files.pythonhosted.org/packages/1a/be/e593399fd6ea1f00aee79ebd7cc401021f218d34e96682a92e1bae092ff6/coverage-7.13.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:343aaeb5f8bb7bcd38620fd7bc56e6ee8207847d8c6103a1e7b72322d381ba4a", size = 261051, upload-time = "2026-02-03T14:01:19.757Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e5/e9e0f6138b21bcdebccac36fbfde9cf15eb1bbcea9f5b1f35cd1f465fb91/coverage-7.13.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b2182129f4c101272ff5f2f18038d7b698db1bf8e7aa9e615cb48440899ad32e", size = 263868, upload-time = "2026-02-03T14:01:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/9a/bf/de72cfebb69756f2d4a2dde35efcc33c47d85cd3ebdf844b3914aac2ef28/coverage-7.13.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:94d2ac94bd0cc57c5626f52f8c2fffed1444b5ae8c9fc68320306cc2b255e155", size = 261498, upload-time = "2026-02-03T14:01:23.097Z" }, + { url = "https://files.pythonhosted.org/packages/f2/91/4a2d313a70fc2e98ca53afd1c8ce67a89b1944cd996589a5b1fe7fbb3e5c/coverage-7.13.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:65436cde5ecabe26fb2f0bf598962f0a054d3f23ad529361326ac002c61a2a1e", size = 260394, upload-time = "2026-02-03T14:01:24.949Z" }, + { url = "https://files.pythonhosted.org/packages/40/83/25113af7cf6941e779eb7ed8de2a677865b859a07ccee9146d4cc06a03e3/coverage-7.13.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:db83b77f97129813dbd463a67e5335adc6a6a91db652cc085d60c2d512746f96", size = 262579, upload-time = "2026-02-03T14:01:26.703Z" }, + { url = "https://files.pythonhosted.org/packages/1e/19/a5f2b96262977e82fb9aabbe19b4d83561f5d063f18dde3e72f34ffc3b2f/coverage-7.13.3-cp313-cp313t-win32.whl", hash = "sha256:dfb428e41377e6b9ba1b0a32df6db5409cb089a0ed1d0a672dc4953ec110d84f", size = 222679, upload-time = "2026-02-03T14:01:28.553Z" }, + { url = "https://files.pythonhosted.org/packages/81/82/ef1747b88c87a5c7d7edc3704799ebd650189a9158e680a063308b6125ef/coverage-7.13.3-cp313-cp313t-win_amd64.whl", hash = "sha256:5badd7e596e6b0c89aa8ec6d37f4473e4357f982ce57f9a2942b0221cd9cf60c", size = 223740, upload-time = "2026-02-03T14:01:30.776Z" }, + { url = "https://files.pythonhosted.org/packages/1c/4c/a67c7bb5b560241c22736a9cb2f14c5034149ffae18630323fde787339e4/coverage-7.13.3-cp313-cp313t-win_arm64.whl", hash = "sha256:989aa158c0eb19d83c76c26f4ba00dbb272485c56e452010a3450bdbc9daafd9", size = 221996, upload-time = "2026-02-03T14:01:32.495Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b3/677bb43427fed9298905106f39c6520ac75f746f81b8f01104526a8026e4/coverage-7.13.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c6f6169bbdbdb85aab8ac0392d776948907267fcc91deeacf6f9d55f7a83ae3b", size = 219513, upload-time = "2026-02-03T14:01:34.29Z" }, + { url = "https://files.pythonhosted.org/packages/42/53/290046e3bbf8986cdb7366a42dab3440b9983711eaff044a51b11006c67b/coverage-7.13.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2f5e731627a3d5ef11a2a35aa0c6f7c435867c7ccbc391268eb4f2ca5dbdcc10", size = 219850, upload-time = "2026-02-03T14:01:35.984Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2b/ab41f10345ba2e49d5e299be8663be2b7db33e77ac1b85cd0af985ea6406/coverage-7.13.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9db3a3285d91c0b70fab9f39f0a4aa37d375873677efe4e71e58d8321e8c5d39", size = 250886, upload-time = "2026-02-03T14:01:38.287Z" }, + { url = "https://files.pythonhosted.org/packages/72/2d/b3f6913ee5a1d5cdd04106f257e5fac5d048992ffc2d9995d07b0f17739f/coverage-7.13.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:06e49c5897cb12e3f7ecdc111d44e97c4f6d0557b81a7a0204ed70a8b038f86f", size = 253393, upload-time = "2026-02-03T14:01:40.118Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f6/b1f48810ffc6accf49a35b9943636560768f0812330f7456aa87dc39aff5/coverage-7.13.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb25061a66802df9fc13a9ba1967d25faa4dae0418db469264fd9860a921dde4", size = 254740, upload-time = "2026-02-03T14:01:42.413Z" }, + { url = "https://files.pythonhosted.org/packages/57/d0/e59c54f9be0b61808f6bc4c8c4346bd79f02dd6bbc3f476ef26124661f20/coverage-7.13.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:99fee45adbb1caeb914da16f70e557fb7ff6ddc9e4b14de665bd41af631367ef", size = 250905, upload-time = "2026-02-03T14:01:44.163Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f7/5291bcdf498bafbee3796bb32ef6966e9915aebd4d0954123c8eae921c32/coverage-7.13.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:318002f1fd819bdc1651c619268aa5bc853c35fa5cc6d1e8c96bd9cd6c828b75", size = 252753, upload-time = "2026-02-03T14:01:45.974Z" }, + { url = "https://files.pythonhosted.org/packages/a0/a9/1dcafa918c281554dae6e10ece88c1add82db685be123e1b05c2056ff3fb/coverage-7.13.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:71295f2d1d170b9977dc386d46a7a1b7cbb30e5405492529b4c930113a33f895", size = 250716, upload-time = "2026-02-03T14:01:48.844Z" }, + { url = "https://files.pythonhosted.org/packages/44/bb/4ea4eabcce8c4f6235df6e059fbc5db49107b24c4bdffc44aee81aeca5a8/coverage-7.13.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5b1ad2e0dc672625c44bc4fe34514602a9fd8b10d52ddc414dc585f74453516c", size = 250530, upload-time = "2026-02-03T14:01:50.793Z" }, + { url = "https://files.pythonhosted.org/packages/6d/31/4a6c9e6a71367e6f923b27b528448c37f4e959b7e4029330523014691007/coverage-7.13.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b2beb64c145593a50d90db5c7178f55daeae129123b0d265bdb3cbec83e5194a", size = 252186, upload-time = "2026-02-03T14:01:52.607Z" }, + { url = "https://files.pythonhosted.org/packages/27/92/e1451ef6390a4f655dc42da35d9971212f7abbbcad0bdb7af4407897eb76/coverage-7.13.3-cp314-cp314-win32.whl", hash = "sha256:3d1aed4f4e837a832df2f3b4f68a690eede0de4560a2dbc214ea0bc55aabcdb4", size = 222253, upload-time = "2026-02-03T14:01:55.071Z" }, + { url = "https://files.pythonhosted.org/packages/8a/98/78885a861a88de020c32a2693487c37d15a9873372953f0c3c159d575a43/coverage-7.13.3-cp314-cp314-win_amd64.whl", hash = "sha256:9f9efbbaf79f935d5fbe3ad814825cbce4f6cdb3054384cb49f0c0f496125fa0", size = 223069, upload-time = "2026-02-03T14:01:56.95Z" }, + { url = "https://files.pythonhosted.org/packages/eb/fb/3784753a48da58a5337972abf7ca58b1fb0f1bda21bc7b4fae992fd28e47/coverage-7.13.3-cp314-cp314-win_arm64.whl", hash = "sha256:31b6e889c53d4e6687ca63706148049494aace140cffece1c4dc6acadb70a7b3", size = 221633, upload-time = "2026-02-03T14:01:58.758Z" }, + { url = "https://files.pythonhosted.org/packages/40/f9/75b732d9674d32cdbffe801ed5f770786dd1c97eecedef2125b0d25102dc/coverage-7.13.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c5e9787cec750793a19a28df7edd85ac4e49d3fb91721afcdc3b86f6c08d9aa8", size = 220243, upload-time = "2026-02-03T14:02:01.109Z" }, + { url = "https://files.pythonhosted.org/packages/cf/7e/2868ec95de5a65703e6f0c87407ea822d1feb3619600fbc3c1c4fa986090/coverage-7.13.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5b86db331c682fd0e4be7098e6acee5e8a293f824d41487c667a93705d415ca", size = 220515, upload-time = "2026-02-03T14:02:02.862Z" }, + { url = "https://files.pythonhosted.org/packages/7d/eb/9f0d349652fced20bcaea0f67fc5777bd097c92369f267975732f3dc5f45/coverage-7.13.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:edc7754932682d52cf6e7a71806e529ecd5ce660e630e8bd1d37109a2e5f63ba", size = 261874, upload-time = "2026-02-03T14:02:04.727Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a5/6619bc4a6c7b139b16818149a3e74ab2e21599ff9a7b6811b6afde99f8ec/coverage-7.13.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3a16d6398666510a6886f67f43d9537bfd0e13aca299688a19daa84f543122f", size = 264004, upload-time = "2026-02-03T14:02:06.634Z" }, + { url = "https://files.pythonhosted.org/packages/29/b7/90aa3fc645a50c6f07881fca4fd0ba21e3bfb6ce3a7078424ea3a35c74c9/coverage-7.13.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:303d38b19626c1981e1bb067a9928236d88eb0e4479b18a74812f05a82071508", size = 266408, upload-time = "2026-02-03T14:02:09.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/55/08bb2a1e4dcbae384e638f0effef486ba5987b06700e481691891427d879/coverage-7.13.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:284e06eadfe15ddfee2f4ee56631f164ef897a7d7d5a15bca5f0bb88889fc5ba", size = 260977, upload-time = "2026-02-03T14:02:11.755Z" }, + { url = "https://files.pythonhosted.org/packages/9b/76/8bd4ae055a42d8fb5dd2230e5cf36ff2e05f85f2427e91b11a27fea52ed7/coverage-7.13.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d401f0864a1d3198422816878e4e84ca89ec1c1bf166ecc0ae01380a39b888cd", size = 263868, upload-time = "2026-02-03T14:02:13.565Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f9/ba000560f11e9e32ec03df5aa8477242c2d95b379c99ac9a7b2e7fbacb1a/coverage-7.13.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3f379b02c18a64de78c4ccdddf1c81c2c5ae1956c72dacb9133d7dd7809794ab", size = 261474, upload-time = "2026-02-03T14:02:16.069Z" }, + { url = "https://files.pythonhosted.org/packages/90/4b/4de4de8f9ca7af4733bfcf4baa440121b7dbb3856daf8428ce91481ff63b/coverage-7.13.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:7a482f2da9086971efb12daca1d6547007ede3674ea06e16d7663414445c683e", size = 260317, upload-time = "2026-02-03T14:02:17.996Z" }, + { url = "https://files.pythonhosted.org/packages/05/71/5cd8436e2c21410ff70be81f738c0dddea91bcc3189b1517d26e0102ccb3/coverage-7.13.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:562136b0d401992118d9b49fbee5454e16f95f85b120a4226a04d816e33fe024", size = 262635, upload-time = "2026-02-03T14:02:20.405Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f8/2834bb45bdd70b55a33ec354b8b5f6062fc90e5bb787e14385903a979503/coverage-7.13.3-cp314-cp314t-win32.whl", hash = "sha256:ca46e5c3be3b195098dd88711890b8011a9fa4feca942292bb84714ce5eab5d3", size = 223035, upload-time = "2026-02-03T14:02:22.323Z" }, + { url = "https://files.pythonhosted.org/packages/26/75/f8290f0073c00d9ae14056d2b84ab92dff21d5370e464cb6cb06f52bf580/coverage-7.13.3-cp314-cp314t-win_amd64.whl", hash = "sha256:06d316dbb3d9fd44cca05b2dbcfbef22948493d63a1f28e828d43e6cc505fed8", size = 224142, upload-time = "2026-02-03T14:02:24.143Z" }, + { url = "https://files.pythonhosted.org/packages/03/01/43ac78dfea8946c4a9161bbc034b5549115cb2b56781a4b574927f0d141a/coverage-7.13.3-cp314-cp314t-win_arm64.whl", hash = "sha256:299d66e9218193f9dc6e4880629ed7c4cd23486005166247c283fb98531656c3", size = 222166, upload-time = "2026-02-03T14:02:26.005Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fb/70af542d2d938c778c9373ce253aa4116dbe7c0a5672f78b2b2ae0e1b94b/coverage-7.13.3-py3-none-any.whl", hash = "sha256:90a8af9dba6429b2573199622d72e0ebf024d6276f16abce394ad4d181bb0910", size = 211237, upload-time = "2026-02-03T14:02:27.986Z" }, ] [package.optional-dependencies] @@ -988,7 +988,7 @@ wheels = [ [[package]] name = "ipykernel" -version = "7.1.0" +version = "7.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "appnope", marker = "sys_platform == 'darwin'" }, @@ -1006,9 +1006,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/a4/4948be6eb88628505b83a1f2f40d90254cab66abf2043b3c40fa07dfce0f/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db", size = 174579, upload-time = "2025-10-27T09:46:39.471Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046, upload-time = "2026-02-06T16:43:27.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c", size = 117968, upload-time = "2025-10-27T09:46:37.805Z" }, + { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" }, ] [[package]] @@ -2323,7 +2323,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, + { name = "ptyprocess" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -3222,11 +3222,11 @@ wheels = [ [[package]] name = "setuptools" -version = "80.10.2" +version = "82.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/f3/748f4d6f65d1756b9ae577f329c951cda23fb900e4de9f70900ced962085/setuptools-82.0.0.tar.gz", hash = "sha256:22e0a2d69474c6ae4feb01951cb69d515ed23728cf96d05513d36e42b62b37cb", size = 1144893, upload-time = "2026-02-08T15:08:40.206Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, + { url = "https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl", hash = "sha256:70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0", size = 1003468, upload-time = "2026-02-08T15:08:38.723Z" }, ] [[package]] @@ -3379,7 +3379,7 @@ version = "3.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astroid", version = "3.3.11", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "astroid", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "astroid", version = "4.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "jinja2" }, { name = "pyyaml" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -3829,11 +3829,11 @@ wheels = [ [[package]] name = "wcwidth" -version = "0.5.3" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c2/62/a7c072fbfefb2980a00f99ca994279cb9ecf310cb2e6b2a4d2a28fe192b3/wcwidth-0.5.3.tar.gz", hash = "sha256:53123b7af053c74e9fe2e92ac810301f6139e64379031f7124574212fb3b4091", size = 157587, upload-time = "2026-01-31T03:52:10.92Z" } +sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl", hash = "sha256:d584eff31cd4753e1e5ff6c12e1edfdb324c995713f75d26c29807bb84bf649e", size = 92981, upload-time = "2026-01-31T03:52:09.14Z" }, + { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, ] [[package]] From fd46fefc063bdeef335ec3a2b814f02d4efcbfaf Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 16 Feb 2026 11:35:09 +0100 Subject: [PATCH 063/110] added check for empty target vector in operation --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 42f64eb1c..f5b12921f 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -155,7 +155,10 @@ auto NativeGateDecomposer::transformToU3( this->nQubits_); std::vector new_layer; for (auto gate : layer) { - gates[gate.get().getTargets().front()].push_back(gate); + //WHat are operations with empty targets doing?? + if (!gate.get().getTargets().empty()) { + gates[gate.get().getTargets().front()].push_back(gate); + } } for (auto qubit_gates : gates) { From 0f93636ef3820c19052c03349901ec55e0a2167d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 10:36:08 +0000 Subject: [PATCH 064/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index f5b12921f..0ae7658ab 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -155,7 +155,7 @@ auto NativeGateDecomposer::transformToU3( this->nQubits_); std::vector new_layer; for (auto gate : layer) { - //WHat are operations with empty targets doing?? + // WHat are operations with empty targets doing?? if (!gate.get().getTargets().empty()) { gates[gate.get().getTargets().front()].push_back(gate); } From 3100f6fcd5c25d48b9f20ec9a0583cbb896677ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 01:38:21 +0000 Subject: [PATCH 065/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=AA=9D=20Update?= =?UTF-8?q?=20pre-commit=20hook=20adhtruong/mirrors-typos=20to=20v1.43.2?= =?UTF-8?q?=20(#928)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [adhtruong/mirrors-typos](https://redirect.github.com/adhtruong/mirrors-typos) | repository | minor | `v1.42.3` → `v1.43.2` | Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://redirect.github.com/renovatebot/renovate/discussions/new) if you have any questions. --- ### Release Notes
adhtruong/mirrors-typos (adhtruong/mirrors-typos) ### [`v1.43.2`](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.43.1...v1.43.2) [Compare Source](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.43.1...v1.43.2) ### [`v1.43.1`](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.43.0...v1.43.1) [Compare Source](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.43.0...v1.43.1) ### [`v1.43.0`](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.3...v1.43.0) [Compare Source](https://redirect.github.com/adhtruong/mirrors-typos/compare/v1.42.3...v1.43.0)
--- ### Configuration 📅 **Schedule**: Branch creation - "every weekend" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). --------- Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Daniel Haag <121057143+denialhaag@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0fff5f84b..e3a14ab16 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,7 +56,7 @@ repos: ## Check for spelling - repo: https://github.com/adhtruong/mirrors-typos - rev: v1.42.3 + rev: v1.43.2 hooks: - id: typos priority: 0 diff --git a/pyproject.toml b/pyproject.toml index ae5c901f5..afb0022fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -294,6 +294,7 @@ anc = "anc" optin = "optin" aer = "aer" iy = "iy" +iz = "iz" ket = "ket" From 4189f4bf7f3d696b42160e124cb36b4b41cba43b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 20:45:02 +0100 Subject: [PATCH 066/110] Bump pillow from 12.1.0 to 12.1.1 in the uv group across 1 directory (#932) --- uv.lock | 196 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 101 insertions(+), 95 deletions(-) diff --git a/uv.lock b/uv.lock index ba8d75898..61a008ec3 100644 --- a/uv.lock +++ b/uv.lock @@ -893,6 +893,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/65/5b235b40581ad75ab97dcd8b4218022ae8e3ab77c13c919f1a1dfe9171fd/greenlet-3.3.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04bee4775f40ecefcdaa9d115ab44736cd4b9c5fba733575bfe9379419582e13", size = 273723, upload-time = "2026-01-23T15:30:37.521Z" }, { url = "https://files.pythonhosted.org/packages/ce/ad/eb4729b85cba2d29499e0a04ca6fbdd8f540afd7be142fd571eea43d712f/greenlet-3.3.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e1457f4fed12a50e427988a07f0f9df53cf0ee8da23fab16e6732c2ec909d4", size = 574874, upload-time = "2026-01-23T16:00:54.551Z" }, { url = "https://files.pythonhosted.org/packages/87/32/57cad7fe4c8b82fdaa098c89498ef85ad92dfbb09d5eb713adedfc2ae1f5/greenlet-3.3.1-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:070472cd156f0656f86f92e954591644e158fd65aa415ffbe2d44ca77656a8f5", size = 586309, upload-time = "2026-01-23T16:05:25.18Z" }, + { url = "https://files.pythonhosted.org/packages/66/66/f041005cb87055e62b0d68680e88ec1a57f4688523d5e2fb305841bc8307/greenlet-3.3.1-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1108b61b06b5224656121c3c8ee8876161c491cbe74e5c519e0634c837cf93d5", size = 597461, upload-time = "2026-01-23T16:15:51.943Z" }, { url = "https://files.pythonhosted.org/packages/87/eb/8a1ec2da4d55824f160594a75a9d8354a5fe0a300fb1c48e7944265217e1/greenlet-3.3.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a300354f27dd86bae5fbf7002e6dd2b3255cd372e9242c933faf5e859b703fe", size = 586985, upload-time = "2026-01-23T15:32:47.968Z" }, { url = "https://files.pythonhosted.org/packages/15/1c/0621dd4321dd8c351372ee8f9308136acb628600658a49be1b7504208738/greenlet-3.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e84b51cbebf9ae573b5fbd15df88887815e3253fc000a7d0ff95170e8f7e9729", size = 1547271, upload-time = "2026-01-23T16:04:18.977Z" }, { url = "https://files.pythonhosted.org/packages/9d/53/24047f8924c83bea7a59c8678d9571209c6bfe5f4c17c94a78c06024e9f2/greenlet-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0093bd1a06d899892427217f0ff2a3c8f306182b8c754336d32e2d587c131b4", size = 1613427, upload-time = "2026-01-23T15:33:44.428Z" }, @@ -900,6 +901,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/e8/2e1462c8fdbe0f210feb5ac7ad2d9029af8be3bf45bd9fa39765f821642f/greenlet-3.3.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5fd23b9bc6d37b563211c6abbb1b3cab27db385a4449af5c32e932f93017080c", size = 274974, upload-time = "2026-01-23T15:31:02.891Z" }, { url = "https://files.pythonhosted.org/packages/7e/a8/530a401419a6b302af59f67aaf0b9ba1015855ea7e56c036b5928793c5bd/greenlet-3.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f51496a0bfbaa9d74d36a52d2580d1ef5ed4fdfcff0a73730abfbbbe1403dd", size = 577175, upload-time = "2026-01-23T16:00:56.213Z" }, { url = "https://files.pythonhosted.org/packages/8e/89/7e812bb9c05e1aaef9b597ac1d0962b9021d2c6269354966451e885c4e6b/greenlet-3.3.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb0feb07fe6e6a74615ee62a880007d976cf739b6669cce95daa7373d4fc69c5", size = 590401, upload-time = "2026-01-23T16:05:26.365Z" }, + { url = "https://files.pythonhosted.org/packages/70/ae/e2d5f0e59b94a2269b68a629173263fa40b63da32f5c231307c349315871/greenlet-3.3.1-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:67ea3fc73c8cd92f42467a72b75e8f05ed51a0e9b1d15398c913416f2dafd49f", size = 601161, upload-time = "2026-01-23T16:15:53.456Z" }, { url = "https://files.pythonhosted.org/packages/5c/ae/8d472e1f5ac5efe55c563f3eabb38c98a44b832602e12910750a7c025802/greenlet-3.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39eda9ba259cc9801da05351eaa8576e9aa83eb9411e8f0c299e05d712a210f2", size = 590272, upload-time = "2026-01-23T15:32:49.411Z" }, { url = "https://files.pythonhosted.org/packages/a8/51/0fde34bebfcadc833550717eade64e35ec8738e6b097d5d248274a01258b/greenlet-3.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e2e7e882f83149f0a71ac822ebf156d902e7a5d22c9045e3e0d1daf59cee2cc9", size = 1550729, upload-time = "2026-01-23T16:04:20.867Z" }, { url = "https://files.pythonhosted.org/packages/16/c9/2fb47bee83b25b119d5a35d580807bb8b92480a54b68fef009a02945629f/greenlet-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80aa4d79eb5564f2e0a6144fcc744b5a37c56c4a92d60920720e99210d88db0f", size = 1615552, upload-time = "2026-01-23T15:33:45.743Z" }, @@ -908,6 +910,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/c8/9d76a66421d1ae24340dfae7e79c313957f6e3195c144d2c73333b5bfe34/greenlet-3.3.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:7e806ca53acf6d15a888405880766ec84721aa4181261cd11a457dfe9a7a4975", size = 276443, upload-time = "2026-01-23T15:30:10.066Z" }, { url = "https://files.pythonhosted.org/packages/81/99/401ff34bb3c032d1f10477d199724f5e5f6fbfb59816ad1455c79c1eb8e7/greenlet-3.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d842c94b9155f1c9b3058036c24ffb8ff78b428414a19792b2380be9cecf4f36", size = 597359, upload-time = "2026-01-23T16:00:57.394Z" }, { url = "https://files.pythonhosted.org/packages/2b/bc/4dcc0871ed557792d304f50be0f7487a14e017952ec689effe2180a6ff35/greenlet-3.3.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20fedaadd422fa02695f82093f9a98bad3dab5fcda793c658b945fcde2ab27ba", size = 607805, upload-time = "2026-01-23T16:05:28.068Z" }, + { url = "https://files.pythonhosted.org/packages/3b/cd/7a7ca57588dac3389e97f7c9521cb6641fd8b6602faf1eaa4188384757df/greenlet-3.3.1-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c620051669fd04ac6b60ebc70478210119c56e2d5d5df848baec4312e260e4ca", size = 622363, upload-time = "2026-01-23T16:15:54.754Z" }, { url = "https://files.pythonhosted.org/packages/cf/05/821587cf19e2ce1f2b24945d890b164401e5085f9d09cbd969b0c193cd20/greenlet-3.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14194f5f4305800ff329cbf02c5fcc88f01886cadd29941b807668a45f0d2336", size = 609947, upload-time = "2026-01-23T15:32:51.004Z" }, { url = "https://files.pythonhosted.org/packages/a4/52/ee8c46ed9f8babaa93a19e577f26e3d28a519feac6350ed6f25f1afee7e9/greenlet-3.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7b2fe4150a0cf59f847a67db8c155ac36aed89080a6a639e9f16df5d6c6096f1", size = 1567487, upload-time = "2026-01-23T16:04:22.125Z" }, { url = "https://files.pythonhosted.org/packages/8f/7c/456a74f07029597626f3a6db71b273a3632aecb9afafeeca452cfa633197/greenlet-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49f4ad195d45f4a66a0eb9c1ba4832bb380570d361912fa3554746830d332149", size = 1636087, upload-time = "2026-01-23T15:33:47.486Z" }, @@ -916,6 +919,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/ab/d26750f2b7242c2b90ea2ad71de70cfcd73a948a49513188a0fc0d6fc15a/greenlet-3.3.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:7ab327905cabb0622adca5971e488064e35115430cec2c35a50fd36e72a315b3", size = 275205, upload-time = "2026-01-23T15:30:24.556Z" }, { url = "https://files.pythonhosted.org/packages/10/d3/be7d19e8fad7c5a78eeefb2d896a08cd4643e1e90c605c4be3b46264998f/greenlet-3.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65be2f026ca6a176f88fb935ee23c18333ccea97048076aef4db1ef5bc0713ac", size = 599284, upload-time = "2026-01-23T16:00:58.584Z" }, { url = "https://files.pythonhosted.org/packages/ae/21/fe703aaa056fdb0f17e5afd4b5c80195bbdab701208918938bd15b00d39b/greenlet-3.3.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a3ae05b3d225b4155bda56b072ceb09d05e974bc74be6c3fc15463cf69f33fd", size = 610274, upload-time = "2026-01-23T16:05:29.312Z" }, + { url = "https://files.pythonhosted.org/packages/06/00/95df0b6a935103c0452dad2203f5be8377e551b8466a29650c4c5a5af6cc/greenlet-3.3.1-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:12184c61e5d64268a160226fb4818af4df02cfead8379d7f8b99a56c3a54ff3e", size = 624375, upload-time = "2026-01-23T16:15:55.915Z" }, { url = "https://files.pythonhosted.org/packages/cb/86/5c6ab23bb3c28c21ed6bebad006515cfe08b04613eb105ca0041fecca852/greenlet-3.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6423481193bbbe871313de5fd06a082f2649e7ce6e08015d2a76c1e9186ca5b3", size = 612904, upload-time = "2026-01-23T15:32:52.317Z" }, { url = "https://files.pythonhosted.org/packages/c2/f3/7949994264e22639e40718c2daf6f6df5169bf48fb038c008a489ec53a50/greenlet-3.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:33a956fe78bbbda82bfc95e128d61129b32d66bcf0a20a1f0c08aa4839ffa951", size = 1567316, upload-time = "2026-01-23T16:04:23.316Z" }, { url = "https://files.pythonhosted.org/packages/8d/6e/d73c94d13b6465e9f7cd6231c68abde838bb22408596c05d9059830b7872/greenlet-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b065d3284be43728dd280f6f9a13990b56470b81be20375a207cdc814a983f2", size = 1636549, upload-time = "2026-01-23T15:33:48.643Z" }, @@ -924,6 +928,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5", size = 275737, upload-time = "2026-01-23T15:32:16.889Z" }, { url = "https://files.pythonhosted.org/packages/41/2e/a3a417d620363fdbb08a48b1dd582956a46a61bf8fd27ee8164f9dfe87c2/greenlet-3.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b31c05dd84ef6871dd47120386aed35323c944d86c3d91a17c4b8d23df62f15b", size = 646422, upload-time = "2026-01-23T16:01:00.354Z" }, { url = "https://files.pythonhosted.org/packages/b4/09/c6c4a0db47defafd2d6bab8ddfe47ad19963b4e30f5bed84d75328059f8c/greenlet-3.3.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02925a0bfffc41e542c70aa14c7eda3593e4d7e274bfcccca1827e6c0875902e", size = 658219, upload-time = "2026-01-23T16:05:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/e2/89/b95f2ddcc5f3c2bc09c8ee8d77be312df7f9e7175703ab780f2014a0e781/greenlet-3.3.1-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3e0f3878ca3a3ff63ab4ea478585942b53df66ddde327b59ecb191b19dbbd62d", size = 671455, upload-time = "2026-01-23T16:15:57.232Z" }, { url = "https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f", size = 660237, upload-time = "2026-01-23T15:32:53.967Z" }, { url = "https://files.pythonhosted.org/packages/96/61/373c30b7197f9e756e4c81ae90a8d55dc3598c17673f91f4d31c3c689c3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aec9ab04e82918e623415947921dea15851b152b822661cce3f8e4393c3df683", size = 1615261, upload-time = "2026-01-23T16:04:25.066Z" }, { url = "https://files.pythonhosted.org/packages/fd/d3/ca534310343f5945316f9451e953dcd89b36fe7a19de652a1dc5a0eeef3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71c767cf281a80d02b6c1bdc41c9468e1f5a494fb11bc8688c360524e273d7b1", size = 1683719, upload-time = "2026-01-23T15:33:50.61Z" }, @@ -932,6 +937,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/28/24/cbbec49bacdcc9ec652a81d3efef7b59f326697e7edf6ed775a5e08e54c2/greenlet-3.3.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:3e63252943c921b90abb035ebe9de832c436401d9c45f262d80e2d06cc659242", size = 282706, upload-time = "2026-01-23T15:33:05.525Z" }, { url = "https://files.pythonhosted.org/packages/86/2e/4f2b9323c144c4fe8842a4e0d92121465485c3c2c5b9e9b30a52e80f523f/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76e39058e68eb125de10c92524573924e827927df5d3891fbc97bd55764a8774", size = 651209, upload-time = "2026-01-23T16:01:01.517Z" }, { url = "https://files.pythonhosted.org/packages/d9/87/50ca60e515f5bb55a2fbc5f0c9b5b156de7d2fc51a0a69abc9d23914a237/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9f9d5e7a9310b7a2f416dd13d2e3fd8b42d803968ea580b7c0f322ccb389b97", size = 654300, upload-time = "2026-01-23T16:05:32.199Z" }, + { url = "https://files.pythonhosted.org/packages/7c/25/c51a63f3f463171e09cb586eb64db0861eb06667ab01a7968371a24c4f3b/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b9721549a95db96689458a1e0ae32412ca18776ed004463df3a9299c1b257ab", size = 662574, upload-time = "2026-01-23T16:15:58.364Z" }, { url = "https://files.pythonhosted.org/packages/1d/94/74310866dfa2b73dd08659a3d18762f83985ad3281901ba0ee9a815194fb/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92497c78adf3ac703b57f1e3813c2d874f27f71a178f9ea5887855da413cd6d2", size = 653842, upload-time = "2026-01-23T15:32:55.671Z" }, { url = "https://files.pythonhosted.org/packages/97/43/8bf0ffa3d498eeee4c58c212a3905dd6146c01c8dc0b0a046481ca29b18c/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ed6b402bc74d6557a705e197d47f9063733091ed6357b3de33619d8a8d93ac53", size = 1614917, upload-time = "2026-01-23T16:04:26.276Z" }, { url = "https://files.pythonhosted.org/packages/89/90/a3be7a5f378fc6e84abe4dcfb2ba32b07786861172e502388b4c90000d1b/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:59913f1e5ada20fde795ba906916aea25d442abcc0593fba7e26c92b7ad76249", size = 1676092, upload-time = "2026-01-23T15:33:52.176Z" }, @@ -2323,7 +2329,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess" }, + { name = "ptyprocess", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -2332,100 +2338,100 @@ wheels = [ [[package]] name = "pillow" -version = "12.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/02/d52c733a2452ef1ffcc123b68e6606d07276b0e358db70eabad7e40042b7/pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9", size = 46977283, upload-time = "2026-01-02T09:13:29.892Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/41/f73d92b6b883a579e79600d391f2e21cb0df767b2714ecbd2952315dfeef/pillow-12.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:fb125d860738a09d363a88daa0f59c4533529a90e564785e20fe875b200b6dbd", size = 5304089, upload-time = "2026-01-02T09:10:24.953Z" }, - { url = "https://files.pythonhosted.org/packages/94/55/7aca2891560188656e4a91ed9adba305e914a4496800da6b5c0a15f09edf/pillow-12.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cad302dc10fac357d3467a74a9561c90609768a6f73a1923b0fd851b6486f8b0", size = 4657815, upload-time = "2026-01-02T09:10:27.063Z" }, - { url = "https://files.pythonhosted.org/packages/e9/d2/b28221abaa7b4c40b7dba948f0f6a708bd7342c4d47ce342f0ea39643974/pillow-12.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a40905599d8079e09f25027423aed94f2823adaf2868940de991e53a449e14a8", size = 6222593, upload-time = "2026-01-02T09:10:29.115Z" }, - { url = "https://files.pythonhosted.org/packages/71/b8/7a61fb234df6a9b0b479f69e66901209d89ff72a435b49933f9122f94cac/pillow-12.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92a7fe4225365c5e3a8e598982269c6d6698d3e783b3b1ae979e7819f9cd55c1", size = 8027579, upload-time = "2026-01-02T09:10:31.182Z" }, - { url = "https://files.pythonhosted.org/packages/ea/51/55c751a57cc524a15a0e3db20e5cde517582359508d62305a627e77fd295/pillow-12.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f10c98f49227ed8383d28174ee95155a675c4ed7f85e2e573b04414f7e371bda", size = 6335760, upload-time = "2026-01-02T09:10:33.02Z" }, - { url = "https://files.pythonhosted.org/packages/dc/7c/60e3e6f5e5891a1a06b4c910f742ac862377a6fe842f7184df4a274ce7bf/pillow-12.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8637e29d13f478bc4f153d8daa9ffb16455f0a6cb287da1b432fdad2bfbd66c7", size = 7027127, upload-time = "2026-01-02T09:10:35.009Z" }, - { url = "https://files.pythonhosted.org/packages/06/37/49d47266ba50b00c27ba63a7c898f1bb41a29627ced8c09e25f19ebec0ff/pillow-12.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:21e686a21078b0f9cb8c8a961d99e6a4ddb88e0fc5ea6e130172ddddc2e5221a", size = 6449896, upload-time = "2026-01-02T09:10:36.793Z" }, - { url = "https://files.pythonhosted.org/packages/f9/e5/67fd87d2913902462cd9b79c6211c25bfe95fcf5783d06e1367d6d9a741f/pillow-12.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2415373395a831f53933c23ce051021e79c8cd7979822d8cc478547a3f4da8ef", size = 7151345, upload-time = "2026-01-02T09:10:39.064Z" }, - { url = "https://files.pythonhosted.org/packages/bd/15/f8c7abf82af68b29f50d77c227e7a1f87ce02fdc66ded9bf603bc3b41180/pillow-12.1.0-cp310-cp310-win32.whl", hash = "sha256:e75d3dba8fc1ddfec0cd752108f93b83b4f8d6ab40e524a95d35f016b9683b09", size = 6325568, upload-time = "2026-01-02T09:10:41.035Z" }, - { url = "https://files.pythonhosted.org/packages/d4/24/7d1c0e160b6b5ac2605ef7d8be537e28753c0db5363d035948073f5513d7/pillow-12.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:64efdf00c09e31efd754448a383ea241f55a994fd079866b92d2bbff598aad91", size = 7032367, upload-time = "2026-01-02T09:10:43.09Z" }, - { url = "https://files.pythonhosted.org/packages/f4/03/41c038f0d7a06099254c60f618d0ec7be11e79620fc23b8e85e5b31d9a44/pillow-12.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:f188028b5af6b8fb2e9a76ac0f841a575bd1bd396e46ef0840d9b88a48fdbcea", size = 2452345, upload-time = "2026-01-02T09:10:44.795Z" }, - { url = "https://files.pythonhosted.org/packages/43/c4/bf8328039de6cc22182c3ef007a2abfbbdab153661c0a9aa78af8d706391/pillow-12.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3", size = 5304057, upload-time = "2026-01-02T09:10:46.627Z" }, - { url = "https://files.pythonhosted.org/packages/43/06/7264c0597e676104cc22ca73ee48f752767cd4b1fe084662620b17e10120/pillow-12.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0", size = 4657811, upload-time = "2026-01-02T09:10:49.548Z" }, - { url = "https://files.pythonhosted.org/packages/72/64/f9189e44474610daf83da31145fa56710b627b5c4c0b9c235e34058f6b31/pillow-12.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451", size = 6232243, upload-time = "2026-01-02T09:10:51.62Z" }, - { url = "https://files.pythonhosted.org/packages/ef/30/0df458009be6a4caca4ca2c52975e6275c387d4e5c95544e34138b41dc86/pillow-12.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:800429ac32c9b72909c671aaf17ecd13110f823ddb7db4dfef412a5587c2c24e", size = 8037872, upload-time = "2026-01-02T09:10:53.446Z" }, - { url = "https://files.pythonhosted.org/packages/e4/86/95845d4eda4f4f9557e25381d70876aa213560243ac1a6d619c46caaedd9/pillow-12.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b022eaaf709541b391ee069f0022ee5b36c709df71986e3f7be312e46f42c84", size = 6345398, upload-time = "2026-01-02T09:10:55.426Z" }, - { url = "https://files.pythonhosted.org/packages/5c/1f/8e66ab9be3aaf1435bc03edd1ebdf58ffcd17f7349c1d970cafe87af27d9/pillow-12.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f345e7bc9d7f368887c712aa5054558bad44d2a301ddf9248599f4161abc7c0", size = 7034667, upload-time = "2026-01-02T09:10:57.11Z" }, - { url = "https://files.pythonhosted.org/packages/f9/f6/683b83cb9b1db1fb52b87951b1c0b99bdcfceaa75febf11406c19f82cb5e/pillow-12.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d70347c8a5b7ccd803ec0c85c8709f036e6348f1e6a5bf048ecd9c64d3550b8b", size = 6458743, upload-time = "2026-01-02T09:10:59.331Z" }, - { url = "https://files.pythonhosted.org/packages/9a/7d/de833d63622538c1d58ce5395e7c6cb7e7dce80decdd8bde4a484e095d9f/pillow-12.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fcc52d86ce7a34fd17cb04e87cfdb164648a3662a6f20565910a99653d66c18", size = 7159342, upload-time = "2026-01-02T09:11:01.82Z" }, - { url = "https://files.pythonhosted.org/packages/8c/40/50d86571c9e5868c42b81fe7da0c76ca26373f3b95a8dd675425f4a92ec1/pillow-12.1.0-cp311-cp311-win32.whl", hash = "sha256:3ffaa2f0659e2f740473bcf03c702c39a8d4b2b7ffc629052028764324842c64", size = 6328655, upload-time = "2026-01-02T09:11:04.556Z" }, - { url = "https://files.pythonhosted.org/packages/6c/af/b1d7e301c4cd26cd45d4af884d9ee9b6fab893b0ad2450d4746d74a6968c/pillow-12.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:806f3987ffe10e867bab0ddad45df1148a2b98221798457fa097ad85d6e8bc75", size = 7031469, upload-time = "2026-01-02T09:11:06.538Z" }, - { url = "https://files.pythonhosted.org/packages/48/36/d5716586d887fb2a810a4a61518a327a1e21c8b7134c89283af272efe84b/pillow-12.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:9f5fefaca968e700ad1a4a9de98bf0869a94e397fe3524c4c9450c1445252304", size = 2452515, upload-time = "2026-01-02T09:11:08.226Z" }, - { url = "https://files.pythonhosted.org/packages/20/31/dc53fe21a2f2996e1b7d92bf671cdb157079385183ef7c1ae08b485db510/pillow-12.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b", size = 5262642, upload-time = "2026-01-02T09:11:10.138Z" }, - { url = "https://files.pythonhosted.org/packages/ab/c1/10e45ac9cc79419cedf5121b42dcca5a50ad2b601fa080f58c22fb27626e/pillow-12.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551", size = 4657464, upload-time = "2026-01-02T09:11:12.319Z" }, - { url = "https://files.pythonhosted.org/packages/ad/26/7b82c0ab7ef40ebede7a97c72d473bda5950f609f8e0c77b04af574a0ddb/pillow-12.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208", size = 6234878, upload-time = "2026-01-02T09:11:14.096Z" }, - { url = "https://files.pythonhosted.org/packages/76/25/27abc9792615b5e886ca9411ba6637b675f1b77af3104710ac7353fe5605/pillow-12.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5", size = 8044868, upload-time = "2026-01-02T09:11:15.903Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ea/f200a4c36d836100e7bc738fc48cd963d3ba6372ebc8298a889e0cfc3359/pillow-12.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661", size = 6349468, upload-time = "2026-01-02T09:11:17.631Z" }, - { url = "https://files.pythonhosted.org/packages/11/8f/48d0b77ab2200374c66d344459b8958c86693be99526450e7aee714e03e4/pillow-12.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17", size = 7041518, upload-time = "2026-01-02T09:11:19.389Z" }, - { url = "https://files.pythonhosted.org/packages/1d/23/c281182eb986b5d31f0a76d2a2c8cd41722d6fb8ed07521e802f9bba52de/pillow-12.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670", size = 6462829, upload-time = "2026-01-02T09:11:21.28Z" }, - { url = "https://files.pythonhosted.org/packages/25/ef/7018273e0faac099d7b00982abdcc39142ae6f3bd9ceb06de09779c4a9d6/pillow-12.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616", size = 7166756, upload-time = "2026-01-02T09:11:23.559Z" }, - { url = "https://files.pythonhosted.org/packages/8f/c8/993d4b7ab2e341fe02ceef9576afcf5830cdec640be2ac5bee1820d693d4/pillow-12.1.0-cp312-cp312-win32.whl", hash = "sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7", size = 6328770, upload-time = "2026-01-02T09:11:25.661Z" }, - { url = "https://files.pythonhosted.org/packages/a7/87/90b358775a3f02765d87655237229ba64a997b87efa8ccaca7dd3e36e7a7/pillow-12.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d", size = 7033406, upload-time = "2026-01-02T09:11:27.474Z" }, - { url = "https://files.pythonhosted.org/packages/5d/cf/881b457eccacac9e5b2ddd97d5071fb6d668307c57cbf4e3b5278e06e536/pillow-12.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c", size = 2452612, upload-time = "2026-01-02T09:11:29.309Z" }, - { url = "https://files.pythonhosted.org/packages/dd/c7/2530a4aa28248623e9d7f27316b42e27c32ec410f695929696f2e0e4a778/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1", size = 4062543, upload-time = "2026-01-02T09:11:31.566Z" }, - { url = "https://files.pythonhosted.org/packages/8f/1f/40b8eae823dc1519b87d53c30ed9ef085506b05281d313031755c1705f73/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179", size = 4138373, upload-time = "2026-01-02T09:11:33.367Z" }, - { url = "https://files.pythonhosted.org/packages/d4/77/6fa60634cf06e52139fd0e89e5bbf055e8166c691c42fb162818b7fda31d/pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0", size = 3601241, upload-time = "2026-01-02T09:11:35.011Z" }, - { url = "https://files.pythonhosted.org/packages/4f/bf/28ab865de622e14b747f0cd7877510848252d950e43002e224fb1c9ababf/pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587", size = 5262410, upload-time = "2026-01-02T09:11:36.682Z" }, - { url = "https://files.pythonhosted.org/packages/1c/34/583420a1b55e715937a85bd48c5c0991598247a1fd2eb5423188e765ea02/pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac", size = 4657312, upload-time = "2026-01-02T09:11:38.535Z" }, - { url = "https://files.pythonhosted.org/packages/1d/fd/f5a0896839762885b3376ff04878f86ab2b097c2f9a9cdccf4eda8ba8dc0/pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b", size = 6232605, upload-time = "2026-01-02T09:11:40.602Z" }, - { url = "https://files.pythonhosted.org/packages/98/aa/938a09d127ac1e70e6ed467bd03834350b33ef646b31edb7452d5de43792/pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea", size = 8041617, upload-time = "2026-01-02T09:11:42.721Z" }, - { url = "https://files.pythonhosted.org/packages/17/e8/538b24cb426ac0186e03f80f78bc8dc7246c667f58b540bdd57c71c9f79d/pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c", size = 6346509, upload-time = "2026-01-02T09:11:44.955Z" }, - { url = "https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc", size = 7038117, upload-time = "2026-01-02T09:11:46.736Z" }, - { url = "https://files.pythonhosted.org/packages/c7/a2/d40308cf86eada842ca1f3ffa45d0ca0df7e4ab33c83f81e73f5eaed136d/pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644", size = 6460151, upload-time = "2026-01-02T09:11:48.625Z" }, - { url = "https://files.pythonhosted.org/packages/f1/88/f5b058ad6453a085c5266660a1417bdad590199da1b32fb4efcff9d33b05/pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c", size = 7164534, upload-time = "2026-01-02T09:11:50.445Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/c17334caea1db789163b5d855a5735e47995b0b5dc8745e9a3605d5f24c0/pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171", size = 6332551, upload-time = "2026-01-02T09:11:52.234Z" }, - { url = "https://files.pythonhosted.org/packages/e5/07/74a9d941fa45c90a0d9465098fe1ec85de3e2afbdc15cc4766622d516056/pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a", size = 7040087, upload-time = "2026-01-02T09:11:54.822Z" }, - { url = "https://files.pythonhosted.org/packages/88/09/c99950c075a0e9053d8e880595926302575bc742b1b47fe1bbcc8d388d50/pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45", size = 2452470, upload-time = "2026-01-02T09:11:56.522Z" }, - { url = "https://files.pythonhosted.org/packages/b5/ba/970b7d85ba01f348dee4d65412476321d40ee04dcb51cd3735b9dc94eb58/pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d", size = 5264816, upload-time = "2026-01-02T09:11:58.227Z" }, - { url = "https://files.pythonhosted.org/packages/10/60/650f2fb55fdba7a510d836202aa52f0baac633e50ab1cf18415d332188fb/pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0", size = 4660472, upload-time = "2026-01-02T09:12:00.798Z" }, - { url = "https://files.pythonhosted.org/packages/2b/c0/5273a99478956a099d533c4f46cbaa19fd69d606624f4334b85e50987a08/pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554", size = 6268974, upload-time = "2026-01-02T09:12:02.572Z" }, - { url = "https://files.pythonhosted.org/packages/b4/26/0bf714bc2e73d5267887d47931d53c4ceeceea6978148ed2ab2a4e6463c4/pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e", size = 8073070, upload-time = "2026-01-02T09:12:04.75Z" }, - { url = "https://files.pythonhosted.org/packages/43/cf/1ea826200de111a9d65724c54f927f3111dc5ae297f294b370a670c17786/pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82", size = 6380176, upload-time = "2026-01-02T09:12:06.626Z" }, - { url = "https://files.pythonhosted.org/packages/03/e0/7938dd2b2013373fd85d96e0f38d62b7a5a262af21ac274250c7ca7847c9/pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4", size = 7067061, upload-time = "2026-01-02T09:12:08.624Z" }, - { url = "https://files.pythonhosted.org/packages/86/ad/a2aa97d37272a929a98437a8c0ac37b3cf012f4f8721e1bd5154699b2518/pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0", size = 6491824, upload-time = "2026-01-02T09:12:10.488Z" }, - { url = "https://files.pythonhosted.org/packages/a4/44/80e46611b288d51b115826f136fb3465653c28f491068a72d3da49b54cd4/pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b", size = 7190911, upload-time = "2026-01-02T09:12:12.772Z" }, - { url = "https://files.pythonhosted.org/packages/86/77/eacc62356b4cf81abe99ff9dbc7402750044aed02cfd6a503f7c6fc11f3e/pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65", size = 6336445, upload-time = "2026-01-02T09:12:14.775Z" }, - { url = "https://files.pythonhosted.org/packages/e7/3c/57d81d0b74d218706dafccb87a87ea44262c43eef98eb3b164fd000e0491/pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0", size = 7045354, upload-time = "2026-01-02T09:12:16.599Z" }, - { url = "https://files.pythonhosted.org/packages/ac/82/8b9b97bba2e3576a340f93b044a3a3a09841170ab4c1eb0d5c93469fd32f/pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8", size = 2454547, upload-time = "2026-01-02T09:12:18.704Z" }, - { url = "https://files.pythonhosted.org/packages/8c/87/bdf971d8bbcf80a348cc3bacfcb239f5882100fe80534b0ce67a784181d8/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91", size = 4062533, upload-time = "2026-01-02T09:12:20.791Z" }, - { url = "https://files.pythonhosted.org/packages/ff/4f/5eb37a681c68d605eb7034c004875c81f86ec9ef51f5be4a63eadd58859a/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796", size = 4138546, upload-time = "2026-01-02T09:12:23.664Z" }, - { url = "https://files.pythonhosted.org/packages/11/6d/19a95acb2edbace40dcd582d077b991646b7083c41b98da4ed7555b59733/pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd", size = 3601163, upload-time = "2026-01-02T09:12:26.338Z" }, - { url = "https://files.pythonhosted.org/packages/fc/36/2b8138e51cb42e4cc39c3297713455548be855a50558c3ac2beebdc251dd/pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13", size = 5266086, upload-time = "2026-01-02T09:12:28.782Z" }, - { url = "https://files.pythonhosted.org/packages/53/4b/649056e4d22e1caa90816bf99cef0884aed607ed38075bd75f091a607a38/pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e", size = 4657344, upload-time = "2026-01-02T09:12:31.117Z" }, - { url = "https://files.pythonhosted.org/packages/6c/6b/c5742cea0f1ade0cd61485dc3d81f05261fc2276f537fbdc00802de56779/pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643", size = 6232114, upload-time = "2026-01-02T09:12:32.936Z" }, - { url = "https://files.pythonhosted.org/packages/bf/8f/9f521268ce22d63991601aafd3d48d5ff7280a246a1ef62d626d67b44064/pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5", size = 8042708, upload-time = "2026-01-02T09:12:34.78Z" }, - { url = "https://files.pythonhosted.org/packages/1a/eb/257f38542893f021502a1bbe0c2e883c90b5cff26cc33b1584a841a06d30/pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de", size = 6347762, upload-time = "2026-01-02T09:12:36.748Z" }, - { url = "https://files.pythonhosted.org/packages/c4/5a/8ba375025701c09b309e8d5163c5a4ce0102fa86bbf8800eb0d7ac87bc51/pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9", size = 7039265, upload-time = "2026-01-02T09:12:39.082Z" }, - { url = "https://files.pythonhosted.org/packages/cf/dc/cf5e4cdb3db533f539e88a7bbf9f190c64ab8a08a9bc7a4ccf55067872e4/pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a", size = 6462341, upload-time = "2026-01-02T09:12:40.946Z" }, - { url = "https://files.pythonhosted.org/packages/d0/47/0291a25ac9550677e22eda48510cfc4fa4b2ef0396448b7fbdc0a6946309/pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a", size = 7165395, upload-time = "2026-01-02T09:12:42.706Z" }, - { url = "https://files.pythonhosted.org/packages/4f/4c/e005a59393ec4d9416be06e6b45820403bb946a778e39ecec62f5b2b991e/pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030", size = 6431413, upload-time = "2026-01-02T09:12:44.944Z" }, - { url = "https://files.pythonhosted.org/packages/1c/af/f23697f587ac5f9095d67e31b81c95c0249cd461a9798a061ed6709b09b5/pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94", size = 7176779, upload-time = "2026-01-02T09:12:46.727Z" }, - { url = "https://files.pythonhosted.org/packages/b3/36/6a51abf8599232f3e9afbd16d52829376a68909fe14efe29084445db4b73/pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4", size = 2543105, upload-time = "2026-01-02T09:12:49.243Z" }, - { url = "https://files.pythonhosted.org/packages/82/54/2e1dd20c8749ff225080d6ba465a0cab4387f5db0d1c5fb1439e2d99923f/pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2", size = 5268571, upload-time = "2026-01-02T09:12:51.11Z" }, - { url = "https://files.pythonhosted.org/packages/57/61/571163a5ef86ec0cf30d265ac2a70ae6fc9e28413d1dc94fa37fae6bda89/pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61", size = 4660426, upload-time = "2026-01-02T09:12:52.865Z" }, - { url = "https://files.pythonhosted.org/packages/5e/e1/53ee5163f794aef1bf84243f755ee6897a92c708505350dd1923f4afec48/pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51", size = 6269908, upload-time = "2026-01-02T09:12:54.884Z" }, - { url = "https://files.pythonhosted.org/packages/bc/0b/b4b4106ff0ee1afa1dc599fde6ab230417f800279745124f6c50bcffed8e/pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc", size = 8074733, upload-time = "2026-01-02T09:12:56.802Z" }, - { url = "https://files.pythonhosted.org/packages/19/9f/80b411cbac4a732439e629a26ad3ef11907a8c7fc5377b7602f04f6fe4e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14", size = 6381431, upload-time = "2026-01-02T09:12:58.823Z" }, - { url = "https://files.pythonhosted.org/packages/8f/b7/d65c45db463b66ecb6abc17c6ba6917a911202a07662247e1355ce1789e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8", size = 7068529, upload-time = "2026-01-02T09:13:00.885Z" }, - { url = "https://files.pythonhosted.org/packages/50/96/dfd4cd726b4a45ae6e3c669fc9e49deb2241312605d33aba50499e9d9bd1/pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924", size = 6492981, upload-time = "2026-01-02T09:13:03.314Z" }, - { url = "https://files.pythonhosted.org/packages/4d/1c/b5dc52cf713ae46033359c5ca920444f18a6359ce1020dd3e9c553ea5bc6/pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef", size = 7191878, upload-time = "2026-01-02T09:13:05.276Z" }, - { url = "https://files.pythonhosted.org/packages/53/26/c4188248bd5edaf543864fe4834aebe9c9cb4968b6f573ce014cc42d0720/pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988", size = 6438703, upload-time = "2026-01-02T09:13:07.491Z" }, - { url = "https://files.pythonhosted.org/packages/b8/0e/69ed296de8ea05cb03ee139cee600f424ca166e632567b2d66727f08c7ed/pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6", size = 7182927, upload-time = "2026-01-02T09:13:09.841Z" }, - { url = "https://files.pythonhosted.org/packages/fc/f5/68334c015eed9b5cff77814258717dec591ded209ab5b6fb70e2ae873d1d/pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831", size = 2545104, upload-time = "2026-01-02T09:13:12.068Z" }, - { url = "https://files.pythonhosted.org/packages/8b/bc/224b1d98cffd7164b14707c91aac83c07b047fbd8f58eba4066a3e53746a/pillow-12.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377", size = 5228605, upload-time = "2026-01-02T09:13:14.084Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ca/49ca7769c4550107de049ed85208240ba0f330b3f2e316f24534795702ce/pillow-12.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72", size = 4622245, upload-time = "2026-01-02T09:13:15.964Z" }, - { url = "https://files.pythonhosted.org/packages/73/48/fac807ce82e5955bcc2718642b94b1bd22a82a6d452aea31cbb678cddf12/pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c", size = 5247593, upload-time = "2026-01-02T09:13:17.913Z" }, - { url = "https://files.pythonhosted.org/packages/d2/95/3e0742fe358c4664aed4fd05d5f5373dcdad0b27af52aa0972568541e3f4/pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84cabc7095dd535ca934d57e9ce2a72ffd216e435a84acb06b2277b1de2689bd", size = 6989008, upload-time = "2026-01-02T09:13:20.083Z" }, - { url = "https://files.pythonhosted.org/packages/5a/74/fe2ac378e4e202e56d50540d92e1ef4ff34ed687f3c60f6a121bcf99437e/pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53d8b764726d3af1a138dd353116f774e3862ec7e3794e0c8781e30db0f35dfc", size = 5313824, upload-time = "2026-01-02T09:13:22.405Z" }, - { url = "https://files.pythonhosted.org/packages/f3/77/2a60dee1adee4e2655ac328dd05c02a955c1cd683b9f1b82ec3feb44727c/pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5da841d81b1a05ef940a8567da92decaa15bc4d7dedb540a8c219ad83d91808a", size = 5963278, upload-time = "2026-01-02T09:13:24.706Z" }, - { url = "https://files.pythonhosted.org/packages/2d/71/64e9b1c7f04ae0027f788a248e6297d7fcc29571371fe7d45495a78172c0/pillow-12.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:75af0b4c229ac519b155028fa1be632d812a519abba9b46b20e50c6caa184f19", size = 7029809, upload-time = "2026-01-02T09:13:26.541Z" }, +version = "12.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/42/5c74462b4fd957fcd7b13b04fb3205ff8349236ea74c7c375766d6c82288/pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4", size = 46980264, upload-time = "2026-02-11T04:23:07.146Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/30/5bd3d794762481f8c8ae9c80e7b76ecea73b916959eb587521358ef0b2f9/pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0", size = 5304099, upload-time = "2026-02-11T04:20:06.13Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c1/aab9e8f3eeb4490180e357955e15c2ef74b31f64790ff356c06fb6cf6d84/pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713", size = 4657880, upload-time = "2026-02-11T04:20:09.291Z" }, + { url = "https://files.pythonhosted.org/packages/f1/0a/9879e30d56815ad529d3985aeff5af4964202425c27261a6ada10f7cbf53/pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b", size = 6222587, upload-time = "2026-02-11T04:20:10.82Z" }, + { url = "https://files.pythonhosted.org/packages/5a/5f/a1b72ff7139e4f89014e8d451442c74a774d5c43cd938fb0a9f878576b37/pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b", size = 8027678, upload-time = "2026-02-11T04:20:12.455Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c2/c7cb187dac79a3d22c3ebeae727abee01e077c8c7d930791dc592f335153/pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4", size = 6335777, upload-time = "2026-02-11T04:20:14.441Z" }, + { url = "https://files.pythonhosted.org/packages/0c/7b/f9b09a7804ec7336effb96c26d37c29d27225783dc1501b7d62dcef6ae25/pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4", size = 7027140, upload-time = "2026-02-11T04:20:16.387Z" }, + { url = "https://files.pythonhosted.org/packages/98/b2/2fa3c391550bd421b10849d1a2144c44abcd966daadd2f7c12e19ea988c4/pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e", size = 6449855, upload-time = "2026-02-11T04:20:18.554Z" }, + { url = "https://files.pythonhosted.org/packages/96/ff/9caf4b5b950c669263c39e96c78c0d74a342c71c4f43fd031bb5cb7ceac9/pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff", size = 7151329, upload-time = "2026-02-11T04:20:20.646Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f8/4b24841f582704da675ca535935bccb32b00a6da1226820845fac4a71136/pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40", size = 6325574, upload-time = "2026-02-11T04:20:22.43Z" }, + { url = "https://files.pythonhosted.org/packages/f8/f9/9f6b01c0881d7036063aa6612ef04c0e2cad96be21325a1e92d0203f8e91/pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23", size = 7032347, upload-time = "2026-02-11T04:20:23.932Z" }, + { url = "https://files.pythonhosted.org/packages/79/13/c7922edded3dcdaf10c59297540b72785620abc0538872c819915746757d/pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9", size = 2453457, upload-time = "2026-02-11T04:20:25.392Z" }, + { url = "https://files.pythonhosted.org/packages/2b/46/5da1ec4a5171ee7bf1a0efa064aba70ba3d6e0788ce3f5acd1375d23c8c0/pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32", size = 5304084, upload-time = "2026-02-11T04:20:27.501Z" }, + { url = "https://files.pythonhosted.org/packages/78/93/a29e9bc02d1cf557a834da780ceccd54e02421627200696fcf805ebdc3fb/pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38", size = 4657866, upload-time = "2026-02-11T04:20:29.827Z" }, + { url = "https://files.pythonhosted.org/packages/13/84/583a4558d492a179d31e4aae32eadce94b9acf49c0337c4ce0b70e0a01f2/pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5", size = 6232148, upload-time = "2026-02-11T04:20:31.329Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e2/53c43334bbbb2d3b938978532fbda8e62bb6e0b23a26ce8592f36bcc4987/pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090", size = 8038007, upload-time = "2026-02-11T04:20:34.225Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a6/3d0e79c8a9d58150dd98e199d7c1c56861027f3829a3a60b3c2784190180/pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af", size = 6345418, upload-time = "2026-02-11T04:20:35.858Z" }, + { url = "https://files.pythonhosted.org/packages/a2/c8/46dfeac5825e600579157eea177be43e2f7ff4a99da9d0d0a49533509ac5/pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b", size = 7034590, upload-time = "2026-02-11T04:20:37.91Z" }, + { url = "https://files.pythonhosted.org/packages/af/bf/e6f65d3db8a8bbfeaf9e13cc0417813f6319863a73de934f14b2229ada18/pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5", size = 6458655, upload-time = "2026-02-11T04:20:39.496Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c2/66091f3f34a25894ca129362e510b956ef26f8fb67a0e6417bc5744e56f1/pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d", size = 7159286, upload-time = "2026-02-11T04:20:41.139Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5a/24bc8eb526a22f957d0cec6243146744966d40857e3d8deb68f7902ca6c1/pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c", size = 6328663, upload-time = "2026-02-11T04:20:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/31/03/bef822e4f2d8f9d7448c133d0a18185d3cce3e70472774fffefe8b0ed562/pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563", size = 7031448, upload-time = "2026-02-11T04:20:44.696Z" }, + { url = "https://files.pythonhosted.org/packages/49/70/f76296f53610bd17b2e7d31728b8b7825e3ac3b5b3688b51f52eab7c0818/pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80", size = 2453651, upload-time = "2026-02-11T04:20:46.243Z" }, + { url = "https://files.pythonhosted.org/packages/07/d3/8df65da0d4df36b094351dce696f2989bec731d4f10e743b1c5f4da4d3bf/pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052", size = 5262803, upload-time = "2026-02-11T04:20:47.653Z" }, + { url = "https://files.pythonhosted.org/packages/d6/71/5026395b290ff404b836e636f51d7297e6c83beceaa87c592718747e670f/pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984", size = 4657601, upload-time = "2026-02-11T04:20:49.328Z" }, + { url = "https://files.pythonhosted.org/packages/b1/2e/1001613d941c67442f745aff0f7cc66dd8df9a9c084eb497e6a543ee6f7e/pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79", size = 6234995, upload-time = "2026-02-11T04:20:51.032Z" }, + { url = "https://files.pythonhosted.org/packages/07/26/246ab11455b2549b9233dbd44d358d033a2f780fa9007b61a913c5b2d24e/pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293", size = 8045012, upload-time = "2026-02-11T04:20:52.882Z" }, + { url = "https://files.pythonhosted.org/packages/b2/8b/07587069c27be7535ac1fe33874e32de118fbd34e2a73b7f83436a88368c/pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397", size = 6349638, upload-time = "2026-02-11T04:20:54.444Z" }, + { url = "https://files.pythonhosted.org/packages/ff/79/6df7b2ee763d619cda2fb4fea498e5f79d984dae304d45a8999b80d6cf5c/pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0", size = 7041540, upload-time = "2026-02-11T04:20:55.97Z" }, + { url = "https://files.pythonhosted.org/packages/2c/5e/2ba19e7e7236d7529f4d873bdaf317a318896bac289abebd4bb00ef247f0/pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3", size = 6462613, upload-time = "2026-02-11T04:20:57.542Z" }, + { url = "https://files.pythonhosted.org/packages/03/03/31216ec124bb5c3dacd74ce8efff4cc7f52643653bad4825f8f08c697743/pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35", size = 7166745, upload-time = "2026-02-11T04:20:59.196Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e7/7c4552d80052337eb28653b617eafdef39adfb137c49dd7e831b8dc13bc5/pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a", size = 6328823, upload-time = "2026-02-11T04:21:01.385Z" }, + { url = "https://files.pythonhosted.org/packages/3d/17/688626d192d7261bbbf98846fc98995726bddc2c945344b65bec3a29d731/pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6", size = 7033367, upload-time = "2026-02-11T04:21:03.536Z" }, + { url = "https://files.pythonhosted.org/packages/ed/fe/a0ef1f73f939b0eca03ee2c108d0043a87468664770612602c63266a43c4/pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523", size = 2453811, upload-time = "2026-02-11T04:21:05.116Z" }, + { url = "https://files.pythonhosted.org/packages/d5/11/6db24d4bd7685583caeae54b7009584e38da3c3d4488ed4cd25b439de486/pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e", size = 4062689, upload-time = "2026-02-11T04:21:06.804Z" }, + { url = "https://files.pythonhosted.org/packages/33/c0/ce6d3b1fe190f0021203e0d9b5b99e57843e345f15f9ef22fcd43842fd21/pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9", size = 4138535, upload-time = "2026-02-11T04:21:08.452Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c6/d5eb6a4fb32a3f9c21a8c7613ec706534ea1cf9f4b3663e99f0d83f6fca8/pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6", size = 3601364, upload-time = "2026-02-11T04:21:10.194Z" }, + { url = "https://files.pythonhosted.org/packages/14/a1/16c4b823838ba4c9c52c0e6bbda903a3fe5a1bdbf1b8eb4fff7156f3e318/pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60", size = 5262561, upload-time = "2026-02-11T04:21:11.742Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ad/ad9dc98ff24f485008aa5cdedaf1a219876f6f6c42a4626c08bc4e80b120/pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2", size = 4657460, upload-time = "2026-02-11T04:21:13.786Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1b/f1a4ea9a895b5732152789326202a82464d5254759fbacae4deea3069334/pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850", size = 6232698, upload-time = "2026-02-11T04:21:15.949Z" }, + { url = "https://files.pythonhosted.org/packages/95/f4/86f51b8745070daf21fd2e5b1fe0eb35d4db9ca26e6d58366562fb56a743/pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289", size = 8041706, upload-time = "2026-02-11T04:21:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/29/9b/d6ecd956bb1266dd1045e995cce9b8d77759e740953a1c9aad9502a0461e/pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e", size = 6346621, upload-time = "2026-02-11T04:21:19.547Z" }, + { url = "https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717", size = 7038069, upload-time = "2026-02-11T04:21:21.378Z" }, + { url = "https://files.pythonhosted.org/packages/94/0e/58cb1a6bc48f746bc4cb3adb8cabff73e2742c92b3bf7a220b7cf69b9177/pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a", size = 6460040, upload-time = "2026-02-11T04:21:23.148Z" }, + { url = "https://files.pythonhosted.org/packages/6c/57/9045cb3ff11eeb6c1adce3b2d60d7d299d7b273a2e6c8381a524abfdc474/pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029", size = 7164523, upload-time = "2026-02-11T04:21:25.01Z" }, + { url = "https://files.pythonhosted.org/packages/73/f2/9be9cb99f2175f0d4dbadd6616ce1bf068ee54a28277ea1bf1fbf729c250/pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b", size = 6332552, upload-time = "2026-02-11T04:21:27.238Z" }, + { url = "https://files.pythonhosted.org/packages/3f/eb/b0834ad8b583d7d9d42b80becff092082a1c3c156bb582590fcc973f1c7c/pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1", size = 7040108, upload-time = "2026-02-11T04:21:29.462Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7d/fc09634e2aabdd0feabaff4a32f4a7d97789223e7c2042fd805ea4b4d2c2/pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a", size = 2453712, upload-time = "2026-02-11T04:21:31.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/2a/b9d62794fc8a0dd14c1943df68347badbd5511103e0d04c035ffe5cf2255/pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da", size = 5264880, upload-time = "2026-02-11T04:21:32.865Z" }, + { url = "https://files.pythonhosted.org/packages/26/9d/e03d857d1347fa5ed9247e123fcd2a97b6220e15e9cb73ca0a8d91702c6e/pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc", size = 4660616, upload-time = "2026-02-11T04:21:34.97Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ec/8a6d22afd02570d30954e043f09c32772bfe143ba9285e2fdb11284952cd/pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c", size = 6269008, upload-time = "2026-02-11T04:21:36.623Z" }, + { url = "https://files.pythonhosted.org/packages/3d/1d/6d875422c9f28a4a361f495a5f68d9de4a66941dc2c619103ca335fa6446/pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8", size = 8073226, upload-time = "2026-02-11T04:21:38.585Z" }, + { url = "https://files.pythonhosted.org/packages/a1/cd/134b0b6ee5eda6dc09e25e24b40fdafe11a520bc725c1d0bbaa5e00bf95b/pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20", size = 6380136, upload-time = "2026-02-11T04:21:40.562Z" }, + { url = "https://files.pythonhosted.org/packages/7a/a9/7628f013f18f001c1b98d8fffe3452f306a70dc6aba7d931019e0492f45e/pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13", size = 7067129, upload-time = "2026-02-11T04:21:42.521Z" }, + { url = "https://files.pythonhosted.org/packages/1e/f8/66ab30a2193b277785601e82ee2d49f68ea575d9637e5e234faaa98efa4c/pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf", size = 6491807, upload-time = "2026-02-11T04:21:44.22Z" }, + { url = "https://files.pythonhosted.org/packages/da/0b/a877a6627dc8318fdb84e357c5e1a758c0941ab1ddffdafd231983788579/pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524", size = 7190954, upload-time = "2026-02-11T04:21:46.114Z" }, + { url = "https://files.pythonhosted.org/packages/83/43/6f732ff85743cf746b1361b91665d9f5155e1483817f693f8d57ea93147f/pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986", size = 6336441, upload-time = "2026-02-11T04:21:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/3b/44/e865ef3986611bb75bfabdf94a590016ea327833f434558801122979cd0e/pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c", size = 7045383, upload-time = "2026-02-11T04:21:50.015Z" }, + { url = "https://files.pythonhosted.org/packages/a8/c6/f4fb24268d0c6908b9f04143697ea18b0379490cb74ba9e8d41b898bd005/pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3", size = 2456104, upload-time = "2026-02-11T04:21:51.633Z" }, + { url = "https://files.pythonhosted.org/packages/03/d0/bebb3ffbf31c5a8e97241476c4cf8b9828954693ce6744b4a2326af3e16b/pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af", size = 4062652, upload-time = "2026-02-11T04:21:53.19Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c0/0e16fb0addda4851445c28f8350d8c512f09de27bbb0d6d0bbf8b6709605/pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f", size = 4138823, upload-time = "2026-02-11T04:22:03.088Z" }, + { url = "https://files.pythonhosted.org/packages/6b/fb/6170ec655d6f6bb6630a013dd7cf7bc218423d7b5fa9071bf63dc32175ae/pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642", size = 3601143, upload-time = "2026-02-11T04:22:04.909Z" }, + { url = "https://files.pythonhosted.org/packages/59/04/dc5c3f297510ba9a6837cbb318b87dd2b8f73eb41a43cc63767f65cb599c/pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd", size = 5266254, upload-time = "2026-02-11T04:22:07.656Z" }, + { url = "https://files.pythonhosted.org/packages/05/30/5db1236b0d6313f03ebf97f5e17cda9ca060f524b2fcc875149a8360b21c/pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202", size = 4657499, upload-time = "2026-02-11T04:22:09.613Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/008d2ca0eb612e81968e8be0bbae5051efba24d52debf930126d7eaacbba/pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f", size = 6232137, upload-time = "2026-02-11T04:22:11.434Z" }, + { url = "https://files.pythonhosted.org/packages/70/f1/f14d5b8eeb4b2cd62b9f9f847eb6605f103df89ef619ac68f92f748614ea/pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f", size = 8042721, upload-time = "2026-02-11T04:22:13.321Z" }, + { url = "https://files.pythonhosted.org/packages/5a/d6/17824509146e4babbdabf04d8171491fa9d776f7061ff6e727522df9bd03/pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f", size = 6347798, upload-time = "2026-02-11T04:22:15.449Z" }, + { url = "https://files.pythonhosted.org/packages/d1/ee/c85a38a9ab92037a75615aba572c85ea51e605265036e00c5b67dfafbfe2/pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e", size = 7039315, upload-time = "2026-02-11T04:22:17.24Z" }, + { url = "https://files.pythonhosted.org/packages/ec/f3/bc8ccc6e08a148290d7523bde4d9a0d6c981db34631390dc6e6ec34cacf6/pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0", size = 6462360, upload-time = "2026-02-11T04:22:19.111Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ab/69a42656adb1d0665ab051eec58a41f169ad295cf81ad45406963105408f/pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb", size = 7165438, upload-time = "2026-02-11T04:22:21.041Z" }, + { url = "https://files.pythonhosted.org/packages/02/46/81f7aa8941873f0f01d4b55cc543b0a3d03ec2ee30d617a0448bf6bd6dec/pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f", size = 6431503, upload-time = "2026-02-11T04:22:22.833Z" }, + { url = "https://files.pythonhosted.org/packages/40/72/4c245f7d1044b67affc7f134a09ea619d4895333d35322b775b928180044/pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15", size = 7176748, upload-time = "2026-02-11T04:22:24.64Z" }, + { url = "https://files.pythonhosted.org/packages/e4/ad/8a87bdbe038c5c698736e3348af5c2194ffb872ea52f11894c95f9305435/pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f", size = 2544314, upload-time = "2026-02-11T04:22:26.685Z" }, + { url = "https://files.pythonhosted.org/packages/6c/9d/efd18493f9de13b87ede7c47e69184b9e859e4427225ea962e32e56a49bc/pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8", size = 5268612, upload-time = "2026-02-11T04:22:29.884Z" }, + { url = "https://files.pythonhosted.org/packages/f8/f1/4f42eb2b388eb2ffc660dcb7f7b556c1015c53ebd5f7f754965ef997585b/pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9", size = 4660567, upload-time = "2026-02-11T04:22:31.799Z" }, + { url = "https://files.pythonhosted.org/packages/01/54/df6ef130fa43e4b82e32624a7b821a2be1c5653a5fdad8469687a7db4e00/pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60", size = 6269951, upload-time = "2026-02-11T04:22:33.921Z" }, + { url = "https://files.pythonhosted.org/packages/a9/48/618752d06cc44bb4aae8ce0cd4e6426871929ed7b46215638088270d9b34/pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7", size = 8074769, upload-time = "2026-02-11T04:22:35.877Z" }, + { url = "https://files.pythonhosted.org/packages/c3/bd/f1d71eb39a72fa088d938655afba3e00b38018d052752f435838961127d8/pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f", size = 6381358, upload-time = "2026-02-11T04:22:37.698Z" }, + { url = "https://files.pythonhosted.org/packages/64/ef/c784e20b96674ed36a5af839305f55616f8b4f8aa8eeccf8531a6e312243/pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586", size = 7068558, upload-time = "2026-02-11T04:22:39.597Z" }, + { url = "https://files.pythonhosted.org/packages/73/cb/8059688b74422ae61278202c4e1ad992e8a2e7375227be0a21c6b87ca8d5/pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce", size = 6493028, upload-time = "2026-02-11T04:22:42.73Z" }, + { url = "https://files.pythonhosted.org/packages/c6/da/e3c008ed7d2dd1f905b15949325934510b9d1931e5df999bb15972756818/pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8", size = 7191940, upload-time = "2026-02-11T04:22:44.543Z" }, + { url = "https://files.pythonhosted.org/packages/01/4a/9202e8d11714c1fc5951f2e1ef362f2d7fbc595e1f6717971d5dd750e969/pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36", size = 6438736, upload-time = "2026-02-11T04:22:46.347Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ca/cbce2327eb9885476b3957b2e82eb12c866a8b16ad77392864ad601022ce/pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b", size = 7182894, upload-time = "2026-02-11T04:22:48.114Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d2/de599c95ba0a973b94410477f8bf0b6f0b5e67360eb89bcb1ad365258beb/pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334", size = 2546446, upload-time = "2026-02-11T04:22:50.342Z" }, + { url = "https://files.pythonhosted.org/packages/56/11/5d43209aa4cb58e0cc80127956ff1796a68b928e6324bbf06ef4db34367b/pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f", size = 5228606, upload-time = "2026-02-11T04:22:52.106Z" }, + { url = "https://files.pythonhosted.org/packages/5f/d5/3b005b4e4fda6698b371fa6c21b097d4707585d7db99e98d9b0b87ac612a/pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9", size = 4622321, upload-time = "2026-02-11T04:22:53.827Z" }, + { url = "https://files.pythonhosted.org/packages/df/36/ed3ea2d594356fd8037e5a01f6156c74bc8d92dbb0fa60746cc96cabb6e8/pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e", size = 5247579, upload-time = "2026-02-11T04:22:56.094Z" }, + { url = "https://files.pythonhosted.org/packages/54/9a/9cc3e029683cf6d20ae5085da0dafc63148e3252c2f13328e553aaa13cfb/pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9", size = 6989094, upload-time = "2026-02-11T04:22:58.288Z" }, + { url = "https://files.pythonhosted.org/packages/00/98/fc53ab36da80b88df0967896b6c4b4cd948a0dc5aa40a754266aa3ae48b3/pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3", size = 5313850, upload-time = "2026-02-11T04:23:00.554Z" }, + { url = "https://files.pythonhosted.org/packages/30/02/00fa585abfd9fe9d73e5f6e554dc36cc2b842898cbfc46d70353dae227f8/pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735", size = 5963343, upload-time = "2026-02-11T04:23:02.934Z" }, + { url = "https://files.pythonhosted.org/packages/f2/26/c56ce33ca856e358d27fda9676c055395abddb82c35ac0f593877ed4562e/pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e", size = 7029880, upload-time = "2026-02-11T04:23:04.783Z" }, ] [[package]] From b79673bcd9e53c413cb093679ba50a9fd14e1223 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 15 Feb 2026 13:57:59 +0000 Subject: [PATCH 067/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=AA=9D=20Update?= =?UTF-8?q?=20pre-commit=20hook=20henryiii/validate-pyproject-schema-store?= =?UTF-8?q?=20to=20v2026.02.15=20(#934)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [henryiii/validate-pyproject-schema-store](https://redirect.github.com/henryiii/validate-pyproject-schema-store) | repository | minor | `2026.01.22` → `2026.02.15` | Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://redirect.github.com/renovatebot/renovate/discussions/new) if you have any questions. --- ### Release Notes
henryiii/validate-pyproject-schema-store (henryiii/validate-pyproject-schema-store) ### [`v2026.02.15`](https://redirect.github.com/henryiii/validate-pyproject-schema-store/compare/2026.01.22...2026.02.15) [Compare Source](https://redirect.github.com/henryiii/validate-pyproject-schema-store/compare/2026.01.22...2026.02.15)
--- ### Configuration 📅 **Schedule**: Branch creation - "every weekend" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e3a14ab16..83993ae54 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,7 @@ repos: ## Check the pyproject.toml file - repo: https://github.com/henryiii/validate-pyproject-schema-store - rev: 2026.01.22 + rev: 2026.02.15 hooks: - id: validate-pyproject priority: 0 From 9e51b68f77b57c5e628cd7f1369a2818c1dd05c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 03:34:55 +0000 Subject: [PATCH 068/110] =?UTF-8?q?=E2=AC=86=EF=B8=8F=F0=9F=94=92=EF=B8=8F?= =?UTF-8?q?=20Lock=20file=20maintenance=20(#935)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Update | Change | |---|---| | lockFileMaintenance | All locks refreshed | 🔧 This Pull Request updates lock files to use the latest dependency versions. --- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/munich-quantum-toolkit/qmap). Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- uv.lock | 250 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 129 insertions(+), 121 deletions(-) diff --git a/uv.lock b/uv.lock index 61a008ec3..6076cdce2 100644 --- a/uv.lock +++ b/uv.lock @@ -85,7 +85,7 @@ wheels = [ [[package]] name = "astroid" -version = "4.0.4" +version = "4.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -98,9 +98,9 @@ resolution-markers = [ "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] -sdist = { url = "https://files.pythonhosted.org/packages/07/63/0adf26577da5eff6eb7a177876c1cfa213856be9926a000f65c4add9692b/astroid-4.0.4.tar.gz", hash = "sha256:986fed8bcf79fb82c78b18a53352a0b287a73817d6dbcfba3162da36667c49a0", size = 406358, upload-time = "2026-02-07T23:35:07.509Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/79/f1e971b3700bcc24c09b3f0d47745d8404675a74afc10b32df8e4929dfdc/astroid-4.1.0.tar.gz", hash = "sha256:e2fbab37f205a651e6a168cb1e9a6a10677f6fa6a1c21833d113999855b04259", size = 412160, upload-time = "2026-02-09T02:19:57.705Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/cf/1c5f42b110e57bc5502eb80dbc3b03d256926062519224835ef08134f1f9/astroid-4.0.4-py3-none-any.whl", hash = "sha256:52f39653876c7dec3e3afd4c2696920e05c83832b9737afc21928f2d2eb7a753", size = 276445, upload-time = "2026-02-07T23:35:05.344Z" }, + { url = "https://files.pythonhosted.org/packages/3f/38/b2becedff0bef4af9ff474b82e2dcaefca608b6d24753d0b460c94003d91/astroid-4.1.0-py3-none-any.whl", hash = "sha256:2f8263bc7a33cbe8fc2bf5a3d37cfa8327a3284bf4afe3f47f5f0debba638e36", size = 279168, upload-time = "2026-02-09T02:19:55.89Z" }, ] [[package]] @@ -533,101 +533,115 @@ wheels = [ [[package]] name = "coverage" -version = "7.13.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/43/3e4ac666cc35f231fa70c94e9f38459299de1a152813f9d2f60fc5f3ecaf/coverage-7.13.3.tar.gz", hash = "sha256:f7f6182d3dfb8802c1747eacbfe611b669455b69b7c037484bb1efbbb56711ac", size = 826832, upload-time = "2026-02-03T14:02:30.944Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/07/1c8099563a8a6c389a31c2d0aa1497cee86d6248bb4b9ba5e779215db9f9/coverage-7.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b4f345f7265cdbdb5ec2521ffff15fa49de6d6c39abf89fc7ad68aa9e3a55f0", size = 219143, upload-time = "2026-02-03T13:59:40.459Z" }, - { url = "https://files.pythonhosted.org/packages/69/39/a892d44af7aa092cab70e0cc5cdbba18eeccfe1d6930695dab1742eef9e9/coverage-7.13.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96c3be8bae9d0333e403cc1a8eb078a7f928b5650bae94a18fb4820cc993fb9b", size = 219663, upload-time = "2026-02-03T13:59:41.951Z" }, - { url = "https://files.pythonhosted.org/packages/9a/25/9669dcf4c2bb4c3861469e6db20e52e8c11908cf53c14ec9b12e9fd4d602/coverage-7.13.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d6f4a21328ea49d38565b55599e1c02834e76583a6953e5586d65cb1efebd8f8", size = 246424, upload-time = "2026-02-03T13:59:43.418Z" }, - { url = "https://files.pythonhosted.org/packages/f3/68/d9766c4e298aca62ea5d9543e1dd1e4e1439d7284815244d8b7db1840bfb/coverage-7.13.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fc970575799a9d17d5c3fafd83a0f6ccf5d5117cdc9ad6fbd791e9ead82418b0", size = 248228, upload-time = "2026-02-03T13:59:44.816Z" }, - { url = "https://files.pythonhosted.org/packages/f0/e2/eea6cb4a4bd443741adf008d4cccec83a1f75401df59b6559aca2bdd9710/coverage-7.13.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:87ff33b652b3556b05e204ae20793d1f872161b0fa5ec8a9ac76f8430e152ed6", size = 250103, upload-time = "2026-02-03T13:59:46.271Z" }, - { url = "https://files.pythonhosted.org/packages/db/77/664280ecd666c2191610842177e2fab9e5dbdeef97178e2078fed46a3d2c/coverage-7.13.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7df8759ee57b9f3f7b66799b7660c282f4375bef620ade1686d6a7b03699e75f", size = 247107, upload-time = "2026-02-03T13:59:48.53Z" }, - { url = "https://files.pythonhosted.org/packages/2b/df/2a672eab99e0d0eba52d8a63e47dc92245eee26954d1b2d3c8f7d372151f/coverage-7.13.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f45c9bcb16bee25a798ccba8a2f6a1251b19de6a0d617bb365d7d2f386c4e20e", size = 248143, upload-time = "2026-02-03T13:59:50.027Z" }, - { url = "https://files.pythonhosted.org/packages/a5/dc/a104e7a87c13e57a358b8b9199a8955676e1703bb372d79722b54978ae45/coverage-7.13.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:318b2e4753cbf611061e01b6cc81477e1cdfeb69c36c4a14e6595e674caadb56", size = 246148, upload-time = "2026-02-03T13:59:52.025Z" }, - { url = "https://files.pythonhosted.org/packages/2b/89/e113d3a58dc20b03b7e59aed1e53ebc9ca6167f961876443e002b10e3ae9/coverage-7.13.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:24db3959de8ee394eeeca89ccb8ba25305c2da9a668dd44173394cbd5aa0777f", size = 246414, upload-time = "2026-02-03T13:59:53.859Z" }, - { url = "https://files.pythonhosted.org/packages/3f/60/a3fd0a6e8d89b488396019a2268b6a1f25ab56d6d18f3be50f35d77b47dc/coverage-7.13.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:be14d0622125edef21b3a4d8cd2d138c4872bf6e38adc90fd92385e3312f406a", size = 247023, upload-time = "2026-02-03T13:59:55.454Z" }, - { url = "https://files.pythonhosted.org/packages/19/fa/de4840bb939dbb22ba0648a6d8069fa91c9cf3b3fca8b0d1df461e885b3d/coverage-7.13.3-cp310-cp310-win32.whl", hash = "sha256:53be4aab8ddef18beb6188f3a3fdbf4d1af2277d098d4e618be3a8e6c88e74be", size = 221751, upload-time = "2026-02-03T13:59:57.383Z" }, - { url = "https://files.pythonhosted.org/packages/de/87/233ff8b7ef62fb63f58c78623b50bef69681111e0c4d43504f422d88cda4/coverage-7.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:bfeee64ad8b4aae3233abb77eb6b52b51b05fa89da9645518671b9939a78732b", size = 222686, upload-time = "2026-02-03T13:59:58.825Z" }, - { url = "https://files.pythonhosted.org/packages/ec/09/1ac74e37cf45f17eb41e11a21854f7f92a4c2d6c6098ef4a1becb0c6d8d3/coverage-7.13.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5907605ee20e126eeee2abe14aae137043c2c8af2fa9b38d2ab3b7a6b8137f73", size = 219276, upload-time = "2026-02-03T14:00:00.296Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cb/71908b08b21beb2c437d0d5870c4ec129c570ca1b386a8427fcdb11cf89c/coverage-7.13.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a88705500988c8acad8b8fd86c2a933d3aa96bec1ddc4bc5cb256360db7bbd00", size = 219776, upload-time = "2026-02-03T14:00:02.414Z" }, - { url = "https://files.pythonhosted.org/packages/09/85/c4f3dd69232887666a2c0394d4be21c60ea934d404db068e6c96aa59cd87/coverage-7.13.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bbb5aa9016c4c29e3432e087aa29ebee3f8fda089cfbfb4e6d64bd292dcd1c2", size = 250196, upload-time = "2026-02-03T14:00:04.197Z" }, - { url = "https://files.pythonhosted.org/packages/9c/cc/560ad6f12010344d0778e268df5ba9aa990aacccc310d478bf82bf3d302c/coverage-7.13.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0c2be202a83dde768937a61cdc5d06bf9fb204048ca199d93479488e6247656c", size = 252111, upload-time = "2026-02-03T14:00:05.639Z" }, - { url = "https://files.pythonhosted.org/packages/f0/66/3193985fb2c58e91f94cfbe9e21a6fdf941e9301fe2be9e92c072e9c8f8c/coverage-7.13.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f45e32ef383ce56e0ca099b2e02fcdf7950be4b1b56afaab27b4ad790befe5b", size = 254217, upload-time = "2026-02-03T14:00:07.738Z" }, - { url = "https://files.pythonhosted.org/packages/c5/78/f0f91556bf1faa416792e537c523c5ef9db9b1d32a50572c102b3d7c45b3/coverage-7.13.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6ed2e787249b922a93cd95c671cc9f4c9797a106e81b455c83a9ddb9d34590c0", size = 250318, upload-time = "2026-02-03T14:00:09.224Z" }, - { url = "https://files.pythonhosted.org/packages/6f/aa/fc654e45e837d137b2c1f3a2cc09b4aea1e8b015acd2f774fa0f3d2ddeba/coverage-7.13.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:05dd25b21afffe545e808265897c35f32d3e4437663923e0d256d9ab5031fb14", size = 251909, upload-time = "2026-02-03T14:00:10.712Z" }, - { url = "https://files.pythonhosted.org/packages/73/4d/ab53063992add8a9ca0463c9d92cce5994a29e17affd1c2daa091b922a93/coverage-7.13.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:46d29926349b5c4f1ea4fca95e8c892835515f3600995a383fa9a923b5739ea4", size = 249971, upload-time = "2026-02-03T14:00:12.402Z" }, - { url = "https://files.pythonhosted.org/packages/29/25/83694b81e46fcff9899694a1b6f57573429cdd82b57932f09a698f03eea5/coverage-7.13.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:fae6a21537519c2af00245e834e5bf2884699cc7c1055738fd0f9dc37a3644ad", size = 249692, upload-time = "2026-02-03T14:00:13.868Z" }, - { url = "https://files.pythonhosted.org/packages/d4/ef/d68fc304301f4cb4bf6aefa0045310520789ca38dabdfba9dbecd3f37919/coverage-7.13.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c672d4e2f0575a4ca2bf2aa0c5ced5188220ab806c1bb6d7179f70a11a017222", size = 250597, upload-time = "2026-02-03T14:00:15.461Z" }, - { url = "https://files.pythonhosted.org/packages/8d/85/240ad396f914df361d0f71e912ddcedb48130c71b88dc4193fe3c0306f00/coverage-7.13.3-cp311-cp311-win32.whl", hash = "sha256:fcda51c918c7a13ad93b5f89a58d56e3a072c9e0ba5c231b0ed81404bf2648fb", size = 221773, upload-time = "2026-02-03T14:00:17.462Z" }, - { url = "https://files.pythonhosted.org/packages/2f/71/165b3a6d3d052704a9ab52d11ea64ef3426745de517dda44d872716213a7/coverage-7.13.3-cp311-cp311-win_amd64.whl", hash = "sha256:d1a049b5c51b3b679928dd35e47c4a2235e0b6128b479a7596d0ef5b42fa6301", size = 222711, upload-time = "2026-02-03T14:00:19.449Z" }, - { url = "https://files.pythonhosted.org/packages/51/d0/0ddc9c5934cdd52639c5df1f1eb0fdab51bb52348f3a8d1c7db9c600d93a/coverage-7.13.3-cp311-cp311-win_arm64.whl", hash = "sha256:79f2670c7e772f4917895c3d89aad59e01f3dbe68a4ed2d0373b431fad1dcfba", size = 221377, upload-time = "2026-02-03T14:00:20.968Z" }, - { url = "https://files.pythonhosted.org/packages/94/44/330f8e83b143f6668778ed61d17ece9dc48459e9e74669177de02f45fec5/coverage-7.13.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ed48b4170caa2c4420e0cd27dc977caaffc7eecc317355751df8373dddcef595", size = 219441, upload-time = "2026-02-03T14:00:22.585Z" }, - { url = "https://files.pythonhosted.org/packages/08/e7/29db05693562c2e65bdf6910c0af2fd6f9325b8f43caf7a258413f369e30/coverage-7.13.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8f2adf4bcffbbec41f366f2e6dffb9d24e8172d16e91da5799c9b7ed6b5716e6", size = 219801, upload-time = "2026-02-03T14:00:24.186Z" }, - { url = "https://files.pythonhosted.org/packages/90/ae/7f8a78249b02b0818db46220795f8ac8312ea4abd1d37d79ea81db5cae81/coverage-7.13.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:01119735c690786b6966a1e9f098da4cd7ca9174c4cfe076d04e653105488395", size = 251306, upload-time = "2026-02-03T14:00:25.798Z" }, - { url = "https://files.pythonhosted.org/packages/62/71/a18a53d1808e09b2e9ebd6b47dad5e92daf4c38b0686b4c4d1b2f3e42b7f/coverage-7.13.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8bb09e83c603f152d855f666d70a71765ca8e67332e5829e62cb9466c176af23", size = 254051, upload-time = "2026-02-03T14:00:27.474Z" }, - { url = "https://files.pythonhosted.org/packages/4a/0a/eb30f6455d04c5a3396d0696cad2df0269ae7444bb322f86ffe3376f7bf9/coverage-7.13.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b607a40cba795cfac6d130220d25962931ce101f2f478a29822b19755377fb34", size = 255160, upload-time = "2026-02-03T14:00:29.024Z" }, - { url = "https://files.pythonhosted.org/packages/7b/7e/a45baac86274ce3ed842dbb84f14560c673ad30535f397d89164ec56c5df/coverage-7.13.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:44f14a62f5da2e9aedf9080e01d2cda61df39197d48e323538ec037336d68da8", size = 251709, upload-time = "2026-02-03T14:00:30.641Z" }, - { url = "https://files.pythonhosted.org/packages/c0/df/dd0dc12f30da11349993f3e218901fdf82f45ee44773596050c8f5a1fb25/coverage-7.13.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:debf29e0b157769843dff0981cc76f79e0ed04e36bb773c6cac5f6029054bd8a", size = 253083, upload-time = "2026-02-03T14:00:32.14Z" }, - { url = "https://files.pythonhosted.org/packages/ab/32/fc764c8389a8ce95cb90eb97af4c32f392ab0ac23ec57cadeefb887188d3/coverage-7.13.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:824bb95cd71604031ae9a48edb91fd6effde669522f960375668ed21b36e3ec4", size = 251227, upload-time = "2026-02-03T14:00:34.721Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ca/d025e9da8f06f24c34d2da9873957cfc5f7e0d67802c3e34d0caa8452130/coverage-7.13.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8f1010029a5b52dc427c8e2a8dbddb2303ddd180b806687d1acd1bb1d06649e7", size = 250794, upload-time = "2026-02-03T14:00:36.278Z" }, - { url = "https://files.pythonhosted.org/packages/45/c7/76bf35d5d488ec8f68682eb8e7671acc50a6d2d1c1182de1d2b6d4ffad3b/coverage-7.13.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cd5dee4fd7659d8306ffa79eeaaafd91fa30a302dac3af723b9b469e549247e0", size = 252671, upload-time = "2026-02-03T14:00:38.368Z" }, - { url = "https://files.pythonhosted.org/packages/bf/10/1921f1a03a7c209e1cb374f81a6b9b68b03cdb3ecc3433c189bc90e2a3d5/coverage-7.13.3-cp312-cp312-win32.whl", hash = "sha256:f7f153d0184d45f3873b3ad3ad22694fd73aadcb8cdbc4337ab4b41ea6b4dff1", size = 221986, upload-time = "2026-02-03T14:00:40.442Z" }, - { url = "https://files.pythonhosted.org/packages/3c/7c/f5d93297f8e125a80c15545edc754d93e0ed8ba255b65e609b185296af01/coverage-7.13.3-cp312-cp312-win_amd64.whl", hash = "sha256:03a6e5e1e50819d6d7436f5bc40c92ded7e484e400716886ac921e35c133149d", size = 222793, upload-time = "2026-02-03T14:00:42.106Z" }, - { url = "https://files.pythonhosted.org/packages/43/59/c86b84170015b4555ebabca8649bdf9f4a1f737a73168088385ed0f947c4/coverage-7.13.3-cp312-cp312-win_arm64.whl", hash = "sha256:51c4c42c0e7d09a822b08b6cf79b3c4db8333fffde7450da946719ba0d45730f", size = 221410, upload-time = "2026-02-03T14:00:43.726Z" }, - { url = "https://files.pythonhosted.org/packages/81/f3/4c333da7b373e8c8bfb62517e8174a01dcc373d7a9083698e3b39d50d59c/coverage-7.13.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:853c3d3c79ff0db65797aad79dee6be020efd218ac4510f15a205f1e8d13ce25", size = 219468, upload-time = "2026-02-03T14:00:45.829Z" }, - { url = "https://files.pythonhosted.org/packages/d6/31/0714337b7d23630c8de2f4d56acf43c65f8728a45ed529b34410683f7217/coverage-7.13.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f75695e157c83d374f88dcc646a60cb94173304a9258b2e74ba5a66b7614a51a", size = 219839, upload-time = "2026-02-03T14:00:47.407Z" }, - { url = "https://files.pythonhosted.org/packages/12/99/bd6f2a2738144c98945666f90cae446ed870cecf0421c767475fcf42cdbe/coverage-7.13.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2d098709621d0819039f3f1e471ee554f55a0b2ac0d816883c765b14129b5627", size = 250828, upload-time = "2026-02-03T14:00:49.029Z" }, - { url = "https://files.pythonhosted.org/packages/6f/99/97b600225fbf631e6f5bfd3ad5bcaf87fbb9e34ff87492e5a572ff01bbe2/coverage-7.13.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:16d23d6579cf80a474ad160ca14d8b319abaa6db62759d6eef53b2fc979b58c8", size = 253432, upload-time = "2026-02-03T14:00:50.655Z" }, - { url = "https://files.pythonhosted.org/packages/5f/5c/abe2b3490bda26bd4f5e3e799be0bdf00bd81edebedc2c9da8d3ef288fa8/coverage-7.13.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00d34b29a59d2076e6f318b30a00a69bf63687e30cd882984ed444e753990cc1", size = 254672, upload-time = "2026-02-03T14:00:52.757Z" }, - { url = "https://files.pythonhosted.org/packages/31/ba/5d1957c76b40daff53971fe0adb84d9c2162b614280031d1d0653dd010c1/coverage-7.13.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ab6d72bffac9deb6e6cb0f61042e748de3f9f8e98afb0375a8e64b0b6e11746b", size = 251050, upload-time = "2026-02-03T14:00:54.332Z" }, - { url = "https://files.pythonhosted.org/packages/69/dc/dffdf3bfe9d32090f047d3c3085378558cb4eb6778cda7de414ad74581ed/coverage-7.13.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e129328ad1258e49cae0123a3b5fcb93d6c2fa90d540f0b4c7cdcdc019aaa3dc", size = 252801, upload-time = "2026-02-03T14:00:56.121Z" }, - { url = "https://files.pythonhosted.org/packages/87/51/cdf6198b0f2746e04511a30dc9185d7b8cdd895276c07bdb538e37f1cd50/coverage-7.13.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2213a8d88ed35459bda71597599d4eec7c2ebad201c88f0bfc2c26fd9b0dd2ea", size = 250763, upload-time = "2026-02-03T14:00:58.719Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1a/596b7d62218c1d69f2475b69cc6b211e33c83c902f38ee6ae9766dd422da/coverage-7.13.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:00dd3f02de6d5f5c9c3d95e3e036c3c2e2a669f8bf2d3ceb92505c4ce7838f67", size = 250587, upload-time = "2026-02-03T14:01:01.197Z" }, - { url = "https://files.pythonhosted.org/packages/f7/46/52330d5841ff660f22c130b75f5e1dd3e352c8e7baef5e5fef6b14e3e991/coverage-7.13.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f9bada7bc660d20b23d7d312ebe29e927b655cf414dadcdb6335a2075695bd86", size = 252358, upload-time = "2026-02-03T14:01:02.824Z" }, - { url = "https://files.pythonhosted.org/packages/36/8a/e69a5be51923097ba7d5cff9724466e74fe486e9232020ba97c809a8b42b/coverage-7.13.3-cp313-cp313-win32.whl", hash = "sha256:75b3c0300f3fa15809bd62d9ca8b170eb21fcf0100eb4b4154d6dc8b3a5bbd43", size = 222007, upload-time = "2026-02-03T14:01:04.876Z" }, - { url = "https://files.pythonhosted.org/packages/0a/09/a5a069bcee0d613bdd48ee7637fa73bc09e7ed4342b26890f2df97cc9682/coverage-7.13.3-cp313-cp313-win_amd64.whl", hash = "sha256:a2f7589c6132c44c53f6e705e1a6677e2b7821378c22f7703b2cf5388d0d4587", size = 222812, upload-time = "2026-02-03T14:01:07.296Z" }, - { url = "https://files.pythonhosted.org/packages/3d/4f/d62ad7dfe32f9e3d4a10c178bb6f98b10b083d6e0530ca202b399371f6c1/coverage-7.13.3-cp313-cp313-win_arm64.whl", hash = "sha256:123ceaf2b9d8c614f01110f908a341e05b1b305d6b2ada98763b9a5a59756051", size = 221433, upload-time = "2026-02-03T14:01:09.156Z" }, - { url = "https://files.pythonhosted.org/packages/04/b2/4876c46d723d80b9c5b695f1a11bf5f7c3dabf540ec00d6edc076ff025e6/coverage-7.13.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc7fd0f726795420f3678ac82ff882c7fc33770bd0074463b5aef7293285ace9", size = 220162, upload-time = "2026-02-03T14:01:11.409Z" }, - { url = "https://files.pythonhosted.org/packages/fc/04/9942b64a0e0bdda2c109f56bda42b2a59d9d3df4c94b85a323c1cae9fc77/coverage-7.13.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d358dc408edc28730aed5477a69338e444e62fba0b7e9e4a131c505fadad691e", size = 220510, upload-time = "2026-02-03T14:01:13.038Z" }, - { url = "https://files.pythonhosted.org/packages/5a/82/5cfe1e81eae525b74669f9795f37eb3edd4679b873d79d1e6c1c14ee6c1c/coverage-7.13.3-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5d67b9ed6f7b5527b209b24b3df9f2e5bf0198c1bbf99c6971b0e2dcb7e2a107", size = 261801, upload-time = "2026-02-03T14:01:14.674Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ec/a553d7f742fd2cd12e36a16a7b4b3582d5934b496ef2b5ea8abeb10903d4/coverage-7.13.3-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:59224bfb2e9b37c1335ae35d00daa3a5b4e0b1a20f530be208fff1ecfa436f43", size = 263882, upload-time = "2026-02-03T14:01:16.343Z" }, - { url = "https://files.pythonhosted.org/packages/e1/58/8f54a2a93e3d675635bc406de1c9ac8d551312142ff52c9d71b5e533ad45/coverage-7.13.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9306b5299e31e31e0d3b908c66bcb6e7e3ddca143dea0266e9ce6c667346d3", size = 266306, upload-time = "2026-02-03T14:01:18.02Z" }, - { url = "https://files.pythonhosted.org/packages/1a/be/e593399fd6ea1f00aee79ebd7cc401021f218d34e96682a92e1bae092ff6/coverage-7.13.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:343aaeb5f8bb7bcd38620fd7bc56e6ee8207847d8c6103a1e7b72322d381ba4a", size = 261051, upload-time = "2026-02-03T14:01:19.757Z" }, - { url = "https://files.pythonhosted.org/packages/5c/e5/e9e0f6138b21bcdebccac36fbfde9cf15eb1bbcea9f5b1f35cd1f465fb91/coverage-7.13.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b2182129f4c101272ff5f2f18038d7b698db1bf8e7aa9e615cb48440899ad32e", size = 263868, upload-time = "2026-02-03T14:01:21.487Z" }, - { url = "https://files.pythonhosted.org/packages/9a/bf/de72cfebb69756f2d4a2dde35efcc33c47d85cd3ebdf844b3914aac2ef28/coverage-7.13.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:94d2ac94bd0cc57c5626f52f8c2fffed1444b5ae8c9fc68320306cc2b255e155", size = 261498, upload-time = "2026-02-03T14:01:23.097Z" }, - { url = "https://files.pythonhosted.org/packages/f2/91/4a2d313a70fc2e98ca53afd1c8ce67a89b1944cd996589a5b1fe7fbb3e5c/coverage-7.13.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:65436cde5ecabe26fb2f0bf598962f0a054d3f23ad529361326ac002c61a2a1e", size = 260394, upload-time = "2026-02-03T14:01:24.949Z" }, - { url = "https://files.pythonhosted.org/packages/40/83/25113af7cf6941e779eb7ed8de2a677865b859a07ccee9146d4cc06a03e3/coverage-7.13.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:db83b77f97129813dbd463a67e5335adc6a6a91db652cc085d60c2d512746f96", size = 262579, upload-time = "2026-02-03T14:01:26.703Z" }, - { url = "https://files.pythonhosted.org/packages/1e/19/a5f2b96262977e82fb9aabbe19b4d83561f5d063f18dde3e72f34ffc3b2f/coverage-7.13.3-cp313-cp313t-win32.whl", hash = "sha256:dfb428e41377e6b9ba1b0a32df6db5409cb089a0ed1d0a672dc4953ec110d84f", size = 222679, upload-time = "2026-02-03T14:01:28.553Z" }, - { url = "https://files.pythonhosted.org/packages/81/82/ef1747b88c87a5c7d7edc3704799ebd650189a9158e680a063308b6125ef/coverage-7.13.3-cp313-cp313t-win_amd64.whl", hash = "sha256:5badd7e596e6b0c89aa8ec6d37f4473e4357f982ce57f9a2942b0221cd9cf60c", size = 223740, upload-time = "2026-02-03T14:01:30.776Z" }, - { url = "https://files.pythonhosted.org/packages/1c/4c/a67c7bb5b560241c22736a9cb2f14c5034149ffae18630323fde787339e4/coverage-7.13.3-cp313-cp313t-win_arm64.whl", hash = "sha256:989aa158c0eb19d83c76c26f4ba00dbb272485c56e452010a3450bdbc9daafd9", size = 221996, upload-time = "2026-02-03T14:01:32.495Z" }, - { url = "https://files.pythonhosted.org/packages/5e/b3/677bb43427fed9298905106f39c6520ac75f746f81b8f01104526a8026e4/coverage-7.13.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c6f6169bbdbdb85aab8ac0392d776948907267fcc91deeacf6f9d55f7a83ae3b", size = 219513, upload-time = "2026-02-03T14:01:34.29Z" }, - { url = "https://files.pythonhosted.org/packages/42/53/290046e3bbf8986cdb7366a42dab3440b9983711eaff044a51b11006c67b/coverage-7.13.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2f5e731627a3d5ef11a2a35aa0c6f7c435867c7ccbc391268eb4f2ca5dbdcc10", size = 219850, upload-time = "2026-02-03T14:01:35.984Z" }, - { url = "https://files.pythonhosted.org/packages/ea/2b/ab41f10345ba2e49d5e299be8663be2b7db33e77ac1b85cd0af985ea6406/coverage-7.13.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9db3a3285d91c0b70fab9f39f0a4aa37d375873677efe4e71e58d8321e8c5d39", size = 250886, upload-time = "2026-02-03T14:01:38.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/2d/b3f6913ee5a1d5cdd04106f257e5fac5d048992ffc2d9995d07b0f17739f/coverage-7.13.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:06e49c5897cb12e3f7ecdc111d44e97c4f6d0557b81a7a0204ed70a8b038f86f", size = 253393, upload-time = "2026-02-03T14:01:40.118Z" }, - { url = "https://files.pythonhosted.org/packages/f0/f6/b1f48810ffc6accf49a35b9943636560768f0812330f7456aa87dc39aff5/coverage-7.13.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb25061a66802df9fc13a9ba1967d25faa4dae0418db469264fd9860a921dde4", size = 254740, upload-time = "2026-02-03T14:01:42.413Z" }, - { url = "https://files.pythonhosted.org/packages/57/d0/e59c54f9be0b61808f6bc4c8c4346bd79f02dd6bbc3f476ef26124661f20/coverage-7.13.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:99fee45adbb1caeb914da16f70e557fb7ff6ddc9e4b14de665bd41af631367ef", size = 250905, upload-time = "2026-02-03T14:01:44.163Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f7/5291bcdf498bafbee3796bb32ef6966e9915aebd4d0954123c8eae921c32/coverage-7.13.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:318002f1fd819bdc1651c619268aa5bc853c35fa5cc6d1e8c96bd9cd6c828b75", size = 252753, upload-time = "2026-02-03T14:01:45.974Z" }, - { url = "https://files.pythonhosted.org/packages/a0/a9/1dcafa918c281554dae6e10ece88c1add82db685be123e1b05c2056ff3fb/coverage-7.13.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:71295f2d1d170b9977dc386d46a7a1b7cbb30e5405492529b4c930113a33f895", size = 250716, upload-time = "2026-02-03T14:01:48.844Z" }, - { url = "https://files.pythonhosted.org/packages/44/bb/4ea4eabcce8c4f6235df6e059fbc5db49107b24c4bdffc44aee81aeca5a8/coverage-7.13.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5b1ad2e0dc672625c44bc4fe34514602a9fd8b10d52ddc414dc585f74453516c", size = 250530, upload-time = "2026-02-03T14:01:50.793Z" }, - { url = "https://files.pythonhosted.org/packages/6d/31/4a6c9e6a71367e6f923b27b528448c37f4e959b7e4029330523014691007/coverage-7.13.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b2beb64c145593a50d90db5c7178f55daeae129123b0d265bdb3cbec83e5194a", size = 252186, upload-time = "2026-02-03T14:01:52.607Z" }, - { url = "https://files.pythonhosted.org/packages/27/92/e1451ef6390a4f655dc42da35d9971212f7abbbcad0bdb7af4407897eb76/coverage-7.13.3-cp314-cp314-win32.whl", hash = "sha256:3d1aed4f4e837a832df2f3b4f68a690eede0de4560a2dbc214ea0bc55aabcdb4", size = 222253, upload-time = "2026-02-03T14:01:55.071Z" }, - { url = "https://files.pythonhosted.org/packages/8a/98/78885a861a88de020c32a2693487c37d15a9873372953f0c3c159d575a43/coverage-7.13.3-cp314-cp314-win_amd64.whl", hash = "sha256:9f9efbbaf79f935d5fbe3ad814825cbce4f6cdb3054384cb49f0c0f496125fa0", size = 223069, upload-time = "2026-02-03T14:01:56.95Z" }, - { url = "https://files.pythonhosted.org/packages/eb/fb/3784753a48da58a5337972abf7ca58b1fb0f1bda21bc7b4fae992fd28e47/coverage-7.13.3-cp314-cp314-win_arm64.whl", hash = "sha256:31b6e889c53d4e6687ca63706148049494aace140cffece1c4dc6acadb70a7b3", size = 221633, upload-time = "2026-02-03T14:01:58.758Z" }, - { url = "https://files.pythonhosted.org/packages/40/f9/75b732d9674d32cdbffe801ed5f770786dd1c97eecedef2125b0d25102dc/coverage-7.13.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c5e9787cec750793a19a28df7edd85ac4e49d3fb91721afcdc3b86f6c08d9aa8", size = 220243, upload-time = "2026-02-03T14:02:01.109Z" }, - { url = "https://files.pythonhosted.org/packages/cf/7e/2868ec95de5a65703e6f0c87407ea822d1feb3619600fbc3c1c4fa986090/coverage-7.13.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5b86db331c682fd0e4be7098e6acee5e8a293f824d41487c667a93705d415ca", size = 220515, upload-time = "2026-02-03T14:02:02.862Z" }, - { url = "https://files.pythonhosted.org/packages/7d/eb/9f0d349652fced20bcaea0f67fc5777bd097c92369f267975732f3dc5f45/coverage-7.13.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:edc7754932682d52cf6e7a71806e529ecd5ce660e630e8bd1d37109a2e5f63ba", size = 261874, upload-time = "2026-02-03T14:02:04.727Z" }, - { url = "https://files.pythonhosted.org/packages/ee/a5/6619bc4a6c7b139b16818149a3e74ab2e21599ff9a7b6811b6afde99f8ec/coverage-7.13.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3a16d6398666510a6886f67f43d9537bfd0e13aca299688a19daa84f543122f", size = 264004, upload-time = "2026-02-03T14:02:06.634Z" }, - { url = "https://files.pythonhosted.org/packages/29/b7/90aa3fc645a50c6f07881fca4fd0ba21e3bfb6ce3a7078424ea3a35c74c9/coverage-7.13.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:303d38b19626c1981e1bb067a9928236d88eb0e4479b18a74812f05a82071508", size = 266408, upload-time = "2026-02-03T14:02:09.037Z" }, - { url = "https://files.pythonhosted.org/packages/62/55/08bb2a1e4dcbae384e638f0effef486ba5987b06700e481691891427d879/coverage-7.13.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:284e06eadfe15ddfee2f4ee56631f164ef897a7d7d5a15bca5f0bb88889fc5ba", size = 260977, upload-time = "2026-02-03T14:02:11.755Z" }, - { url = "https://files.pythonhosted.org/packages/9b/76/8bd4ae055a42d8fb5dd2230e5cf36ff2e05f85f2427e91b11a27fea52ed7/coverage-7.13.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d401f0864a1d3198422816878e4e84ca89ec1c1bf166ecc0ae01380a39b888cd", size = 263868, upload-time = "2026-02-03T14:02:13.565Z" }, - { url = "https://files.pythonhosted.org/packages/e3/f9/ba000560f11e9e32ec03df5aa8477242c2d95b379c99ac9a7b2e7fbacb1a/coverage-7.13.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3f379b02c18a64de78c4ccdddf1c81c2c5ae1956c72dacb9133d7dd7809794ab", size = 261474, upload-time = "2026-02-03T14:02:16.069Z" }, - { url = "https://files.pythonhosted.org/packages/90/4b/4de4de8f9ca7af4733bfcf4baa440121b7dbb3856daf8428ce91481ff63b/coverage-7.13.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:7a482f2da9086971efb12daca1d6547007ede3674ea06e16d7663414445c683e", size = 260317, upload-time = "2026-02-03T14:02:17.996Z" }, - { url = "https://files.pythonhosted.org/packages/05/71/5cd8436e2c21410ff70be81f738c0dddea91bcc3189b1517d26e0102ccb3/coverage-7.13.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:562136b0d401992118d9b49fbee5454e16f95f85b120a4226a04d816e33fe024", size = 262635, upload-time = "2026-02-03T14:02:20.405Z" }, - { url = "https://files.pythonhosted.org/packages/e7/f8/2834bb45bdd70b55a33ec354b8b5f6062fc90e5bb787e14385903a979503/coverage-7.13.3-cp314-cp314t-win32.whl", hash = "sha256:ca46e5c3be3b195098dd88711890b8011a9fa4feca942292bb84714ce5eab5d3", size = 223035, upload-time = "2026-02-03T14:02:22.323Z" }, - { url = "https://files.pythonhosted.org/packages/26/75/f8290f0073c00d9ae14056d2b84ab92dff21d5370e464cb6cb06f52bf580/coverage-7.13.3-cp314-cp314t-win_amd64.whl", hash = "sha256:06d316dbb3d9fd44cca05b2dbcfbef22948493d63a1f28e828d43e6cc505fed8", size = 224142, upload-time = "2026-02-03T14:02:24.143Z" }, - { url = "https://files.pythonhosted.org/packages/03/01/43ac78dfea8946c4a9161bbc034b5549115cb2b56781a4b574927f0d141a/coverage-7.13.3-cp314-cp314t-win_arm64.whl", hash = "sha256:299d66e9218193f9dc6e4880629ed7c4cd23486005166247c283fb98531656c3", size = 222166, upload-time = "2026-02-03T14:02:26.005Z" }, - { url = "https://files.pythonhosted.org/packages/7d/fb/70af542d2d938c778c9373ce253aa4116dbe7c0a5672f78b2b2ae0e1b94b/coverage-7.13.3-py3-none-any.whl", hash = "sha256:90a8af9dba6429b2573199622d72e0ebf024d6276f16abce394ad4d181bb0910", size = 211237, upload-time = "2026-02-03T14:02:27.986Z" }, +version = "7.13.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91", size = 827239, upload-time = "2026-02-09T12:59:03.86Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/d4/7827d9ffa34d5d4d752eec907022aa417120936282fc488306f5da08c292/coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415", size = 219152, upload-time = "2026-02-09T12:56:11.974Z" }, + { url = "https://files.pythonhosted.org/packages/35/b0/d69df26607c64043292644dbb9dc54b0856fabaa2cbb1eeee3331cc9e280/coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b", size = 219667, upload-time = "2026-02-09T12:56:13.33Z" }, + { url = "https://files.pythonhosted.org/packages/82/a4/c1523f7c9e47b2271dbf8c2a097e7a1f89ef0d66f5840bb59b7e8814157b/coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a", size = 246425, upload-time = "2026-02-09T12:56:14.552Z" }, + { url = "https://files.pythonhosted.org/packages/f8/02/aa7ec01d1a5023c4b680ab7257f9bfde9defe8fdddfe40be096ac19e8177/coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f", size = 248229, upload-time = "2026-02-09T12:56:16.31Z" }, + { url = "https://files.pythonhosted.org/packages/35/98/85aba0aed5126d896162087ef3f0e789a225697245256fc6181b95f47207/coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012", size = 250106, upload-time = "2026-02-09T12:56:18.024Z" }, + { url = "https://files.pythonhosted.org/packages/96/72/1db59bd67494bc162e3e4cd5fbc7edba2c7026b22f7c8ef1496d58c2b94c/coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def", size = 252021, upload-time = "2026-02-09T12:56:19.272Z" }, + { url = "https://files.pythonhosted.org/packages/9d/97/72899c59c7066961de6e3daa142d459d47d104956db43e057e034f015c8a/coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256", size = 247114, upload-time = "2026-02-09T12:56:21.051Z" }, + { url = "https://files.pythonhosted.org/packages/39/1f/f1885573b5970235e908da4389176936c8933e86cb316b9620aab1585fa2/coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda", size = 248143, upload-time = "2026-02-09T12:56:22.585Z" }, + { url = "https://files.pythonhosted.org/packages/a8/cf/e80390c5b7480b722fa3e994f8202807799b85bc562aa4f1dde209fbb7be/coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92", size = 246152, upload-time = "2026-02-09T12:56:23.748Z" }, + { url = "https://files.pythonhosted.org/packages/44/bf/f89a8350d85572f95412debb0fb9bb4795b1d5b5232bd652923c759e787b/coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c", size = 249959, upload-time = "2026-02-09T12:56:25.209Z" }, + { url = "https://files.pythonhosted.org/packages/f7/6e/612a02aece8178c818df273e8d1642190c4875402ca2ba74514394b27aba/coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58", size = 246416, upload-time = "2026-02-09T12:56:26.475Z" }, + { url = "https://files.pythonhosted.org/packages/cb/98/b5afc39af67c2fa6786b03c3a7091fc300947387ce8914b096db8a73d67a/coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9", size = 247025, upload-time = "2026-02-09T12:56:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/51/30/2bba8ef0682d5bd210c38fe497e12a06c9f8d663f7025e9f5c2c31ce847d/coverage-7.13.4-cp310-cp310-win32.whl", hash = "sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf", size = 221758, upload-time = "2026-02-09T12:56:29.051Z" }, + { url = "https://files.pythonhosted.org/packages/78/13/331f94934cf6c092b8ea59ff868eb587bc8fe0893f02c55bc6c0183a192e/coverage-7.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95", size = 222693, upload-time = "2026-02-09T12:56:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053", size = 219278, upload-time = "2026-02-09T12:56:31.673Z" }, + { url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11", size = 219783, upload-time = "2026-02-09T12:56:33.104Z" }, + { url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa", size = 250200, upload-time = "2026-02-09T12:56:34.474Z" }, + { url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7", size = 252114, upload-time = "2026-02-09T12:56:35.749Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00", size = 254220, upload-time = "2026-02-09T12:56:37.796Z" }, + { url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef", size = 256164, upload-time = "2026-02-09T12:56:39.016Z" }, + { url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903", size = 250325, upload-time = "2026-02-09T12:56:40.668Z" }, + { url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f", size = 251913, upload-time = "2026-02-09T12:56:41.97Z" }, + { url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299", size = 249974, upload-time = "2026-02-09T12:56:43.323Z" }, + { url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505", size = 253741, upload-time = "2026-02-09T12:56:45.155Z" }, + { url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6", size = 249695, upload-time = "2026-02-09T12:56:46.636Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9", size = 250599, upload-time = "2026-02-09T12:56:48.13Z" }, + { url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9", size = 221780, upload-time = "2026-02-09T12:56:50.479Z" }, + { url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f", size = 222715, upload-time = "2026-02-09T12:56:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f", size = 221385, upload-time = "2026-02-09T12:56:53.194Z" }, + { url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459", size = 219449, upload-time = "2026-02-09T12:56:54.889Z" }, + { url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3", size = 219810, upload-time = "2026-02-09T12:56:56.33Z" }, + { url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634", size = 251308, upload-time = "2026-02-09T12:56:57.858Z" }, + { url = "https://files.pythonhosted.org/packages/5d/a0/2ea570925524ef4e00bb6c82649f5682a77fac5ab910a65c9284de422600/coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3", size = 254052, upload-time = "2026-02-09T12:56:59.754Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ac/45dc2e19a1939098d783c846e130b8f862fbb50d09e0af663988f2f21973/coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa", size = 255165, upload-time = "2026-02-09T12:57:01.287Z" }, + { url = "https://files.pythonhosted.org/packages/2d/4d/26d236ff35abc3b5e63540d3386e4c3b192168c1d96da5cb2f43c640970f/coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3", size = 257432, upload-time = "2026-02-09T12:57:02.637Z" }, + { url = "https://files.pythonhosted.org/packages/ec/55/14a966c757d1348b2e19caf699415a2a4c4f7feaa4bbc6326a51f5c7dd1b/coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a", size = 251716, upload-time = "2026-02-09T12:57:04.056Z" }, + { url = "https://files.pythonhosted.org/packages/77/33/50116647905837c66d28b2af1321b845d5f5d19be9655cb84d4a0ea806b4/coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7", size = 253089, upload-time = "2026-02-09T12:57:05.503Z" }, + { url = "https://files.pythonhosted.org/packages/c2/b4/8efb11a46e3665d92635a56e4f2d4529de6d33f2cb38afd47d779d15fc99/coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc", size = 251232, upload-time = "2026-02-09T12:57:06.879Z" }, + { url = "https://files.pythonhosted.org/packages/51/24/8cd73dd399b812cc76bb0ac260e671c4163093441847ffe058ac9fda1e32/coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47", size = 255299, upload-time = "2026-02-09T12:57:08.245Z" }, + { url = "https://files.pythonhosted.org/packages/03/94/0a4b12f1d0e029ce1ccc1c800944a9984cbe7d678e470bb6d3c6bc38a0da/coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985", size = 250796, upload-time = "2026-02-09T12:57:10.142Z" }, + { url = "https://files.pythonhosted.org/packages/73/44/6002fbf88f6698ca034360ce474c406be6d5a985b3fdb3401128031eef6b/coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0", size = 252673, upload-time = "2026-02-09T12:57:12.197Z" }, + { url = "https://files.pythonhosted.org/packages/de/c6/a0279f7c00e786be75a749a5674e6fa267bcbd8209cd10c9a450c655dfa7/coverage-7.13.4-cp312-cp312-win32.whl", hash = "sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246", size = 221990, upload-time = "2026-02-09T12:57:14.085Z" }, + { url = "https://files.pythonhosted.org/packages/77/4e/c0a25a425fcf5557d9abd18419c95b63922e897bc86c1f327f155ef234a9/coverage-7.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126", size = 222800, upload-time = "2026-02-09T12:57:15.944Z" }, + { url = "https://files.pythonhosted.org/packages/47/ac/92da44ad9a6f4e3a7debd178949d6f3769bedca33830ce9b1dcdab589a37/coverage-7.13.4-cp312-cp312-win_arm64.whl", hash = "sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d", size = 221415, upload-time = "2026-02-09T12:57:17.497Z" }, + { url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9", size = 219474, upload-time = "2026-02-09T12:57:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac", size = 219844, upload-time = "2026-02-09T12:57:20.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea", size = 250832, upload-time = "2026-02-09T12:57:22.007Z" }, + { url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b", size = 253434, upload-time = "2026-02-09T12:57:23.339Z" }, + { url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525", size = 254676, upload-time = "2026-02-09T12:57:24.774Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242", size = 256807, upload-time = "2026-02-09T12:57:26.125Z" }, + { url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148", size = 251058, upload-time = "2026-02-09T12:57:27.614Z" }, + { url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a", size = 252805, upload-time = "2026-02-09T12:57:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23", size = 250766, upload-time = "2026-02-09T12:57:30.522Z" }, + { url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80", size = 254923, upload-time = "2026-02-09T12:57:31.946Z" }, + { url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea", size = 250591, upload-time = "2026-02-09T12:57:33.842Z" }, + { url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a", size = 252364, upload-time = "2026-02-09T12:57:35.743Z" }, + { url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl", hash = "sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d", size = 222010, upload-time = "2026-02-09T12:57:37.25Z" }, + { url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd", size = 222818, upload-time = "2026-02-09T12:57:38.734Z" }, + { url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl", hash = "sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af", size = 221438, upload-time = "2026-02-09T12:57:40.223Z" }, + { url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d", size = 220165, upload-time = "2026-02-09T12:57:41.639Z" }, + { url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12", size = 220516, upload-time = "2026-02-09T12:57:44.215Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b", size = 261804, upload-time = "2026-02-09T12:57:45.989Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9", size = 263885, upload-time = "2026-02-09T12:57:47.42Z" }, + { url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092", size = 266308, upload-time = "2026-02-09T12:57:49.345Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9", size = 267452, upload-time = "2026-02-09T12:57:50.811Z" }, + { url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26", size = 261057, upload-time = "2026-02-09T12:57:52.447Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2", size = 263875, upload-time = "2026-02-09T12:57:53.938Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940", size = 261500, upload-time = "2026-02-09T12:57:56.012Z" }, + { url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c", size = 265212, upload-time = "2026-02-09T12:57:57.5Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0", size = 260398, upload-time = "2026-02-09T12:57:59.027Z" }, + { url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b", size = 262584, upload-time = "2026-02-09T12:58:01.129Z" }, + { url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl", hash = "sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9", size = 222688, upload-time = "2026-02-09T12:58:02.736Z" }, + { url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl", hash = "sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd", size = 223746, upload-time = "2026-02-09T12:58:05.362Z" }, + { url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl", hash = "sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997", size = 222003, upload-time = "2026-02-09T12:58:06.952Z" }, + { url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601", size = 219522, upload-time = "2026-02-09T12:58:08.623Z" }, + { url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689", size = 219855, upload-time = "2026-02-09T12:58:10.176Z" }, + { url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c", size = 250887, upload-time = "2026-02-09T12:58:12.503Z" }, + { url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129", size = 253396, upload-time = "2026-02-09T12:58:14.615Z" }, + { url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552", size = 254745, upload-time = "2026-02-09T12:58:16.162Z" }, + { url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a", size = 257055, upload-time = "2026-02-09T12:58:17.892Z" }, + { url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356", size = 250911, upload-time = "2026-02-09T12:58:19.495Z" }, + { url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71", size = 252754, upload-time = "2026-02-09T12:58:21.064Z" }, + { url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5", size = 250720, upload-time = "2026-02-09T12:58:22.622Z" }, + { url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98", size = 254994, upload-time = "2026-02-09T12:58:24.548Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5", size = 250531, upload-time = "2026-02-09T12:58:26.271Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0", size = 252189, upload-time = "2026-02-09T12:58:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl", hash = "sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb", size = 222258, upload-time = "2026-02-09T12:58:29.441Z" }, + { url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505", size = 223073, upload-time = "2026-02-09T12:58:31.026Z" }, + { url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl", hash = "sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2", size = 221638, upload-time = "2026-02-09T12:58:32.599Z" }, + { url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056", size = 220246, upload-time = "2026-02-09T12:58:34.181Z" }, + { url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc", size = 220514, upload-time = "2026-02-09T12:58:35.704Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9", size = 261877, upload-time = "2026-02-09T12:58:37.864Z" }, + { url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf", size = 264004, upload-time = "2026-02-09T12:58:39.492Z" }, + { url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55", size = 266408, upload-time = "2026-02-09T12:58:41.852Z" }, + { url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72", size = 267544, upload-time = "2026-02-09T12:58:44.093Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a", size = 260980, upload-time = "2026-02-09T12:58:45.721Z" }, + { url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6", size = 263871, upload-time = "2026-02-09T12:58:47.334Z" }, + { url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3", size = 261472, upload-time = "2026-02-09T12:58:48.995Z" }, + { url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750", size = 265210, upload-time = "2026-02-09T12:58:51.178Z" }, + { url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39", size = 260319, upload-time = "2026-02-09T12:58:53.081Z" }, + { url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0", size = 262638, upload-time = "2026-02-09T12:58:55.258Z" }, + { url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl", hash = "sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea", size = 223040, upload-time = "2026-02-09T12:58:56.936Z" }, + { url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932", size = 224148, upload-time = "2026-02-09T12:58:58.645Z" }, + { url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl", hash = "sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b", size = 222172, upload-time = "2026-02-09T12:59:00.396Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0", size = 211242, upload-time = "2026-02-09T12:59:02.032Z" }, ] [package.optional-dependencies] @@ -802,11 +816,11 @@ wheels = [ [[package]] name = "filelock" -version = "3.20.3" +version = "3.24.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/65/ce7f1b70157833bf3cb851b556a37d4547ceafc158aa9b34b36782f23696/filelock-3.20.3.tar.gz", hash = "sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1", size = 19485, upload-time = "2026-01-09T17:55:05.421Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4f/8a/b24ff2c2d7f20ce930b5efe91e7260247d185d8939707721168ad204e465/filelock-3.24.1.tar.gz", hash = "sha256:3440181dd03f8904c108c8e9f5b11d1663e9fc960f1c837586a11f1c5c041e54", size = 37452, upload-time = "2026-02-15T22:03:16.564Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/36/7fb70f04bf00bc646cd5bb45aa9eddb15e19437a28b8fb2b4a5249fac770/filelock-3.20.3-py3-none-any.whl", hash = "sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1", size = 16701, upload-time = "2026-01-09T17:55:04.334Z" }, + { url = "https://files.pythonhosted.org/packages/97/64/3613e89811e79aca8d0d4f2c984fc66336bc9d83529c1cbe02f5df010d0a/filelock-3.24.1-py3-none-any.whl", hash = "sha256:7c59f595e3cf4887dc95b403a896849da49ed183d7c9d7ee855646ca99f10698", size = 24153, upload-time = "2026-02-15T22:03:15.262Z" }, ] [[package]] @@ -893,7 +907,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/65/5b235b40581ad75ab97dcd8b4218022ae8e3ab77c13c919f1a1dfe9171fd/greenlet-3.3.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04bee4775f40ecefcdaa9d115ab44736cd4b9c5fba733575bfe9379419582e13", size = 273723, upload-time = "2026-01-23T15:30:37.521Z" }, { url = "https://files.pythonhosted.org/packages/ce/ad/eb4729b85cba2d29499e0a04ca6fbdd8f540afd7be142fd571eea43d712f/greenlet-3.3.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e1457f4fed12a50e427988a07f0f9df53cf0ee8da23fab16e6732c2ec909d4", size = 574874, upload-time = "2026-01-23T16:00:54.551Z" }, { url = "https://files.pythonhosted.org/packages/87/32/57cad7fe4c8b82fdaa098c89498ef85ad92dfbb09d5eb713adedfc2ae1f5/greenlet-3.3.1-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:070472cd156f0656f86f92e954591644e158fd65aa415ffbe2d44ca77656a8f5", size = 586309, upload-time = "2026-01-23T16:05:25.18Z" }, - { url = "https://files.pythonhosted.org/packages/66/66/f041005cb87055e62b0d68680e88ec1a57f4688523d5e2fb305841bc8307/greenlet-3.3.1-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1108b61b06b5224656121c3c8ee8876161c491cbe74e5c519e0634c837cf93d5", size = 597461, upload-time = "2026-01-23T16:15:51.943Z" }, { url = "https://files.pythonhosted.org/packages/87/eb/8a1ec2da4d55824f160594a75a9d8354a5fe0a300fb1c48e7944265217e1/greenlet-3.3.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a300354f27dd86bae5fbf7002e6dd2b3255cd372e9242c933faf5e859b703fe", size = 586985, upload-time = "2026-01-23T15:32:47.968Z" }, { url = "https://files.pythonhosted.org/packages/15/1c/0621dd4321dd8c351372ee8f9308136acb628600658a49be1b7504208738/greenlet-3.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e84b51cbebf9ae573b5fbd15df88887815e3253fc000a7d0ff95170e8f7e9729", size = 1547271, upload-time = "2026-01-23T16:04:18.977Z" }, { url = "https://files.pythonhosted.org/packages/9d/53/24047f8924c83bea7a59c8678d9571209c6bfe5f4c17c94a78c06024e9f2/greenlet-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0093bd1a06d899892427217f0ff2a3c8f306182b8c754336d32e2d587c131b4", size = 1613427, upload-time = "2026-01-23T15:33:44.428Z" }, @@ -901,7 +914,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/e8/2e1462c8fdbe0f210feb5ac7ad2d9029af8be3bf45bd9fa39765f821642f/greenlet-3.3.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5fd23b9bc6d37b563211c6abbb1b3cab27db385a4449af5c32e932f93017080c", size = 274974, upload-time = "2026-01-23T15:31:02.891Z" }, { url = "https://files.pythonhosted.org/packages/7e/a8/530a401419a6b302af59f67aaf0b9ba1015855ea7e56c036b5928793c5bd/greenlet-3.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f51496a0bfbaa9d74d36a52d2580d1ef5ed4fdfcff0a73730abfbbbe1403dd", size = 577175, upload-time = "2026-01-23T16:00:56.213Z" }, { url = "https://files.pythonhosted.org/packages/8e/89/7e812bb9c05e1aaef9b597ac1d0962b9021d2c6269354966451e885c4e6b/greenlet-3.3.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb0feb07fe6e6a74615ee62a880007d976cf739b6669cce95daa7373d4fc69c5", size = 590401, upload-time = "2026-01-23T16:05:26.365Z" }, - { url = "https://files.pythonhosted.org/packages/70/ae/e2d5f0e59b94a2269b68a629173263fa40b63da32f5c231307c349315871/greenlet-3.3.1-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:67ea3fc73c8cd92f42467a72b75e8f05ed51a0e9b1d15398c913416f2dafd49f", size = 601161, upload-time = "2026-01-23T16:15:53.456Z" }, { url = "https://files.pythonhosted.org/packages/5c/ae/8d472e1f5ac5efe55c563f3eabb38c98a44b832602e12910750a7c025802/greenlet-3.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39eda9ba259cc9801da05351eaa8576e9aa83eb9411e8f0c299e05d712a210f2", size = 590272, upload-time = "2026-01-23T15:32:49.411Z" }, { url = "https://files.pythonhosted.org/packages/a8/51/0fde34bebfcadc833550717eade64e35ec8738e6b097d5d248274a01258b/greenlet-3.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e2e7e882f83149f0a71ac822ebf156d902e7a5d22c9045e3e0d1daf59cee2cc9", size = 1550729, upload-time = "2026-01-23T16:04:20.867Z" }, { url = "https://files.pythonhosted.org/packages/16/c9/2fb47bee83b25b119d5a35d580807bb8b92480a54b68fef009a02945629f/greenlet-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80aa4d79eb5564f2e0a6144fcc744b5a37c56c4a92d60920720e99210d88db0f", size = 1615552, upload-time = "2026-01-23T15:33:45.743Z" }, @@ -910,7 +922,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/c8/9d76a66421d1ae24340dfae7e79c313957f6e3195c144d2c73333b5bfe34/greenlet-3.3.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:7e806ca53acf6d15a888405880766ec84721aa4181261cd11a457dfe9a7a4975", size = 276443, upload-time = "2026-01-23T15:30:10.066Z" }, { url = "https://files.pythonhosted.org/packages/81/99/401ff34bb3c032d1f10477d199724f5e5f6fbfb59816ad1455c79c1eb8e7/greenlet-3.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d842c94b9155f1c9b3058036c24ffb8ff78b428414a19792b2380be9cecf4f36", size = 597359, upload-time = "2026-01-23T16:00:57.394Z" }, { url = "https://files.pythonhosted.org/packages/2b/bc/4dcc0871ed557792d304f50be0f7487a14e017952ec689effe2180a6ff35/greenlet-3.3.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20fedaadd422fa02695f82093f9a98bad3dab5fcda793c658b945fcde2ab27ba", size = 607805, upload-time = "2026-01-23T16:05:28.068Z" }, - { url = "https://files.pythonhosted.org/packages/3b/cd/7a7ca57588dac3389e97f7c9521cb6641fd8b6602faf1eaa4188384757df/greenlet-3.3.1-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c620051669fd04ac6b60ebc70478210119c56e2d5d5df848baec4312e260e4ca", size = 622363, upload-time = "2026-01-23T16:15:54.754Z" }, { url = "https://files.pythonhosted.org/packages/cf/05/821587cf19e2ce1f2b24945d890b164401e5085f9d09cbd969b0c193cd20/greenlet-3.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14194f5f4305800ff329cbf02c5fcc88f01886cadd29941b807668a45f0d2336", size = 609947, upload-time = "2026-01-23T15:32:51.004Z" }, { url = "https://files.pythonhosted.org/packages/a4/52/ee8c46ed9f8babaa93a19e577f26e3d28a519feac6350ed6f25f1afee7e9/greenlet-3.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7b2fe4150a0cf59f847a67db8c155ac36aed89080a6a639e9f16df5d6c6096f1", size = 1567487, upload-time = "2026-01-23T16:04:22.125Z" }, { url = "https://files.pythonhosted.org/packages/8f/7c/456a74f07029597626f3a6db71b273a3632aecb9afafeeca452cfa633197/greenlet-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49f4ad195d45f4a66a0eb9c1ba4832bb380570d361912fa3554746830d332149", size = 1636087, upload-time = "2026-01-23T15:33:47.486Z" }, @@ -919,7 +930,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/ab/d26750f2b7242c2b90ea2ad71de70cfcd73a948a49513188a0fc0d6fc15a/greenlet-3.3.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:7ab327905cabb0622adca5971e488064e35115430cec2c35a50fd36e72a315b3", size = 275205, upload-time = "2026-01-23T15:30:24.556Z" }, { url = "https://files.pythonhosted.org/packages/10/d3/be7d19e8fad7c5a78eeefb2d896a08cd4643e1e90c605c4be3b46264998f/greenlet-3.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65be2f026ca6a176f88fb935ee23c18333ccea97048076aef4db1ef5bc0713ac", size = 599284, upload-time = "2026-01-23T16:00:58.584Z" }, { url = "https://files.pythonhosted.org/packages/ae/21/fe703aaa056fdb0f17e5afd4b5c80195bbdab701208918938bd15b00d39b/greenlet-3.3.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a3ae05b3d225b4155bda56b072ceb09d05e974bc74be6c3fc15463cf69f33fd", size = 610274, upload-time = "2026-01-23T16:05:29.312Z" }, - { url = "https://files.pythonhosted.org/packages/06/00/95df0b6a935103c0452dad2203f5be8377e551b8466a29650c4c5a5af6cc/greenlet-3.3.1-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:12184c61e5d64268a160226fb4818af4df02cfead8379d7f8b99a56c3a54ff3e", size = 624375, upload-time = "2026-01-23T16:15:55.915Z" }, { url = "https://files.pythonhosted.org/packages/cb/86/5c6ab23bb3c28c21ed6bebad006515cfe08b04613eb105ca0041fecca852/greenlet-3.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6423481193bbbe871313de5fd06a082f2649e7ce6e08015d2a76c1e9186ca5b3", size = 612904, upload-time = "2026-01-23T15:32:52.317Z" }, { url = "https://files.pythonhosted.org/packages/c2/f3/7949994264e22639e40718c2daf6f6df5169bf48fb038c008a489ec53a50/greenlet-3.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:33a956fe78bbbda82bfc95e128d61129b32d66bcf0a20a1f0c08aa4839ffa951", size = 1567316, upload-time = "2026-01-23T16:04:23.316Z" }, { url = "https://files.pythonhosted.org/packages/8d/6e/d73c94d13b6465e9f7cd6231c68abde838bb22408596c05d9059830b7872/greenlet-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b065d3284be43728dd280f6f9a13990b56470b81be20375a207cdc814a983f2", size = 1636549, upload-time = "2026-01-23T15:33:48.643Z" }, @@ -928,7 +938,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5", size = 275737, upload-time = "2026-01-23T15:32:16.889Z" }, { url = "https://files.pythonhosted.org/packages/41/2e/a3a417d620363fdbb08a48b1dd582956a46a61bf8fd27ee8164f9dfe87c2/greenlet-3.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b31c05dd84ef6871dd47120386aed35323c944d86c3d91a17c4b8d23df62f15b", size = 646422, upload-time = "2026-01-23T16:01:00.354Z" }, { url = "https://files.pythonhosted.org/packages/b4/09/c6c4a0db47defafd2d6bab8ddfe47ad19963b4e30f5bed84d75328059f8c/greenlet-3.3.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02925a0bfffc41e542c70aa14c7eda3593e4d7e274bfcccca1827e6c0875902e", size = 658219, upload-time = "2026-01-23T16:05:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/e2/89/b95f2ddcc5f3c2bc09c8ee8d77be312df7f9e7175703ab780f2014a0e781/greenlet-3.3.1-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3e0f3878ca3a3ff63ab4ea478585942b53df66ddde327b59ecb191b19dbbd62d", size = 671455, upload-time = "2026-01-23T16:15:57.232Z" }, { url = "https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f", size = 660237, upload-time = "2026-01-23T15:32:53.967Z" }, { url = "https://files.pythonhosted.org/packages/96/61/373c30b7197f9e756e4c81ae90a8d55dc3598c17673f91f4d31c3c689c3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aec9ab04e82918e623415947921dea15851b152b822661cce3f8e4393c3df683", size = 1615261, upload-time = "2026-01-23T16:04:25.066Z" }, { url = "https://files.pythonhosted.org/packages/fd/d3/ca534310343f5945316f9451e953dcd89b36fe7a19de652a1dc5a0eeef3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71c767cf281a80d02b6c1bdc41c9468e1f5a494fb11bc8688c360524e273d7b1", size = 1683719, upload-time = "2026-01-23T15:33:50.61Z" }, @@ -937,7 +946,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/28/24/cbbec49bacdcc9ec652a81d3efef7b59f326697e7edf6ed775a5e08e54c2/greenlet-3.3.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:3e63252943c921b90abb035ebe9de832c436401d9c45f262d80e2d06cc659242", size = 282706, upload-time = "2026-01-23T15:33:05.525Z" }, { url = "https://files.pythonhosted.org/packages/86/2e/4f2b9323c144c4fe8842a4e0d92121465485c3c2c5b9e9b30a52e80f523f/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76e39058e68eb125de10c92524573924e827927df5d3891fbc97bd55764a8774", size = 651209, upload-time = "2026-01-23T16:01:01.517Z" }, { url = "https://files.pythonhosted.org/packages/d9/87/50ca60e515f5bb55a2fbc5f0c9b5b156de7d2fc51a0a69abc9d23914a237/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9f9d5e7a9310b7a2f416dd13d2e3fd8b42d803968ea580b7c0f322ccb389b97", size = 654300, upload-time = "2026-01-23T16:05:32.199Z" }, - { url = "https://files.pythonhosted.org/packages/7c/25/c51a63f3f463171e09cb586eb64db0861eb06667ab01a7968371a24c4f3b/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b9721549a95db96689458a1e0ae32412ca18776ed004463df3a9299c1b257ab", size = 662574, upload-time = "2026-01-23T16:15:58.364Z" }, { url = "https://files.pythonhosted.org/packages/1d/94/74310866dfa2b73dd08659a3d18762f83985ad3281901ba0ee9a815194fb/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92497c78adf3ac703b57f1e3813c2d874f27f71a178f9ea5887855da413cd6d2", size = 653842, upload-time = "2026-01-23T15:32:55.671Z" }, { url = "https://files.pythonhosted.org/packages/97/43/8bf0ffa3d498eeee4c58c212a3905dd6146c01c8dc0b0a046481ca29b18c/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ed6b402bc74d6557a705e197d47f9063733091ed6357b3de33619d8a8d93ac53", size = 1614917, upload-time = "2026-01-23T16:04:26.276Z" }, { url = "https://files.pythonhosted.org/packages/89/90/a3be7a5f378fc6e84abe4dcfb2ba32b07786861172e502388b4c90000d1b/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:59913f1e5ada20fde795ba906916aea25d442abcc0593fba7e26c92b7ad76249", size = 1676092, upload-time = "2026-01-23T15:33:52.176Z" }, @@ -1970,7 +1978,7 @@ wheels = [ [[package]] name = "nox" -version = "2025.11.12" +version = "2026.2.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, @@ -1982,9 +1990,9 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b4/a8/e169497599266d176832e2232c08557ffba97eef87bf8a18f9f918e0c6aa/nox-2025.11.12.tar.gz", hash = "sha256:3d317f9e61f49d6bde39cf2f59695bb4e1722960457eee3ae19dacfe03c07259", size = 4030561, upload-time = "2025-11-12T18:39:03.319Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6e/8e/55a9679b31f1efc48facedd2448eb53c7f1e647fb592aa1403c9dd7a4590/nox-2026.2.9.tar.gz", hash = "sha256:1bc8a202ee8cd69be7aaada63b2a7019126899a06fc930a7aee75585bf8ee41b", size = 4031165, upload-time = "2026-02-10T04:38:58.878Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/34/434c594e0125a16b05a7bedaea33e63c90abbfbe47e5729a735a8a8a90ea/nox-2025.11.12-py3-none-any.whl", hash = "sha256:707171f9f63bc685da9d00edd8c2ceec8405b8e38b5fb4e46114a860070ef0ff", size = 74447, upload-time = "2025-11-12T18:39:01.575Z" }, + { url = "https://files.pythonhosted.org/packages/8d/58/0d5e5a044f1868bdc45f38afdc2d90ff9867ce398b4e8fa9e666bfc9bfba/nox-2026.2.9-py3-none-any.whl", hash = "sha256:1b7143bc8ecdf25f2353201326152c5303ae4ae56ca097b1fb6179ad75164c47", size = 74615, upload-time = "2026-02-10T04:38:57.266Z" }, ] [[package]] @@ -2308,11 +2316,11 @@ wheels = [ [[package]] name = "parso" -version = "0.8.5" +version = "0.8.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/76/a1e769043c0c0c9fe391b702539d594731a4362334cdf4dc25d0c09761e7/parso-0.8.6.tar.gz", hash = "sha256:2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd", size = 401621, upload-time = "2026-02-09T15:45:24.425Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, + { url = "https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl", hash = "sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff", size = 106894, upload-time = "2026-02-09T15:45:21.391Z" }, ] [[package]] @@ -2329,7 +2337,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, + { name = "ptyprocess" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -2436,11 +2444,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.5.1" +version = "4.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/d5/763666321efaded11112de8b7a7f2273dd8d1e205168e73c334e54b0ab9a/platformdirs-4.9.1.tar.gz", hash = "sha256:f310f16e89c4e29117805d8328f7c10876eeff36c94eac879532812110f7d39f", size = 28392, upload-time = "2026-02-14T21:02:44.973Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, + { url = "https://files.pythonhosted.org/packages/70/77/e8c95e95f1d4cdd88c90a96e31980df7e709e51059fac150046ad67fac63/platformdirs-4.9.1-py3-none-any.whl", hash = "sha256:61d8b967d34791c162d30d60737369cbbd77debad5b981c4bfda1842e71e0d66", size = 21307, upload-time = "2026-02-14T21:02:43.492Z" }, ] [[package]] @@ -3381,20 +3389,20 @@ wheels = [ [[package]] name = "sphinx-autoapi" -version = "3.6.1" +version = "3.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astroid", version = "3.3.11", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "astroid", version = "4.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "astroid", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "jinja2" }, { name = "pyyaml" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/ad/c627976d5f4d812b203ef1136108bbd81ef9bbbfd3f700f1295c322c22e6/sphinx_autoapi-3.6.1.tar.gz", hash = "sha256:1ff2992b7d5e39ccf92413098a376e0f91e7b4ca532c4f3e71298dbc8a4a9900", size = 55456, upload-time = "2025-10-06T16:21:22.888Z" } +sdist = { url = "https://files.pythonhosted.org/packages/47/22/7ea4b660e98ffa271dbec5847b64738127955746d887f9596940279d30bf/sphinx_autoapi-3.7.0.tar.gz", hash = "sha256:5c8a934d788f00d11b8c8092536c7373592cce986820de8dd7daf6dfd79afd91", size = 58136, upload-time = "2026-02-11T05:24:29.86Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/89/aea2f346fcdb44eb72464842e106b6291b2687feec2dd8b2de920ab89f28/sphinx_autoapi-3.6.1-py3-none-any.whl", hash = "sha256:6b7af0d5650f6eac1f4b85c1eb9f9a4911160ec7138bdc4451c77a5e94d5832c", size = 35334, upload-time = "2025-10-06T16:21:21.33Z" }, + { url = "https://files.pythonhosted.org/packages/d8/11/9825443890d3ef6b6a0db938054e7c806e9911509e0315fe984d00a090c1/sphinx_autoapi-3.7.0-py3-none-any.whl", hash = "sha256:5ea37271b50de08538cf6e33044ef4fb6e981ddb693060ec84f297005014fdfd", size = 36021, upload-time = "2026-02-11T05:24:28.657Z" }, ] [[package]] From 9a96db8664861c94c6aacbb1729afb6ff2e801fc Mon Sep 17 00:00:00 2001 From: ga96dup Date: Fri, 27 Feb 2026 18:30:44 +0100 Subject: [PATCH 069/110] Coverage Tests added --- test/na/zoned/test_native_gate_decomposer.cpp | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 61f969281..dd51895d8 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -59,6 +59,149 @@ class DecomposerTest : public ::testing::Test { constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; +// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, SX, Sxdg, Unrecognized, H _>Just do them all? + +TEST(Test, ZRotGateTranslationTest) { + + qc::StandardOperation op =qc::StandardOperation(0, qc::Z); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon))); + + op =qc::StandardOperation(0, qc::RZ, {qc::PI_2}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + op =qc::StandardOperation(0, qc::P,{qc::PI_2}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + + op =qc::StandardOperation(0, qc::S); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + + op =qc::StandardOperation(0, qc::Sdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1/std::sqrt(2), epsilon))); + op =qc::StandardOperation(0, qc::T); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0.5*std::sqrt(2-std::sqrt(2)), epsilon))); + + op =qc::StandardOperation(0, qc::Tdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-0.5*std::sqrt(2-std::sqrt(2)), epsilon))); + + + +} + +TEST(Test, XYRotGateTranslationTest) { + qc::StandardOperation op =qc::StandardOperation(0, qc::X); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::RX,{qc::PI_2}); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::Y); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0,qc::RY,{qc::PI_2}); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::SX); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + op =qc::StandardOperation(0, qc::SXdg); + + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(-1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + + +} + +TEST(Test, UGateTranslationTest) { + qc::fp p=qc::PI_2; + qc::fp t=qc::PI_4; + qc::fp l=qc::PI_4; + qc::StandardOperation op =qc::StandardOperation(0, qc::U,{t,p,l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); + + t=qc::PI_2; + op =qc::StandardOperation(0, qc::U2,{p,l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); + + t=-1*qc::PI_2; + l=-1*qc::PI_2; + + op =qc::StandardOperation(0, qc::Vdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), + ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); + op =qc::StandardOperation(0, qc::H); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1/std::sqrt(2), epsilon))); + +} + TEST(Test, ThreeQuaternionCombiTest) { std::array q1 = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; std::array q2 = {cos(qc::PI_2), 0, sin(qc::PI_2), 0}; From c2700b55dca6328797116f530cf226d27108a027 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Wed, 4 Mar 2026 17:18:27 +0100 Subject: [PATCH 070/110] Small fixes --- test/na/zoned/test_native_gate_decomposer.cpp | 306 +++++++++++------- 1 file changed, 184 insertions(+), 122 deletions(-) diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index dd51895d8..85c19d1ee 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -59,147 +59,209 @@ class DecomposerTest : public ::testing::Test { constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; -// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, SX, Sxdg, Unrecognized, H _>Just do them all? +// Test Translation of : S gate, Sdg Gate, T-gate, t dg gate, U2, RY, Y, Vdg, +// SX, Sxdg, Unrecognized, H _>Just do them all? TEST(Test, ZRotGateTranslationTest) { - qc::StandardOperation op =qc::StandardOperation(0, qc::Z); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon))); - - op =qc::StandardOperation(0, qc::RZ, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - op =qc::StandardOperation(0, qc::P,{qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - - op =qc::StandardOperation(0, qc::S); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - - op =qc::StandardOperation(0, qc::Sdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-1/std::sqrt(2), epsilon))); - op =qc::StandardOperation(0, qc::T); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0.5*std::sqrt(2-std::sqrt(2)), epsilon))); - - op =qc::StandardOperation(0, qc::Tdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0.5*std::sqrt(2+std::sqrt(2)), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(-0.5*std::sqrt(2-std::sqrt(2)), epsilon))); - + qc::StandardOperation op = qc::StandardOperation(0, qc::Z); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon))); + op = qc::StandardOperation(0, qc::RZ, {qc::PI_2}); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::P, {qc::PI_2}); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::S); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); + + op = qc::StandardOperation(0, qc::Sdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-1 / std::sqrt(2), epsilon))); + op = qc::StandardOperation(0, qc::T); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); + + op = qc::StandardOperation(0, qc::Tdg); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear(0.5 * std::sqrt(2 + std::sqrt(2)), epsilon), + ::testing::DoubleNear(0, epsilon), ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(-0.5 * std::sqrt(2 - std::sqrt(2)), epsilon))); } TEST(Test, XYRotGateTranslationTest) { - qc::StandardOperation op =qc::StandardOperation(0, qc::X); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); - - op =qc::StandardOperation(0, qc::RX,{qc::PI_2}); - - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + qc::StandardOperation op = qc::StandardOperation(0, qc::X); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::Y); + op = qc::StandardOperation(0, qc::RX, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0,qc::RY,{qc::PI_2}); + op = qc::StandardOperation(0, qc::Y); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1, epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::SX); + op = qc::StandardOperation(0, qc::RY, {qc::PI_2}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon))); - op =qc::StandardOperation(0, qc::SXdg); + op = qc::StandardOperation(0, qc::SX); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(-1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(0, epsilon))); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); + op = qc::StandardOperation(0, qc::SXdg); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(-1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(0, epsilon))); } TEST(Test, UGateTranslationTest) { - qc::fp p=qc::PI_2; - qc::fp t=qc::PI_4; - qc::fp l=qc::PI_4; - qc::StandardOperation op =qc::StandardOperation(0, qc::U,{t,p,l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - - t=qc::PI_2; - op =qc::StandardOperation(0, qc::U2,{p,l}); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - - t=-1*qc::PI_2; - l=-1*qc::PI_2; - - op =qc::StandardOperation(0, qc::Vdg); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear((std::cos(p/2)*std::cos(t/2)*std::cos(l/2))-(std::sin(p/2)*std::cos(t/2)*std::sin(l/2)), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::sin(l/2)-std::sin(p/2)*std::cos(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::sin(t/2)*std::cos(l/2)+std::sin(p/2)*std::sin(l/2)*std::sin(t/2), epsilon), - ::testing::DoubleNear(std::cos(p/2)*std::cos(t/2)*std::sin(l/2)+std::sin(p/2)*std::cos(l/2)*std::cos(t/2), epsilon))); - op =qc::StandardOperation(0, qc::H); - EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion(std::reference_wrapper (op)), ::testing::ElementsAre( - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon), - ::testing::DoubleNear(0, epsilon), - ::testing::DoubleNear(1/std::sqrt(2), epsilon))); - + qc::fp p = qc::PI_2; + qc::fp t = qc::PI_4; + qc::fp l = qc::PI_4; + qc::StandardOperation op = qc::StandardOperation(0, qc::U, {t, p, l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + + t = qc::PI_2; + op = qc::StandardOperation(0, qc::U2, {p, l}); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + + t = -1 * qc::PI_2; + l = -1 * qc::PI_2; + + op = qc::StandardOperation(0, qc::Vdg); + EXPECT_THAT(NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre( + ::testing::DoubleNear( + (std::cos(p / 2) * std::cos(t / 2) * std::cos(l / 2)) - + (std::sin(p / 2) * std::cos(t / 2) * std::sin(l / 2)), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::sin(l / 2) - + std::sin(p / 2) * std::cos(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::sin(t / 2) * std::cos(l / 2) + + std::sin(p / 2) * std::sin(l / 2) * std::sin(t / 2), + epsilon), + ::testing::DoubleNear( + std::cos(p / 2) * std::cos(t / 2) * std::sin(l / 2) + + std::sin(p / 2) * std::cos(l / 2) * std::cos(t / 2), + epsilon))); + op = qc::StandardOperation(0, qc::H); + EXPECT_THAT( + NativeGateDecomposer::convertGateToQuaternion( + std::reference_wrapper(op)), + ::testing::ElementsAre(::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon), + ::testing::DoubleNear(0, epsilon), + ::testing::DoubleNear(1 / std::sqrt(2), epsilon))); } TEST(Test, ThreeQuaternionCombiTest) { @@ -336,7 +398,7 @@ TEST_F(DecomposerTest, SingleRXGate) { // ┌───────┐ // q: ┤ Rx(π) ├ // └───────┘ - int n = 1; + size_t n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); const auto& sched = scheduler.schedule(qc); @@ -365,7 +427,7 @@ TEST_F(DecomposerTest, SingleU3Gate) { // ┌─────────────┐ // q: ┤ U3(0,π,π/2) ├ // └─────────────┘ - int n = 1; + size_t n = 1; qc::QuantumComputation qc(n); qc.u(0.0, qc::PI, qc::PI_2, 0); const auto& sched = scheduler.schedule(qc); From 20d0b6a62eee3df2c9a46a1ee991a6ebc2fb6774 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 10 Mar 2026 15:01:48 +0100 Subject: [PATCH 071/110] Copy elison fix --- src/na/zoned/decomposer/NativeGateDecomposer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 0ae7658ab..7732ade3d 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -248,12 +248,12 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true)))); + NewLayer.emplace_back(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::move(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true)))); + NewLayer.emplace_back(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); From 8c474ba11638c8674ca1a540388721f2f042175c Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 16 Mar 2026 20:11:21 +0100 Subject: [PATCH 072/110] First impl preprocessing & Dag creation --- .../na/zoned/scheduler/ThetaOptScheduler.hpp | 110 +++++++++++++++ src/na/zoned/scheduler/ThetaOptScheduler.cpp | 128 ++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 include/na/zoned/scheduler/ThetaOptScheduler.hpp create mode 100644 src/na/zoned/scheduler/ThetaOptScheduler.cpp diff --git a/include/na/zoned/scheduler/ThetaOptScheduler.hpp b/include/na/zoned/scheduler/ThetaOptScheduler.hpp new file mode 100644 index 000000000..7359dab3e --- /dev/null +++ b/include/na/zoned/scheduler/ThetaOptScheduler.hpp @@ -0,0 +1,110 @@ +// +// Created by cpsch on 12.03.2026. +// +#pragma once + +#include "ASAPScheduler.hpp" +#include "ir/QuantumComputation.hpp" +#include "na/zoned/Architecture.hpp" +#include "na/zoned/Types.hpp" +#include "na/zoned/scheduler/SchedulerBase.hpp" + +#include +#include +#include + +namespace na::zoned { +/** + * The class ThetaOptScheduler implements a scheduling strategy minimizing the + * total global rotation angle theta over the circuit for the zoned neutral atom + * compiler. + */ +class ThetaOptScheduler : public SchedulerBase { + /// A reference to the zoned neutral atom architecture + std::reference_wrapper architecture_; + /** + * This value is calculated based on the architecture and indicates the + * the entanglement zone. + */ + size_t maxTwoQubitGateNumPerLayer_ = 0; + +public: + /// The configuration of the ASAPScheduler + struct Config { + /// The maximal share of traps that are used in the entanglement zone. + double maxFillingFactor = 0.9; + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, maxFillingFactor); + }; + + template class DiGraph { + std::size_t nodes; + std::vector> adjacencies_; + std::vector node_values_; + + public: + DiGraph() { + nodes = 0; + adjacencies_ = std::vector>(); + node_values_ = std::vector(); + } + std::size_t add_Node(T node) { + adjacencies_.push_back(std::vector()); + node_values_.push_back(node); + return nodes++; + } + bool add_Edge(std::size_t from, std::size_t to) { + // TODO: Cycle Check + if (from < nodes && to < nodes && from != to) { + adjacencies_[from].push_back(to); + return true; + } else { + return false; + } + } + T get_Node_Value(std::size_t node) { + if (node > nodes) { + return node_values_.at(node); + } else { + std::ostringstream oss; + oss << "ERROR: Node Number out of range: " << node << "\n"; + throw std::invalid_argument(oss.str()); + } + } + std::size_t get_N_Nodes() const { return nodes; } + DiGraph topographicSort(DiGraph graph) { + // TODO: Topographic Sort + return graph; + } + }; + +private: + /// The configuration of the ThetaOptScheduler + Config config_; + +public: + /** + * Create a new ThetaOptScheduler. + * @param architecture is the architecture of the neutral atom system + * @param config is the configuration for the scheduler + */ + ThetaOptScheduler(const Architecture& architecture, const Config& config); + DiGraph> convert_circ_to_dag( + const std::pair, + std::vector>& qc) const; + std::pair, std::vector> + preprocess_qc(const qc::QuantumComputation& qc, + const Architecture& architecture, + ASAPScheduler::Config config) const; + /** + * This function schedules the operations of a quantum computation. + * @details + * @param qc is the quantum computation + * @return a pair of two vectors. The first vector contains the layers of + * single-qubit operations. The second vector contains the layers of two-qubit + * operations. A pair of qubits represents every two-qubit operation. + */ + [[nodiscard]] auto schedule(const qc::QuantumComputation& qc) const + -> std::pair, + std::vector> override; +}; +} // namespace na::zoned diff --git a/src/na/zoned/scheduler/ThetaOptScheduler.cpp b/src/na/zoned/scheduler/ThetaOptScheduler.cpp new file mode 100644 index 000000000..263adcc69 --- /dev/null +++ b/src/na/zoned/scheduler/ThetaOptScheduler.cpp @@ -0,0 +1,128 @@ +// +// Created by cpsch on 12.03.2026. +// +#include "na/zoned/scheduler/ThetaOptScheduler.hpp" + +#include "ir/Definitions.hpp" +#include "ir/QuantumComputation.hpp" +#include "ir/operations/OpType.hpp" +#include "ir/operations/StandardOperation.hpp" +#include "na/zoned/Architecture.hpp" +#include "na/zoned/decomposer/NativeGateDecomposer.hpp" +#include "na/zoned/scheduler/ASAPScheduler.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace na::zoned { + +ThetaOptScheduler::ThetaOptScheduler(const Architecture& architecture, + const Config& config) + : architecture_(architecture), config_(config) {} + +std::pair, std::vector> +ThetaOptScheduler::preprocess_qc(const qc::QuantumComputation& qc, + const Architecture& architecture, + const ASAPScheduler::Config config) const { + // TODO: Find out if only CZ's in Mulit qubit gate layers + ASAPScheduler scheduler = ASAPScheduler(architecture, config); + std::pair, + std::vector> + asap_schedule = scheduler.schedule(qc); + std::vector> + singlequbitlayers_U3 = + NativeGateDecomposer::transformToU3(asap_schedule.first); + std::vector NewSingleQubitLayers = + std::vector{}; + SingleQubitGateLayer NewLayer; + for (auto layer : singlequbitlayers_U3) { + NewLayer.clear(); + for (auto gate : layer) { + NewLayer.emplace_back(std::make_unique( + qc::StandardOperation::StandardOperation(gate.qubit, qc::U, + gate.angles))); + } + NewSingleQubitLayers.emplace_back(NewLayer); + } + return std::pair(NewSingleQubitLayers, asap_schedule.second); +} + +ThetaOptScheduler::DiGraph> +ThetaOptScheduler::convert_circ_to_dag( + const std::pair, + std::vector>& qc) const { + ThetaOptScheduler::DiGraph> graph = + DiGraph>(); + std::vector> qubit_paths = + std::vector>{}; + // assert that One mor sql exists than mql + for (auto i = 0; i < qc.first.size(); ++i) { + for (auto s = 0; s < qc.first.at(i).size(); ++s) { + size_t node = graph.add_Node(qc.first.at(i).at(s)); + + for (auto t = 0; t < qc.first.at(i).at(s)->getNtargets(); t++) { + qubit_paths.at(qc.first.at(i).at(s)->getTargets().at(t)) + .push_back(node); + } + } + for (auto m = 0; m < qc.second.at(i).size(); ++m) { + size_t node = graph.add_Node(qc.second.at(i).at(m)); + + for (auto t = 0; t < qc.first.at(i).at(m)->getNtargets(); t++) { + qubit_paths.at(qc.first.at(i).at(m)->getTargets().at(t)) + .push_back(node); + } + for (auto c = 0; c < qc.first.at(i).at(m)->getNcontrols(); c++) { + qubit_paths.at(qc.first.at(i).at(m)->getControls().at(m)) + .push_back(node); + } + } + } + for (auto s = 0; s < qc.first.end()->size(); ++s) { + size_t node = graph.add_Node(qc.first.end()->at(s)); + + for (auto t = 0; t < qc.first.end()->at(s)->getNtargets(); t++) { + qubit_paths.at(qc.first.end()->at(s)->getTargets().at(t)).push_back(node); + } + } + for (std::size_t i = 0; i < qubit_paths.size(); ++i) { + for (std::size_t op = 0; op < qubit_paths.at(i).size(); ++op) { + graph.add_Edge(i, qubit_paths.at(i).at(op)); + } + } + return graph; +} + +auto ThetaOptScheduler::schedule(const qc::QuantumComputation& qc) const + -> std::pair, + std::vector> { + // TODO: Preprocessing-> Convert gates to combined U3 and CZ? Issue with + // Single qubit layer/SIngle Qubit ReferenceLayer + std::pair, std::vector> + qc_p = preprocess_qc(qc, architecture_, config_); + // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? + DiGraph> circuit = + convert_circ_to_dag(qc_p); + // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) + // SIFt IMPL? + + // TODO: Create Subproblem Graph + + // TODO: First Call of Recursive Function to create Schedule + + // TODO: Create Schedule from Subproblem Graph + + return std::pair(std::vector(), + std::vector()); +} + +} // namespace na::zoned \ No newline at end of file From 1eb1e15bcdc56ed2ef9a9bb4e93bf4bfc3b40d09 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 30 Mar 2026 13:16:03 +0200 Subject: [PATCH 073/110] More impl --- .../na/zoned/scheduler/ThetaOptScheduler.hpp | 62 +++++- src/na/zoned/scheduler/ThetaOptScheduler.cpp | 208 ++++++++++++++++-- 2 files changed, 239 insertions(+), 31 deletions(-) diff --git a/include/na/zoned/scheduler/ThetaOptScheduler.hpp b/include/na/zoned/scheduler/ThetaOptScheduler.hpp index 7359dab3e..9b3c09826 100644 --- a/include/na/zoned/scheduler/ThetaOptScheduler.hpp +++ b/include/na/zoned/scheduler/ThetaOptScheduler.hpp @@ -38,32 +38,45 @@ class ThetaOptScheduler : public SchedulerBase { template class DiGraph { std::size_t nodes; - std::vector> adjacencies_; + //Add pedecessors??? + std::vector>> adjacencies_; std::vector node_values_; public: DiGraph() { nodes = 0; - adjacencies_ = std::vector>(); + adjacencies_ = std::vector>>(); node_values_ = std::vector(); } std::size_t add_Node(T node) { - adjacencies_.push_back(std::vector()); - node_values_.push_back(node); + adjacencies_.push_back(std::vector>()); + node_values_.push_back(std::move(node)); return nodes++; } + bool add_Edge(std::size_t from, std::size_t to, double weight) { + // TODO: Cycle Check + if (from < nodes && to < nodes && from != to) { + adjacencies_[from].push_back(std::pair(to,weight)); + return true; + } else { + return false; + } + } + bool add_Edge(std::size_t from, std::size_t to) { // TODO: Cycle Check if (from < nodes && to < nodes && from != to) { - adjacencies_[from].push_back(to); + adjacencies_[from].push_back(std::pair(to,1.0)); return true; } else { return false; } } - T get_Node_Value(std::size_t node) { - if (node > nodes) { - return node_values_.at(node); + + T* get_Node_Value(std::size_t node) { + if (node < nodes) { + return &node_values_[node]; + //return node_values_.at(node); } else { std::ostringstream oss; oss << "ERROR: Node Number out of range: " << node << "\n"; @@ -71,7 +84,11 @@ class ThetaOptScheduler : public SchedulerBase { } } std::size_t get_N_Nodes() const { return nodes; } - DiGraph topographicSort(DiGraph graph) { + + std::vector> get_adjacent(std::size_t i) const { + return adjacencies_.at(i); + } + static DiGraph topographicSort(DiGraph graph) { // TODO: Topographic Sort return graph; } @@ -79,7 +96,7 @@ class ThetaOptScheduler : public SchedulerBase { private: /// The configuration of the ThetaOptScheduler - Config config_; + ASAPScheduler::Config config_; public: /** @@ -95,6 +112,31 @@ class ThetaOptScheduler : public SchedulerBase { preprocess_qc(const qc::QuantumComputation& qc, const Architecture& architecture, ASAPScheduler::Config config) const; + static std::vector, 4>, qc::fp>> + get_possible_moments(DiGraph>& circuit, + const std::vector& v0_c, + const std::array, 3>& v_new); + static qc::fp max_theta(DiGraph>& circuit, + const std::vector& nodes); + static std::array,3> sift(DiGraph>& circuit, + size_t n_qubits); + std::pair, + std::vector> build_schedule(DiGraph>& circuit, + DiGraph, std::vector>>& + subproblem_graph) const; + + static auto add_node_to_sub_prob_graph( + std::vector v_p, std::vector v_c, qc::fp cost, + DiGraph, std::vector>>& + subproblem_graph, + size_t prev_node) -> size_t; + + static double schedule_remaining( + const std::array, 3>& v, + DiGraph>& circuit, + DiGraph, std::vector>>& + subproblem_graph, + size_t prev_node, size_t n_qubits); /** * This function schedules the operations of a quantum computation. * @details diff --git a/src/na/zoned/scheduler/ThetaOptScheduler.cpp b/src/na/zoned/scheduler/ThetaOptScheduler.cpp index 263adcc69..3451a1997 100644 --- a/src/na/zoned/scheduler/ThetaOptScheduler.cpp +++ b/src/na/zoned/scheduler/ThetaOptScheduler.cpp @@ -10,6 +10,8 @@ #include "na/zoned/Architecture.hpp" #include "na/zoned/decomposer/NativeGateDecomposer.hpp" #include "na/zoned/scheduler/ASAPScheduler.hpp" +#include "spdlog/fmt/bundled/args.h" +#include "spdlog/fmt/bundled/printf.h" #include #include @@ -48,12 +50,37 @@ ThetaOptScheduler::preprocess_qc(const qc::QuantumComputation& qc, NewLayer.clear(); for (auto gate : layer) { NewLayer.emplace_back(std::make_unique( - qc::StandardOperation::StandardOperation(gate.qubit, qc::U, - gate.angles))); + qc::StandardOperation((qc::Qubit) gate.qubit, qc::U,{gate.angles[0],gate.angles[1],gate.angles[2]}))); } - NewSingleQubitLayers.emplace_back(NewLayer); + NewSingleQubitLayers.push_back(std::move((NewLayer))); } - return std::pair(NewSingleQubitLayers, asap_schedule.second); + return std::pair(std::move(NewSingleQubitLayers), asap_schedule.second); +} +std::vector,4>,qc::fp>> ThetaOptScheduler::get_possible_moments( + DiGraph>& circuit, + const std::vector& v0_c, + const std::array, 3>& v_new) { + + std::vector v_p1_star=v_new[0]; + std::vector v_p1_square=std::vector(); + std::vector v_c1_star=v_new[1]; + std::vector v_c1_square=std::vector(); + + qc::fp v_c0_cost=max_theta(circuit, v0_c); + qc::fp v_c1_cost=max_theta(circuit, v_new[1]); + qc::fp orig_comb_cost=v_c0_cost+v_c1_cost; + qc::fp new_v_C1_cost=std::max(v_c0_cost,v_c1_cost); + + std::array,4> v_arg={v0_c,v_new[0],v_new[1],v_new[2]}; + auto args={std::pair(v_arg,v_c0_cost)}; + //TODO: Check Condition 1 + //Sort v_0C from highest to lowest theta + + //TODO: Check Condition 2 + // TODO: Check Condition 3 + //TODO Check Condition 4 ?? Find out what it does!! + + return args; } ThetaOptScheduler::DiGraph> @@ -67,28 +94,25 @@ ThetaOptScheduler::convert_circ_to_dag( // assert that One mor sql exists than mql for (auto i = 0; i < qc.first.size(); ++i) { for (auto s = 0; s < qc.first.at(i).size(); ++s) { - size_t node = graph.add_Node(qc.first.at(i).at(s)); - + size_t node = graph.add_Node(qc.first.at(i).at(s)->clone()); for (auto t = 0; t < qc.first.at(i).at(s)->getNtargets(); t++) { qubit_paths.at(qc.first.at(i).at(s)->getTargets().at(t)) .push_back(node); } } for (auto m = 0; m < qc.second.at(i).size(); ++m) { - size_t node = graph.add_Node(qc.second.at(i).at(m)); - - for (auto t = 0; t < qc.first.at(i).at(m)->getNtargets(); t++) { - qubit_paths.at(qc.first.at(i).at(m)->getTargets().at(t)) + auto t=qc.second.at(i); + //Create CZ & Make_unique + size_t node = graph.add_Node(std::make_unique(qc::StandardOperation(qc::Control(qc.second.at(i).at(m)[0]),qc.second.at(i).at(m)[1],qc::Z,{}))); + qubit_paths.at(qc.second.at(i).at(m).at(0)) .push_back(node); - } - for (auto c = 0; c < qc.first.at(i).at(m)->getNcontrols(); c++) { - qubit_paths.at(qc.first.at(i).at(m)->getControls().at(m)) + qubit_paths.at(qc.second.at(i).at(m).at(1)) .push_back(node); - } + } } for (auto s = 0; s < qc.first.end()->size(); ++s) { - size_t node = graph.add_Node(qc.first.end()->at(s)); + size_t node = graph.add_Node(qc.first.end()->at(s)->clone()); for (auto t = 0; t < qc.first.end()->at(s)->getNtargets(); t++) { qubit_paths.at(qc.first.end()->at(s)->getTargets().at(t)).push_back(node); @@ -102,6 +126,143 @@ ThetaOptScheduler::convert_circ_to_dag( return graph; } + +bool disjunct(const std::unordered_set& set1, + const std::unordered_set& set2) { + for (auto elem: set1) { + if (set2.contains(elem)){return false;} + } + return true; +} + +qc::fp ThetaOptScheduler::max_theta( + DiGraph>& circuit, + const std::vector& nodes) { + qc::fp max_cost=0; + for (const auto node : nodes) { + if ((*circuit.get_Node_Value(node))->getParameter()[0]>=max_cost) { + max_cost=(*circuit.get_Node_Value(node))->getParameter()[0]; + } + } + return max_cost; +} + +std::array, 3> ThetaOptScheduler::sift( + DiGraph>& circuit, + size_t n_qubits) { + std::vector v_p=std::vector(); + std::vector v_c=std::vector(); + std::vector v_r=std::vector(); + + std::unordered_set removed=std::unordered_set(); + + for (auto node=0; node < circuit.get_N_Nodes(); node++) { + //TODO: Check for unique pointer issue + auto op=circuit.get_Node_Value(node); + std::unordered_set op_qubits=std::unordered_set(); + for (auto qubit:op->get()->getUsedQubits()){op_qubits.insert(qubit);} + if (removed.size()get()->getNqubits()==1) { + v_c.push_back(node); + removed.insert(op->get()->getTargets().at(0)); + }else { + v_p.push_back(node); + //Add something to make it only pick one 2-Qubit gate per Qubit per moment??? + } + }else { + v_r.push_back(node); + } + } + return std::array, 3>({v_p,v_c,v_r}); +} + +static std::pair, std::vector> +ThetaOptScheduler::build_schedule( + DiGraph>& circuit, + DiGraph,std::vector>>& + subproblem_graph) { + + //TODO: Find Leaf Nodes of di_graph + std::vector leaf_nodes; + for (std::size_t i=0;i start_nodes= find_start_nodes(subproblem_graph); + std::vector> paths_to_leafs= find_shortest_paths(subproblem_graph,leaf_nodes,start_nodes); + //TODO: Find shortest path with minimal weight + std::vector minimal_path=std::vector(); + double min_cost= 100000000000000; //TODO: Find Max double + for (auto path: paths_to_leafs) { + double cost=calc_cost(subproblem_graph,cost); + if (cost, std::vector> schedule=std::pair, std::vector>{}; + //TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st v_p empty skip adding it . If not add empty SQGL + for (auto i=0;isecond.size();++j) { + auto op=subproblem_graph.get_Node_Value(minimal_path[i])->second.at(j); + schedule.first.at(i+1).emplace_back(std::move(*circuit.get_Node_Value(op))); + } + + for (auto j=0;jfirst.size();++j) { + auto op=subproblem_graph.get_Node_Value(minimal_path[i])->first.at(j); + schedule.second.at(i).emplace_back(std::move(*circuit.get_Node_Value(op))); + } + } + return schedule; +} +size_t ThetaOptScheduler::add_node_to_sub_prob_graph( + std::vector v_p, std::vector v_c, qc::fp cost, + DiGraph,std::vector>>& + subproblem_graph,std::size_t prev_node) { + std::size_t new_node=subproblem_graph.add_Node(std::pair(v_p,v_c)); + subproblem_graph.add_Edge(prev_node,new_node,cost); + return new_node; +} +double ThetaOptScheduler::schedule_remaining( + const std::array, 3>& v, + DiGraph>& circuit, + DiGraph, std::vector>>& + subproblem_graph, + size_t prev_node, size_t n_qubits) { + double cost; + //TODO: Check if subproblem has been computed + //auto id=?;//What to do for id?? + //if (memo.contains()) {//KEy set?? + // cost=memo.at(id)[0]; + // sub_node=memo.at(id)[1]; + // edge_weight=memo.at(id)[2]; + // subproblem_graph.add_edge(prev_node,sub_node,edge_weight); + // return cost; + // } + //TODO: Base Case-> V_rem is empty + if (v[2].size()==0) { + cost=0; + for (auto i=0; i cost) { + cost=std::fabs(v[1].at(i)); + } + } + add_node_to_sub_prob_graph(v[0],v[1],cost,subproblem_graph, prev_node); + return cost; + } + //TODO: Recursive Call + auto v_new=sift(circuit,n_qubits); + auto args= get_possible_moments(circuit,v[1],v_new); + std::vector costs=std::vector(); + for (const auto& arg:args) { + auto new_node=add_node_to_sub_prob_graph(v[0],v_new[1],arg.second,subproblem_graph, prev_node); + costs.push_back(schedule_remaining(v_new,circuit,subproblem_graph,new_node,n_qubits)+arg.second); + } + cost= *std::ranges::min_element(costs); + //memo.add(id,) + return cost; +} + auto ThetaOptScheduler::schedule(const qc::QuantumComputation& qc) const -> std::pair, std::vector> { @@ -110,19 +271,24 @@ auto ThetaOptScheduler::schedule(const qc::QuantumComputation& qc) const std::pair, std::vector> qc_p = preprocess_qc(qc, architecture_, config_); // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? + //TODO: Circuit on NON_Unique pointers?? DiGraph> circuit = convert_circ_to_dag(qc_p); // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) - // SIFt IMPL? - + // v=(v_p,v_c,v_r) + std::array, 3> v=sift(circuit,qc.size()); // TODO: Create Subproblem Graph - + DiGraph, + std::vector>>sub_prob_graph= DiGraph, + std::vector>> (); // TODO: First Call of Recursive Function to create Schedule + auto base_node=sub_prob_graph.add_Node(std::pair,std::vector>({},{})); + auto cost=schedule_remaining(v, circuit, sub_prob_graph, base_node,qc.getNqubits()); // TODO: Create Schedule from Subproblem Graph - - return std::pair(std::vector(), - std::vector()); + std::pair, + std::vector> final_circuit=build_schedule(circuit,sub_prob_graph); + return final_circuit; } } // namespace na::zoned \ No newline at end of file From 2e7cb4f63c79a4848700d0b3b13b3c71124c432f Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sat, 4 Apr 2026 22:27:16 +0200 Subject: [PATCH 074/110] More impl --- .../na/zoned/scheduler/ThetaOptScheduler.hpp | 86 ++- src/na/zoned/scheduler/ThetaOptScheduler.cpp | 503 +++++++++++++----- 2 files changed, 422 insertions(+), 167 deletions(-) diff --git a/include/na/zoned/scheduler/ThetaOptScheduler.hpp b/include/na/zoned/scheduler/ThetaOptScheduler.hpp index 9b3c09826..b4bf8afb7 100644 --- a/include/na/zoned/scheduler/ThetaOptScheduler.hpp +++ b/include/na/zoned/scheduler/ThetaOptScheduler.hpp @@ -38,25 +38,25 @@ class ThetaOptScheduler : public SchedulerBase { template class DiGraph { std::size_t nodes; - //Add pedecessors??? - std::vector>> adjacencies_; + // Add pedecessors??? + std::vector>> adjacencies_; std::vector node_values_; public: DiGraph() { nodes = 0; - adjacencies_ = std::vector>>(); + adjacencies_ = std::vector>>(); node_values_ = std::vector(); } std::size_t add_Node(T node) { - adjacencies_.push_back(std::vector>()); + adjacencies_.push_back(std::vector>()); node_values_.push_back(std::move(node)); return nodes++; } bool add_Edge(std::size_t from, std::size_t to, double weight) { - // TODO: Cycle Check if (from < nodes && to < nodes && from != to) { - adjacencies_[from].push_back(std::pair(to,weight)); + adjacencies_[from].push_back( + std::pair(to, weight)); return true; } else { return false; @@ -64,9 +64,9 @@ class ThetaOptScheduler : public SchedulerBase { } bool add_Edge(std::size_t from, std::size_t to) { - // TODO: Cycle Check if (from < nodes && to < nodes && from != to) { - adjacencies_[from].push_back(std::pair(to,1.0)); + adjacencies_[from].push_back( + std::pair(to, 1.0)); return true; } else { return false; @@ -76,7 +76,7 @@ class ThetaOptScheduler : public SchedulerBase { T* get_Node_Value(std::size_t node) { if (node < nodes) { return &node_values_[node]; - //return node_values_.at(node); + // return node_values_.at(node); } else { std::ostringstream oss; oss << "ERROR: Node Number out of range: " << node << "\n"; @@ -85,18 +85,15 @@ class ThetaOptScheduler : public SchedulerBase { } std::size_t get_N_Nodes() const { return nodes; } - std::vector> get_adjacent(std::size_t i) const { + std::vector> + get_adjacent(std::size_t i) const { return adjacencies_.at(i); } - static DiGraph topographicSort(DiGraph graph) { - // TODO: Topographic Sort - return graph; - } }; private: /// The configuration of the ThetaOptScheduler - ASAPScheduler::Config config_; + Config config_; public: /** @@ -105,23 +102,44 @@ class ThetaOptScheduler : public SchedulerBase { * @param config is the configuration for the scheduler */ ThetaOptScheduler(const Architecture& architecture, const Config& config); - DiGraph> convert_circ_to_dag( - const std::pair, - std::vector>& qc) const; + static DiGraph> + convert_circ_to_dag(const std::pair, + std::vector>& qc); std::pair, std::vector> preprocess_qc(const qc::QuantumComputation& qc, - const Architecture& architecture, - ASAPScheduler::Config config) const; + const Architecture& architecture, Config config) const; + static std::pair, double> shortest_path_to_start( + const DiGraph, std::vector>>& + subproblem_graph, + unsigned long long curr_node, std::set leaf_nodes); + std::vector find_shortest_path( + const DiGraph, + std::vector>>& di_graph, + const std::vector& vector); + static double + calc_cost(std::vector>::const_reference path, + DiGraph, std::vector>>& + subproblem_graph); + static std::vector find_leaf_nodes( + DiGraph>& circuit, + const DiGraph, + std::vector>>& subproblem_graph); + static std::vector + sort_by_theta_dec(DiGraph>& circuit, + const std::vector& vector); + static std::vector + remove_element(const std::vector& vector, std::size_t node); static std::vector, 4>, qc::fp>> get_possible_moments(DiGraph>& circuit, const std::vector& v0_c, const std::array, 3>& v_new); - static qc::fp max_theta(DiGraph>& circuit, - const std::vector& nodes); - static std::array,3> sift(DiGraph>& circuit, - size_t n_qubits); - std::pair, - std::vector> build_schedule(DiGraph>& circuit, + static qc::fp + max_theta(DiGraph>& circuit, + const std::vector& nodes); + static std::array, 3> + sift(DiGraph>& circuit, size_t n_qubits); + std::pair, std::vector> + build_schedule(DiGraph>& circuit, DiGraph, std::vector>>& subproblem_graph) const; @@ -136,7 +154,8 @@ class ThetaOptScheduler : public SchedulerBase { DiGraph>& circuit, DiGraph, std::vector>>& subproblem_graph, - size_t prev_node, size_t n_qubits); + size_t prev_node, size_t n_qubits, + std::map>>& memo); /** * This function schedules the operations of a quantum computation. * @details @@ -150,3 +169,16 @@ class ThetaOptScheduler : public SchedulerBase { std::vector> override; }; } // namespace na::zoned + +template <> struct std::hash, 3>> { + std::size_t operator()( + const std::array, 3>& array) const noexcept { + std::size_t seed = 0U; + for (auto v : array) { + for (auto node : v) { + qc::hashCombine(seed, std::hash{}(node)); + } + } + return seed; + } +}; diff --git a/src/na/zoned/scheduler/ThetaOptScheduler.cpp b/src/na/zoned/scheduler/ThetaOptScheduler.cpp index 3451a1997..391ae9220 100644 --- a/src/na/zoned/scheduler/ThetaOptScheduler.cpp +++ b/src/na/zoned/scheduler/ThetaOptScheduler.cpp @@ -3,6 +3,7 @@ // #include "na/zoned/scheduler/ThetaOptScheduler.hpp" +#include "dd/Approximation.hpp" #include "ir/Definitions.hpp" #include "ir/QuantumComputation.hpp" #include "ir/operations/OpType.hpp" @@ -16,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +36,7 @@ ThetaOptScheduler::ThetaOptScheduler(const Architecture& architecture, std::pair, std::vector> ThetaOptScheduler::preprocess_qc(const qc::QuantumComputation& qc, const Architecture& architecture, - const ASAPScheduler::Config config) const { + const Config config) const { // TODO: Find out if only CZ's in Mulit qubit gate layers ASAPScheduler scheduler = ASAPScheduler(architecture, config); std::pair, @@ -49,44 +51,258 @@ ThetaOptScheduler::preprocess_qc(const qc::QuantumComputation& qc, for (auto layer : singlequbitlayers_U3) { NewLayer.clear(); for (auto gate : layer) { - NewLayer.emplace_back(std::make_unique( - qc::StandardOperation((qc::Qubit) gate.qubit, qc::U,{gate.angles[0],gate.angles[1],gate.angles[2]}))); + NewLayer.emplace_back( + std::make_unique(qc::StandardOperation( + (qc::Qubit)gate.qubit, qc::U, + {gate.angles[0], gate.angles[1], gate.angles[2]}))); } NewSingleQubitLayers.push_back(std::move((NewLayer))); } return std::pair(std::move(NewSingleQubitLayers), asap_schedule.second); } -std::vector,4>,qc::fp>> ThetaOptScheduler::get_possible_moments( +std::vector ThetaOptScheduler::find_shortest_path( + const DiGraph, + std::vector>>& subproblem_graph, + const std::vector& leaf_nodes) { + std::set leafs = + std::set(leaf_nodes.begin(), leaf_nodes.end()); + std::pair, double> leaf_path = + shortest_path_to_start(subproblem_graph, 0, leafs); + std::reverse(leaf_path.first.begin(), leaf_path.first.end()); + return leaf_path.first; +} +bool disjunct(const std::set& set1, const std::set& set2) { + for (auto elem : set1) { + if (set2.contains(elem)) { + return false; + } + } + return true; +} + +bool disjunct(const std::set& set1, + const std::set& set2) { + for (auto elem : set1) { + if (set2.contains(elem)) { + return false; + } + } + return true; +} + +std::pair, double> +ThetaOptScheduler::shortest_path_to_start( + const DiGraph, + std::vector>>& subproblem_graph, + std::size_t curr_node, std::set leaf_nodes) { + std::vector, double>> possible_paths = {}; + // Check if leaf nodes are reached + for (auto node : subproblem_graph.get_adjacent(curr_node)) { + if (leaf_nodes.contains(node.first)) { + possible_paths.push_back({std::pair, double>( + {node.first, curr_node}, node.second)}); + } + } + // Recursive Case + if (possible_paths.empty()) { + for (auto node : subproblem_graph.get_adjacent(curr_node)) { + auto path = + shortest_path_to_start(subproblem_graph, node.first, leaf_nodes); + path.first.push_back(curr_node); + path.second += node.second; + possible_paths.push_back(path); + } + } + // Base Case: + // Choose shortest Paths + auto min_length = possible_paths.at(0).first.size(); + std::vector, double>> shortest_paths = {}; + for (auto path : possible_paths) { + if (path.first.size() < min_length) { + min_length = path.first.size(); + } + } + for (auto path : possible_paths) { + if (path.first.size() == min_length) { + ; + shortest_paths.push_back(path); + } + } + if (shortest_paths.size() == 1) { + return shortest_paths.at(0); + } + // Find shortest path with minimal cost + auto min_cost = shortest_paths.at(0).second; + auto best_path = shortest_paths.at(0); + for (auto path : shortest_paths) { + if (path.second > min_cost) { + min_cost = path.second; + best_path = path; + } + } + return best_path; +} +double ThetaOptScheduler::calc_cost( + std::vector>::const_reference path, + DiGraph, std::vector>>& + subproblem_graph) { + double cost = 0; + for (size_t node = 0; node < path.size() - 1; node++) { + for (const auto [child, weight] : + subproblem_graph.get_adjacent(path[node])) { + if (child == path[node + 1]) { + cost += weight; + break; + } + } + } + return cost; +} +std::vector ThetaOptScheduler::find_leaf_nodes( + DiGraph>& circuit, + const DiGraph, + std::vector>>& subproblem_graph) { + std::vector end_nodes = std::vector{}; + for (size_t i = 0; i < subproblem_graph.get_N_Nodes(); i++) { + if (subproblem_graph.get_adjacent(i).empty()) { + end_nodes.push_back(i); + } + } + return end_nodes; +} +std::vector ThetaOptScheduler::sort_by_theta_dec( + DiGraph>& circuit, + const std::vector& vector) { + std::vector sorted = {}; +} +std::vector +ThetaOptScheduler::remove_element(const std::vector& vector, + std::size_t node) { + std::vector new_vector = {}; + for (auto element : vector) { + if (element != node) { + new_vector.push_back(element); + } + } + return new_vector; +} + +// TODO: ADD last cond Bool?? +std::vector, 4>, qc::fp>> +ThetaOptScheduler::get_possible_moments( DiGraph>& circuit, const std::vector& v0_c, const std::array, 3>& v_new) { - std::vector v_p1_star=v_new[0]; - std::vector v_p1_square=std::vector(); - std::vector v_c1_star=v_new[1]; - std::vector v_c1_square=std::vector(); + std::vector v_p1_star = v_new[0]; + std::vector v_p1_square = {}; + std::vector v_c1_star = v_new[1]; + std::vector v_c1_square = {}; - qc::fp v_c0_cost=max_theta(circuit, v0_c); - qc::fp v_c1_cost=max_theta(circuit, v_new[1]); - qc::fp orig_comb_cost=v_c0_cost+v_c1_cost; - qc::fp new_v_C1_cost=std::max(v_c0_cost,v_c1_cost); + qc::fp v_c0_cost = max_theta(circuit, v0_c); + qc::fp v_c1_cost = max_theta(circuit, v_new[1]); + qc::fp orig_comb_cost = v_c0_cost + v_c1_cost; + qc::fp new_v_C1_cost = std::max(v_c0_cost, v_c1_cost); - std::array,4> v_arg={v0_c,v_new[0],v_new[1],v_new[2]}; - auto args={std::pair(v_arg,v_c0_cost)}; - //TODO: Check Condition 1 - //Sort v_0C from highest to lowest theta + std::array, 4> v_arg = {v0_c, v_new[0], v_new[1], + v_new[2]}; + std::vector, 4>, qc::fp>> args = + {std::pair(v_arg, v_c0_cost)}; + // Sort v_0C from highest to lowest theta + std::vector v_sort(v0_c); + auto sort_by_theta = [&circuit](std::size_t a, std::size_t b) { + return circuit.get_Node_Value(a)->get()->getParameter().front() > + circuit.get_Node_Value(b)->get()->getParameter().front(); + }; + std::ranges::sort(v_sort, sort_by_theta); + // TODO: Check Condition 1 + std::vector, 2>, + std::pair, qc::fp>>> + potential_arg = {}; + auto prev_theta = + circuit.get_Node_Value(v_sort[0])->get()->getParameter().front(); + auto this_theta = prev_theta; + // TODO: This should be Qubits not Operations!!! change ARG + std::set mk_qubits = { + circuit.get_Node_Value(v_sort[0])->get()->getUsedQubits()}; + for (auto i = 0; i < v_sort.size(); i++) { + this_theta = + circuit.get_Node_Value(v_sort[i])->get()->getParameter().front(); + if (this_theta != prev_theta) { + std::vector discarded = {v_sort.begin(), + v_sort.begin() + (i - 1)}; + std::vector kept = {v_sort.begin() + i, v_sort.end()}; + potential_arg.push_back(std::pair, 2>, + std::pair, qc::fp>>( + {kept, discarded}, + std::pair, qc::fp>(mk_qubits, this_theta))); + prev_theta = this_theta; + mk_qubits.clear(); + } + mk_qubits.merge(circuit.get_Node_Value(v_sort[i])->get()->getUsedQubits()); + } + std::vector push_back_nodes = {}; + std::set p_square_qubits = {}; - //TODO: Check Condition 2 - // TODO: Check Condition 3 - //TODO Check Condition 4 ?? Find out what it does!! + for (auto pot : potential_arg) { + // TODO: Check Condition 2 + for (auto node : v_p1_star) { + std::set qubits = + circuit.get_Node_Value(node)->get()->getUsedQubits(); + if (!disjunct(qubits, pot.second.first)) { + push_back_nodes.emplace_back(node); + p_square_qubits.merge(qubits); + } + } + for (auto node : push_back_nodes) { + v_p1_star = remove_element(v_p1_star, node); + v_p1_square.emplace_back(node); + } + + if (v_p1_star.empty()) { + break; + } + // TODO: Check Condition 3 + std::set push_qubits = pot.second.first; + push_qubits.merge(p_square_qubits); + push_back_nodes.clear(); - return args; + for (auto node : v_c1_star) { + std::set qubits = + circuit.get_Node_Value(node)->get()->getUsedQubits(); + if (!disjunct(qubits, push_qubits)) { + push_back_nodes.emplace_back(node); + } + } + for (auto node : push_back_nodes) { + v_c1_star = remove_element(v_c1_star, node); + v_c1_square.emplace_back(node); + } + + if (v_c1_star.empty()) { + break; + } + // TODO Check Condition 4 ?? Find out what it does!! + bool check_last_cond = false; + if ((!check_last_cond) || + (check_last_cond && + pot.second.second + new_v_C1_cost < orig_comb_cost)) { + v_arg = {pot.first[0], v_p1_star,pot.first[1],v_new[2]}; + for (auto node: v_c1_star) { + v_arg[2].push_back(node); + } + for (auto node : v_c1_square) {v_arg[3].push_back(node);} + for (auto node:v_p1_square) {v_arg[3].push_back(node);} + args.push_back(std::pair, 4>, qc::fp>(v_arg,pot.second.second)); + } + } + return args; } ThetaOptScheduler::DiGraph> ThetaOptScheduler::convert_circ_to_dag( const std::pair, - std::vector>& qc) const { + std::vector>& qc) { ThetaOptScheduler::DiGraph> graph = DiGraph>(); std::vector> qubit_paths = @@ -101,14 +317,14 @@ ThetaOptScheduler::convert_circ_to_dag( } } for (auto m = 0; m < qc.second.at(i).size(); ++m) { - auto t=qc.second.at(i); - //Create CZ & Make_unique - size_t node = graph.add_Node(std::make_unique(qc::StandardOperation(qc::Control(qc.second.at(i).at(m)[0]),qc.second.at(i).at(m)[1],qc::Z,{}))); + auto t = qc.second.at(i); + // Create CZ & Make_unique + size_t node = graph.add_Node(std::make_unique( + qc::StandardOperation(qc::Control(qc.second.at(i).at(m)[0]), + qc.second.at(i).at(m)[1], qc::Z, {}))); qubit_paths.at(qc.second.at(i).at(m).at(0)) .push_back(node); - qubit_paths.at(qc.second.at(i).at(m).at(1)) - .push_back(node); - + qubit_paths.at(qc.second.at(i).at(m).at(1)).push_back(node); } } for (auto s = 0; s < qc.first.end()->size(); ++s) { @@ -126,141 +342,147 @@ ThetaOptScheduler::convert_circ_to_dag( return graph; } - -bool disjunct(const std::unordered_set& set1, - const std::unordered_set& set2) { - for (auto elem: set1) { - if (set2.contains(elem)){return false;} - } - return true; -} - qc::fp ThetaOptScheduler::max_theta( DiGraph>& circuit, const std::vector& nodes) { - qc::fp max_cost=0; - for (const auto node : nodes) { - if ((*circuit.get_Node_Value(node))->getParameter()[0]>=max_cost) { - max_cost=(*circuit.get_Node_Value(node))->getParameter()[0]; - } + qc::fp max_cost = 0; + for (const auto node : nodes) { + if ((*circuit.get_Node_Value(node))->getParameter()[0] >= max_cost) { + max_cost = (*circuit.get_Node_Value(node))->getParameter()[0]; } - return max_cost; + } + return max_cost; } -std::array, 3> ThetaOptScheduler::sift( - DiGraph>& circuit, - size_t n_qubits) { - std::vector v_p=std::vector(); - std::vector v_c=std::vector(); - std::vector v_r=std::vector(); +std::array, 3> +ThetaOptScheduler::sift(DiGraph>& circuit, + size_t n_qubits) { + std::vector v_p = std::vector(); + std::vector v_c = std::vector(); + std::vector v_r = std::vector(); - std::unordered_set removed=std::unordered_set(); + std::set removed = std::set(); - for (auto node=0; node < circuit.get_N_Nodes(); node++) { - //TODO: Check for unique pointer issue - auto op=circuit.get_Node_Value(node); - std::unordered_set op_qubits=std::unordered_set(); - for (auto qubit:op->get()->getUsedQubits()){op_qubits.insert(qubit);} - if (removed.size()get()->getNqubits()==1) { - v_c.push_back(node); - removed.insert(op->get()->getTargets().at(0)); - }else { - v_p.push_back(node); - //Add something to make it only pick one 2-Qubit gate per Qubit per moment??? - } - }else { - v_r.push_back(node); + for (auto node = 0; node < circuit.get_N_Nodes(); node++) { + // TODO: Check for unique pointer issue + auto op = circuit.get_Node_Value(node); + std::set op_qubits = std::set(); + for (auto qubit : op->get()->getUsedQubits()) { + op_qubits.insert(qubit); + } + if (removed.size() < n_qubits && disjunct(removed, op_qubits)) { + if (op->get()->getNqubits() == 1) { + v_c.push_back(node); + removed.insert(op->get()->getTargets().at(0)); + } else { + v_p.push_back(node); + // Add something to make it only pick one 2-Qubit gate per Qubit per + // moment??? } + } else { + v_r.push_back(node); + } } - return std::array, 3>({v_p,v_c,v_r}); + return std::array, 3>({v_p, v_c, v_r}); } -static std::pair, std::vector> +std::pair, std::vector> ThetaOptScheduler::build_schedule( + // TODO: FIgure ouot how to interface with scheduler DiGraph>& circuit, - DiGraph,std::vector>>& + DiGraph, std::vector>>& subproblem_graph) { - //TODO: Find Leaf Nodes of di_graph - std::vector leaf_nodes; - for (std::size_t i=0;i start_nodes= find_start_nodes(subproblem_graph); - std::vector> paths_to_leafs= find_shortest_paths(subproblem_graph,leaf_nodes,start_nodes); - //TODO: Find shortest path with minimal weight - std::vector minimal_path=std::vector(); - double min_cost= 100000000000000; //TODO: Find Max double - for (auto path: paths_to_leafs) { - double cost=calc_cost(subproblem_graph,cost); - if (cost, std::vector> schedule=std::pair, std::vector>{}; - //TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st v_p empty skip adding it . If not add empty SQGL - for (auto i=0;isecond.size();++j) { - auto op=subproblem_graph.get_Node_Value(minimal_path[i])->second.at(j); - schedule.first.at(i+1).emplace_back(std::move(*circuit.get_Node_Value(op))); + // TODO: Find Leaf Nodes of di_graph + std::vector leaf_nodes = + find_leaf_nodes(circuit, subproblem_graph); + // TODO: Find shortest path with minimal weight + std::vector minimal_path = + find_shortest_path(subproblem_graph, leaf_nodes); + std::pair, std::vector> + schedule = std::pair, + std::vector>{}; + // TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st v_p + // empty skip adding it . If not add empty SQGL + for (auto i = 0; i < minimal_path.size(); i++) { + for (auto j = 0; + j < subproblem_graph.get_Node_Value(minimal_path[i])->second.size(); + ++j) { + auto op = subproblem_graph.get_Node_Value(minimal_path[i])->second.at(j); + schedule.first.at(i + 1).emplace_back( + std::move(*circuit.get_Node_Value(op))); } - for (auto j=0;jfirst.size();++j) { - auto op=subproblem_graph.get_Node_Value(minimal_path[i])->first.at(j); - schedule.second.at(i).emplace_back(std::move(*circuit.get_Node_Value(op))); + for (auto j = 0; + j < subproblem_graph.get_Node_Value(minimal_path[i])->first.size(); + ++j) { + auto op = circuit.get_Node_Value( + subproblem_graph.get_Node_Value(minimal_path[i])->first.at(j)); + schedule.second.at(i).emplace_back( + std::array({op->get()->getControls().begin()->qubit, op->get()->getTargets()[0]})); } } return schedule; } size_t ThetaOptScheduler::add_node_to_sub_prob_graph( std::vector v_p, std::vector v_c, qc::fp cost, - DiGraph,std::vector>>& - subproblem_graph,std::size_t prev_node) { - std::size_t new_node=subproblem_graph.add_Node(std::pair(v_p,v_c)); - subproblem_graph.add_Edge(prev_node,new_node,cost); - return new_node; + DiGraph, std::vector>>& + subproblem_graph, + std::size_t prev_node) { + std::size_t new_node = subproblem_graph.add_Node(std::pair(v_p, v_c)); + subproblem_graph.add_Edge(prev_node, new_node, cost); + return new_node; } + double ThetaOptScheduler::schedule_remaining( const std::array, 3>& v, - DiGraph>& circuit, - DiGraph, std::vector>>& + DiGraph>& circuit, + DiGraph, std::vector>>& subproblem_graph, - size_t prev_node, size_t n_qubits) { - double cost; - //TODO: Check if subproblem has been computed - //auto id=?;//What to do for id?? - //if (memo.contains()) {//KEy set?? - // cost=memo.at(id)[0]; - // sub_node=memo.at(id)[1]; - // edge_weight=memo.at(id)[2]; - // subproblem_graph.add_edge(prev_node,sub_node,edge_weight); - // return cost; - // } - //TODO: Base Case-> V_rem is empty - if (v[2].size()==0) { - cost=0; - for (auto i=0; i cost) { - cost=std::fabs(v[1].at(i)); - } - } - add_node_to_sub_prob_graph(v[0],v[1],cost,subproblem_graph, prev_node); - return cost; - } - //TODO: Recursive Call - auto v_new=sift(circuit,n_qubits); - auto args= get_possible_moments(circuit,v[1],v_new); - std::vector costs=std::vector(); - for (const auto& arg:args) { - auto new_node=add_node_to_sub_prob_graph(v[0],v_new[1],arg.second,subproblem_graph, prev_node); - costs.push_back(schedule_remaining(v_new,circuit,subproblem_graph,new_node,n_qubits)+arg.second); + size_t prev_node, size_t n_qubits, + std::map>>& + memo) { + double cost; + // TODO: Check if subproblem has been computed + std::size_t id = std::hash, 3>>{}(v); + if (memo.contains(id)) { + std::size_t sub_node = memo.at(id).first; + double edge_weight = memo.at(id).second[1]; + subproblem_graph.add_Edge(prev_node, sub_node, edge_weight); + return cost; + } + // TODO: Base Case-> V_rem is empty + if (v[2].size() == 0) { + cost = v[1].at(0); + for (auto i = 0; i < v[1].size(); ++i) { + // DO I need abs here??? + if (v[1].at(i) > cost) { + cost = v[1].at(i); } - cost= *std::ranges::min_element(costs); - //memo.add(id,) - return cost; + } + add_node_to_sub_prob_graph(v[0], v[1], cost, subproblem_graph, prev_node); + return cost; + } + // TODO: Recursive Call + auto v_new = sift(circuit, n_qubits); + auto args = get_possible_moments(circuit, v[1], v_new); + qc::fp temp_cost = 0; + double min_cost = std::numeric_limits::max(); + double min_weight = std::numeric_limits::max(); + std::size_t min_node; + for (const auto& arg : args) { + auto new_node = add_node_to_sub_prob_graph(v[0], v_new[1], arg.second, + subproblem_graph, prev_node); + temp_cost=schedule_remaining(v_new, circuit, subproblem_graph, + new_node, n_qubits, memo) +arg.second; + if (temp_cost>(min_node,{min_cost,min_weight}); + return cost; } auto ThetaOptScheduler::schedule(const qc::QuantumComputation& qc) const @@ -271,19 +493,20 @@ auto ThetaOptScheduler::schedule(const qc::QuantumComputation& qc) const std::pair, std::vector> qc_p = preprocess_qc(qc, architecture_, config_); // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? - //TODO: Circuit on NON_Unique pointers?? + // TODO: Circuit on NON_Unique pointers?? DiGraph> circuit = convert_circ_to_dag(qc_p); // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) // v=(v_p,v_c,v_r) - std::array, 3> v=sift(circuit,qc.size()); + std::array, 3> v = sift(circuit, qc.size()); // TODO: Create Subproblem Graph - DiGraph, - std::vector>>sub_prob_graph= DiGraph, - std::vector>> (); + DiGraph, std::vector>>sub_prob_graph= DiGraph< + std::pair, std::vector>>(); // TODO: First Call of Recursive Function to create Schedule - auto base_node=sub_prob_graph.add_Node(std::pair,std::vector>({},{})); - auto cost=schedule_remaining(v, circuit, sub_prob_graph, base_node,qc.getNqubits()); + auto base_node = sub_prob_graph.add_Node(std::pair,std::vector>({},{})); + std::map>> memo={}; + auto cost=schedule_remaining(v, circuit, sub_prob_graph, base_node, + qc.getNqubits(), memo); // TODO: Create Schedule from Subproblem Graph std::pair, From 6840edfc49036f6d754cd115922eb0a852ebcebe Mon Sep 17 00:00:00 2001 From: ga96dup Date: Wed, 8 Apr 2026 00:24:06 +0200 Subject: [PATCH 075/110] Decomposer Version of the Scheduler --- .../na/zoned/decomposer/DecomposerBase.hpp | 6 +- .../zoned/decomposer/NativeGateDecomposer.hpp | 156 ++++- .../na/zoned/scheduler/ThetaOptScheduler.hpp | 169 ------ .../zoned/decomposer/NativeGateDecomposer.cpp | 535 +++++++++++++++++- src/na/zoned/scheduler/ThetaOptScheduler.cpp | 483 ---------------- 5 files changed, 687 insertions(+), 662 deletions(-) diff --git a/include/na/zoned/decomposer/DecomposerBase.hpp b/include/na/zoned/decomposer/DecomposerBase.hpp index 7713f5f48..6cf38ecd5 100644 --- a/include/na/zoned/decomposer/DecomposerBase.hpp +++ b/include/na/zoned/decomposer/DecomposerBase.hpp @@ -31,7 +31,9 @@ class DecomposerBase { */ [[nodiscard]] virtual auto decompose(size_t nQubits, - const std::vector& singleQubitGateLayers) - -> std::vector = 0; + const std::pair, + std::vector>& asap_schedule) + -> std::pair, + std::vector> = 0; }; } // namespace na::zoned diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index a81cca4e4..68b48a160 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -33,6 +33,7 @@ class NativeGateDecomposer : public DecomposerBase { */ using Quaternion = std::array; size_t nQubits_ = 0; + bool theta_opt_schedule = false; constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; @@ -49,6 +50,7 @@ class NativeGateDecomposer : public DecomposerBase { }; /// Create a new NativeGateDecomposer. + // TODO: Add in BOOL for scheduling here? NativeGateDecomposer(const Architecture& /* unused */, const Config& /* unused */) {} @@ -121,8 +123,156 @@ class NativeGateDecomposer : public DecomposerBase { [[nodiscard]] auto decompose(size_t nQubits, - const std::vector& singleQubitGateLayers) - -> std::vector override; -}; + const std::pair, + std::vector>& asap_schedule) + -> std::pair, + std::vector> override; + static auto NativeGateDecomposer::preprocess( + const std::pair>, + std::vector>& schedule) + -> std::pair, + std::vector>; + + template class DiGraph { + std::size_t nodes; + std::vector>> adjacencies_; + std::vector node_values_; + + public: + DiGraph() { + nodes = 0; + adjacencies_ = std::vector>>(); + node_values_ = std::vector(); + } + std::size_t add_Node(T node) { + adjacencies_.push_back(std::vector>()); + node_values_.push_back(std::move(node)); + return nodes++; + } + bool add_Edge(std::size_t from, std::size_t to, double weight) { + if (from < nodes && to < nodes && from != to) { + adjacencies_[from].push_back( + std::pair(to, weight)); + return true; + } else { + return false; + } + } + + bool add_Edge(std::size_t from, std::size_t to) { + if (from < nodes && to < nodes && from != to) { + adjacencies_[from].push_back( + std::pair(to, 1.0)); + return true; + } else { + return false; + } + } + + T* get_Node_Value(std::size_t node) { + if (node < nodes) { + return &node_values_[node]; + // return node_values_.at(node); + } else { + std::ostringstream oss; + oss << "ERROR: Node Number out of range: " << node << "\n"; + throw std::invalid_argument(oss.str()); + } + } + std::size_t get_N_Nodes() const { return nodes; } + + std::vector> + get_adjacent(std::size_t i) const { + return adjacencies_.at(i); + } + }; + + static static auto NativeGateDecomposer::convert_circ_to_dag( + std::pair, + std::vector>& qc) + -> NativeGateDecomposer::DiGraph>; + + static std::pair, double> shortest_path_to_start( + const DiGraph, std::vector>>& + subproblem_graph, + unsigned long long curr_node, std::set leaf_nodes); + static std::vector find_shortest_path( + const DiGraph, + std::vector>>& di_graph, + const std::vector& vector); + static double + calc_cost(std::vector>::const_reference path, + DiGraph, std::vector>>& + subproblem_graph); + static std::vector find_leaf_nodes( + DiGraph>& circuit, + const DiGraph, + std::vector>>& subproblem_graph); + static std::vector + sort_by_theta_dec(DiGraph>& circuit, + const std::vector& vector); + static std::vector + remove_element(const std::vector& vector, std::size_t node); + static std::vector, 4>, qc::fp>> + get_possible_moments(DiGraph>& circuit, + const std::vector& v0_c, + const std::array, 3>& v_new); + static std::pair>, + std::vector> + postprocess(std::pair, + std::vector>); + static qc::fp + max_theta(DiGraph>& circuit, + const std::vector& nodes); + static std::array, 3> + sift(DiGraph>& circuit, size_t n_qubits); + static auto NativeGateDecomposer::build_schedule( + DiGraph>& circuit, + DiGraph, std::vector>>& + subproblem_graph) -> std::pair, + std::vector>; + + static auto add_node_to_sub_prob_graph( + std::vector v_p, std::vector v_c, qc::fp cost, + DiGraph, std::vector>>& + subproblem_graph, + size_t prev_node) -> size_t; + + static double schedule_remaining( + const std::array, 3>& v, + DiGraph>& circuit, + DiGraph, std::vector>>& + subproblem_graph, + size_t prev_node, size_t n_qubits, + std::map>>& memo); + /** + * This function schedules the operations of a quantum computation. + * @details + * @param qc is the quantum computation + * @return a pair of two vectors. The first vector contains the layers of + * single-qubit operations. The second vector contains the layers of two-qubit + * operations. A pair of qubits represents every two-qubit operation. + */ + auto NativeGateDecomposer::schedule( + const std::pair>, + std::vector>& asap_schedule) const + -> std::pair>, + std::vector>; +}; } // namespace na::zoned + +template <> struct std::hash, 3>> { + std::size_t operator()( + const std::array, 3>& array) const noexcept { + std::size_t seed = 0U; + for (auto v : array) { + for (auto node : v) { + qc::hashCombine(seed, std::hash{}(node)); + } + } + return seed; + } +}; + + diff --git a/include/na/zoned/scheduler/ThetaOptScheduler.hpp b/include/na/zoned/scheduler/ThetaOptScheduler.hpp index b4bf8afb7..5f0ffe535 100644 --- a/include/na/zoned/scheduler/ThetaOptScheduler.hpp +++ b/include/na/zoned/scheduler/ThetaOptScheduler.hpp @@ -13,172 +13,3 @@ #include #include -namespace na::zoned { -/** - * The class ThetaOptScheduler implements a scheduling strategy minimizing the - * total global rotation angle theta over the circuit for the zoned neutral atom - * compiler. - */ -class ThetaOptScheduler : public SchedulerBase { - /// A reference to the zoned neutral atom architecture - std::reference_wrapper architecture_; - /** - * This value is calculated based on the architecture and indicates the - * the entanglement zone. - */ - size_t maxTwoQubitGateNumPerLayer_ = 0; - -public: - /// The configuration of the ASAPScheduler - struct Config { - /// The maximal share of traps that are used in the entanglement zone. - double maxFillingFactor = 0.9; - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, maxFillingFactor); - }; - - template class DiGraph { - std::size_t nodes; - // Add pedecessors??? - std::vector>> adjacencies_; - std::vector node_values_; - - public: - DiGraph() { - nodes = 0; - adjacencies_ = std::vector>>(); - node_values_ = std::vector(); - } - std::size_t add_Node(T node) { - adjacencies_.push_back(std::vector>()); - node_values_.push_back(std::move(node)); - return nodes++; - } - bool add_Edge(std::size_t from, std::size_t to, double weight) { - if (from < nodes && to < nodes && from != to) { - adjacencies_[from].push_back( - std::pair(to, weight)); - return true; - } else { - return false; - } - } - - bool add_Edge(std::size_t from, std::size_t to) { - if (from < nodes && to < nodes && from != to) { - adjacencies_[from].push_back( - std::pair(to, 1.0)); - return true; - } else { - return false; - } - } - - T* get_Node_Value(std::size_t node) { - if (node < nodes) { - return &node_values_[node]; - // return node_values_.at(node); - } else { - std::ostringstream oss; - oss << "ERROR: Node Number out of range: " << node << "\n"; - throw std::invalid_argument(oss.str()); - } - } - std::size_t get_N_Nodes() const { return nodes; } - - std::vector> - get_adjacent(std::size_t i) const { - return adjacencies_.at(i); - } - }; - -private: - /// The configuration of the ThetaOptScheduler - Config config_; - -public: - /** - * Create a new ThetaOptScheduler. - * @param architecture is the architecture of the neutral atom system - * @param config is the configuration for the scheduler - */ - ThetaOptScheduler(const Architecture& architecture, const Config& config); - static DiGraph> - convert_circ_to_dag(const std::pair, - std::vector>& qc); - std::pair, std::vector> - preprocess_qc(const qc::QuantumComputation& qc, - const Architecture& architecture, Config config) const; - static std::pair, double> shortest_path_to_start( - const DiGraph, std::vector>>& - subproblem_graph, - unsigned long long curr_node, std::set leaf_nodes); - std::vector find_shortest_path( - const DiGraph, - std::vector>>& di_graph, - const std::vector& vector); - static double - calc_cost(std::vector>::const_reference path, - DiGraph, std::vector>>& - subproblem_graph); - static std::vector find_leaf_nodes( - DiGraph>& circuit, - const DiGraph, - std::vector>>& subproblem_graph); - static std::vector - sort_by_theta_dec(DiGraph>& circuit, - const std::vector& vector); - static std::vector - remove_element(const std::vector& vector, std::size_t node); - static std::vector, 4>, qc::fp>> - get_possible_moments(DiGraph>& circuit, - const std::vector& v0_c, - const std::array, 3>& v_new); - static qc::fp - max_theta(DiGraph>& circuit, - const std::vector& nodes); - static std::array, 3> - sift(DiGraph>& circuit, size_t n_qubits); - std::pair, std::vector> - build_schedule(DiGraph>& circuit, - DiGraph, std::vector>>& - subproblem_graph) const; - - static auto add_node_to_sub_prob_graph( - std::vector v_p, std::vector v_c, qc::fp cost, - DiGraph, std::vector>>& - subproblem_graph, - size_t prev_node) -> size_t; - - static double schedule_remaining( - const std::array, 3>& v, - DiGraph>& circuit, - DiGraph, std::vector>>& - subproblem_graph, - size_t prev_node, size_t n_qubits, - std::map>>& memo); - /** - * This function schedules the operations of a quantum computation. - * @details - * @param qc is the quantum computation - * @return a pair of two vectors. The first vector contains the layers of - * single-qubit operations. The second vector contains the layers of two-qubit - * operations. A pair of qubits represents every two-qubit operation. - */ - [[nodiscard]] auto schedule(const qc::QuantumComputation& qc) const - -> std::pair, - std::vector> override; -}; -} // namespace na::zoned - -template <> struct std::hash, 3>> { - std::size_t operator()( - const std::array, 3>& array) const noexcept { - std::size_t seed = 0U; - for (auto v : array) { - for (auto node : v) { - qc::hashCombine(seed, std::hash{}(node)); - } - } - return seed; - } -}; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 7732ade3d..fcf9c0505 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -205,13 +205,23 @@ auto NativeGateDecomposer::getDecompositionAngles( } auto NativeGateDecomposer::decompose( - const size_t nQubits, - const std::vector& singleQubitGateLayers) - -> std::vector { + size_t nQubits, + const std::pair, + std::vector>& asap_schedule) + -> std::pair, + std::vector> { nQubits_ = nQubits; std::vector> U3Layers = - transformToU3(singleQubitGateLayers); + transformToU3(asap_schedule.first); + std::vector NewTwoQubitGateLayers = asap_schedule.second; + if (theta_opt_schedule) { + // TODO: Put in scheduling function here + auto thetaOptSchedule = + schedule(std::pair(U3Layers, NewTwoQubitGateLayers)); + U3Layers = thetaOptSchedule.first; + NewTwoQubitGateLayers = thetaOptSchedule.second; + } std::vector NewSingleQubitLayers = std::vector{}; @@ -260,6 +270,521 @@ auto NativeGateDecomposer::decompose( } NewSingleQubitLayers.push_back(std::move(NewLayer)); } // layer::SingleQubitLayers - return NewSingleQubitLayers; + return {std::move(NewSingleQubitLayers), NewTwoQubitGateLayers}; +} + +auto NativeGateDecomposer::preprocess( + const std::pair>, + std::vector>& schedule) + -> std::pair, + std::vector> { + std::vector NewSingleQubitLayers = + std::vector{}; + SingleQubitGateLayer NewLayer; + for (const auto& singleQubitLayer : schedule.first) { + NewLayer.clear(); + for (auto gate : singleQubitLayer) { + NewLayer.emplace_back( + std::make_unique(qc::StandardOperation( + (qc::Qubit)gate.qubit, qc::U, + {gate.angles[0], gate.angles[1], gate.angles[2]}))); + } + NewSingleQubitLayers.push_back(std::move((NewLayer))); + } + std::vector NewTwoQubitLayers = + std::vector{}; + + for (const auto& twoQubitLayer : schedule.second) { + NewLayer.clear(); + for (auto gate : twoQubitLayer) { + NewLayer.emplace_back( + std::make_unique(qc::StandardOperation( + qc::Control((qc::Qubit)gate[0]), (qc::Qubit)gate[1], qc::Z, {}))); + } + NewTwoQubitLayers.push_back(std::move((NewLayer))); + } + return std::pair, + std::vector>( + std::move(NewSingleQubitLayers), std::move(NewTwoQubitLayers)); +} + +std::vector NativeGateDecomposer::find_shortest_path( + const DiGraph, + std::vector>>& subproblem_graph, + const std::vector& leaf_nodes) { + std::set leafs = + std::set(leaf_nodes.begin(), leaf_nodes.end()); + std::pair, double> leaf_path = + shortest_path_to_start(subproblem_graph, 0, leafs); + std::reverse(leaf_path.first.begin(), leaf_path.first.end()); + return leaf_path.first; +} +bool disjunct(const std::set& set1, const std::set& set2) { + for (auto elem : set1) { + if (set2.contains(elem)) { + return false; + } + } + return true; +} + +bool disjunct(const std::set& set1, + const std::set& set2) { + for (auto elem : set1) { + if (set2.contains(elem)) { + return false; + } + } + return true; +} + +std::pair, double> +NativeGateDecomposer::shortest_path_to_start( + const DiGraph, + std::vector>>& subproblem_graph, + std::size_t curr_node, std::set leaf_nodes) { + std::vector, double>> possible_paths = {}; + // Check if leaf nodes are reached + for (auto node : subproblem_graph.get_adjacent(curr_node)) { + if (leaf_nodes.contains(node.first)) { + possible_paths.push_back({std::pair, double>( + {node.first, curr_node}, node.second)}); + } + } + // Recursive Case + if (possible_paths.empty()) { + for (auto node : subproblem_graph.get_adjacent(curr_node)) { + auto path = + shortest_path_to_start(subproblem_graph, node.first, leaf_nodes); + path.first.push_back(curr_node); + path.second += node.second; + possible_paths.push_back(path); + } + } + // Base Case: + // Choose shortest Paths + auto min_length = possible_paths.at(0).first.size(); + std::vector, double>> shortest_paths = {}; + for (auto path : possible_paths) { + if (path.first.size() < min_length) { + min_length = path.first.size(); + } + } + for (auto path : possible_paths) { + if (path.first.size() == min_length) { + ; + shortest_paths.push_back(path); + } + } + if (shortest_paths.size() == 1) { + return shortest_paths.at(0); + } + // Find shortest path with minimal cost + auto min_cost = shortest_paths.at(0).second; + auto best_path = shortest_paths.at(0); + for (auto path : shortest_paths) { + if (path.second > min_cost) { + min_cost = path.second; + best_path = path; + } + } + return best_path; +} +double NativeGateDecomposer::calc_cost( + std::vector>::const_reference path, + DiGraph, std::vector>>& + subproblem_graph) { + double cost = 0; + for (size_t node = 0; node < path.size() - 1; node++) { + for (const auto [child, weight] : + subproblem_graph.get_adjacent(path[node])) { + if (child == path[node + 1]) { + cost += weight; + break; + } + } + } + return cost; +} +std::vector NativeGateDecomposer::find_leaf_nodes( + DiGraph>& circuit, + const DiGraph, + std::vector>>& subproblem_graph) { + std::vector end_nodes = std::vector{}; + for (size_t i = 0; i < subproblem_graph.get_N_Nodes(); i++) { + if (subproblem_graph.get_adjacent(i).empty()) { + end_nodes.push_back(i); + } + } + return end_nodes; +} +std::vector NativeGateDecomposer::sort_by_theta_dec( + DiGraph>& circuit, + const std::vector& vector) { + std::vector sorted = {}; +} +std::vector +NativeGateDecomposer::remove_element(const std::vector& vector, + std::size_t node) { + std::vector new_vector = {}; + for (auto element : vector) { + if (element != node) { + new_vector.push_back(element); + } + } + return new_vector; +} + +// TODO: ADD last cond Bool?? +std::vector, 4>, qc::fp>> +NativeGateDecomposer::get_possible_moments( + DiGraph>& circuit, + const std::vector& v0_c, + const std::array, 3>& v_new) { + + std::vector v_p1_star = v_new[0]; + std::vector v_p1_square = {}; + std::vector v_c1_star = v_new[1]; + std::vector v_c1_square = {}; + + qc::fp v_c0_cost = max_theta(circuit, v0_c); + qc::fp v_c1_cost = max_theta(circuit, v_new[1]); + qc::fp orig_comb_cost = v_c0_cost + v_c1_cost; + qc::fp new_v_C1_cost = std::max(v_c0_cost, v_c1_cost); + + std::array, 4> v_arg = {v0_c, v_new[0], v_new[1], + v_new[2]}; + std::vector, 4>, qc::fp>> args = + {std::pair(v_arg, v_c0_cost)}; + // Sort v_0C from highest to lowest theta + std::vector v_sort(v0_c); + auto sort_by_theta = [&circuit](std::size_t a, std::size_t b) { + return circuit.get_Node_Value(a)->get()->getParameter().front() > + circuit.get_Node_Value(b)->get()->getParameter().front(); + }; + std::ranges::sort(v_sort, sort_by_theta); + // TODO: Check Condition 1 + std::vector, 2>, + std::pair, qc::fp>>> + potential_arg = {}; + auto prev_theta = + circuit.get_Node_Value(v_sort[0])->get()->getParameter().front(); + auto this_theta = prev_theta; + // TODO: This should be Qubits not Operations!!! change ARG + std::set mk_qubits = { + circuit.get_Node_Value(v_sort[0])->get()->getUsedQubits()}; + for (auto i = 0; i < v_sort.size(); i++) { + this_theta = + circuit.get_Node_Value(v_sort[i])->get()->getParameter().front(); + if (this_theta != prev_theta) { + std::vector discarded = {v_sort.begin(), + v_sort.begin() + (i - 1)}; + std::vector kept = {v_sort.begin() + i, v_sort.end()}; + potential_arg.push_back(std::pair, 2>, + std::pair, qc::fp>>( + {kept, discarded}, + std::pair, qc::fp>(mk_qubits, this_theta))); + prev_theta = this_theta; + mk_qubits.clear(); + } + mk_qubits.merge(circuit.get_Node_Value(v_sort[i])->get()->getUsedQubits()); + } + std::vector push_back_nodes = {}; + std::set p_square_qubits = {}; + + for (auto pot : potential_arg) { + // TODO: Check Condition 2 + for (auto node : v_p1_star) { + std::set qubits = + circuit.get_Node_Value(node)->get()->getUsedQubits(); + if (!disjunct(qubits, pot.second.first)) { + push_back_nodes.emplace_back(node); + p_square_qubits.merge(qubits); + } + } + for (auto node : push_back_nodes) { + v_p1_star = remove_element(v_p1_star, node); + v_p1_square.emplace_back(node); + } + + if (v_p1_star.empty()) { + break; + } + // TODO: Check Condition 3 + std::set push_qubits = pot.second.first; + push_qubits.merge(p_square_qubits); + push_back_nodes.clear(); + + for (auto node : v_c1_star) { + std::set qubits = + circuit.get_Node_Value(node)->get()->getUsedQubits(); + if (!disjunct(qubits, push_qubits)) { + push_back_nodes.emplace_back(node); + } + } + for (auto node : push_back_nodes) { + v_c1_star = remove_element(v_c1_star, node); + v_c1_square.emplace_back(node); + } + + if (v_c1_star.empty()) { + break; + } + // TODO Check Condition 4 ?? Find out what it does!! + bool check_last_cond = false; + if ((!check_last_cond) || + (check_last_cond && + pot.second.second + new_v_C1_cost < orig_comb_cost)) { + v_arg = {pot.first[0], v_p1_star, pot.first[1], v_new[2]}; + for (auto node : v_c1_star) { + v_arg[2].push_back(node); + } + for (auto node : v_c1_square) { + v_arg[3].push_back(node); + } + for (auto node : v_p1_square) { + v_arg[3].push_back(node); + } + args.push_back(std::pair, 4>, qc::fp>( + v_arg, pot.second.second)); + } + } + return args; +} +std::pair>, + std::vector> +NativeGateDecomposer::postprocess( + std::pair, std::vector> + schedule) { + std::vector> U3Layers = {}; + for (size_t i = 0; i < schedule.first.size(); i++) { + U3Layers.emplace_back(); + for (size_t j = 0; j < schedule.first.at(i).size(); j++) { + U3Layers.back().push_back( + StructU3({schedule.first.at(i)[j]->getParameter()[0], + schedule.first.at(i)[j]->getParameter()[1], + schedule.first.at(i)[j]->getParameter()[2]}, + schedule.first.at(i)[j]->getTargets()[0])); + } + } +} + +NativeGateDecomposer::DiGraph> +NativeGateDecomposer::convert_circ_to_dag( + std::pair, + std::vector>& qc) { + NativeGateDecomposer::DiGraph> graph = + DiGraph>(); + std::vector> qubit_paths = + std::vector>{}; + // TODO:assert that One more sql exists than mql ?? + for (auto i = 0; i < qc.second.size(); ++i) { + for (const auto& s : qc.first.at(i)) { + size_t node = graph.add_Node(s->clone()); + for (auto t = 0; t < s->getNtargets(); t++) { + qubit_paths.at(s->getTargets().at(t)).push_back(node); + } + } + + for (const auto& t : qc.second.at(i)) { + size_t node = graph.add_Node(t->clone()); + qubit_paths.at(t->getControls().begin()->qubit).push_back(node); + qubit_paths.at(t->getTargets().at(0)).push_back(node); + } + } + for (auto s = 0; s < qc.first.end()->size(); ++s) { + size_t node = graph.add_Node(qc.first.end()->at(s)->clone()); + + for (auto t = 0; t < qc.first.end()->at(s)->getNtargets(); t++) { + qubit_paths.at(qc.first.end()->at(s)->getTargets().at(t)).push_back(node); + } + } + for (std::size_t i = 0; i < qubit_paths.size(); ++i) { + for (std::size_t op = 0; op < qubit_paths.at(i).size(); ++op) { + graph.add_Edge(i, qubit_paths.at(i).at(op)); + } + } + return graph; +} + +qc::fp NativeGateDecomposer::max_theta( + DiGraph>& circuit, + const std::vector& nodes) { + qc::fp max_cost = 0; + for (const auto node : nodes) { + if ((*circuit.get_Node_Value(node))->getParameter()[0] >= max_cost) { + max_cost = (*circuit.get_Node_Value(node))->getParameter()[0]; + } + } + return max_cost; +} + +std::array, 3> NativeGateDecomposer::sift( + DiGraph>& circuit, size_t n_qubits) { + std::vector v_p = std::vector(); + std::vector v_c = std::vector(); + std::vector v_r = std::vector(); + + std::set removed = std::set(); + + for (auto node = 0; node < circuit.get_N_Nodes(); node++) { + // TODO: Check for unique pointer issue + auto op = circuit.get_Node_Value(node); + std::set op_qubits = std::set(); + for (auto qubit : op->get()->getUsedQubits()) { + op_qubits.insert(qubit); + } + if (removed.size() < n_qubits && disjunct(removed, op_qubits)) { + if (op->get()->getNqubits() == 1) { + v_c.push_back(node); + removed.insert(op->get()->getTargets().at(0)); + } else { + v_p.push_back(node); + // Add something to make it only pick one 2-Qubit gate per Qubit per + // moment??? + } + } else { + v_r.push_back(node); + } + } + return std::array, 3>({v_p, v_c, v_r}); +} + +auto NativeGateDecomposer::build_schedule( + DiGraph>& circuit, + DiGraph, std::vector>>& + subproblem_graph) -> std::pair, + std::vector> { + + // TODO: Find Leaf Nodes of di_graph + std::vector leaf_nodes = + find_leaf_nodes(circuit, subproblem_graph); + // TODO: Find shortest path with minimal weight + std::vector minimal_path = + find_shortest_path(subproblem_graph, leaf_nodes); + std::pair, std::vector> + schedule = std::pair, + std::vector>{}; + // TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st v_p + // empty skip adding it . If not add empty SQGL + for (auto i = 0; i < minimal_path.size(); i++) { + for (auto j = 0; + j < subproblem_graph.get_Node_Value(minimal_path[i])->second.size(); + ++j) { + auto op = subproblem_graph.get_Node_Value(minimal_path[i])->second.at(j); + schedule.first.at(i + 1).emplace_back( + std::move(*circuit.get_Node_Value(op))); + } + + for (auto j = 0; + j < subproblem_graph.get_Node_Value(minimal_path[i])->first.size(); + ++j) { + auto op = circuit.get_Node_Value( + subproblem_graph.get_Node_Value(minimal_path[i])->first.at(j)); + schedule.second.at(i).emplace_back( + std::array({op->get()->getControls().begin()->qubit, + op->get()->getTargets()[0]})); + } + } + return schedule; +} +size_t NativeGateDecomposer::add_node_to_sub_prob_graph( + std::vector v_p, std::vector v_c, qc::fp cost, + DiGraph, std::vector>>& + subproblem_graph, + std::size_t prev_node) { + std::size_t new_node = subproblem_graph.add_Node(std::pair(v_p, v_c)); + subproblem_graph.add_Edge(prev_node, new_node, cost); + return new_node; +} + +double NativeGateDecomposer::schedule_remaining( + const std::array, 3>& v, + DiGraph>& circuit, + DiGraph, std::vector>>& + subproblem_graph, + size_t prev_node, size_t n_qubits, + std::map>>& + memo) { + double cost; + // TODO: Check if subproblem has been computed + std::size_t id = std::hash, 3>>{}(v); + if (memo.contains(id)) { + std::size_t sub_node = memo.at(id).first; + double edge_weight = memo.at(id).second[1]; + subproblem_graph.add_Edge(prev_node, sub_node, edge_weight); + return cost; + } + // TODO: Base Case-> V_rem is empty + if (v[2].size() == 0) { + cost = v[1].at(0); + for (auto i = 0; i < v[1].size(); ++i) { + // DO I need abs here??? + if (v[1].at(i) > cost) { + cost = v[1].at(i); + } + } + add_node_to_sub_prob_graph(v[0], v[1], cost, subproblem_graph, prev_node); + return cost; + } + // TODO: Recursive Call + auto v_new = sift(circuit, n_qubits); + auto args = get_possible_moments(circuit, v[1], v_new); + qc::fp temp_cost = 0; + double min_cost = std::numeric_limits::max(); + double min_weight = std::numeric_limits::max(); + std::size_t min_node; + for (const auto& arg : args) { + auto new_node = add_node_to_sub_prob_graph(v[0], v_new[1], arg.second, + subproblem_graph, prev_node); + temp_cost = schedule_remaining(v_new, circuit, subproblem_graph, new_node, + n_qubits, memo) + + arg.second; + if (temp_cost < min_cost) { + min_cost = temp_cost; + min_node = new_node; + min_weight = arg.second; + } + } + memo[id] = std::pair>( + min_node, {min_cost, min_weight}); + return cost; +} + +auto NativeGateDecomposer::schedule( + const std::pair>, + std::vector>& asap_schedule) const + -> std::pair>, + std::vector> { + // TODO: Preprocessing-> Convert gates to combined U3 and CZ? Issue with + // Single qubit layer/SIngle Qubit ReferenceLayer + std::pair, + std::vector> + qc_p = preprocess(asap_schedule); + // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? + DiGraph> circuit = + convert_circ_to_dag(qc_p); + // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) + // v=(v_p,v_c,v_r) + + std::array, 3> v = sift(circuit, nQubits_); + // TODO: Create Subproblem Graph + DiGraph, std::vector>> + sub_prob_graph = DiGraph< + std::pair, std::vector>>(); + // TODO: First Call of Recursive Function to create Schedule + auto base_node = sub_prob_graph.add_Node( + std::pair, std::vector>({}, {})); + std::map>> memo = + {}; + auto cost = + schedule_remaining(v, circuit, sub_prob_graph, base_node, nQubits_, memo); + + // TODO: Create Schedule from Subproblem Graph + std::pair, std::vector> + final_circuit = build_schedule(circuit, sub_prob_graph); + std::pair>, std::vector> + postprocessed = postprocess(final_circuit); + return postprocessed; } } // namespace na::zoned diff --git a/src/na/zoned/scheduler/ThetaOptScheduler.cpp b/src/na/zoned/scheduler/ThetaOptScheduler.cpp index 391ae9220..283ce580b 100644 --- a/src/na/zoned/scheduler/ThetaOptScheduler.cpp +++ b/src/na/zoned/scheduler/ThetaOptScheduler.cpp @@ -29,489 +29,6 @@ namespace na::zoned { -ThetaOptScheduler::ThetaOptScheduler(const Architecture& architecture, - const Config& config) - : architecture_(architecture), config_(config) {} -std::pair, std::vector> -ThetaOptScheduler::preprocess_qc(const qc::QuantumComputation& qc, - const Architecture& architecture, - const Config config) const { - // TODO: Find out if only CZ's in Mulit qubit gate layers - ASAPScheduler scheduler = ASAPScheduler(architecture, config); - std::pair, - std::vector> - asap_schedule = scheduler.schedule(qc); - std::vector> - singlequbitlayers_U3 = - NativeGateDecomposer::transformToU3(asap_schedule.first); - std::vector NewSingleQubitLayers = - std::vector{}; - SingleQubitGateLayer NewLayer; - for (auto layer : singlequbitlayers_U3) { - NewLayer.clear(); - for (auto gate : layer) { - NewLayer.emplace_back( - std::make_unique(qc::StandardOperation( - (qc::Qubit)gate.qubit, qc::U, - {gate.angles[0], gate.angles[1], gate.angles[2]}))); - } - NewSingleQubitLayers.push_back(std::move((NewLayer))); - } - return std::pair(std::move(NewSingleQubitLayers), asap_schedule.second); -} -std::vector ThetaOptScheduler::find_shortest_path( - const DiGraph, - std::vector>>& subproblem_graph, - const std::vector& leaf_nodes) { - std::set leafs = - std::set(leaf_nodes.begin(), leaf_nodes.end()); - std::pair, double> leaf_path = - shortest_path_to_start(subproblem_graph, 0, leafs); - std::reverse(leaf_path.first.begin(), leaf_path.first.end()); - return leaf_path.first; -} -bool disjunct(const std::set& set1, const std::set& set2) { - for (auto elem : set1) { - if (set2.contains(elem)) { - return false; - } - } - return true; -} - -bool disjunct(const std::set& set1, - const std::set& set2) { - for (auto elem : set1) { - if (set2.contains(elem)) { - return false; - } - } - return true; -} - -std::pair, double> -ThetaOptScheduler::shortest_path_to_start( - const DiGraph, - std::vector>>& subproblem_graph, - std::size_t curr_node, std::set leaf_nodes) { - std::vector, double>> possible_paths = {}; - // Check if leaf nodes are reached - for (auto node : subproblem_graph.get_adjacent(curr_node)) { - if (leaf_nodes.contains(node.first)) { - possible_paths.push_back({std::pair, double>( - {node.first, curr_node}, node.second)}); - } - } - // Recursive Case - if (possible_paths.empty()) { - for (auto node : subproblem_graph.get_adjacent(curr_node)) { - auto path = - shortest_path_to_start(subproblem_graph, node.first, leaf_nodes); - path.first.push_back(curr_node); - path.second += node.second; - possible_paths.push_back(path); - } - } - // Base Case: - // Choose shortest Paths - auto min_length = possible_paths.at(0).first.size(); - std::vector, double>> shortest_paths = {}; - for (auto path : possible_paths) { - if (path.first.size() < min_length) { - min_length = path.first.size(); - } - } - for (auto path : possible_paths) { - if (path.first.size() == min_length) { - ; - shortest_paths.push_back(path); - } - } - if (shortest_paths.size() == 1) { - return shortest_paths.at(0); - } - // Find shortest path with minimal cost - auto min_cost = shortest_paths.at(0).second; - auto best_path = shortest_paths.at(0); - for (auto path : shortest_paths) { - if (path.second > min_cost) { - min_cost = path.second; - best_path = path; - } - } - return best_path; -} -double ThetaOptScheduler::calc_cost( - std::vector>::const_reference path, - DiGraph, std::vector>>& - subproblem_graph) { - double cost = 0; - for (size_t node = 0; node < path.size() - 1; node++) { - for (const auto [child, weight] : - subproblem_graph.get_adjacent(path[node])) { - if (child == path[node + 1]) { - cost += weight; - break; - } - } - } - return cost; -} -std::vector ThetaOptScheduler::find_leaf_nodes( - DiGraph>& circuit, - const DiGraph, - std::vector>>& subproblem_graph) { - std::vector end_nodes = std::vector{}; - for (size_t i = 0; i < subproblem_graph.get_N_Nodes(); i++) { - if (subproblem_graph.get_adjacent(i).empty()) { - end_nodes.push_back(i); - } - } - return end_nodes; -} -std::vector ThetaOptScheduler::sort_by_theta_dec( - DiGraph>& circuit, - const std::vector& vector) { - std::vector sorted = {}; -} -std::vector -ThetaOptScheduler::remove_element(const std::vector& vector, - std::size_t node) { - std::vector new_vector = {}; - for (auto element : vector) { - if (element != node) { - new_vector.push_back(element); - } - } - return new_vector; -} - -// TODO: ADD last cond Bool?? -std::vector, 4>, qc::fp>> -ThetaOptScheduler::get_possible_moments( - DiGraph>& circuit, - const std::vector& v0_c, - const std::array, 3>& v_new) { - - std::vector v_p1_star = v_new[0]; - std::vector v_p1_square = {}; - std::vector v_c1_star = v_new[1]; - std::vector v_c1_square = {}; - - qc::fp v_c0_cost = max_theta(circuit, v0_c); - qc::fp v_c1_cost = max_theta(circuit, v_new[1]); - qc::fp orig_comb_cost = v_c0_cost + v_c1_cost; - qc::fp new_v_C1_cost = std::max(v_c0_cost, v_c1_cost); - - std::array, 4> v_arg = {v0_c, v_new[0], v_new[1], - v_new[2]}; - std::vector, 4>, qc::fp>> args = - {std::pair(v_arg, v_c0_cost)}; - // Sort v_0C from highest to lowest theta - std::vector v_sort(v0_c); - auto sort_by_theta = [&circuit](std::size_t a, std::size_t b) { - return circuit.get_Node_Value(a)->get()->getParameter().front() > - circuit.get_Node_Value(b)->get()->getParameter().front(); - }; - std::ranges::sort(v_sort, sort_by_theta); - // TODO: Check Condition 1 - std::vector, 2>, - std::pair, qc::fp>>> - potential_arg = {}; - auto prev_theta = - circuit.get_Node_Value(v_sort[0])->get()->getParameter().front(); - auto this_theta = prev_theta; - // TODO: This should be Qubits not Operations!!! change ARG - std::set mk_qubits = { - circuit.get_Node_Value(v_sort[0])->get()->getUsedQubits()}; - for (auto i = 0; i < v_sort.size(); i++) { - this_theta = - circuit.get_Node_Value(v_sort[i])->get()->getParameter().front(); - if (this_theta != prev_theta) { - std::vector discarded = {v_sort.begin(), - v_sort.begin() + (i - 1)}; - std::vector kept = {v_sort.begin() + i, v_sort.end()}; - potential_arg.push_back(std::pair, 2>, - std::pair, qc::fp>>( - {kept, discarded}, - std::pair, qc::fp>(mk_qubits, this_theta))); - prev_theta = this_theta; - mk_qubits.clear(); - } - mk_qubits.merge(circuit.get_Node_Value(v_sort[i])->get()->getUsedQubits()); - } - std::vector push_back_nodes = {}; - std::set p_square_qubits = {}; - - for (auto pot : potential_arg) { - // TODO: Check Condition 2 - for (auto node : v_p1_star) { - std::set qubits = - circuit.get_Node_Value(node)->get()->getUsedQubits(); - if (!disjunct(qubits, pot.second.first)) { - push_back_nodes.emplace_back(node); - p_square_qubits.merge(qubits); - } - } - for (auto node : push_back_nodes) { - v_p1_star = remove_element(v_p1_star, node); - v_p1_square.emplace_back(node); - } - - if (v_p1_star.empty()) { - break; - } - // TODO: Check Condition 3 - std::set push_qubits = pot.second.first; - push_qubits.merge(p_square_qubits); - push_back_nodes.clear(); - - for (auto node : v_c1_star) { - std::set qubits = - circuit.get_Node_Value(node)->get()->getUsedQubits(); - if (!disjunct(qubits, push_qubits)) { - push_back_nodes.emplace_back(node); - } - } - for (auto node : push_back_nodes) { - v_c1_star = remove_element(v_c1_star, node); - v_c1_square.emplace_back(node); - } - - if (v_c1_star.empty()) { - break; - } - // TODO Check Condition 4 ?? Find out what it does!! - bool check_last_cond = false; - if ((!check_last_cond) || - (check_last_cond && - pot.second.second + new_v_C1_cost < orig_comb_cost)) { - v_arg = {pot.first[0], v_p1_star,pot.first[1],v_new[2]}; - for (auto node: v_c1_star) { - v_arg[2].push_back(node); - } - for (auto node : v_c1_square) {v_arg[3].push_back(node);} - for (auto node:v_p1_square) {v_arg[3].push_back(node);} - args.push_back(std::pair, 4>, qc::fp>(v_arg,pot.second.second)); - } - } - return args; -} - -ThetaOptScheduler::DiGraph> -ThetaOptScheduler::convert_circ_to_dag( - const std::pair, - std::vector>& qc) { - ThetaOptScheduler::DiGraph> graph = - DiGraph>(); - std::vector> qubit_paths = - std::vector>{}; - // assert that One mor sql exists than mql - for (auto i = 0; i < qc.first.size(); ++i) { - for (auto s = 0; s < qc.first.at(i).size(); ++s) { - size_t node = graph.add_Node(qc.first.at(i).at(s)->clone()); - for (auto t = 0; t < qc.first.at(i).at(s)->getNtargets(); t++) { - qubit_paths.at(qc.first.at(i).at(s)->getTargets().at(t)) - .push_back(node); - } - } - for (auto m = 0; m < qc.second.at(i).size(); ++m) { - auto t = qc.second.at(i); - // Create CZ & Make_unique - size_t node = graph.add_Node(std::make_unique( - qc::StandardOperation(qc::Control(qc.second.at(i).at(m)[0]), - qc.second.at(i).at(m)[1], qc::Z, {}))); - qubit_paths.at(qc.second.at(i).at(m).at(0)) - .push_back(node); - qubit_paths.at(qc.second.at(i).at(m).at(1)).push_back(node); - } - } - for (auto s = 0; s < qc.first.end()->size(); ++s) { - size_t node = graph.add_Node(qc.first.end()->at(s)->clone()); - - for (auto t = 0; t < qc.first.end()->at(s)->getNtargets(); t++) { - qubit_paths.at(qc.first.end()->at(s)->getTargets().at(t)).push_back(node); - } - } - for (std::size_t i = 0; i < qubit_paths.size(); ++i) { - for (std::size_t op = 0; op < qubit_paths.at(i).size(); ++op) { - graph.add_Edge(i, qubit_paths.at(i).at(op)); - } - } - return graph; -} - -qc::fp ThetaOptScheduler::max_theta( - DiGraph>& circuit, - const std::vector& nodes) { - qc::fp max_cost = 0; - for (const auto node : nodes) { - if ((*circuit.get_Node_Value(node))->getParameter()[0] >= max_cost) { - max_cost = (*circuit.get_Node_Value(node))->getParameter()[0]; - } - } - return max_cost; -} - -std::array, 3> -ThetaOptScheduler::sift(DiGraph>& circuit, - size_t n_qubits) { - std::vector v_p = std::vector(); - std::vector v_c = std::vector(); - std::vector v_r = std::vector(); - - std::set removed = std::set(); - - for (auto node = 0; node < circuit.get_N_Nodes(); node++) { - // TODO: Check for unique pointer issue - auto op = circuit.get_Node_Value(node); - std::set op_qubits = std::set(); - for (auto qubit : op->get()->getUsedQubits()) { - op_qubits.insert(qubit); - } - if (removed.size() < n_qubits && disjunct(removed, op_qubits)) { - if (op->get()->getNqubits() == 1) { - v_c.push_back(node); - removed.insert(op->get()->getTargets().at(0)); - } else { - v_p.push_back(node); - // Add something to make it only pick one 2-Qubit gate per Qubit per - // moment??? - } - } else { - v_r.push_back(node); - } - } - return std::array, 3>({v_p, v_c, v_r}); -} - -std::pair, std::vector> -ThetaOptScheduler::build_schedule( - // TODO: FIgure ouot how to interface with scheduler - DiGraph>& circuit, - DiGraph, std::vector>>& - subproblem_graph) { - - // TODO: Find Leaf Nodes of di_graph - std::vector leaf_nodes = - find_leaf_nodes(circuit, subproblem_graph); - // TODO: Find shortest path with minimal weight - std::vector minimal_path = - find_shortest_path(subproblem_graph, leaf_nodes); - std::pair, std::vector> - schedule = std::pair, - std::vector>{}; - // TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st v_p - // empty skip adding it . If not add empty SQGL - for (auto i = 0; i < minimal_path.size(); i++) { - for (auto j = 0; - j < subproblem_graph.get_Node_Value(minimal_path[i])->second.size(); - ++j) { - auto op = subproblem_graph.get_Node_Value(minimal_path[i])->second.at(j); - schedule.first.at(i + 1).emplace_back( - std::move(*circuit.get_Node_Value(op))); - } - - for (auto j = 0; - j < subproblem_graph.get_Node_Value(minimal_path[i])->first.size(); - ++j) { - auto op = circuit.get_Node_Value( - subproblem_graph.get_Node_Value(minimal_path[i])->first.at(j)); - schedule.second.at(i).emplace_back( - std::array({op->get()->getControls().begin()->qubit, op->get()->getTargets()[0]})); - } - } - return schedule; -} -size_t ThetaOptScheduler::add_node_to_sub_prob_graph( - std::vector v_p, std::vector v_c, qc::fp cost, - DiGraph, std::vector>>& - subproblem_graph, - std::size_t prev_node) { - std::size_t new_node = subproblem_graph.add_Node(std::pair(v_p, v_c)); - subproblem_graph.add_Edge(prev_node, new_node, cost); - return new_node; -} - -double ThetaOptScheduler::schedule_remaining( - const std::array, 3>& v, - DiGraph>& circuit, - DiGraph, std::vector>>& - subproblem_graph, - size_t prev_node, size_t n_qubits, - std::map>>& - memo) { - double cost; - // TODO: Check if subproblem has been computed - std::size_t id = std::hash, 3>>{}(v); - if (memo.contains(id)) { - std::size_t sub_node = memo.at(id).first; - double edge_weight = memo.at(id).second[1]; - subproblem_graph.add_Edge(prev_node, sub_node, edge_weight); - return cost; - } - // TODO: Base Case-> V_rem is empty - if (v[2].size() == 0) { - cost = v[1].at(0); - for (auto i = 0; i < v[1].size(); ++i) { - // DO I need abs here??? - if (v[1].at(i) > cost) { - cost = v[1].at(i); - } - } - add_node_to_sub_prob_graph(v[0], v[1], cost, subproblem_graph, prev_node); - return cost; - } - // TODO: Recursive Call - auto v_new = sift(circuit, n_qubits); - auto args = get_possible_moments(circuit, v[1], v_new); - qc::fp temp_cost = 0; - double min_cost = std::numeric_limits::max(); - double min_weight = std::numeric_limits::max(); - std::size_t min_node; - for (const auto& arg : args) { - auto new_node = add_node_to_sub_prob_graph(v[0], v_new[1], arg.second, - subproblem_graph, prev_node); - temp_cost=schedule_remaining(v_new, circuit, subproblem_graph, - new_node, n_qubits, memo) +arg.second; - if (temp_cost>(min_node,{min_cost,min_weight}); - return cost; -} - -auto ThetaOptScheduler::schedule(const qc::QuantumComputation& qc) const - -> std::pair, - std::vector> { - // TODO: Preprocessing-> Convert gates to combined U3 and CZ? Issue with - // Single qubit layer/SIngle Qubit ReferenceLayer - std::pair, std::vector> - qc_p = preprocess_qc(qc, architecture_, config_); - // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? - // TODO: Circuit on NON_Unique pointers?? - DiGraph> circuit = - convert_circ_to_dag(qc_p); - // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) - // v=(v_p,v_c,v_r) - std::array, 3> v = sift(circuit, qc.size()); - // TODO: Create Subproblem Graph - DiGraph, std::vector>>sub_prob_graph= DiGraph< - std::pair, std::vector>>(); - // TODO: First Call of Recursive Function to create Schedule - auto base_node = sub_prob_graph.add_Node(std::pair,std::vector>({},{})); - std::map>> memo={}; - auto cost=schedule_remaining(v, circuit, sub_prob_graph, base_node, - qc.getNqubits(), memo); - - // TODO: Create Schedule from Subproblem Graph - std::pair, - std::vector> final_circuit=build_schedule(circuit,sub_prob_graph); - return final_circuit; -} } // namespace na::zoned \ No newline at end of file From c61492a919fa6961bf9c66d45dbc39a0931810bb Mon Sep 17 00:00:00 2001 From: ga96dup Date: Wed, 8 Apr 2026 00:37:00 +0200 Subject: [PATCH 076/110] Decomposer Version of the Scheduler --- .../na/zoned/decomposer/NativeGateDecomposer.hpp | 8 ++++++++ src/na/zoned/decomposer/NativeGateDecomposer.cpp | 14 ++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 68b48a160..99511e493 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -54,6 +54,14 @@ class NativeGateDecomposer : public DecomposerBase { NativeGateDecomposer(const Architecture& /* unused */, const Config& /* unused */) {} + /// Create a new NativeGateDecomposer with option to toggle theta opt schedule + /// adjustments + /// @param theta_opt: If true: Theta Opt Scheduling is performed + NativeGateDecomposer(const Architecture& /* unused */, + const Config& /* unused */, bool theta_opt) { + theta_opt_schedule = theta_opt; + } + /** * @brief Converts commonly used single qubit gates into their Quaternion * representation. diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index fcf9c0505..84dab6a2d 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -215,8 +215,7 @@ auto NativeGateDecomposer::decompose( std::vector> U3Layers = transformToU3(asap_schedule.first); std::vector NewTwoQubitGateLayers = asap_schedule.second; - if (theta_opt_schedule) { - // TODO: Put in scheduling function here + if (this->theta_opt_schedule) { auto thetaOptSchedule = schedule(std::pair(U3Layers, NewTwoQubitGateLayers)); U3Layers = thetaOptSchedule.first; @@ -303,15 +302,13 @@ auto NativeGateDecomposer::preprocess( } NewTwoQubitLayers.push_back(std::move((NewLayer))); } - return std::pair, - std::vector>( - std::move(NewSingleQubitLayers), std::move(NewTwoQubitLayers)); + return {std::move(NewSingleQubitLayers), std::move(NewTwoQubitLayers)}; } -std::vector NativeGateDecomposer::find_shortest_path( +auto NativeGateDecomposer::find_shortest_path( const DiGraph, std::vector>>& subproblem_graph, - const std::vector& leaf_nodes) { + const std::vector& leaf_nodes) -> std::vector { std::set leafs = std::set(leaf_nodes.begin(), leaf_nodes.end()); std::pair, double> leaf_path = @@ -319,7 +316,8 @@ std::vector NativeGateDecomposer::find_shortest_path( std::reverse(leaf_path.first.begin(), leaf_path.first.end()); return leaf_path.first; } -bool disjunct(const std::set& set1, const std::set& set2) { +auto disjunct(const std::set& set1, const std::set& set2) + -> bool { for (auto elem : set1) { if (set2.contains(elem)) { return false; From 261d508b13ca420cf277493f001ffab0e309a92f Mon Sep 17 00:00:00 2001 From: ga96dup Date: Fri, 10 Apr 2026 18:13:14 +0200 Subject: [PATCH 077/110] Intriduced Variants instead of unique pointers: Added first Test --- include/na/zoned/Compiler.hpp | 4 +- .../na/zoned/decomposer/DecomposerBase.hpp | 2 +- .../zoned/decomposer/NativeGateDecomposer.hpp | 172 ++++----- .../na/zoned/decomposer/NoOpDecomposer.hpp | 6 +- .../na/zoned/scheduler/ThetaOptScheduler.hpp | 15 - .../zoned/decomposer/NativeGateDecomposer.cpp | 363 ++++++++---------- src/na/zoned/decomposer/NoOpDecomposer.cpp | 12 +- src/na/zoned/scheduler/ThetaOptScheduler.cpp | 34 -- test/na/zoned/test_native_gate_decomposer.cpp | 102 ++--- test/na/zoned/test_theta_opt_scheduler.cpp | 155 ++++++++ 10 files changed, 464 insertions(+), 401 deletions(-) delete mode 100644 include/na/zoned/scheduler/ThetaOptScheduler.hpp delete mode 100644 src/na/zoned/scheduler/ThetaOptScheduler.cpp create mode 100644 test/na/zoned/test_theta_opt_scheduler.cpp diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index ce37b3414..cca5f6c06 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -21,6 +21,7 @@ #include "layout_synthesizer/placer/VertexMatchingPlacer.hpp" #include "layout_synthesizer/router/IndependentSetRouter.hpp" #include "na/NAComputation.hpp" +#include "qdmi/devices/sc/Generator.hpp" #include "reuse_analyzer/VertexMatchingReuseAnalyzer.hpp" #include "scheduler/ASAPScheduler.hpp" @@ -204,7 +205,8 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Decomposing..."); const auto decomposingStart = std::chrono::system_clock::now(); const auto& decomposedSingleQubitGateLayers = - SELF.decompose(qComp.getNqubits(), singleQubitGateLayers); + SELF.decompose(qComp.getNqubits(), schedule).first; + // TODO: How to deal with two Qubit layers const auto decomposingEnd = std::chrono::system_clock::now(); statistics_.decomposingTime = std::chrono::duration_cast(decomposingEnd - diff --git a/include/na/zoned/decomposer/DecomposerBase.hpp b/include/na/zoned/decomposer/DecomposerBase.hpp index 6cf38ecd5..978c42f35 100644 --- a/include/na/zoned/decomposer/DecomposerBase.hpp +++ b/include/na/zoned/decomposer/DecomposerBase.hpp @@ -25,7 +25,7 @@ class DecomposerBase { /** * This function defines the interface of the decomposer. * @param nQubits is the number of qubits in the quantum computation. - * @param singleQubitGateLayers are the layers of single-qubit gates that are + * @param SingleQubitGateRefLayer are the layers of single-qubit gates that are * meant to be first decomposed into the native gate set. * @return the new single-qubit gate layers */ diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 99511e493..5ce1bbd74 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -12,6 +12,7 @@ #include "DecomposerBase.hpp" #include "ir/operations/StandardOperation.hpp" +#include "na/zoned/Compiler.hpp" #include "na/zoned/Types.hpp" #include @@ -19,49 +20,46 @@ namespace na::zoned { class NativeGateDecomposer : public DecomposerBase { - /** - * A minimal struct to store the parameters of a U3 gate along with the qubit - * it acts on. - */ - struct StructU3 { - std::array angles; - qc::Qubit qubit; - }; + /** * A quaternion is represented by an array of four `qc::fp` values `{q0, q1, * q2, q3}` denoting the components of the quaternion. */ using Quaternion = std::array; size_t nQubits_ = 0; - bool theta_opt_schedule = false; constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; public: /// The configuration of the NativeGateDecomposer + /// TODO:: ADD Theta_opt option (and check last?)) struct Config { - template - friend void to_json(BasicJsonType& /* unused */, - const Config& /* unused */) {} - template - friend void from_json(const BasicJsonType& /* unused */, - Config& /* unused */) {} + bool theta_opt_schedule = false; + bool check_final_cond = false; + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, theta_opt_schedule, + check_final_cond); + }; + + /** + * A minimal struct to store the parameters of a U3 gate along with the qubit + * it acts on. + */ + struct StructU3 { + std::array angles; + qc::Qubit qubit; }; +private: + /// The configuration of the NativeGateDecomposer + Config config_; + +public: /// Create a new NativeGateDecomposer. // TODO: Add in BOOL for scheduling here? NativeGateDecomposer(const Architecture& /* unused */, const Config& /* unused */) {} - /// Create a new NativeGateDecomposer with option to toggle theta opt schedule - /// adjustments - /// @param theta_opt: If true: Theta Opt Scheduling is performed - NativeGateDecomposer(const Architecture& /* unused */, - const Config& /* unused */, bool theta_opt) { - theta_opt_schedule = theta_opt; - } - /** * @brief Converts commonly used single qubit gates into their Quaternion * representation. @@ -112,9 +110,9 @@ class NativeGateDecomposer : public DecomposerBase { * @returns a vector of vectors of StructU3 objects representing the single * qubit gate layers. */ - [[nodiscard]] auto - transformToU3(const std::vector& layers) const - -> std::vector>; + [[nodiscard]] static auto + transformToU3(const std::vector& layers, + size_t n_qubits) -> std::vector>; /** * @brief Takes a vector of `qc::fp` representing the U3-gate angles of a * single-qubit gate and the maximal value of theta for the single qubit gate @@ -135,11 +133,6 @@ class NativeGateDecomposer : public DecomposerBase { std::vector>& asap_schedule) -> std::pair, std::vector> override; - static auto NativeGateDecomposer::preprocess( - const std::pair>, - std::vector>& schedule) - -> std::pair, - std::vector>; template class DiGraph { std::size_t nodes; @@ -152,14 +145,14 @@ class NativeGateDecomposer : public DecomposerBase { adjacencies_ = std::vector>>(); node_values_ = std::vector(); } - std::size_t add_Node(T node) { - adjacencies_.push_back(std::vector>()); + auto add_Node(T node) -> std::size_t { + adjacencies_.emplace_back(); node_values_.push_back(std::move(node)); return nodes++; } - bool add_Edge(std::size_t from, std::size_t to, double weight) { + auto add_Edge(std::size_t from, std::size_t to, double weight) -> bool { if (from < nodes && to < nodes && from != to) { - adjacencies_[from].push_back( + adjacencies_[from].emplace_back( std::pair(to, weight)); return true; } else { @@ -167,9 +160,9 @@ class NativeGateDecomposer : public DecomposerBase { } } - bool add_Edge(std::size_t from, std::size_t to) { + auto add_Edge(std::size_t from, std::size_t to) -> bool { if (from < nodes && to < nodes && from != to) { - adjacencies_[from].push_back( + adjacencies_[from].emplace_back( std::pair(to, 1.0)); return true; } else { @@ -177,9 +170,9 @@ class NativeGateDecomposer : public DecomposerBase { } } - T* get_Node_Value(std::size_t node) { + auto get_Node_Value(std::size_t node) -> T { if (node < nodes) { - return &node_values_[node]; + return node_values_[node]; // return node_values_.at(node); } else { std::ostringstream oss; @@ -187,94 +180,95 @@ class NativeGateDecomposer : public DecomposerBase { throw std::invalid_argument(oss.str()); } } - std::size_t get_N_Nodes() const { return nodes; } + [[nodiscard]] auto get_N_Nodes() const -> std::size_t { return nodes; } - std::vector> - get_adjacent(std::size_t i) const { + [[nodiscard]] auto get_adjacent(std::size_t i) const + -> std::vector> { return adjacencies_.at(i); } }; - static static auto NativeGateDecomposer::convert_circ_to_dag( - std::pair, - std::vector>& qc) - -> NativeGateDecomposer::DiGraph>; + static auto + convert_circ_to_dag(const std::pair>, + std::vector>& qc, + size_t n_qubits) + -> DiGraph>>; - static std::pair, double> shortest_path_to_start( + static auto shortest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, - unsigned long long curr_node, std::set leaf_nodes); - static std::vector find_shortest_path( + unsigned long long curr_node, const std::set& leaf_nodes) + -> std::pair, double>; + static auto find_shortest_path( const DiGraph, std::vector>>& di_graph, - const std::vector& vector); - static double + const std::vector& vector) -> std::vector; + static auto calc_cost(std::vector>::const_reference path, - DiGraph, std::vector>>& - subproblem_graph); - static std::vector find_leaf_nodes( - DiGraph>& circuit, + const DiGraph, std::vector>>& + subproblem_graph) -> double; + static auto find_leaf_nodes( const DiGraph, - std::vector>>& subproblem_graph); - static std::vector - sort_by_theta_dec(DiGraph>& circuit, - const std::vector& vector); - static std::vector - remove_element(const std::vector& vector, std::size_t node); - static std::vector, 4>, qc::fp>> - get_possible_moments(DiGraph>& circuit, - const std::vector& v0_c, - const std::array, 3>& v_new); - static std::pair>, - std::vector> - postprocess(std::pair, - std::vector>); - static qc::fp - max_theta(DiGraph>& circuit, - const std::vector& nodes); - static std::array, 3> - sift(DiGraph>& circuit, size_t n_qubits); + std::vector>>& subproblem_graph) + -> std::vector; + static auto remove_element(const std::vector& vector, + std::size_t node) -> std::vector; + static auto get_possible_moments( + DiGraph>>& circuit, + const std::vector& v0_c, + const std::array, 3>& v_new, bool check_final_cond) + -> std::vector, 4>, qc::fp>>; + static auto + max_theta(DiGraph>>& circuit, + const std::vector& nodes) -> qc::fp; + static auto + sift(DiGraph>>& circuit, + size_t n_qubits) -> std::array, 3>; - static auto NativeGateDecomposer::build_schedule( - DiGraph>& circuit, - DiGraph, std::vector>>& - subproblem_graph) -> std::pair, + static auto build_schedule( + DiGraph>>& circuit, + DiGraph, std::vector>>& + subproblem_graph) -> std::pair>, std::vector>; static auto add_node_to_sub_prob_graph( - std::vector v_p, std::vector v_c, qc::fp cost, + const std::vector& v_p, const std::vector& v_c, + qc::fp cost, DiGraph, std::vector>>& subproblem_graph, size_t prev_node) -> size_t; - static double schedule_remaining( + static auto schedule_remaining( const std::array, 3>& v, - DiGraph>& circuit, + DiGraph>>& circuit, DiGraph, std::vector>>& subproblem_graph, - size_t prev_node, size_t n_qubits, - std::map>>& memo); + size_t prev_node, size_t n_qubits, bool check_final_cond, + std::map>>& memo) + -> double; /** * This function schedules the operations of a quantum computation. * @details + * @param asap_schedule * @param qc is the quantum computation * @return a pair of two vectors. The first vector contains the layers of * single-qubit operations. The second vector contains the layers of two-qubit * operations. A pair of qubits represents every two-qubit operation. */ - auto NativeGateDecomposer::schedule( + [[nodiscard]] auto schedule_theta_opt( const std::pair>, - std::vector>& asap_schedule) const + std::vector>& asap_schedule, + std::size_t n_qubits) const -> std::pair>, std::vector>; }; } // namespace na::zoned template <> struct std::hash, 3>> { - std::size_t operator()( - const std::array, 3>& array) const noexcept { + auto operator()(const std::array, 3>& array) + const noexcept -> std::size_t { std::size_t seed = 0U; - for (auto v : array) { + for (const auto& v : array) { for (auto node : v) { qc::hashCombine(seed, std::hash{}(node)); } @@ -282,5 +276,3 @@ template <> struct std::hash, 3>> { return seed; } }; - - diff --git a/include/na/zoned/decomposer/NoOpDecomposer.hpp b/include/na/zoned/decomposer/NoOpDecomposer.hpp index 2942195d3..2bce9c624 100644 --- a/include/na/zoned/decomposer/NoOpDecomposer.hpp +++ b/include/na/zoned/decomposer/NoOpDecomposer.hpp @@ -43,7 +43,9 @@ class NoOpDecomposer : public DecomposerBase { [[nodiscard]] auto decompose(size_t nQubits, - const std::vector& singleQubitGateLayers) - -> std::vector override; + const std::pair, + std::vector>& asap_schedule) + -> std::pair, + std::vector> override; }; } // namespace na::zoned diff --git a/include/na/zoned/scheduler/ThetaOptScheduler.hpp b/include/na/zoned/scheduler/ThetaOptScheduler.hpp deleted file mode 100644 index 5f0ffe535..000000000 --- a/include/na/zoned/scheduler/ThetaOptScheduler.hpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// Created by cpsch on 12.03.2026. -// -#pragma once - -#include "ASAPScheduler.hpp" -#include "ir/QuantumComputation.hpp" -#include "na/zoned/Architecture.hpp" -#include "na/zoned/Types.hpp" -#include "na/zoned/scheduler/SchedulerBase.hpp" - -#include -#include -#include - diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 84dab6a2d..6fc582e59 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -15,7 +15,7 @@ #include "ir/operations/CompoundOperation.hpp" -#include +#include #include namespace na::zoned { @@ -147,12 +147,12 @@ auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) return theta_max; } auto NativeGateDecomposer::transformToU3( - const std::vector& layers) const + const std::vector& layers, size_t n_qubits) -> std::vector> { std::vector> new_layers; for (const auto& layer : layers) { std::vector>> gates( - this->nQubits_); + n_qubits); std::vector new_layer; for (auto gate : layer) { // WHat are operations with empty targets doing?? @@ -193,7 +193,8 @@ auto NativeGateDecomposer::getDecompositionAngles( alpha = qc::PI_2; } } else { - qc::fp kappa = std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) /sin_sq_diff); + qc::fp kappa = + std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / sin_sq_diff); alpha = atan(cos(theta_max / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } @@ -213,11 +214,11 @@ auto NativeGateDecomposer::decompose( nQubits_ = nQubits; std::vector> U3Layers = - transformToU3(asap_schedule.first); + transformToU3(asap_schedule.first, nQubits); std::vector NewTwoQubitGateLayers = asap_schedule.second; - if (this->theta_opt_schedule) { + if (config_.theta_opt_schedule) { auto thetaOptSchedule = - schedule(std::pair(U3Layers, NewTwoQubitGateLayers)); + schedule_theta_opt(std::pair(U3Layers, NewTwoQubitGateLayers), nQubits); U3Layers = thetaOptSchedule.first; NewTwoQubitGateLayers = thetaOptSchedule.second; } @@ -236,11 +237,14 @@ auto NativeGateDecomposer::decompose( getDecompositionAngles(gate.angles, theta_max); // GR(theta_max/2, PI_2)==Global Y due to PI_2 - FrontLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); + FrontLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - MidLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); + MidLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - BackLayer.emplace_back(std::make_unique(qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); + BackLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer std::vector> GR_plus; @@ -257,12 +261,14 @@ auto NativeGateDecomposer::decompose( NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::make_unique(qc::CompoundOperation(std::move(GR_plus), true))); + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_plus), true))); for (auto&& gate : MidLayer) { NewLayer.push_back(std::move(gate)); } - NewLayer.emplace_back(std::make_unique(qc::CompoundOperation(std::move(GR_minus), true))); + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_minus), true))); for (auto&& gate : BackLayer) { NewLayer.push_back(std::move(gate)); @@ -272,39 +278,6 @@ auto NativeGateDecomposer::decompose( return {std::move(NewSingleQubitLayers), NewTwoQubitGateLayers}; } -auto NativeGateDecomposer::preprocess( - const std::pair>, - std::vector>& schedule) - -> std::pair, - std::vector> { - std::vector NewSingleQubitLayers = - std::vector{}; - SingleQubitGateLayer NewLayer; - for (const auto& singleQubitLayer : schedule.first) { - NewLayer.clear(); - for (auto gate : singleQubitLayer) { - NewLayer.emplace_back( - std::make_unique(qc::StandardOperation( - (qc::Qubit)gate.qubit, qc::U, - {gate.angles[0], gate.angles[1], gate.angles[2]}))); - } - NewSingleQubitLayers.push_back(std::move((NewLayer))); - } - std::vector NewTwoQubitLayers = - std::vector{}; - - for (const auto& twoQubitLayer : schedule.second) { - NewLayer.clear(); - for (auto gate : twoQubitLayer) { - NewLayer.emplace_back( - std::make_unique(qc::StandardOperation( - qc::Control((qc::Qubit)gate[0]), (qc::Qubit)gate[1], qc::Z, {}))); - } - NewTwoQubitLayers.push_back(std::move((NewLayer))); - } - return {std::move(NewSingleQubitLayers), std::move(NewTwoQubitLayers)}; -} - auto NativeGateDecomposer::find_shortest_path( const DiGraph, std::vector>>& subproblem_graph, @@ -313,7 +286,7 @@ auto NativeGateDecomposer::find_shortest_path( std::set(leaf_nodes.begin(), leaf_nodes.end()); std::pair, double> leaf_path = shortest_path_to_start(subproblem_graph, 0, leafs); - std::reverse(leaf_path.first.begin(), leaf_path.first.end()); + std::ranges::reverse(leaf_path.first); return leaf_path.first; } auto disjunct(const std::set& set1, const std::set& set2) @@ -326,8 +299,8 @@ auto disjunct(const std::set& set1, const std::set& set2) return true; } -bool disjunct(const std::set& set1, - const std::set& set2) { +auto disjunct(const std::set& set1, const std::set& set2) + -> bool { for (auto elem : set1) { if (set2.contains(elem)) { return false; @@ -336,11 +309,11 @@ bool disjunct(const std::set& set1, return true; } -std::pair, double> -NativeGateDecomposer::shortest_path_to_start( +auto NativeGateDecomposer::shortest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, - std::size_t curr_node, std::set leaf_nodes) { + std::size_t curr_node, const std::set& leaf_nodes) + -> std::pair, double> { std::vector, double>> possible_paths = {}; // Check if leaf nodes are reached for (auto node : subproblem_graph.get_adjacent(curr_node)) { @@ -363,12 +336,12 @@ NativeGateDecomposer::shortest_path_to_start( // Choose shortest Paths auto min_length = possible_paths.at(0).first.size(); std::vector, double>> shortest_paths = {}; - for (auto path : possible_paths) { - if (path.first.size() < min_length) { - min_length = path.first.size(); + for (const auto& key : possible_paths | std::views::keys) { + if (key.size() < min_length) { + min_length = key.size(); } } - for (auto path : possible_paths) { + for (const auto& path : possible_paths) { if (path.first.size() == min_length) { ; shortest_paths.push_back(path); @@ -380,7 +353,7 @@ NativeGateDecomposer::shortest_path_to_start( // Find shortest path with minimal cost auto min_cost = shortest_paths.at(0).second; auto best_path = shortest_paths.at(0); - for (auto path : shortest_paths) { + for (const auto& path : shortest_paths) { if (path.second > min_cost) { min_cost = path.second; best_path = path; @@ -388,10 +361,11 @@ NativeGateDecomposer::shortest_path_to_start( } return best_path; } -double NativeGateDecomposer::calc_cost( +auto NativeGateDecomposer::calc_cost( std::vector>::const_reference path, - DiGraph, std::vector>>& - subproblem_graph) { + const DiGraph, + std::vector>>& subproblem_graph) + -> double { double cost = 0; for (size_t node = 0; node < path.size() - 1; node++) { for (const auto [child, weight] : @@ -404,10 +378,10 @@ double NativeGateDecomposer::calc_cost( } return cost; } -std::vector NativeGateDecomposer::find_leaf_nodes( - DiGraph>& circuit, +auto NativeGateDecomposer::find_leaf_nodes( const DiGraph, - std::vector>>& subproblem_graph) { + std::vector>>& subproblem_graph) + -> std::vector { std::vector end_nodes = std::vector{}; for (size_t i = 0; i < subproblem_graph.get_N_Nodes(); i++) { if (subproblem_graph.get_adjacent(i).empty()) { @@ -416,14 +390,10 @@ std::vector NativeGateDecomposer::find_leaf_nodes( } return end_nodes; } -std::vector NativeGateDecomposer::sort_by_theta_dec( - DiGraph>& circuit, - const std::vector& vector) { - std::vector sorted = {}; -} -std::vector -NativeGateDecomposer::remove_element(const std::vector& vector, - std::size_t node) { + +auto NativeGateDecomposer::remove_element( + const std::vector& vector, std::size_t node) + -> std::vector { std::vector new_vector = {}; for (auto element : vector) { if (element != node) { @@ -434,11 +404,11 @@ NativeGateDecomposer::remove_element(const std::vector& vector, } // TODO: ADD last cond Bool?? -std::vector, 4>, qc::fp>> -NativeGateDecomposer::get_possible_moments( - DiGraph>& circuit, +auto NativeGateDecomposer::get_possible_moments( + DiGraph>>& circuit, const std::vector& v0_c, - const std::array, 3>& v_new) { + const std::array, 3>& v_new, bool check_final_cond) + -> std::vector, 4>, qc::fp>> { std::vector v_p1_star = v_new[0]; std::vector v_p1_square = {}; @@ -448,7 +418,7 @@ NativeGateDecomposer::get_possible_moments( qc::fp v_c0_cost = max_theta(circuit, v0_c); qc::fp v_c1_cost = max_theta(circuit, v_new[1]); qc::fp orig_comb_cost = v_c0_cost + v_c1_cost; - qc::fp new_v_C1_cost = std::max(v_c0_cost, v_c1_cost); + qc::fp new_v_c1_cost = std::max(v_c0_cost, v_c1_cost); std::array, 4> v_arg = {v0_c, v_new[0], v_new[1], v_new[2]}; @@ -456,9 +426,10 @@ NativeGateDecomposer::get_possible_moments( {std::pair(v_arg, v_c0_cost)}; // Sort v_0C from highest to lowest theta std::vector v_sort(v0_c); - auto sort_by_theta = [&circuit](std::size_t a, std::size_t b) { - return circuit.get_Node_Value(a)->get()->getParameter().front() > - circuit.get_Node_Value(b)->get()->getParameter().front(); + auto sort_by_theta = [&circuit](std::size_t a, std::size_t b) -> bool { + // TODO: IF CHECK??? + return std::get(circuit.get_Node_Value(a)).angles[0] > + std::get(circuit.get_Node_Value(b)).angles[0]; }; std::ranges::sort(v_sort, sort_by_theta); // TODO: Check Condition 1 @@ -466,14 +437,13 @@ NativeGateDecomposer::get_possible_moments( std::pair, qc::fp>>> potential_arg = {}; auto prev_theta = - circuit.get_Node_Value(v_sort[0])->get()->getParameter().front(); + std::get(circuit.get_Node_Value(v_sort[0])).angles[0]; auto this_theta = prev_theta; - // TODO: This should be Qubits not Operations!!! change ARG std::set mk_qubits = { - circuit.get_Node_Value(v_sort[0])->get()->getUsedQubits()}; + std::get(circuit.get_Node_Value(v_sort[0])).qubit}; for (auto i = 0; i < v_sort.size(); i++) { this_theta = - circuit.get_Node_Value(v_sort[i])->get()->getParameter().front(); + std::get(circuit.get_Node_Value(v_sort[i])).angles[0]; if (this_theta != prev_theta) { std::vector discarded = {v_sort.begin(), v_sort.begin() + (i - 1)}; @@ -485,7 +455,8 @@ NativeGateDecomposer::get_possible_moments( prev_theta = this_theta; mk_qubits.clear(); } - mk_qubits.merge(circuit.get_Node_Value(v_sort[i])->get()->getUsedQubits()); + mk_qubits.insert( + std::get(circuit.get_Node_Value(v_sort[i])).qubit); } std::vector push_back_nodes = {}; std::set p_square_qubits = {}; @@ -493,8 +464,9 @@ NativeGateDecomposer::get_possible_moments( for (auto pot : potential_arg) { // TODO: Check Condition 2 for (auto node : v_p1_star) { - std::set qubits = - circuit.get_Node_Value(node)->get()->getUsedQubits(); + std::set qubits = { + std::get>(circuit.get_Node_Value(node))[0], + std::get>(circuit.get_Node_Value(node))[1]}; if (!disjunct(qubits, pot.second.first)) { push_back_nodes.emplace_back(node); p_square_qubits.merge(qubits); @@ -514,8 +486,8 @@ NativeGateDecomposer::get_possible_moments( push_back_nodes.clear(); for (auto node : v_c1_star) { - std::set qubits = - circuit.get_Node_Value(node)->get()->getUsedQubits(); + std::set qubits = { + std::get(circuit.get_Node_Value(node)).qubit}; if (!disjunct(qubits, push_qubits)) { push_back_nodes.emplace_back(node); } @@ -529,10 +501,9 @@ NativeGateDecomposer::get_possible_moments( break; } // TODO Check Condition 4 ?? Find out what it does!! - bool check_last_cond = false; - if ((!check_last_cond) || - (check_last_cond && - pot.second.second + new_v_C1_cost < orig_comb_cost)) { + if ((!check_final_cond) || + (check_final_cond && + pot.second.second + new_v_c1_cost < orig_comb_cost)) { v_arg = {pot.first[0], v_p1_star, pot.first[1], v_new[2]}; for (auto node : v_c1_star) { v_arg[2].push_back(node); @@ -543,60 +514,40 @@ NativeGateDecomposer::get_possible_moments( for (auto node : v_p1_square) { v_arg[3].push_back(node); } - args.push_back(std::pair, 4>, qc::fp>( - v_arg, pot.second.second)); + args.emplace_back(v_arg, pot.second.second); } } return args; } -std::pair>, - std::vector> -NativeGateDecomposer::postprocess( - std::pair, std::vector> - schedule) { - std::vector> U3Layers = {}; - for (size_t i = 0; i < schedule.first.size(); i++) { - U3Layers.emplace_back(); - for (size_t j = 0; j < schedule.first.at(i).size(); j++) { - U3Layers.back().push_back( - StructU3({schedule.first.at(i)[j]->getParameter()[0], - schedule.first.at(i)[j]->getParameter()[1], - schedule.first.at(i)[j]->getParameter()[2]}, - schedule.first.at(i)[j]->getTargets()[0])); - } - } -} -NativeGateDecomposer::DiGraph> -NativeGateDecomposer::convert_circ_to_dag( - std::pair, - std::vector>& qc) { - NativeGateDecomposer::DiGraph> graph = - DiGraph>(); - std::vector> qubit_paths = - std::vector>{}; +auto NativeGateDecomposer::convert_circ_to_dag( + const std::pair>, + std::vector>& qc, + std::size_t n_qubits) + -> DiGraph>> { + // std::variant> instead of Unique_pointer + // For Readout: + DiGraph>> graph = + DiGraph>>(); + std::vector> qubit_paths(n_qubits); // TODO:assert that One more sql exists than mql ?? for (auto i = 0; i < qc.second.size(); ++i) { for (const auto& s : qc.first.at(i)) { - size_t node = graph.add_Node(s->clone()); - for (auto t = 0; t < s->getNtargets(); t++) { - qubit_paths.at(s->getTargets().at(t)).push_back(node); - } + size_t node = graph.add_Node(s); + qubit_paths.at(s.qubit).push_back(node); } for (const auto& t : qc.second.at(i)) { - size_t node = graph.add_Node(t->clone()); - qubit_paths.at(t->getControls().begin()->qubit).push_back(node); - qubit_paths.at(t->getTargets().at(0)).push_back(node); + size_t node = graph.add_Node(t); + qubit_paths.at(t[0]).push_back(node); + qubit_paths.at(t[1]).push_back(node); } } - for (auto s = 0; s < qc.first.end()->size(); ++s) { - size_t node = graph.add_Node(qc.first.end()->at(s)->clone()); - - for (auto t = 0; t < qc.first.end()->at(s)->getNtargets(); t++) { - qubit_paths.at(qc.first.end()->at(s)->getTargets().at(t)).push_back(node); - } + for (const auto& s : qc.first.back()) { + size_t node = graph.add_Node(s); + qubit_paths.at(s.qubit).push_back(node); } + for (std::size_t i = 0; i < qubit_paths.size(); ++i) { for (std::size_t op = 0; op < qubit_paths.at(i).size(); ++op) { graph.add_Edge(i, qubit_paths.at(i).at(op)); @@ -605,20 +556,22 @@ NativeGateDecomposer::convert_circ_to_dag( return graph; } -qc::fp NativeGateDecomposer::max_theta( - DiGraph>& circuit, - const std::vector& nodes) { +auto NativeGateDecomposer::max_theta( + DiGraph>>& circuit, + const std::vector& nodes) -> qc::fp { qc::fp max_cost = 0; for (const auto node : nodes) { - if ((*circuit.get_Node_Value(node))->getParameter()[0] >= max_cost) { - max_cost = (*circuit.get_Node_Value(node))->getParameter()[0]; + if (std::get(circuit.get_Node_Value(node)).angles[0] >= + max_cost) { + max_cost = std::get(circuit.get_Node_Value(node)).angles[0]; } } return max_cost; } - -std::array, 3> NativeGateDecomposer::sift( - DiGraph>& circuit, size_t n_qubits) { +// TODO: This only ever gives the first Moment????? +auto NativeGateDecomposer::sift( + DiGraph>>& circuit, + size_t n_qubits) -> std::array, 3> { std::vector v_p = std::vector(); std::vector v_c = std::vector(); std::vector v_r = std::vector(); @@ -626,16 +579,26 @@ std::array, 3> NativeGateDecomposer::sift( std::set removed = std::set(); for (auto node = 0; node < circuit.get_N_Nodes(); node++) { - // TODO: Check for unique pointer issue auto op = circuit.get_Node_Value(node); + std::set op_qubits = std::set(); - for (auto qubit : op->get()->getUsedQubits()) { + // TODO: distinguish variant + + std::set used_qubits; + if (std::holds_alternative(op)) { + used_qubits = {std::get(op).qubit}; + } else { + used_qubits = {std::get>(op)[0], + std::get>(op)[1]}; + } + + for (auto qubit : used_qubits) { op_qubits.insert(qubit); } if (removed.size() < n_qubits && disjunct(removed, op_qubits)) { - if (op->get()->getNqubits() == 1) { + if (std::holds_alternative(op)) { v_c.push_back(node); - removed.insert(op->get()->getTargets().at(0)); + removed.insert(std::get(op).qubit); } else { v_p.push_back(node); // Add something to make it only pick one 2-Qubit gate per Qubit per @@ -649,77 +612,81 @@ std::array, 3> NativeGateDecomposer::sift( } auto NativeGateDecomposer::build_schedule( - DiGraph>& circuit, + DiGraph>>& circuit, DiGraph, std::vector>>& - subproblem_graph) -> std::pair, + subproblem_graph) -> std::pair>, std::vector> { // TODO: Find Leaf Nodes of di_graph - std::vector leaf_nodes = - find_leaf_nodes(circuit, subproblem_graph); + std::vector leaf_nodes = find_leaf_nodes(subproblem_graph); // TODO: Find shortest path with minimal weight std::vector minimal_path = find_shortest_path(subproblem_graph, leaf_nodes); - std::pair, std::vector> - schedule = std::pair, + std::pair>, std::vector> + schedule = std::pair>, std::vector>{}; - // TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st v_p - // empty skip adding it . If not add empty SQGL - for (auto i = 0; i < minimal_path.size(); i++) { + // !!!!TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st + // v_p empty skip adding it . If not add empty SQGL + for (std::size_t i = 0; i < minimal_path.size(); i++) { for (auto j = 0; - j < subproblem_graph.get_Node_Value(minimal_path[i])->second.size(); + j < subproblem_graph.get_Node_Value(minimal_path[i]).second.size(); ++j) { - auto op = subproblem_graph.get_Node_Value(minimal_path[i])->second.at(j); - schedule.first.at(i + 1).emplace_back( - std::move(*circuit.get_Node_Value(op))); + auto op = circuit.get_Node_Value( + subproblem_graph.get_Node_Value(minimal_path[i]).second.at(j)); + if (std::holds_alternative(op)) { + schedule.first.at(i + 1).emplace_back(std::get(op)); + } } for (auto j = 0; - j < subproblem_graph.get_Node_Value(minimal_path[i])->first.size(); + j < subproblem_graph.get_Node_Value(minimal_path[i]).first.size(); ++j) { auto op = circuit.get_Node_Value( - subproblem_graph.get_Node_Value(minimal_path[i])->first.at(j)); - schedule.second.at(i).emplace_back( - std::array({op->get()->getControls().begin()->qubit, - op->get()->getTargets()[0]})); + subproblem_graph.get_Node_Value(minimal_path[i]).first.at(j)); + + if (std::holds_alternative(op)) { + schedule.second.at(i).emplace_back( + std::get>(op)); + } } } return schedule; } -size_t NativeGateDecomposer::add_node_to_sub_prob_graph( - std::vector v_p, std::vector v_c, qc::fp cost, +auto NativeGateDecomposer::add_node_to_sub_prob_graph( + const std::vector& v_p, const std::vector& v_c, qc::fp cost, DiGraph, std::vector>>& subproblem_graph, - std::size_t prev_node) { + std::size_t prev_node) -> size_t { std::size_t new_node = subproblem_graph.add_Node(std::pair(v_p, v_c)); subproblem_graph.add_Edge(prev_node, new_node, cost); return new_node; } -double NativeGateDecomposer::schedule_remaining( +auto NativeGateDecomposer::schedule_remaining( const std::array, 3>& v, - DiGraph>& circuit, + DiGraph>>& circuit, DiGraph, std::vector>>& subproblem_graph, - size_t prev_node, size_t n_qubits, - std::map>>& - memo) { + size_t prev_node, size_t n_qubits, bool check_final_cond, + std::map>>& memo) + -> double { double cost; // TODO: Check if subproblem has been computed std::size_t id = std::hash, 3>>{}(v); if (memo.contains(id)) { std::size_t sub_node = memo.at(id).first; double edge_weight = memo.at(id).second[1]; + cost = memo.at(id).second[0]; subproblem_graph.add_Edge(prev_node, sub_node, edge_weight); return cost; } // TODO: Base Case-> V_rem is empty - if (v[2].size() == 0) { - cost = v[1].at(0); - for (auto i = 0; i < v[1].size(); ++i) { - // DO I need abs here??? - if (v[1].at(i) > cost) { - cost = v[1].at(i); + if (v[2].empty()) { + // TODO:DEcide if I need if to check for TWO QUBIT + cost = std::get(circuit.get_Node_Value(v[1].at(0))).angles[0]; + for (std::size_t i : v[1]) { + if (std::get(circuit.get_Node_Value(i)).angles[0] > cost) { + cost = std::get(circuit.get_Node_Value(i)).angles[0]; } } add_node_to_sub_prob_graph(v[0], v[1], cost, subproblem_graph, prev_node); @@ -727,45 +694,40 @@ double NativeGateDecomposer::schedule_remaining( } // TODO: Recursive Call auto v_new = sift(circuit, n_qubits); - auto args = get_possible_moments(circuit, v[1], v_new); + auto args = get_possible_moments(circuit, v[1], v_new, check_final_cond); qc::fp temp_cost = 0; double min_cost = std::numeric_limits::max(); double min_weight = std::numeric_limits::max(); std::size_t min_node; - for (const auto& arg : args) { - auto new_node = add_node_to_sub_prob_graph(v[0], v_new[1], arg.second, + for (const auto& val : args | std::views::values) { + auto new_node = add_node_to_sub_prob_graph(v[0], v_new[1], val, subproblem_graph, prev_node); temp_cost = schedule_remaining(v_new, circuit, subproblem_graph, new_node, - n_qubits, memo) + - arg.second; + n_qubits, check_final_cond, memo) + + val; if (temp_cost < min_cost) { min_cost = temp_cost; min_node = new_node; - min_weight = arg.second; + min_weight = val; } } memo[id] = std::pair>( min_node, {min_cost, min_weight}); - return cost; + return min_cost; } -auto NativeGateDecomposer::schedule( +auto NativeGateDecomposer::schedule_theta_opt( const std::pair>, - std::vector>& asap_schedule) const - -> std::pair>, - std::vector> { - // TODO: Preprocessing-> Convert gates to combined U3 and CZ? Issue with - // Single qubit layer/SIngle Qubit ReferenceLayer - std::pair, - std::vector> - qc_p = preprocess(asap_schedule); + std::vector>& asap_schedule, + std::size_t n_qubits) const -> std::pair>, + std::vector> { + // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? - DiGraph> circuit = - convert_circ_to_dag(qc_p); + DiGraph>> circuit = + convert_circ_to_dag(asap_schedule, n_qubits); // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) // v=(v_p,v_c,v_r) - - std::array, 3> v = sift(circuit, nQubits_); + std::array, 3> v = sift(circuit, n_qubits); // TODO: Create Subproblem Graph DiGraph, std::vector>> sub_prob_graph = DiGraph< @@ -775,14 +737,11 @@ auto NativeGateDecomposer::schedule( std::pair, std::vector>({}, {})); std::map>> memo = {}; - auto cost = - schedule_remaining(v, circuit, sub_prob_graph, base_node, nQubits_, memo); - + auto cost = schedule_remaining(v, circuit, sub_prob_graph, base_node, + nQubits_, config_.check_final_cond, memo); // TODO: Create Schedule from Subproblem Graph - std::pair, std::vector> - final_circuit = build_schedule(circuit, sub_prob_graph); std::pair>, std::vector> - postprocessed = postprocess(final_circuit); - return postprocessed; + final_circuit = build_schedule(circuit, sub_prob_graph); + return final_circuit; } } // namespace na::zoned diff --git a/src/na/zoned/decomposer/NoOpDecomposer.cpp b/src/na/zoned/decomposer/NoOpDecomposer.cpp index 8dd5684f3..5596cd707 100644 --- a/src/na/zoned/decomposer/NoOpDecomposer.cpp +++ b/src/na/zoned/decomposer/NoOpDecomposer.cpp @@ -19,11 +19,13 @@ namespace na::zoned { auto NoOpDecomposer::decompose( size_t /* unused */, - const std::vector& singleQubitGateLayers) - -> std::vector { + const std::pair, + std::vector>& asap_schedule) + -> std::pair, + std::vector> { std::vector result; - result.reserve(singleQubitGateLayers.size()); - for (const auto& layer : singleQubitGateLayers) { + result.reserve(asap_schedule.first.size()); + for (const auto& layer : asap_schedule.first) { SingleQubitGateLayer newLayer; newLayer.reserve(layer.size()); for (const auto& opRef : layer) { @@ -31,6 +33,6 @@ auto NoOpDecomposer::decompose( } result.emplace_back(std::move(newLayer)); } - return result; + return {std::move(result), asap_schedule.second}; } } // namespace na::zoned diff --git a/src/na/zoned/scheduler/ThetaOptScheduler.cpp b/src/na/zoned/scheduler/ThetaOptScheduler.cpp deleted file mode 100644 index 283ce580b..000000000 --- a/src/na/zoned/scheduler/ThetaOptScheduler.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Created by cpsch on 12.03.2026. -// -#include "na/zoned/scheduler/ThetaOptScheduler.hpp" - -#include "dd/Approximation.hpp" -#include "ir/Definitions.hpp" -#include "ir/QuantumComputation.hpp" -#include "ir/operations/OpType.hpp" -#include "ir/operations/StandardOperation.hpp" -#include "na/zoned/Architecture.hpp" -#include "na/zoned/decomposer/NativeGateDecomposer.hpp" -#include "na/zoned/scheduler/ASAPScheduler.hpp" -#include "spdlog/fmt/bundled/args.h" -#include "spdlog/fmt/bundled/printf.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace na::zoned { - - - -} // namespace na::zoned \ No newline at end of file diff --git a/test/na/zoned/test_native_gate_decomposer.cpp b/test/na/zoned/test_native_gate_decomposer.cpp index 85c19d1ee..9a0ecf4e5 100644 --- a/test/na/zoned/test_native_gate_decomposer.cpp +++ b/test/na/zoned/test_native_gate_decomposer.cpp @@ -401,25 +401,25 @@ TEST_F(DecomposerTest, SingleRXGate) { size_t n = 1; qc::QuantumComputation qc(n); qc.rx(qc::PI, 0); - const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); - EXPECT_EQ(decomp.size(), 1); - EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), + const auto& schedule = scheduler.schedule(qc); + auto decomp = decomposer.decompose(qc.getNqubits(), schedule); + EXPECT_EQ(decomp.first.size(), 1); + EXPECT_EQ(decomp.first[0].size(), 5); + EXPECT_EQ(decomp.first[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][0]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(), + EXPECT_TRUE(decomp.first[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp.first[0][1]->isGlobal(n)); + EXPECT_EQ(decomp.first[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][2]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(), + EXPECT_TRUE(decomp.first[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp.first[0][3]->isGlobal(n)); + EXPECT_EQ(decomp.first[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][4]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } @@ -431,25 +431,25 @@ TEST_F(DecomposerTest, SingleU3Gate) { qc::QuantumComputation qc(n); qc.u(0.0, qc::PI, qc::PI_2, 0); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); - EXPECT_EQ(decomp.size(), 1); - EXPECT_EQ(decomp[0].size(), 5); + auto decomp = decomposer.decompose(qc.getNqubits(), sched); + EXPECT_EQ(decomp.first.size(), 1); + EXPECT_EQ(decomp.first[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), + EXPECT_EQ(decomp.first[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][0]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(0, epsilon))); - EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(), + EXPECT_TRUE(decomp.first[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp.first[0][1]->isGlobal(n)); + EXPECT_EQ(decomp.first[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][2]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][4]->getParameter(), + EXPECT_TRUE(decomp.first[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp.first[0][3]->isGlobal(n)); + EXPECT_EQ(decomp.first[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][4]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); } @@ -462,26 +462,26 @@ TEST_F(DecomposerTest, TwoPauliGatesOneQubit) { qc.x(0); qc.z(0); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched); - EXPECT_EQ(decomp.size(), 1); - EXPECT_EQ(decomp[0].size(), 5); - EXPECT_EQ(decomp[0][0]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][0]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][0]->getParameter(), + EXPECT_EQ(decomp.first.size(), 1); + EXPECT_EQ(decomp.first[0].size(), 5); + EXPECT_EQ(decomp.first[0][0]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][0]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][0]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(qc::PI_2, epsilon))); - EXPECT_TRUE(decomp[0][1]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][1]->isGlobal(n)); - EXPECT_EQ(decomp[0][2]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][2]->getTargets(), ::testing::ElementsAre(0)); - EXPECT_THAT(decomp[0][2]->getParameter(), + EXPECT_TRUE(decomp.first[0][1]->isCompoundOperation()); + EXPECT_TRUE(decomp.first[0][1]->isGlobal(n)); + EXPECT_EQ(decomp.first[0][2]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][2]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_THAT(decomp.first[0][2]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(qc::PI, epsilon))); - EXPECT_TRUE(decomp[0][3]->isCompoundOperation()); - EXPECT_TRUE(decomp[0][3]->isGlobal(n)); - EXPECT_EQ(decomp[0][4]->getType(), qc::RZ); - EXPECT_THAT(decomp[0][4]->getTargets(), ::testing::ElementsAre(0)); + EXPECT_TRUE(decomp.first[0][3]->isCompoundOperation()); + EXPECT_TRUE(decomp.first[0][3]->isGlobal(n)); + EXPECT_EQ(decomp.first[0][4]->getType(), qc::RZ); + EXPECT_THAT(decomp.first[0][4]->getTargets(), ::testing::ElementsAre(0)); EXPECT_THAT( - decomp[0][4]->getParameter(), + decomp.first[0][4]->getParameter(), ::testing::ElementsAre(::testing::DoubleNear(3 * qc::PI_2, epsilon))); } @@ -498,7 +498,7 @@ TEST_F(DecomposerTest, TwoPauliGatesTwoQubits) { qc.x(0); qc.z(1); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched).first; EXPECT_EQ(decomp.size(), 1); EXPECT_EQ(decomp[0].size(), 8); @@ -554,7 +554,7 @@ TEST_F(DecomposerTest, TwoQubitsTwoLayers) { qc.z(0); qc.x(1); const auto& sched = scheduler.schedule(qc); - auto decomp = decomposer.decompose(qc.getNqubits(), sched.first); + auto decomp = decomposer.decompose(qc.getNqubits(), sched).first; EXPECT_EQ(decomp.size(), 2); EXPECT_EQ(decomp[0].size(), 5); EXPECT_EQ(decomp[1].size(), 8); diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp new file mode 100644 index 000000000..712196394 --- /dev/null +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -0,0 +1,155 @@ +#include "ir/QuantumComputation.hpp" +#include "na/zoned/decomposer/NativeGateDecomposer.hpp" +#include "na/zoned/scheduler/ASAPScheduler.hpp" + +#include +#include +#include +#include +#include + +// +// Created by cpsch on 08.04.2026. +// +namespace na::zoned { +constexpr std::string_view architectureJson = R"({ + "name": "asap_scheduler_architecture", + "storage_zones": [{ + "zone_id": 0, + "slms": [{"id": 0, "site_separation": [3, 3], "r": 20, "c": 20, "location": [0, 0]}], + "offset": [0, 0], + "dimension": [60, 60] + }], + "entanglement_zones": [{ + "zone_id": 0, + "slms": [ + {"id": 1, "site_separation": [12, 10], "r": 4, "c": 4, "location": [5, 70]}, + {"id": 2, "site_separation": [12, 10], "r": 4, "c": 4, "location": [7, 70]} + ], + "offset": [5, 70], + "dimension": [50, 40] + }], + "aods":[{"id": 0, "site_separation": 2, "r": 20, "c": 20}], + "rydberg_range": [[[5, 70], [55, 110]]] +})"; + +class ThetaOptTest : public ::testing::Test { +protected: + Architecture architecture; + ASAPScheduler::Config schedulerConfig{.maxFillingFactor = .8}; + ASAPScheduler scheduler; + NativeGateDecomposer::Config decomposerConfig{.theta_opt_schedule = true, + .check_final_cond = false}; + NativeGateDecomposer decomposer; + ThetaOptTest() + : architecture(Architecture::fromJSONString(architectureJson)), + scheduler(architecture, schedulerConfig), + decomposer(architecture, decomposerConfig) {} +}; + +constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; + +TEST_F(ThetaOptTest, GraphTest) { + // Circuit + // ┌───────┐ ┌───────┐ + // q_0: ─┤ X ├───■───┤ Z ├─ + // └───────┘ │ └───────┘ + // │ ┌───────┐ + // q_1: ─────────────■───┤ X ├─ + // └───────┘ + + size_t n = 2; + qc::QuantumComputation qc(n); + qc.x(0); + qc.cz(0, 1); + qc.z(0); + qc.x(1); + + auto schedule = scheduler.schedule(qc); + auto one_qubit_gates = decomposer.transformToU3(schedule.first, n); + auto graph = NativeGateDecomposer::convert_circ_to_dag( + {one_qubit_gates, schedule.second}, n); + // Currently accepting gates other than U3?? + EXPECT_EQ( + std::get(graph.get_Node_Value(0)).qubit, + 0); + EXPECT_THAT( + std::get(graph.get_Node_Value(0)).angles, + ::testing::ElementsAre( + ::testing::DoubleNear( + schedule.first.front().front().get().getParameter().at(0), + epsilon), + ::testing::DoubleNear( + schedule.first.front().front().get().getParameter().at(1), + epsilon), + ::testing::DoubleNear( + schedule.first.front().front().get().getParameter().at(2), + epsilon))); + EXPECT_THAT(graph.get_adjacent(0), + ::testing::ElementsAre(std::pair(1, 1.0))); + + auto tqg = std::get>(graph.get_Node_Value(1)); + EXPECT_THAT(tqg, ::testing::ElementsAre(static_cast(0), + static_cast(1))); + EXPECT_THAT(graph.get_adjacent(1), + ::testing::ElementsAre(std::pair(2, 1.0), + std::pair(3, 1.0))); + + EXPECT_EQ( + std::get(graph.get_Node_Value(2)).qubit, + 0); + EXPECT_THAT( + std::get(graph.get_Node_Value(2)).angles, + ::testing::ElementsAre( + ::testing::DoubleNear( + schedule.first.at(1).front().get().getParameter().at(0), epsilon), + ::testing::DoubleNear( + schedule.first.at(1).front().get().getParameter().at(1), epsilon), + ::testing::DoubleNear( + schedule.first.at(1).front().get().getParameter().at(2), + epsilon))); + EXPECT_THAT(graph.get_adjacent(2), ::testing::IsEmpty()); + + EXPECT_EQ( + std::get(graph.get_Node_Value(3)).qubit, + 1); + EXPECT_THAT( + std::get(graph.get_Node_Value(3)).angles, + ::testing::ElementsAre( + ::testing::DoubleNear( + schedule.first.at(1).at(1).get().getParameter().at(0), epsilon), + ::testing::DoubleNear( + schedule.first.at(1).at(1).get().getParameter().at(1), epsilon), + ::testing::DoubleNear( + schedule.first.at(1).at(1).get().getParameter().at(2), epsilon))); + EXPECT_THAT(graph.get_adjacent(3), ::testing::IsEmpty()); +} + +TEST_F(ThetaOptTest, SiftTest) { + // Circuit + // Build Circuit graph + // Perform Sift (multiple times???) +} + +TEST_F(ThetaOptTest, RecursionMemoTest) { + // Circuit +} + +TEST_F(ThetaOptTest, RecursionBaseTest) { + // Circuit +} + +TEST_F(ThetaOptTest, RecursionCallTest) { + // Circuit +} + +TEST_F(ThetaOptTest, BuildScheduleTest) { + // Circuit +} + +TEST_F(ThetaOptTest, CompleteTestSmall) { + // Circuit +} + +TEST_F(ThetaOptTest, CompleteTestBig) {} +} // namespace na::zoned \ No newline at end of file From 67549b8249650dd4f2a898f7fc9ce7e31fd44418 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 13 Apr 2026 21:51:36 +0200 Subject: [PATCH 078/110] Compiler fix and new test --- include/na/zoned/Compiler.hpp | 19 +- .../na/zoned/decomposer/DecomposerBase.hpp | 3 +- .../zoned/decomposer/NativeGateDecomposer.hpp | 261 +++++++++++++++--- .../zoned/decomposer/NativeGateDecomposer.cpp | 153 +++++----- test/na/zoned/test_theta_opt_scheduler.cpp | 99 +++++-- 5 files changed, 375 insertions(+), 160 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index cca5f6c06..13ec86672 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -10,18 +10,17 @@ #pragma once -#include "Architecture.hpp" -#include "code_generator/CodeGenerator.hpp" -#include "decomposer/NativeGateDecomposer.hpp" -#include "decomposer/NoOpDecomposer.hpp" #include "ir/QuantumComputation.hpp" #include "ir/operations/Operation.hpp" -#include "layout_synthesizer/PlaceAndRouteSynthesizer.hpp" -#include "layout_synthesizer/placer/HeuristicPlacer.hpp" -#include "layout_synthesizer/placer/VertexMatchingPlacer.hpp" -#include "layout_synthesizer/router/IndependentSetRouter.hpp" #include "na/NAComputation.hpp" -#include "qdmi/devices/sc/Generator.hpp" +#include "na/zoned/Architecture.hpp" +#include "na/zoned/code_generator/CodeGenerator.hpp" +#include "na/zoned/decomposer/NativeGateDecomposer.hpp" +#include "na/zoned/decomposer/NoOpDecomposer.hpp" +#include "na/zoned/layout_synthesizer/PlaceAndRouteSynthesizer.hpp" +#include "na/zoned/layout_synthesizer/placer/HeuristicPlacer.hpp" +#include "na/zoned/layout_synthesizer/placer/VertexMatchingPlacer.hpp" +#include "na/zoned/layout_synthesizer/router/IndependentSetRouter.hpp" #include "reuse_analyzer/VertexMatchingReuseAnalyzer.hpp" #include "scheduler/ASAPScheduler.hpp" @@ -327,4 +326,4 @@ class RoutingAwareNativeGateCompiler final explicit RoutingAwareNativeGateCompiler(const Architecture& architecture) : Compiler(architecture) {} }; -} // namespace na::zoned +} // namespace na::zoned \ No newline at end of file diff --git a/include/na/zoned/decomposer/DecomposerBase.hpp b/include/na/zoned/decomposer/DecomposerBase.hpp index 978c42f35..0a9146df9 100644 --- a/include/na/zoned/decomposer/DecomposerBase.hpp +++ b/include/na/zoned/decomposer/DecomposerBase.hpp @@ -25,7 +25,8 @@ class DecomposerBase { /** * This function defines the interface of the decomposer. * @param nQubits is the number of qubits in the quantum computation. - * @param SingleQubitGateRefLayer are the layers of single-qubit gates that are + * @param asap_schedule std::pair, + std::vector> are the layers of single-qubit gates that are * meant to be first decomposed into the native gate set. * @return the new single-qubit gate layers */ diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 5ce1bbd74..75384c630 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -10,12 +10,10 @@ #pragma once -#include "DecomposerBase.hpp" -#include "ir/operations/StandardOperation.hpp" -#include "na/zoned/Compiler.hpp" #include "na/zoned/Types.hpp" - +#include "na/zoned/decomposer/DecomposerBase.hpp" #include +#include namespace na::zoned { @@ -28,12 +26,12 @@ class NativeGateDecomposer : public DecomposerBase { using Quaternion = std::array; size_t nQubits_ = 0; + ///A value to use as a margin of error for float equality constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; public: /// The configuration of the NativeGateDecomposer - /// TODO:: ADD Theta_opt option (and check last?)) struct Config { bool theta_opt_schedule = false; bool check_final_cond = false; @@ -56,7 +54,6 @@ class NativeGateDecomposer : public DecomposerBase { public: /// Create a new NativeGateDecomposer. - // TODO: Add in BOOL for scheduling here? NativeGateDecomposer(const Architecture& /* unused */, const Config& /* unused */) {} @@ -114,11 +111,12 @@ class NativeGateDecomposer : public DecomposerBase { transformToU3(const std::vector& layers, size_t n_qubits) -> std::vector>; /** - * @brief Takes a vector of `qc::fp` representing the U3-gate angles of a + * @brief Calculates the decomposition angles of a U3 gate + * @details Takes a vector of `qc::fp` representing the U3-gate angles of a * single-qubit gate and the maximal value of theta for the single qubit gate * layer and calculates the transversal decomposition angles as in Nottingham * et. al. 2024. - * @param angles is a `std::array` of `qc::fp` representing (theta, phi, + * @param angles `std::array` of `qc::fp` representing (theta, phi, * lambda). * @param theta_max the maximal theta value of the single-qubit gate layer. * @returns an array of `qc::fp` values giving the angles (chi, gamma_minus, @@ -127,31 +125,67 @@ class NativeGateDecomposer : public DecomposerBase { auto static getDecompositionAngles(const std::array& angles, qc::fp theta_max) -> std::array; + /** + * @brief Decomposes a given schedule of operations into the native gate set + * and, if theta_opt_scheduling is selected re-schedules them to minimize + * the total global rotation angle theta across the circuit + * @details + * @param nQubits the number of Qubits in the scheduled circuit + * @param schedule a pair of vectors containing SingleQubitGateRefLayers + * and TwoQubitGateLayers + * @returns a pair of vectors containing SingleQubitLayers and TwoQubitLayers + * representing the decomposed (and rescheduled) circuit + */ [[nodiscard]] auto decompose(size_t nQubits, const std::pair, - std::vector>& asap_schedule) + std::vector>& schedule) -> std::pair, std::vector> override; + /** + * @class A class implementing a simple DiGraph for use in the scheduling + * component of the native gate decomposer. + * @tparam T , the type of object associated with each node + */ template class DiGraph { - std::size_t nodes; + ///number of nodes in the graph + std::size_t node_number; + /// a vector containing the adjacency lists of each node std::vector>> adjacencies_; + /// a vector containing the values associated with each node std::vector node_values_; public: + /** + * @brief Creates an empty graph to hold objects of type T + */ DiGraph() { - nodes = 0; + node_number = 0; adjacencies_ = std::vector>>(); node_values_ = std::vector(); } + + /** + * @brief Adds a node with given value to the graph + * @param node the type T value to be added to the graph + * @returns the node index of the created node + */ auto add_Node(T node) -> std::size_t { adjacencies_.emplace_back(); node_values_.push_back(std::move(node)); - return nodes++; + return node_number++; } + + /** + * @brief Adds an edge between two nodes to the graph with given weight + * @param from index of the node from which the edge originates + * @param to index of the node the edge is going to + * @param weight the weight of the edge + * @returns a bool indicating if adding the edge was successful + */ auto add_Edge(std::size_t from, std::size_t to, double weight) -> bool { - if (from < nodes && to < nodes && from != to) { + if (from < node_number && to < node_number && from != to) { adjacencies_[from].emplace_back( std::pair(to, weight)); return true; @@ -160,8 +194,14 @@ class NativeGateDecomposer : public DecomposerBase { } } + /** + * @brief Adds an edge between two nodes to the graph (weight 1.0) + * @param from index of the node from which the edge originates + * @param to index of the node the edge is going to + * @returns a bool indicating if adding the edge was successful + */ auto add_Edge(std::size_t from, std::size_t to) -> bool { - if (from < nodes && to < nodes && from != to) { + if (from < node_number && to < node_number && from != to) { adjacencies_[from].emplace_back( std::pair(to, 1.0)); return true; @@ -170,67 +210,183 @@ class NativeGateDecomposer : public DecomposerBase { } } + /** + * @brief Gets the value of a given node + * @param node the node index of a node in the graph + * @returns an object of type T contained in the given node + */ auto get_Node_Value(std::size_t node) -> T { - if (node < nodes) { + if (node < node_number) { return node_values_[node]; - // return node_values_.at(node); } else { std::ostringstream oss; oss << "ERROR: Node Number out of range: " << node << "\n"; throw std::invalid_argument(oss.str()); } } - [[nodiscard]] auto get_N_Nodes() const -> std::size_t { return nodes; } - [[nodiscard]] auto get_adjacent(std::size_t i) const + /** + * @brief A function which returns the size/number of nodes of the graph + * @returns the number of nodes in the graph + */ + [[nodiscard]] auto size() const -> std::size_t { return node_number; } + + /** + * @brief Returns the successor nodes of a given node + * @param node the index of a node in the graph + * @returns a vector containing the node indices of all nodes the passed node + * has outgoing edges to. + */ + [[nodiscard]] auto get_adjacent(std::size_t node) const -> std::vector> { - return adjacencies_.at(i); + return adjacencies_.at(node); } }; - + /** + * @brief converts a schedule of operations into a directional acyclic graph, + * where each operation is a node and each edge represents a dependency + * @details A circuit made up of U3-Gates (represented by layers of StructU3's) + * and CZ-Gates (represented by layers of two element arrays denoting + * control and target qubits) is transformed into a graph modeling the + * circuit and operational dependencies. + * Each node contains a std::variant containing either a StructU3 or + * an array representing a CZ-Gate. + * Edges between nodes mean that the destination node is dependent + * on the source node (e.g. that the operation of the source node must + * be executed before the one of the destination node). + * @param schedule a pair of vectors containing layers of StructU3's representing + * U3-Gates and TwoQubitGateLayers + * @param nQubits the number of Qubits in the scheduled circuit + * @returns a DiGraph consisting of nodes containing either a StructU3 + * representation of U3-Gates of an array representation of CZ Gates. + */ static auto convert_circ_to_dag(const std::pair>, - std::vector>& qc, - size_t n_qubits) + std::vector>& schedule,size_t nQubits) -> DiGraph>>; - + /** + * @brief Recursively finds the shortest path to the start node of the + * subproblem graph from a set of leaf nodes. + * @details + * @param subproblem_graph the subproblem graph to find the path in + * @param current_node the node of the current function call + * @param leaf_nodes a set of nodes with no outgoing edges (aka. leaf nodes) + * @returns a pair made up of a vector of the indices making up the shortest + * path and the path's total cost (the sum of the maximal theta angles + * of each moment) + */ static auto shortest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, - unsigned long long curr_node, const std::set& leaf_nodes) + std::size_t current_node, const std::set& leaf_nodes) -> std::pair, double>; + + /** + * @brief Finds the shortest (fewest edges) and cheapest (lowest cost) path + * from the start node to a leaf node in a subproblem_graph + * @details + * @param subproblem_graph the subproblem graph + * @param path a vector containing the indices of all leaf nodes of the graph + * @returns a vector containing the node inidces of the shortest path through + * the graph + */ static auto find_shortest_path( const DiGraph, - std::vector>>& di_graph, - const std::vector& vector) -> std::vector; - static auto - calc_cost(std::vector>::const_reference path, - const DiGraph, std::vector>>& - subproblem_graph) -> double; + std::vector>>& subproblem_graph, + const std::vector& path) -> std::vector; + + + /** + * @brief Finds the leaf nodes (Nodes with no outgoing edges) of a subproblem graph + * @details + * @param subproblem_graph the subproblem graph + * @returns a vectr of node indices for the leaf nodes + */ static auto find_leaf_nodes( const DiGraph, std::vector>>& subproblem_graph) -> std::vector; + + /** + * @brief Removes all copies of an element from a vector + * @param vector the vector of std::size_t to remove the element from + * @param elem the element to be removed from the vector + * @returns the vector without the element + */ static auto remove_element(const std::vector& vector, - std::size_t node) -> std::vector; + std::size_t elem) -> std::vector; + + /** + * @brief Returns all plausible subsets of the current moments to be scheduled + * @details + * @param circuit the graph representation of the quantum circuit + * @param v0_c a vector containing the node indices of the current set of + * single Qubit operations + * @param v_new =[v_p1,v_c1, v_rem] an array containing vectors holding the node + * indices of the next set of two Qubit operations (v_p), single Qubit + * operations (v_c) and all remaining operations (v_rem) + * @param check_final_cond a bool deciding whether to check for a strict cost + * reduction + * @returns a vector holding pairs of the possible next moments to be scheduled + * [v_c0, v_p1,vc1,v_rem] and the moments associated + */ static auto get_possible_moments( DiGraph>>& circuit, const std::vector& v0_c, const std::array, 3>& v_new, bool check_final_cond) -> std::vector, 4>, qc::fp>>; + + /** + * @brief Finds the maximal value of the angle theta among the given set of nodes + * @param circuit the passed circuit graph containing operations + * @param nodes a vector of node indices for which to find the maximal theta + * @returns the maximal theta value + */ static auto max_theta(DiGraph>>& circuit, - const std::vector& nodes) -> qc::fp; + const std::vector& nodes) -> qc::fp; + + /** + * @brief returns the next two- and single-Qubit moments which can be scheduled + * @details + * @param circuit the quantum circuit in graph form + * @param v a vector containing all unscheduled nodes + * @param nQubits the number of qubits in the circuit + * @returns an array containing vectors of the next two Qubit moments which can + * be scheduled and the remaining nodes: [v_p,v_c,v_rem] + * v_p: next two qubit gate moment + * v_c: next single qubit gate moment + * V-rem: remaining unscheduled nodes + */ static auto sift(DiGraph>>& circuit, - size_t n_qubits) -> std::array, 3>; + std::vector v, size_t nQubits) -> std::array, 3>; + /** + * @brief Builds a schedule from a circuit and subproblem graph + * @details + * @param circuit the circuit to be scheduled in graph form + * @param subproblem_graph the subproblem graph of the circuit + * @returns a pair of vectrs containing layers of StructU3's and two element + * arrays of Qubits representing CZ gates making up a schedule + */ static auto build_schedule( DiGraph>>& circuit, DiGraph, std::vector>>& subproblem_graph) -> std::pair>, std::vector>; + /** + * @brief Adds a node corresponding to the subproblem [v_p,v_c] to the + * subproblem graph + * @details + * @param v_p a vector of node indices making up a two-Qubit gate moment + * @param v_c a vector of node indices making up a single-Qubit gate moment + * @param cost the maximal theta value of operations in v_c (aka. the cost) + * @param subproblem_graph a subproblem graph of a circuit + * @param prev_node the node corresponding to the previous subproblem + * @returns the node index of the node added to the subproblem graph + */ static auto add_node_to_sub_prob_graph( const std::vector& v_p, const std::vector& v_c, qc::fp cost, @@ -238,32 +394,51 @@ class NativeGateDecomposer : public DecomposerBase { subproblem_graph, size_t prev_node) -> size_t; + + /** + * @brief Recursively creates a subproblem graph for a given circuit + * @details + * @param v the current subproblem [v_p,v_c,v_rem] for which to create a schedule + * @param circuit the graph representation of the circuit to be scheduled + * @param subproblem_graph the subproblem graph of the circuit to be scheduled + * @param prev_node the previous node in the subproblem graph + * @param nQubits the number of qubits in the circuit + * @param check_final_cond a bool deciding whether the function should only + * allow possible next moments with strictly decreasing cost + * @param memo a map using subproblem hashes as keys and saving as values a pair + * of a node index in the subproblem graph and an array containing the + * cost of the single-Qubit layer in the current subproblem and the total + * cost of the schedule originating from that subproblem + * @returns + */ static auto schedule_remaining( const std::array, 3>& v, DiGraph>>& circuit, DiGraph, std::vector>>& subproblem_graph, - size_t prev_node, size_t n_qubits, bool check_final_cond, + size_t prev_node, size_t nQubits, bool check_final_cond, std::map>>& memo) -> double; + /** - * This function schedules the operations of a quantum computation. + * @brief Creates a schedule minimizing the sum total of the global rotation + * angles theta across a quantum circuit * @details - * @param asap_schedule - * @param qc is the quantum computation - * @return a pair of two vectors. The first vector contains the layers of - * single-qubit operations. The second vector contains the layers of two-qubit - * operations. A pair of qubits represents every two-qubit operation. + * @param schedule the preliminary schedule provided + * @param nQubits the number of qubits in the circuit + * @returns a schedule minimizing the total rotation angle theta */ [[nodiscard]] auto schedule_theta_opt( const std::pair>, - std::vector>& asap_schedule, - std::size_t n_qubits) const + std::vector>& schedule, + std::size_t nQubits) const -> std::pair>, std::vector>; }; } // namespace na::zoned - +/** + * A hash function for subproblems [v_p,v_c,v_rem] + */ template <> struct std::hash, 3>> { auto operator()(const std::array, 3>& array) const noexcept -> std::size_t { diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 6fc582e59..b3f0ecbde 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -8,12 +8,11 @@ * Licensed under the MIT License */ -// -// Created by cpsch on 11.12.2025. -// #include "na/zoned/decomposer/NativeGateDecomposer.hpp" #include "ir/operations/CompoundOperation.hpp" +#include "ir/operations/Operation.hpp" +#include "ir/operations/StandardOperation.hpp" #include #include @@ -206,16 +205,15 @@ auto NativeGateDecomposer::getDecompositionAngles( } auto NativeGateDecomposer::decompose( - size_t nQubits, - const std::pair, - std::vector>& asap_schedule) + size_t nQubits, const std::pair, + std::vector>& schedule) -> std::pair, std::vector> { nQubits_ = nQubits; std::vector> U3Layers = - transformToU3(asap_schedule.first, nQubits); - std::vector NewTwoQubitGateLayers = asap_schedule.second; + transformToU3(schedule.first, nQubits); + std::vector NewTwoQubitGateLayers = schedule.second; if (config_.theta_opt_schedule) { auto thetaOptSchedule = schedule_theta_opt(std::pair(U3Layers, NewTwoQubitGateLayers), nQubits); @@ -282,10 +280,10 @@ auto NativeGateDecomposer::find_shortest_path( const DiGraph, std::vector>>& subproblem_graph, const std::vector& leaf_nodes) -> std::vector { - std::set leafs = + std::set leaves = std::set(leaf_nodes.begin(), leaf_nodes.end()); std::pair, double> leaf_path = - shortest_path_to_start(subproblem_graph, 0, leafs); + shortest_path_to_start(subproblem_graph, 0, leaves); std::ranges::reverse(leaf_path.first); return leaf_path.first; } @@ -312,22 +310,22 @@ auto disjunct(const std::set& set1, const std::set& set2) auto NativeGateDecomposer::shortest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, - std::size_t curr_node, const std::set& leaf_nodes) + std::size_t current_node, const std::set& leaf_nodes) -> std::pair, double> { std::vector, double>> possible_paths = {}; // Check if leaf nodes are reached - for (auto node : subproblem_graph.get_adjacent(curr_node)) { + for (auto node : subproblem_graph.get_adjacent(current_node)) { if (leaf_nodes.contains(node.first)) { possible_paths.push_back({std::pair, double>( - {node.first, curr_node}, node.second)}); + {node.first, current_node}, node.second)}); } } // Recursive Case if (possible_paths.empty()) { - for (auto node : subproblem_graph.get_adjacent(curr_node)) { + for (auto node : subproblem_graph.get_adjacent(current_node)) { auto path = shortest_path_to_start(subproblem_graph, node.first, leaf_nodes); - path.first.push_back(curr_node); + path.first.push_back(current_node); path.second += node.second; possible_paths.push_back(path); } @@ -361,29 +359,13 @@ auto NativeGateDecomposer::shortest_path_to_start( } return best_path; } -auto NativeGateDecomposer::calc_cost( - std::vector>::const_reference path, - const DiGraph, - std::vector>>& subproblem_graph) - -> double { - double cost = 0; - for (size_t node = 0; node < path.size() - 1; node++) { - for (const auto [child, weight] : - subproblem_graph.get_adjacent(path[node])) { - if (child == path[node + 1]) { - cost += weight; - break; - } - } - } - return cost; -} + auto NativeGateDecomposer::find_leaf_nodes( const DiGraph, std::vector>>& subproblem_graph) -> std::vector { std::vector end_nodes = std::vector{}; - for (size_t i = 0; i < subproblem_graph.get_N_Nodes(); i++) { + for (size_t i = 0; i < subproblem_graph.size(); i++) { if (subproblem_graph.get_adjacent(i).empty()) { end_nodes.push_back(i); } @@ -392,11 +374,11 @@ auto NativeGateDecomposer::find_leaf_nodes( } auto NativeGateDecomposer::remove_element( - const std::vector& vector, std::size_t node) + const std::vector& vector, std::size_t elem) -> std::vector { std::vector new_vector = {}; for (auto element : vector) { - if (element != node) { + if (element != elem) { new_vector.push_back(element); } } @@ -522,35 +504,35 @@ auto NativeGateDecomposer::get_possible_moments( auto NativeGateDecomposer::convert_circ_to_dag( const std::pair>, - std::vector>& qc, - std::size_t n_qubits) + std::vector>& schedule, + std::size_t nQubits) -> DiGraph>> { // std::variant> instead of Unique_pointer // For Readout: DiGraph>> graph = DiGraph>>(); - std::vector> qubit_paths(n_qubits); + std::vector> qubit_paths(nQubits); // TODO:assert that One more sql exists than mql ?? - for (auto i = 0; i < qc.second.size(); ++i) { - for (const auto& s : qc.first.at(i)) { + for (auto i = 0; i < schedule.second.size(); ++i) { + for (const auto& s : schedule.first.at(i)) { size_t node = graph.add_Node(s); qubit_paths.at(s.qubit).push_back(node); } - for (const auto& t : qc.second.at(i)) { - size_t node = graph.add_Node(t); - qubit_paths.at(t[0]).push_back(node); - qubit_paths.at(t[1]).push_back(node); + for (const auto& gate : schedule.second.at(i)) { + size_t node = graph.add_Node(gate); + qubit_paths.at(gate[0]).push_back(node); + qubit_paths.at(gate[1]).push_back(node); } } - for (const auto& s : qc.first.back()) { + for (const auto& s : schedule.first.back()) { size_t node = graph.add_Node(s); qubit_paths.at(s.qubit).push_back(node); } for (std::size_t i = 0; i < qubit_paths.size(); ++i) { - for (std::size_t op = 0; op < qubit_paths.at(i).size(); ++op) { - graph.add_Edge(i, qubit_paths.at(i).at(op)); + for (std::size_t op = 0; op < qubit_paths.at(i).size() - 1; ++op) { + graph.add_Edge(qubit_paths.at(i).at(op), qubit_paths.at(i).at(op + 1)); } } return graph; @@ -558,7 +540,7 @@ auto NativeGateDecomposer::convert_circ_to_dag( auto NativeGateDecomposer::max_theta( DiGraph>>& circuit, - const std::vector& nodes) -> qc::fp { + const std::vector& nodes) -> qc::fp { qc::fp max_cost = 0; for (const auto node : nodes) { if (std::get(circuit.get_Node_Value(node)).angles[0] >= @@ -571,41 +553,48 @@ auto NativeGateDecomposer::max_theta( // TODO: This only ever gives the first Moment????? auto NativeGateDecomposer::sift( DiGraph>>& circuit, - size_t n_qubits) -> std::array, 3> { + std::vector v, size_t nQubits) + -> std::array, 3> { std::vector v_p = std::vector(); std::vector v_c = std::vector(); std::vector v_r = std::vector(); + std::set v_rem = std::set(v.begin(), v.end()); std::set removed = std::set(); - for (auto node = 0; node < circuit.get_N_Nodes(); node++) { - auto op = circuit.get_Node_Value(node); + for (auto node = 0; node < circuit.size(); node++) { + if (v_rem.contains(node)) { // TODO: SORT V_rem??? Needs to be a topological + // sort!!!-> order in Circuit is topological + auto op = circuit.get_Node_Value(node); - std::set op_qubits = std::set(); - // TODO: distinguish variant - - std::set used_qubits; - if (std::holds_alternative(op)) { - used_qubits = {std::get(op).qubit}; - } else { - used_qubits = {std::get>(op)[0], - std::get>(op)[1]}; - } + std::set op_qubits = std::set(); - for (auto qubit : used_qubits) { - op_qubits.insert(qubit); - } - if (removed.size() < n_qubits && disjunct(removed, op_qubits)) { + std::set used_qubits; if (std::holds_alternative(op)) { - v_c.push_back(node); - removed.insert(std::get(op).qubit); + used_qubits = {std::get(op).qubit}; } else { - v_p.push_back(node); - // Add something to make it only pick one 2-Qubit gate per Qubit per - // moment??? + used_qubits = {std::get>(op)[0], + std::get>(op)[1]}; + } + + for (auto qubit : used_qubits) { + op_qubits.insert(qubit); + } + if (removed.size() < nQubits && disjunct(removed, op_qubits)) { + if (std::holds_alternative(op)) { + v_c.push_back(node); + removed.insert(std::get(op).qubit); + } else { + v_p.push_back(node); + // Add something to make it only pick one 2-Qubit gate per Qubit per + // moment??? + } + } else { + v_r.push_back(node); + for (auto qubit : op_qubits) { + removed.insert(qubit); + } } - } else { - v_r.push_back(node); } } return std::array, 3>({v_p, v_c, v_r}); @@ -667,7 +656,7 @@ auto NativeGateDecomposer::schedule_remaining( DiGraph>>& circuit, DiGraph, std::vector>>& subproblem_graph, - size_t prev_node, size_t n_qubits, bool check_final_cond, + size_t prev_node, size_t nQubits, bool check_final_cond, std::map>>& memo) -> double { double cost; @@ -693,7 +682,7 @@ auto NativeGateDecomposer::schedule_remaining( return cost; } // TODO: Recursive Call - auto v_new = sift(circuit, n_qubits); + auto v_new = sift(circuit, v[2], nQubits); auto args = get_possible_moments(circuit, v[1], v_new, check_final_cond); qc::fp temp_cost = 0; double min_cost = std::numeric_limits::max(); @@ -703,7 +692,7 @@ auto NativeGateDecomposer::schedule_remaining( auto new_node = add_node_to_sub_prob_graph(v[0], v_new[1], val, subproblem_graph, prev_node); temp_cost = schedule_remaining(v_new, circuit, subproblem_graph, new_node, - n_qubits, check_final_cond, memo) + + nQubits, check_final_cond, memo) + val; if (temp_cost < min_cost) { min_cost = temp_cost; @@ -718,16 +707,20 @@ auto NativeGateDecomposer::schedule_remaining( auto NativeGateDecomposer::schedule_theta_opt( const std::pair>, - std::vector>& asap_schedule, - std::size_t n_qubits) const -> std::pair>, - std::vector> { + std::vector>& schedule, + std::size_t nQubits) const -> std::pair>, + std::vector> { // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? DiGraph>> circuit = - convert_circ_to_dag(asap_schedule, n_qubits); + convert_circ_to_dag(schedule, nQubits); // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) + std::vector v_start = {}; + for (auto i = 0; i < circuit.size(); ++i) { + v_start.push_back(i); + } // v=(v_p,v_c,v_r) - std::array, 3> v = sift(circuit, n_qubits); + std::array, 3> v = sift(circuit, v_start, nQubits); // TODO: Create Subproblem Graph DiGraph, std::vector>> sub_prob_graph = DiGraph< diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index 712196394..47d7db938 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -66,25 +66,21 @@ TEST_F(ThetaOptTest, GraphTest) { qc.x(1); auto schedule = scheduler.schedule(qc); - auto one_qubit_gates = decomposer.transformToU3(schedule.first, n); + auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); auto graph = NativeGateDecomposer::convert_circ_to_dag( {one_qubit_gates, schedule.second}, n); - // Currently accepting gates other than U3?? EXPECT_EQ( std::get(graph.get_Node_Value(0)).qubit, 0); EXPECT_THAT( std::get(graph.get_Node_Value(0)).angles, ::testing::ElementsAre( - ::testing::DoubleNear( - schedule.first.front().front().get().getParameter().at(0), - epsilon), - ::testing::DoubleNear( - schedule.first.front().front().get().getParameter().at(1), - epsilon), - ::testing::DoubleNear( - schedule.first.front().front().get().getParameter().at(2), - epsilon))); + ::testing::DoubleNear(one_qubit_gates.front().front().angles.at(0), + epsilon), + ::testing::DoubleNear(one_qubit_gates.front().front().angles.at(1), + epsilon), + ::testing::DoubleNear(one_qubit_gates.front().front().angles.at(2), + epsilon))); EXPECT_THAT(graph.get_adjacent(0), ::testing::ElementsAre(std::pair(1, 1.0))); @@ -101,13 +97,11 @@ TEST_F(ThetaOptTest, GraphTest) { EXPECT_THAT( std::get(graph.get_Node_Value(2)).angles, ::testing::ElementsAre( - ::testing::DoubleNear( - schedule.first.at(1).front().get().getParameter().at(0), epsilon), - ::testing::DoubleNear( - schedule.first.at(1).front().get().getParameter().at(1), epsilon), - ::testing::DoubleNear( - schedule.first.at(1).front().get().getParameter().at(2), - epsilon))); + ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(0), + epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(1), epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(2), + epsilon))); EXPECT_THAT(graph.get_adjacent(2), ::testing::IsEmpty()); EXPECT_EQ( @@ -116,19 +110,65 @@ TEST_F(ThetaOptTest, GraphTest) { EXPECT_THAT( std::get(graph.get_Node_Value(3)).angles, ::testing::ElementsAre( - ::testing::DoubleNear( - schedule.first.at(1).at(1).get().getParameter().at(0), epsilon), - ::testing::DoubleNear( - schedule.first.at(1).at(1).get().getParameter().at(1), epsilon), - ::testing::DoubleNear( - schedule.first.at(1).at(1).get().getParameter().at(2), epsilon))); + ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(0), epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(1), + epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(2), epsilon))); EXPECT_THAT(graph.get_adjacent(3), ::testing::IsEmpty()); } TEST_F(ThetaOptTest, SiftTest) { // Circuit - // Build Circuit graph + // ┌───────┐ ┌───────┐ ┌───────┐ + // q_0: ──┤ X ├───■───────┤ Z ├───■───┤ Y ├─ + // └───────┘ │ └───────┘ │ └───────┘ + // │ ┌───────┐ │ + // q_1: ──────────────■───■───┤ X ├───│───────────── + // │ └───────┘ │ + // ┌───────┐ │ ┌───────┐ │ + // q_1: ──┤ X ├───────■───┤ Y ├───■───────────── + // └───────┘ └───────┘ + + size_t n = 3; + qc::QuantumComputation qc(n); + qc.x(0); + qc.x(2); + qc.cz(0, 1); + qc.cz(1, 2); + qc.z(0); + qc.x(1); + qc.y(2); + qc.cz(0, 2); + qc.y(0); + + auto schedule = scheduler.schedule(qc); + auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); + auto graph = NativeGateDecomposer::convert_circ_to_dag( + {one_qubit_gates, schedule.second}, n); + // Perform Sift (multiple times???) + std::vector v_start = {0}; + for (auto i = 0; i < graph.size(); ++i) { + v_start.push_back(i); + } + std::array, 3> v = + NativeGateDecomposer::sift(graph, v_start, n); + + EXPECT_THAT(v[0], ::testing::IsEmpty()); + EXPECT_THAT(v[1], ::testing::ElementsAre(0, 1)); + EXPECT_THAT(v[2], ::testing::ElementsAre(2, 3, 4, 5, 6, 7, 8)); + + v = NativeGateDecomposer::sift(graph, v[2], n); + + EXPECT_THAT(v[0], ::testing::ElementsAre(2, 4)); + EXPECT_THAT(v[1], ::testing::ElementsAre(3, 5, 6)); + EXPECT_THAT(v[2], ::testing::ElementsAre(7, 8)); + + v = NativeGateDecomposer::sift(graph, v[2], n); + + EXPECT_THAT(v[0], ::testing::ElementsAre(7)); + EXPECT_THAT(v[1], ::testing::ElementsAre(8)); + EXPECT_THAT(v[2], ::testing::IsEmpty()); } TEST_F(ThetaOptTest, RecursionMemoTest) { @@ -143,6 +183,11 @@ TEST_F(ThetaOptTest, RecursionCallTest) { // Circuit } +TEST_F(ThetaOptTest, ShortesPathTest) { + // Subproblem graph! + +} + TEST_F(ThetaOptTest, BuildScheduleTest) { // Circuit } @@ -151,5 +196,7 @@ TEST_F(ThetaOptTest, CompleteTestSmall) { // Circuit } -TEST_F(ThetaOptTest, CompleteTestBig) {} +TEST_F(ThetaOptTest, CompleteTestBig) { + +} } // namespace na::zoned \ No newline at end of file From 782412592ecc3fc4d5f8a567b39f0907440ed6cb Mon Sep 17 00:00:00 2001 From: ga96dup Date: Wed, 15 Apr 2026 01:45:45 +0200 Subject: [PATCH 079/110] TESTS and FIxes --- .../zoned/decomposer/NativeGateDecomposer.hpp | 339 +++++++++--------- .../zoned/decomposer/NativeGateDecomposer.cpp | 92 +++-- test/na/zoned/test_theta_opt_scheduler.cpp | 328 ++++++++++++++++- 3 files changed, 547 insertions(+), 212 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 75384c630..97ac74bc9 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -12,8 +12,9 @@ #include "na/zoned/Types.hpp" #include "na/zoned/decomposer/DecomposerBase.hpp" -#include + #include +#include namespace na::zoned { @@ -26,7 +27,7 @@ class NativeGateDecomposer : public DecomposerBase { using Quaternion = std::array; size_t nQubits_ = 0; - ///A value to use as a margin of error for float equality + /// A value to use as a margin of error for float equality constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; @@ -126,16 +127,16 @@ class NativeGateDecomposer : public DecomposerBase { qc::fp theta_max) -> std::array; /** - * @brief Decomposes a given schedule of operations into the native gate set - * and, if theta_opt_scheduling is selected re-schedules them to minimize - * the total global rotation angle theta across the circuit - * @details - * @param nQubits the number of Qubits in the scheduled circuit - * @param schedule a pair of vectors containing SingleQubitGateRefLayers - * and TwoQubitGateLayers - * @returns a pair of vectors containing SingleQubitLayers and TwoQubitLayers - * representing the decomposed (and rescheduled) circuit - */ + * @brief Decomposes a given schedule of operations into the native gate set + * and, if theta_opt_scheduling is selected re-schedules them to + * minimize the total global rotation angle theta across the circuit + * @details + * @param nQubits the number of Qubits in the scheduled circuit + * @param schedule a pair of vectors containing SingleQubitGateRefLayers + * and TwoQubitGateLayers + * @returns a pair of vectors containing SingleQubitLayers and TwoQubitLayers + * representing the decomposed (and rescheduled) circuit + */ [[nodiscard]] auto decompose(size_t nQubits, const std::pair, @@ -144,12 +145,12 @@ class NativeGateDecomposer : public DecomposerBase { std::vector> override; /** - * @class A class implementing a simple DiGraph for use in the scheduling - * component of the native gate decomposer. - * @tparam T , the type of object associated with each node - */ + * @class A class implementing a simple DiGraph for use in the scheduling + * component of the native gate decomposer. + * @tparam T , the type of object associated with each node + */ template class DiGraph { - ///number of nodes in the graph + /// number of nodes in the graph std::size_t node_number; /// a vector containing the adjacency lists of each node std::vector>> adjacencies_; @@ -157,53 +158,53 @@ class NativeGateDecomposer : public DecomposerBase { std::vector node_values_; public: - /** - * @brief Creates an empty graph to hold objects of type T - */ + /** + * @brief Creates an empty graph to hold objects of type T + */ DiGraph() { node_number = 0; adjacencies_ = std::vector>>(); node_values_ = std::vector(); } - /** - * @brief Adds a node with given value to the graph - * @param node the type T value to be added to the graph - * @returns the node index of the created node - */ + /** + * @brief Adds a node with given value to the graph + * @param node the type T value to be added to the graph + * @returns the node index of the created node + */ auto add_Node(T node) -> std::size_t { adjacencies_.emplace_back(); node_values_.push_back(std::move(node)); return node_number++; } - /** - * @brief Adds an edge between two nodes to the graph with given weight - * @param from index of the node from which the edge originates - * @param to index of the node the edge is going to - * @param weight the weight of the edge - * @returns a bool indicating if adding the edge was successful - */ + /** + * @brief Adds an edge between two nodes to the graph with given weight + * @param from index of the node from which the edge originates + * @param to index of the node the edge is going to + * @param weight the weight of the edge + * @returns a bool indicating if adding the edge was successful + */ auto add_Edge(std::size_t from, std::size_t to, double weight) -> bool { if (from < node_number && to < node_number && from != to) { adjacencies_[from].emplace_back( - std::pair(to, weight)); + std::pair(to, weight)); return true; } else { return false; } } - /** - * @brief Adds an edge between two nodes to the graph (weight 1.0) - * @param from index of the node from which the edge originates - * @param to index of the node the edge is going to - * @returns a bool indicating if adding the edge was successful - */ + /** + * @brief Adds an edge between two nodes to the graph (weight 1.0) + * @param from index of the node from which the edge originates + * @param to index of the node the edge is going to + * @returns a bool indicating if adding the edge was successful + */ auto add_Edge(std::size_t from, std::size_t to) -> bool { if (from < node_number && to < node_number && from != to) { adjacencies_[from].emplace_back( - std::pair(to, 1.0)); + std::pair(to, 1.0)); return true; } else { return false; @@ -211,10 +212,10 @@ class NativeGateDecomposer : public DecomposerBase { } /** - * @brief Gets the value of a given node - * @param node the node index of a node in the graph - * @returns an object of type T contained in the given node - */ + * @brief Gets the value of a given node + * @param node the node index of a node in the graph + * @returns an object of type T contained in the given node + */ auto get_Node_Value(std::size_t node) -> T { if (node < node_number) { return node_values_[node]; @@ -225,56 +226,56 @@ class NativeGateDecomposer : public DecomposerBase { } } - /** - * @brief A function which returns the size/number of nodes of the graph - * @returns the number of nodes in the graph - */ + /** + * @brief A function which returns the size/number of nodes of the graph + * @returns the number of nodes in the graph + */ [[nodiscard]] auto size() const -> std::size_t { return node_number; } - /** - * @brief Returns the successor nodes of a given node - * @param node the index of a node in the graph - * @returns a vector containing the node indices of all nodes the passed node - * has outgoing edges to. - */ + /** + * @brief Returns the successor nodes of a given node + * @param node the index of a node in the graph + * @returns a vector containing the node indices of all nodes the passed + * node has outgoing edges to. + */ [[nodiscard]] auto get_adjacent(std::size_t node) const -> std::vector> { return adjacencies_.at(node); } }; /** - * @brief converts a schedule of operations into a directional acyclic graph, - * where each operation is a node and each edge represents a dependency - * @details A circuit made up of U3-Gates (represented by layers of StructU3's) - * and CZ-Gates (represented by layers of two element arrays denoting - * control and target qubits) is transformed into a graph modeling the - * circuit and operational dependencies. - * Each node contains a std::variant containing either a StructU3 or - * an array representing a CZ-Gate. - * Edges between nodes mean that the destination node is dependent - * on the source node (e.g. that the operation of the source node must - * be executed before the one of the destination node). - * @param schedule a pair of vectors containing layers of StructU3's representing - * U3-Gates and TwoQubitGateLayers - * @param nQubits the number of Qubits in the scheduled circuit - * @returns a DiGraph consisting of nodes containing either a StructU3 - * representation of U3-Gates of an array representation of CZ Gates. - */ + * @brief converts a schedule of operations into a directional acyclic graph, + * where each operation is a node and each edge represents a dependency + * @details A circuit made up of U3-Gates (represented by layers of + * StructU3's) and CZ-Gates (represented by layers of two element arrays + * denoting control and target qubits) is transformed into a graph modeling + * the circuit and operational dependencies. Each node contains a std::variant + * containing either a StructU3 or an array representing a CZ-Gate. Edges + * between nodes mean that the destination node is dependent on the source + * node (e.g. that the operation of the source node must be executed before + * the one of the destination node). + * @param schedule a pair of vectors containing layers of StructU3's + * representing U3-Gates and TwoQubitGateLayers + * @param nQubits the number of Qubits in the scheduled circuit + * @returns a DiGraph consisting of nodes containing either a StructU3 + * representation of U3-Gates of an array representation of CZ Gates. + */ static auto convert_circ_to_dag(const std::pair>, - std::vector>& schedule,size_t nQubits) + std::vector>& schedule, + size_t nQubits) -> DiGraph>>; /** - * @brief Recursively finds the shortest path to the start node of the - * subproblem graph from a set of leaf nodes. - * @details - * @param subproblem_graph the subproblem graph to find the path in - * @param current_node the node of the current function call - * @param leaf_nodes a set of nodes with no outgoing edges (aka. leaf nodes) - * @returns a pair made up of a vector of the indices making up the shortest - * path and the path's total cost (the sum of the maximal theta angles - * of each moment) - */ + * @brief Recursively finds the shortest path to the start node of the + * subproblem graph from a set of leaf nodes. + * @details + * @param subproblem_graph the subproblem graph to find the path in + * @param current_node the node of the current function call + * @param leaf_nodes a set of nodes with no outgoing edges (aka. leaf nodes) + * @returns a pair made up of a vector of the indices making up the shortest + * path and the path's total cost (the sum of the maximal theta angles + * of each moment) + */ static auto shortest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, @@ -282,54 +283,54 @@ class NativeGateDecomposer : public DecomposerBase { -> std::pair, double>; /** - * @brief Finds the shortest (fewest edges) and cheapest (lowest cost) path - * from the start node to a leaf node in a subproblem_graph - * @details - * @param subproblem_graph the subproblem graph - * @param path a vector containing the indices of all leaf nodes of the graph - * @returns a vector containing the node inidces of the shortest path through - * the graph - */ + * @brief Finds the shortest (fewest edges) and cheapest (lowest cost) path + * from the start node to a leaf node in a subproblem_graph + * @details + * @param subproblem_graph the subproblem graph + * @param path a vector containing the indices of all leaf nodes of the graph + * @returns a vector containing the node inidces of the shortest path through + * the graph + */ static auto find_shortest_path( const DiGraph, std::vector>>& subproblem_graph, const std::vector& path) -> std::vector; - /** - * @brief Finds the leaf nodes (Nodes with no outgoing edges) of a subproblem graph - * @details - * @param subproblem_graph the subproblem graph - * @returns a vectr of node indices for the leaf nodes - */ + * @brief Finds the leaf nodes (Nodes with no outgoing edges) of a subproblem + * graph + * @details + * @param subproblem_graph the subproblem graph + * @returns a vectr of node indices for the leaf nodes + */ static auto find_leaf_nodes( const DiGraph, std::vector>>& subproblem_graph) -> std::vector; /** - * @brief Removes all copies of an element from a vector - * @param vector the vector of std::size_t to remove the element from - * @param elem the element to be removed from the vector - * @returns the vector without the element - */ + * @brief Removes all copies of an element from a vector + * @param vector the vector of std::size_t to remove the element from + * @param elem the element to be removed from the vector + * @returns the vector without the element + */ static auto remove_element(const std::vector& vector, std::size_t elem) -> std::vector; /** - * @brief Returns all plausible subsets of the current moments to be scheduled - * @details - * @param circuit the graph representation of the quantum circuit - * @param v0_c a vector containing the node indices of the current set of - * single Qubit operations - * @param v_new =[v_p1,v_c1, v_rem] an array containing vectors holding the node - * indices of the next set of two Qubit operations (v_p), single Qubit - * operations (v_c) and all remaining operations (v_rem) - * @param check_final_cond a bool deciding whether to check for a strict cost - * reduction - * @returns a vector holding pairs of the possible next moments to be scheduled - * [v_c0, v_p1,vc1,v_rem] and the moments associated - */ + * @brief Returns all plausible subsets of the current moments to be scheduled + * @details + * @param circuit the graph representation of the quantum circuit + * @param v0_c a vector containing the node indices of the current set of + * single Qubit operations + * @param v_new =[v_p1,v_c1, v_rem] an array containing vectors holding the + * node indices of the next set of two Qubit operations (v_p), single Qubit + * operations (v_c) and all remaining operations (v_rem) + * @param check_final_cond a bool deciding whether to check for a strict cost + * reduction + * @returns a vector holding pairs of the possible next moments to be + * scheduled [v_c0, v_p1,vc_1,v_rem] and the moments associated + */ static auto get_possible_moments( DiGraph>>& circuit, const std::vector& v0_c, @@ -337,39 +338,41 @@ class NativeGateDecomposer : public DecomposerBase { -> std::vector, 4>, qc::fp>>; /** - * @brief Finds the maximal value of the angle theta among the given set of nodes - * @param circuit the passed circuit graph containing operations - * @param nodes a vector of node indices for which to find the maximal theta - * @returns the maximal theta value - */ + * @brief Finds the maximal value of the angle theta among the given set of + * nodes + * @param circuit the passed circuit graph containing operations + * @param nodes a vector of node indices for which to find the maximal theta + * @returns the maximal theta value + */ static auto max_theta(DiGraph>>& circuit, const std::vector& nodes) -> qc::fp; /** - * @brief returns the next two- and single-Qubit moments which can be scheduled - * @details - * @param circuit the quantum circuit in graph form - * @param v a vector containing all unscheduled nodes - * @param nQubits the number of qubits in the circuit - * @returns an array containing vectors of the next two Qubit moments which can - * be scheduled and the remaining nodes: [v_p,v_c,v_rem] - * v_p: next two qubit gate moment - * v_c: next single qubit gate moment - * V-rem: remaining unscheduled nodes - */ + * @brief returns the next two- and single-Qubit moments which can be + * scheduled + * @details + * @param circuit the quantum circuit in graph form + * @param v a vector containing all unscheduled nodes + * @param nQubits the number of qubits in the circuit + * @returns an array containing vectors of the next two Qubit moments which + * can be scheduled and the remaining nodes: [v_p,v_c,v_rem] v_p: next two + * qubit gate moment v_c: next single qubit gate moment V-rem: remaining + * unscheduled nodes + */ static auto sift(DiGraph>>& circuit, - std::vector v, size_t nQubits) -> std::array, 3>; + std::vector v, size_t nQubits) + -> std::array, 3>; /** - * @brief Builds a schedule from a circuit and subproblem graph - * @details - * @param circuit the circuit to be scheduled in graph form - * @param subproblem_graph the subproblem graph of the circuit - * @returns a pair of vectrs containing layers of StructU3's and two element - * arrays of Qubits representing CZ gates making up a schedule - */ + * @brief Builds a schedule from a circuit and subproblem graph + * @details + * @param circuit the circuit to be scheduled in graph form + * @param subproblem_graph the subproblem graph of the circuit + * @returns a pair of vectrs containing layers of StructU3's and two element + * arrays of Qubits representing CZ gates making up a schedule + */ static auto build_schedule( DiGraph>>& circuit, DiGraph, std::vector>>& @@ -377,16 +380,16 @@ class NativeGateDecomposer : public DecomposerBase { std::vector>; /** - * @brief Adds a node corresponding to the subproblem [v_p,v_c] to the - * subproblem graph - * @details - * @param v_p a vector of node indices making up a two-Qubit gate moment - * @param v_c a vector of node indices making up a single-Qubit gate moment - * @param cost the maximal theta value of operations in v_c (aka. the cost) - * @param subproblem_graph a subproblem graph of a circuit - * @param prev_node the node corresponding to the previous subproblem - * @returns the node index of the node added to the subproblem graph - */ + * @brief Adds a node corresponding to the subproblem [v_p,v_c] to the + * subproblem graph + * @details + * @param v_p a vector of node indices making up a two-Qubit gate moment + * @param v_c a vector of node indices making up a single-Qubit gate moment + * @param cost the maximal theta value of operations in v_c (aka. the cost) + * @param subproblem_graph a subproblem graph of a circuit + * @param prev_node the node corresponding to the previous subproblem + * @returns the node index of the node added to the subproblem graph + */ static auto add_node_to_sub_prob_graph( const std::vector& v_p, const std::vector& v_c, qc::fp cost, @@ -394,23 +397,23 @@ class NativeGateDecomposer : public DecomposerBase { subproblem_graph, size_t prev_node) -> size_t; - /** - * @brief Recursively creates a subproblem graph for a given circuit - * @details - * @param v the current subproblem [v_p,v_c,v_rem] for which to create a schedule - * @param circuit the graph representation of the circuit to be scheduled - * @param subproblem_graph the subproblem graph of the circuit to be scheduled - * @param prev_node the previous node in the subproblem graph - * @param nQubits the number of qubits in the circuit - * @param check_final_cond a bool deciding whether the function should only - * allow possible next moments with strictly decreasing cost - * @param memo a map using subproblem hashes as keys and saving as values a pair - * of a node index in the subproblem graph and an array containing the - * cost of the single-Qubit layer in the current subproblem and the total - * cost of the schedule originating from that subproblem - * @returns - */ + * @brief Recursively creates a subproblem graph for a given circuit + * @details + * @param v the current subproblem [v_p,v_c,v_rem] for which to create a + * schedule + * @param circuit the graph representation of the circuit to be scheduled + * @param subproblem_graph the subproblem graph of the circuit to be scheduled + * @param prev_node the previous node in the subproblem graph + * @param nQubits the number of qubits in the circuit + * @param check_final_cond a bool deciding whether the function should only + * allow possible next moments with strictly decreasing cost + * @param memo a map using subproblem hashes as keys and saving as values a + * pair of a node index in the subproblem graph and an array containing the + * cost of the single-Qubit layer in the current subproblem and the + * total cost of the schedule originating from that subproblem + * @returns + */ static auto schedule_remaining( const std::array, 3>& v, DiGraph>>& circuit, @@ -428,10 +431,10 @@ class NativeGateDecomposer : public DecomposerBase { * @param nQubits the number of qubits in the circuit * @returns a schedule minimizing the total rotation angle theta */ - [[nodiscard]] auto schedule_theta_opt( - const std::pair>, - std::vector>& schedule, - std::size_t nQubits) const + [[nodiscard]] auto + schedule_theta_opt(const std::pair>, + std::vector>& schedule, + std::size_t nQubits) const -> std::pair>, std::vector>; }; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index b3f0ecbde..1892f204e 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -285,7 +285,8 @@ auto NativeGateDecomposer::find_shortest_path( std::pair, double> leaf_path = shortest_path_to_start(subproblem_graph, 0, leaves); std::ranges::reverse(leaf_path.first); - return leaf_path.first; + + return {leaf_path.first.begin() + 1, leaf_path.first.end()}; } auto disjunct(const std::set& set1, const std::set& set2) -> bool { @@ -314,19 +315,19 @@ auto NativeGateDecomposer::shortest_path_to_start( -> std::pair, double> { std::vector, double>> possible_paths = {}; // Check if leaf nodes are reached - for (auto node : subproblem_graph.get_adjacent(current_node)) { - if (leaf_nodes.contains(node.first)) { + for (auto edge : subproblem_graph.get_adjacent(current_node)) { + if (leaf_nodes.contains(edge.first)) { possible_paths.push_back({std::pair, double>( - {node.first, current_node}, node.second)}); + {edge.first, current_node}, edge.second)}); } } // Recursive Case if (possible_paths.empty()) { - for (auto node : subproblem_graph.get_adjacent(current_node)) { + for (auto edge : subproblem_graph.get_adjacent(current_node)) { auto path = - shortest_path_to_start(subproblem_graph, node.first, leaf_nodes); + shortest_path_to_start(subproblem_graph, edge.first, leaf_nodes); path.first.push_back(current_node); - path.second += node.second; + path.second += edge.second; possible_paths.push_back(path); } } @@ -341,7 +342,6 @@ auto NativeGateDecomposer::shortest_path_to_start( } for (const auto& path : possible_paths) { if (path.first.size() == min_length) { - ; shortest_paths.push_back(path); } } @@ -352,7 +352,7 @@ auto NativeGateDecomposer::shortest_path_to_start( auto min_cost = shortest_paths.at(0).second; auto best_path = shortest_paths.at(0); for (const auto& path : shortest_paths) { - if (path.second > min_cost) { + if (path.second < min_cost) { min_cost = path.second; best_path = path; } @@ -385,7 +385,6 @@ auto NativeGateDecomposer::remove_element( return new_vector; } -// TODO: ADD last cond Bool?? auto NativeGateDecomposer::get_possible_moments( DiGraph>>& circuit, const std::vector& v0_c, @@ -427,8 +426,7 @@ auto NativeGateDecomposer::get_possible_moments( this_theta = std::get(circuit.get_Node_Value(v_sort[i])).angles[0]; if (this_theta != prev_theta) { - std::vector discarded = {v_sort.begin(), - v_sort.begin() + (i - 1)}; + std::vector discarded = {v_sort.begin(), v_sort.begin() + i}; std::vector kept = {v_sort.begin() + i, v_sort.end()}; potential_arg.push_back(std::pair, 2>, std::pair, qc::fp>>( @@ -482,10 +480,9 @@ auto NativeGateDecomposer::get_possible_moments( if (v_c1_star.empty()) { break; } - // TODO Check Condition 4 ?? Find out what it does!! - if ((!check_final_cond) || - (check_final_cond && - pot.second.second + new_v_c1_cost < orig_comb_cost)) { + // TODO Check Condition 4 + if (!check_final_cond || + pot.second.second + new_v_c1_cost < orig_comb_cost) { v_arg = {pot.first[0], v_p1_star, pot.first[1], v_new[2]}; for (auto node : v_c1_star) { v_arg[2].push_back(node); @@ -564,7 +561,6 @@ auto NativeGateDecomposer::sift( for (auto node = 0; node < circuit.size(); node++) { if (v_rem.contains(node)) { // TODO: SORT V_rem??? Needs to be a topological - // sort!!!-> order in Circuit is topological auto op = circuit.get_Node_Value(node); std::set op_qubits = std::set(); @@ -606,9 +602,7 @@ auto NativeGateDecomposer::build_schedule( subproblem_graph) -> std::pair>, std::vector> { - // TODO: Find Leaf Nodes of di_graph std::vector leaf_nodes = find_leaf_nodes(subproblem_graph); - // TODO: Find shortest path with minimal weight std::vector minimal_path = find_shortest_path(subproblem_graph, leaf_nodes); std::pair>, std::vector> @@ -616,31 +610,52 @@ auto NativeGateDecomposer::build_schedule( std::vector>{}; // !!!!TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st // v_p empty skip adding it . If not add empty SQGL + + std::vector singleQubitGates; + std::vector> twoQubitGates; + + if (!subproblem_graph.get_Node_Value(minimal_path[0]).first.empty()) { + schedule.first.push_back({}); + } + std::set used_qubits{}; + for (std::size_t i = 0; i < minimal_path.size(); i++) { - for (auto j = 0; - j < subproblem_graph.get_Node_Value(minimal_path[i]).second.size(); - ++j) { - auto op = circuit.get_Node_Value( - subproblem_graph.get_Node_Value(minimal_path[i]).second.at(j)); - if (std::holds_alternative(op)) { - schedule.first.at(i + 1).emplace_back(std::get(op)); + singleQubitGates.clear(); + twoQubitGates.clear(); + used_qubits.clear(); + + for (auto j : subproblem_graph.get_Node_Value(minimal_path[i]).first) { + auto op = circuit.get_Node_Value(j); + if (std::holds_alternative>(op)) { + // TODO: Check if TWOQUBIT GATES Can be executed in parallel!! + auto gate = std::get>(op); + if (used_qubits.contains(gate[0]) || used_qubits.contains(gate[1])) { + schedule.second.push_back(twoQubitGates); + schedule.first.push_back({}); + twoQubitGates.clear(); + used_qubits.clear(); + } + used_qubits.insert(gate[0]); + used_qubits.insert(gate[1]); + twoQubitGates.emplace_back(gate); } } - for (auto j = 0; - j < subproblem_graph.get_Node_Value(minimal_path[i]).first.size(); - ++j) { - auto op = circuit.get_Node_Value( - subproblem_graph.get_Node_Value(minimal_path[i]).first.at(j)); - + for (auto j : subproblem_graph.get_Node_Value(minimal_path[i]).second) { + auto op = circuit.get_Node_Value(j); if (std::holds_alternative(op)) { - schedule.second.at(i).emplace_back( - std::get>(op)); + singleQubitGates.emplace_back(std::get(op)); } } + schedule.first.push_back(singleQubitGates); + if (i != 0 || + !subproblem_graph.get_Node_Value(minimal_path[0]).first.empty()) { + schedule.second.push_back(twoQubitGates); + } } return schedule; } + auto NativeGateDecomposer::add_node_to_sub_prob_graph( const std::vector& v_p, const std::vector& v_c, qc::fp cost, DiGraph, std::vector>>& @@ -688,16 +703,17 @@ auto NativeGateDecomposer::schedule_remaining( double min_cost = std::numeric_limits::max(); double min_weight = std::numeric_limits::max(); std::size_t min_node; - for (const auto& val : args | std::views::values) { - auto new_node = add_node_to_sub_prob_graph(v[0], v_new[1], val, + for (const auto& val : args) { + // v_new[1] is WRONG! + auto new_node = add_node_to_sub_prob_graph(v[0], val.first[0], val.second, subproblem_graph, prev_node); temp_cost = schedule_remaining(v_new, circuit, subproblem_graph, new_node, nQubits, check_final_cond, memo) + - val; + val.second; if (temp_cost < min_cost) { min_cost = temp_cost; min_node = new_node; - min_weight = val; + min_weight = val.second; } } memo[id] = std::pair>( diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index 47d7db938..06f7816cf 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -148,7 +148,7 @@ TEST_F(ThetaOptTest, SiftTest) { // Perform Sift (multiple times???) std::vector v_start = {0}; - for (auto i = 0; i < graph.size(); ++i) { + for (std::size_t i = 0; i < graph.size(); ++i) { v_start.push_back(i); } std::array, 3> v = @@ -171,32 +171,348 @@ TEST_F(ThetaOptTest, SiftTest) { EXPECT_THAT(v[2], ::testing::IsEmpty()); } -TEST_F(ThetaOptTest, RecursionMemoTest) { +TEST_F(ThetaOptTest, NextMomentsPushTest) { + // Circuit + // ┌─────────────────┐ ┌───────┐ + // q_0: ──┤ U(PI,Pi/2,PI/4) ├─────────■───┤ X ├─────────■──── + // └─────────────────┘ │ └───────┘ │ + // │ ┌───────┐ │ + // q_1: ──────────────────────────■───■───┤ Y ├─────────│──── + // │ └───────┘ │ + // ┌───────────────────┐ │ ┌────────────────┐ │ + // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■───┤ U(PI/2,0,PI/2) ├────■──── + // └───────────────────┘ └────────────────┘ + size_t n = 3; + qc::QuantumComputation qc(n); + qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); + qc.u(qc::PI_4, qc::PI_4, qc::PI_4, 2); + qc.cz(1, 2); + qc.cz(0, 1); + qc.x(0); + qc.y(1); + qc.u(qc::PI_2, 0.0, qc::PI_2, 2); + qc.cz(0, 2); + auto schedule = scheduler.schedule(qc); + auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); + auto graph = NativeGateDecomposer::convert_circ_to_dag( + {one_qubit_gates, schedule.second}, n); + auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); + NativeGateDecomposer::DiGraph< + std::pair, std::vector>> + subproblem_graph{}; + subproblem_graph.add_Node( + std::pair, std::vector>({}, {})); + auto v_new = NativeGateDecomposer::sift(graph, v[2], n); + auto moments = + NativeGateDecomposer::get_possible_moments(graph, v[1], v_new, false); + + EXPECT_EQ(moments.size(), 2); + + EXPECT_THAT(moments[0].second, ::testing::DoubleNear(qc::PI, epsilon)); + EXPECT_THAT(moments[0].first[0], ::testing::UnorderedElementsAre(0, 1)); + EXPECT_THAT(moments[0].first[1], ::testing::UnorderedElementsAre(2, 4)); + EXPECT_THAT(moments[0].first[2], ::testing::UnorderedElementsAre(3, 5, 6)); + EXPECT_THAT(moments[0].first[3], ::testing::UnorderedElementsAre(7)); + + EXPECT_THAT(moments[1].second, ::testing::DoubleNear(qc::PI_4, epsilon)); + EXPECT_THAT(moments[1].first[0], ::testing::UnorderedElementsAre(1)); + EXPECT_THAT(moments[1].first[1], ::testing::UnorderedElementsAre(2)); + EXPECT_THAT(moments[1].first[2], ::testing::UnorderedElementsAre(3, 0)); + EXPECT_THAT(moments[1].first[3], ::testing::UnorderedElementsAre(4, 5, 6, 7)); +} + +TEST_F(ThetaOptTest, NextMomentsCond2Test) { + // Circuit + // ┌─────────────────┐ ┌───────┐ + // q_0: ──┤ U(PI,Pi/2,PI/4) ├─────■───■───┤ X ├─────────■──── + // └─────────────────┘ │ │ └───────┘ │ + // │ │ ┌───────┐ │ + // q_1: ──────────────────────────│───■───┤ Y ├─────────│──── + // │ └───────┘ │ + // ┌───────────────────┐ │ ┌────────────────┐ │ + // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■───┤ U(PI/2,0,PI/2) ├────■──── + // └───────────────────┘ └────────────────┘ + size_t n = 3; + qc::QuantumComputation qc(n); + qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); + qc.u(qc::PI_4, qc::PI_4, qc::PI_4, 2); + qc.cz(0, 2); + qc.cz(0, 1); + qc.x(0); + qc.y(1); + qc.u(qc::PI_2, 0.0, qc::PI_2, 2); + qc.cz(0, 2); + auto schedule = scheduler.schedule(qc); + auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); + auto graph = NativeGateDecomposer::convert_circ_to_dag( + {one_qubit_gates, schedule.second}, n); + auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); + NativeGateDecomposer::DiGraph< + std::pair, std::vector>> + subproblem_graph{}; + subproblem_graph.add_Node( + std::pair, std::vector>({}, {})); + auto v_new = NativeGateDecomposer::sift(graph, v[2], n); + auto moments = + NativeGateDecomposer::get_possible_moments(graph, v[1], v_new, false); + + EXPECT_EQ(moments.size(), 1); + + EXPECT_THAT(moments[0].second, ::testing::DoubleNear(qc::PI, epsilon)); + EXPECT_THAT(moments[0].first[0], ::testing::UnorderedElementsAre(0, 1)); + EXPECT_THAT(moments[0].first[1], ::testing::UnorderedElementsAre(2, 4)); + EXPECT_THAT(moments[0].first[2], ::testing::UnorderedElementsAre(3, 5, 6)); + EXPECT_THAT(moments[0].first[3], ::testing::UnorderedElementsAre(7)); +} + +TEST_F(ThetaOptTest, NextMomentsCond3Test) { // Circuit + // ┌─────────────────┐ ┌───────┐ + // q_0: ──┤ U(PI,Pi/2,PI/4) ├─────────■───┤ X ├─────■──── + // └─────────────────┘ │ └───────┘ │ + // │ ┌───────┐ │ + // q_1: ──────────────────────────■───■───┤ Y ├─────│──── + // │ └───────┘ │ + // ┌───────────────────┐ │ │ + // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■─────────────────────■──── + // └───────────────────┘ + size_t n = 3; + qc::QuantumComputation qc(n); + qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); + qc.u(qc::PI_4, qc::PI_4, qc::PI_4, 2); + qc.cz(1, 2); + qc.cz(0, 1); + qc.x(0); + qc.y(1); + qc.cz(0, 2); + auto schedule = scheduler.schedule(qc); + auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); + auto graph = NativeGateDecomposer::convert_circ_to_dag( + {one_qubit_gates, schedule.second}, n); + auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); + NativeGateDecomposer::DiGraph< + std::pair, std::vector>> + subproblem_graph{}; + subproblem_graph.add_Node( + std::pair, std::vector>({}, {})); + auto v_new = NativeGateDecomposer::sift(graph, v[2], n); + auto moments = + NativeGateDecomposer::get_possible_moments(graph, v[1], v_new, false); + + EXPECT_EQ(moments.size(), 1); + + EXPECT_THAT(moments[0].second, ::testing::DoubleNear(qc::PI, epsilon)); + EXPECT_THAT(moments[0].first[0], ::testing::UnorderedElementsAre(0, 1)); + EXPECT_THAT(moments[0].first[1], ::testing::UnorderedElementsAre(2, 3)); + EXPECT_THAT(moments[0].first[2], ::testing::UnorderedElementsAre(4, 5)); + EXPECT_THAT(moments[0].first[3], ::testing::UnorderedElementsAre(6)); } +// COND4 Test?? + TEST_F(ThetaOptTest, RecursionBaseTest) { // Circuit + // ┌───────┐ ┌───────┐ ┌───────┐ + // q_0: ──┤ U() ├───■───────┤ U ├───■───┤ U(3/2) ├─ + // └───────┘ │ └───────┘ │ └───────┘ + // │ ┌───────┐ │ + // q_1: ──────────────■───■───┤ U ├───│───────────── + // │ └───────┘ │ + // ┌───────┐ │ ┌───────┐ │ + // q_1: ──┤ U() ├───────■───┤ U ├───■───────────── + // └───────┘ └───────┘ + + size_t n = 3; + qc::QuantumComputation qc(n); + qc.x(0); + qc.x(2); + qc.cz(0, 1); + qc.cz(1, 2); + qc.z(0); + qc.x(1); + qc.y(2); + qc.cz(0, 2); + qc.y(0); + + auto schedule = scheduler.schedule(qc); + auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); + auto graph = NativeGateDecomposer::convert_circ_to_dag( + {one_qubit_gates, schedule.second}, n); + auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); + NativeGateDecomposer::DiGraph< + std::pair, std::vector>> + subproblem_graph{}; + subproblem_graph.add_Node( + std::pair, std::vector>({}, {})); + std::map>> memo = + std::map>>(); + auto result = NativeGateDecomposer::schedule_remaining( + v, graph, subproblem_graph, 0, n, false, memo); + + EXPECT_THAT(subproblem_graph.get_Node_Value(1).first, ::testing::IsEmpty()); + EXPECT_THAT(subproblem_graph.get_Node_Value(1).second, + ::testing::ElementsAre(0, 1)); } -TEST_F(ThetaOptTest, RecursionCallTest) { +TEST_F(ThetaOptTest, RecursionMemoTest) { // Circuit } -TEST_F(ThetaOptTest, ShortesPathTest) { +TEST_F(ThetaOptTest, ShortestPathTest) { // Subproblem graph! - + NativeGateDecomposer::DiGraph< + std::pair, std::vector>> + subproblem_graph{}; + for (int i = 0; i < 14; i++) { + subproblem_graph.add_Node( + std::pair, std::vector>({}, {})); + } + subproblem_graph.add_Edge(0, 1); + subproblem_graph.add_Edge(0, 2); + subproblem_graph.add_Edge(0, 3, 0.5); + subproblem_graph.add_Edge(1, 4); + subproblem_graph.add_Edge(2, 5); + subproblem_graph.add_Edge(3, 6); + subproblem_graph.add_Edge(3, 7); + subproblem_graph.add_Edge(4, 8); + subproblem_graph.add_Edge(5, 8); + subproblem_graph.add_Edge(5, 9); + subproblem_graph.add_Edge(6, 10); + subproblem_graph.add_Edge(7, 11); + subproblem_graph.add_Edge(8, 12); + subproblem_graph.add_Edge(11, 13); + auto leaf_nodes = NativeGateDecomposer::find_leaf_nodes(subproblem_graph); + auto path = + NativeGateDecomposer::find_shortest_path(subproblem_graph, leaf_nodes); + EXPECT_THAT(leaf_nodes, ::testing::ElementsAre(9, 10, 12, 13)); + EXPECT_THAT(path, ::testing::ElementsAre(3, 6, 10)); } TEST_F(ThetaOptTest, BuildScheduleTest) { // Circuit + // ┌───────┐ ┌───────┐ ┌───────┐ + // q_0: ──┤ X ├───■───────┤ Z ├───■───┤ Y ├─ + // └───────┘ │ └───────┘ │ └───────┘ + // │ ┌───────┐ │ + // q_1: ──────────────■───■───┤ X ├───│───────────── + // │ └───────┘ │ + // ┌───────┐ │ ┌───────┐ │ + // q_2: ──┤ X ├───────■───┤ Y ├───■───────────── + // └───────┘ └───────┘ + + size_t n = 3; + qc::QuantumComputation qc(n); + qc.x(0); + qc.x(2); + qc.cz(0, 1); + qc.cz(1, 2); + qc.z(0); + qc.x(1); + qc.y(2); + qc.cz(0, 2); + qc.y(0); + + auto asap_schedule = scheduler.schedule(qc); + auto one_qubit_gates = + NativeGateDecomposer::transformToU3(asap_schedule.first, n); + auto graph = NativeGateDecomposer::convert_circ_to_dag( + {one_qubit_gates, asap_schedule.second}, n); + + // Create Basic Subproblem graph from purely sifted schedule + NativeGateDecomposer::DiGraph< + std::pair, std::vector>> + subproblem_graph{}; + subproblem_graph.add_Node( + std::pair, std::vector>({}, {})); + subproblem_graph.add_Node( + std::pair, std::vector>({}, + {0, 1})); + subproblem_graph.add_Node( + std::pair, std::vector>({2, 4}, + {3, 5, 6})); + subproblem_graph.add_Node( + std::pair, std::vector>({7}, {8})); + subproblem_graph.add_Edge(0, 1, + NativeGateDecomposer::max_theta(graph, {0, 1})); + subproblem_graph.add_Edge(1, 2, + NativeGateDecomposer::max_theta(graph, {3, 5, 6})); + subproblem_graph.add_Edge(2, 3, NativeGateDecomposer::max_theta(graph, {8})); + + auto schedule = NativeGateDecomposer::build_schedule(graph, subproblem_graph); + + EXPECT_EQ(schedule.first.size(), 4); + EXPECT_EQ(schedule.second.size(), 3); + + EXPECT_EQ(schedule.first.front().at(0).qubit, 0); + EXPECT_THAT(schedule.first.front().at(0).angles, + ::testing::ElementsAre(one_qubit_gates.at(0).at(0).angles[0], + one_qubit_gates.at(0).at(0).angles[1], + one_qubit_gates.at(0).at(0).angles[2])); + EXPECT_EQ(schedule.first.at(0).at(1).qubit, 2); + EXPECT_THAT(schedule.first.at(0).at(1).angles, + ::testing::ElementsAre(one_qubit_gates.at(0).at(0).angles[0], + one_qubit_gates.at(0).at(0).angles[1], + one_qubit_gates.at(0).at(0).angles[2])); + + EXPECT_THAT(schedule.second.at(0).at(0), ::testing::ElementsAre(0, 1)); + + EXPECT_TRUE(schedule.first.at(1).empty()); + + EXPECT_THAT(schedule.second.at(1).at(0), ::testing::ElementsAre(1, 2)); + + EXPECT_EQ(schedule.first.at(2).at(0).qubit, 0); + EXPECT_THAT(schedule.first.at(2).at(0).angles, + ::testing::ElementsAre(one_qubit_gates.at(1).at(0).angles[0], + one_qubit_gates.at(1).at(0).angles[1], + one_qubit_gates.at(1).at(0).angles[2])); + // Two gates flipped?? + EXPECT_EQ(schedule.first.at(2).at(1).qubit, 1); + EXPECT_THAT(schedule.first.at(2).at(1).angles, + ::testing::ElementsAre(one_qubit_gates.at(2).at(0).angles[0], + one_qubit_gates.at(2).at(0).angles[1], + one_qubit_gates.at(2).at(0).angles[2])); + EXPECT_EQ(schedule.first.at(2).at(2).qubit, 2); + EXPECT_THAT(schedule.first.at(2).at(2).angles, + ::testing::ElementsAre(one_qubit_gates.at(2).at(1).angles[0], + one_qubit_gates.at(2).at(1).angles[1], + one_qubit_gates.at(2).at(1).angles[2])); + + EXPECT_THAT(schedule.second.at(2).at(0),::testing::ElementsAre(0,2)); + + EXPECT_EQ(schedule.first.at(3).at(0).qubit,0); + EXPECT_THAT(schedule.first.at(3).at(0).angles,::testing::ElementsAre(one_qubit_gates.at(3).at(0).angles[0], + one_qubit_gates.at(3).at(0).angles[1],one_qubit_gates.at(3).at(0).angles[2])); + } TEST_F(ThetaOptTest, CompleteTestSmall) { // Circuit + // ┌───────┐ ┌───────┐ ┌───────┐ + // q_0: ──┤ X ├───■───────┤ Z ├───■───┤ Y ├─ + // └───────┘ │ └───────┘ │ └───────┘ + // │ ┌───────┐ │ + // q_1: ──────────────■───■───┤ X ├───│───────────── + // │ └───────┘ │ + // ┌───────┐ │ ┌───────┐ │ + // q_2: ──┤ X ├───────■───┤ Y ├───■───────────── + // └───────┘ └───────┘ + + size_t n = 3; + qc::QuantumComputation qc(n); + qc.x(0); + qc.x(2); + qc.cz(0, 1); + qc.cz(1, 2); + qc.z(0); + qc.x(1); + qc.y(2); + qc.cz(0, 2); + qc.y(0); + + } TEST_F(ThetaOptTest, CompleteTestBig) { - +//Circuit BIG } } // namespace na::zoned \ No newline at end of file From bf0d6c6e8019b2e1bdb5baccee5b09fee3ff77e5 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 16 Apr 2026 15:53:51 +0200 Subject: [PATCH 080/110] TESTS and FIxes --- .../zoned/decomposer/NativeGateDecomposer.cpp | 19 ++++----- test/na/zoned/test_theta_opt_scheduler.cpp | 39 ++++++++++--------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 1892f204e..4e6c7cb55 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -120,12 +120,10 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) lambda = 2 * alpha_1; } } else { - theta = qc::PI; // or § PI if sin(theta/2)=-1... Relevant? Or is the -1= - // exp(i*pi) just global phase + theta = qc::PI; if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { phi = 0; lambda = 2 * std::atan2(quat[1], quat[2]); - // atan can give PI instead of 0 Problem? } else { // This should never happen! Exception?? phi = 0.; @@ -678,6 +676,7 @@ auto NativeGateDecomposer::schedule_remaining( // TODO: Check if subproblem has been computed std::size_t id = std::hash, 3>>{}(v); if (memo.contains(id)) { + // Wrong memory Call!!! std::size_t sub_node = memo.at(id).first; double edge_weight = memo.at(id).second[1]; cost = memo.at(id).second[0]; @@ -693,10 +692,13 @@ auto NativeGateDecomposer::schedule_remaining( cost = std::get(circuit.get_Node_Value(i)).angles[0]; } } - add_node_to_sub_prob_graph(v[0], v[1], cost, subproblem_graph, prev_node); + auto end_node = add_node_to_sub_prob_graph(v[0], v[1], cost, + subproblem_graph, prev_node); + memo[id] = std::pair>( + end_node, {cost, cost}); // TODO: Correct to put cost for both??? return cost; } - // TODO: Recursive Call + // TODO: Recursive Call: Only auto v_new = sift(circuit, v[2], nQubits); auto args = get_possible_moments(circuit, v[1], v_new, check_final_cond); qc::fp temp_cost = 0; @@ -704,12 +706,11 @@ auto NativeGateDecomposer::schedule_remaining( double min_weight = std::numeric_limits::max(); std::size_t min_node; for (const auto& val : args) { - // v_new[1] is WRONG! auto new_node = add_node_to_sub_prob_graph(v[0], val.first[0], val.second, subproblem_graph, prev_node); - temp_cost = schedule_remaining(v_new, circuit, subproblem_graph, new_node, - nQubits, check_final_cond, memo) + - val.second; + // USdingg v_new is incorrect!! need adjusted one for arg + temp_cost = schedule_remaining({val.first[1], val.first[2], val.first[3]}, + circuit, subproblem_graph, new_node, nQubits, check_final_cond, memo) + val.second; if (temp_cost < min_cost) { min_cost = temp_cost; min_node = new_node; diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index 06f7816cf..a022a20a1 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -312,27 +312,31 @@ TEST_F(ThetaOptTest, NextMomentsCond3Test) { TEST_F(ThetaOptTest, RecursionBaseTest) { // Circuit - // ┌───────┐ ┌───────┐ ┌───────┐ - // q_0: ──┤ U() ├───■───────┤ U ├───■───┤ U(3/2) ├─ - // └───────┘ │ └───────┘ │ └───────┘ - // │ ┌───────┐ │ - // q_1: ──────────────■───■───┤ U ├───│───────────── - // │ └───────┘ │ - // ┌───────┐ │ ┌───────┐ │ - // q_1: ──┤ U() ├───────■───┤ U ├───■───────────── - // └───────┘ └───────┘ - + // ┌─────────────────┐ ┌───────┐ ┌─────────────────┐ + // q_0: ──┤ U(PI,Pi/2,PI/4) ├─────────■───┤ X ├─────────■───┤ + // U(PI/2,PI/2,PI) ├── + // └─────────────────┘ │ └───────┘ │ + // └─────────────────┘ + // │ ┌───────┐ │ + // q_1: ──────────────────────────■───■───┤ Y + // ├─────────│─────────────────────── + // │ └───────┘ │ + // ┌───────────────────┐ │ ┌────────────────┐ │ + // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■───┤ U(PI/2,0,PI/2) + // ├────■─────────────────────── + // └───────────────────┘ └────────────────┘ size_t n = 3; qc::QuantumComputation qc(n); - qc.x(0); - qc.x(2); - qc.cz(0, 1); + qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); + qc.u(qc::PI_4, qc::PI_4, qc::PI_4, 2); qc.cz(1, 2); - qc.z(0); - qc.x(1); - qc.y(2); + qc.cz(0, 1); + qc.x(0); + qc.y(1); + qc.u(qc::PI_2, 0.0, qc::PI_2, 2); qc.cz(0, 2); qc.y(0); + qc.u(qc::PI_2, qc::PI_2, qc::PI, 0); auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); @@ -354,9 +358,6 @@ TEST_F(ThetaOptTest, RecursionBaseTest) { ::testing::ElementsAre(0, 1)); } -TEST_F(ThetaOptTest, RecursionMemoTest) { - // Circuit -} TEST_F(ThetaOptTest, ShortestPathTest) { // Subproblem graph! From cf1c3991bc074823a4384c04abecf2181896f53b Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:32:06 +0200 Subject: [PATCH 081/110] =?UTF-8?q?=F0=9F=8E=A8=20Update=20Python=20bindin?= =?UTF-8?q?gs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/register_zoned.cpp | 163 +++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 272575cd2..7bd167a07 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -371,6 +371,169 @@ void registerZoned(nb::module_& m) { }, R"pb(Get the statistics of the last compilation. +Returns: + The statistics as a dictionary)pb"); + + //===--------------------------------------------------------------------===// + // Routing-aware Native Gate Compiler + //===--------------------------------------------------------------------===// + nb::class_ + routingAwareNativeGateCompiler( + m, "RoutingAwareNativeGateCompiler", + "Routing-aware native gate zoned neutral atom compiler."); + { + const na::zoned::RoutingAwareNativeGateCompiler::Config defaultConfig; + routingAwareNativeGateCompiler.def( + "__init__", + [](na::zoned::RoutingAwareNativeGateCompiler* self, + const na::zoned::Architecture& arch, const std::string& logLevel, + const double maxFillingFactor, const bool thetaOptSchedule, + const bool checkFinalCond, const bool useWindow, + const size_t windowMinWidth, const double windowRatio, + const double windowShare, + const na::zoned::HeuristicPlacer::Config::Method placementMethod, + const float deepeningFactor, const float deepeningValue, + const float lookaheadFactor, const float reuseLevel, + const size_t maxNodes, const size_t trials, + const size_t queueCapacity, + const na::zoned::IndependentSetRouter::Config::Method routingMethod, + const double preferSplit, const bool warnUnsupportedGates) { + na::zoned::RoutingAwareNativeGateCompiler::Config config; + config.logLevel = spdlog::level::from_str(logLevel); + config.schedulerConfig.maxFillingFactor = maxFillingFactor; + config.decomposerConfig = {.theta_opt_schedule = thetaOptSchedule, + .check_final_cond = checkFinalCond}; + config.layoutSynthesizerConfig.placerConfig = { + .useWindow = useWindow, + .windowMinWidth = windowMinWidth, + .windowRatio = windowRatio, + .windowShare = windowShare, + .method = placementMethod, + .deepeningFactor = deepeningFactor, + .deepeningValue = deepeningValue, + .lookaheadFactor = lookaheadFactor, + .reuseLevel = reuseLevel, + .maxNodes = maxNodes, + .trials = trials, + .queueCapacity = queueCapacity, + }; + config.layoutSynthesizerConfig.routerConfig = { + .method = routingMethod, .preferSplit = preferSplit}; + config.codeGeneratorConfig = {.warnUnsupportedGates = + warnUnsupportedGates}; + new (self) na::zoned::RoutingAwareNativeGateCompiler{arch, config}; + }, + nb::keep_alive<1, 2>(), "arch"_a, + "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), + "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, + "theta_opt_schedule"_a = + defaultConfig.decomposerConfig.theta_opt_schedule, + "check_final_cond"_a = defaultConfig.decomposerConfig.check_final_cond, + "use_window"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, + "window_min_width"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, + "window_ratio"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, + "window_share"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, + "placement_method"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.method, + "deepening_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, + "deepening_value"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, + "lookahead_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, + "reuse_level"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, + "max_nodes"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, + "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, + "queue_capacity"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, + "routing_method"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.method, + "prefer_split"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, + "warn_unsupported_gates"_a = + defaultConfig.codeGeneratorConfig.warnUnsupportedGates, + R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. + +Args: + arch: The zoned neutral atom architecture + log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel + theta_opt_schedule: TODO + check_final_cond: TODO + use_window: Whether to use a window for the placer + window_min_width: The minimum width of the window for the placer + window_ratio: The ratio between the height and the width of the window + window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step + placement_method: The placement method that should be used for the heuristic placer + deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation + deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` + lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer + reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone + max_nodes: The maximum number of nodes that are considered in the A* search. + If this number is exceeded, the search is aborted and an error is raised. + In the current implementation, one node roughly consumes 120 Byte. + Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. + trials: The number of restarts during IDS. + queue_capacity: The maximum capacity of the priority queue used during IDS. + routing_method: The routing method that should be used for the independent set router + prefer_split: The threshold factor for group merging decisions during routing. + warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); + } + + routingAwareNativeGateCompiler.def_static( + "from_json_string", + [](const na::zoned::Architecture& arch, + const std::string& json) -> na::zoned::RoutingAwareNativeGateCompiler { + // The correct header is included, but clang-tidy + // confuses it with the wrong forward header + // NOLINTNEXTLINE(misc-include-cleaner) + return {arch, nlohmann::json::parse(json)}; + }, + "arch"_a, "json"_a, + R"pb(Create a compiler for the given architecture and configurations from a JSON string. + +Args: + arch: The zoned neutral atom architecture + json: The JSON string + +Returns: + The initialized compiler + +Raises: + ValueError: If the string is not a valid JSON string)pb"); + + routingAwareNativeGateCompiler.def( + "compile", + [](na::zoned::RoutingAwareNativeGateCompiler& self, + const qc::QuantumComputation& qc) -> std::string { + return self.compile(qc).toString(); + }, + "qc"_a, + R"pb(Compile a quantum circuit for the zoned neutral atom architecture. + +Args: + qc: The quantum circuit + +Returns: + The compilation result as a string in the .naviz format.)pb"); + + routingAwareNativeGateCompiler.def( + "stats", + [](const na::zoned::RoutingAwareNativeGateCompiler& self) { + const auto json = nb::module_::import_("json"); + const auto loads = json.attr("loads"); + const nlohmann::json stats = self.getStatistics(); + const auto dict = loads(stats.dump()); + return nb::cast>(dict); + }, + R"pb(Get the statistics of the last compilation. + Returns: The statistics as a dictionary)pb"); } From 38bdc9b5147e9e7a6b1bb94deafa8859bb12e1b1 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:39:31 +0200 Subject: [PATCH 082/110] =?UTF-8?q?=F0=9F=8E=A8=20Update=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/mqt/qmap/na/zoned.pyi | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/python/mqt/qmap/na/zoned.pyi b/python/mqt/qmap/na/zoned.pyi index b0fb618bf..22a54cd3d 100644 --- a/python/mqt/qmap/na/zoned.pyi +++ b/python/mqt/qmap/na/zoned.pyi @@ -219,3 +219,89 @@ class RoutingAwareCompiler: Returns: The statistics as a dictionary """ + +class RoutingAwareNativeGateCompiler: + """Routing-aware native gate zoned neutral atom compiler.""" + + def __init__( + self, + arch: ZonedNeutralAtomArchitecture, + log_level: str = "I", + theta_opt_schedule: bool = False, + check_final_cond: bool = False, + max_filling_factor: float = 0.9, + use_window: bool = True, + window_min_width: int = 16, + window_ratio: float = 1.0, + window_share: float = 0.8, + placement_method: PlacementMethod = ..., + deepening_factor: float = ..., + deepening_value: float = 0.0, + lookahead_factor: float = ..., + reuse_level: float = 5.0, + max_nodes: int = 10000000, + trials: int = 4, + queue_capacity: int = 100, + routing_method: RoutingMethod = ..., + prefer_split: float = 1.0, + warn_unsupported_gates: bool = True, + ) -> None: + """Create a routing-aware compiler for the given architecture and configurations. + + Args: + arch: The zoned neutral atom architecture + log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + theta_opt_schedule: TODO + check_final_cond: TODO + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel + use_window: Whether to use a window for the placer + window_min_width: The minimum width of the window for the placer + window_ratio: The ratio between the height and the width of the window + window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step + placement_method: The placement method that should be used for the heuristic placer + deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation + deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` + lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer + reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone + max_nodes: The maximum number of nodes that are considered in the A* search. + If this number is exceeded, the search is aborted and an error is raised. + In the current implementation, one node roughly consumes 120 Byte. + Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. + trials: The number of restarts during IDS. + queue_capacity: The maximum capacity of the priority queue used during IDS. + routing_method: The routing method that should be used for the independent set router + prefer_split: The threshold factor for group merging decisions during routing. + warn_unsupported_gates: Whether to warn about unsupported gates in the code generator + """ + + @staticmethod + def from_json_string(arch: ZonedNeutralAtomArchitecture, json: str) -> RoutingAwareNativeGateCompiler: + """Create a compiler for the given architecture and configurations from a JSON string. + + Args: + arch: The zoned neutral atom architecture + json: The JSON string + + Returns: + The initialized compiler + + Raises: + ValueError: If the string is not a valid JSON string + """ + + def compile(self, qc: mqt.core.ir.QuantumComputation) -> str: + """Compile a quantum circuit for the zoned neutral atom architecture. + + Args: + qc: The quantum circuit + + Returns: + The compilation result as a string in the .naviz format. + """ + + def stats(self) -> dict[str, float]: + """Get the statistics of the last compilation. + + Returns: + The statistics as a dictionary + """ From df150e767373a21f777a771a8d95cd2ad3421ae0 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:44:47 +0200 Subject: [PATCH 083/110] =?UTF-8?q?=F0=9F=8E=A8=20Add=20script=20for=20nat?= =?UTF-8?q?ive=20gate=20compiler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/eval_native_gate_decomposition.py | 690 ++++++++++++++++++ 1 file changed, 690 insertions(+) create mode 100755 eval/na/zoned/eval_native_gate_decomposition.py diff --git a/eval/na/zoned/eval_native_gate_decomposition.py b/eval/na/zoned/eval_native_gate_decomposition.py new file mode 100755 index 000000000..aaf8310b6 --- /dev/null +++ b/eval/na/zoned/eval_native_gate_decomposition.py @@ -0,0 +1,690 @@ +#!/usr/bin/env -S uv run --script --quiet +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +# /// script +# dependencies = [ +# "mqt.bench==2.1.0", +# "mqt.qmap==3.5.0", +# ] +# [tool.uv] +# exclude-newer = "2026-05-01T12:59:59Z" +# /// + +"""Script for evaluating the routing-aware native gate zoned neutral atom compiler. + +In particular, TODO +""" + +from __future__ import annotations + +import json +import os +import pathlib +import queue +import re +from itertools import chain +from math import sqrt +from multiprocessing import get_context +from typing import TYPE_CHECKING + +from mqt.bench import BenchmarkLevel, get_benchmark +from mqt.core import load +from qiskit import QuantumCircuit, transpile + +from mqt.qmap.na.zoned import ( + PlacementMethod, + RoutingAwareCompiler, + RoutingAwareNativeGateCompiler, + RoutingMethod, + ZonedNeutralAtomArchitecture, +) + +if TYPE_CHECKING: + from collections.abc import Callable, Iterable, Iterator, Mapping + from multiprocessing import Queue + from typing import Any, ParamSpec, TypeVar + + from mqt.core.ir import QuantumComputation + + P = ParamSpec("P") + R = TypeVar("R") + + +"""Timeout for running the benchmark in seconds.""" +TIMEOUT = 15 * 60 # sec + + +def _proc_target(q: Queue, func: Callable[P, R], args: P.args, kwargs: P.kwargs) -> None: + """Target function for the process to run the given function and put the result in the queue. + + Args: + q: The queue to put the result in. + func: The function to run. + args: The positional arguments to pass to the function. + kwargs: The keyword arguments to pass to the function. + """ + try: + q.put(("ok", func(*args, **kwargs))) + except Exception as e: + q.put(("err", e)) + + +def run_with_process_timeout(func: Callable[P, R], timeout: float, *args: P.args, **kwargs: P.kwargs) -> R: + """Run a function in a separate process and timeout after the given timeout. + + Args: + func: The function to run. + timeout: The timeout in seconds. + *args: The positional arguments to pass to the function. + **kwargs: The keyword arguments to pass to the function. + + Returns: + The result of the function. + + Raises: + TimeoutError: If the function times out. + Exception: If the function raises an exception. + """ + # "fork" context avoids pickling bound methods but is Unix/macOS only. + ctx = get_context("fork") # use fork so bound methods don't need to be pickled on macOS/Unix + q = ctx.Queue() + p = ctx.Process(target=_proc_target, args=(q, func, args, kwargs)) + p.start() + try: + status, payload = q.get(block=True, timeout=timeout) + except queue.Empty as e: + msg = f"Timed out after {timeout}s" + raise TimeoutError(msg) from e + finally: + if p.is_alive(): + p.terminate() + p.join(2) + if p.is_alive(): + p.kill() + p.join() + if status == "ok": + return payload + if ( + status == "err" + and isinstance(payload, Exception) + and payload.args + and isinstance(payload.args[0], str) + and "Maximum number of nodes reached" in payload.args[0] + ): + msg = "Out of memory" + raise MemoryError(msg) + raise payload + + +def transpile_benchmark(benchmark: str, circuit: QuantumCircuit) -> QuantumCircuit: + """Transpile the given benchmark circuit to the native gate set. + + Args: + benchmark: Name of the benchmark. + circuit: The benchmark circuit to transpile. + + Returns: + The transpiled benchmark circuit. + """ + print(f"\033[32m[INFO]\033[0m Transpiling {benchmark}...") + flattened = QuantumCircuit(circuit.num_qubits, circuit.num_clbits) + flattened.compose(circuit, inplace=True) + transpiled = transpile( + flattened, basis_gates=["cz", "id", "u2", "u1", "u3"], optimization_level=3, seed_transpiler=0 + ) + stripped = QuantumCircuit(*transpiled.qregs, *transpiled.cregs) + for instr in transpiled.data: + if instr.operation.name not in {"measure", "barrier"}: + stripped.append(instr) + print("\033[32m[INFO]\033[0m Done") + return stripped + + +def benchmarks( + benchmark_dict: Iterable[tuple[str, tuple[BenchmarkLevel, Iterable[int]]]], +) -> Iterator[tuple[str, QuantumComputation]]: + """Yields the benchmark names and their circuits.""" + for benchmark, settings in benchmark_dict: + mode, limits = settings + for qubits in limits: + circuit = get_benchmark(benchmark, mode, qubits) + transpiled = transpile_benchmark(benchmark, circuit) + qc = load(transpiled) + yield benchmark, qc + + +def _compile_wrapper( + compiler: RoutingAwareCompiler | RoutingAwareNativeGateCompiler, qc: QuantumComputation +) -> tuple[str, Mapping[str, Any]]: + """Compile and return the compiled code and stats. + + Args: + compiler: The compiler to use. + qc: The circuit to compile. + + Returns: + The compiled code and stats. + """ + return compiler.compile(qc), compiler.stats() + + +def process_benchmark( + compiler: RoutingAwareCompiler | RoutingAwareNativeGateCompiler, + setting_name: str, + qc: QuantumComputation, + benchmark_name: str, + evaluator: Evaluator, +) -> bool: + """Compile and evaluate the given benchmark circuit. + + Args: + compiler: The compiler to use. + setting_name: Name of the compiler setting. + qc: The benchmark circuit to compile. + benchmark_name: Name of the benchmark. + evaluator: The evaluator to use. + + Returns: + True if compilation succeeded, False otherwise. + """ + compiler_name = type(compiler).__name__ + print(f"\033[32m[INFO]\033[0m Compiling {benchmark_name} with {qc.num_qubits} qubits with {compiler_name}...") + try: + code, stats = run_with_process_timeout(_compile_wrapper, TIMEOUT, compiler, qc) + except TimeoutError as e: + print(f"\033[31m[ERROR]\033[0m Failed ({e})") + evaluator.print_timeout(benchmark_name, qc, setting_name) + return False + except MemoryError as e: + print(f"\033[31m[ERROR]\033[0m Failed ({e})") + evaluator.print_memout(benchmark_name, qc, setting_name) + return False + except RuntimeError as e: + print(f"\033[31m[ERROR]\033[0m Failed ({e})") + evaluator.print_error(benchmark_name, qc, setting_name) + return False + + code = "\n".join(line for line in code.splitlines() if not line.startswith("@+ u")) + pathlib.Path(f"out/{compiler_name}/{setting_name}").mkdir(exist_ok=True, parents=True) + pathlib.Path(f"out/{compiler_name}/{setting_name}/{benchmark_name}_{qc.num_qubits}.naviz").write_text( + code, encoding="utf-8" + ) + print("\033[32m[INFO]\033[0m Done") + + print(f"\033[32m[INFO]\033[0m Evaluating {benchmark_name} with {qc.num_qubits} qubits...") + evaluator.reset() + evaluator.evaluate(benchmark_name, qc, setting_name, code, stats) + evaluator.print_data() + print("\033[32m[INFO]\033[0m Done") + return True + + +class Evaluator: + """Class for evaluating compiled circuits. + + Attributes: + arch: The architecture dictionary. + filename: The output CSV filename. + circuit_name: Name of the circuit. + setting: Compiler setting name. + num_qubits: Number of qubits. + two_qubit_gates: Number of two-qubit gates. + scheduling_time: Time taken for scheduling. + reuse_analysis_time: Time taken for reuse analysis. + placement_time: Time taken for placement. + routing_time: Time taken for routing. + code_generation_time: Time taken for code generation. + total_time: Total compilation time. + rearrangement_duration: Duration of rearrangement operations. + two_qubit_gate_layer: Number of two-qubit gate layers. + max_two_qubit_gates: Maximum number of two-qubit gates in a layer. + atom_locations: Dictionary of atom locations. + """ + + def __init__(self, arch: Mapping[str, Any], filename: str) -> None: + """Initialize the Evaluator. + + Args: + arch: The architecture dictionary. + filename: The output CSV filename. + """ + self.arch = arch + self.filename = filename + + self.reset() + + def reset(self) -> None: + """Reset the Evaluator.""" + self.circuit_name = "" + self.num_qubits = 0 + self.setting = "" + self.two_qubit_gates = 0 + + self.scheduling_time = 0 + self.reuse_analysis_time = 0 + self.placement_time = 0 + self.routing_time = 0 + self.code_generation_time = 0 + self.total_time = 0 + + self.rearrangement_duration = 0.0 + self.two_qubit_gate_layer = 0 + self.max_two_qubit_gates = 0 + + self.atom_locations = {} + + def _process_load(self, line: str, it: Iterator[str]) -> None: + """Process a load operation. + + Args: + line: The current line being processed. + it: An iterator over the remaining lines. + """ + # Extract atoms from the load operation + atoms = [] + match = re.match(r"@\+ load \[", line) + if match: + # Multi-line load + for next_line in it: + next_line_stripped = next_line.strip() + if next_line_stripped == "]": + break + if next_line_stripped not in self.atom_locations: + msg = f"Atom {next_line_stripped} not found in atom locations" + raise ValueError(msg) + atoms.append(next_line_stripped) + else: + # Single atom load + match = re.match(r"@\+ load (\w+)", line) + if match: + atom = match.group(1) + if atom not in self.atom_locations: + msg = f"Atom {atom} not found in atom locations" + raise ValueError(msg) + atoms.append(atom) + self._apply_load(atoms) + + def _process_move(self, line: str, it: Iterator[str]) -> None: + """Process a move operation. + + Args: + line: The current line being processed. + it: An iterator over the remaining lines. + """ + # Extract atoms and coordinates from the move operation + moves = [] + match = re.match(r"@\+ move \[", line) + if match: + # Multi-line move + for next_line in it: + next_line_stripped = next_line.strip() + if next_line_stripped == "]": + break + move_match = re.match(r"\((-?\d+\.\d+), (-?\d+\.\d+)\) (\w+)", next_line_stripped) + if move_match: + x, y, atom = move_match.groups() + assert atom in self.atom_locations, f"Atom {atom} not found in atom locations" + moves.append((atom, (int(float(x)), int(float(y))))) + else: + # Single atom move + match = re.match(r"@\+ move \((-?\d+\.\d+), (-?\d+\.\d+)\) (\w+)", line) + if match: + x, y, atom = match.groups() + assert atom in self.atom_locations, f"Atom {atom} not found in atom locations" + moves.append((atom, (int(float(x)), int(float(y))))) + self._apply_move(moves) + + def _process_store(self, line: str, it: Iterator[str]) -> None: + """Process a store operation. + + Args: + line: The current line being processed. + it: An iterator over the remaining lines. + """ + # Extract atoms from the store operation + match = re.match(r"@\+ store \[", line) + atoms = [] + if match: + # Multi-line store + for next_line in it: + next_line_stripped = next_line.strip() + if next_line_stripped == "]": + break + assert next_line_stripped in self.atom_locations, ( + f"Atom {next_line_stripped} not found in atom locations" + ) + atoms.append(next_line_stripped) + else: + # Single atom store + match = re.match(r"@\+ store (\w+)", line) + if match: + assert match.group(1) in self.atom_locations, f"Atom {match.group(1)} not found in atom locations" + atoms.append(match.group(1)) + self._apply_store(atoms) + + def _process_cz(self) -> None: + """Process a cz operation.""" + atoms = [] + y_min = self.arch["entanglement_zones"][0]["slms"][0]["location"][1] + for atom, coord in self.atom_locations.items(): + if coord[1] >= y_min: # atom is in the entanglement zone + atoms.append(atom) + assert len(atoms) % 2 == 0, f"Expected even number of atoms in entanglement zone, got {len(atoms)}" + self._apply_cz(atoms) + + def _process_u(self, line: str, it: Iterator[str]) -> None: + """Process a u operation. + + Args: + line: The current line being processed. + it: An iterator over the remaining lines. + """ + # Extract atoms from u operation + atoms = [] + match = re.match(r"@\+ u( \d\.\d+){3} \[", line) + if match: + # Multi-line u + for next_line in it: + next_line_stripped = next_line.strip() + if next_line_stripped == "]": + break + assert next_line_stripped in self.atom_locations, ( + f"Atom {next_line_stripped} not found in atom locations" + ) + atoms.append(next_line_stripped) + else: + # Single atom u + match = re.match(r"@\+ u( \d\.\d+){3} (\w+)", line) + if match: + if match.group(2) not in self.atom_locations: + self._apply_global_u() + return + atoms.append(match.group(2)) + self._apply_u(atoms) + + def _process_rz(self, line: str, it: Iterator[str]) -> None: + """Process a rz operation. + + Args: + line: The current line being processed. + it: An iterator over the remaining lines. + """ + # Extract atoms from u operation + atoms = [] + match = re.match(r"@\+ rz \d\.\d+ \[", line) + if match: + # Multi-line u + for next_line in it: + next_line_stripped = next_line.strip() + if next_line_stripped == "]": + break + assert next_line_stripped in self.atom_locations, ( + f"Atom {next_line_stripped} not found in atom locations" + ) + atoms.append(next_line_stripped) + else: + # Single atom u + match = re.match(r"@\+ rz \d\.\d+ (\w+)", line) + if match: + assert match.group(1) in self.atom_locations, f"Atom {match.group(1)} not found in atom locations" + atoms.append(match.group(1)) + self._apply_rz(atoms) + + def _apply_load(self, _: list[str]) -> None: + """Apply a load operation. + + Args: + _: List of atoms to load. + """ + self.rearrangement_duration += self.arch["operation_duration"]["atom_transfer"] + + def _apply_move(self, moves: list[tuple[str, tuple[int, int]]]) -> None: + """Apply a move operation. + + Args: + moves: List of tuples containing atom names and their target coordinates. + """ + max_distance = 0.0 + for atom, coord in moves: + if atom in self.atom_locations: + distance = sqrt( + (coord[0] - self.atom_locations[atom][0]) ** 2 + (coord[1] - self.atom_locations[atom][1]) ** 2 + ) + max_distance = max(max_distance, distance) + + # Movement timing model parameters (units: um, us) + t_d_max = 200 # Time to traverse max distance (us) + d_max = 110 # Maximum distance for cubic profile (um) + jerk = 32 * d_max / t_d_max**3 # 0.00044, Jerk constant (um/us³) + v_max = d_max / t_d_max * 2 # = 1.1, Maximum velocity (um/us) + + if max_distance <= d_max: + rearrangement_time = 2 * (4 * max_distance / jerk) ** (1 / 3) + else: + rearrangement_time = t_d_max + (max_distance - d_max) / v_max + self.rearrangement_duration += rearrangement_time + # Update atom locations + for atom, coord in moves: + assert atom in self.atom_locations, f"Atom {atom} not found in atom locations" + self.atom_locations[atom] = coord + + def _apply_store(self, _: list[str]) -> None: + """Apply a store operation. + + Args: + _: List of atoms to store. + """ + self.rearrangement_duration += self.arch["operation_duration"]["atom_transfer"] + + def _apply_cz(self, atoms: list[str]) -> None: + """Apply a cz operation. + + Args: + atoms: List of atoms involved in the cz operation. + """ + self.two_qubit_gate_layer += 1 + self.max_two_qubit_gates = max(self.max_two_qubit_gates, len(atoms) // 2) + + def _apply_u(self, atoms: list[str]) -> None: + """Apply an u operation. + + Args: + atoms: List of atoms involved in the u operation. + """ + + def _apply_global_u(self) -> None: + """Apply a global u operation.""" + + def _apply_global_ry(self) -> None: + """Apply a global rydberg gate operation.""" + self._apply_global_u() + + def _apply_rz(self, atoms: list[str]) -> None: + """Apply a rz operation. + + Args: + atoms: List of atoms involved in the rz operation. + """ + self._apply_u(atoms) + + def evaluate(self, name: str, qc: QuantumComputation, setting: str, code: str, stats: Mapping[str, Any]) -> None: + """Evaluate a circuit. + + Args: + name: Name of the circuit. + qc: The quantum circuit. + setting: Compiler setting name. + code: The compiled code. + stats: Compilation statistics. + """ + self.circuit_name = name + self.num_qubits = qc.num_qubits + self.setting = setting + self.two_qubit_gates = sum(len(op.get_used_qubits()) == 2 for op in qc) + + self.scheduling_time = stats["schedulingTime"] + self.reuse_analysis_time = stats["reuseAnalysisTime"] + self.placement_time = stats["layoutSynthesizerStatistics"]["placementTime"] + self.routing_time = stats["layoutSynthesizerStatistics"]["routingTime"] + self.code_generation_time = stats["codeGenerationTime"] + self.total_time = stats["totalTime"] + + it = iter(code.splitlines()) + + for line in it: + match = re.match(r"atom\s+\((-?\d+\.\d+),\s*(-?\d+\.\d+)\)\s+(\w+)", line) + if match: + x, y, atom_name = match.groups() + self.atom_locations[atom_name] = (int(float(x)), int(float(y))) + else: + # put line back on top of iterator + it = chain([line], it) + break + + for line in it: + if line.startswith("@+ load"): + self._process_load(line, it) + elif line.startswith("@+ move"): + self._process_move(line, it) + elif line.startswith("@+ store"): + self._process_store(line, it) + elif line.startswith("@+ cz"): + self._process_cz() + elif line.startswith("@+ u"): + self._process_u(line, it) + elif line.startswith("@+ rz"): + self._process_rz(line, it) + else: + msg = f"Unrecognized operation: {line}" + raise ValueError(msg) + + def print_header(self) -> None: + """Print the header of the CSV file.""" + pathlib.Path(self.filename).write_text( + "circuit_name,num_qubits,setting,status,two_qubit_gates,scheduling_time,reuse_analysis_time," + "placement_time,routing_time,code_generation_time,total_time,two_qubit_gate_layer,max_two_qubit_gates," + "rearrangement_duration\n", + encoding="utf-8", + ) + + def print_data(self) -> None: + """Print the data of the CSV file.""" + with pathlib.Path(self.filename).open("a", encoding="utf-8") as csv: + csv.write( + f"{self.circuit_name},{self.num_qubits},{self.setting},ok,{self.two_qubit_gates}," + f"{self.scheduling_time},{self.reuse_analysis_time},{self.placement_time}," + f"{self.routing_time},{self.code_generation_time},{self.total_time},{self.two_qubit_gate_layer}," + f"{self.max_two_qubit_gates},{self.rearrangement_duration}\n" + ) + + def print_timeout(self, circuit_name: str, qc: QuantumComputation, setting: str) -> None: + """Print the data of the CSV file. + + Args: + circuit_name: Name of the circuit. + qc: The quantum circuit. + setting: Compiler setting name. + """ + with pathlib.Path(self.filename).open("a", encoding="utf-8") as csv: + csv.write(f"{circuit_name},{qc.num_qubits},{setting},timeout,,,,,,,,,\n") + + def print_memout(self, circuit_name: str, qc: QuantumComputation, setting: str) -> None: + """Print the data of the CSV file. + + Args: + circuit_name: Name of the circuit. + qc: The quantum circuit. + setting: Compiler setting name. + """ + with pathlib.Path(self.filename).open("a", encoding="utf-8") as csv: + csv.write(f"{circuit_name},{qc.num_qubits},{setting},memout,,,,,,,,,\n") + + def print_error(self, circuit_name: str, qc: QuantumComputation, setting: str) -> None: + """Print the data of the CSV file. + + Args: + circuit_name: Name of the circuit. + qc: The quantum circuit. + setting: Compiler setting name. + """ + with pathlib.Path(self.filename).open("a", encoding="utf-8") as csv: + csv.write(f"{circuit_name},{qc.num_qubits},{setting},error,,,,,,,,,\n") + + +def main() -> None: + """Main function for evaluating the fast relaxed compiler.""" + # set working directory to script location + os.chdir(pathlib.Path(pathlib.Path(__file__).resolve()).parent) + print("\033[32m[INFO]\033[0m Reading in architecture...") + with pathlib.Path("square_architecture.json").open(encoding="utf-8") as f: + arch_dict = json.load(f) + arch = ZonedNeutralAtomArchitecture.from_json_file("square_architecture.json") + arch.to_namachine_file("arch.namachine") + print("\033[32m[INFO]\033[0m Done") + common_config = { + "log_level": "error", + "max_filling_factor": 0.9, + "use_window": True, + "window_min_width": 16, + "window_ratio": 1.0, + "window_share": 0.8, + "placement_method": PlacementMethod.ids, + "deepening_factor": 0.01, + "deepening_value": 0.0, + "lookahead_factor": 0.4, + "reuse_level": 5.0, + "trials": 4, + "queue_capacity": 100, + "routing_method": RoutingMethod.relaxed, + "prefer_split": 1.0, + "warn_unsupported_gates": False, + } + baseline = RoutingAwareCompiler(arch, **common_config) + setting1 = RoutingAwareNativeGateCompiler(arch, **common_config) + setting2 = RoutingAwareNativeGateCompiler(arch, **common_config, theta_opt_schedule=True) + + evaluator = Evaluator(arch_dict, "results.csv") + evaluator.print_header() + pathlib.Path("in").mkdir(exist_ok=True) + + benchmark_list = [ + ("graphstate", (BenchmarkLevel.INDEP, [60])), + # ("graphstate", (BenchmarkLevel.INDEP, [60, 80, 100, 120, 140, 160, 180, 200, 500, 1000, 2000, 5000])), + # ("qft", (BenchmarkLevel.INDEP, [500, 1000])), + # ("qpeexact", (BenchmarkLevel.INDEP, [500, 1000])), + # ("wstate", (BenchmarkLevel.INDEP, [500, 1000])), + # ("qaoa", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), + # ("vqe_two_local", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), + ] + + for benchmark, qc in benchmarks(benchmark_list): + qc.qasm3(f"in/{benchmark}_n{qc.num_qubits}.qasm") + process_benchmark(baseline, "baseline", qc, benchmark, evaluator) + process_benchmark(setting1, "setting1", qc, benchmark, evaluator) + process_benchmark(setting2, "setting2", qc, benchmark, evaluator) + + print( + "\033[32m[INFO]\033[0m =============================================================\n" + "\033[32m[INFO]\033[0m Now, \n" + "\033[32m[INFO]\033[0m - the results are located in `results.csv`,\n" + "\033[32m[INFO]\033[0m - the input circuits in the QASM format are located in\n" + "\033[32m[INFO]\033[0m the `in` directory,\n" + "\033[32m[INFO]\033[0m - the compiled circuits in the naviz format are located\n" + "\033[32m[INFO]\033[0m in the `out` directory separated for each compiler and\n" + "\033[32m[INFO]\033[0m setting, and\n" + "\033[32m[INFO]\033[0m - the architecture specification compatible with NAViz is\n" + "\033[32m[INFO]\033[0m located in `arch.namachine`\n" + "\033[32m[INFO]\033[0m \n" + "\033[32m[INFO]\033[0m The generated `.naviz` files can be animated with the\n" + "\033[32m[INFO]\033[0m MQT NAViz tool." + ) + + +if __name__ == "__main__": + main() From 8cbf07bf0db5b5af2b96b41adf5c5f09438c4ed1 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Sun, 19 Apr 2026 14:05:01 +0200 Subject: [PATCH 084/110] TESTS and FIxes --- .../zoned/decomposer/NativeGateDecomposer.cpp | 32 ++-- test/na/zoned/test_theta_opt_scheduler.cpp | 179 +++++++++++++++--- 2 files changed, 165 insertions(+), 46 deletions(-) diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 4e6c7cb55..7b69f379c 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -110,9 +110,9 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) if (std::fabs(quat[0]) > epsilon || std::fabs(quat[3]) > epsilon) { theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); - qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // phi+ lambda + qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // (phi+ lambda) /2 if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { - qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); + qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); //(phi-lambda)/2 phi = alpha_1 + alpha_2; // phi lambda = alpha_1 - alpha_2; } else { @@ -313,6 +313,9 @@ auto NativeGateDecomposer::shortest_path_to_start( -> std::pair, double> { std::vector, double>> possible_paths = {}; // Check if leaf nodes are reached + + // TODO: Check if Path cost takes into account edge weight from current node + // to next node!!! for (auto edge : subproblem_graph.get_adjacent(current_node)) { if (leaf_nodes.contains(edge.first)) { possible_paths.push_back({std::pair, double>( @@ -545,7 +548,6 @@ auto NativeGateDecomposer::max_theta( } return max_cost; } -// TODO: This only ever gives the first Moment????? auto NativeGateDecomposer::sift( DiGraph>>& circuit, std::vector v, size_t nQubits) @@ -557,22 +559,18 @@ auto NativeGateDecomposer::sift( std::set v_rem = std::set(v.begin(), v.end()); std::set removed = std::set(); + // We traverse the graph rather than v_rem to use the graph's topological + // ordering for (auto node = 0; node < circuit.size(); node++) { - if (v_rem.contains(node)) { // TODO: SORT V_rem??? Needs to be a topological + if (v_rem.contains(node)) { auto op = circuit.get_Node_Value(node); - std::set op_qubits = std::set(); - std::set used_qubits; if (std::holds_alternative(op)) { - used_qubits = {std::get(op).qubit}; + op_qubits = {std::get(op).qubit}; } else { - used_qubits = {std::get>(op)[0], - std::get>(op)[1]}; - } - - for (auto qubit : used_qubits) { - op_qubits.insert(qubit); + op_qubits = {std::get>(op)[0], + std::get>(op)[1]}; } if (removed.size() < nQubits && disjunct(removed, op_qubits)) { if (std::holds_alternative(op)) { @@ -580,8 +578,6 @@ auto NativeGateDecomposer::sift( removed.insert(std::get(op).qubit); } else { v_p.push_back(node); - // Add something to make it only pick one 2-Qubit gate per Qubit per - // moment??? } } else { v_r.push_back(node); @@ -676,7 +672,6 @@ auto NativeGateDecomposer::schedule_remaining( // TODO: Check if subproblem has been computed std::size_t id = std::hash, 3>>{}(v); if (memo.contains(id)) { - // Wrong memory Call!!! std::size_t sub_node = memo.at(id).first; double edge_weight = memo.at(id).second[1]; cost = memo.at(id).second[0]; @@ -708,7 +703,6 @@ auto NativeGateDecomposer::schedule_remaining( for (const auto& val : args) { auto new_node = add_node_to_sub_prob_graph(v[0], val.first[0], val.second, subproblem_graph, prev_node); - // USdingg v_new is incorrect!! need adjusted one for arg temp_cost = schedule_remaining({val.first[1], val.first[2], val.first[3]}, circuit, subproblem_graph, new_node, nQubits, check_final_cond, memo) + val.second; if (temp_cost < min_cost) { @@ -747,8 +741,8 @@ auto NativeGateDecomposer::schedule_theta_opt( std::pair, std::vector>({}, {})); std::map>> memo = {}; - auto cost = schedule_remaining(v, circuit, sub_prob_graph, base_node, - nQubits_, config_.check_final_cond, memo); + auto cost = schedule_remaining(v, circuit, sub_prob_graph, base_node, nQubits, + config_.check_final_cond, memo); // TODO: Create Schedule from Subproblem Graph std::pair>, std::vector> final_circuit = build_schedule(circuit, sub_prob_graph); diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index a022a20a1..252c237e4 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -312,19 +312,24 @@ TEST_F(ThetaOptTest, NextMomentsCond3Test) { TEST_F(ThetaOptTest, RecursionBaseTest) { // Circuit - // ┌─────────────────┐ ┌───────┐ ┌─────────────────┐ - // q_0: ──┤ U(PI,Pi/2,PI/4) ├─────────■───┤ X ├─────────■───┤ - // U(PI/2,PI/2,PI) ├── + // ┌─────────────────┐ ┌───────┐ + // q_0: ──┤ U(PI,Pi/2,PI/4) ├─────────■───┤ X ├─────────■─ ─ ─ // └─────────────────┘ │ └───────┘ │ - // └─────────────────┘ // │ ┌───────┐ │ - // q_1: ──────────────────────────■───■───┤ Y - // ├─────────│─────────────────────── + // q_1: ──────────────────────────■───■───┤ Y ├─────────│─ ─ ─ // │ └───────┘ │ // ┌───────────────────┐ │ ┌────────────────┐ │ - // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■───┤ U(PI/2,0,PI/2) - // ├────■─────────────────────── + // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■───┤ U(PI/2,0,PI/2) ├────■─ ─ ─ // └───────────────────┘ └────────────────┘ + // + // ┌─────────────────┐ + // q_0: ─ ─ ─┤ U(PI/2,PI/2,PI) ├── + // └─────────────────┘ + // + // q_1: ─ ─ ────────────────────── + // + // q_2: ─ ─ ────────────────────── + size_t n = 3; qc::QuantumComputation qc(n); qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); @@ -353,9 +358,48 @@ TEST_F(ThetaOptTest, RecursionBaseTest) { auto result = NativeGateDecomposer::schedule_remaining( v, graph, subproblem_graph, 0, n, false, memo); + EXPECT_EQ(result, 5 * qc::PI_2); + + EXPECT_EQ(subproblem_graph.size(), 1 + 6); + auto t = subproblem_graph.get_adjacent(0); + EXPECT_THAT(subproblem_graph.get_adjacent(0), + ::testing::UnorderedElementsAre(::testing::Pair(1, qc::PI), + ::testing::Pair(4, qc::PI_4))); + EXPECT_THAT(subproblem_graph.get_Node_Value(1).first, ::testing::IsEmpty()); EXPECT_THAT(subproblem_graph.get_Node_Value(1).second, - ::testing::ElementsAre(0, 1)); + ::testing::UnorderedElementsAre(0, 1)); + EXPECT_THAT(subproblem_graph.get_adjacent(1), + ::testing::UnorderedElementsAre(::testing::Pair(2, qc::PI))); + EXPECT_THAT(subproblem_graph.get_Node_Value(2).first, + ::testing::UnorderedElementsAre(2, 4)); + EXPECT_THAT(subproblem_graph.get_Node_Value(2).second, + ::testing::UnorderedElementsAre(3, 5, 6)); + EXPECT_THAT(subproblem_graph.get_adjacent(2), + ::testing::UnorderedElementsAre(::testing::Pair(3, qc::PI_2))); + EXPECT_THAT(subproblem_graph.get_Node_Value(3).first, + ::testing::UnorderedElementsAre(7)); + EXPECT_THAT(subproblem_graph.get_Node_Value(3).second, + ::testing::UnorderedElementsAre(8)); + EXPECT_THAT(subproblem_graph.get_adjacent(3), ::testing::IsEmpty()); + + EXPECT_THAT(subproblem_graph.get_Node_Value(4).first, ::testing::IsEmpty()); + EXPECT_THAT(subproblem_graph.get_Node_Value(4).second, + ::testing::UnorderedElementsAre(1)); + EXPECT_THAT(subproblem_graph.get_adjacent(4), + ::testing::UnorderedElementsAre(::testing::Pair(5, qc::PI))); + EXPECT_THAT(subproblem_graph.get_Node_Value(5).first, + ::testing::UnorderedElementsAre(2)); + EXPECT_THAT(subproblem_graph.get_Node_Value(5).second, + ::testing::UnorderedElementsAre(0, 3)); + EXPECT_THAT(subproblem_graph.get_adjacent(5), + ::testing::UnorderedElementsAre(::testing::Pair(6, qc::PI))); + EXPECT_THAT(subproblem_graph.get_Node_Value(6).first, + ::testing::UnorderedElementsAre(4)); + EXPECT_THAT(subproblem_graph.get_Node_Value(6).second, + ::testing::UnorderedElementsAre(5, 6)); + EXPECT_THAT(subproblem_graph.get_adjacent(6), + ::testing::UnorderedElementsAre(::testing::Pair(3,qc::PI_2))); } @@ -482,38 +526,119 @@ TEST_F(ThetaOptTest, BuildScheduleTest) { EXPECT_EQ(schedule.first.at(3).at(0).qubit,0); EXPECT_THAT(schedule.first.at(3).at(0).angles,::testing::ElementsAre(one_qubit_gates.at(3).at(0).angles[0], - one_qubit_gates.at(3).at(0).angles[1],one_qubit_gates.at(3).at(0).angles[2])); - + one_qubit_gates.at(3).at(0).angles[1], + one_qubit_gates.at(3).at(0).angles[2])); } TEST_F(ThetaOptTest, CompleteTestSmall) { // Circuit - // ┌───────┐ ┌───────┐ ┌───────┐ - // q_0: ──┤ X ├───■───────┤ Z ├───■───┤ Y ├─ - // └───────┘ │ └───────┘ │ └───────┘ - // │ ┌───────┐ │ - // q_1: ──────────────■───■───┤ X ├───│───────────── - // │ └───────┘ │ - // ┌───────┐ │ ┌───────┐ │ - // q_2: ──┤ X ├───────■───┤ Y ├───■───────────── - // └───────┘ └───────┘ + // ┌─────────────────┐ ┌───────┐ + // q_0: ──┤ U(PI,PI/2,PI/4) ├─────────■───┤ X ├─────────■─ ─ ─ + // └─────────────────┘ │ └───────┘ │ + // │ ┌───────┐ │ + // q_1: ──────────────────────────■───■───┤ Y ├─────────│─ ─ ─ + // │ └───────┘ │ + // ┌───────────────────┐ │ ┌────────────────┐ │ + // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■───┤ U(PI/2,0,PI/2) ├────■─ ─ ─ + // └───────────────────┘ └────────────────┘ + // + // ┌─────────────────┐ + // q_0: ─ ─ ─┤ U(PI/2,PI/2,PI) ├── + // └─────────────────┘ + // + // q_1: ─ ─ ────────────────────── + // + // q_2: ─ ─ ────────────────────── size_t n = 3; qc::QuantumComputation qc(n); - qc.x(0); - qc.x(2); - qc.cz(0, 1); + qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); + qc.u(qc::PI_4, qc::PI_4, qc::PI_4, 2); qc.cz(1, 2); - qc.z(0); - qc.x(1); - qc.y(2); + qc.cz(0, 1); + qc.x(0); + qc.y(1); + qc.u(qc::PI_2, 0.0, qc::PI_2, 2); qc.cz(0, 2); qc.y(0); + qc.u(qc::PI_2, qc::PI_2, qc::PI, 0); + + auto schedule = scheduler.schedule(qc); + auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); + auto theta_opt_schedule = + decomposer.schedule_theta_opt({one_qubit_gates, schedule.second}, n); + + EXPECT_EQ(theta_opt_schedule.first.size(), 4); + EXPECT_EQ(theta_opt_schedule.second.size(), 3); + + EXPECT_EQ(theta_opt_schedule.first.at(0).size(), 2); + EXPECT_EQ(theta_opt_schedule.first.at(1).size(), 0); + EXPECT_EQ(theta_opt_schedule.first.at(2).size(), 3); + EXPECT_EQ(theta_opt_schedule.first.at(3).size(), 1); + + EXPECT_EQ(theta_opt_schedule.second.at(0).size(), 1); + EXPECT_EQ(theta_opt_schedule.second.at(1).size(), 1); + EXPECT_EQ(theta_opt_schedule.second.at(2).size(), 1); + + EXPECT_EQ(theta_opt_schedule.first.at(0).at(0).qubit, 0); + // TODO: DOUBLE Nears!!! + EXPECT_THAT( + theta_opt_schedule.first.at(0).at(0).angles, + ::testing::ElementsAre( + ::testing::DoubleNear(one_qubit_gates.at(0).at(0).angles[0], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(0).at(0).angles[1], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(0).at(0).angles[2], + epsilon))); + EXPECT_EQ(theta_opt_schedule.first.at(0).at(1).qubit, 2); + EXPECT_THAT( + theta_opt_schedule.first.at(0).at(1).angles, + ::testing::ElementsAre( + ::testing::DoubleNear(one_qubit_gates.at(0).at(1).angles[0], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(0).at(1).angles[1], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(0).at(1).angles[2], + epsilon))); + + EXPECT_THAT(theta_opt_schedule.second.at(0).front(), + ::testing::ElementsAre(1, 2)); + + EXPECT_THAT(theta_opt_schedule.second.at(1).front(), + ::testing::ElementsAre(0, 1)); + // QUAT + EXPECT_EQ(theta_opt_schedule.first.at(2).at(0).qubit, 2); + EXPECT_THAT( + theta_opt_schedule.first.at(2).at(0).angles, + ::testing::ElementsAre( + ::testing::DoubleNear(one_qubit_gates.at(1).at(0).angles[0], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).at(0).angles[1], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).at(0).angles[2], + epsilon))); + EXPECT_EQ(theta_opt_schedule.first.at(2).at(1).qubit, 0); + EXPECT_THAT( + theta_opt_schedule.first.at(2).at(1).angles, + ::testing::ElementsAre( + ::testing::DoubleNear(one_qubit_gates.at(2).at(0).angles[0], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(2).at(0).angles[1], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(2).at(0).angles[2], + epsilon))); + EXPECT_EQ(theta_opt_schedule.first.at(2).at(2).qubit, 1); + EXPECT_THAT( + theta_opt_schedule.first.at(2).at(2).angles, + ::testing::ElementsAre( + ::testing::DoubleNear(one_qubit_gates.at(2).at(1).angles[0], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(2).at(1).angles[1], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(2).at(1).angles[2], epsilon))); + + EXPECT_THAT(theta_opt_schedule.second.at(2).front(),::testing::ElementsAre(0,2)); + EXPECT_EQ(theta_opt_schedule.first.at(3).at(0).qubit,0); + EXPECT_THAT(theta_opt_schedule.first.at(3).at(0).angles,::testing::ElementsAre( + ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[0], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[1], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[2], epsilon))); } TEST_F(ThetaOptTest, CompleteTestBig) { -//Circuit BIG + //Circuit BIG } } // namespace na::zoned \ No newline at end of file From 973031b5a22ad0d31d7f754b6ad9121be90608d6 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:34:06 +0200 Subject: [PATCH 085/110] =?UTF-8?q?=E2=9E=96=20Only=20have=20NA=20compiler?= =?UTF-8?q?=20in=20python=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/CMakeLists.txt | 3 +-- bindings/na/na.cpp | 6 +++--- pyproject.toml | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/bindings/na/CMakeLists.txt b/bindings/na/CMakeLists.txt index 71edf5450..5e002a06e 100644 --- a/bindings/na/CMakeLists.txt +++ b/bindings/na/CMakeLists.txt @@ -6,7 +6,7 @@ # # Licensed under the MIT License -file(GLOB_RECURSE NA_SOURCES **.cpp) +file(GLOB_RECURSE NA_SOURCES na.cpp, register_zoned.cpp) add_mqt_python_binding_nanobind( QMAP @@ -17,7 +17,6 @@ add_mqt_python_binding_nanobind( INSTALL_DIR . LINK_LIBS - MQT::NASP MQT::QMapNAZoned MQT::CoreQASM) diff --git a/bindings/na/na.cpp b/bindings/na/na.cpp index 6d052b9d6..d0cd73dee 100644 --- a/bindings/na/na.cpp +++ b/bindings/na/na.cpp @@ -13,12 +13,12 @@ namespace nb = nanobind; // forward declarations -void registerStatePreparation(nb::module_& m); +// void registerStatePreparation(nb::module_& m); void registerZoned(nb::module_& m); NB_MODULE(MQT_QMAP_MODULE_NAME, m) { - auto statePreparation = m.def_submodule("state_preparation"); - registerStatePreparation(statePreparation); + // auto statePreparation = m.def_submodule("state_preparation"); + // registerStatePreparation(statePreparation); auto zoned = m.def_submodule("zoned"); registerZoned(zoned); diff --git a/pyproject.toml b/pyproject.toml index afb0022fe..66a7e72bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,10 +94,10 @@ build-dir = "build/{wheel_tag}/{build_type}" # Only build the Python bindings target build.targets = [ - "mqt-qmap-clifford_synthesis-bindings", - "mqt-qmap-hybrid_mapper-bindings", +# "mqt-qmap-clifford_synthesis-bindings", +# "mqt-qmap-hybrid_mapper-bindings", "mqt-qmap-na-bindings", - "mqt-qmap-sc-bindings", +# "mqt-qmap-sc-bindings", ] # Only install the Python package component From 0c4e79a0b89772ee76a1458e92c70ebb7f042a7a Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 23 Apr 2026 14:19:46 +0200 Subject: [PATCH 086/110] =?UTF-8?q?=F0=9F=8E=A8=20COmment=20out=20subdirs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index ba7af1ee3..7d67f0fa5 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -25,8 +25,6 @@ list( ${BASEPOINT}/../../core/lib ${BASEPOINT}/../../core/lib64) -# add all modules -add_subdirectory(clifford_synthesis) -add_subdirectory(hybrid_mapper) +# add all modules add_subdirectory(clifford_synthesis) add_subdirectory(hybrid_mapper) add_subdirectory(na) -add_subdirectory(sc) +# add_subdirectory(sc) From 2cf6547691ca42798d3fa435fe41de5674d734d2 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 23 Apr 2026 15:39:45 +0200 Subject: [PATCH 087/110] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20cmake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/CMakeLists.txt | 2 +- bindings/na/register_zoned.cpp | 163 --------------------------------- 2 files changed, 1 insertion(+), 164 deletions(-) diff --git a/bindings/na/CMakeLists.txt b/bindings/na/CMakeLists.txt index 5e002a06e..043bc85a1 100644 --- a/bindings/na/CMakeLists.txt +++ b/bindings/na/CMakeLists.txt @@ -6,7 +6,7 @@ # # Licensed under the MIT License -file(GLOB_RECURSE NA_SOURCES na.cpp, register_zoned.cpp) +file(GLOB_RECURSE NA_SOURCES na.cpp register_zoned.cpp) add_mqt_python_binding_nanobind( QMAP diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 7bd167a07..272575cd2 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -371,169 +371,6 @@ void registerZoned(nb::module_& m) { }, R"pb(Get the statistics of the last compilation. -Returns: - The statistics as a dictionary)pb"); - - //===--------------------------------------------------------------------===// - // Routing-aware Native Gate Compiler - //===--------------------------------------------------------------------===// - nb::class_ - routingAwareNativeGateCompiler( - m, "RoutingAwareNativeGateCompiler", - "Routing-aware native gate zoned neutral atom compiler."); - { - const na::zoned::RoutingAwareNativeGateCompiler::Config defaultConfig; - routingAwareNativeGateCompiler.def( - "__init__", - [](na::zoned::RoutingAwareNativeGateCompiler* self, - const na::zoned::Architecture& arch, const std::string& logLevel, - const double maxFillingFactor, const bool thetaOptSchedule, - const bool checkFinalCond, const bool useWindow, - const size_t windowMinWidth, const double windowRatio, - const double windowShare, - const na::zoned::HeuristicPlacer::Config::Method placementMethod, - const float deepeningFactor, const float deepeningValue, - const float lookaheadFactor, const float reuseLevel, - const size_t maxNodes, const size_t trials, - const size_t queueCapacity, - const na::zoned::IndependentSetRouter::Config::Method routingMethod, - const double preferSplit, const bool warnUnsupportedGates) { - na::zoned::RoutingAwareNativeGateCompiler::Config config; - config.logLevel = spdlog::level::from_str(logLevel); - config.schedulerConfig.maxFillingFactor = maxFillingFactor; - config.decomposerConfig = {.theta_opt_schedule = thetaOptSchedule, - .check_final_cond = checkFinalCond}; - config.layoutSynthesizerConfig.placerConfig = { - .useWindow = useWindow, - .windowMinWidth = windowMinWidth, - .windowRatio = windowRatio, - .windowShare = windowShare, - .method = placementMethod, - .deepeningFactor = deepeningFactor, - .deepeningValue = deepeningValue, - .lookaheadFactor = lookaheadFactor, - .reuseLevel = reuseLevel, - .maxNodes = maxNodes, - .trials = trials, - .queueCapacity = queueCapacity, - }; - config.layoutSynthesizerConfig.routerConfig = { - .method = routingMethod, .preferSplit = preferSplit}; - config.codeGeneratorConfig = {.warnUnsupportedGates = - warnUnsupportedGates}; - new (self) na::zoned::RoutingAwareNativeGateCompiler{arch, config}; - }, - nb::keep_alive<1, 2>(), "arch"_a, - "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), - "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, - "theta_opt_schedule"_a = - defaultConfig.decomposerConfig.theta_opt_schedule, - "check_final_cond"_a = defaultConfig.decomposerConfig.check_final_cond, - "use_window"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, - "window_min_width"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, - "window_ratio"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, - "window_share"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, - "placement_method"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.method, - "deepening_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, - "deepening_value"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, - "lookahead_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, - "reuse_level"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, - "max_nodes"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, - "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, - "queue_capacity"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, - "routing_method"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.method, - "prefer_split"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, - "warn_unsupported_gates"_a = - defaultConfig.codeGeneratorConfig.warnUnsupportedGates, - R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. - -Args: - arch: The zoned neutral atom architecture - log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" - max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel - theta_opt_schedule: TODO - check_final_cond: TODO - use_window: Whether to use a window for the placer - window_min_width: The minimum width of the window for the placer - window_ratio: The ratio between the height and the width of the window - window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step - placement_method: The placement method that should be used for the heuristic placer - deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation - deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` - lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer - reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone - max_nodes: The maximum number of nodes that are considered in the A* search. - If this number is exceeded, the search is aborted and an error is raised. - In the current implementation, one node roughly consumes 120 Byte. - Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. - trials: The number of restarts during IDS. - queue_capacity: The maximum capacity of the priority queue used during IDS. - routing_method: The routing method that should be used for the independent set router - prefer_split: The threshold factor for group merging decisions during routing. - warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); - } - - routingAwareNativeGateCompiler.def_static( - "from_json_string", - [](const na::zoned::Architecture& arch, - const std::string& json) -> na::zoned::RoutingAwareNativeGateCompiler { - // The correct header is included, but clang-tidy - // confuses it with the wrong forward header - // NOLINTNEXTLINE(misc-include-cleaner) - return {arch, nlohmann::json::parse(json)}; - }, - "arch"_a, "json"_a, - R"pb(Create a compiler for the given architecture and configurations from a JSON string. - -Args: - arch: The zoned neutral atom architecture - json: The JSON string - -Returns: - The initialized compiler - -Raises: - ValueError: If the string is not a valid JSON string)pb"); - - routingAwareNativeGateCompiler.def( - "compile", - [](na::zoned::RoutingAwareNativeGateCompiler& self, - const qc::QuantumComputation& qc) -> std::string { - return self.compile(qc).toString(); - }, - "qc"_a, - R"pb(Compile a quantum circuit for the zoned neutral atom architecture. - -Args: - qc: The quantum circuit - -Returns: - The compilation result as a string in the .naviz format.)pb"); - - routingAwareNativeGateCompiler.def( - "stats", - [](const na::zoned::RoutingAwareNativeGateCompiler& self) { - const auto json = nb::module_::import_("json"); - const auto loads = json.attr("loads"); - const nlohmann::json stats = self.getStatistics(); - const auto dict = loads(stats.dump()); - return nb::cast>(dict); - }, - R"pb(Get the statistics of the last compilation. - Returns: The statistics as a dictionary)pb"); } From 786aef6168d4dee8785aac1d2a087898c1e059ca Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 23 Apr 2026 15:40:04 +0200 Subject: [PATCH 088/110] =?UTF-8?q?=F0=9F=8E=A8=20Add=20bindings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/register_zoned.cpp | 163 +++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 272575cd2..7bd167a07 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -371,6 +371,169 @@ void registerZoned(nb::module_& m) { }, R"pb(Get the statistics of the last compilation. +Returns: + The statistics as a dictionary)pb"); + + //===--------------------------------------------------------------------===// + // Routing-aware Native Gate Compiler + //===--------------------------------------------------------------------===// + nb::class_ + routingAwareNativeGateCompiler( + m, "RoutingAwareNativeGateCompiler", + "Routing-aware native gate zoned neutral atom compiler."); + { + const na::zoned::RoutingAwareNativeGateCompiler::Config defaultConfig; + routingAwareNativeGateCompiler.def( + "__init__", + [](na::zoned::RoutingAwareNativeGateCompiler* self, + const na::zoned::Architecture& arch, const std::string& logLevel, + const double maxFillingFactor, const bool thetaOptSchedule, + const bool checkFinalCond, const bool useWindow, + const size_t windowMinWidth, const double windowRatio, + const double windowShare, + const na::zoned::HeuristicPlacer::Config::Method placementMethod, + const float deepeningFactor, const float deepeningValue, + const float lookaheadFactor, const float reuseLevel, + const size_t maxNodes, const size_t trials, + const size_t queueCapacity, + const na::zoned::IndependentSetRouter::Config::Method routingMethod, + const double preferSplit, const bool warnUnsupportedGates) { + na::zoned::RoutingAwareNativeGateCompiler::Config config; + config.logLevel = spdlog::level::from_str(logLevel); + config.schedulerConfig.maxFillingFactor = maxFillingFactor; + config.decomposerConfig = {.theta_opt_schedule = thetaOptSchedule, + .check_final_cond = checkFinalCond}; + config.layoutSynthesizerConfig.placerConfig = { + .useWindow = useWindow, + .windowMinWidth = windowMinWidth, + .windowRatio = windowRatio, + .windowShare = windowShare, + .method = placementMethod, + .deepeningFactor = deepeningFactor, + .deepeningValue = deepeningValue, + .lookaheadFactor = lookaheadFactor, + .reuseLevel = reuseLevel, + .maxNodes = maxNodes, + .trials = trials, + .queueCapacity = queueCapacity, + }; + config.layoutSynthesizerConfig.routerConfig = { + .method = routingMethod, .preferSplit = preferSplit}; + config.codeGeneratorConfig = {.warnUnsupportedGates = + warnUnsupportedGates}; + new (self) na::zoned::RoutingAwareNativeGateCompiler{arch, config}; + }, + nb::keep_alive<1, 2>(), "arch"_a, + "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), + "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, + "theta_opt_schedule"_a = + defaultConfig.decomposerConfig.theta_opt_schedule, + "check_final_cond"_a = defaultConfig.decomposerConfig.check_final_cond, + "use_window"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, + "window_min_width"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, + "window_ratio"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, + "window_share"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, + "placement_method"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.method, + "deepening_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, + "deepening_value"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, + "lookahead_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, + "reuse_level"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, + "max_nodes"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, + "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, + "queue_capacity"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, + "routing_method"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.method, + "prefer_split"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, + "warn_unsupported_gates"_a = + defaultConfig.codeGeneratorConfig.warnUnsupportedGates, + R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. + +Args: + arch: The zoned neutral atom architecture + log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel + theta_opt_schedule: TODO + check_final_cond: TODO + use_window: Whether to use a window for the placer + window_min_width: The minimum width of the window for the placer + window_ratio: The ratio between the height and the width of the window + window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step + placement_method: The placement method that should be used for the heuristic placer + deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation + deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` + lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer + reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone + max_nodes: The maximum number of nodes that are considered in the A* search. + If this number is exceeded, the search is aborted and an error is raised. + In the current implementation, one node roughly consumes 120 Byte. + Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. + trials: The number of restarts during IDS. + queue_capacity: The maximum capacity of the priority queue used during IDS. + routing_method: The routing method that should be used for the independent set router + prefer_split: The threshold factor for group merging decisions during routing. + warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); + } + + routingAwareNativeGateCompiler.def_static( + "from_json_string", + [](const na::zoned::Architecture& arch, + const std::string& json) -> na::zoned::RoutingAwareNativeGateCompiler { + // The correct header is included, but clang-tidy + // confuses it with the wrong forward header + // NOLINTNEXTLINE(misc-include-cleaner) + return {arch, nlohmann::json::parse(json)}; + }, + "arch"_a, "json"_a, + R"pb(Create a compiler for the given architecture and configurations from a JSON string. + +Args: + arch: The zoned neutral atom architecture + json: The JSON string + +Returns: + The initialized compiler + +Raises: + ValueError: If the string is not a valid JSON string)pb"); + + routingAwareNativeGateCompiler.def( + "compile", + [](na::zoned::RoutingAwareNativeGateCompiler& self, + const qc::QuantumComputation& qc) -> std::string { + return self.compile(qc).toString(); + }, + "qc"_a, + R"pb(Compile a quantum circuit for the zoned neutral atom architecture. + +Args: + qc: The quantum circuit + +Returns: + The compilation result as a string in the .naviz format.)pb"); + + routingAwareNativeGateCompiler.def( + "stats", + [](const na::zoned::RoutingAwareNativeGateCompiler& self) { + const auto json = nb::module_::import_("json"); + const auto loads = json.attr("loads"); + const nlohmann::json stats = self.getStatistics(); + const auto dict = loads(stats.dump()); + return nb::cast>(dict); + }, + R"pb(Get the statistics of the last compilation. + Returns: The statistics as a dictionary)pb"); } From ee20ff09f01937e8dd38728009e2ba650942958b Mon Sep 17 00:00:00 2001 From: ga96dup Date: Mon, 27 Apr 2026 14:39:01 +0200 Subject: [PATCH 089/110] Eval Script changes to remove need for z3 and add AxialDecomposer --- bindings/CMakeLists.txt | 4 +- bindings/clifford_synthesis/CMakeLists.txt | 2 +- bindings/na/register_zoned.cpp | 156 +++++++++++++ bindings/sc/CMakeLists.txt | 2 +- cmake/ExternalDependencies.cmake | 20 +- .../zoned/eval_native_gate_decomposition.py | 30 ++- include/na/zoned/Compiler.hpp | 14 ++ .../na/zoned/decomposer/AxialDecomposer.hpp | 113 +++++++++ .../zoned/decomposer/NativeGateDecomposer.hpp | 1 + pyproject.toml | 2 +- python/mqt/qmap/na/zoned.pyi | 82 +++++++ src/na/zoned/decomposer/AxialDecomposer.cpp | 215 ++++++++++++++++++ 12 files changed, 626 insertions(+), 15 deletions(-) create mode 100644 include/na/zoned/decomposer/AxialDecomposer.hpp create mode 100644 src/na/zoned/decomposer/AxialDecomposer.cpp diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index 7d67f0fa5..c41a2d3c3 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -25,6 +25,8 @@ list( ${BASEPOINT}/../../core/lib ${BASEPOINT}/../../core/lib64) -# add all modules add_subdirectory(clifford_synthesis) add_subdirectory(hybrid_mapper) +# add all modules +#add_subdirectory(clifford_synthesis) +#add_subdirectory(hybrid_mapper) add_subdirectory(na) # add_subdirectory(sc) diff --git a/bindings/clifford_synthesis/CMakeLists.txt b/bindings/clifford_synthesis/CMakeLists.txt index 1f84d93c4..71e07c5aa 100644 --- a/bindings/clifford_synthesis/CMakeLists.txt +++ b/bindings/clifford_synthesis/CMakeLists.txt @@ -15,7 +15,7 @@ add_mqt_python_binding_nanobind( INSTALL_DIR . LINK_LIBS - MQT::QMapCliffordSynthesis + #MQT::QMapCliffordSynthesis MQT::CoreQASM) # install the Python stub files in editable mode for better IDE support diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 7bd167a07..9225a2680 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -374,6 +374,162 @@ void registerZoned(nb::module_& m) { Returns: The statistics as a dictionary)pb"); + //===--------------------------------------------------------------------===// + // Routing-aware Axial Compiler + //===--------------------------------------------------------------------===// + nb::class_ routingAwareAxialCompiler( + m, "routingAwareAxialCompiler", + "Routing-aware axial zoned neutral atom compiler."); + { + const na::zoned::routingAwareAxialCompiler::Config defaultConfig; + routingAwareAxialCompiler.def( + "__init__", + [](na::zoned::routingAwareAxialCompiler* self, + const na::zoned::Architecture& arch, const std::string& logLevel, + const double maxFillingFactor, const bool useWindow, + const size_t windowMinWidth, const double windowRatio, + const double windowShare, + const na::zoned::HeuristicPlacer::Config::Method placementMethod, + const float deepeningFactor, const float deepeningValue, + const float lookaheadFactor, const float reuseLevel, + const size_t maxNodes, const size_t trials, + const size_t queueCapacity, + const na::zoned::IndependentSetRouter::Config::Method routingMethod, + const double preferSplit, const bool warnUnsupportedGates) { + na::zoned::RoutingAwareNativeGateCompiler::Config config; + config.logLevel = spdlog::level::from_str(logLevel); + config.schedulerConfig.maxFillingFactor = maxFillingFactor; + config.decomposerConfig = {}; + config.layoutSynthesizerConfig.placerConfig = { + .useWindow = useWindow, + .windowMinWidth = windowMinWidth, + .windowRatio = windowRatio, + .windowShare = windowShare, + .method = placementMethod, + .deepeningFactor = deepeningFactor, + .deepeningValue = deepeningValue, + .lookaheadFactor = lookaheadFactor, + .reuseLevel = reuseLevel, + .maxNodes = maxNodes, + .trials = trials, + .queueCapacity = queueCapacity, + }; + config.layoutSynthesizerConfig.routerConfig = { + .method = routingMethod, .preferSplit = preferSplit}; + config.codeGeneratorConfig = {.warnUnsupportedGates = + warnUnsupportedGates}; + new (self) na::zoned::routingAwareAxialCompiler{arch, config}; + }, + nb::keep_alive<1, 2>(), "arch"_a, + "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), + "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, + "theta_opt_schedule"_a = + defaultConfig.decomposerConfig.theta_opt_schedule, + "check_final_cond"_a = defaultConfig.decomposerConfig.check_final_cond, + "use_window"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, + "window_min_width"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, + "window_ratio"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, + "window_share"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, + "placement_method"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.method, + "deepening_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, + "deepening_value"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, + "lookahead_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, + "reuse_level"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, + "max_nodes"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, + "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, + "queue_capacity"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, + "routing_method"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.method, + "prefer_split"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, + "warn_unsupported_gates"_a = + defaultConfig.codeGeneratorConfig.warnUnsupportedGates, + R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. +Args: + arch: The zoned neutral atom architecture + log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel + use_window: Whether to use a window for the placer + window_min_width: The minimum width of the window for the placer + window_ratio: The ratio between the height and the width of the window + window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step + placement_method: The placement method that should be used for the heuristic placer + deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation + deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` + lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer + reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone + max_nodes: The maximum number of nodes that are considered in the A* search. + If this number is exceeded, the search is aborted and an error is raised. + In the current implementation, one node roughly consumes 120 Byte. + Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. + trials: The number of restarts during IDS. + queue_capacity: The maximum capacity of the priority queue used during IDS. + routing_method: The routing method that should be used for the independent set router + prefer_split: The threshold factor for group merging decisions during routing. + warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); + } + + routingAwareAxialCompiler.def_static( + "from_json_string", + [](const na::zoned::Architecture& arch, + const std::string& json) -> na::zoned::routingAwareAxialCompiler { + // The correct header is included, but clang-tidy + // confuses it with the wrong forward header + // NOLINTNEXTLINE(misc-include-cleaner) + return {arch, nlohmann::json::parse(json)}; + }, + "arch"_a, "json"_a, + R"pb(Create a compiler for the given architecture and configurations from a JSON string. + + Args: + arch: The zoned neutral atom architecture + json: The JSON string + +Returns: + The initialized compiler + +Raises: + ValueError: If the string is not a valid JSON string)pb"); + + routingAwareAxialCompiler.def( + "compile", + [](na::zoned::routingAwareAxialCompiler& self, + const qc::QuantumComputation& qc) -> std::string { + return self.compile(qc).toString(); + }, + "qc"_a, + R"pb(Compile a quantum circuit for the zoned neutral atom architecture. + +Args: + qc: The quantum circuit + +Returns: + The compilation result as a string in the .naviz format.)pb"); + + routingAwareAxialCompiler.def( + "stats", + [](const na::zoned::RoutingAwareNativeGateCompiler& self) { + const auto json = nb::module_::import_("json"); + const auto loads = json.attr("loads"); + const nlohmann::json stats = self.getStatistics(); + const auto dict = loads(stats.dump()); + return nb::cast>(dict); + }, + R"pb(Get the statistics of the last compilation. + Returns: + The statistics as a dictionary)pb"); + //===--------------------------------------------------------------------===// // Routing-aware Native Gate Compiler //===--------------------------------------------------------------------===// diff --git a/bindings/sc/CMakeLists.txt b/bindings/sc/CMakeLists.txt index 39475db47..c97a72dc1 100644 --- a/bindings/sc/CMakeLists.txt +++ b/bindings/sc/CMakeLists.txt @@ -15,7 +15,7 @@ add_mqt_python_binding_nanobind( INSTALL_DIR . LINK_LIBS - MQT::QMapSCExact + #MQT::QMapSCExact MQT::QMapSCHeuristic MQT::CoreQASM) diff --git a/cmake/ExternalDependencies.cmake b/cmake/ExternalDependencies.cmake index 4f0a520f6..6554f5455 100644 --- a/cmake/ExternalDependencies.cmake +++ b/cmake/ExternalDependencies.cmake @@ -12,12 +12,11 @@ include(CMakeDependentOption) include(FetchContent) set(FETCH_PACKAGES "") -# search for Z3 -find_package(Z3 4.8.15) -if(NOT Z3_FOUND) - message( - WARNING "Did not find Z3. Exact mapper and Clifford synthesis libraries will not be available") -endif() +#FetchContent_Declare(Z3 +# GIT_REPOSITORY https://github.com/Z3Prover/z3 +# GIT_TAG z3-4.8.15 +#) +#list(APPEND FETCH_PACKAGES Z3) if(BUILD_MQT_QMAP_BINDINGS) # Manually detect the installed mqt-core package. @@ -50,6 +49,8 @@ set(MQT_CORE_REV "8747a89766dfb943d62ed100d383cd1823d2356c" set(MQT_CORE_REPO_OWNER "munich-quantum-toolkit" CACHE STRING "MQT Core repository owner (change when using a fork)") # cmake-format: on + + FetchContent_Declare( mqt-core GIT_REPOSITORY https://github.com/${MQT_CORE_REPO_OWNER}/core.git @@ -103,6 +104,13 @@ endif() # Make all declared dependencies available. FetchContent_MakeAvailable(${FETCH_PACKAGES}) +# search for Z3 +find_package(Z3 4.8.15) +if (NOT Z3_FOUND) + message( + WARNING "Did not find Z3. Exact mapper and Clifford synthesis libraries will not be available") +endif () + # Mark the plog includes as SYSTEM includes to suppress warnings. get_target_property(PLOG_IID plog INTERFACE_INCLUDE_DIRECTORIES) set_target_properties(plog PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${PLOG_IID}") diff --git a/eval/na/zoned/eval_native_gate_decomposition.py b/eval/na/zoned/eval_native_gate_decomposition.py index aaf8310b6..4f09c7b76 100755 --- a/eval/na/zoned/eval_native_gate_decomposition.py +++ b/eval/na/zoned/eval_native_gate_decomposition.py @@ -40,6 +40,7 @@ from mqt.qmap.na.zoned import ( PlacementMethod, RoutingAwareCompiler, + RoutingAwareAxialCompiler, RoutingAwareNativeGateCompiler, RoutingMethod, ZonedNeutralAtomArchitecture, @@ -196,7 +197,8 @@ def process_benchmark( compiler_name = type(compiler).__name__ print(f"\033[32m[INFO]\033[0m Compiling {benchmark_name} with {qc.num_qubits} qubits with {compiler_name}...") try: - code, stats = run_with_process_timeout(_compile_wrapper, TIMEOUT, compiler, qc) + code, stats = _compile_wrapper(compiler, + qc) # run_with_process_timeout(_compile_wrapper, TIMEOUT, compiler, qc) except TimeoutError as e: print(f"\033[31m[ERROR]\033[0m Failed ({e})") evaluator.print_timeout(benchmark_name, qc, setting_name) @@ -436,6 +438,14 @@ def _process_rz(self, line: str, it: Iterator[str]) -> None: atoms.append(match.group(1)) self._apply_rz(atoms) + def _process_ry(self, line: str, it: Iterator[str]) -> None: + """Process a global ry operation. + + Args: + line: The current line being processed. + it: An iterator over the remaining lines. + """ + self._apply_global_ry() def _apply_load(self, _: list[str]) -> None: """Apply a load operation. @@ -560,6 +570,8 @@ def evaluate(self, name: str, qc: QuantumComputation, setting: str, code: str, s self._process_u(line, it) elif line.startswith("@+ rz"): self._process_rz(line, it) + elif line.startswith("@+ ry"): + self._process_ry(line, it) else: msg = f"Unrecognized operation: {line}" raise ValueError(msg) @@ -646,28 +658,36 @@ def main() -> None: "warn_unsupported_gates": False, } baseline = RoutingAwareCompiler(arch, **common_config) - setting1 = RoutingAwareNativeGateCompiler(arch, **common_config) - setting2 = RoutingAwareNativeGateCompiler(arch, **common_config, theta_opt_schedule=True) + setting1 = RoutingAwareAxialCompiler(arch, **common_config) + setting2 = RoutingAwareNativeGateCompiler(arch, **common_config) + setting3 = RoutingAwareNativeGateCompiler(arch, **common_config, theta_opt_schedule=True) evaluator = Evaluator(arch_dict, "results.csv") evaluator.print_header() pathlib.Path("in").mkdir(exist_ok=True) benchmark_list = [ - ("graphstate", (BenchmarkLevel.INDEP, [60])), + ("graphstate", (BenchmarkLevel.INDEP, [60, 100])), # ("graphstate", (BenchmarkLevel.INDEP, [60, 80, 100, 120, 140, 160, 180, 200, 500, 1000, 2000, 5000])), + ("qft", (BenchmarkLevel.INDEP, [100])), # ("qft", (BenchmarkLevel.INDEP, [500, 1000])), + ("qpeexact", (BenchmarkLevel.INDEP, [100])), # ("qpeexact", (BenchmarkLevel.INDEP, [500, 1000])), + ("wstate", (BenchmarkLevel.INDEP, [100])), # ("wstate", (BenchmarkLevel.INDEP, [500, 1000])), + ("qaoa", (BenchmarkLevel.INDEP, [50, 100])), # ("qaoa", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), + ("vqe_two_local", (BenchmarkLevel.INDEP, [50, 100])), # ("vqe_two_local", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), ] for benchmark, qc in benchmarks(benchmark_list): qc.qasm3(f"in/{benchmark}_n{qc.num_qubits}.qasm") process_benchmark(baseline, "baseline", qc, benchmark, evaluator) - process_benchmark(setting1, "setting1", qc, benchmark, evaluator) + # process_benchmark(setting1, "setting1", qc, benchmark, evaluator) process_benchmark(setting2, "setting2", qc, benchmark, evaluator) + process_benchmark(setting2, "setting3", qc, benchmark, evaluator) + print( "\033[32m[INFO]\033[0m =============================================================\n" diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index 13ec86672..482044e04 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -15,6 +15,7 @@ #include "na/NAComputation.hpp" #include "na/zoned/Architecture.hpp" #include "na/zoned/code_generator/CodeGenerator.hpp" +#include "na/zoned/decomposer/AxialDecomposer.hpp" #include "na/zoned/decomposer/NativeGateDecomposer.hpp" #include "na/zoned/decomposer/NoOpDecomposer.hpp" #include "na/zoned/layout_synthesizer/PlaceAndRouteSynthesizer.hpp" @@ -314,6 +315,19 @@ class RoutingAwareCompiler final : Compiler(architecture) {} }; +class RoutingAwareAxialCompiler final + : public Compiler { +public: + RoutingAwareAxialCompiler(const Architecture& architecture, + const Config& config) + : Compiler(architecture, config) {} + + explicit RoutingAwareAxialCompiler(const Architecture& architecture) + : Compiler(architecture) {} +}; + class RoutingAwareNativeGateCompiler final : public Compiler + +namespace na::zoned { +class AxialDecomposer : public DecomposerBase { + /** + * A quaternion is represented by an array of four `qc::fp` values `{q0, q1, + * q2, q3}` denoting the components of the quaternion. + */ + using Quaternion = std::array; + + /// A value to use as a margin of error for float equality + constexpr static qc::fp epsilon = + std::numeric_limits::epsilon() * 1024; + +public: + /// The configuration of the NativeGateDecomposer + struct Config { + template + friend void to_json(BasicJsonType& /* unused */, + const Config& /* unused */) {} + template + friend void from_json(const BasicJsonType& /* unused */, + Config& /* unused */) {} + }; + + /** + * A minimal struct to store the parameters of a U3 gate along with the qubit + * it acts on. + */ + struct StructU3 { + std::array angles; + qc::Qubit qubit; + }; + +private: + /// The configuration of the NativeGateDecomposer + Config config_; + +public: + /// Create a new NativeGateDecomposer. + AxialDecomposer(const Architecture& /* unused */, + const Config& /* unused */) {} + + /** + * @brief Converts commonly used single qubit gates into their Quaternion + * representation. + * @details A single qubit gate R_v(phi) with rotation axis v=(v0,v1,v2) + * and rotation angle phi can be represented as a quaternion: + * @code quaternion(R_v(phi)) = (cos(phi/2) * I, v0 * sin(phi/2) * X, v1 * + * sin(phi/2) * Y, v2 * sin(phi/2) * Z)@endcode with X, Y, Z Pauli Matrices. + * @param op a reference_wrapper to the operation to be converted + * @returns a quaternion. + */ + static auto + convertGateToQuaternion(std::reference_wrapper op) + -> Quaternion; + /** + * @brief Merges the quaternions representing two gates as in a matrix + * multiplication of the gates. + * @param q1 the first quaternion to be combined. + * @param q2 the second quaternion to be combined. + * @returns an quaternion. + */ + static auto combineQuaternions(const Quaternion& q1, const Quaternion& q2) + -> Quaternion; + /** + * @brief Calculates the values of the U3-gate parameters theta, phi, and + * lambda. + * @param quat is a quaternion representing a single qubit gate. + * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving + * the U3 gate angles. + */ + static auto getU3AnglesFromQuaternion(const Quaternion& quat) + -> std::array; + + /** + * @brief Takes a vector of SingleQubitGateLayers and, for each layer, + * transforms all gates into U3 gates represented by `StructU3` objects. + * @details It combines all gates acting on the same qubit into a single U3 + * gate. + * @param layers is a std::vector of SingleQubitGateLayers of a scheduled + * circuit. + * @param n_qubits the number of Qubits in the scheduled circuit + * @returns a vector of vectors of StructU3 objects representing the single + * qubit gate layers. + */ + [[nodiscard]] static auto + transformToU3(const std::vector& layers, + size_t n_qubits) -> std::vector>; + /** + * @brief Decomposes a given schedule of operations into the native gate set + * and, if theta_opt_scheduling is selected re-schedules them to + * minimize the total global rotation angle theta across the circuit + * @details + * @param nQubits the number of Qubits in the scheduled circuit + * @param schedule a pair of vectors containing SingleQubitGateRefLayers + * and TwoQubitGateLayers + * @returns a pair of vectors containing SingleQubitLayers and TwoQubitLayers + * representing the decomposed (and rescheduled) circuit + */ + [[nodiscard]] auto + decompose(size_t nQubits, + const std::pair, + std::vector>& schedule) + -> std::pair, + std::vector> override; +}; +} // namespace na::zoned \ No newline at end of file diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 97ac74bc9..58c66cdf4 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -105,6 +105,7 @@ class NativeGateDecomposer : public DecomposerBase { * gate. * @param layers is a std::vector of SingleQubitGateLayers of a scheduled * circuit. + * @param n_qubits the number of Qubits in the scheduled circuit * @returns a vector of vectors of StructU3 objects representing the single * qubit gate layers. */ diff --git a/pyproject.toml b/pyproject.toml index 66a7e72bc..716252255 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,7 @@ build-dir = "build/{wheel_tag}/{build_type}" # Only build the Python bindings target build.targets = [ -# "mqt-qmap-clifford_synthesis-bindings", + # "mqt-qmap-clifford_synthesis-bindings", # "mqt-qmap-hybrid_mapper-bindings", "mqt-qmap-na-bindings", # "mqt-qmap-sc-bindings", diff --git a/python/mqt/qmap/na/zoned.pyi b/python/mqt/qmap/na/zoned.pyi index 22a54cd3d..f54b09d25 100644 --- a/python/mqt/qmap/na/zoned.pyi +++ b/python/mqt/qmap/na/zoned.pyi @@ -220,6 +220,88 @@ class RoutingAwareCompiler: The statistics as a dictionary """ + +class RoutingAwareAxialCompiler: + """Routing-aware native gate zoned neutral atom compiler.""" + + def __init__( + self, + arch: ZonedNeutralAtomArchitecture, + log_level: str = "I", + max_filling_factor: float = 0.9, + use_window: bool = True, + window_min_width: int = 16, + window_ratio: float = 1.0, + window_share: float = 0.8, + placement_method: PlacementMethod = ..., + deepening_factor: float = ..., + deepening_value: float = 0.0, + lookahead_factor: float = ..., + reuse_level: float = 5.0, + max_nodes: int = 10000000, + trials: int = 4, + queue_capacity: int = 100, + routing_method: RoutingMethod = ..., + prefer_split: float = 1.0, + warn_unsupported_gates: bool = True, + ) -> None: + """Create a routing-aware compiler for the given architecture and configurations. + + Args: + arch: The zoned neutral atom architecture + log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel + use_window: Whether to use a window for the placer + window_min_width: The minimum width of the window for the placer + window_ratio: The ratio between the height and the width of the window + window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step + placement_method: The placement method that should be used for the heuristic placer + deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation + deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` + lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer + reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone + max_nodes: The maximum number of nodes that are considered in the A* search. + If this number is exceeded, the search is aborted and an error is raised. + In the current implementation, one node roughly consumes 120 Byte. + Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. + trials: The number of restarts during IDS. + queue_capacity: The maximum capacity of the priority queue used during IDS. + routing_method: The routing method that should be used for the independent set router + prefer_split: The threshold factor for group merging decisions during routing. + warn_unsupported_gates: Whether to warn about unsupported gates in the code generator + """ + + @staticmethod + def from_json_string(arch: ZonedNeutralAtomArchitecture, json: str) -> RoutingAwareAxialCompiler: + """Create a compiler for the given architecture and configurations from a JSON string. + + Args: + arch: The zoned neutral atom architecture + json: The JSON string + + Returns: + The initialized compiler + + Raises: + ValueError: If the string is not a valid JSON string + """ + + def compile(self, qc: mqt.core.ir.QuantumComputation) -> str: + """Compile a quantum circuit for the zoned neutral atom architecture. + + Args: + qc: The quantum circuit + + Returns: + The compilation result as a string in the .naviz format. + """ + + def stats(self) -> dict[str, float]: + """Get the statistics of the last compilation. + + Returns: + The statistics as a dictionary + """ class RoutingAwareNativeGateCompiler: """Routing-aware native gate zoned neutral atom compiler.""" diff --git a/src/na/zoned/decomposer/AxialDecomposer.cpp b/src/na/zoned/decomposer/AxialDecomposer.cpp new file mode 100644 index 000000000..0e75c33c1 --- /dev/null +++ b/src/na/zoned/decomposer/AxialDecomposer.cpp @@ -0,0 +1,215 @@ +#include "na/zoned/decomposer/AxialDecomposer.hpp" + +#include "ir/operations/CompoundOperation.hpp" +#include "ir/operations/Operation.hpp" +#include "ir/operations/StandardOperation.hpp" + +namespace na::zoned { +auto AxialDecomposer::convertGateToQuaternion( + std::reference_wrapper op) -> Quaternion { + assert(op.get().getNqubits() == 1); + Quaternion quat{}; + if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { + quat = {cos(op.get().getParameter().front() / 2), 0, 0, + sin(op.get().getParameter().front() / 2)}; + } else if (op.get().getType() == qc::Z) { + quat = {0, 0, 0, 1}; + } else if (op.get().getType() == qc::S) { + quat = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + } else if (op.get().getType() == qc::Sdg) { + quat = {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}; + } else if (op.get().getType() == qc::T) { + quat = {cos(qc::PI_4 / 2), 0, 0, sin(qc::PI_4 / 2)}; + } else if (op.get().getType() == qc::Tdg) { + quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; + } else if (op.get().getType() == qc::U) { + quat = combineQuaternions( + combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, + sin(op.get().getParameter().at(1) / 2)}, + {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}), + {cos(op.get().getParameter().at(2) / 2), 0, 0, + sin(op.get().getParameter().at(2) / 2)}); + } else if (op.get().getType() == qc::U2) { + quat = combineQuaternions( + combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, + sin(op.get().getParameter().front() / 2)}, + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(op.get().getParameter().at(1) / 2), 0, 0, + sin(op.get().getParameter().at(1) / 2)}); + } else if (op.get().getType() == qc::RX) { + quat = {cos(op.get().getParameter().front() / 2), + sin(op.get().getParameter().front() / 2), 0, 0}; + } else if (op.get().getType() == qc::RY) { + quat = {cos(op.get().getParameter().front() / 2), 0, + sin(op.get().getParameter().front() / 2), 0}; + } else if (op.get().getType() == qc::H) { + quat = combineQuaternions( + combineQuaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); + } else if (op.get().getType() == qc::X) { + quat = {0, 1, 0, 0}; + } else if (op.get().getType() == qc::Y) { + quat = {0, 0, 1, 0}; + } else if (op.get().getType() == qc::Vdg) { + quat = combineQuaternions( + combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); + } else if (op.get().getType() == qc::SX) { + quat = combineQuaternions( + combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), + {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); + } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { + quat = combineQuaternions( + combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, + {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), + {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); + } else { + // if the gate type is not recognized, an error is printed and the + // gate is not included in the output. + std::ostringstream oss; + oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() + << "\n"; + throw std::invalid_argument(oss.str()); + } + return quat; +} + +auto AxialDecomposer::combineQuaternions(const Quaternion& q1, + const Quaternion& q2) -> Quaternion { + Quaternion new_quat{}; + new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; + new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; + new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; + new_quat[3] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]; + return new_quat; +} + +auto AxialDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) + -> std::array { + qc::fp theta; + qc::fp phi; + qc::fp lambda; + if (std::fabs(quat[0]) > epsilon || std::fabs(quat[3]) > epsilon) { + theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), + std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); + qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // (phi+ lambda) /2 + if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { + qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); //(phi-lambda)/2 + phi = alpha_1 + alpha_2; // phi + lambda = alpha_1 - alpha_2; + } else { + phi = 0; + lambda = 2 * alpha_1; + } + } else { + theta = qc::PI; + if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { + phi = 0; + lambda = 2 * std::atan2(quat[1], quat[2]); + } else { + // This should never happen! Exception?? + phi = 0.; + lambda = 0.; + } + } + return {theta, phi, lambda}; +} + +auto AxialDecomposer::transformToU3( + const std::vector& layers, size_t n_qubits) + -> std::vector> { + std::vector> new_layers; + for (const auto& layer : layers) { + std::vector>> gates( + n_qubits); + std::vector new_layer; + for (auto gate : layer) { + // WHat are operations with empty targets doing?? + if (!gate.get().getTargets().empty()) { + gates[gate.get().getTargets().front()].push_back(gate); + } + } + + for (auto qubit_gates : gates) { + if (!qubit_gates.empty()) { + std::array quat = convertGateToQuaternion(qubit_gates[0]); + for (size_t i = 1; i < qubit_gates.size(); i++) { + quat = + combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); + } + std::array angles = getU3AnglesFromQuaternion(quat); + new_layer.emplace_back( + StructU3{angles, qubit_gates[0].get().getTargets().front()}); + } + } + new_layers.push_back(new_layer); + } + return new_layers; +} + +auto AxialDecomposer::decompose( + size_t nQubits, const std::pair, + std::vector>& schedule) + -> std::pair, + std::vector> { + + std::vector> U3Layers = + transformToU3(schedule.first, nQubits); + std::vector NewTwoQubitGateLayers = schedule.second; + std::vector NewSingleQubitLayers = + std::vector{}; + + for (const auto& layer : U3Layers) { + SingleQubitGateLayer FrontLayer; + SingleQubitGateLayer MidLayer; + SingleQubitGateLayer BackLayer; + SingleQubitGateLayer NewLayer; + + for (auto gate : layer) { + + // Global RX here instead of RY + FrontLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {gate.angles[1]}))); + + MidLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {gate.angles[0]}))); + + BackLayer.emplace_back(std::make_unique( + qc::StandardOperation(gate.qubit, qc::RZ, {gate.angles[2]}))); + } // gate::layer + + std::vector> GR_plus; + std::vector> GR_minus; + + for (size_t i = 0; i < nQubits; ++i) { + GR_plus.emplace_back(std::make_unique( + i, qc::RX, std::initializer_list{-qc::PI / 2})); + GR_minus.emplace_back(std::make_unique( + i, qc::RX, std::initializer_list{qc::PI / 2})); + } + + for (auto&& gate : FrontLayer) { + NewLayer.push_back(std::move(gate)); + } + + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_plus), true))); + + for (auto&& gate : MidLayer) { + NewLayer.push_back(std::move(gate)); + } + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_minus), true))); + + for (auto&& gate : BackLayer) { + NewLayer.push_back(std::move(gate)); + } + NewSingleQubitLayers.push_back(std::move(NewLayer)); + } // layer::SingleQubitLayers + return {std::move(NewSingleQubitLayers), NewTwoQubitGateLayers}; +} + +} // namespace na::zoned \ No newline at end of file From d80d412b839abc065eb30dbbc84dd0d5699b23fe Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:03:42 +0200 Subject: [PATCH 090/110] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../na/zoned/decomposer/AxialDecomposer.hpp | 17 +++++++---- .../zoned/decomposer/NativeGateDecomposer.cpp | 29 +++++++++++-------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/include/na/zoned/decomposer/AxialDecomposer.hpp b/include/na/zoned/decomposer/AxialDecomposer.hpp index 2e88f99e8..9a57f5e51 100644 --- a/include/na/zoned/decomposer/AxialDecomposer.hpp +++ b/include/na/zoned/decomposer/AxialDecomposer.hpp @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + #pragma once #include "na/zoned/Types.hpp" @@ -37,11 +47,6 @@ class AxialDecomposer : public DecomposerBase { qc::Qubit qubit; }; -private: - /// The configuration of the NativeGateDecomposer - Config config_; - -public: /// Create a new NativeGateDecomposer. AxialDecomposer(const Architecture& /* unused */, const Config& /* unused */) {} @@ -110,4 +115,4 @@ class AxialDecomposer : public DecomposerBase { -> std::pair, std::vector> override; }; -} // namespace na::zoned \ No newline at end of file +} // namespace na::zoned diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 7b69f379c..e9d1f6313 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -113,7 +113,7 @@ auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // (phi+ lambda) /2 if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); //(phi-lambda)/2 - phi = alpha_1 + alpha_2; // phi + phi = alpha_1 + alpha_2; // phi lambda = alpha_1 - alpha_2; } else { phi = 0; @@ -423,9 +423,10 @@ auto NativeGateDecomposer::get_possible_moments( auto this_theta = prev_theta; std::set mk_qubits = { std::get(circuit.get_Node_Value(v_sort[0])).qubit}; - for (auto i = 0; i < v_sort.size(); i++) { - this_theta = - std::get(circuit.get_Node_Value(v_sort[i])).angles[0]; + for (auto i = 0; static_cast(i) < v_sort.size(); i++) { + this_theta = std::get( + circuit.get_Node_Value(v_sort[static_cast(i)])) + .angles[0]; if (this_theta != prev_theta) { std::vector discarded = {v_sort.begin(), v_sort.begin() + i}; std::vector kept = {v_sort.begin() + i, v_sort.end()}; @@ -436,8 +437,9 @@ auto NativeGateDecomposer::get_possible_moments( prev_theta = this_theta; mk_qubits.clear(); } - mk_qubits.insert( - std::get(circuit.get_Node_Value(v_sort[i])).qubit); + mk_qubits.insert(std::get( + circuit.get_Node_Value(v_sort[static_cast(i)])) + .qubit); } std::vector push_back_nodes = {}; std::set p_square_qubits = {}; @@ -511,7 +513,7 @@ auto NativeGateDecomposer::convert_circ_to_dag( DiGraph>>(); std::vector> qubit_paths(nQubits); // TODO:assert that One more sql exists than mql ?? - for (auto i = 0; i < schedule.second.size(); ++i) { + for (size_t i = 0; i < schedule.second.size(); ++i) { for (const auto& s : schedule.first.at(i)) { size_t node = graph.add_Node(s); qubit_paths.at(s.qubit).push_back(node); @@ -561,7 +563,7 @@ auto NativeGateDecomposer::sift( // We traverse the graph rather than v_rem to use the graph's topological // ordering - for (auto node = 0; node < circuit.size(); node++) { + for (size_t node = 0; node < circuit.size(); node++) { if (v_rem.contains(node)) { auto op = circuit.get_Node_Value(node); std::set op_qubits = std::set(); @@ -704,7 +706,9 @@ auto NativeGateDecomposer::schedule_remaining( auto new_node = add_node_to_sub_prob_graph(v[0], val.first[0], val.second, subproblem_graph, prev_node); temp_cost = schedule_remaining({val.first[1], val.first[2], val.first[3]}, - circuit, subproblem_graph, new_node, nQubits, check_final_cond, memo) + val.second; + circuit, subproblem_graph, new_node, nQubits, + check_final_cond, memo) + + val.second; if (temp_cost < min_cost) { min_cost = temp_cost; min_node = new_node; @@ -725,9 +729,10 @@ auto NativeGateDecomposer::schedule_theta_opt( // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? DiGraph>> circuit = convert_circ_to_dag(schedule, nQubits); - // TODO: Get initial Moments( Nott does MQB THEN SQB!! SOl to get SQB MQB??) - std::vector v_start = {}; - for (auto i = 0; i < circuit.size(); ++i) { + // TODO: Get initial Moments( Not does MQB THEN SQB!! SOl to get SQB MQB??) + std::vector v_start{}; + v_start.reserve(circuit.size()); + for (size_t i = 0; i < circuit.size(); ++i) { v_start.push_back(i); } // v=(v_p,v_c,v_r) From f801cb7df3aa9a7b9602f6c061384874ec6fc387 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:08:02 +0200 Subject: [PATCH 091/110] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20bindings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/register_zoned.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 9225a2680..46545a919 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -377,14 +377,14 @@ void registerZoned(nb::module_& m) { //===--------------------------------------------------------------------===// // Routing-aware Axial Compiler //===--------------------------------------------------------------------===// - nb::class_ routingAwareAxialCompiler( + nb::class_ routingAwareAxialCompiler( m, "routingAwareAxialCompiler", "Routing-aware axial zoned neutral atom compiler."); { - const na::zoned::routingAwareAxialCompiler::Config defaultConfig; + const na::zoned::RoutingAwareAxialCompiler::Config defaultConfig; routingAwareAxialCompiler.def( "__init__", - [](na::zoned::routingAwareAxialCompiler* self, + [](na::zoned::RoutingAwareAxialCompiler* self, const na::zoned::Architecture& arch, const std::string& logLevel, const double maxFillingFactor, const bool useWindow, const size_t windowMinWidth, const double windowRatio, @@ -396,7 +396,7 @@ void registerZoned(nb::module_& m) { const size_t queueCapacity, const na::zoned::IndependentSetRouter::Config::Method routingMethod, const double preferSplit, const bool warnUnsupportedGates) { - na::zoned::RoutingAwareNativeGateCompiler::Config config; + na::zoned::RoutingAwareAxialCompiler::Config config; config.logLevel = spdlog::level::from_str(logLevel); config.schedulerConfig.maxFillingFactor = maxFillingFactor; config.decomposerConfig = {}; @@ -418,14 +418,11 @@ void registerZoned(nb::module_& m) { .method = routingMethod, .preferSplit = preferSplit}; config.codeGeneratorConfig = {.warnUnsupportedGates = warnUnsupportedGates}; - new (self) na::zoned::routingAwareAxialCompiler{arch, config}; + new (self) na::zoned::RoutingAwareAxialCompiler{arch, config}; }, nb::keep_alive<1, 2>(), "arch"_a, "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, - "theta_opt_schedule"_a = - defaultConfig.decomposerConfig.theta_opt_schedule, - "check_final_cond"_a = defaultConfig.decomposerConfig.check_final_cond, "use_window"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, "window_min_width"_a = @@ -483,7 +480,7 @@ void registerZoned(nb::module_& m) { routingAwareAxialCompiler.def_static( "from_json_string", [](const na::zoned::Architecture& arch, - const std::string& json) -> na::zoned::routingAwareAxialCompiler { + const std::string& json) -> na::zoned::RoutingAwareAxialCompiler { // The correct header is included, but clang-tidy // confuses it with the wrong forward header // NOLINTNEXTLINE(misc-include-cleaner) @@ -504,7 +501,7 @@ void registerZoned(nb::module_& m) { routingAwareAxialCompiler.def( "compile", - [](na::zoned::routingAwareAxialCompiler& self, + [](na::zoned::RoutingAwareAxialCompiler& self, const qc::QuantumComputation& qc) -> std::string { return self.compile(qc).toString(); }, From eca1016af4698b4521faccd9ec72b1ac6e87866b Mon Sep 17 00:00:00 2001 From: ga96dup Date: Tue, 28 Apr 2026 14:42:20 +0200 Subject: [PATCH 092/110] Small change to the Decomposers to avoid adding global rotations by 0 in empty 1-qubit gate layers --- .../zoned/eval_native_gate_decomposition.py | 18 +++---- src/na/zoned/decomposer/AxialDecomposer.cpp | 47 ++++++++++--------- .../zoned/decomposer/NativeGateDecomposer.cpp | 47 ++++++++++--------- 3 files changed, 57 insertions(+), 55 deletions(-) diff --git a/eval/na/zoned/eval_native_gate_decomposition.py b/eval/na/zoned/eval_native_gate_decomposition.py index 4f09c7b76..48d60645e 100755 --- a/eval/na/zoned/eval_native_gate_decomposition.py +++ b/eval/na/zoned/eval_native_gate_decomposition.py @@ -40,7 +40,7 @@ from mqt.qmap.na.zoned import ( PlacementMethod, RoutingAwareCompiler, - RoutingAwareAxialCompiler, + # RoutingAwareAxialCompiler, RoutingAwareNativeGateCompiler, RoutingMethod, ZonedNeutralAtomArchitecture, @@ -658,7 +658,7 @@ def main() -> None: "warn_unsupported_gates": False, } baseline = RoutingAwareCompiler(arch, **common_config) - setting1 = RoutingAwareAxialCompiler(arch, **common_config) + #setting1 = RoutingAwareAxialCompiler(arch, **common_config) setting2 = RoutingAwareNativeGateCompiler(arch, **common_config) setting3 = RoutingAwareNativeGateCompiler(arch, **common_config, theta_opt_schedule=True) @@ -667,17 +667,17 @@ def main() -> None: pathlib.Path("in").mkdir(exist_ok=True) benchmark_list = [ - ("graphstate", (BenchmarkLevel.INDEP, [60, 100])), + ("graphstate", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), # ("graphstate", (BenchmarkLevel.INDEP, [60, 80, 100, 120, 140, 160, 180, 200, 500, 1000, 2000, 5000])), - ("qft", (BenchmarkLevel.INDEP, [100])), + ("qft", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), # ("qft", (BenchmarkLevel.INDEP, [500, 1000])), - ("qpeexact", (BenchmarkLevel.INDEP, [100])), + ("qpeexact", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), # ("qpeexact", (BenchmarkLevel.INDEP, [500, 1000])), - ("wstate", (BenchmarkLevel.INDEP, [100])), + ("wstate", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), # ("wstate", (BenchmarkLevel.INDEP, [500, 1000])), - ("qaoa", (BenchmarkLevel.INDEP, [50, 100])), + ("qaoa", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), # ("qaoa", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), - ("vqe_two_local", (BenchmarkLevel.INDEP, [50, 100])), + ("vqe_two_local", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), # ("vqe_two_local", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), ] @@ -686,7 +686,7 @@ def main() -> None: process_benchmark(baseline, "baseline", qc, benchmark, evaluator) # process_benchmark(setting1, "setting1", qc, benchmark, evaluator) process_benchmark(setting2, "setting2", qc, benchmark, evaluator) - process_benchmark(setting2, "setting3", qc, benchmark, evaluator) + process_benchmark(setting3, "setting3", qc, benchmark, evaluator) print( diff --git a/src/na/zoned/decomposer/AxialDecomposer.cpp b/src/na/zoned/decomposer/AxialDecomposer.cpp index 0e75c33c1..29ef183e3 100644 --- a/src/na/zoned/decomposer/AxialDecomposer.cpp +++ b/src/na/zoned/decomposer/AxialDecomposer.cpp @@ -166,7 +166,7 @@ auto AxialDecomposer::decompose( SingleQubitGateLayer FrontLayer; SingleQubitGateLayer MidLayer; SingleQubitGateLayer BackLayer; - SingleQubitGateLayer NewLayer; + SingleQubitGateLayer NewLayer = {}; for (auto gate : layer) { @@ -180,32 +180,33 @@ auto AxialDecomposer::decompose( BackLayer.emplace_back(std::make_unique( qc::StandardOperation(gate.qubit, qc::RZ, {gate.angles[2]}))); } // gate::layer + if (!layer.empty()) { + std::vector> GR_plus; + std::vector> GR_minus; + + for (size_t i = 0; i < nQubits; ++i) { + GR_plus.emplace_back(std::make_unique( + i, qc::RX, std::initializer_list{-qc::PI / 2})); + GR_minus.emplace_back(std::make_unique( + i, qc::RX, std::initializer_list{qc::PI / 2})); + } - std::vector> GR_plus; - std::vector> GR_minus; - - for (size_t i = 0; i < nQubits; ++i) { - GR_plus.emplace_back(std::make_unique( - i, qc::RX, std::initializer_list{-qc::PI / 2})); - GR_minus.emplace_back(std::make_unique( - i, qc::RX, std::initializer_list{qc::PI / 2})); - } - - for (auto&& gate : FrontLayer) { - NewLayer.push_back(std::move(gate)); - } + for (auto&& gate : FrontLayer) { + NewLayer.push_back(std::move(gate)); + } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_plus), true))); + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_plus), true))); - for (auto&& gate : MidLayer) { - NewLayer.push_back(std::move(gate)); - } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_minus), true))); + for (auto&& gate : MidLayer) { + NewLayer.push_back(std::move(gate)); + } + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_minus), true))); - for (auto&& gate : BackLayer) { - NewLayer.push_back(std::move(gate)); + for (auto&& gate : BackLayer) { + NewLayer.push_back(std::move(gate)); + } } NewSingleQubitLayers.push_back(std::move(NewLayer)); } // layer::SingleQubitLayers diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index e9d1f6313..a541d416b 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -226,7 +226,7 @@ auto NativeGateDecomposer::decompose( SingleQubitGateLayer FrontLayer; SingleQubitGateLayer MidLayer; SingleQubitGateLayer BackLayer; - SingleQubitGateLayer NewLayer; + SingleQubitGateLayer NewLayer = {}; for (auto gate : layer) { std::array decomp_angles = @@ -242,32 +242,33 @@ auto NativeGateDecomposer::decompose( BackLayer.emplace_back(std::make_unique( qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); } // gate::layer + if (!layer.empty()) { + std::vector> GR_plus; + std::vector> GR_minus; + + for (size_t i = 0; i < this->nQubits_; ++i) { + GR_plus.emplace_back(std::make_unique( + i, qc::RY, std::initializer_list{theta_max / 2})); + GR_minus.emplace_back(std::make_unique( + i, qc::RY, std::initializer_list{-1 * theta_max / 2})); + } - std::vector> GR_plus; - std::vector> GR_minus; - - for (size_t i = 0; i < this->nQubits_; ++i) { - GR_plus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{theta_max / 2})); - GR_minus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{-1 * theta_max / 2})); - } - - for (auto&& gate : FrontLayer) { - NewLayer.push_back(std::move(gate)); - } + for (auto&& gate : FrontLayer) { + NewLayer.push_back(std::move(gate)); + } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_plus), true))); + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_plus), true))); - for (auto&& gate : MidLayer) { - NewLayer.push_back(std::move(gate)); - } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_minus), true))); + for (auto&& gate : MidLayer) { + NewLayer.push_back(std::move(gate)); + } + NewLayer.emplace_back(std::make_unique( + qc::CompoundOperation(std::move(GR_minus), true))); - for (auto&& gate : BackLayer) { - NewLayer.push_back(std::move(gate)); + for (auto&& gate : BackLayer) { + NewLayer.push_back(std::move(gate)); + } } NewSingleQubitLayers.push_back(std::move(NewLayer)); } // layer::SingleQubitLayers From 69b47a37f6ca2d13b17a694b04548f5fce7d6d53 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Wed, 29 Apr 2026 16:16:05 +0200 Subject: [PATCH 093/110] =?UTF-8?q?=F0=9F=90=9B=20Fix=20binding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/register_zoned.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 46545a919..8e57a8f69 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -378,7 +378,7 @@ void registerZoned(nb::module_& m) { // Routing-aware Axial Compiler //===--------------------------------------------------------------------===// nb::class_ routingAwareAxialCompiler( - m, "routingAwareAxialCompiler", + m, "RoutingAwareAxialCompiler", "Routing-aware axial zoned neutral atom compiler."); { const na::zoned::RoutingAwareAxialCompiler::Config defaultConfig; From f7f7ae98b73d9ca61ed8ad6a9c749745a0c6e885 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:45:05 +0200 Subject: [PATCH 094/110] =?UTF-8?q?=F0=9F=8E=A8=20Looking=20for=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/register_zoned.cpp | 8 +-- .../zoned/decomposer/NativeGateDecomposer.hpp | 11 ++-- .../zoned/decomposer/NativeGateDecomposer.cpp | 8 ++- test/na/zoned/test_compiler.cpp | 29 +++++++++ test/na/zoned/test_theta_opt_scheduler.cpp | 59 ++++++++++++------- 5 files changed, 82 insertions(+), 33 deletions(-) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 8e57a8f69..033d63197 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -554,8 +554,8 @@ void registerZoned(nb::module_& m) { na::zoned::RoutingAwareNativeGateCompiler::Config config; config.logLevel = spdlog::level::from_str(logLevel); config.schedulerConfig.maxFillingFactor = maxFillingFactor; - config.decomposerConfig = {.theta_opt_schedule = thetaOptSchedule, - .check_final_cond = checkFinalCond}; + config.decomposerConfig = {.thetaOptSchedule = thetaOptSchedule, + .checkFinalCond = checkFinalCond}; config.layoutSynthesizerConfig.placerConfig = { .useWindow = useWindow, .windowMinWidth = windowMinWidth, @@ -580,8 +580,8 @@ void registerZoned(nb::module_& m) { "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, "theta_opt_schedule"_a = - defaultConfig.decomposerConfig.theta_opt_schedule, - "check_final_cond"_a = defaultConfig.decomposerConfig.check_final_cond, + defaultConfig.decomposerConfig.thetaOptSchedule, + "check_final_cond"_a = defaultConfig.decomposerConfig.checkFinalCond, "use_window"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, "window_min_width"_a = diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 58c66cdf4..2bf49001e 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -34,10 +34,10 @@ class NativeGateDecomposer : public DecomposerBase { public: /// The configuration of the NativeGateDecomposer struct Config { - bool theta_opt_schedule = false; - bool check_final_cond = false; - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, theta_opt_schedule, - check_final_cond); + bool thetaOptSchedule = false; + bool checkFinalCond = false; + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, thetaOptSchedule, + checkFinalCond); }; /** @@ -55,8 +55,7 @@ class NativeGateDecomposer : public DecomposerBase { public: /// Create a new NativeGateDecomposer. - NativeGateDecomposer(const Architecture& /* unused */, - const Config& /* unused */) {} + NativeGateDecomposer(const Architecture& /* unused */, const Config& config); /** * @brief Converts commonly used single qubit gates into their Quaternion diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index a541d416b..53160c515 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -19,6 +19,10 @@ namespace na::zoned { +NativeGateDecomposer::NativeGateDecomposer(const Architecture&, + const Config& config) { + config_ = config; +} auto NativeGateDecomposer::convertGateToQuaternion( std::reference_wrapper op) -> Quaternion { assert(op.get().getNqubits() == 1); @@ -212,7 +216,7 @@ auto NativeGateDecomposer::decompose( std::vector> U3Layers = transformToU3(schedule.first, nQubits); std::vector NewTwoQubitGateLayers = schedule.second; - if (config_.theta_opt_schedule) { + if (config_.thetaOptSchedule) { auto thetaOptSchedule = schedule_theta_opt(std::pair(U3Layers, NewTwoQubitGateLayers), nQubits); U3Layers = thetaOptSchedule.first; @@ -748,7 +752,7 @@ auto NativeGateDecomposer::schedule_theta_opt( std::map>> memo = {}; auto cost = schedule_remaining(v, circuit, sub_prob_graph, base_node, nQubits, - config_.check_final_cond, memo); + config_.checkFinalCond, memo); // TODO: Create Schedule from Subproblem Graph std::pair>, std::vector> final_circuit = build_schedule(circuit, sub_prob_graph); diff --git a/test/na/zoned/test_compiler.cpp b/test/na/zoned/test_compiler.cpp index 5a6f9ba91..f6288be3f 100644 --- a/test/na/zoned/test_compiler.cpp +++ b/test/na/zoned/test_compiler.cpp @@ -123,6 +123,33 @@ constexpr std::string_view fastRelaxedRoutingAwareConfiguration = R"({ } } })"; +constexpr std::string_view routingAwareNativeGateConfiguration = R"({ + "logLevel" : 1, + "codeGeneratorConfig" : { + "warnUnsupportedGates" : false + }, + "decomposerConfig" : { + "thetaOptSchedule" : true, + "checkFinalCond" : false + }, + "layoutSynthesizerConfig" : { + "placerConfig" : { + "useWindow" : true, + "windowMinWidth" : 4, + "windowRatio" : 1.5, + "windowShare" : 0.6, + "method" : "ids", + "deepeningFactor" : 0.01, + "deepeningValue" : 0.0, + "lookaheadFactor": 0.4, + "reuseLevel": 5.0 + }, + "routerConfig" : { + "method" : "relaxed", + "preferSplit" : 0.0 + } + } +})"; #define COMPILER_TEST(test_name, compiler_type, config) \ TEST(test_name##Test, ConstructorWithoutConfig) { \ Architecture architecture( \ @@ -188,6 +215,8 @@ COMPILER_TEST(FastRelaxedRoutingAwareCompiler, RoutingAwareCompiler, COMPILER_TEST(FastRelaxedRoutingAwareNativeGateCompiler, RoutingAwareNativeGateCompiler, fastRelaxedRoutingAwareConfiguration); +COMPILER_TEST(RoutingAwareNativeGateCompiler, RoutingAwareNativeGateCompiler, + routingAwareNativeGateConfiguration); // Tests that the bug described in issue // https://github.com/munich-quantum-toolkit/qmap/issues/727 is fixed. diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index 252c237e4..19e5365af 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + #include "ir/QuantumComputation.hpp" #include "na/zoned/decomposer/NativeGateDecomposer.hpp" #include "na/zoned/scheduler/ASAPScheduler.hpp" @@ -38,8 +48,8 @@ class ThetaOptTest : public ::testing::Test { Architecture architecture; ASAPScheduler::Config schedulerConfig{.maxFillingFactor = .8}; ASAPScheduler scheduler; - NativeGateDecomposer::Config decomposerConfig{.theta_opt_schedule = true, - .check_final_cond = false}; + NativeGateDecomposer::Config decomposerConfig{.thetaOptSchedule = true, + .checkFinalCond = false}; NativeGateDecomposer decomposer; ThetaOptTest() : architecture(Architecture::fromJSONString(architectureJson)), @@ -99,7 +109,8 @@ TEST_F(ThetaOptTest, GraphTest) { ::testing::ElementsAre( ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(0), epsilon), - ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(1), epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(1), + epsilon), ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(2), epsilon))); EXPECT_THAT(graph.get_adjacent(2), ::testing::IsEmpty()); @@ -110,10 +121,12 @@ TEST_F(ThetaOptTest, GraphTest) { EXPECT_THAT( std::get(graph.get_Node_Value(3)).angles, ::testing::ElementsAre( - ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(0), epsilon), + ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(0), + epsilon), ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(1), epsilon), - ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(2), epsilon))); + ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(2), + epsilon))); EXPECT_THAT(graph.get_adjacent(3), ::testing::IsEmpty()); } @@ -399,10 +412,9 @@ TEST_F(ThetaOptTest, RecursionBaseTest) { EXPECT_THAT(subproblem_graph.get_Node_Value(6).second, ::testing::UnorderedElementsAre(5, 6)); EXPECT_THAT(subproblem_graph.get_adjacent(6), - ::testing::UnorderedElementsAre(::testing::Pair(3,qc::PI_2))); + ::testing::UnorderedElementsAre(::testing::Pair(3, qc::PI_2))); } - TEST_F(ThetaOptTest, ShortestPathTest) { // Subproblem graph! NativeGateDecomposer::DiGraph< @@ -522,11 +534,12 @@ TEST_F(ThetaOptTest, BuildScheduleTest) { one_qubit_gates.at(2).at(1).angles[1], one_qubit_gates.at(2).at(1).angles[2])); - EXPECT_THAT(schedule.second.at(2).at(0),::testing::ElementsAre(0,2)); + EXPECT_THAT(schedule.second.at(2).at(0), ::testing::ElementsAre(0, 2)); - EXPECT_EQ(schedule.first.at(3).at(0).qubit,0); - EXPECT_THAT(schedule.first.at(3).at(0).angles,::testing::ElementsAre(one_qubit_gates.at(3).at(0).angles[0], - one_qubit_gates.at(3).at(0).angles[1], + EXPECT_EQ(schedule.first.at(3).at(0).qubit, 0); + EXPECT_THAT(schedule.first.at(3).at(0).angles, + ::testing::ElementsAre(one_qubit_gates.at(3).at(0).angles[0], + one_qubit_gates.at(3).at(0).angles[1], one_qubit_gates.at(3).at(0).angles[2])); } @@ -626,19 +639,23 @@ TEST_F(ThetaOptTest, CompleteTestSmall) { ::testing::ElementsAre( ::testing::DoubleNear(one_qubit_gates.at(2).at(1).angles[0], epsilon), ::testing::DoubleNear(one_qubit_gates.at(2).at(1).angles[1], epsilon), - ::testing::DoubleNear(one_qubit_gates.at(2).at(1).angles[2], epsilon))); - - EXPECT_THAT(theta_opt_schedule.second.at(2).front(),::testing::ElementsAre(0,2)); + ::testing::DoubleNear(one_qubit_gates.at(2).at(1).angles[2], + epsilon))); - EXPECT_EQ(theta_opt_schedule.first.at(3).at(0).qubit,0); - EXPECT_THAT(theta_opt_schedule.first.at(3).at(0).angles,::testing::ElementsAre( - ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[0], epsilon), - ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[1], epsilon), - ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[2], epsilon))); + EXPECT_THAT(theta_opt_schedule.second.at(2).front(), + ::testing::ElementsAre(0, 2)); + EXPECT_EQ(theta_opt_schedule.first.at(3).at(0).qubit, 0); + EXPECT_THAT( + theta_opt_schedule.first.at(3).at(0).angles, + ::testing::ElementsAre( + ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[0], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[1], epsilon), + ::testing::DoubleNear(one_qubit_gates.at(3).at(0).angles[2], + epsilon))); } TEST_F(ThetaOptTest, CompleteTestBig) { - //Circuit BIG + // Circuit BIG } -} // namespace na::zoned \ No newline at end of file +} // namespace na::zoned From 4a9398d94771ad8a6a95b8aa8bdcd6c40f46db0a Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 30 Apr 2026 21:34:19 +0200 Subject: [PATCH 095/110] Small fix in theta opt scheduler&Compiler --- include/na/zoned/Compiler.hpp | 9 ++++----- .../zoned/decomposer/NativeGateDecomposer.cpp | 12 +++++++----- test/na/zoned/test_theta_opt_scheduler.cpp | 17 ++++++++++++++++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index 482044e04..9ebebaf50 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -204,9 +204,8 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Decomposing..."); const auto decomposingStart = std::chrono::system_clock::now(); - const auto& decomposedSingleQubitGateLayers = - SELF.decompose(qComp.getNqubits(), schedule).first; - // TODO: How to deal with two Qubit layers + const auto& decomposedSchedule = + SELF.decompose(qComp.getNqubits(), schedule); const auto decomposingEnd = std::chrono::system_clock::now(); statistics_.decomposingTime = std::chrono::duration_cast(decomposingEnd - @@ -216,7 +215,7 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Analyzing reuse..."); const auto reuseAnalysisStart = std::chrono::system_clock::now(); - const auto& reuseQubits = SELF.analyzeReuse(twoQubitGateLayers); + const auto& reuseQubits = SELF.analyzeReuse(decomposedSchedule.second); const auto reuseAnalysisEnd = std::chrono::system_clock::now(); statistics_.reuseAnalysisTime = std::chrono::duration_cast( @@ -241,7 +240,7 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Generating code..."); const auto codeGenerationStart = std::chrono::system_clock::now(); NAComputation code = - SELF.generate(decomposedSingleQubitGateLayers, placement, routing); + SELF.generate(decomposedSchedule.first, placement, routing); const auto codeGenerationEnd = std::chrono::system_clock::now(); assert(code.validate().first); statistics_.codeGenerationTime = diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 53160c515..8c8cf4b6e 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -318,9 +318,7 @@ auto NativeGateDecomposer::shortest_path_to_start( -> std::pair, double> { std::vector, double>> possible_paths = {}; // Check if leaf nodes are reached - - // TODO: Check if Path cost takes into account edge weight from current node - // to next node!!! + // Base Case: for (auto edge : subproblem_graph.get_adjacent(current_node)) { if (leaf_nodes.contains(edge.first)) { possible_paths.push_back({std::pair, double>( @@ -337,7 +335,7 @@ auto NativeGateDecomposer::shortest_path_to_start( possible_paths.push_back(path); } } - // Base Case: + // Choose shortest Paths auto min_length = possible_paths.at(0).first.size(); std::vector, double>> shortest_paths = {}; @@ -688,7 +686,11 @@ auto NativeGateDecomposer::schedule_remaining( // TODO: Base Case-> V_rem is empty if (v[2].empty()) { // TODO:DEcide if I need if to check for TWO QUBIT - cost = std::get(circuit.get_Node_Value(v[1].at(0))).angles[0]; + if (v[1].empty()) { + cost = 0; + } else { + cost = std::get(circuit.get_Node_Value(v[1].at(0))).angles[0]; + } for (std::size_t i : v[1]) { if (std::get(circuit.get_Node_Value(i)).angles[0] > cost) { cost = std::get(circuit.get_Node_Value(i)).angles[0]; diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index 19e5365af..da26a81b5 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -655,7 +655,22 @@ TEST_F(ThetaOptTest, CompleteTestSmall) { epsilon))); } -TEST_F(ThetaOptTest, CompleteTestBig) { +TEST_F(ThetaOptTest, CompleteTest) { + qc::QuantumComputation qc(4); + qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); + qc.u(qc::PI_4, qc::PI_2, qc::PI_2, 1); + qc.u(qc::PI_2, qc::PI_2, qc::PI_2, 2); + qc.cz(1, 2); + qc.cz(2, 3); + // qc.cz(0,1); + qc.u(qc::PI_2, qc::PI_4, qc::PI_2, 2); + qc.u(qc::PI_2, qc::PI_2, qc::PI_4, 3); + qc.cz(2, 3); + qc.u(qc::PI, qc::PI_2, qc::PI_4, 2); + auto schedule = scheduler.schedule(qc); + auto res = decomposer.decompose(4, schedule); // Circuit BIG + EXPECT_EQ(res.first.size(), 4); + } } // namespace na::zoned From 8e08a7063d4ef98a0dc7851c77dc7ef46750a58c Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 30 Apr 2026 22:12:41 +0200 Subject: [PATCH 096/110] Changed shortest path to cheapest path to allow for last layer 2QGL's to be calculated correctly Added abs for cost calculation --- .../zoned/decomposer/NativeGateDecomposer.hpp | 12 ++-- .../zoned/decomposer/NativeGateDecomposer.cpp | 63 ++++++++----------- test/na/zoned/test_theta_opt_scheduler.cpp | 29 ++++----- 3 files changed, 45 insertions(+), 59 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 2bf49001e..3ed82652f 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -266,32 +266,32 @@ class NativeGateDecomposer : public DecomposerBase { size_t nQubits) -> DiGraph>>; /** - * @brief Recursively finds the shortest path to the start node of the + * @brief Recursively finds the cheapest path to the start node of the * subproblem graph from a set of leaf nodes. * @details * @param subproblem_graph the subproblem graph to find the path in * @param current_node the node of the current function call * @param leaf_nodes a set of nodes with no outgoing edges (aka. leaf nodes) - * @returns a pair made up of a vector of the indices making up the shortest + * @returns a pair made up of a vector of the indices making up the cheapest * path and the path's total cost (the sum of the maximal theta angles * of each moment) */ - static auto shortest_path_to_start( + static auto cheapest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, std::size_t current_node, const std::set& leaf_nodes) -> std::pair, double>; /** - * @brief Finds the shortest (fewest edges) and cheapest (lowest cost) path + * @brief Finds the cheapest (lowest cost) path * from the start node to a leaf node in a subproblem_graph * @details * @param subproblem_graph the subproblem graph * @param path a vector containing the indices of all leaf nodes of the graph - * @returns a vector containing the node inidces of the shortest path through + * @returns a vector containing the node inidces of the cheapest path through * the graph */ - static auto find_shortest_path( + static auto find_cheapest_path( const DiGraph, std::vector>>& subproblem_graph, const std::vector& path) -> std::vector; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 8c8cf4b6e..0c1783544 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -279,14 +279,14 @@ auto NativeGateDecomposer::decompose( return {std::move(NewSingleQubitLayers), NewTwoQubitGateLayers}; } -auto NativeGateDecomposer::find_shortest_path( +auto NativeGateDecomposer::find_cheapest_path( const DiGraph, std::vector>>& subproblem_graph, const std::vector& leaf_nodes) -> std::vector { std::set leaves = std::set(leaf_nodes.begin(), leaf_nodes.end()); std::pair, double> leaf_path = - shortest_path_to_start(subproblem_graph, 0, leaves); + cheapest_path_to_start(subproblem_graph, 0, leaves); std::ranges::reverse(leaf_path.first); return {leaf_path.first.begin() + 1, leaf_path.first.end()}; @@ -311,7 +311,7 @@ auto disjunct(const std::set& set1, const std::set& set2) return true; } -auto NativeGateDecomposer::shortest_path_to_start( +auto NativeGateDecomposer::cheapest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, std::size_t current_node, const std::set& leaf_nodes) @@ -329,33 +329,21 @@ auto NativeGateDecomposer::shortest_path_to_start( if (possible_paths.empty()) { for (auto edge : subproblem_graph.get_adjacent(current_node)) { auto path = - shortest_path_to_start(subproblem_graph, edge.first, leaf_nodes); + cheapest_path_to_start(subproblem_graph, edge.first, leaf_nodes); path.first.push_back(current_node); path.second += edge.second; possible_paths.push_back(path); } } - // Choose shortest Paths - auto min_length = possible_paths.at(0).first.size(); - std::vector, double>> shortest_paths = {}; - for (const auto& key : possible_paths | std::views::keys) { - if (key.size() < min_length) { - min_length = key.size(); - } - } - for (const auto& path : possible_paths) { - if (path.first.size() == min_length) { - shortest_paths.push_back(path); - } - } - if (shortest_paths.size() == 1) { - return shortest_paths.at(0); + // Choose cheapest Paths + if (possible_paths.size() == 1) { + return possible_paths.at(0); } // Find shortest path with minimal cost - auto min_cost = shortest_paths.at(0).second; - auto best_path = shortest_paths.at(0); - for (const auto& path : shortest_paths) { + auto min_cost = possible_paths.at(0).second; + auto best_path = possible_paths.at(0); + for (const auto& path : possible_paths) { if (path.second < min_cost) { min_cost = path.second; best_path = path; @@ -412,24 +400,24 @@ auto NativeGateDecomposer::get_possible_moments( // Sort v_0C from highest to lowest theta std::vector v_sort(v0_c); auto sort_by_theta = [&circuit](std::size_t a, std::size_t b) -> bool { - // TODO: IF CHECK??? - return std::get(circuit.get_Node_Value(a)).angles[0] > - std::get(circuit.get_Node_Value(b)).angles[0]; + return std::fabs(std::get(circuit.get_Node_Value(a)).angles[0]) > + std::fabs(std::get(circuit.get_Node_Value(b)).angles[0]); }; std::ranges::sort(v_sort, sort_by_theta); // TODO: Check Condition 1 std::vector, 2>, std::pair, qc::fp>>> potential_arg = {}; - auto prev_theta = - std::get(circuit.get_Node_Value(v_sort[0])).angles[0]; + auto prev_theta = std::fabs( + std::get(circuit.get_Node_Value(v_sort[0])).angles[0]); auto this_theta = prev_theta; std::set mk_qubits = { std::get(circuit.get_Node_Value(v_sort[0])).qubit}; for (auto i = 0; static_cast(i) < v_sort.size(); i++) { - this_theta = std::get( - circuit.get_Node_Value(v_sort[static_cast(i)])) - .angles[0]; + this_theta = + std::fabs(std::get( + circuit.get_Node_Value(v_sort[static_cast(i)])) + .angles[0]); if (this_theta != prev_theta) { std::vector discarded = {v_sort.begin(), v_sort.begin() + i}; std::vector kept = {v_sort.begin() + i, v_sort.end()}; @@ -546,9 +534,10 @@ auto NativeGateDecomposer::max_theta( const std::vector& nodes) -> qc::fp { qc::fp max_cost = 0; for (const auto node : nodes) { - if (std::get(circuit.get_Node_Value(node)).angles[0] >= + if (std::fabs(std::get(circuit.get_Node_Value(node)).angles[0]) >= max_cost) { - max_cost = std::get(circuit.get_Node_Value(node)).angles[0]; + max_cost = + std::fabs(std::get(circuit.get_Node_Value(node)).angles[0]); } } return max_cost; @@ -603,12 +592,10 @@ auto NativeGateDecomposer::build_schedule( std::vector leaf_nodes = find_leaf_nodes(subproblem_graph); std::vector minimal_path = - find_shortest_path(subproblem_graph, leaf_nodes); + find_cheapest_path(subproblem_graph, leaf_nodes); std::pair>, std::vector> schedule = std::pair>, std::vector>{}; - // !!!!TODO:ADD in the check that makes sure SQGL's sandwich schedule: If 1st - // v_p empty skip adding it . If not add empty SQGL std::vector singleQubitGates; std::vector> twoQubitGates; @@ -689,11 +676,13 @@ auto NativeGateDecomposer::schedule_remaining( if (v[1].empty()) { cost = 0; } else { - cost = std::get(circuit.get_Node_Value(v[1].at(0))).angles[0]; + cost = std::fabs( + std::get(circuit.get_Node_Value(v[1].at(0))).angles[0]); } for (std::size_t i : v[1]) { if (std::get(circuit.get_Node_Value(i)).angles[0] > cost) { - cost = std::get(circuit.get_Node_Value(i)).angles[0]; + cost = + std::fabs(std::get(circuit.get_Node_Value(i)).angles[0]); } } auto end_node = add_node_to_sub_prob_graph(v[0], v[1], cost, diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index da26a81b5..f5c54ed1a 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -280,18 +280,18 @@ TEST_F(ThetaOptTest, NextMomentsCond2Test) { TEST_F(ThetaOptTest, NextMomentsCond3Test) { // Circuit - // ┌─────────────────┐ ┌───────┐ - // q_0: ──┤ U(PI,Pi/2,PI/4) ├─────────■───┤ X ├─────■──── - // └─────────────────┘ │ └───────┘ │ - // │ ┌───────┐ │ - // q_1: ──────────────────────────■───■───┤ Y ├─────│──── - // │ └───────┘ │ - // ┌───────────────────┐ │ │ - // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■─────────────────────■──── + // ┌──────────────────┐ ┌───────┐ + // q_0: ──┤ U(-PI,Pi/2,PI/4) ├─────────■───┤ X ├─────■──── + // └──────────────────┘ │ └───────┘ │ + // │ ┌───────┐ │ + // q_1: ──────────────────────────■────■───┤ Y ├─────│──── + // │ └───────┘ │ + // ┌───────────────────┐ │ │ + // q_2: ──┤ U(PI/4,PI/4,PI/4) ├───■──────────────────────■──── // └───────────────────┘ size_t n = 3; qc::QuantumComputation qc(n); - qc.u(qc::PI, qc::PI_2, qc::PI_4, 0); + qc.u(-qc::PI, qc::PI_2, qc::PI_4, 0); qc.u(qc::PI_4, qc::PI_4, qc::PI_4, 2); qc.cz(1, 2); qc.cz(0, 1); @@ -321,7 +321,6 @@ TEST_F(ThetaOptTest, NextMomentsCond3Test) { EXPECT_THAT(moments[0].first[3], ::testing::UnorderedElementsAre(6)); } -// COND4 Test?? TEST_F(ThetaOptTest, RecursionBaseTest) { // Circuit @@ -415,7 +414,7 @@ TEST_F(ThetaOptTest, RecursionBaseTest) { ::testing::UnorderedElementsAre(::testing::Pair(3, qc::PI_2))); } -TEST_F(ThetaOptTest, ShortestPathTest) { +TEST_F(ThetaOptTest, CheapestPathTest) { // Subproblem graph! NativeGateDecomposer::DiGraph< std::pair, std::vector>> @@ -440,7 +439,7 @@ TEST_F(ThetaOptTest, ShortestPathTest) { subproblem_graph.add_Edge(11, 13); auto leaf_nodes = NativeGateDecomposer::find_leaf_nodes(subproblem_graph); auto path = - NativeGateDecomposer::find_shortest_path(subproblem_graph, leaf_nodes); + NativeGateDecomposer::find_cheapest_path(subproblem_graph, leaf_nodes); EXPECT_THAT(leaf_nodes, ::testing::ElementsAre(9, 10, 12, 13)); EXPECT_THAT(path, ::testing::ElementsAre(3, 6, 10)); } @@ -662,15 +661,13 @@ TEST_F(ThetaOptTest, CompleteTest) { qc.u(qc::PI_2, qc::PI_2, qc::PI_2, 2); qc.cz(1, 2); qc.cz(2, 3); - // qc.cz(0,1); + qc.cz(0, 1); qc.u(qc::PI_2, qc::PI_4, qc::PI_2, 2); qc.u(qc::PI_2, qc::PI_2, qc::PI_4, 3); qc.cz(2, 3); qc.u(qc::PI, qc::PI_2, qc::PI_4, 2); auto schedule = scheduler.schedule(qc); auto res = decomposer.decompose(4, schedule); - // Circuit BIG - EXPECT_EQ(res.first.size(), 4); - + EXPECT_EQ(res.first.size(), 5); } } // namespace na::zoned From 83a3253d37b5449124fcf995e2b23ce5a56ee9bc Mon Sep 17 00:00:00 2001 From: ga96dup Date: Thu, 30 Apr 2026 22:55:39 +0200 Subject: [PATCH 097/110] chnage to proper layers in compiler --- include/na/zoned/Compiler.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index 9ebebaf50..deb13fe9c 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -226,7 +226,7 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Synthesizing layout..."); const auto layoutSynthesisStart = std::chrono::system_clock::now(); const auto& [placement, routing] = LayoutSynthesizer::synthesize( - qComp.getNqubits(), twoQubitGateLayers, reuseQubits); + qComp.getNqubits(), decomposedSchedule.second, reuseQubits); const auto layoutSynthesisEnd = std::chrono::system_clock::now(); statistics_.layoutSynthesisTime = std::chrono::duration_cast( From a6ed9505fdecf86d773885eba5187df9c3e07302 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Fri, 1 May 2026 16:16:39 +0200 Subject: [PATCH 098/110] Added memo element to recursive function looking for path --- .../zoned/decomposer/NativeGateDecomposer.hpp | 4 ++- .../zoned/decomposer/NativeGateDecomposer.cpp | 31 ++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 3ed82652f..be5fbc2ef 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -272,6 +272,7 @@ class NativeGateDecomposer : public DecomposerBase { * @param subproblem_graph the subproblem graph to find the path in * @param current_node the node of the current function call * @param leaf_nodes a set of nodes with no outgoing edges (aka. leaf nodes) + * @param memo * @returns a pair made up of a vector of the indices making up the cheapest * path and the path's total cost (the sum of the maximal theta angles * of each moment) @@ -279,7 +280,8 @@ class NativeGateDecomposer : public DecomposerBase { static auto cheapest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, - std::size_t current_node, const std::set& leaf_nodes) + size_t current_node, const std::set& leaf_nodes, + std::map, qc::fp>>& memo) -> std::pair, double>; /** diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 0c1783544..b29d0c44c 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -13,6 +13,7 @@ #include "ir/operations/CompoundOperation.hpp" #include "ir/operations/Operation.hpp" #include "ir/operations/StandardOperation.hpp" +#include "spdlog/spdlog.h" #include #include @@ -216,6 +217,7 @@ auto NativeGateDecomposer::decompose( std::vector> U3Layers = transformToU3(schedule.first, nQubits); std::vector NewTwoQubitGateLayers = schedule.second; + if (config_.thetaOptSchedule) { auto thetaOptSchedule = schedule_theta_opt(std::pair(U3Layers, NewTwoQubitGateLayers), nQubits); @@ -285,8 +287,10 @@ auto NativeGateDecomposer::find_cheapest_path( const std::vector& leaf_nodes) -> std::vector { std::set leaves = std::set(leaf_nodes.begin(), leaf_nodes.end()); + // Memory Map : Subprob NOdes as keys + std::map, qc::fp>> memo = {}; std::pair, double> leaf_path = - cheapest_path_to_start(subproblem_graph, 0, leaves); + cheapest_path_to_start(subproblem_graph, 0, leaves, memo); std::ranges::reverse(leaf_path.first); return {leaf_path.first.begin() + 1, leaf_path.first.end()}; @@ -314,10 +318,15 @@ auto disjunct(const std::set& set1, const std::set& set2) auto NativeGateDecomposer::cheapest_path_to_start( const DiGraph, std::vector>>& subproblem_graph, - std::size_t current_node, const std::set& leaf_nodes) + std::size_t current_node, const std::set& leaf_nodes, + std::map, qc::fp>>& memo) -> std::pair, double> { std::vector, double>> possible_paths = {}; // Check if leaf nodes are reached + if (memo.contains(current_node)) { + return memo.at(current_node); + } + // Base Case: for (auto edge : subproblem_graph.get_adjacent(current_node)) { if (leaf_nodes.contains(edge.first)) { @@ -328,11 +337,16 @@ auto NativeGateDecomposer::cheapest_path_to_start( // Recursive Case if (possible_paths.empty()) { for (auto edge : subproblem_graph.get_adjacent(current_node)) { - auto path = - cheapest_path_to_start(subproblem_graph, edge.first, leaf_nodes); + auto path = cheapest_path_to_start(subproblem_graph, edge.first, + leaf_nodes, memo); + // Check if current node is already in path. If so don't add + // std::set path_nodes=std::set(path.first.begin(), + // path.first.end()); + // if (!path_nodes.contains(current_node)) { path.first.push_back(current_node); path.second += edge.second; possible_paths.push_back(path); + // } } } @@ -349,6 +363,7 @@ auto NativeGateDecomposer::cheapest_path_to_start( best_path = path; } } + memo[current_node] = best_path; return best_path; } @@ -516,14 +531,16 @@ auto NativeGateDecomposer::convert_circ_to_dag( qubit_paths.at(gate[1]).push_back(node); } } + SPDLOG_DEBUG("Added Nodes"); for (const auto& s : schedule.first.back()) { size_t node = graph.add_Node(s); qubit_paths.at(s.qubit).push_back(node); } - for (std::size_t i = 0; i < qubit_paths.size(); ++i) { - for (std::size_t op = 0; op < qubit_paths.at(i).size() - 1; ++op) { - graph.add_Edge(qubit_paths.at(i).at(op), qubit_paths.at(i).at(op + 1)); + if (qubit_paths.at(i).size() > 0) { + for (std::size_t op = 0; op < (qubit_paths.at(i).size() - 1); ++op) { + graph.add_Edge(qubit_paths.at(i).at(op), qubit_paths.at(i).at(op + 1)); + } } } return graph; From 24ffd9d8e0f79cb4611c25b6fe00bb56a2ad1085 Mon Sep 17 00:00:00 2001 From: ga96dup Date: Fri, 29 May 2026 13:42:40 +0200 Subject: [PATCH 099/110] Axial- unneeded Chages to bindings --- bindings/na/register_zoned.cpp | 2 +- include/na/zoned/decomposer/AxialDecomposer.hpp | 2 +- src/na/zoned/decomposer/AxialDecomposer.cpp | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 033d63197..16a530895 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -516,7 +516,7 @@ void registerZoned(nb::module_& m) { routingAwareAxialCompiler.def( "stats", - [](const na::zoned::RoutingAwareNativeGateCompiler& self) { + [](const na::zoned::RoutingAwareAxialCompiler& self) { const auto json = nb::module_::import_("json"); const auto loads = json.attr("loads"); const nlohmann::json stats = self.getStatistics(); diff --git a/include/na/zoned/decomposer/AxialDecomposer.hpp b/include/na/zoned/decomposer/AxialDecomposer.hpp index 9a57f5e51..e72a0498c 100644 --- a/include/na/zoned/decomposer/AxialDecomposer.hpp +++ b/include/na/zoned/decomposer/AxialDecomposer.hpp @@ -28,7 +28,7 @@ class AxialDecomposer : public DecomposerBase { std::numeric_limits::epsilon() * 1024; public: - /// The configuration of the NativeGateDecomposer + /// The configuration of the AxialDecomposer struct Config { template friend void to_json(BasicJsonType& /* unused */, diff --git a/src/na/zoned/decomposer/AxialDecomposer.cpp b/src/na/zoned/decomposer/AxialDecomposer.cpp index 29ef183e3..08a958a7d 100644 --- a/src/na/zoned/decomposer/AxialDecomposer.cpp +++ b/src/na/zoned/decomposer/AxialDecomposer.cpp @@ -185,10 +185,11 @@ auto AxialDecomposer::decompose( std::vector> GR_minus; for (size_t i = 0; i < nQubits; ++i) { + // Should be X_Rotations GR_plus.emplace_back(std::make_unique( - i, qc::RX, std::initializer_list{-qc::PI / 2})); + i, qc::RY, std::initializer_list{-qc::PI / 2})); GR_minus.emplace_back(std::make_unique( - i, qc::RX, std::initializer_list{qc::PI / 2})); + i, qc::RY, std::initializer_list{qc::PI / 2})); } for (auto&& gate : FrontLayer) { From d17021bce584da4e3db39a91d6a2d81c019814e9 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 10:56:50 +0200 Subject: [PATCH 100/110] =?UTF-8?q?=E2=8F=AA=EF=B8=8F=20Revert=20cmake=20s?= =?UTF-8?q?etup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/CMakeLists.txt | 6 +- bindings/clifford_synthesis/CMakeLists.txt | 2 +- bindings/na/CMakeLists.txt | 3 +- bindings/na/na.cpp | 6 +- bindings/na/register_zoned.cpp | 316 --------------------- bindings/sc/CMakeLists.txt | 2 +- cmake/ExternalDependencies.cmake | 16 +- pyproject.toml | 6 +- 8 files changed, 19 insertions(+), 338 deletions(-) diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index c41a2d3c3..ba7af1ee3 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -26,7 +26,7 @@ list( ${BASEPOINT}/../../core/lib64) # add all modules -#add_subdirectory(clifford_synthesis) -#add_subdirectory(hybrid_mapper) +add_subdirectory(clifford_synthesis) +add_subdirectory(hybrid_mapper) add_subdirectory(na) -# add_subdirectory(sc) +add_subdirectory(sc) diff --git a/bindings/clifford_synthesis/CMakeLists.txt b/bindings/clifford_synthesis/CMakeLists.txt index 71e07c5aa..1f84d93c4 100644 --- a/bindings/clifford_synthesis/CMakeLists.txt +++ b/bindings/clifford_synthesis/CMakeLists.txt @@ -15,7 +15,7 @@ add_mqt_python_binding_nanobind( INSTALL_DIR . LINK_LIBS - #MQT::QMapCliffordSynthesis + MQT::QMapCliffordSynthesis MQT::CoreQASM) # install the Python stub files in editable mode for better IDE support diff --git a/bindings/na/CMakeLists.txt b/bindings/na/CMakeLists.txt index 043bc85a1..71edf5450 100644 --- a/bindings/na/CMakeLists.txt +++ b/bindings/na/CMakeLists.txt @@ -6,7 +6,7 @@ # # Licensed under the MIT License -file(GLOB_RECURSE NA_SOURCES na.cpp register_zoned.cpp) +file(GLOB_RECURSE NA_SOURCES **.cpp) add_mqt_python_binding_nanobind( QMAP @@ -17,6 +17,7 @@ add_mqt_python_binding_nanobind( INSTALL_DIR . LINK_LIBS + MQT::NASP MQT::QMapNAZoned MQT::CoreQASM) diff --git a/bindings/na/na.cpp b/bindings/na/na.cpp index d0cd73dee..6d052b9d6 100644 --- a/bindings/na/na.cpp +++ b/bindings/na/na.cpp @@ -13,12 +13,12 @@ namespace nb = nanobind; // forward declarations -// void registerStatePreparation(nb::module_& m); +void registerStatePreparation(nb::module_& m); void registerZoned(nb::module_& m); NB_MODULE(MQT_QMAP_MODULE_NAME, m) { - // auto statePreparation = m.def_submodule("state_preparation"); - // registerStatePreparation(statePreparation); + auto statePreparation = m.def_submodule("state_preparation"); + registerStatePreparation(statePreparation); auto zoned = m.def_submodule("zoned"); registerZoned(zoned); diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 16a530895..272575cd2 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -371,322 +371,6 @@ void registerZoned(nb::module_& m) { }, R"pb(Get the statistics of the last compilation. -Returns: - The statistics as a dictionary)pb"); - - //===--------------------------------------------------------------------===// - // Routing-aware Axial Compiler - //===--------------------------------------------------------------------===// - nb::class_ routingAwareAxialCompiler( - m, "RoutingAwareAxialCompiler", - "Routing-aware axial zoned neutral atom compiler."); - { - const na::zoned::RoutingAwareAxialCompiler::Config defaultConfig; - routingAwareAxialCompiler.def( - "__init__", - [](na::zoned::RoutingAwareAxialCompiler* self, - const na::zoned::Architecture& arch, const std::string& logLevel, - const double maxFillingFactor, const bool useWindow, - const size_t windowMinWidth, const double windowRatio, - const double windowShare, - const na::zoned::HeuristicPlacer::Config::Method placementMethod, - const float deepeningFactor, const float deepeningValue, - const float lookaheadFactor, const float reuseLevel, - const size_t maxNodes, const size_t trials, - const size_t queueCapacity, - const na::zoned::IndependentSetRouter::Config::Method routingMethod, - const double preferSplit, const bool warnUnsupportedGates) { - na::zoned::RoutingAwareAxialCompiler::Config config; - config.logLevel = spdlog::level::from_str(logLevel); - config.schedulerConfig.maxFillingFactor = maxFillingFactor; - config.decomposerConfig = {}; - config.layoutSynthesizerConfig.placerConfig = { - .useWindow = useWindow, - .windowMinWidth = windowMinWidth, - .windowRatio = windowRatio, - .windowShare = windowShare, - .method = placementMethod, - .deepeningFactor = deepeningFactor, - .deepeningValue = deepeningValue, - .lookaheadFactor = lookaheadFactor, - .reuseLevel = reuseLevel, - .maxNodes = maxNodes, - .trials = trials, - .queueCapacity = queueCapacity, - }; - config.layoutSynthesizerConfig.routerConfig = { - .method = routingMethod, .preferSplit = preferSplit}; - config.codeGeneratorConfig = {.warnUnsupportedGates = - warnUnsupportedGates}; - new (self) na::zoned::RoutingAwareAxialCompiler{arch, config}; - }, - nb::keep_alive<1, 2>(), "arch"_a, - "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), - "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, - "use_window"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, - "window_min_width"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, - "window_ratio"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, - "window_share"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, - "placement_method"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.method, - "deepening_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, - "deepening_value"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, - "lookahead_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, - "reuse_level"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, - "max_nodes"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, - "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, - "queue_capacity"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, - "routing_method"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.method, - "prefer_split"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, - "warn_unsupported_gates"_a = - defaultConfig.codeGeneratorConfig.warnUnsupportedGates, - R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. -Args: - arch: The zoned neutral atom architecture - log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" - max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel - use_window: Whether to use a window for the placer - window_min_width: The minimum width of the window for the placer - window_ratio: The ratio between the height and the width of the window - window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step - placement_method: The placement method that should be used for the heuristic placer - deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation - deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` - lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer - reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone - max_nodes: The maximum number of nodes that are considered in the A* search. - If this number is exceeded, the search is aborted and an error is raised. - In the current implementation, one node roughly consumes 120 Byte. - Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. - trials: The number of restarts during IDS. - queue_capacity: The maximum capacity of the priority queue used during IDS. - routing_method: The routing method that should be used for the independent set router - prefer_split: The threshold factor for group merging decisions during routing. - warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); - } - - routingAwareAxialCompiler.def_static( - "from_json_string", - [](const na::zoned::Architecture& arch, - const std::string& json) -> na::zoned::RoutingAwareAxialCompiler { - // The correct header is included, but clang-tidy - // confuses it with the wrong forward header - // NOLINTNEXTLINE(misc-include-cleaner) - return {arch, nlohmann::json::parse(json)}; - }, - "arch"_a, "json"_a, - R"pb(Create a compiler for the given architecture and configurations from a JSON string. - - Args: - arch: The zoned neutral atom architecture - json: The JSON string - -Returns: - The initialized compiler - -Raises: - ValueError: If the string is not a valid JSON string)pb"); - - routingAwareAxialCompiler.def( - "compile", - [](na::zoned::RoutingAwareAxialCompiler& self, - const qc::QuantumComputation& qc) -> std::string { - return self.compile(qc).toString(); - }, - "qc"_a, - R"pb(Compile a quantum circuit for the zoned neutral atom architecture. - -Args: - qc: The quantum circuit - -Returns: - The compilation result as a string in the .naviz format.)pb"); - - routingAwareAxialCompiler.def( - "stats", - [](const na::zoned::RoutingAwareAxialCompiler& self) { - const auto json = nb::module_::import_("json"); - const auto loads = json.attr("loads"); - const nlohmann::json stats = self.getStatistics(); - const auto dict = loads(stats.dump()); - return nb::cast>(dict); - }, - R"pb(Get the statistics of the last compilation. - Returns: - The statistics as a dictionary)pb"); - - //===--------------------------------------------------------------------===// - // Routing-aware Native Gate Compiler - //===--------------------------------------------------------------------===// - nb::class_ - routingAwareNativeGateCompiler( - m, "RoutingAwareNativeGateCompiler", - "Routing-aware native gate zoned neutral atom compiler."); - { - const na::zoned::RoutingAwareNativeGateCompiler::Config defaultConfig; - routingAwareNativeGateCompiler.def( - "__init__", - [](na::zoned::RoutingAwareNativeGateCompiler* self, - const na::zoned::Architecture& arch, const std::string& logLevel, - const double maxFillingFactor, const bool thetaOptSchedule, - const bool checkFinalCond, const bool useWindow, - const size_t windowMinWidth, const double windowRatio, - const double windowShare, - const na::zoned::HeuristicPlacer::Config::Method placementMethod, - const float deepeningFactor, const float deepeningValue, - const float lookaheadFactor, const float reuseLevel, - const size_t maxNodes, const size_t trials, - const size_t queueCapacity, - const na::zoned::IndependentSetRouter::Config::Method routingMethod, - const double preferSplit, const bool warnUnsupportedGates) { - na::zoned::RoutingAwareNativeGateCompiler::Config config; - config.logLevel = spdlog::level::from_str(logLevel); - config.schedulerConfig.maxFillingFactor = maxFillingFactor; - config.decomposerConfig = {.thetaOptSchedule = thetaOptSchedule, - .checkFinalCond = checkFinalCond}; - config.layoutSynthesizerConfig.placerConfig = { - .useWindow = useWindow, - .windowMinWidth = windowMinWidth, - .windowRatio = windowRatio, - .windowShare = windowShare, - .method = placementMethod, - .deepeningFactor = deepeningFactor, - .deepeningValue = deepeningValue, - .lookaheadFactor = lookaheadFactor, - .reuseLevel = reuseLevel, - .maxNodes = maxNodes, - .trials = trials, - .queueCapacity = queueCapacity, - }; - config.layoutSynthesizerConfig.routerConfig = { - .method = routingMethod, .preferSplit = preferSplit}; - config.codeGeneratorConfig = {.warnUnsupportedGates = - warnUnsupportedGates}; - new (self) na::zoned::RoutingAwareNativeGateCompiler{arch, config}; - }, - nb::keep_alive<1, 2>(), "arch"_a, - "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), - "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, - "theta_opt_schedule"_a = - defaultConfig.decomposerConfig.thetaOptSchedule, - "check_final_cond"_a = defaultConfig.decomposerConfig.checkFinalCond, - "use_window"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, - "window_min_width"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, - "window_ratio"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, - "window_share"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, - "placement_method"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.method, - "deepening_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, - "deepening_value"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, - "lookahead_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, - "reuse_level"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, - "max_nodes"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, - "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, - "queue_capacity"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, - "routing_method"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.method, - "prefer_split"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, - "warn_unsupported_gates"_a = - defaultConfig.codeGeneratorConfig.warnUnsupportedGates, - R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. - -Args: - arch: The zoned neutral atom architecture - log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" - max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel - theta_opt_schedule: TODO - check_final_cond: TODO - use_window: Whether to use a window for the placer - window_min_width: The minimum width of the window for the placer - window_ratio: The ratio between the height and the width of the window - window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step - placement_method: The placement method that should be used for the heuristic placer - deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation - deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` - lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer - reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone - max_nodes: The maximum number of nodes that are considered in the A* search. - If this number is exceeded, the search is aborted and an error is raised. - In the current implementation, one node roughly consumes 120 Byte. - Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. - trials: The number of restarts during IDS. - queue_capacity: The maximum capacity of the priority queue used during IDS. - routing_method: The routing method that should be used for the independent set router - prefer_split: The threshold factor for group merging decisions during routing. - warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); - } - - routingAwareNativeGateCompiler.def_static( - "from_json_string", - [](const na::zoned::Architecture& arch, - const std::string& json) -> na::zoned::RoutingAwareNativeGateCompiler { - // The correct header is included, but clang-tidy - // confuses it with the wrong forward header - // NOLINTNEXTLINE(misc-include-cleaner) - return {arch, nlohmann::json::parse(json)}; - }, - "arch"_a, "json"_a, - R"pb(Create a compiler for the given architecture and configurations from a JSON string. - -Args: - arch: The zoned neutral atom architecture - json: The JSON string - -Returns: - The initialized compiler - -Raises: - ValueError: If the string is not a valid JSON string)pb"); - - routingAwareNativeGateCompiler.def( - "compile", - [](na::zoned::RoutingAwareNativeGateCompiler& self, - const qc::QuantumComputation& qc) -> std::string { - return self.compile(qc).toString(); - }, - "qc"_a, - R"pb(Compile a quantum circuit for the zoned neutral atom architecture. - -Args: - qc: The quantum circuit - -Returns: - The compilation result as a string in the .naviz format.)pb"); - - routingAwareNativeGateCompiler.def( - "stats", - [](const na::zoned::RoutingAwareNativeGateCompiler& self) { - const auto json = nb::module_::import_("json"); - const auto loads = json.attr("loads"); - const nlohmann::json stats = self.getStatistics(); - const auto dict = loads(stats.dump()); - return nb::cast>(dict); - }, - R"pb(Get the statistics of the last compilation. - Returns: The statistics as a dictionary)pb"); } diff --git a/bindings/sc/CMakeLists.txt b/bindings/sc/CMakeLists.txt index c97a72dc1..39475db47 100644 --- a/bindings/sc/CMakeLists.txt +++ b/bindings/sc/CMakeLists.txt @@ -15,7 +15,7 @@ add_mqt_python_binding_nanobind( INSTALL_DIR . LINK_LIBS - #MQT::QMapSCExact + MQT::QMapSCExact MQT::QMapSCHeuristic MQT::CoreQASM) diff --git a/cmake/ExternalDependencies.cmake b/cmake/ExternalDependencies.cmake index 53a1ef062..d41a4f566 100644 --- a/cmake/ExternalDependencies.cmake +++ b/cmake/ExternalDependencies.cmake @@ -12,8 +12,12 @@ include(CMakeDependentOption) include(FetchContent) set(FETCH_PACKAGES "") -# FetchContent_Declare(Z3 GIT_REPOSITORY https://github.com/Z3Prover/z3 GIT_TAG z3-4.8.15 ) -# list(APPEND FETCH_PACKAGES Z3) +# search for Z3 +find_package(Z3 4.8.15) +if(NOT Z3_FOUND) + message( + WARNING "Did not find Z3. Exact mapper and Clifford synthesis libraries will not be available") +endif() if(BUILD_MQT_QMAP_BINDINGS) # Manually detect the installed mqt-core package. @@ -46,7 +50,6 @@ set(MQT_CORE_REV "8224856776df527ff2e9911fb1751572fefaf80a" set(MQT_CORE_REPO_OWNER "munich-quantum-toolkit" CACHE STRING "MQT Core repository owner (change when using a fork)") # cmake-format: on - FetchContent_Declare( mqt-core GIT_REPOSITORY https://github.com/${MQT_CORE_REPO_OWNER}/core.git @@ -100,13 +103,6 @@ endif() # Make all declared dependencies available. FetchContent_MakeAvailable(${FETCH_PACKAGES}) -# search for Z3 -find_package(Z3 4.8.15) -if(NOT Z3_FOUND) - message( - WARNING "Did not find Z3. Exact mapper and Clifford synthesis libraries will not be available") -endif() - # Mark the plog includes as SYSTEM includes to suppress warnings. get_target_property(PLOG_IID plog INTERFACE_INCLUDE_DIRECTORIES) set_target_properties(plog PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${PLOG_IID}") diff --git a/pyproject.toml b/pyproject.toml index 36a07d17f..365d0cb7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,10 +94,10 @@ build-dir = "build/{wheel_tag}/{build_type}" # Only build the Python bindings target build.targets = [ - # "mqt-qmap-clifford_synthesis-bindings", -# "mqt-qmap-hybrid_mapper-bindings", + "mqt-qmap-clifford_synthesis-bindings", + "mqt-qmap-hybrid_mapper-bindings", "mqt-qmap-na-bindings", -# "mqt-qmap-sc-bindings", + "mqt-qmap-sc-bindings", ] # Only install the Python package component From cba8d5b9f9de7d85ced9fd9e44fbd15d4eb923c7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 10:02:51 +0000 Subject: [PATCH 101/110] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/eval_native_gate_decomposition.py | 9 +++-- python/mqt/qmap/na/zoned.pyi | 40 +++++++++---------- src/na/zoned/decomposer/AxialDecomposer.cpp | 12 +++++- test/na/zoned/test_theta_opt_scheduler.cpp | 1 - 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/eval/na/zoned/eval_native_gate_decomposition.py b/eval/na/zoned/eval_native_gate_decomposition.py index 48d60645e..59a05c6a1 100755 --- a/eval/na/zoned/eval_native_gate_decomposition.py +++ b/eval/na/zoned/eval_native_gate_decomposition.py @@ -197,8 +197,9 @@ def process_benchmark( compiler_name = type(compiler).__name__ print(f"\033[32m[INFO]\033[0m Compiling {benchmark_name} with {qc.num_qubits} qubits with {compiler_name}...") try: - code, stats = _compile_wrapper(compiler, - qc) # run_with_process_timeout(_compile_wrapper, TIMEOUT, compiler, qc) + code, stats = _compile_wrapper( + compiler, qc + ) # run_with_process_timeout(_compile_wrapper, TIMEOUT, compiler, qc) except TimeoutError as e: print(f"\033[31m[ERROR]\033[0m Failed ({e})") evaluator.print_timeout(benchmark_name, qc, setting_name) @@ -446,6 +447,7 @@ def _process_ry(self, line: str, it: Iterator[str]) -> None: it: An iterator over the remaining lines. """ self._apply_global_ry() + def _apply_load(self, _: list[str]) -> None: """Apply a load operation. @@ -658,7 +660,7 @@ def main() -> None: "warn_unsupported_gates": False, } baseline = RoutingAwareCompiler(arch, **common_config) - #setting1 = RoutingAwareAxialCompiler(arch, **common_config) + # setting1 = RoutingAwareAxialCompiler(arch, **common_config) setting2 = RoutingAwareNativeGateCompiler(arch, **common_config) setting3 = RoutingAwareNativeGateCompiler(arch, **common_config, theta_opt_schedule=True) @@ -688,7 +690,6 @@ def main() -> None: process_benchmark(setting2, "setting2", qc, benchmark, evaluator) process_benchmark(setting3, "setting3", qc, benchmark, evaluator) - print( "\033[32m[INFO]\033[0m =============================================================\n" "\033[32m[INFO]\033[0m Now, \n" diff --git a/python/mqt/qmap/na/zoned.pyi b/python/mqt/qmap/na/zoned.pyi index f54b09d25..439becf79 100644 --- a/python/mqt/qmap/na/zoned.pyi +++ b/python/mqt/qmap/na/zoned.pyi @@ -220,30 +220,29 @@ class RoutingAwareCompiler: The statistics as a dictionary """ - class RoutingAwareAxialCompiler: """Routing-aware native gate zoned neutral atom compiler.""" def __init__( - self, - arch: ZonedNeutralAtomArchitecture, - log_level: str = "I", - max_filling_factor: float = 0.9, - use_window: bool = True, - window_min_width: int = 16, - window_ratio: float = 1.0, - window_share: float = 0.8, - placement_method: PlacementMethod = ..., - deepening_factor: float = ..., - deepening_value: float = 0.0, - lookahead_factor: float = ..., - reuse_level: float = 5.0, - max_nodes: int = 10000000, - trials: int = 4, - queue_capacity: int = 100, - routing_method: RoutingMethod = ..., - prefer_split: float = 1.0, - warn_unsupported_gates: bool = True, + self, + arch: ZonedNeutralAtomArchitecture, + log_level: str = "I", + max_filling_factor: float = 0.9, + use_window: bool = True, + window_min_width: int = 16, + window_ratio: float = 1.0, + window_share: float = 0.8, + placement_method: PlacementMethod = ..., + deepening_factor: float = ..., + deepening_value: float = 0.0, + lookahead_factor: float = ..., + reuse_level: float = 5.0, + max_nodes: int = 10000000, + trials: int = 4, + queue_capacity: int = 100, + routing_method: RoutingMethod = ..., + prefer_split: float = 1.0, + warn_unsupported_gates: bool = True, ) -> None: """Create a routing-aware compiler for the given architecture and configurations. @@ -302,6 +301,7 @@ class RoutingAwareAxialCompiler: Returns: The statistics as a dictionary """ + class RoutingAwareNativeGateCompiler: """Routing-aware native gate zoned neutral atom compiler.""" diff --git a/src/na/zoned/decomposer/AxialDecomposer.cpp b/src/na/zoned/decomposer/AxialDecomposer.cpp index 08a958a7d..9ff9ca73d 100644 --- a/src/na/zoned/decomposer/AxialDecomposer.cpp +++ b/src/na/zoned/decomposer/AxialDecomposer.cpp @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + #include "na/zoned/decomposer/AxialDecomposer.hpp" #include "ir/operations/CompoundOperation.hpp" @@ -214,4 +224,4 @@ auto AxialDecomposer::decompose( return {std::move(NewSingleQubitLayers), NewTwoQubitGateLayers}; } -} // namespace na::zoned \ No newline at end of file +} // namespace na::zoned diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index f5c54ed1a..1c144d18d 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -321,7 +321,6 @@ TEST_F(ThetaOptTest, NextMomentsCond3Test) { EXPECT_THAT(moments[0].first[3], ::testing::UnorderedElementsAre(6)); } - TEST_F(ThetaOptTest, RecursionBaseTest) { // Circuit // ┌─────────────────┐ ┌───────┐ From 127f331d917283aad0ab035866dafc0e868bcb92 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:18:24 +0200 Subject: [PATCH 102/110] =?UTF-8?q?=F0=9F=8E=A8=20Update=20evaluation=20sc?= =?UTF-8?q?ript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/eval_native_gate_decomposition.py | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/eval/na/zoned/eval_native_gate_decomposition.py b/eval/na/zoned/eval_native_gate_decomposition.py index 59a05c6a1..093c178c2 100755 --- a/eval/na/zoned/eval_native_gate_decomposition.py +++ b/eval/na/zoned/eval_native_gate_decomposition.py @@ -10,15 +10,17 @@ # /// script # dependencies = [ # "mqt.bench==2.1.0", -# "mqt.qmap==3.5.0", +# "mqt.qmap==3.7.1", # ] # [tool.uv] -# exclude-newer = "2026-05-01T12:59:59Z" +# exclude-newer = "2026-06-30T12:59:59Z" # /// """Script for evaluating the routing-aware native gate zoned neutral atom compiler. -In particular, TODO +In particular, it runs the native gate compiler to produce hardware compliant output. +It records central metrics of the compilation runs and the generated code. It compares +two different settings to evaluate the effectiveness of the theta optimization. """ from __future__ import annotations @@ -72,7 +74,7 @@ def _proc_target(q: Queue, func: Callable[P, R], args: P.args, kwargs: P.kwargs) """ try: q.put(("ok", func(*args, **kwargs))) - except Exception as e: + except Exception as e: # noqa: BLE001 q.put(("err", e)) @@ -439,7 +441,7 @@ def _process_rz(self, line: str, it: Iterator[str]) -> None: atoms.append(match.group(1)) self._apply_rz(atoms) - def _process_ry(self, line: str, it: Iterator[str]) -> None: + def _process_ry(self, line: str, it: Iterator[str]) -> None: # noqa: ARG002 """Process a global ry operation. Args: @@ -632,7 +634,7 @@ def print_error(self, circuit_name: str, qc: QuantumComputation, setting: str) - def main() -> None: - """Main function for evaluating the fast relaxed compiler.""" + """Main function for evaluating the native gate compiler.""" # set working directory to script location os.chdir(pathlib.Path(pathlib.Path(__file__).resolve()).parent) print("\033[32m[INFO]\033[0m Reading in architecture...") @@ -660,35 +662,27 @@ def main() -> None: "warn_unsupported_gates": False, } baseline = RoutingAwareCompiler(arch, **common_config) - # setting1 = RoutingAwareAxialCompiler(arch, **common_config) - setting2 = RoutingAwareNativeGateCompiler(arch, **common_config) - setting3 = RoutingAwareNativeGateCompiler(arch, **common_config, theta_opt_schedule=True) + setting1 = RoutingAwareNativeGateCompiler(arch, **common_config) + setting2 = RoutingAwareNativeGateCompiler(arch, **common_config, theta_opt_schedule=True) evaluator = Evaluator(arch_dict, "results.csv") evaluator.print_header() pathlib.Path("in").mkdir(exist_ok=True) benchmark_list = [ - ("graphstate", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), - # ("graphstate", (BenchmarkLevel.INDEP, [60, 80, 100, 120, 140, 160, 180, 200, 500, 1000, 2000, 5000])), - ("qft", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), - # ("qft", (BenchmarkLevel.INDEP, [500, 1000])), - ("qpeexact", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), - # ("qpeexact", (BenchmarkLevel.INDEP, [500, 1000])), - ("wstate", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), - # ("wstate", (BenchmarkLevel.INDEP, [500, 1000])), - ("qaoa", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), - # ("qaoa", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), - ("vqe_two_local", (BenchmarkLevel.INDEP, [20, 40, 60, 80, 100])), - # ("vqe_two_local", (BenchmarkLevel.INDEP, [50, 100, 150, 200])), + ("graphstate", (BenchmarkLevel.INDEP, [20, 100])), + ("qft", (BenchmarkLevel.INDEP, [20, 100])), + ("qpeexact", (BenchmarkLevel.INDEP, [20, 100])), + ("wstate", (BenchmarkLevel.INDEP, [20, 100])), + ("qaoa", (BenchmarkLevel.INDEP, [20, 100])), + ("vqe_two_local", (BenchmarkLevel.INDEP, [20, 100])), ] for benchmark, qc in benchmarks(benchmark_list): qc.qasm3(f"in/{benchmark}_n{qc.num_qubits}.qasm") process_benchmark(baseline, "baseline", qc, benchmark, evaluator) - # process_benchmark(setting1, "setting1", qc, benchmark, evaluator) + process_benchmark(setting1, "setting1", qc, benchmark, evaluator) process_benchmark(setting2, "setting2", qc, benchmark, evaluator) - process_benchmark(setting3, "setting3", qc, benchmark, evaluator) print( "\033[32m[INFO]\033[0m =============================================================\n" From 9736ee35cd0aff1d0bcac4ef49f3080b0c5ab882 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:29:24 +0200 Subject: [PATCH 103/110] =?UTF-8?q?=F0=9F=8E=A8=20Remove=20unnecessary=20b?= =?UTF-8?q?inding=20from=20interface=20file=20and=20update=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/mqt/qmap/na/zoned.pyi | 86 +----------------------------------- 1 file changed, 2 insertions(+), 84 deletions(-) diff --git a/python/mqt/qmap/na/zoned.pyi b/python/mqt/qmap/na/zoned.pyi index 439becf79..5c1a425bc 100644 --- a/python/mqt/qmap/na/zoned.pyi +++ b/python/mqt/qmap/na/zoned.pyi @@ -220,88 +220,6 @@ class RoutingAwareCompiler: The statistics as a dictionary """ -class RoutingAwareAxialCompiler: - """Routing-aware native gate zoned neutral atom compiler.""" - - def __init__( - self, - arch: ZonedNeutralAtomArchitecture, - log_level: str = "I", - max_filling_factor: float = 0.9, - use_window: bool = True, - window_min_width: int = 16, - window_ratio: float = 1.0, - window_share: float = 0.8, - placement_method: PlacementMethod = ..., - deepening_factor: float = ..., - deepening_value: float = 0.0, - lookahead_factor: float = ..., - reuse_level: float = 5.0, - max_nodes: int = 10000000, - trials: int = 4, - queue_capacity: int = 100, - routing_method: RoutingMethod = ..., - prefer_split: float = 1.0, - warn_unsupported_gates: bool = True, - ) -> None: - """Create a routing-aware compiler for the given architecture and configurations. - - Args: - arch: The zoned neutral atom architecture - log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" - max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel - use_window: Whether to use a window for the placer - window_min_width: The minimum width of the window for the placer - window_ratio: The ratio between the height and the width of the window - window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step - placement_method: The placement method that should be used for the heuristic placer - deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation - deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` - lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer - reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone - max_nodes: The maximum number of nodes that are considered in the A* search. - If this number is exceeded, the search is aborted and an error is raised. - In the current implementation, one node roughly consumes 120 Byte. - Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. - trials: The number of restarts during IDS. - queue_capacity: The maximum capacity of the priority queue used during IDS. - routing_method: The routing method that should be used for the independent set router - prefer_split: The threshold factor for group merging decisions during routing. - warn_unsupported_gates: Whether to warn about unsupported gates in the code generator - """ - - @staticmethod - def from_json_string(arch: ZonedNeutralAtomArchitecture, json: str) -> RoutingAwareAxialCompiler: - """Create a compiler for the given architecture and configurations from a JSON string. - - Args: - arch: The zoned neutral atom architecture - json: The JSON string - - Returns: - The initialized compiler - - Raises: - ValueError: If the string is not a valid JSON string - """ - - def compile(self, qc: mqt.core.ir.QuantumComputation) -> str: - """Compile a quantum circuit for the zoned neutral atom architecture. - - Args: - qc: The quantum circuit - - Returns: - The compilation result as a string in the .naviz format. - """ - - def stats(self) -> dict[str, float]: - """Get the statistics of the last compilation. - - Returns: - The statistics as a dictionary - """ - class RoutingAwareNativeGateCompiler: """Routing-aware native gate zoned neutral atom compiler.""" @@ -333,8 +251,8 @@ class RoutingAwareNativeGateCompiler: Args: arch: The zoned neutral atom architecture log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" - theta_opt_schedule: TODO - check_final_cond: TODO + theta_opt_schedule: If this setting is turned on, a re-scheduling pass is executed immediately after translating the gates into their U3 representation. The theta optimization tries to minimize the maximum theta per layer by possibly scheduling single-qubit gates in later layers. + check_final_cond: If enabled the theta optimization checks if the sum of the resulting layer's maximum theta and the next layer's maximum theta is strictly less than the sum of previous maximum thetas. This does not guarantee that the total schedule is the one with minimal cost but reduces the recursive calls by excluding some subsets. max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel use_window: Whether to use a window for the placer window_min_width: The minimum width of the window for the placer From 28d6e0c5530980c1de090d3397ccba3b0f36171d Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:33:55 +0200 Subject: [PATCH 104/110] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Recover=20bindings?= =?UTF-8?q?=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/register_zoned.cpp | 316 +++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 272575cd2..16a530895 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -371,6 +371,322 @@ void registerZoned(nb::module_& m) { }, R"pb(Get the statistics of the last compilation. +Returns: + The statistics as a dictionary)pb"); + + //===--------------------------------------------------------------------===// + // Routing-aware Axial Compiler + //===--------------------------------------------------------------------===// + nb::class_ routingAwareAxialCompiler( + m, "RoutingAwareAxialCompiler", + "Routing-aware axial zoned neutral atom compiler."); + { + const na::zoned::RoutingAwareAxialCompiler::Config defaultConfig; + routingAwareAxialCompiler.def( + "__init__", + [](na::zoned::RoutingAwareAxialCompiler* self, + const na::zoned::Architecture& arch, const std::string& logLevel, + const double maxFillingFactor, const bool useWindow, + const size_t windowMinWidth, const double windowRatio, + const double windowShare, + const na::zoned::HeuristicPlacer::Config::Method placementMethod, + const float deepeningFactor, const float deepeningValue, + const float lookaheadFactor, const float reuseLevel, + const size_t maxNodes, const size_t trials, + const size_t queueCapacity, + const na::zoned::IndependentSetRouter::Config::Method routingMethod, + const double preferSplit, const bool warnUnsupportedGates) { + na::zoned::RoutingAwareAxialCompiler::Config config; + config.logLevel = spdlog::level::from_str(logLevel); + config.schedulerConfig.maxFillingFactor = maxFillingFactor; + config.decomposerConfig = {}; + config.layoutSynthesizerConfig.placerConfig = { + .useWindow = useWindow, + .windowMinWidth = windowMinWidth, + .windowRatio = windowRatio, + .windowShare = windowShare, + .method = placementMethod, + .deepeningFactor = deepeningFactor, + .deepeningValue = deepeningValue, + .lookaheadFactor = lookaheadFactor, + .reuseLevel = reuseLevel, + .maxNodes = maxNodes, + .trials = trials, + .queueCapacity = queueCapacity, + }; + config.layoutSynthesizerConfig.routerConfig = { + .method = routingMethod, .preferSplit = preferSplit}; + config.codeGeneratorConfig = {.warnUnsupportedGates = + warnUnsupportedGates}; + new (self) na::zoned::RoutingAwareAxialCompiler{arch, config}; + }, + nb::keep_alive<1, 2>(), "arch"_a, + "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), + "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, + "use_window"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, + "window_min_width"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, + "window_ratio"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, + "window_share"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, + "placement_method"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.method, + "deepening_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, + "deepening_value"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, + "lookahead_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, + "reuse_level"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, + "max_nodes"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, + "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, + "queue_capacity"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, + "routing_method"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.method, + "prefer_split"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, + "warn_unsupported_gates"_a = + defaultConfig.codeGeneratorConfig.warnUnsupportedGates, + R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. +Args: + arch: The zoned neutral atom architecture + log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel + use_window: Whether to use a window for the placer + window_min_width: The minimum width of the window for the placer + window_ratio: The ratio between the height and the width of the window + window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step + placement_method: The placement method that should be used for the heuristic placer + deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation + deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` + lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer + reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone + max_nodes: The maximum number of nodes that are considered in the A* search. + If this number is exceeded, the search is aborted and an error is raised. + In the current implementation, one node roughly consumes 120 Byte. + Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. + trials: The number of restarts during IDS. + queue_capacity: The maximum capacity of the priority queue used during IDS. + routing_method: The routing method that should be used for the independent set router + prefer_split: The threshold factor for group merging decisions during routing. + warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); + } + + routingAwareAxialCompiler.def_static( + "from_json_string", + [](const na::zoned::Architecture& arch, + const std::string& json) -> na::zoned::RoutingAwareAxialCompiler { + // The correct header is included, but clang-tidy + // confuses it with the wrong forward header + // NOLINTNEXTLINE(misc-include-cleaner) + return {arch, nlohmann::json::parse(json)}; + }, + "arch"_a, "json"_a, + R"pb(Create a compiler for the given architecture and configurations from a JSON string. + + Args: + arch: The zoned neutral atom architecture + json: The JSON string + +Returns: + The initialized compiler + +Raises: + ValueError: If the string is not a valid JSON string)pb"); + + routingAwareAxialCompiler.def( + "compile", + [](na::zoned::RoutingAwareAxialCompiler& self, + const qc::QuantumComputation& qc) -> std::string { + return self.compile(qc).toString(); + }, + "qc"_a, + R"pb(Compile a quantum circuit for the zoned neutral atom architecture. + +Args: + qc: The quantum circuit + +Returns: + The compilation result as a string in the .naviz format.)pb"); + + routingAwareAxialCompiler.def( + "stats", + [](const na::zoned::RoutingAwareAxialCompiler& self) { + const auto json = nb::module_::import_("json"); + const auto loads = json.attr("loads"); + const nlohmann::json stats = self.getStatistics(); + const auto dict = loads(stats.dump()); + return nb::cast>(dict); + }, + R"pb(Get the statistics of the last compilation. + Returns: + The statistics as a dictionary)pb"); + + //===--------------------------------------------------------------------===// + // Routing-aware Native Gate Compiler + //===--------------------------------------------------------------------===// + nb::class_ + routingAwareNativeGateCompiler( + m, "RoutingAwareNativeGateCompiler", + "Routing-aware native gate zoned neutral atom compiler."); + { + const na::zoned::RoutingAwareNativeGateCompiler::Config defaultConfig; + routingAwareNativeGateCompiler.def( + "__init__", + [](na::zoned::RoutingAwareNativeGateCompiler* self, + const na::zoned::Architecture& arch, const std::string& logLevel, + const double maxFillingFactor, const bool thetaOptSchedule, + const bool checkFinalCond, const bool useWindow, + const size_t windowMinWidth, const double windowRatio, + const double windowShare, + const na::zoned::HeuristicPlacer::Config::Method placementMethod, + const float deepeningFactor, const float deepeningValue, + const float lookaheadFactor, const float reuseLevel, + const size_t maxNodes, const size_t trials, + const size_t queueCapacity, + const na::zoned::IndependentSetRouter::Config::Method routingMethod, + const double preferSplit, const bool warnUnsupportedGates) { + na::zoned::RoutingAwareNativeGateCompiler::Config config; + config.logLevel = spdlog::level::from_str(logLevel); + config.schedulerConfig.maxFillingFactor = maxFillingFactor; + config.decomposerConfig = {.thetaOptSchedule = thetaOptSchedule, + .checkFinalCond = checkFinalCond}; + config.layoutSynthesizerConfig.placerConfig = { + .useWindow = useWindow, + .windowMinWidth = windowMinWidth, + .windowRatio = windowRatio, + .windowShare = windowShare, + .method = placementMethod, + .deepeningFactor = deepeningFactor, + .deepeningValue = deepeningValue, + .lookaheadFactor = lookaheadFactor, + .reuseLevel = reuseLevel, + .maxNodes = maxNodes, + .trials = trials, + .queueCapacity = queueCapacity, + }; + config.layoutSynthesizerConfig.routerConfig = { + .method = routingMethod, .preferSplit = preferSplit}; + config.codeGeneratorConfig = {.warnUnsupportedGates = + warnUnsupportedGates}; + new (self) na::zoned::RoutingAwareNativeGateCompiler{arch, config}; + }, + nb::keep_alive<1, 2>(), "arch"_a, + "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), + "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, + "theta_opt_schedule"_a = + defaultConfig.decomposerConfig.thetaOptSchedule, + "check_final_cond"_a = defaultConfig.decomposerConfig.checkFinalCond, + "use_window"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, + "window_min_width"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, + "window_ratio"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, + "window_share"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, + "placement_method"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.method, + "deepening_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, + "deepening_value"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, + "lookahead_factor"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, + "reuse_level"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, + "max_nodes"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, + "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, + "queue_capacity"_a = + defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, + "routing_method"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.method, + "prefer_split"_a = + defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, + "warn_unsupported_gates"_a = + defaultConfig.codeGeneratorConfig.warnUnsupportedGates, + R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. + +Args: + arch: The zoned neutral atom architecture + log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel + theta_opt_schedule: TODO + check_final_cond: TODO + use_window: Whether to use a window for the placer + window_min_width: The minimum width of the window for the placer + window_ratio: The ratio between the height and the width of the window + window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step + placement_method: The placement method that should be used for the heuristic placer + deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation + deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` + lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer + reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone + max_nodes: The maximum number of nodes that are considered in the A* search. + If this number is exceeded, the search is aborted and an error is raised. + In the current implementation, one node roughly consumes 120 Byte. + Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. + trials: The number of restarts during IDS. + queue_capacity: The maximum capacity of the priority queue used during IDS. + routing_method: The routing method that should be used for the independent set router + prefer_split: The threshold factor for group merging decisions during routing. + warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); + } + + routingAwareNativeGateCompiler.def_static( + "from_json_string", + [](const na::zoned::Architecture& arch, + const std::string& json) -> na::zoned::RoutingAwareNativeGateCompiler { + // The correct header is included, but clang-tidy + // confuses it with the wrong forward header + // NOLINTNEXTLINE(misc-include-cleaner) + return {arch, nlohmann::json::parse(json)}; + }, + "arch"_a, "json"_a, + R"pb(Create a compiler for the given architecture and configurations from a JSON string. + +Args: + arch: The zoned neutral atom architecture + json: The JSON string + +Returns: + The initialized compiler + +Raises: + ValueError: If the string is not a valid JSON string)pb"); + + routingAwareNativeGateCompiler.def( + "compile", + [](na::zoned::RoutingAwareNativeGateCompiler& self, + const qc::QuantumComputation& qc) -> std::string { + return self.compile(qc).toString(); + }, + "qc"_a, + R"pb(Compile a quantum circuit for the zoned neutral atom architecture. + +Args: + qc: The quantum circuit + +Returns: + The compilation result as a string in the .naviz format.)pb"); + + routingAwareNativeGateCompiler.def( + "stats", + [](const na::zoned::RoutingAwareNativeGateCompiler& self) { + const auto json = nb::module_::import_("json"); + const auto loads = json.attr("loads"); + const nlohmann::json stats = self.getStatistics(); + const auto dict = loads(stats.dump()); + return nb::cast>(dict); + }, + R"pb(Get the statistics of the last compilation. + Returns: The statistics as a dictionary)pb"); } From 39fa2bbac0d7374bd4211197ee75d12bbca8b51f Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:39:42 +0200 Subject: [PATCH 105/110] =?UTF-8?q?=F0=9F=8E=A8=20Remove=20unnecessary=20b?= =?UTF-8?q?indings=20code=20and=20align=20interfaces?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/na/register_zoned.cpp | 157 +-------------------------------- python/mqt/qmap/na/zoned.pyi | 4 +- 2 files changed, 4 insertions(+), 157 deletions(-) diff --git a/bindings/na/register_zoned.cpp b/bindings/na/register_zoned.cpp index 16a530895..5f9140ca0 100644 --- a/bindings/na/register_zoned.cpp +++ b/bindings/na/register_zoned.cpp @@ -374,159 +374,6 @@ void registerZoned(nb::module_& m) { Returns: The statistics as a dictionary)pb"); - //===--------------------------------------------------------------------===// - // Routing-aware Axial Compiler - //===--------------------------------------------------------------------===// - nb::class_ routingAwareAxialCompiler( - m, "RoutingAwareAxialCompiler", - "Routing-aware axial zoned neutral atom compiler."); - { - const na::zoned::RoutingAwareAxialCompiler::Config defaultConfig; - routingAwareAxialCompiler.def( - "__init__", - [](na::zoned::RoutingAwareAxialCompiler* self, - const na::zoned::Architecture& arch, const std::string& logLevel, - const double maxFillingFactor, const bool useWindow, - const size_t windowMinWidth, const double windowRatio, - const double windowShare, - const na::zoned::HeuristicPlacer::Config::Method placementMethod, - const float deepeningFactor, const float deepeningValue, - const float lookaheadFactor, const float reuseLevel, - const size_t maxNodes, const size_t trials, - const size_t queueCapacity, - const na::zoned::IndependentSetRouter::Config::Method routingMethod, - const double preferSplit, const bool warnUnsupportedGates) { - na::zoned::RoutingAwareAxialCompiler::Config config; - config.logLevel = spdlog::level::from_str(logLevel); - config.schedulerConfig.maxFillingFactor = maxFillingFactor; - config.decomposerConfig = {}; - config.layoutSynthesizerConfig.placerConfig = { - .useWindow = useWindow, - .windowMinWidth = windowMinWidth, - .windowRatio = windowRatio, - .windowShare = windowShare, - .method = placementMethod, - .deepeningFactor = deepeningFactor, - .deepeningValue = deepeningValue, - .lookaheadFactor = lookaheadFactor, - .reuseLevel = reuseLevel, - .maxNodes = maxNodes, - .trials = trials, - .queueCapacity = queueCapacity, - }; - config.layoutSynthesizerConfig.routerConfig = { - .method = routingMethod, .preferSplit = preferSplit}; - config.codeGeneratorConfig = {.warnUnsupportedGates = - warnUnsupportedGates}; - new (self) na::zoned::RoutingAwareAxialCompiler{arch, config}; - }, - nb::keep_alive<1, 2>(), "arch"_a, - "log_level"_a = spdlog::level::to_short_c_str(defaultConfig.logLevel), - "max_filling_factor"_a = defaultConfig.schedulerConfig.maxFillingFactor, - "use_window"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.useWindow, - "window_min_width"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowMinWidth, - "window_ratio"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowRatio, - "window_share"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.windowShare, - "placement_method"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.method, - "deepening_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningFactor, - "deepening_value"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.deepeningValue, - "lookahead_factor"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.lookaheadFactor, - "reuse_level"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.reuseLevel, - "max_nodes"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.maxNodes, - "trials"_a = defaultConfig.layoutSynthesizerConfig.placerConfig.trials, - "queue_capacity"_a = - defaultConfig.layoutSynthesizerConfig.placerConfig.queueCapacity, - "routing_method"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.method, - "prefer_split"_a = - defaultConfig.layoutSynthesizerConfig.routerConfig.preferSplit, - "warn_unsupported_gates"_a = - defaultConfig.codeGeneratorConfig.warnUnsupportedGates, - R"pb(Create a routing-aware native gate compiler for the given architecture and configurations. -Args: - arch: The zoned neutral atom architecture - log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" - max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel - use_window: Whether to use a window for the placer - window_min_width: The minimum width of the window for the placer - window_ratio: The ratio between the height and the width of the window - window_share: The share of free sites in the window in relation to the number of atoms to be moved in this step - placement_method: The placement method that should be used for the heuristic placer - deepening_factor: Controls the impact of the term in the heuristic of the A* search that resembles the standard deviation of the differences between the current and target sites of the atoms to be moved in every orientation - deepening_value: Is added to the sum of standard deviations before it is multiplied with the number of unplaced nodes and :attr:`deepening_factor` - lookahead_factor: Controls the lookahead's influence that considers the distance of atoms to their interaction partner in the next layer - reuse_level: The reuse level that corresponds to the estimated extra fidelity loss due to the extra trap transfers when the atom is not reused and instead moved to the storage zone and back to the entanglement zone - max_nodes: The maximum number of nodes that are considered in the A* search. - If this number is exceeded, the search is aborted and an error is raised. - In the current implementation, one node roughly consumes 120 Byte. - Hence, allowing 50,000,000 nodes results in memory consumption of about 6 GB plus the size of the rest of the data structures. - trials: The number of restarts during IDS. - queue_capacity: The maximum capacity of the priority queue used during IDS. - routing_method: The routing method that should be used for the independent set router - prefer_split: The threshold factor for group merging decisions during routing. - warn_unsupported_gates: Whether to warn about unsupported gates in the code generator)pb"); - } - - routingAwareAxialCompiler.def_static( - "from_json_string", - [](const na::zoned::Architecture& arch, - const std::string& json) -> na::zoned::RoutingAwareAxialCompiler { - // The correct header is included, but clang-tidy - // confuses it with the wrong forward header - // NOLINTNEXTLINE(misc-include-cleaner) - return {arch, nlohmann::json::parse(json)}; - }, - "arch"_a, "json"_a, - R"pb(Create a compiler for the given architecture and configurations from a JSON string. - - Args: - arch: The zoned neutral atom architecture - json: The JSON string - -Returns: - The initialized compiler - -Raises: - ValueError: If the string is not a valid JSON string)pb"); - - routingAwareAxialCompiler.def( - "compile", - [](na::zoned::RoutingAwareAxialCompiler& self, - const qc::QuantumComputation& qc) -> std::string { - return self.compile(qc).toString(); - }, - "qc"_a, - R"pb(Compile a quantum circuit for the zoned neutral atom architecture. - -Args: - qc: The quantum circuit - -Returns: - The compilation result as a string in the .naviz format.)pb"); - - routingAwareAxialCompiler.def( - "stats", - [](const na::zoned::RoutingAwareAxialCompiler& self) { - const auto json = nb::module_::import_("json"); - const auto loads = json.attr("loads"); - const nlohmann::json stats = self.getStatistics(); - const auto dict = loads(stats.dump()); - return nb::cast>(dict); - }, - R"pb(Get the statistics of the last compilation. - Returns: - The statistics as a dictionary)pb"); - //===--------------------------------------------------------------------===// // Routing-aware Native Gate Compiler //===--------------------------------------------------------------------===// @@ -617,8 +464,8 @@ void registerZoned(nb::module_& m) { arch: The zoned neutral atom architecture log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel - theta_opt_schedule: TODO - check_final_cond: TODO + theta_opt_schedule: If this setting is turned on, a re-scheduling pass is executed immediately after translating the gates into their U3 representation. The theta optimization tries to minimize the maximum theta per layer by possibly scheduling single-qubit gates in later layers. + check_final_cond: If enabled the theta optimization checks if the sum of the resulting layer's maximum theta and the next layer's maximum theta is strictly less than the sum of previous maximum thetas. This does not guarantee that the total schedule is the one with minimal cost but reduces the recursive calls by excluding some subsets. use_window: Whether to use a window for the placer window_min_width: The minimum width of the window for the placer window_ratio: The ratio between the height and the width of the window diff --git a/python/mqt/qmap/na/zoned.pyi b/python/mqt/qmap/na/zoned.pyi index 5c1a425bc..8052ef49c 100644 --- a/python/mqt/qmap/na/zoned.pyi +++ b/python/mqt/qmap/na/zoned.pyi @@ -227,9 +227,9 @@ class RoutingAwareNativeGateCompiler: self, arch: ZonedNeutralAtomArchitecture, log_level: str = "I", + max_filling_factor: float = 0.9, theta_opt_schedule: bool = False, check_final_cond: bool = False, - max_filling_factor: float = 0.9, use_window: bool = True, window_min_width: int = 16, window_ratio: float = 1.0, @@ -251,9 +251,9 @@ class RoutingAwareNativeGateCompiler: Args: arch: The zoned neutral atom architecture log_level: The log level for the compiler, possible values are "debug"/"D", "info"/"I", "warning"/"W", "error"/"E", and "critical"/"C" + max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel theta_opt_schedule: If this setting is turned on, a re-scheduling pass is executed immediately after translating the gates into their U3 representation. The theta optimization tries to minimize the maximum theta per layer by possibly scheduling single-qubit gates in later layers. check_final_cond: If enabled the theta optimization checks if the sum of the resulting layer's maximum theta and the next layer's maximum theta is strictly less than the sum of previous maximum thetas. This does not guarantee that the total schedule is the one with minimal cost but reduces the recursive calls by excluding some subsets. - max_filling_factor: The maximum filling factor for the entanglement zone, i.e., it sets the limit for the maximum number of entangling gates that are scheduled in parallel use_window: Whether to use a window for the placer window_min_width: The minimum width of the window for the placer window_ratio: The ratio between the height and the width of the window From 5bb67d4b741df33227be136d2b2bb552c245d391 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:44:21 +0200 Subject: [PATCH 106/110] =?UTF-8?q?=F0=9F=94=A5=20Delete=20axial=20compile?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../na/zoned/decomposer/AxialDecomposer.hpp | 118 --------- src/na/zoned/decomposer/AxialDecomposer.cpp | 227 ------------------ 2 files changed, 345 deletions(-) delete mode 100644 include/na/zoned/decomposer/AxialDecomposer.hpp delete mode 100644 src/na/zoned/decomposer/AxialDecomposer.cpp diff --git a/include/na/zoned/decomposer/AxialDecomposer.hpp b/include/na/zoned/decomposer/AxialDecomposer.hpp deleted file mode 100644 index e72a0498c..000000000 --- a/include/na/zoned/decomposer/AxialDecomposer.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM - * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH - * All rights reserved. - * - * SPDX-License-Identifier: MIT - * - * Licensed under the MIT License - */ - -#pragma once - -#include "na/zoned/Types.hpp" -#include "na/zoned/decomposer/DecomposerBase.hpp" - -#include - -namespace na::zoned { -class AxialDecomposer : public DecomposerBase { - /** - * A quaternion is represented by an array of four `qc::fp` values `{q0, q1, - * q2, q3}` denoting the components of the quaternion. - */ - using Quaternion = std::array; - - /// A value to use as a margin of error for float equality - constexpr static qc::fp epsilon = - std::numeric_limits::epsilon() * 1024; - -public: - /// The configuration of the AxialDecomposer - struct Config { - template - friend void to_json(BasicJsonType& /* unused */, - const Config& /* unused */) {} - template - friend void from_json(const BasicJsonType& /* unused */, - Config& /* unused */) {} - }; - - /** - * A minimal struct to store the parameters of a U3 gate along with the qubit - * it acts on. - */ - struct StructU3 { - std::array angles; - qc::Qubit qubit; - }; - - /// Create a new NativeGateDecomposer. - AxialDecomposer(const Architecture& /* unused */, - const Config& /* unused */) {} - - /** - * @brief Converts commonly used single qubit gates into their Quaternion - * representation. - * @details A single qubit gate R_v(phi) with rotation axis v=(v0,v1,v2) - * and rotation angle phi can be represented as a quaternion: - * @code quaternion(R_v(phi)) = (cos(phi/2) * I, v0 * sin(phi/2) * X, v1 * - * sin(phi/2) * Y, v2 * sin(phi/2) * Z)@endcode with X, Y, Z Pauli Matrices. - * @param op a reference_wrapper to the operation to be converted - * @returns a quaternion. - */ - static auto - convertGateToQuaternion(std::reference_wrapper op) - -> Quaternion; - /** - * @brief Merges the quaternions representing two gates as in a matrix - * multiplication of the gates. - * @param q1 the first quaternion to be combined. - * @param q2 the second quaternion to be combined. - * @returns an quaternion. - */ - static auto combineQuaternions(const Quaternion& q1, const Quaternion& q2) - -> Quaternion; - /** - * @brief Calculates the values of the U3-gate parameters theta, phi, and - * lambda. - * @param quat is a quaternion representing a single qubit gate. - * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving - * the U3 gate angles. - */ - static auto getU3AnglesFromQuaternion(const Quaternion& quat) - -> std::array; - - /** - * @brief Takes a vector of SingleQubitGateLayers and, for each layer, - * transforms all gates into U3 gates represented by `StructU3` objects. - * @details It combines all gates acting on the same qubit into a single U3 - * gate. - * @param layers is a std::vector of SingleQubitGateLayers of a scheduled - * circuit. - * @param n_qubits the number of Qubits in the scheduled circuit - * @returns a vector of vectors of StructU3 objects representing the single - * qubit gate layers. - */ - [[nodiscard]] static auto - transformToU3(const std::vector& layers, - size_t n_qubits) -> std::vector>; - /** - * @brief Decomposes a given schedule of operations into the native gate set - * and, if theta_opt_scheduling is selected re-schedules them to - * minimize the total global rotation angle theta across the circuit - * @details - * @param nQubits the number of Qubits in the scheduled circuit - * @param schedule a pair of vectors containing SingleQubitGateRefLayers - * and TwoQubitGateLayers - * @returns a pair of vectors containing SingleQubitLayers and TwoQubitLayers - * representing the decomposed (and rescheduled) circuit - */ - [[nodiscard]] auto - decompose(size_t nQubits, - const std::pair, - std::vector>& schedule) - -> std::pair, - std::vector> override; -}; -} // namespace na::zoned diff --git a/src/na/zoned/decomposer/AxialDecomposer.cpp b/src/na/zoned/decomposer/AxialDecomposer.cpp deleted file mode 100644 index 9ff9ca73d..000000000 --- a/src/na/zoned/decomposer/AxialDecomposer.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM - * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH - * All rights reserved. - * - * SPDX-License-Identifier: MIT - * - * Licensed under the MIT License - */ - -#include "na/zoned/decomposer/AxialDecomposer.hpp" - -#include "ir/operations/CompoundOperation.hpp" -#include "ir/operations/Operation.hpp" -#include "ir/operations/StandardOperation.hpp" - -namespace na::zoned { -auto AxialDecomposer::convertGateToQuaternion( - std::reference_wrapper op) -> Quaternion { - assert(op.get().getNqubits() == 1); - Quaternion quat{}; - if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front() / 2), 0, 0, - sin(op.get().getParameter().front() / 2)}; - } else if (op.get().getType() == qc::Z) { - quat = {0, 0, 0, 1}; - } else if (op.get().getType() == qc::S) { - quat = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - } else if (op.get().getType() == qc::Sdg) { - quat = {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}; - } else if (op.get().getType() == qc::T) { - quat = {cos(qc::PI_4 / 2), 0, 0, sin(qc::PI_4 / 2)}; - } else if (op.get().getType() == qc::Tdg) { - quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; - } else if (op.get().getType() == qc::U) { - quat = combineQuaternions( - combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, - sin(op.get().getParameter().at(1) / 2)}, - {cos(op.get().getParameter().front() / 2), 0, - sin(op.get().getParameter().front() / 2), 0}), - {cos(op.get().getParameter().at(2) / 2), 0, 0, - sin(op.get().getParameter().at(2) / 2)}); - } else if (op.get().getType() == qc::U2) { - quat = combineQuaternions( - combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, - sin(op.get().getParameter().front() / 2)}, - {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), - {cos(op.get().getParameter().at(1) / 2), 0, 0, - sin(op.get().getParameter().at(1) / 2)}); - } else if (op.get().getType() == qc::RX) { - quat = {cos(op.get().getParameter().front() / 2), - sin(op.get().getParameter().front() / 2), 0, 0}; - } else if (op.get().getType() == qc::RY) { - quat = {cos(op.get().getParameter().front() / 2), 0, - sin(op.get().getParameter().front() / 2), 0}; - } else if (op.get().getType() == qc::H) { - quat = combineQuaternions( - combineQuaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), - {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); - } else if (op.get().getType() == qc::X) { - quat = {0, 1, 0, 0}; - } else if (op.get().getType() == qc::Y) { - quat = {0, 0, 1, 0}; - } else if (op.get().getType() == qc::Vdg) { - quat = combineQuaternions( - combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), - {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); - } else if (op.get().getType() == qc::SX) { - quat = combineQuaternions( - combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), - {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); - } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { - quat = combineQuaternions( - combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, - {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), - {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); - } else { - // if the gate type is not recognized, an error is printed and the - // gate is not included in the output. - std::ostringstream oss; - oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() - << "\n"; - throw std::invalid_argument(oss.str()); - } - return quat; -} - -auto AxialDecomposer::combineQuaternions(const Quaternion& q1, - const Quaternion& q2) -> Quaternion { - Quaternion new_quat{}; - new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; - new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; - new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; - new_quat[3] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]; - return new_quat; -} - -auto AxialDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) - -> std::array { - qc::fp theta; - qc::fp phi; - qc::fp lambda; - if (std::fabs(quat[0]) > epsilon || std::fabs(quat[3]) > epsilon) { - theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), - std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); - qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // (phi+ lambda) /2 - if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { - qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); //(phi-lambda)/2 - phi = alpha_1 + alpha_2; // phi - lambda = alpha_1 - alpha_2; - } else { - phi = 0; - lambda = 2 * alpha_1; - } - } else { - theta = qc::PI; - if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { - phi = 0; - lambda = 2 * std::atan2(quat[1], quat[2]); - } else { - // This should never happen! Exception?? - phi = 0.; - lambda = 0.; - } - } - return {theta, phi, lambda}; -} - -auto AxialDecomposer::transformToU3( - const std::vector& layers, size_t n_qubits) - -> std::vector> { - std::vector> new_layers; - for (const auto& layer : layers) { - std::vector>> gates( - n_qubits); - std::vector new_layer; - for (auto gate : layer) { - // WHat are operations with empty targets doing?? - if (!gate.get().getTargets().empty()) { - gates[gate.get().getTargets().front()].push_back(gate); - } - } - - for (auto qubit_gates : gates) { - if (!qubit_gates.empty()) { - std::array quat = convertGateToQuaternion(qubit_gates[0]); - for (size_t i = 1; i < qubit_gates.size(); i++) { - quat = - combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); - } - std::array angles = getU3AnglesFromQuaternion(quat); - new_layer.emplace_back( - StructU3{angles, qubit_gates[0].get().getTargets().front()}); - } - } - new_layers.push_back(new_layer); - } - return new_layers; -} - -auto AxialDecomposer::decompose( - size_t nQubits, const std::pair, - std::vector>& schedule) - -> std::pair, - std::vector> { - - std::vector> U3Layers = - transformToU3(schedule.first, nQubits); - std::vector NewTwoQubitGateLayers = schedule.second; - std::vector NewSingleQubitLayers = - std::vector{}; - - for (const auto& layer : U3Layers) { - SingleQubitGateLayer FrontLayer; - SingleQubitGateLayer MidLayer; - SingleQubitGateLayer BackLayer; - SingleQubitGateLayer NewLayer = {}; - - for (auto gate : layer) { - - // Global RX here instead of RY - FrontLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {gate.angles[1]}))); - - MidLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {gate.angles[0]}))); - - BackLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {gate.angles[2]}))); - } // gate::layer - if (!layer.empty()) { - std::vector> GR_plus; - std::vector> GR_minus; - - for (size_t i = 0; i < nQubits; ++i) { - // Should be X_Rotations - GR_plus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{-qc::PI / 2})); - GR_minus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{qc::PI / 2})); - } - - for (auto&& gate : FrontLayer) { - NewLayer.push_back(std::move(gate)); - } - - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_plus), true))); - - for (auto&& gate : MidLayer) { - NewLayer.push_back(std::move(gate)); - } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_minus), true))); - - for (auto&& gate : BackLayer) { - NewLayer.push_back(std::move(gate)); - } - } - NewSingleQubitLayers.push_back(std::move(NewLayer)); - } // layer::SingleQubitLayers - return {std::move(NewSingleQubitLayers), NewTwoQubitGateLayers}; -} - -} // namespace na::zoned From 2fd31a12adfedee45de78845fc3778ac26b0ad6c Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:45:41 +0200 Subject: [PATCH 107/110] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Restore=20NoOpDeco?= =?UTF-8?q?mposer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/decomposer/NoOpDecomposer.hpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/na/zoned/decomposer/NoOpDecomposer.hpp b/include/na/zoned/decomposer/NoOpDecomposer.hpp index 1176c7791..d0a9edef1 100644 --- a/include/na/zoned/decomposer/NoOpDecomposer.hpp +++ b/include/na/zoned/decomposer/NoOpDecomposer.hpp @@ -27,10 +27,17 @@ class NoOpDecomposer : public DecomposerBase { public: /// The configuration of the NoOpDecomposer struct Config { - template + template < + typename BasicJsonType, + nlohmann::detail::enable_if_t< + nlohmann::detail::is_basic_json::value, int> = 0> friend void to_json(BasicJsonType& /* unused */, const Config& /* unused */) {} - template + + template < + typename BasicJsonType, + nlohmann::detail::enable_if_t< + nlohmann::detail::is_basic_json::value, int> = 0> friend void from_json(const BasicJsonType& /* unused */, Config& /* unused */) {} }; From 6ee449f046890811634da8f57e61645cd6176cc6 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:51:04 +0200 Subject: [PATCH 108/110] =?UTF-8?q?=F0=9F=90=9B=20Fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/Compiler.hpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index f95ee1bcc..613b6901b 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -15,15 +15,14 @@ #include "na/NAComputation.hpp" #include "na/zoned/Architecture.hpp" #include "na/zoned/code_generator/CodeGenerator.hpp" -#include "na/zoned/decomposer/AxialDecomposer.hpp" #include "na/zoned/decomposer/NativeGateDecomposer.hpp" #include "na/zoned/decomposer/NoOpDecomposer.hpp" #include "na/zoned/layout_synthesizer/PlaceAndRouteSynthesizer.hpp" #include "na/zoned/layout_synthesizer/placer/HeuristicPlacer.hpp" #include "na/zoned/layout_synthesizer/placer/VertexMatchingPlacer.hpp" #include "na/zoned/layout_synthesizer/router/IndependentSetRouter.hpp" -#include "reuse_analyzer/VertexMatchingReuseAnalyzer.hpp" -#include "scheduler/ASAPScheduler.hpp" +#include "na/zoned/reuse_analyzer/VertexMatchingReuseAnalyzer.hpp" +#include "na/zoned/scheduler/ASAPScheduler.hpp" #include #include @@ -240,7 +239,7 @@ class Compiler : protected Scheduler, SPDLOG_DEBUG("Generating code..."); const auto codeGenerationStart = std::chrono::system_clock::now(); NAComputation code = - SELF.generate(decomposedSchedule.first, placement, routing); + SELF.generate(decomposedSingleQubitGateLayers, placement, routing); const auto codeGenerationEnd = std::chrono::system_clock::now(); assert(code.validate().first); statistics_.codeGenerationTime = @@ -314,19 +313,6 @@ class RoutingAwareCompiler final : Compiler(architecture) {} }; -class RoutingAwareAxialCompiler final - : public Compiler { -public: - RoutingAwareAxialCompiler(const Architecture& architecture, - const Config& config) - : Compiler(architecture, config) {} - - explicit RoutingAwareAxialCompiler(const Architecture& architecture) - : Compiler(architecture) {} -}; - class RoutingAwareNativeGateCompiler final : public Compiler Date: Thu, 25 Jun 2026 13:01:45 +0200 Subject: [PATCH 109/110] =?UTF-8?q?=F0=9F=90=9B=20Fix=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/na/zoned/Compiler.hpp | 5 ++-- .../na/zoned/decomposer/DecomposerBase.hpp | 4 ++- .../zoned/decomposer/NativeGateDecomposer.hpp | 27 +++++++------------ .../na/zoned/decomposer/NoOpDecomposer.hpp | 3 ++- .../zoned/decomposer/NativeGateDecomposer.cpp | 8 +++--- src/na/zoned/decomposer/NoOpDecomposer.cpp | 1 + 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/include/na/zoned/Compiler.hpp b/include/na/zoned/Compiler.hpp index 613b6901b..ca0a62374 100644 --- a/include/na/zoned/Compiler.hpp +++ b/include/na/zoned/Compiler.hpp @@ -186,7 +186,7 @@ class Compiler : protected Scheduler, spdlog::should_log(spdlog::level::debug)) { const auto& [min, sum, max] = std::accumulate( twoQubitGateLayers.cbegin(), twoQubitGateLayers.cend(), - std::array{std::numeric_limits::max(), 0UL, 0UL}, + std::array{std::numeric_limits::max(), 0UL, 0UL}, [](const auto& acc, const auto& layer) -> std::array { const auto& [minAcc, sumAcc, maxAcc] = acc; const auto n = layer.size(); @@ -204,7 +204,8 @@ class Compiler : protected Scheduler, const auto decomposingStart = std::chrono::system_clock::now(); const auto& [decomposedSingleQubitGateLayers, decomposedTwoQubitGateLayers] = - SELF.decompose(singleQubitGateLayers, twoQubitGateLayers); + SELF.decompose(qComp.getNqubits(), singleQubitGateLayers, + twoQubitGateLayers); const auto decomposingEnd = std::chrono::system_clock::now(); statistics_.decomposingTime = std::chrono::duration_cast(decomposingEnd - diff --git a/include/na/zoned/decomposer/DecomposerBase.hpp b/include/na/zoned/decomposer/DecomposerBase.hpp index 218996dc6..e0b2633a8 100644 --- a/include/na/zoned/decomposer/DecomposerBase.hpp +++ b/include/na/zoned/decomposer/DecomposerBase.hpp @@ -27,6 +27,7 @@ class DecomposerBase { * * The decomposer may change the layering produced by the scheduler and, * hence, it receives the single-qubit and two-qubit gate layers. + * @param nQubits is the number of qubits in the scheduled circuit. * @param singleQubitGateLayers are the layers of single-qubit gates that are * meant to be first decomposed into the native gate set. * @param twoQubitGateLayers are the layers of two-qubit gates that the @@ -38,7 +39,8 @@ class DecomposerBase { * layer more than two-qubit gate layers. */ [[nodiscard]] virtual auto - decompose(const std::vector& singleQubitGateLayers, + decompose(size_t nQubits, + const std::vector& singleQubitGateLayers, const std::vector& twoQubitGateLayers) const -> DecompositionResult = 0; }; diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index be5fbc2ef..0b9694a54 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -18,6 +18,11 @@ namespace na::zoned { +/** + * Decomposes a given schedule of operations into the native gate set and, if + * `theta_opt_scheduling` is enabled, re-schedules them to minimize the total + * global rotation angle theta across the circuit + */ class NativeGateDecomposer : public DecomposerBase { /** @@ -126,28 +131,16 @@ class NativeGateDecomposer : public DecomposerBase { auto static getDecompositionAngles(const std::array& angles, qc::fp theta_max) -> std::array; - /** - * @brief Decomposes a given schedule of operations into the native gate set - * and, if theta_opt_scheduling is selected re-schedules them to - * minimize the total global rotation angle theta across the circuit - * @details - * @param nQubits the number of Qubits in the scheduled circuit - * @param schedule a pair of vectors containing SingleQubitGateRefLayers - * and TwoQubitGateLayers - * @returns a pair of vectors containing SingleQubitLayers and TwoQubitLayers - * representing the decomposed (and rescheduled) circuit - */ [[nodiscard]] auto decompose(size_t nQubits, - const std::pair, - std::vector>& schedule) - -> std::pair, - std::vector> override; + const std::vector& singleQubitGateLayers, + const std::vector& twoQubitGateLayers) const + -> DecompositionResult override; /** - * @class A class implementing a simple DiGraph for use in the scheduling + * A class implementing a simple DiGraph for use in the scheduling * component of the native gate decomposer. - * @tparam T , the type of object associated with each node + * @tparam T is the type of object associated with each node */ template class DiGraph { /// number of nodes in the graph diff --git a/include/na/zoned/decomposer/NoOpDecomposer.hpp b/include/na/zoned/decomposer/NoOpDecomposer.hpp index d0a9edef1..fb6a8d788 100644 --- a/include/na/zoned/decomposer/NoOpDecomposer.hpp +++ b/include/na/zoned/decomposer/NoOpDecomposer.hpp @@ -49,7 +49,8 @@ class NoOpDecomposer : public DecomposerBase { } [[nodiscard]] auto - decompose(const std::vector& singleQubitGateLayers, + decompose(size_t nQubits, + const std::vector& singleQubitGateLayers, const std::vector& twoQubitGateLayers) const -> DecompositionResult override; }; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index b29d0c44c..6ea6e33a9 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -208,10 +208,10 @@ auto NativeGateDecomposer::getDecompositionAngles( } auto NativeGateDecomposer::decompose( - size_t nQubits, const std::pair, - std::vector>& schedule) - -> std::pair, - std::vector> { + const size_t nQubits, + const std::vector& singleQubitGateLayers, + const std::vector& twoQubitGateLayers) const + -> DecompositionResult { nQubits_ = nQubits; std::vector> U3Layers = diff --git a/src/na/zoned/decomposer/NoOpDecomposer.cpp b/src/na/zoned/decomposer/NoOpDecomposer.cpp index 3d2e63dbd..e4fa3401c 100644 --- a/src/na/zoned/decomposer/NoOpDecomposer.cpp +++ b/src/na/zoned/decomposer/NoOpDecomposer.cpp @@ -17,6 +17,7 @@ namespace na::zoned { auto NoOpDecomposer::decompose( + [[maybe_unused]] const size_t nQubits, const std::vector& singleQubitGateLayers, const std::vector& twoQubitGateLayers) const -> DecompositionResult { From 52b1cd40b92ee06093c2d7a323e9b241e960cbd6 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jun 2026 17:48:00 +0200 Subject: [PATCH 110/110] =?UTF-8?q?=F0=9F=8E=A8=20First=20pass=20through?= =?UTF-8?q?=20native=20gate=20decomposer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zoned/decomposer/NativeGateDecomposer.hpp | 230 ++--- .../zoned/decomposer/NativeGateDecomposer.cpp | 817 +++++++++--------- test/na/zoned/test_theta_opt_scheduler.cpp | 132 ++- 3 files changed, 569 insertions(+), 610 deletions(-) diff --git a/include/na/zoned/decomposer/NativeGateDecomposer.hpp b/include/na/zoned/decomposer/NativeGateDecomposer.hpp index 0b9694a54..2a05a7ba0 100644 --- a/include/na/zoned/decomposer/NativeGateDecomposer.hpp +++ b/include/na/zoned/decomposer/NativeGateDecomposer.hpp @@ -20,29 +20,35 @@ namespace na::zoned { /** * Decomposes a given schedule of operations into the native gate set and, if - * `theta_opt_scheduling` is enabled, re-schedules them to minimize the total + * `thetaOptScheduling` is enabled, re-schedules them to minimize the total * global rotation angle theta across the circuit */ class NativeGateDecomposer : public DecomposerBase { - /** * A quaternion is represented by an array of four `qc::fp` values `{q0, q1, - * q2, q3}` denoting the components of the quaternion. + * q2, q3}` denoting the components of the quaternion. The default initialized + * Quaternion denotes the identity, i.e., the neutral element, e.g., when + * calling @ref combineQuaternions with the identity quaternion, the other + * quaternion is returned. */ - using Quaternion = std::array; - size_t nQubits_ = 0; + struct Quaternion { + qc::fp a = 1; + qc::fp b = 0; + qc::fp c = 0; + qc::fp d = 0; + }; /// A value to use as a margin of error for float equality constexpr static qc::fp epsilon = std::numeric_limits::epsilon() * 1024; -public: - /// The configuration of the NativeGateDecomposer - struct Config { - bool thetaOptSchedule = false; - bool checkFinalCond = false; - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, thetaOptSchedule, - checkFinalCond); + /** + * A struct to store the decomposition angles of a U3 gate. + */ + struct Angles { + qc::fp theta = 0; + qc::fp phi = 0; + qc::fp lambda = 0; }; /** @@ -50,10 +56,19 @@ class NativeGateDecomposer : public DecomposerBase { * it acts on. */ struct StructU3 { - std::array angles; + Angles angles; qc::Qubit qubit; }; +public: + /// The configuration of the NativeGateDecomposer + struct Config { + bool thetaOptSchedule = false; + bool checkFinalCond = false; + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, thetaOptSchedule, + checkFinalCond); + }; + private: /// The configuration of the NativeGateDecomposer Config config_; @@ -91,16 +106,15 @@ class NativeGateDecomposer : public DecomposerBase { * @returns an array of three `qc::fp` values `{theta, phi, lambda}` giving * the U3 gate angles. */ - static auto getU3AnglesFromQuaternion(const Quaternion& quat) - -> std::array; + static auto getU3AnglesFromQuaternion(const Quaternion& quat) -> Angles; /** * @brief Calculates the largest value of the U3-gate parameter theta from a * vector of operations. - * @param layer is a vector of U3 parameters. + * @param layers is a vector of U3 parameters. * @returns the maximal value of theta in the given layer. */ - static auto calcThetaMax(const std::vector& layer) -> qc::fp; + static auto calcThetaMax(const std::vector& layers) -> qc::fp; /** * @brief Takes a vector of SingleQubitGateLayers and, for each layer, @@ -109,13 +123,13 @@ class NativeGateDecomposer : public DecomposerBase { * gate. * @param layers is a std::vector of SingleQubitGateLayers of a scheduled * circuit. - * @param n_qubits the number of Qubits in the scheduled circuit + * @param nQubits the number of Qubits in the scheduled circuit * @returns a vector of vectors of StructU3 objects representing the single * qubit gate layers. */ [[nodiscard]] static auto transformToU3(const std::vector& layers, - size_t n_qubits) -> std::vector>; + size_t nQubits) -> std::vector>; /** * @brief Calculates the decomposition angles of a U3 gate * @details Takes a vector of `qc::fp` representing the U3-gate angles of a @@ -124,12 +138,12 @@ class NativeGateDecomposer : public DecomposerBase { * et. al. 2024. * @param angles `std::array` of `qc::fp` representing (theta, phi, * lambda). - * @param theta_max the maximal theta value of the single-qubit gate layer. - * @returns an array of `qc::fp` values giving the angles (chi, gamma_minus, - * gamma_plus). + * @param thetaMax the maximal theta value of the single-qubit gate layer. + * @returns an array of `qc::fp` values giving the angles (chi, gammaMinus, + * gammaPlus). */ - auto static getDecompositionAngles(const std::array& angles, - qc::fp theta_max) -> std::array; + auto static getDecompositionAngles(const Angles& angles, qc::fp thetaMax) + -> Angles; [[nodiscard]] auto decompose(size_t nQubits, @@ -144,20 +158,20 @@ class NativeGateDecomposer : public DecomposerBase { */ template class DiGraph { /// number of nodes in the graph - std::size_t node_number; + size_t nodeNumber; /// a vector containing the adjacency lists of each node - std::vector>> adjacencies_; + std::vector>> adjacencies_; /// a vector containing the values associated with each node - std::vector node_values_; + std::vector nodeValues_; public: /** * @brief Creates an empty graph to hold objects of type T */ DiGraph() { - node_number = 0; - adjacencies_ = std::vector>>(); - node_values_ = std::vector(); + nodeNumber = 0; + adjacencies_ = std::vector>>(); + nodeValues_ = std::vector(); } /** @@ -165,10 +179,10 @@ class NativeGateDecomposer : public DecomposerBase { * @param node the type T value to be added to the graph * @returns the node index of the created node */ - auto add_Node(T node) -> std::size_t { + auto add_Node(T node) -> size_t { adjacencies_.emplace_back(); - node_values_.push_back(std::move(node)); - return node_number++; + nodeValues_.push_back(std::move(node)); + return nodeNumber++; } /** @@ -178,14 +192,12 @@ class NativeGateDecomposer : public DecomposerBase { * @param weight the weight of the edge * @returns a bool indicating if adding the edge was successful */ - auto add_Edge(std::size_t from, std::size_t to, double weight) -> bool { - if (from < node_number && to < node_number && from != to) { - adjacencies_[from].emplace_back( - std::pair(to, weight)); + auto addEdge(const size_t from, size_t to, double weight) -> bool { + if (from < nodeNumber && to < nodeNumber && from != to) { + adjacencies_[from].emplace_back(std::pair(to, weight)); return true; - } else { - return false; } + return false; } /** @@ -194,14 +206,12 @@ class NativeGateDecomposer : public DecomposerBase { * @param to index of the node the edge is going to * @returns a bool indicating if adding the edge was successful */ - auto add_Edge(std::size_t from, std::size_t to) -> bool { - if (from < node_number && to < node_number && from != to) { - adjacencies_[from].emplace_back( - std::pair(to, 1.0)); + auto addEdge(size_t from, size_t to) -> bool { + if (from < nodeNumber && to < nodeNumber && from != to) { + adjacencies_[from].emplace_back(std::pair(to, 1.0)); return true; - } else { - return false; } + return false; } /** @@ -209,9 +219,9 @@ class NativeGateDecomposer : public DecomposerBase { * @param node the node index of a node in the graph * @returns an object of type T contained in the given node */ - auto get_Node_Value(std::size_t node) -> T { - if (node < node_number) { - return node_values_[node]; + auto getNodeValue(size_t node) -> T { + if (node < nodeNumber) { + return nodeValues_[node]; } else { std::ostringstream oss; oss << "ERROR: Node Number out of range: " << node << "\n"; @@ -223,7 +233,7 @@ class NativeGateDecomposer : public DecomposerBase { * @brief A function which returns the size/number of nodes of the graph * @returns the number of nodes in the graph */ - [[nodiscard]] auto size() const -> std::size_t { return node_number; } + [[nodiscard]] auto size() const -> size_t { return nodeNumber; } /** * @brief Returns the successor nodes of a given node @@ -231,8 +241,8 @@ class NativeGateDecomposer : public DecomposerBase { * @returns a vector containing the node indices of all nodes the passed * node has outgoing edges to. */ - [[nodiscard]] auto get_adjacent(std::size_t node) const - -> std::vector> { + [[nodiscard]] auto getAdjacent(size_t node) const + -> std::vector> { return adjacencies_.at(node); } }; @@ -254,7 +264,7 @@ class NativeGateDecomposer : public DecomposerBase { * representation of U3-Gates of an array representation of CZ Gates. */ static auto - convert_circ_to_dag(const std::pair>, + convertCircuitToDAG(const std::pair>, std::vector>& schedule, size_t nQubits) -> DiGraph>>; @@ -262,74 +272,74 @@ class NativeGateDecomposer : public DecomposerBase { * @brief Recursively finds the cheapest path to the start node of the * subproblem graph from a set of leaf nodes. * @details - * @param subproblem_graph the subproblem graph to find the path in - * @param current_node the node of the current function call - * @param leaf_nodes a set of nodes with no outgoing edges (aka. leaf nodes) + * @param subproblemGraph the subproblem graph to find the path in + * @param currentNode the node of the current function call + * @param leafNodes a set of nodes with no outgoing edges (aka. leaf nodes) * @param memo * @returns a pair made up of a vector of the indices making up the cheapest * path and the path's total cost (the sum of the maximal theta angles * of each moment) */ - static auto cheapest_path_to_start( + static auto cheapestPathToStart( const DiGraph, std::vector>>& - subproblem_graph, - size_t current_node, const std::set& leaf_nodes, + subproblemGraph, + size_t currentNode, const std::set& leafNodes, std::map, qc::fp>>& memo) -> std::pair, double>; /** * @brief Finds the cheapest (lowest cost) path - * from the start node to a leaf node in a subproblem_graph + * from the start node to a leaf node in a subproblemGraph * @details - * @param subproblem_graph the subproblem graph - * @param path a vector containing the indices of all leaf nodes of the graph + * @param subproblemGraph the subproblem graph + * @param leafNodes a vector containing the indices of all leaf nodes of the + * graph * @returns a vector containing the node inidces of the cheapest path through * the graph */ - static auto find_cheapest_path( - const DiGraph, - std::vector>>& subproblem_graph, - const std::vector& path) -> std::vector; + static auto findCheapestPath( + const DiGraph, std::vector>>& + subproblemGraph, + const std::vector& leafNodes) -> std::vector; /** * @brief Finds the leaf nodes (Nodes with no outgoing edges) of a subproblem * graph * @details - * @param subproblem_graph the subproblem graph + * @param subproblemGraph the subproblem graph * @returns a vectr of node indices for the leaf nodes */ - static auto find_leaf_nodes( - const DiGraph, - std::vector>>& subproblem_graph) - -> std::vector; + static auto findLeafNodes( + const DiGraph, std::vector>>& + subproblemGraph) -> std::vector; /** * @brief Removes all copies of an element from a vector - * @param vector the vector of std::size_t to remove the element from + * @param vector the vector of size_t to remove the element from * @param elem the element to be removed from the vector * @returns the vector without the element */ - static auto remove_element(const std::vector& vector, - std::size_t elem) -> std::vector; + static auto removeElement(const std::vector& vector, size_t elem) + -> std::vector; /** * @brief Returns all plausible subsets of the current moments to be scheduled * @details * @param circuit the graph representation of the quantum circuit - * @param v0_c a vector containing the node indices of the current set of + * @param v0Current a vector containing the node indices of the current set of * single Qubit operations - * @param v_new =[v_p1,v_c1, v_rem] an array containing vectors holding the + * @param vNew =[v_p1,v_c1, v_rem] an array containing vectors holding the * node indices of the next set of two Qubit operations (v_p), single Qubit * operations (v_c) and all remaining operations (v_rem) - * @param check_final_cond a bool deciding whether to check for a strict cost + * @param checkFinalCond a bool deciding whether to check for a strict cost * reduction * @returns a vector holding pairs of the possible next moments to be * scheduled [v_c0, v_p1,vc_1,v_rem] and the moments associated */ - static auto get_possible_moments( + static auto getPossibleMoments( DiGraph>>& circuit, - const std::vector& v0_c, - const std::array, 3>& v_new, bool check_final_cond) + const std::vector& v0Current, + const std::array, 3>& vNew, bool checkFinalCond) -> std::vector, 4>, qc::fp>>; /** @@ -340,8 +350,8 @@ class NativeGateDecomposer : public DecomposerBase { * @returns the maximal theta value */ static auto - max_theta(DiGraph>>& circuit, - const std::vector& nodes) -> qc::fp; + maxTheta(DiGraph>>& circuit, + const std::vector& nodes) -> qc::fp; /** * @brief returns the next two- and single-Qubit moments which can be @@ -357,40 +367,39 @@ class NativeGateDecomposer : public DecomposerBase { */ static auto sift(DiGraph>>& circuit, - std::vector v, size_t nQubits) + std::vector v, size_t nQubits) -> std::array, 3>; /** * @brief Builds a schedule from a circuit and subproblem graph * @details * @param circuit the circuit to be scheduled in graph form - * @param subproblem_graph the subproblem graph of the circuit + * @param subproblemGraph the subproblem graph of the circuit * @returns a pair of vectrs containing layers of StructU3's and two element * arrays of Qubits representing CZ gates making up a schedule */ - static auto build_schedule( + static auto buildSchedule( DiGraph>>& circuit, DiGraph, std::vector>>& - subproblem_graph) -> std::pair>, - std::vector>; + subproblemGraph) -> std::pair>, + std::vector>; /** * @brief Adds a node corresponding to the subproblem [v_p,v_c] to the * subproblem graph * @details - * @param v_p a vector of node indices making up a two-Qubit gate moment - * @param v_c a vector of node indices making up a single-Qubit gate moment - * @param cost the maximal theta value of operations in v_c (aka. the cost) - * @param subproblem_graph a subproblem graph of a circuit - * @param prev_node the node corresponding to the previous subproblem + * @param vp a vector of node indices making up a two-Qubit gate moment + * @param vc a vector of node indices making up a single-Qubit gate moment + * @param cost the maximal theta value of operations in vc (aka. the cost) + * @param subproblemGraph a subproblem graph of a circuit + * @param prevNode the node corresponding to the previous subproblem * @returns the node index of the node added to the subproblem graph */ - static auto add_node_to_sub_prob_graph( - const std::vector& v_p, const std::vector& v_c, - qc::fp cost, + static auto addNodeToSubproblemGraph( + const std::vector& vp, const std::vector& vc, qc::fp cost, DiGraph, std::vector>>& - subproblem_graph, - size_t prev_node) -> size_t; + subproblemGraph, + size_t prevNode) -> size_t; /** * @brief Recursively creates a subproblem graph for a given circuit @@ -398,10 +407,10 @@ class NativeGateDecomposer : public DecomposerBase { * @param v the current subproblem [v_p,v_c,v_rem] for which to create a * schedule * @param circuit the graph representation of the circuit to be scheduled - * @param subproblem_graph the subproblem graph of the circuit to be scheduled - * @param prev_node the previous node in the subproblem graph + * @param subproblemGraph the subproblem graph of the circuit to be scheduled + * @param prevNode the previous node in the subproblem graph * @param nQubits the number of qubits in the circuit - * @param check_final_cond a bool deciding whether the function should only + * @param checkFinalCond a bool deciding whether the function should only * allow possible next moments with strictly decreasing cost * @param memo a map using subproblem hashes as keys and saving as values a * pair of a node index in the subproblem graph and an array containing the @@ -409,12 +418,12 @@ class NativeGateDecomposer : public DecomposerBase { * total cost of the schedule originating from that subproblem * @returns */ - static auto schedule_remaining( + static auto scheduleRemaining( const std::array, 3>& v, DiGraph>>& circuit, DiGraph, std::vector>>& - subproblem_graph, - size_t prev_node, size_t nQubits, bool check_final_cond, + subproblemGraph, + size_t prevNode, size_t nQubits, bool checkFinalCond, std::map>>& memo) -> double; @@ -427,9 +436,9 @@ class NativeGateDecomposer : public DecomposerBase { * @returns a schedule minimizing the total rotation angle theta */ [[nodiscard]] auto - schedule_theta_opt(const std::pair>, - std::vector>& schedule, - std::size_t nQubits) const + scheduleThetaOpt(const std::pair>, + std::vector>& schedule, + size_t nQubits) const -> std::pair>, std::vector>; }; @@ -437,13 +446,14 @@ class NativeGateDecomposer : public DecomposerBase { /** * A hash function for subproblems [v_p,v_c,v_rem] */ -template <> struct std::hash, 3>> { - auto operator()(const std::array, 3>& array) - const noexcept -> std::size_t { - std::size_t seed = 0U; +template <> struct std::hash, 3>> { + auto + operator()(const std::array, 3>& array) const noexcept + -> size_t { + size_t seed = 0U; for (const auto& v : array) { for (auto node : v) { - qc::hashCombine(seed, std::hash{}(node)); + qc::hashCombine(seed, std::hash{}(node)); } } return seed; diff --git a/src/na/zoned/decomposer/NativeGateDecomposer.cpp b/src/na/zoned/decomposer/NativeGateDecomposer.cpp index 6ea6e33a9..969708fe8 100644 --- a/src/na/zoned/decomposer/NativeGateDecomposer.cpp +++ b/src/na/zoned/decomposer/NativeGateDecomposer.cpp @@ -25,186 +25,184 @@ NativeGateDecomposer::NativeGateDecomposer(const Architecture&, config_ = config; } auto NativeGateDecomposer::convertGateToQuaternion( - std::reference_wrapper op) -> Quaternion { - assert(op.get().getNqubits() == 1); - Quaternion quat{}; - if (op.get().getType() == qc::RZ || op.get().getType() == qc::P) { - quat = {cos(op.get().getParameter().front() / 2), 0, 0, + const std::reference_wrapper op) -> Quaternion { + assert(op.get().getNqubits() == 1 && "Works only for single-qubit gates."); + switch (op.get().getType()) { + case qc::RZ: + case qc::P: + return {cos(op.get().getParameter().front() / 2), 0, 0, sin(op.get().getParameter().front() / 2)}; - } else if (op.get().getType() == qc::Z) { - quat = {0, 0, 0, 1}; - } else if (op.get().getType() == qc::S) { - quat = {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; - } else if (op.get().getType() == qc::Sdg) { - quat = {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}; - } else if (op.get().getType() == qc::T) { - quat = {cos(qc::PI_4 / 2), 0, 0, sin(qc::PI_4 / 2)}; - } else if (op.get().getType() == qc::Tdg) { - quat = {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; - } else if (op.get().getType() == qc::U) { - quat = combineQuaternions( + case qc::Z: + return {0, 0, 0, 1}; + case qc::S: + return {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}; + case qc::Sdg: + return {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}; + case qc::T: + return {cos(qc::PI_4 / 2), 0, 0, sin(qc::PI_4 / 2)}; + case qc::Tdg: + return {cos(-qc::PI_4 / 2), 0, 0, sin(-qc::PI_4 / 2)}; + case qc::U: + return combineQuaternions( combineQuaternions({cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}, {cos(op.get().getParameter().front() / 2), 0, sin(op.get().getParameter().front() / 2), 0}), {cos(op.get().getParameter().at(2) / 2), 0, 0, sin(op.get().getParameter().at(2) / 2)}); - } else if (op.get().getType() == qc::U2) { - quat = combineQuaternions( + case qc::U2: + return combineQuaternions( combineQuaternions({cos(op.get().getParameter().front() / 2), 0, 0, sin(op.get().getParameter().front() / 2)}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(op.get().getParameter().at(1) / 2), 0, 0, sin(op.get().getParameter().at(1) / 2)}); - } else if (op.get().getType() == qc::RX) { - quat = {cos(op.get().getParameter().front() / 2), + case qc::RX: + return {cos(op.get().getParameter().front() / 2), sin(op.get().getParameter().front() / 2), 0, 0}; - } else if (op.get().getType() == qc::RY) { - quat = {cos(op.get().getParameter().front() / 2), 0, + case qc::RY: + return {cos(op.get().getParameter().front() / 2), 0, sin(op.get().getParameter().front() / 2), 0}; - } else if (op.get().getType() == qc::H) { - quat = combineQuaternions( + case qc::H: + return combineQuaternions( combineQuaternions({1, 0, 0, 0}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_2), 0, 0, sin(qc::PI_2)}); - } else if (op.get().getType() == qc::X) { - quat = {0, 1, 0, 0}; - } else if (op.get().getType() == qc::Y) { - quat = {0, 0, 1, 0}; - } else if (op.get().getType() == qc::Vdg) { - quat = combineQuaternions( + case qc::X: + return {0, 1, 0, 0}; + case qc::Y: + return {0, 0, 1, 0}; + case qc::Vdg: + return combineQuaternions( combineQuaternions({cos(qc::PI_4), 0, 0, sin(qc::PI_4)}, {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}); - } else if (op.get().getType() == qc::SX) { - quat = combineQuaternions( + case qc::SX: + return combineQuaternions( combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, {cos(qc::PI_4), 0, sin(qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); - } else if (op.get().getType() == qc::SXdg || op.get().getType() == qc::V) { - quat = combineQuaternions( + case qc::SXdg: + case qc::V: + return combineQuaternions( combineQuaternions({cos(-qc::PI_4), 0, 0, sin(-qc::PI_4)}, {cos(-qc::PI_4), 0, sin(-qc::PI_4), 0}), {cos(qc::PI_4), 0, 0, sin(qc::PI_4)}); - } else { - // if the gate type is not recognized, an error is printed and the - // gate is not included in the output. + default: std::ostringstream oss; - oss << "ERROR: Unsupported single-qubit gate: " << op.get().getType() - << "\n"; + oss << "Unsupported single-qubit gate: " << op.get().getType(); throw std::invalid_argument(oss.str()); } - return quat; } auto NativeGateDecomposer::combineQuaternions(const Quaternion& q1, const Quaternion& q2) -> Quaternion { - Quaternion new_quat{}; - new_quat[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; - new_quat[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; - new_quat[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; - new_quat[3] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]; - return new_quat; + return {q1.a * q2.a - q1.b * q2.b - q1.c * q2.c - q1.d * q2.d, + q1.a * q2.b + q1.b * q2.a + q1.c * q2.d - q1.d * q2.c, + q1.a * q2.c - q1.b * q2.d + q1.c * q2.a + q1.d * q2.b, + q1.a * q2.d + q1.b * q2.c - q1.c * q2.b + q1.d * q2.a}; } auto NativeGateDecomposer::getU3AnglesFromQuaternion(const Quaternion& quat) - -> std::array { - qc::fp theta; - qc::fp phi; - qc::fp lambda; - if (std::fabs(quat[0]) > epsilon || std::fabs(quat[3]) > epsilon) { - theta = 2. * std::atan2(std::sqrt(quat[2] * quat[2] + quat[1] * quat[1]), - std::sqrt(quat[0] * quat[0] + quat[3] * quat[3])); - qc::fp alpha_1 = std::atan2(quat[3], quat[0]); // (phi+ lambda) /2 - if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { - qc::fp alpha_2 = -1 * std::atan2(quat[1], quat[2]); //(phi-lambda)/2 - phi = alpha_1 + alpha_2; // phi - lambda = alpha_1 - alpha_2; + -> Angles { + Angles angles; + if (std::fabs(quat.a) > epsilon || std::fabs(quat.d) > epsilon) { + angles.theta = + 2. * std::atan2(std::sqrt(quat.c * quat.c + quat.b * quat.b), + std::sqrt(quat.a * quat.a + quat.d * quat.d)); + const qc::fp alpha1 = std::atan2(quat.d, quat.a); // (phi+ lambda) /2 + if (std::fabs(quat.b) > epsilon || std::fabs(quat.c) > epsilon) { + const qc::fp alpha2 = -1 * std::atan2(quat.b, quat.c); //(phi-lambda)/2 + angles.phi = alpha1 + alpha2; // phi + angles.lambda = alpha1 - alpha2; } else { - phi = 0; - lambda = 2 * alpha_1; + angles.phi = 0; + angles.lambda = 2 * alpha1; } } else { - theta = qc::PI; - if (std::fabs(quat[1]) > epsilon || std::fabs(quat[2]) > epsilon) { - phi = 0; - lambda = 2 * std::atan2(quat[1], quat[2]); + angles.theta = qc::PI; + if (std::fabs(quat.b) > epsilon || std::fabs(quat.c) > epsilon) { + angles.phi = 0; + angles.lambda = 2 * std::atan2(quat.b, quat.c); } else { - // This should never happen! Exception?? - phi = 0.; - lambda = 0.; + throw std::invalid_argument("Invalid quaternion"); } } - return {theta, phi, lambda}; + return angles; } -auto NativeGateDecomposer::calcThetaMax(const std::vector& layer) +auto NativeGateDecomposer::calcThetaMax(const std::vector& layers) -> qc::fp { - qc::fp theta_max = 0; - for (auto gate : layer) { - if (std::fabs(gate.angles[0]) > theta_max) { - theta_max = std::fabs(gate.angles[0]); + qc::fp thetaMax = 0; + for (auto [angles, qubit] : layers) { + if (std::fabs(angles.theta) > thetaMax) { + thetaMax = std::fabs(angles.theta); } } - return theta_max; + return thetaMax; } auto NativeGateDecomposer::transformToU3( - const std::vector& layers, size_t n_qubits) + const std::vector& layers, const size_t nQubits) -> std::vector> { - std::vector> new_layers; + std::vector> newLayers; for (const auto& layer : layers) { - std::vector>> gates( - n_qubits); - std::vector new_layer; - for (auto gate : layer) { - // WHat are operations with empty targets doing?? - if (!gate.get().getTargets().empty()) { - gates[gate.get().getTargets().front()].push_back(gate); - } - } - - for (auto qubit_gates : gates) { - if (!qubit_gates.empty()) { - std::array quat = convertGateToQuaternion(qubit_gates[0]); - for (size_t i = 1; i < qubit_gates.size(); i++) { - quat = - combineQuaternions(quat, convertGateToQuaternion(qubit_gates[i])); - } - std::array angles = getU3AnglesFromQuaternion(quat); - new_layer.emplace_back( - StructU3{angles, qubit_gates[0].get().getTargets().front()}); - } - } - new_layers.push_back(new_layer); + std::vector>> + gatesPerQubit(nQubits); + std::ranges::for_each(layer, [&gatesPerQubit](const auto& gate) -> void { + assert(gate.get().getNqubits() != 1 && + "Gate has to be a single qubit gate."); + gatesPerQubit[gate.get().getTargets().front()].emplace_back(gate); + }); + std::vector newLayer; + std::ranges::transform( + std::views::iota(gatesPerQubit.size()) | + std::views::filter([&gatesPerQubit](const auto i) -> bool { + return !gatesPerQubit[i].empty(); + }), + std::back_inserter(newLayer), + [&gatesPerQubit](const auto i) -> StructU3 { + const auto& gates = gatesPerQubit[i]; + const auto& quat = std::accumulate( + gates.begin(), gates.end(), Quaternion{}, + [](Quaternion q, const auto& gate) -> Quaternion { + return combineQuaternions(std::move(q), + convertGateToQuaternion(gate)); + }); + const auto& angles = getU3AnglesFromQuaternion(quat); + return StructU3{.angles = angles, + .qubit = gates.front().get().getTargets().front()}; + }); + newLayers.emplace_back(newLayer); } - return new_layers; + return newLayers; } -auto NativeGateDecomposer::getDecompositionAngles( - const std::array& angles, qc::fp theta_max) - -> std::array { - qc::fp alpha, chi; - // U3(theta,phi_min(phi),phi_plus(lambda)->Rz(gamma_minus)GR(theta_max/2, +auto NativeGateDecomposer::getDecompositionAngles(const Angles& angles, + const qc::fp thetaMax) + -> Angles { + qc::fp alpha; + qc::fp chi; + // U3(theta,phi_min(phi),phi_plus(lambda))->Rz(gamma_minus)GR(theta_max/2, // PI_2)Rz(chi)GR(-theta_max/2,PI_2)RZ(gamma_plus) - qc::fp sin_sq_diff = (sin(theta_max / 2) * sin(theta_max / 2) - - (sin(angles[0] / 2) * sin(angles[0] / 2))); - if (std::fabs(sin_sq_diff) < epsilon) { + const auto sinSqDiff = sin(thetaMax / 2) * sin(thetaMax / 2) - + sin(angles.theta / 2) * sin(angles.theta / 2); + if (std::fabs(sinSqDiff) < epsilon) { chi = qc::PI; - if (std::fabs(cos(theta_max / 2)) < epsilon) { // Periodicity covered? + if (std::fabs(cos(thetaMax / 2)) < epsilon) { // Periodicity covered? alpha = 0; } else { alpha = qc::PI_2; } } else { - qc::fp kappa = - std::sqrt((sin(angles[0] / 2) * sin(angles[0] / 2)) / sin_sq_diff); - alpha = atan(cos(theta_max / 2) * kappa); + const auto kappa = + std::sqrt((sin(angles.theta / 2) * sin(angles.theta / 2)) / sinSqDiff); + alpha = atan(cos(thetaMax / 2) * kappa); chi = fmod(2 * atan(kappa), qc::TAU); } - qc::fp beta = angles[0] < 0 ? -1 * qc::PI_2 : qc::PI_2; - qc::fp gamma_plus = fmod(angles[2] - (alpha + beta), qc::TAU); - qc::fp gamma_minus = fmod(angles[1] - (alpha - beta), qc::TAU); + const auto beta = angles.theta < 0 ? -1 * qc::PI_2 : qc::PI_2; - return {chi, gamma_minus, gamma_plus}; + return {.theta = beta, + .phi = fmod(angles.phi - (alpha - beta), qc::TAU), + .lambda = fmod(angles.lambda - (alpha + beta), qc::TAU)}; } auto NativeGateDecomposer::decompose( @@ -212,303 +210,258 @@ auto NativeGateDecomposer::decompose( const std::vector& singleQubitGateLayers, const std::vector& twoQubitGateLayers) const -> DecompositionResult { - nQubits_ = nQubits; - - std::vector> U3Layers = - transformToU3(schedule.first, nQubits); - std::vector NewTwoQubitGateLayers = schedule.second; - + auto u3Layers = transformToU3(singleQubitGateLayers, nQubits); + std::vector newTwoQubitLayers; if (config_.thetaOptSchedule) { - auto thetaOptSchedule = - schedule_theta_opt(std::pair(U3Layers, NewTwoQubitGateLayers), nQubits); - U3Layers = thetaOptSchedule.first; - NewTwoQubitGateLayers = thetaOptSchedule.second; + auto schedule = + scheduleThetaOpt(std::pair(u3Layers, twoQubitGateLayers), nQubits); + u3Layers = schedule.first; + newTwoQubitLayers = schedule.second; + } else { + newTwoQubitLayers = twoQubitGateLayers; } - std::vector NewSingleQubitLayers = - std::vector{}; - - for (const auto& layer : U3Layers) { - qc::fp theta_max = calcThetaMax(layer); - SingleQubitGateLayer FrontLayer; - SingleQubitGateLayer MidLayer; - SingleQubitGateLayer BackLayer; - SingleQubitGateLayer NewLayer = {}; + std::vector newSingleQubitLayers; + for (const auto& layer : u3Layers) { + const auto thetaMax = calcThetaMax(layer); + SingleQubitGateLayer frontLayer; + SingleQubitGateLayer midLayer; + SingleQubitGateLayer backLayer; + auto& newLayer = newSingleQubitLayers.emplace_back(); for (auto gate : layer) { - std::array decomp_angles = - getDecompositionAngles(gate.angles, theta_max); - - // GR(theta_max/2, PI_2)==Global Y due to PI_2 - FrontLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[1]}))); - - MidLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[0]}))); - - BackLayer.emplace_back(std::make_unique( - qc::StandardOperation(gate.qubit, qc::RZ, {decomp_angles[2]}))); - } // gate::layer + const auto& [theta, phi, lambda] = + getDecompositionAngles(gate.angles, thetaMax); + frontLayer.emplace_back(std::make_unique( + gate.qubit, qc::RZ, std::vector{phi})); + midLayer.emplace_back(std::make_unique( + gate.qubit, qc::RZ, std::vector{theta})); + backLayer.emplace_back(std::make_unique( + gate.qubit, qc::RZ, std::vector{lambda})); + } if (!layer.empty()) { - std::vector> GR_plus; - std::vector> GR_minus; - - for (size_t i = 0; i < this->nQubits_; ++i) { - GR_plus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{theta_max / 2})); - GR_minus.emplace_back(std::make_unique( - i, qc::RY, std::initializer_list{-1 * theta_max / 2})); - } - - for (auto&& gate : FrontLayer) { - NewLayer.push_back(std::move(gate)); - } - - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_plus), true))); - - for (auto&& gate : MidLayer) { - NewLayer.push_back(std::move(gate)); - } - NewLayer.emplace_back(std::make_unique( - qc::CompoundOperation(std::move(GR_minus), true))); - - for (auto&& gate : BackLayer) { - NewLayer.push_back(std::move(gate)); + std::vector> globalRotation; + std::vector> globalReversRotation; + for (size_t i = 0; i < nQubits; ++i) { + globalRotation.emplace_back(std::make_unique( + i, qc::RY, std::vector{thetaMax / 2})); + globalReversRotation.emplace_back( + std::make_unique( + i, qc::RY, std::vector{-thetaMax / 2})); } + // combine all lists into a flat list + std::ranges::move(frontLayer, std::back_inserter(newLayer)); + newLayer.emplace_back(std::make_unique( + std::move(globalRotation), true)); + std::ranges::move(midLayer, std::back_inserter(newLayer)); + newLayer.emplace_back(std::make_unique( + std::move(globalReversRotation), true)); + std::ranges::move(backLayer, std::back_inserter(newLayer)); } - NewSingleQubitLayers.push_back(std::move(NewLayer)); - } // layer::SingleQubitLayers - return {std::move(NewSingleQubitLayers), NewTwoQubitGateLayers}; + } + return {.singleQubitLayers = std::move(newSingleQubitLayers), + .twoQubitLayers = std::move(newTwoQubitLayers)}; } -auto NativeGateDecomposer::find_cheapest_path( +auto NativeGateDecomposer::findCheapestPath( const DiGraph, - std::vector>>& subproblem_graph, - const std::vector& leaf_nodes) -> std::vector { - std::set leaves = - std::set(leaf_nodes.begin(), leaf_nodes.end()); - // Memory Map : Subprob NOdes as keys - std::map, qc::fp>> memo = {}; - std::pair, double> leaf_path = - cheapest_path_to_start(subproblem_graph, 0, leaves, memo); - std::ranges::reverse(leaf_path.first); - - return {leaf_path.first.begin() + 1, leaf_path.first.end()}; + std::vector>>& subproblemGraph, + const std::vector& leafNodes) -> std::vector { + const std::set leaves(leafNodes.begin(), leafNodes.end()); + // Memory Map : Sub-problem nodes as keys + std::map, qc::fp>> memo; + auto [path, cost] = cheapestPathToStart(subproblemGraph, 0, leaves, memo); + path.resize(path.size() - 1); + std::ranges::reverse(path); + return path; } auto disjunct(const std::set& set1, const std::set& set2) -> bool { - for (auto elem : set1) { - if (set2.contains(elem)) { - return false; - } - } - return true; + return std::ranges::all_of(set1, + [&](auto elem) { return !set2.contains(elem); }); } auto disjunct(const std::set& set1, const std::set& set2) -> bool { - for (auto elem : set1) { - if (set2.contains(elem)) { - return false; - } - } - return true; + return std::ranges::all_of(set1, + [&](auto elem) { return !set2.contains(elem); }); } -auto NativeGateDecomposer::cheapest_path_to_start( +auto NativeGateDecomposer::cheapestPathToStart( const DiGraph, - std::vector>>& subproblem_graph, - std::size_t current_node, const std::set& leaf_nodes, + std::vector>>& subproblemGraph, + std::size_t currentNode, const std::set& leafNodes, std::map, qc::fp>>& memo) -> std::pair, double> { - std::vector, double>> possible_paths = {}; + std::vector, double>> possiblePaths; // Check if leaf nodes are reached - if (memo.contains(current_node)) { - return memo.at(current_node); + if (memo.contains(currentNode)) { + return memo.at(currentNode); } - // Base Case: - for (auto edge : subproblem_graph.get_adjacent(current_node)) { - if (leaf_nodes.contains(edge.first)) { - possible_paths.push_back({std::pair, double>( - {edge.first, current_node}, edge.second)}); + for (auto [source, target] : subproblemGraph.getAdjacent(currentNode)) { + if (leafNodes.contains(source)) { + possiblePaths.emplace_back(std::vector{source, currentNode}, target); } } // Recursive Case - if (possible_paths.empty()) { - for (auto edge : subproblem_graph.get_adjacent(current_node)) { - auto path = cheapest_path_to_start(subproblem_graph, edge.first, - leaf_nodes, memo); - // Check if current node is already in path. If so don't add - // std::set path_nodes=std::set(path.first.begin(), - // path.first.end()); - // if (!path_nodes.contains(current_node)) { - path.first.push_back(current_node); - path.second += edge.second; - possible_paths.push_back(path); - // } + if (possiblePaths.empty()) { + for (auto [source, target] : subproblemGraph.getAdjacent(currentNode)) { + auto path = cheapestPathToStart(subproblemGraph, source, leafNodes, memo); + path.first.emplace_back(currentNode); + path.second += target; + possiblePaths.emplace_back(path); } } - - // Choose cheapest Paths - if (possible_paths.size() == 1) { - return possible_paths.at(0); - } - // Find shortest path with minimal cost - auto min_cost = possible_paths.at(0).second; - auto best_path = possible_paths.at(0); - for (const auto& path : possible_paths) { - if (path.second < min_cost) { - min_cost = path.second; - best_path = path; - } - } - memo[current_node] = best_path; - return best_path; + // Choose the cheapest path + assert(!possiblePaths.empty() && "No path found to leaf nodes."); + const auto& bestPathWithCost = *std::ranges::min_element( + possiblePaths, + [](const auto& a, const auto& b) { return a.second < b.second; }); + memo[currentNode] = bestPathWithCost; + return bestPathWithCost; } -auto NativeGateDecomposer::find_leaf_nodes( +auto NativeGateDecomposer::findLeafNodes( const DiGraph, - std::vector>>& subproblem_graph) + std::vector>>& subproblemGraph) -> std::vector { - std::vector end_nodes = std::vector{}; - for (size_t i = 0; i < subproblem_graph.size(); i++) { - if (subproblem_graph.get_adjacent(i).empty()) { - end_nodes.push_back(i); - } - } - return end_nodes; + std::vector leafNodes; + std::ranges::copy(std::views::iota(subproblemGraph.size()) | + std::views::filter([&subproblemGraph](auto i) -> bool { + return subproblemGraph.getAdjacent(i).empty(); + }), + std::back_inserter(leafNodes)); + return leafNodes; } -auto NativeGateDecomposer::remove_element( - const std::vector& vector, std::size_t elem) +auto NativeGateDecomposer::removeElement(const std::vector& vector, + const std::size_t elem) -> std::vector { - std::vector new_vector = {}; + std::vector newVector; for (auto element : vector) { if (element != elem) { - new_vector.push_back(element); + newVector.emplace_back(element); } } - return new_vector; + return newVector; } -auto NativeGateDecomposer::get_possible_moments( +auto NativeGateDecomposer::getPossibleMoments( DiGraph>>& circuit, - const std::vector& v0_c, - const std::array, 3>& v_new, bool check_final_cond) + const std::vector& v0Current, + const std::array, 3>& vNew, bool checkFinalCond) -> std::vector, 4>, qc::fp>> { - std::vector v_p1_star = v_new[0]; - std::vector v_p1_square = {}; - std::vector v_c1_star = v_new[1]; - std::vector v_c1_square = {}; + std::vector vP1Star = vNew[0]; + std::vector vP1Square = {}; + std::vector vc1Star = vNew[1]; + std::vector vc1Square = {}; - qc::fp v_c0_cost = max_theta(circuit, v0_c); - qc::fp v_c1_cost = max_theta(circuit, v_new[1]); - qc::fp orig_comb_cost = v_c0_cost + v_c1_cost; - qc::fp new_v_c1_cost = std::max(v_c0_cost, v_c1_cost); + qc::fp vc0Cost = maxTheta(circuit, v0Current); + qc::fp vc1Cost = maxTheta(circuit, vNew[1]); + qc::fp origCombCost = vc0Cost + vc1Cost; + qc::fp newVc1Cost = std::max(vc0Cost, vc1Cost); - std::array, 4> v_arg = {v0_c, v_new[0], v_new[1], - v_new[2]}; + std::array, 4> vArg = {v0Current, vNew[0], vNew[1], + vNew[2]}; std::vector, 4>, qc::fp>> args = - {std::pair(v_arg, v_c0_cost)}; + {std::pair(vArg, vc0Cost)}; // Sort v_0C from highest to lowest theta - std::vector v_sort(v0_c); - auto sort_by_theta = [&circuit](std::size_t a, std::size_t b) -> bool { - return std::fabs(std::get(circuit.get_Node_Value(a)).angles[0]) > - std::fabs(std::get(circuit.get_Node_Value(b)).angles[0]); + std::vector vSort(v0Current); + auto sortByTheta = [&circuit](std::size_t a, std::size_t b) -> bool { + return std::fabs(std::get(circuit.getNodeValue(a)).angles.theta) > + std::fabs(std::get(circuit.getNodeValue(b)).angles.theta); }; - std::ranges::sort(v_sort, sort_by_theta); + std::ranges::sort(vSort, sortByTheta); // TODO: Check Condition 1 std::vector, 2>, std::pair, qc::fp>>> - potential_arg = {}; - auto prev_theta = std::fabs( - std::get(circuit.get_Node_Value(v_sort[0])).angles[0]); - auto this_theta = prev_theta; - std::set mk_qubits = { - std::get(circuit.get_Node_Value(v_sort[0])).qubit}; - for (auto i = 0; static_cast(i) < v_sort.size(); i++) { - this_theta = - std::fabs(std::get( - circuit.get_Node_Value(v_sort[static_cast(i)])) - .angles[0]); - if (this_theta != prev_theta) { - std::vector discarded = {v_sort.begin(), v_sort.begin() + i}; - std::vector kept = {v_sort.begin() + i, v_sort.end()}; - potential_arg.push_back(std::pair, 2>, - std::pair, qc::fp>>( - {kept, discarded}, - std::pair, qc::fp>(mk_qubits, this_theta))); - prev_theta = this_theta; - mk_qubits.clear(); - } - mk_qubits.insert(std::get( - circuit.get_Node_Value(v_sort[static_cast(i)])) - .qubit); + potentialArg = {}; + auto prevTheta = std::fabs( + std::get(circuit.getNodeValue(vSort[0])).angles.theta); + auto thisTheta = prevTheta; + std::set mkQubits = { + std::get(circuit.getNodeValue(vSort[0])).qubit}; + for (auto i = 0; static_cast(i) < vSort.size(); i++) { + thisTheta = std::fabs( + std::get(circuit.getNodeValue(vSort[static_cast(i)])) + .angles.theta); + if (thisTheta != prevTheta) { + std::vector discarded = {vSort.begin(), vSort.begin() + i}; + std::vector kept = {vSort.begin() + i, vSort.end()}; + potentialArg.emplace_back( + std::pair, 2>, + std::pair, qc::fp>>( + {kept, discarded}, + std::pair, qc::fp>(mkQubits, thisTheta))); + prevTheta = thisTheta; + mkQubits.clear(); + } + mkQubits.insert( + std::get(circuit.getNodeValue(vSort[static_cast(i)])) + .qubit); } - std::vector push_back_nodes = {}; - std::set p_square_qubits = {}; + std::vector emplaceBackNodes = {}; + std::set pSquareQubits = {}; - for (auto pot : potential_arg) { + for (auto pot : potentialArg) { // TODO: Check Condition 2 - for (auto node : v_p1_star) { + for (auto node : vP1Star) { std::set qubits = { - std::get>(circuit.get_Node_Value(node))[0], - std::get>(circuit.get_Node_Value(node))[1]}; + std::get>(circuit.getNodeValue(node))[0], + std::get>(circuit.getNodeValue(node))[1]}; if (!disjunct(qubits, pot.second.first)) { - push_back_nodes.emplace_back(node); - p_square_qubits.merge(qubits); + emplaceBackNodes.emplace_back(node); + pSquareQubits.merge(qubits); } } - for (auto node : push_back_nodes) { - v_p1_star = remove_element(v_p1_star, node); - v_p1_square.emplace_back(node); + for (auto node : emplaceBackNodes) { + const auto ret = std::ranges::remove(vP1Star, node); + vP1Star.erase(ret.begin(), ret.end()); + vP1Square.emplace_back(node); } - if (v_p1_star.empty()) { + if (vP1Star.empty()) { break; } // TODO: Check Condition 3 - std::set push_qubits = pot.second.first; - push_qubits.merge(p_square_qubits); - push_back_nodes.clear(); - - for (auto node : v_c1_star) { - std::set qubits = { - std::get(circuit.get_Node_Value(node)).qubit}; - if (!disjunct(qubits, push_qubits)) { - push_back_nodes.emplace_back(node); + std::set pushQubits = pot.second.first; + pushQubits.merge(pSquareQubits); + emplaceBackNodes.clear(); + + for (auto node : vc1Star) { + std::set qubits = {std::get(circuit.getNodeValue(node)).qubit}; + if (!disjunct(qubits, pushQubits)) { + emplaceBackNodes.emplace_back(node); } } - for (auto node : push_back_nodes) { - v_c1_star = remove_element(v_c1_star, node); - v_c1_square.emplace_back(node); + for (auto node : emplaceBackNodes) { + vc1Star = removeElement(vc1Star, node); + vc1Square.emplace_back(node); } - if (v_c1_star.empty()) { + if (vc1Star.empty()) { break; } // TODO Check Condition 4 - if (!check_final_cond || - pot.second.second + new_v_c1_cost < orig_comb_cost) { - v_arg = {pot.first[0], v_p1_star, pot.first[1], v_new[2]}; - for (auto node : v_c1_star) { - v_arg[2].push_back(node); + if (!checkFinalCond || pot.second.second + newVc1Cost < origCombCost) { + vArg = {pot.first[0], vP1Star, pot.first[1], vNew[2]}; + for (auto node : vc1Star) { + vArg[2].emplace_back(node); } - for (auto node : v_c1_square) { - v_arg[3].push_back(node); + for (auto node : vc1Square) { + vArg[3].emplace_back(node); } - for (auto node : v_p1_square) { - v_arg[3].push_back(node); + for (auto node : vP1Square) { + vArg[3].emplace_back(node); } - args.emplace_back(v_arg, pot.second.second); + args.emplace_back(vArg, pot.second.second); } } return args; } -auto NativeGateDecomposer::convert_circ_to_dag( +auto NativeGateDecomposer::convertCircuitToDAG( const std::pair>, std::vector>& schedule, std::size_t nQubits) @@ -517,44 +470,45 @@ auto NativeGateDecomposer::convert_circ_to_dag( // For Readout: DiGraph>> graph = DiGraph>>(); - std::vector> qubit_paths(nQubits); + std::vector> qubitPaths(nQubits); // TODO:assert that One more sql exists than mql ?? for (size_t i = 0; i < schedule.second.size(); ++i) { for (const auto& s : schedule.first.at(i)) { size_t node = graph.add_Node(s); - qubit_paths.at(s.qubit).push_back(node); + qubitPaths.at(s.qubit).emplace_back(node); } for (const auto& gate : schedule.second.at(i)) { size_t node = graph.add_Node(gate); - qubit_paths.at(gate[0]).push_back(node); - qubit_paths.at(gate[1]).push_back(node); + qubitPaths.at(gate[0]).emplace_back(node); + qubitPaths.at(gate[1]).emplace_back(node); } } SPDLOG_DEBUG("Added Nodes"); for (const auto& s : schedule.first.back()) { size_t node = graph.add_Node(s); - qubit_paths.at(s.qubit).push_back(node); + qubitPaths.at(s.qubit).emplace_back(node); } - for (std::size_t i = 0; i < qubit_paths.size(); ++i) { - if (qubit_paths.at(i).size() > 0) { - for (std::size_t op = 0; op < (qubit_paths.at(i).size() - 1); ++op) { - graph.add_Edge(qubit_paths.at(i).at(op), qubit_paths.at(i).at(op + 1)); + for (std::size_t i = 0; i < qubitPaths.size(); ++i) { + if (qubitPaths.at(i).size() > 0) { + for (std::size_t op = 0; op < (qubitPaths.at(i).size() - 1); ++op) { + graph.addEdge(qubitPaths.at(i).at(op), qubitPaths.at(i).at(op + 1)); } } } return graph; } -auto NativeGateDecomposer::max_theta( +auto NativeGateDecomposer::maxTheta( DiGraph>>& circuit, const std::vector& nodes) -> qc::fp { qc::fp max_cost = 0; for (const auto node : nodes) { - if (std::fabs(std::get(circuit.get_Node_Value(node)).angles[0]) >= + if (std::fabs( + std::get(circuit.getNodeValue(node)).angles.theta) >= max_cost) { - max_cost = - std::fabs(std::get(circuit.get_Node_Value(node)).angles[0]); + max_cost = std::fabs( + std::get(circuit.getNodeValue(node)).angles.theta); } } return max_cost; @@ -563,53 +517,53 @@ auto NativeGateDecomposer::sift( DiGraph>>& circuit, std::vector v, size_t nQubits) -> std::array, 3> { - std::vector v_p = std::vector(); + std::vector vp = std::vector(); std::vector v_c = std::vector(); - std::vector v_r = std::vector(); + std::vector vr = std::vector(); - std::set v_rem = std::set(v.begin(), v.end()); + std::set vRemaining = std::set(v.begin(), v.end()); std::set removed = std::set(); // We traverse the graph rather than v_rem to use the graph's topological // ordering for (size_t node = 0; node < circuit.size(); node++) { - if (v_rem.contains(node)) { - auto op = circuit.get_Node_Value(node); - std::set op_qubits = std::set(); + if (vRemaining.contains(node)) { + auto op = circuit.getNodeValue(node); + std::set opQubits = std::set(); if (std::holds_alternative(op)) { - op_qubits = {std::get(op).qubit}; + opQubits = {std::get(op).qubit}; } else { - op_qubits = {std::get>(op)[0], - std::get>(op)[1]}; + opQubits = {std::get>(op)[0], + std::get>(op)[1]}; } - if (removed.size() < nQubits && disjunct(removed, op_qubits)) { + if (removed.size() < nQubits && disjunct(removed, opQubits)) { if (std::holds_alternative(op)) { - v_c.push_back(node); + v_c.emplace_back(node); removed.insert(std::get(op).qubit); } else { - v_p.push_back(node); + vp.emplace_back(node); } } else { - v_r.push_back(node); - for (auto qubit : op_qubits) { + vr.emplace_back(node); + for (auto qubit : opQubits) { removed.insert(qubit); } } } } - return std::array, 3>({v_p, v_c, v_r}); + return std::array, 3>{{vp, v_c, vr}}; } -auto NativeGateDecomposer::build_schedule( +auto NativeGateDecomposer::buildSchedule( DiGraph>>& circuit, DiGraph, std::vector>>& - subproblem_graph) -> std::pair>, - std::vector> { + subproblemGraph) -> std::pair>, + std::vector> { - std::vector leaf_nodes = find_leaf_nodes(subproblem_graph); - std::vector minimal_path = - find_cheapest_path(subproblem_graph, leaf_nodes); + std::vector leafNodes = findLeafNodes(subproblemGraph); + std::vector minimalPath = + findCheapestPath(subproblemGraph, leafNodes); std::pair>, std::vector> schedule = std::pair>, std::vector>{}; @@ -617,123 +571,122 @@ auto NativeGateDecomposer::build_schedule( std::vector singleQubitGates; std::vector> twoQubitGates; - if (!subproblem_graph.get_Node_Value(minimal_path[0]).first.empty()) { - schedule.first.push_back({}); + if (!subproblemGraph.getNodeValue(minimalPath[0]).first.empty()) { + schedule.first.emplace_back(); } - std::set used_qubits{}; + std::set usedQubits{}; - for (std::size_t i = 0; i < minimal_path.size(); i++) { + for (std::size_t i = 0; i < minimalPath.size(); i++) { singleQubitGates.clear(); twoQubitGates.clear(); - used_qubits.clear(); + usedQubits.clear(); - for (auto j : subproblem_graph.get_Node_Value(minimal_path[i]).first) { - auto op = circuit.get_Node_Value(j); + for (auto j : subproblemGraph.getNodeValue(minimalPath[i]).first) { + auto op = circuit.getNodeValue(j); if (std::holds_alternative>(op)) { // TODO: Check if TWOQUBIT GATES Can be executed in parallel!! auto gate = std::get>(op); - if (used_qubits.contains(gate[0]) || used_qubits.contains(gate[1])) { - schedule.second.push_back(twoQubitGates); - schedule.first.push_back({}); + if (usedQubits.contains(gate[0]) || usedQubits.contains(gate[1])) { + schedule.second.emplace_back(twoQubitGates); + schedule.first.emplace_back(); twoQubitGates.clear(); - used_qubits.clear(); + usedQubits.clear(); } - used_qubits.insert(gate[0]); - used_qubits.insert(gate[1]); + usedQubits.insert(gate[0]); + usedQubits.insert(gate[1]); twoQubitGates.emplace_back(gate); } } - for (auto j : subproblem_graph.get_Node_Value(minimal_path[i]).second) { - auto op = circuit.get_Node_Value(j); + for (auto j : subproblemGraph.getNodeValue(minimalPath[i]).second) { + auto op = circuit.getNodeValue(j); if (std::holds_alternative(op)) { singleQubitGates.emplace_back(std::get(op)); } } - schedule.first.push_back(singleQubitGates); - if (i != 0 || - !subproblem_graph.get_Node_Value(minimal_path[0]).first.empty()) { - schedule.second.push_back(twoQubitGates); + schedule.first.emplace_back(singleQubitGates); + if (i != 0 || !subproblemGraph.getNodeValue(minimalPath[0]).first.empty()) { + schedule.second.emplace_back(twoQubitGates); } } return schedule; } -auto NativeGateDecomposer::add_node_to_sub_prob_graph( - const std::vector& v_p, const std::vector& v_c, qc::fp cost, +auto NativeGateDecomposer::addNodeToSubproblemGraph( + const std::vector& vp, const std::vector& vc, qc::fp cost, DiGraph, std::vector>>& - subproblem_graph, - std::size_t prev_node) -> size_t { - std::size_t new_node = subproblem_graph.add_Node(std::pair(v_p, v_c)); - subproblem_graph.add_Edge(prev_node, new_node, cost); - return new_node; + subproblemGraph, + std::size_t prevNode) -> size_t { + std::size_t newNode = subproblemGraph.add_Node(std::pair(vp, vc)); + subproblemGraph.addEdge(prevNode, newNode, cost); + return newNode; } -auto NativeGateDecomposer::schedule_remaining( +auto NativeGateDecomposer::scheduleRemaining( const std::array, 3>& v, DiGraph>>& circuit, DiGraph, std::vector>>& - subproblem_graph, - size_t prev_node, size_t nQubits, bool check_final_cond, + subproblemGraph, + size_t prevNode, size_t nQubits, bool checkFinalCond, std::map>>& memo) -> double { double cost; // TODO: Check if subproblem has been computed std::size_t id = std::hash, 3>>{}(v); if (memo.contains(id)) { - std::size_t sub_node = memo.at(id).first; - double edge_weight = memo.at(id).second[1]; + std::size_t subNode = memo.at(id).first; + double edgeWeight = memo.at(id).second[1]; cost = memo.at(id).second[0]; - subproblem_graph.add_Edge(prev_node, sub_node, edge_weight); + subproblemGraph.addEdge(prevNode, subNode, edgeWeight); return cost; } // TODO: Base Case-> V_rem is empty if (v[2].empty()) { - // TODO:DEcide if I need if to check for TWO QUBIT + // TODO:Decide if I need if to check for TWO QUBIT if (v[1].empty()) { cost = 0; } else { cost = std::fabs( - std::get(circuit.get_Node_Value(v[1].at(0))).angles[0]); + std::get(circuit.getNodeValue(v[1].at(0))).angles.theta); } for (std::size_t i : v[1]) { - if (std::get(circuit.get_Node_Value(i)).angles[0] > cost) { + if (std::get(circuit.getNodeValue(i)).angles.theta > cost) { cost = - std::fabs(std::get(circuit.get_Node_Value(i)).angles[0]); + std::fabs(std::get(circuit.getNodeValue(i)).angles.theta); } } - auto end_node = add_node_to_sub_prob_graph(v[0], v[1], cost, - subproblem_graph, prev_node); + auto end_node = + addNodeToSubproblemGraph(v[0], v[1], cost, subproblemGraph, prevNode); memo[id] = std::pair>( end_node, {cost, cost}); // TODO: Correct to put cost for both??? return cost; } // TODO: Recursive Call: Only - auto v_new = sift(circuit, v[2], nQubits); - auto args = get_possible_moments(circuit, v[1], v_new, check_final_cond); - qc::fp temp_cost = 0; - double min_cost = std::numeric_limits::max(); - double min_weight = std::numeric_limits::max(); - std::size_t min_node; + auto vNew = sift(circuit, v[2], nQubits); + auto args = getPossibleMoments(circuit, v[1], vNew, checkFinalCond); + qc::fp tempCost = 0; + double minCost = std::numeric_limits::max(); + double minWeight = std::numeric_limits::max(); + std::size_t minNode; for (const auto& val : args) { - auto new_node = add_node_to_sub_prob_graph(v[0], val.first[0], val.second, - subproblem_graph, prev_node); - temp_cost = schedule_remaining({val.first[1], val.first[2], val.first[3]}, - circuit, subproblem_graph, new_node, nQubits, - check_final_cond, memo) + - val.second; - if (temp_cost < min_cost) { - min_cost = temp_cost; - min_node = new_node; - min_weight = val.second; + auto newNode = addNodeToSubproblemGraph(v[0], val.first[0], val.second, + subproblemGraph, prevNode); + tempCost = scheduleRemaining({val.first[1], val.first[2], val.first[3]}, + circuit, subproblemGraph, newNode, nQubits, + checkFinalCond, memo) + + val.second; + if (tempCost < minCost) { + minCost = tempCost; + minNode = newNode; + minWeight = val.second; } } memo[id] = std::pair>( - min_node, {min_cost, min_weight}); - return min_cost; + minNode, {minCost, minWeight}); + return minCost; } -auto NativeGateDecomposer::schedule_theta_opt( +auto NativeGateDecomposer::scheduleThetaOpt( const std::pair>, std::vector>& schedule, std::size_t nQubits) const -> std::pair>, @@ -741,29 +694,29 @@ auto NativeGateDecomposer::schedule_theta_opt( // TODO: Convert Circuit to DAG: How to handle the unique Pointer situation??? DiGraph>> circuit = - convert_circ_to_dag(schedule, nQubits); + convertCircuitToDAG(schedule, nQubits); // TODO: Get initial Moments( Not does MQB THEN SQB!! SOl to get SQB MQB??) std::vector v_start{}; v_start.reserve(circuit.size()); for (size_t i = 0; i < circuit.size(); ++i) { - v_start.push_back(i); + v_start.emplace_back(i); } // v=(v_p,v_c,v_r) std::array, 3> v = sift(circuit, v_start, nQubits); // TODO: Create Subproblem Graph DiGraph, std::vector>> - sub_prob_graph = DiGraph< + subproblemGraph = DiGraph< std::pair, std::vector>>(); // TODO: First Call of Recursive Function to create Schedule - auto base_node = sub_prob_graph.add_Node( + auto baseNode = subproblemGraph.add_Node( std::pair, std::vector>({}, {})); std::map>> memo = {}; - auto cost = schedule_remaining(v, circuit, sub_prob_graph, base_node, nQubits, - config_.checkFinalCond, memo); + auto cost = scheduleRemaining(v, circuit, subproblemGraph, baseNode, nQubits, + config_.checkFinalCond, memo); // TODO: Create Schedule from Subproblem Graph std::pair>, std::vector> - final_circuit = build_schedule(circuit, sub_prob_graph); - return final_circuit; + finalCircuit = buildSchedule(circuit, subproblemGraph); + return finalCircuit; } } // namespace na::zoned diff --git a/test/na/zoned/test_theta_opt_scheduler.cpp b/test/na/zoned/test_theta_opt_scheduler.cpp index 1c144d18d..bd53830b6 100644 --- a/test/na/zoned/test_theta_opt_scheduler.cpp +++ b/test/na/zoned/test_theta_opt_scheduler.cpp @@ -77,13 +77,12 @@ TEST_F(ThetaOptTest, GraphTest) { auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); - auto graph = NativeGateDecomposer::convert_circ_to_dag( + auto graph = NativeGateDecomposer::convertCircuitToDAG( {one_qubit_gates, schedule.second}, n); EXPECT_EQ( - std::get(graph.get_Node_Value(0)).qubit, - 0); + std::get(graph.getNodeValue(0)).qubit, 0); EXPECT_THAT( - std::get(graph.get_Node_Value(0)).angles, + std::get(graph.getNodeValue(0)).angles, ::testing::ElementsAre( ::testing::DoubleNear(one_qubit_gates.front().front().angles.at(0), epsilon), @@ -91,21 +90,20 @@ TEST_F(ThetaOptTest, GraphTest) { epsilon), ::testing::DoubleNear(one_qubit_gates.front().front().angles.at(2), epsilon))); - EXPECT_THAT(graph.get_adjacent(0), + EXPECT_THAT(graph.getAdjacent(0), ::testing::ElementsAre(std::pair(1, 1.0))); - auto tqg = std::get>(graph.get_Node_Value(1)); + auto tqg = std::get>(graph.getNodeValue(1)); EXPECT_THAT(tqg, ::testing::ElementsAre(static_cast(0), static_cast(1))); - EXPECT_THAT(graph.get_adjacent(1), + EXPECT_THAT(graph.getAdjacent(1), ::testing::ElementsAre(std::pair(2, 1.0), std::pair(3, 1.0))); EXPECT_EQ( - std::get(graph.get_Node_Value(2)).qubit, - 0); + std::get(graph.getNodeValue(2)).qubit, 0); EXPECT_THAT( - std::get(graph.get_Node_Value(2)).angles, + std::get(graph.getNodeValue(2)).angles, ::testing::ElementsAre( ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(0), epsilon), @@ -113,13 +111,12 @@ TEST_F(ThetaOptTest, GraphTest) { epsilon), ::testing::DoubleNear(one_qubit_gates.at(1).front().angles.at(2), epsilon))); - EXPECT_THAT(graph.get_adjacent(2), ::testing::IsEmpty()); + EXPECT_THAT(graph.getAdjacent(2), ::testing::IsEmpty()); EXPECT_EQ( - std::get(graph.get_Node_Value(3)).qubit, - 1); + std::get(graph.getNodeValue(3)).qubit, 1); EXPECT_THAT( - std::get(graph.get_Node_Value(3)).angles, + std::get(graph.getNodeValue(3)).angles, ::testing::ElementsAre( ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(0), epsilon), @@ -127,7 +124,7 @@ TEST_F(ThetaOptTest, GraphTest) { epsilon), ::testing::DoubleNear(one_qubit_gates.at(1).at(1).angles.at(2), epsilon))); - EXPECT_THAT(graph.get_adjacent(3), ::testing::IsEmpty()); + EXPECT_THAT(graph.getAdjacent(3), ::testing::IsEmpty()); } TEST_F(ThetaOptTest, SiftTest) { @@ -156,7 +153,7 @@ TEST_F(ThetaOptTest, SiftTest) { auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); - auto graph = NativeGateDecomposer::convert_circ_to_dag( + auto graph = NativeGateDecomposer::convertCircuitToDAG( {one_qubit_gates, schedule.second}, n); // Perform Sift (multiple times???) @@ -207,7 +204,7 @@ TEST_F(ThetaOptTest, NextMomentsPushTest) { qc.cz(0, 2); auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); - auto graph = NativeGateDecomposer::convert_circ_to_dag( + auto graph = NativeGateDecomposer::convertCircuitToDAG( {one_qubit_gates, schedule.second}, n); auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); NativeGateDecomposer::DiGraph< @@ -217,7 +214,7 @@ TEST_F(ThetaOptTest, NextMomentsPushTest) { std::pair, std::vector>({}, {})); auto v_new = NativeGateDecomposer::sift(graph, v[2], n); auto moments = - NativeGateDecomposer::get_possible_moments(graph, v[1], v_new, false); + NativeGateDecomposer::getPossibleMoments(graph, v[1], v_new, false); EXPECT_EQ(moments.size(), 2); @@ -257,7 +254,7 @@ TEST_F(ThetaOptTest, NextMomentsCond2Test) { qc.cz(0, 2); auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); - auto graph = NativeGateDecomposer::convert_circ_to_dag( + auto graph = NativeGateDecomposer::convertCircuitToDAG( {one_qubit_gates, schedule.second}, n); auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); NativeGateDecomposer::DiGraph< @@ -267,7 +264,7 @@ TEST_F(ThetaOptTest, NextMomentsCond2Test) { std::pair, std::vector>({}, {})); auto v_new = NativeGateDecomposer::sift(graph, v[2], n); auto moments = - NativeGateDecomposer::get_possible_moments(graph, v[1], v_new, false); + NativeGateDecomposer::getPossibleMoments(graph, v[1], v_new, false); EXPECT_EQ(moments.size(), 1); @@ -300,7 +297,7 @@ TEST_F(ThetaOptTest, NextMomentsCond3Test) { qc.cz(0, 2); auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); - auto graph = NativeGateDecomposer::convert_circ_to_dag( + auto graph = NativeGateDecomposer::convertCircuitToDAG( {one_qubit_gates, schedule.second}, n); auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); NativeGateDecomposer::DiGraph< @@ -310,7 +307,7 @@ TEST_F(ThetaOptTest, NextMomentsCond3Test) { std::pair, std::vector>({}, {})); auto v_new = NativeGateDecomposer::sift(graph, v[2], n); auto moments = - NativeGateDecomposer::get_possible_moments(graph, v[1], v_new, false); + NativeGateDecomposer::getPossibleMoments(graph, v[1], v_new, false); EXPECT_EQ(moments.size(), 1); @@ -356,7 +353,7 @@ TEST_F(ThetaOptTest, RecursionBaseTest) { auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); - auto graph = NativeGateDecomposer::convert_circ_to_dag( + auto graph = NativeGateDecomposer::convertCircuitToDAG( {one_qubit_gates, schedule.second}, n); auto v = NativeGateDecomposer::sift(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8}, n); NativeGateDecomposer::DiGraph< @@ -366,50 +363,50 @@ TEST_F(ThetaOptTest, RecursionBaseTest) { std::pair, std::vector>({}, {})); std::map>> memo = std::map>>(); - auto result = NativeGateDecomposer::schedule_remaining( + auto result = NativeGateDecomposer::scheduleRemaining( v, graph, subproblem_graph, 0, n, false, memo); EXPECT_EQ(result, 5 * qc::PI_2); EXPECT_EQ(subproblem_graph.size(), 1 + 6); - auto t = subproblem_graph.get_adjacent(0); - EXPECT_THAT(subproblem_graph.get_adjacent(0), + auto t = subproblem_graph.getAdjacent(0); + EXPECT_THAT(subproblem_graph.getAdjacent(0), ::testing::UnorderedElementsAre(::testing::Pair(1, qc::PI), ::testing::Pair(4, qc::PI_4))); - EXPECT_THAT(subproblem_graph.get_Node_Value(1).first, ::testing::IsEmpty()); - EXPECT_THAT(subproblem_graph.get_Node_Value(1).second, + EXPECT_THAT(subproblem_graph.getNodeValue(1).first, ::testing::IsEmpty()); + EXPECT_THAT(subproblem_graph.getNodeValue(1).second, ::testing::UnorderedElementsAre(0, 1)); - EXPECT_THAT(subproblem_graph.get_adjacent(1), + EXPECT_THAT(subproblem_graph.getAdjacent(1), ::testing::UnorderedElementsAre(::testing::Pair(2, qc::PI))); - EXPECT_THAT(subproblem_graph.get_Node_Value(2).first, + EXPECT_THAT(subproblem_graph.getNodeValue(2).first, ::testing::UnorderedElementsAre(2, 4)); - EXPECT_THAT(subproblem_graph.get_Node_Value(2).second, + EXPECT_THAT(subproblem_graph.getNodeValue(2).second, ::testing::UnorderedElementsAre(3, 5, 6)); - EXPECT_THAT(subproblem_graph.get_adjacent(2), + EXPECT_THAT(subproblem_graph.getAdjacent(2), ::testing::UnorderedElementsAre(::testing::Pair(3, qc::PI_2))); - EXPECT_THAT(subproblem_graph.get_Node_Value(3).first, + EXPECT_THAT(subproblem_graph.getNodeValue(3).first, ::testing::UnorderedElementsAre(7)); - EXPECT_THAT(subproblem_graph.get_Node_Value(3).second, + EXPECT_THAT(subproblem_graph.getNodeValue(3).second, ::testing::UnorderedElementsAre(8)); - EXPECT_THAT(subproblem_graph.get_adjacent(3), ::testing::IsEmpty()); + EXPECT_THAT(subproblem_graph.getAdjacent(3), ::testing::IsEmpty()); - EXPECT_THAT(subproblem_graph.get_Node_Value(4).first, ::testing::IsEmpty()); - EXPECT_THAT(subproblem_graph.get_Node_Value(4).second, + EXPECT_THAT(subproblem_graph.getNodeValue(4).first, ::testing::IsEmpty()); + EXPECT_THAT(subproblem_graph.getNodeValue(4).second, ::testing::UnorderedElementsAre(1)); - EXPECT_THAT(subproblem_graph.get_adjacent(4), + EXPECT_THAT(subproblem_graph.getAdjacent(4), ::testing::UnorderedElementsAre(::testing::Pair(5, qc::PI))); - EXPECT_THAT(subproblem_graph.get_Node_Value(5).first, + EXPECT_THAT(subproblem_graph.getNodeValue(5).first, ::testing::UnorderedElementsAre(2)); - EXPECT_THAT(subproblem_graph.get_Node_Value(5).second, + EXPECT_THAT(subproblem_graph.getNodeValue(5).second, ::testing::UnorderedElementsAre(0, 3)); - EXPECT_THAT(subproblem_graph.get_adjacent(5), + EXPECT_THAT(subproblem_graph.getAdjacent(5), ::testing::UnorderedElementsAre(::testing::Pair(6, qc::PI))); - EXPECT_THAT(subproblem_graph.get_Node_Value(6).first, + EXPECT_THAT(subproblem_graph.getNodeValue(6).first, ::testing::UnorderedElementsAre(4)); - EXPECT_THAT(subproblem_graph.get_Node_Value(6).second, + EXPECT_THAT(subproblem_graph.getNodeValue(6).second, ::testing::UnorderedElementsAre(5, 6)); - EXPECT_THAT(subproblem_graph.get_adjacent(6), + EXPECT_THAT(subproblem_graph.getAdjacent(6), ::testing::UnorderedElementsAre(::testing::Pair(3, qc::PI_2))); } @@ -422,23 +419,23 @@ TEST_F(ThetaOptTest, CheapestPathTest) { subproblem_graph.add_Node( std::pair, std::vector>({}, {})); } - subproblem_graph.add_Edge(0, 1); - subproblem_graph.add_Edge(0, 2); - subproblem_graph.add_Edge(0, 3, 0.5); - subproblem_graph.add_Edge(1, 4); - subproblem_graph.add_Edge(2, 5); - subproblem_graph.add_Edge(3, 6); - subproblem_graph.add_Edge(3, 7); - subproblem_graph.add_Edge(4, 8); - subproblem_graph.add_Edge(5, 8); - subproblem_graph.add_Edge(5, 9); - subproblem_graph.add_Edge(6, 10); - subproblem_graph.add_Edge(7, 11); - subproblem_graph.add_Edge(8, 12); - subproblem_graph.add_Edge(11, 13); - auto leaf_nodes = NativeGateDecomposer::find_leaf_nodes(subproblem_graph); + subproblem_graph.addEdge(0, 1); + subproblem_graph.addEdge(0, 2); + subproblem_graph.addEdge(0, 3, 0.5); + subproblem_graph.addEdge(1, 4); + subproblem_graph.addEdge(2, 5); + subproblem_graph.addEdge(3, 6); + subproblem_graph.addEdge(3, 7); + subproblem_graph.addEdge(4, 8); + subproblem_graph.addEdge(5, 8); + subproblem_graph.addEdge(5, 9); + subproblem_graph.addEdge(6, 10); + subproblem_graph.addEdge(7, 11); + subproblem_graph.addEdge(8, 12); + subproblem_graph.addEdge(11, 13); + auto leaf_nodes = NativeGateDecomposer::findLeafNodes(subproblem_graph); auto path = - NativeGateDecomposer::find_cheapest_path(subproblem_graph, leaf_nodes); + NativeGateDecomposer::findCheapestPath(subproblem_graph, leaf_nodes); EXPECT_THAT(leaf_nodes, ::testing::ElementsAre(9, 10, 12, 13)); EXPECT_THAT(path, ::testing::ElementsAre(3, 6, 10)); } @@ -470,7 +467,7 @@ TEST_F(ThetaOptTest, BuildScheduleTest) { auto asap_schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(asap_schedule.first, n); - auto graph = NativeGateDecomposer::convert_circ_to_dag( + auto graph = NativeGateDecomposer::convertCircuitToDAG( {one_qubit_gates, asap_schedule.second}, n); // Create Basic Subproblem graph from purely sifted schedule @@ -487,13 +484,12 @@ TEST_F(ThetaOptTest, BuildScheduleTest) { {3, 5, 6})); subproblem_graph.add_Node( std::pair, std::vector>({7}, {8})); - subproblem_graph.add_Edge(0, 1, - NativeGateDecomposer::max_theta(graph, {0, 1})); - subproblem_graph.add_Edge(1, 2, - NativeGateDecomposer::max_theta(graph, {3, 5, 6})); - subproblem_graph.add_Edge(2, 3, NativeGateDecomposer::max_theta(graph, {8})); + subproblem_graph.addEdge(0, 1, NativeGateDecomposer::maxTheta(graph, {0, 1})); + subproblem_graph.addEdge(1, 2, + NativeGateDecomposer::maxTheta(graph, {3, 5, 6})); + subproblem_graph.addEdge(2, 3, NativeGateDecomposer::maxTheta(graph, {8})); - auto schedule = NativeGateDecomposer::build_schedule(graph, subproblem_graph); + auto schedule = NativeGateDecomposer::buildSchedule(graph, subproblem_graph); EXPECT_EQ(schedule.first.size(), 4); EXPECT_EQ(schedule.second.size(), 3); @@ -577,7 +573,7 @@ TEST_F(ThetaOptTest, CompleteTestSmall) { auto schedule = scheduler.schedule(qc); auto one_qubit_gates = NativeGateDecomposer::transformToU3(schedule.first, n); auto theta_opt_schedule = - decomposer.schedule_theta_opt({one_qubit_gates, schedule.second}, n); + decomposer.scheduleThetaOpt({one_qubit_gates, schedule.second}, n); EXPECT_EQ(theta_opt_schedule.first.size(), 4); EXPECT_EQ(theta_opt_schedule.second.size(), 3);