ProjectQ-Framework / ProjectQ

ProjectQ: An open source software framework for quantum computing
https://projectq.ch
Apache License 2.0
891 stars 275 forks source link

Optimizing Simulation Time for Large Circuits in ProjectQ #476

Closed saifawan2703 closed 1 month ago

saifawan2703 commented 1 month ago

Hi! ProjectQ team, I am working on a project (applying grover on a simple 26 qubits sbox) using the ProjectQ framework, and I've noticed that simulation takes a significant amount of time (7 hours and continue). Could you provide any guidance on methods or optimizations to reduce the simulation time? Are there specific settings, techniques, or resources that might help improve performance, especially when working with larger qubit counts or complex circuits?

I am running my simulation on a server with 500G of RAM and 40 CPUs, however during simulation , only 10% of memory and few CPUs are utilized. How can I make this framework to use resources to full potential in order to increase performance?

One thing more, I am trying to generate circuit diagram as follow project q github example like that $ python examples/bellpair_circuit.py > bellpair_circuit.tex $ pdflatex bellpair_circuit.tex when i print that latex code is cannot display circuit diagram. please share an easy way to draw circuit diagram.

Thank you for your support!

damiansteiger commented 1 month ago

This sounds very long for a 26 qubit circuit, how many gates are you simulating? You could use the ResourceCounter without a simulator to quickly check.

The simulator and its advanced features (e.g. multi-threading, gate fusion, ...) are explained in simulator tutorial

saifawan2703 commented 1 month ago

AllocateQubitGate : 23 CCCCCCCZGate : 24 CCXGate : 520 CXGate : 650 DeallocateQubitGate : 23 HGate : 104 MeasureGate : 900 SwapGate : 494 XGate : 198

Gate counts: Allocate : 23 CCCCCCCZ : 24 CCX : 520 CX : 650 Deallocate : 23 H : 104 Measure : 900 Swap : 494 X : 198 Max. width (number of qubits) : 23. That are the gates counts.

import projectq from projectq.backends import Simulator eng = projectq.MainEngine(backend=Simulator(gate_fusion=True)) # Enables gate fusion I also used this but there is no any increase in speed of simulation of qubits.

damiansteiger commented 1 month ago

Regarding the CircuitDrawer for printing the bell pair

1) There is a bug in that code (my pdflatex just produces the image even with it), it misses a f at the start of the this line:

https://github.com/ProjectQ-Framework/ProjectQ/blob/f2a2c2117a668869b3864f8da2b14260276527de/projectq/backends/_circuits/_to_latex.py#L759 f"\n\\node[none,minimum height={gate_height}cm,outer sep=0] ({self._op(line, offset=1)}) "

2) the example code of the bellpair_circuit.tex https://github.com/ProjectQ-Framework/ProjectQ/blob/develop/examples/bellpair_circuit.py needs to measure the qubits in the end as the simulator is used (currently it is missing this)

damiansteiger commented 1 month ago

7 hours is far long for this circuit. For testing, I have created a (stupid circuit) with the same gates, see below. It finishes on a notebook within less than a minute.

Note that the engine_list only has one compiler engine to count the gates. Did you try with an empty engine_list=[]?

import projectq
from projectq.backends import Simulator
from projectq.meta import Control
from projectq.backends import ResourceCounter
from projectq.ops import H, Swap, X, Z, C, Measure

resource_counter = ResourceCounter()
eng = projectq.MainEngine(backend=Simulator(gate_fusion=True), 
    engine_list=[resource_counter])

qureg = eng.allocate_qureg(23)
for i in range(104):
    H | qureg[i%23]
for i in range(198):
    X | qureg[i%23]
for i in range(650):
    C(X) | (qureg[i%23], qureg[(i+1)%23])
for i in range(520):
    C(C(X)) | (qureg[i%23], qureg[(i+1)%23], qureg[(i+2)%23])
for i in range(494):
    Swap | (qureg[i%23], qureg[(i+1)%23])
for i in range(24):
    with Control(eng, qureg[:7]):
        Z | qureg[i%10+8]

for i in range(900):
    Measure | qureg[i%23]
eng.flush(deallocate_qubits=True)

print(resource_counter)
saifawan2703 commented 1 month ago

Thank you for your previous response. I am running my simulation on a PowerEdge R750xa server with the following specifications:

CPUs: 56 (Intel Xeon Gold 6330 @ 2 GHz)
Memory: 450 GB RAM

I ran the example code you provided, but it has been executing for over 2 hours and is still running. Could you share the hardware and environment you used where the circuit executed within a minute? Additionally, could you provide guidance on how I can optimize the simulation to make better use of my hardware resources and improve execution speed?

Thank you for your assistance.

damiansteiger commented 1 month ago

I ran it on an M1 MacBook Pro with 32GB RAM (not necessary to have that much RAM)

Your hardware should be able to handle it just fine.

ProjectQ has two simulators: A C++ simulator and a python fallback simulator if the installation with the C++ simulator didnt work as noted in the simulator tutorial. Make sure that the C++ simulator gets installed correctly. You could try a fresh install (compiling from source code) of ProjectQ on the system you want to run the code: instructions