Let’s move beyond circuits!

Last week I attended IEEE Quantum Week conference in Colorado. Out of all the wonderful conversations, presentations and discussions, there is one thought that felt particularly important, which I encapsulated in this tweet:

There was some discussion in the comments and obviously Twitter is not best place for having a nuanced discussion, so let me write explain where does it come from.

Before we start, I want to make a couple of things clear: contrary to most of my blogposts, this one is a hot take. I’m writing it as I sit on the airport and airplane back from the conference, trying to give some structure to the thoughts I have. I’m probably wrong about a lot of things. I’m no expert in compilation, I don’t understand how hardware operates, my quantum information knowledge is pretty rudimentary. I have not researched yet what are the alternatives, who else worked on some solutions to this and what that could possibly be.

But I am a software engineer (doing some research on the side), who tries to create better tools for people to interface with quantum computers. I think a lot about abstractions, interfaces, integrations and this is where I’m coming from – the “algorithms development”, “software tools” and “QC applications” part of the stack. I want to get this out while it’s still fresh in my mind to keep the momentum going – as I feel there’s a lot of momentum in the community to push this topic forward.

I cannot acknowledge all the people who contributed to this blogpost through the discussions, as I have talked with so many people about it. However, I need to make one exception – huge kudos to Yuval Sanders. We started talking about related issues months ago and all the discussions with him were eye-opening!

OK, after this overly lengthy introduction, let’s get into the details.

Problems with circuits

The problems stated below are in no particular order.

Problem 1 – expressivity

Let’s say I want to start my algorithm from a state that’s equal superposition of all possible states. How do I do that? I put Hadamard gates at the beginning of my circuit. Ok, now let’s say I want to change the basis in which I measure from Z to X1. What do I do? I put Hadamard gates at the end of my circuit!

So when someone looks at my circuit and they see “H”, this could mean a lot of different things. The fact that you use Hadamards to create equal superposition, should be an implementation detail, not how you express your intent. You can argue that most of the time it’s obvious from the context what author meant. But that’s true only if you have significant amount of experience, and you can “read between the lines”. This definitely creates a barrier (not a huge one, but still) for new people and adds unnecessary cognitive load for everyone. In the end, my intention is not to use a Hadamard gate. My intention is to create equal superposition. Writing down a circuit with particular gates is not an effective way to communicate this intention.

Side note on cognitive load

If you’re not familiar with it, let me introduce you to the concept of “cognitive load”.

Cognitive load is basically the work that our brain needs to put in order to perform our task. Imagine having a conversation with someone while you are walking through an empty park on a sunny day. And now imagine having the same conversation in a crowded room, with loud music. One of the reason why it’s harder to have conversation in the latter situation is that your brain needs to ignore all the extra signals and focus only on what’s relevant for the conversation. All the noise adds the cognitive load.

Similarly in the data visualization – a good data visualization doesn’t have plenty of unnecessary details, it only has what’s necessary to convey the message. The more elements there are, the more our brain has to process. Which means that processing is slower and less efficient.

So in our case, the fact that someone needs to look at the circuit and figure out what we meant by the Hadamard gates in this specific context adds some unnecessary cognitive load.

Problem 2 – Circuits are too low level for many algorithms

When you want to tell microprocessor which diode to light when you hit a button, you can write this program using assembler. When you want to create a web form that takes some data, sends it to a server, stores in a database and sends an e-mail notification, you can write this in, let’s say, Django (Python).


Cause depending on the task at hand, it’s better to work at different layers of abstractions. Sure, your Python code will in the end get compiled to assembler, but you, as a web developer, can live your whole life and never think about this fact. Sure, you can try writing the whole web app in assembler – good luck! And what if your server breaks and you get a new one that uses different architecture? Rewriting the whole thing from scratch sounds fun, right?

What language we speak influences how we think – for better or worse. So back to quantum – thinking about algorithms in terms of circuits definitely is useful in some contexts, but is limiting in others. And actually, many people don’t think about algorithms in terms of circuits. They write equations, make operations on unitary matrices, use block diagrams. But often in the end, they need to express these ideas in terms of circuits, which as Yuval pointed out in this talk, is somewhat painful.

And the fact, that we don’t have a common way of expressing algorithms at higher level through software makes it harder to move field forward. Speaking from my own experience.

Problem 3 – Compilation

Let’s say I want to run QAOA. I can express QAOA with the following equations (details in my QAOA blogpost ):

