QuantumCanvas is a web application designed for parsing, visualizing, optimizing, and converting quantum circuits. It features a Python-based backend with FastAPI and a React/TypeScript frontend.
QuantumCanvas/
├── backend/ # FastAPI application
│ ├── app/
│ │ ├── main.py # FastAPI app initialization and CORS
│ │ ├── models.py # Pydantic models for data structures (CircuitJSON, GateModel, etc.)
│ │ ├── routers/
│ │ │ └── circuit.py # API endpoints for circuit operations
│ │ ├── services/
│ │ │ └── optimization_passes.py # Circuit optimization algorithms
│ │ └── utils/
│ │ └── circuit_conversions.py # Logic for converting between circuit formats
│ ├── tests/ # Pytest unit tests for backend logic
│ ├── pyproject.toml # Project dependencies and metadata (Poetry)
│ └── README.md # Backend specific details (currently empty)
├── frontend/ # React/Vite application
│ ├── public/
│ ├── src/
│ │ ├── App.tsx # Main application component, state management, API calls
│ │ ├── main.tsx # Entry point for the React application
│ │ ├── components/ui/ # Reusable UI components (Button, Textarea, Card, etc.)
│ │ ├── lib/utils.ts # Utility functions (e.g., `cn` for classnames)
│ │ └── index.css # Global styles and TailwindCSS base
│ ├── index.html # Main HTML file
│ ├── vite.config.ts # Vite configuration
│ ├── tailwind.config.js # TailwindCSS configuration
│ ├── tsconfig.json # TypeScript configuration
│ └── package.json # Frontend dependencies and scripts (npm/yarn/pnpm)
└── .gitignore # Git ignore rules for the entire project
The backend is built using FastAPI and handles the core quantum circuit logic.
-
QASM Parsing:
- Incoming OpenQASM 2.0 strings are parsed using Qiskit's
qiskit.qasm2.loadsfunction. - The endpoint
/circuit/parsehandles this. It currently enforces that the input string starts withOPENQASM 2.0;. - The parsed Qiskit
QuantumCircuitis then converted into a customCircuitJSONmodel.
- Incoming OpenQASM 2.0 strings are parsed using Qiskit's
-
Internal Circuit Representation (
CircuitJSON):- Defined in
app/models.py,CircuitJSONis the primary data structure for representing quantum circuits within the backend. - It includes:
num_qubits: Total number of qubits.gates: A list ofGateModelobjects, where eachGateModeldefines the gate's name, targets, controls (optional), and parameters (optional).metadata: Optional information like circuit name.gate_counts: A dictionary palavras-chaveing gate names to their counts.depth: The depth of the circuit.
- Gate counts and depth are calculated during the conversion from Qiskit's format.
- Defined in
-
Circuit Optimization:
- The
/circuit/optimizeendpoint applies specified optimization passes. - Optimization passes are defined in
app/services/optimization_passes.py. - Currently, one pass is implemented:
remove_self_inverse_pairs: Removes adjacent identical single-qubit gates that are their own inverse (e.g., H-H, X-X). This pass iterates through the gates and removes such pairs.
- The
OPTIMIZATION_PASS_REGISTRYallows for easy addition of new optimization functions. - After optimization, if gate counts or depth were invalidated (set to
Noneby a pass), the circuit is converted to Qiskit and back toCircuitJSONto recalculate these statistics.
- The
-
Circuit Conversion & Export:
- The backend supports converting the internal
CircuitJSONrepresentation to various formats:- QASM 2.0: The
/circuit/export/qasmendpoint convertsCircuitJSONback into an OpenQASM 2.0 string. - Pennylane Script: The
/circuit/export/pennylane_scriptendpoint generates a Python script string that defines the circuit as a Pennylane QNode. This conversion is handled bycircuit_json_to_pennylane_scriptinapp/utils/circuit_conversions.py. It maps gate names to Pennylane operations and handles parameters, including string representations like "pi/2". It usesqml.ctrlfor gates that are not natively controlled in Pennylane but have controls specified in theCircuitJSON.
- QASM 2.0: The
- Conversion logic resides in
app/utils/circuit_conversions.py, which includes:qiskit_circuit_to_json: QiskitQuantumCircuittoCircuitJSON.circuit_json_to_qiskit:CircuitJSONto QiskitQuantumCircuit.circuit_json_to_cirq:CircuitJSONto CirqCircuit.cirq_circuit_to_json: CirqCircuittoCircuitJSON.circuit_json_to_pennylane_script:CircuitJSONto Pennylane script string.
- Gate name mapping (e.g.,
QISKIT_GATE_MAP,CIRQT_GATE_MAP_TO_CIRQT,PENNYLANE_GATE_MAP) is used to translate between the different library conventions.
- The backend supports converting the internal
- FastAPI: For building the RESTful API.
- Pydantic: For data validation and settings management (used in
app/models.py). - Qiskit: Core library for QASM parsing, circuit manipulation, and as an intermediate for statistics calculation.
- Cirq & Pennylane: For conversion to their respective formats/scripts.
- Uvicorn: ASGI server to run the FastAPI application.
- Poetry: For dependency management.
- Unit tests are located in the
backend/tests/directory. test_circuit_endpoints.pytests the API endpoints for parsing, optimization, and QASM export.test_pennylane_conversions.pytests the conversion logic to Pennylane scripts, including handling of various gates, parameters, and control logic.
The frontend provides a user interface to interact with the backend API.
- QASM Input: Users can input OpenQASM 2.0 strings via a textarea (
Textareacomponent). - Circuit Parsing & Display:
- Sends the QASM string to the backend's
/circuit/parseendpoint. - Displays the parsed circuit details (
CircuitDetailsViewcomponent inApp.tsx), including qubit count, gate counts, depth, and the raw JSON of gates. - Renders a visual representation of the circuit using SVG (
CircuitDiagramcomponent inApp.tsx). The diagram logic calculates gate positions based on qubit availability.
- Sends the QASM string to the backend's
- Circuit Optimization:
- Allows users to trigger optimization (currently hardcoded to the "remove_self_inverse_pairs" pass) via a button.
- Sends the parsed circuit to the
/circuit/optimizeendpoint. - Displays the optimized circuit details and diagram alongside the original.
- Export Functionality:
- Buttons to export the parsed or optimized circuit to:
- QASM (calls
/circuit/export/qasm). - Pennylane script (calls
/circuit/export/pennylane_script).
- QASM (calls
- The exported content is displayed in read-only textareas.
- Buttons to export the parsed or optimized circuit to:
- State Management: Uses React's
useStatehook extensively inApp.tsxto manage QASM input, parsed/optimized circuits, exported strings, loading states, and errors.
- React: For building the user interface.
- TypeScript: For static typing.
- Vite: For the development server and build tooling.
- TailwindCSS: For utility-first styling. Configuration is in
tailwind.config.jsand base styles/variables insrc/index.css. - shadcn/ui components: Uses pre-built components like
Button,Textarea,Label, andCardfor the UI, which are styled with TailwindCSS. - clsx & tailwind-merge: Utilities for conditional class names, used in
cnfunction insrc/lib/utils.ts.
- Navigate to the
backenddirectory:cd backend - Install dependencies using Poetry:
poetry install - Run the FastAPI development server:
poetry run uvicorn app.main:app --reload --port 8000
- Navigate to the
frontenddirectory:cd frontend - Install dependencies:
npm install(oryarn install/pnpm install) - Run the Vite development server:
npm run dev(usually serves onhttp://localhost:5173)
- More Optimization Passes: Implement a wider range of circuit optimization algorithms (e.g., gate fusion, commutation rules, template matching).
- QASM 3 Support: Extend parsing capabilities to support OpenQASM 3.0 features.
- Advanced Circuit Visualization: Enhance the SVG diagram with more gate types, better control visualization, and interactivity.
- Error Handling: More granular error reporting from the backend to the frontend.
- Benchmarking: Integrate functionality to benchmark circuits on different simulators.
- User-Selectable Optimization Passes: Allow users to choose which optimization passes to apply via the UI.
- Improved Pennylane Script Generation:
- Allow selection of different devices.
- Offer options for different measurement types beyond the default
qml.expval(qml.PauliZ(0)). - More robust handling of complex or custom gates during conversion.
- Cirq Integration in Frontend: Allow exporting to and potentially importing from Cirq JSON or other Cirq-specific formats directly from the UI.
- Performance: For very large circuits, optimize the conversion and rendering processes.