\[| \gamma, \beta \rangle = U(H_B, \beta_p) U(H_C, \gamma_p) … U(H_B, \beta_1) U(H_C, \gamma_1) | s \rangle\]

Does this expresses exactly my intent? Yeah. Is this unambiguous? Sure.

Now I want to run it on some hardware. So I express it as a circuit – let’s say I use CNOTs, RXs, H and whatever else I need. I want to send this to hardware, but my hardware uses a different gate set. Ok, I can compile it to that gate set and we’re good to go.

So I have two steps: 

“Mathematical formulation” -> “Abstract circuit” -> “Physical circuit”

Now what if we had some better representation?

We would get:

“Mathematical formulation” -> “Better representation” -> “Physical circuit”.

Still the same number of steps, so we’re kinda in the same place. But we already get some minor benefits – it’s way easier to do the first transition in the second case, as “better representation” is much closer to the “mathematical formulation”. And the other part is automated anyway.

But actually “better representation” might make the second transition easier as well. QAOA is pretty structured – I basically repeat the same operations over and over again, just with different parameters. In the “abstract circuit” representation I don’t have a way to express that, so if I have 1000 layers, I’ll create a very long circuit and them I’m forced to perform basicalyl the same compilation operations 1000 times. But if you have a better representation, you can do this better.

You can say that “better representation” could be simply “circuits with for loops” – I agree with that, this already would be an improvement in this case!

Another example, this time very close to my heart. In one project I’m working on, we’re building a pipeline that takes a “Quantum program”, compiles it to a set of fault tolerant operations and then performs resource estimation. Ok, so how does the process looks like in our case?

Logical circuit -> “Clifford + T” circuit -> ICM Circuit -> Graph state -> Some FTQC operations2

Details about this method has been described in this recent paper.

The point is, that (as far as I can tell), performing the first three transitions is not super important from the point of view of the algorithm. It’s just necessary evil, which is introduced because we express our algorithms as circuits.

Perhaps (pure speculation on my end) there is a more direct mapping from higher level algorithm primitives like “QFT” to the “Graph state”, which doesn’t require going through circuits. Maybe not, I have no idea. But isn’t it worth exploring such possibility more?3

Problem 4 – classical control flow

It’s really hard, perhaps even impossible, to express certain “classical flow” operations with circuits.Things like:

  • Repeat until success
  • Conditional execution based on mid-circuit measurements
  • For loops 

Not to mention quantum error correction (QEC) instructions – but I leave this out as I would consider these “low level” – see section about QIR for more discussion.

As far as I remember QASM 3.0 gives you some of these things and I consider QASM 3.0 to be “extended circuits”, so I guess it kind of can be done, but I’m not sure to what extent.

Problem 5 – non-gate based computation

Another issue (brought to my attention by Jonathan Wurtz from QuEra, thanks man!) is that prevalence of circuits limits the usage of alternative approaches.

From what I understand about QuEra’s approach, they have analog machines. With these machines you can simulate the evolution of some Hamiltonian – which allows you to solve a wide variety of problems.

So you could implement QAOA on such machine – but the fact that you usually express them as circuits makes it harder. Sure, you can do some reverse-engineering, but it takes time and introduces friction. Having a better representation could makes it much easier to work with non-circuit-based platforms. (Probably missed out a lot of details, sorry for that! But I hope the point still holds.)

Another example – much more mundane, but affected me personally. Again – QAOA-centric. Most of the integrations with hardware/simulators we have at Zapata are circuit-centric. But there are very efficient ways of simulating QAOA (under certain conditions) that don’t require using circuits. For example, you can use analytical equations to simulate 1-layer QAOA for certain Hamiltonians. But I don’t do that, because the way I express QAOA ansatz is tied directly to circuits. And adding such option would be too much refactoring to be worth the effort for the project I’m working on.

Another paradigm that might suffer from circuits’ prevalence is Measurement-Based Quantum Computing (MBQC). MBQC is a very different way to think about quantum computation that I have not fully grasped yet, so I might be wrong here, but that’s my hunch.

Mid-blogpost remarks

Remark on QAOA 

I’m using QAOA as example so much, for several reasons:

  • I’m very familiar with this algorithm
  • It has very good high-level representation and structure
  • It’s relatively simple, which makes discussion more approachable

I think that a lot of these points could be made with other algorithms – I don’t think that the fact that QAOA is variational algorithm has any importance here.

Remark on circuits usefulness

I don’t say the circuits are terrible abstraction that we should get rid off. No, they have their uses. I think the closer you’re to the hardware the more sense there is to use them. They are also very useful for optimizing performance of your algorithm if you want to run your algorithm in 2022.

My point is – they have limitations, let’s acknowledge them as a community and come up with a better abstractions that works for higher-level users as well.

Remark on breaking abstraction

In his presentation at IEEE Quantum Week 2022, Fred Chong mentioned that in their group, rather than building more abstractions, they are breaking the existing abstractions. I find their approach very appealing, but what I propose is building more abstractions. How do I reconcile this?

I think that breaking abstractions has two uses:

  • It allows you to build a better one
  • It allows you to increase efficiency of your program

In classical computing automated tool for compilation are so advanced that no human is able to beat it3. However, we’re not at this stage with QC and, at least for the next couple of years, researchers will have to do low-level tinkering with circuits in order to get best results.  However, keep in mind, that not all the researchers work on algorithms that they want to run today – for them breaking the abstractions might not be as useful


Ok, I ranted on circuits for a bit. So what’s my idea to make it better?


I don’t have a good idea!

I feel the pain, I see the problem, but I don’t have a solution. Even more – I’m pretty sure I don’t have the expertise to come up with such solution myself. But please bear with me for a couple minutes more, as while I don’t have solutions, I have some thoughts about how to get one..

Existing tools

I think there are many people who came up with solutions to tackle some of these problems. I have very vague idea about what they do and how they work, but from my brief interactions with them it seems to me that they extend / build on top of circuits and attempt to solve some of the issues listed above.

I might be wrong – one of these might have already solved all the issues! But I don’t know that and researching that would delay me releasing this by weeks, so I just expect other people to tell me what are the pros and cons of these solutions. Given my ignorance, I’ll just throw the names here without any commentary:

These are all very different, but I think they all have some elements that might be useful/inspiring for the end solution.

Quantum Intermediate Representation

There is this thing called Quantum Intermediate Representations (QIR), which looked very promising to me at first. It solves a lot of problems with compilation of quantum programs into instructions that are executable on hardware. It tackles issues with inter-platform compatibility and control flow – I’m pretty sure it has been designed to be QEC-compatible, at least to some extent.

However, from my superficial understanding of what QIR is, I think that it does’t actually solve the problems that I’m mostly concerned with – the problem of expressibility, of traversing layers of abstractions in the graph-state compilation process, or being good tool for thinking about the algorithms.

QIR is designed more to be a “machine-to-machine” representation, and not something that’s human readable.

QASM 3.0 on the other hand is much more human readable. But it’s still gates and circuits centric, which also doesn’t make it a good solution to the problems that I think about. QIR and QASM people – feel free to argue! As I said, this is all just my perspective.

Oh, and huge thanks to Cassandra Granade for the discussions on the topic and explaining me what QIR does a couple of times now ;) 

Sidenote on naming

One of the issues I have with QIR is the matter of naming. As we can read in Wikipedia, “intermediate representation” (IR) is: “the data structure or code used internally by a compiler or virtual machine to represent source code”

So in my “Graph state compilation” example, my graph state is an IR. If you do Lattice Surgery, your time-space slices (or whatever that thing is called) is IR.

What QIR alliance is doing (unintentionally I guess) is owning the name “intermediate representation” for the IR that exists at the level of the stack that they have defined – which is somewhere between circuits and hardware. I might be totally wrong here and perhaps the examples I have given shouldn’t fall under “IR”. Again – people who are more experienced, please tell me!


I have one idea for a representation which has the following pros:

  • It’s slightly higher level than circuits (so we don’t risk getting too far from current state of affairs ;) )
  • People are already using it 
  • Is pretty flexible

It’s called “Using blocks that are higher level than gates”, or UBTAHLTG.

OMG, I just laughed on my own joke :D 

How would such blocks look like?

Well, you could have a block called “prepare equal superposition” or “QFT” or “Grover’s oracle” and then you could construct your quantum program from these blocks. It’s basically how people write algorithms in their papers.

And if you want classical control flow, let’s express it as workflows (at Zapata we have love workflows ;) ). Or maybe computational graphs, whatever you want to call them. I’m not a computer scientists.

I don’t think it’s particularly revolutionary or novel, but I haven’t seen it widely used or expressed in software (though I bet people already did it). So maybe worth giving it some more attention and maybe coming up with some common conventions how to do this?

Here are some nice visualizations of how one can build circuits from blocks by Yidong Liao from UTS:

Visualization 1

Visualization 2

Note on standardization

In order for this to be useful and not introduce more friction, we would need it to be standardized to some level, we would need to have some common conventions.  However, since we will still be experimenting with all this, we definitely don’t want to create poor standards and then force people to follow.

Not sure what’s a good way to deal with that.

This will be messy!

I don’t think anyone has a very good answer for the problems I stated. If that was the case, I think it would have already dominated the landscape4. So we will do, what software developers always do - create another competing standard!

But seriously – the process will be messy, there’s no doubt about it. But I think we can do it in a way that it’s not overly painful.

Let’s try not to compete. Let’s not try to force people into using this or that representation. Let’s not make incompatible standards and create technological lock-ins.

Instead let’s come to this with experimentation mindset. Let’s make it obvious to the users of our frameworks, that this feature is very experimental and it might change. Let’s make sure that they don’t get too attached and not build too much infrastructure around it. Let’s be nimble and collaborative. Let’s play with each other’s tools, take inspiration and ideas. Let’s be ready to ditch the projects that we’ve been working on and switch to something better than someone else designed.

That sounds idealistic, right? Is that possible – honestly I don’t think so. But I believe that if we keep such principles in mind, at least the whole process will be smoother.

How are we going to work on this?

First things first – I’m in no position to tell people what to do with all this. I just have some frustrations, talked with a bunch of people, listened to their frustrations and then decided to write it down. I just want to spur some discussion about the topic and hope that something will come out of this. I love my job, I love this community, but not enough to cut down my family and sleep time ;) Therefore this blogpost is not my declaration that I’ll come forward and lead the way.

I think we need to talk more – IEEE Quantum Week was a great place to start these discussions and I think we could use some other major conferences to advance it even further. If someone feels like organizing some virtual workshops on the topic – let me know, I’d be glad to participate.

Maybe more people should write what they think about it? Maybe even papers if someone feels like it? Maybe some conference talks, I don’t know.

Another extremely useful thing – if you know how this kind of “experimenting with new abstractions and driving community consensus” has been done in other industries, please share this knowledge with others! I think we, as a quantum community, sometimes try to reinvent the wheel, while there are already battle tested solutions.

Also, I’d be really glad if we could have some discussions in the comment section under this blogpost – I’ve read some really good discussion under some Scott Aaronson blogposts, so I think this is not a bad way to have a discussion.

Speaking of Scott Aaronson – if anyone feels like asking people who have been thinking about foundational issues in quantum information for decades already, that would be great. I bet they have plenty of good thoughts on the topic.

Final remarks

I think this blogpost is good way to start discussion, but will get outdated pretty fast, as I will be getting feedback – I expect ~50% of what I stated here to be at least somewhat misguided and/or inaccurate. So I think that instead of trying to keep it updated, I’ll just write a proper version when I get enough feedback to feel confident about doing it.

If you’d like to read more of my “raw thoughts” like this, please let me know. As anyone who ever talked with me would know, I have plenty of thoughts on multiple topics (especially quantum software), so perhaps it’s worth start sharing them more publicly.

Please comment, please share, please argue! For me the best outcome would be if someone proved to me that circuit is the ultimate best abstraction for QC, cause then we have one less problem to worry about and I can get back to doing different things ;) 

And don’t forget to subscribe to the newsletter here if you’d like to stay up to date with my writing and other projects.

Have a nice day!


P.S. It’s kind of refreshing feeling to know that I can write a whole blogpost in 4 hours, then spend extra 2 hours reading and editing (instead of usual 30+). And I don’t have to give it to at least 5 people to proof-read and ask Rafał to do all the editing and correction. Wow!


  1. I think that actually just to change the base you need only RY(\(\frac{\pi}{2}\)), cause Hadamard adds some extra rotation to the mix. But I also think that people sometimes use Hadamard to change the basis, so feel free to correct me if I got something wrong. 

  2. This is still at the early stage of development and I still don’t understand all the steps very well – that’s where the vague “Some FTQC operations” is coming from. 

  3. I think Jim Keller said that in one of the interviews with Lex Fridman. Absolutely excellent interviews, highly recommend listening to them: link 1, link 2).  2

  4. There’s also a good chance that it was just so ahead of times that the world was not ready for it and we need to revisit this idea.