# Quantum Programming using Fortran

**URL:** <https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776>\
**Category:** Uncategorized\
**Created:** [March 12, 2026, 10:29am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776 "2026-03-12T10:29:04Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![shobhit21287](https://avatars.discourse-cdn.com/v4/letter/s/5e9695/32.png) [@shobhit21287](https://fortran-lang.discourse.group/u/shobhit21287)\
**Post date:** [March 12, 2026, 10:29am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/1 "2026-03-12T10:29:04Z")

</div>

We work with [Qiskit](http://github.com/Qiskit/) and it’s recently enabled a C API ([code](https://github.com/Qiskit/qiskit/tree/main/crates/cext), [demo](https://github.com/qiskit-community/qiskit-c-api-demo/tree/main)) to its Rust core to provide low level access to the data model. There is some interesting potential applications with Fortran, due to the promising recent advancements in quantum computing applications to scientific computing eg. [[1](https://www.sciencedirect.com/science/article/pii/S0167739X24002012),[2](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.037001),[3](https://arxiv.org/abs/2508.02578),[4](https://www.science.org/doi/10.1126/science.aea3321)], and we’re looking for help on how to best integrate it. Bindings for other languages have been under development such as [C++](https://github.com/Qiskit/qiskit-cpp), [Julia](https://github.com/Qiskit/Qiskit.jl), and [Rust](https://github.com/Qiskit/qiskit-rs) and adding Fortran to this list could be really useful in certain application domains. We are looking to see if this project is of interest to folks here, from a development and application standpoint.

---

<div class="post-metadata">

**Author:** ![shobhit21287](https://avatars.discourse-cdn.com/v4/letter/s/5e9695/32.png) [@shobhit21287](https://fortran-lang.discourse.group/u/shobhit21287)\
**Post date:** [March 12, 2026, 1:41pm UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/2 "2026-03-12T13:41:23Z")

</div>

If anyone has any suggestions or would like to co-develop this project please feel free to comment your thoughts.

---

<div class="post-metadata">

**Author:** ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)\
**Post date:** [March 12, 2026, 1:58pm UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/3 "2026-03-12T13:58:49Z")

</div>

Quantum Programming is not my topic of expertise but it is something that I read about for fun and I did wonder if there would be a Fortran API out there.

So I’ll just give you my two cents because why not 🙂

If you already automated generating the C API, I think the easiest path forward would be to automate a companion twin Fortran API using `iso_c_binding` to expose the C procedures within a Fortran module.

> **[iso\_c\_binding in Fortran Wiki](https://fortranwiki.org/fortran/show/iso_c_binding)**

> [@Iso\_c\_binding: Looking for practical example of how it helps with mangling](https://fortran-lang.discourse.group/t/iso-c-binding-looking-for-practical-example-of-how-it-helps-with-mangling/3393):
>
> After reading a wikipedia about [mangling](https://en.m.wikipedia.org/wiki/Name_mangling), I feel that I don’t understand the need for iso\_c\_binding. Question: Can you give me a simple practical example which shows the importance of iso\_c\_binding. Basically, I’d like to know what can happen without it. I’m looking for intuition in an explanation. I’m looking for a complete example. I want to really really understand it, so give me your best explanation. Thank you,

> **[Exploring ISO\_C\_BINDING and type-bound procedures](https://rgoswami.me/posts/iso-c-type-bound-fortran/)**
>
> A closer look at the standard Fortran C compatibility layer by exploring objects and linkers
> Background Derived types and their interoperability have been covered previously in the context of usage from Python. However, much of the focus of the...

> **[C interoperability in Fortran Wiki](https://fortranwiki.org/fortran/show/C+interoperability)**

---

<div class="post-metadata">

**Author:** ![eelis](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@eelis](https://fortran-lang.discourse.group/u/eelis)\
**Post date:** [March 13, 2026, 6:15am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/5 "2026-03-13T06:15:44Z")

</div>

A general comment to ``Quantum Programming`: in the future, classical languages may need to develop language extensions to support certain rules that Quantum Physics enforce. A great example of this is the so called `no cloning theorem`. Consider an instance of a type `QUANTUM COMPLEX :: a` for which the compiler would need to enforce that the value cannot be copied. Moreover, it also cannot be read, but only once, and then be destroyed. Sure, one can think that these`can tackeled with derived types and some assign operators. But, I think, for a healthy and userfriendly `Quantum Language`, especially for a high-performance computing language, these aspects **must** be first class citizens.

If I were a committee member, I’d start thinking about these and I think the committee should start running a task force to think if these conceps can be baked into the language. This is the future and it is coming like a zunami - nobody knows the hour, but when it comes, it will be quick. @certik @rouson

I know this is a bit besides the point, since the question was more about how to generate, transpile and measure `Quantum Circuits` but I think, eventually the way for a compiled high level language, the realistic and useful way forward is to be compatible with the rules imposed by quantum physics at the language level.

---

<div class="post-metadata">

**Author:** ![aaryav-3](https://avatars.discourse-cdn.com/v4/letter/a/e5b9ba/32.png) [@aaryav-3](https://fortran-lang.discourse.group/u/aaryav-3)\
**Post date:** [March 13, 2026, 6:19am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/6 "2026-03-13T06:19:21Z")

</div>

That is certainly something I had in mind. I’ve also been exploring a tentative architecture with ISO\_C\_BINDING, by looking at how established HPC libraries structure their Fortran bindings, which surfaced some of the design questions below.

_Memory lifecycle:_ HDF5 and FFTW land on explicit manual lifecycle (`h5open_f`/`h5close_f`, `fftw_plan_*`/`fftw_destroy_plan`), and the Qiskit C API follows the same pattern with paired `qk_*_new`/`qk_*_free` per handle type. A thin ISO\_C\_BINDING mirror could expose those directly, OR we add a higher-level derived-type wrapper with `FINAL` on top, the way `qiskit-cpp`adds RAII over the same raw C handles. The latter is more ergonomic, but I’m curious to hear from people, why manual lifecycle is otherwise preferred in certain cases? where does the distinction lie in either approach?

_Memory layout:_ C is row-major, Fortran is column-major. A Fortran routine receiving a matrix from C will silently treat it as transposed. Do we mandate a layout convention, expose stride parameters (control to the caller), or absorb a transpose inside the wrapper (simple, but 2x memory usage)? Each of these creates a tradeoff between ergonomics, memory overhead, and where the responsibility sits (user vs. binding).

_Qubit index ordering:_ Qiskit uses little-endian bit ordering, qubit 0 is rightmost. Quantum chemistry codes like GAMESS and NWChem export Hamiltonians in FCIDUMP format, which uses 1-based orbital indices in chemist’s notation. A mismatch here is silent and physically wrong. Worth deciding early whether the binding translates indices at the API boundary, flags a mismatch, or documents the convention and leaves it to the caller.

Once some preliminary design questions above are settled, I feel the ISO\_C\_BINDING layer itself is fairly mechanical to write, and the right answers to those questions live squarely within this community’s expertise.There are likely concerns I’ve overlooked too, so please feel free to bring those to light. Curious to see how this project pans out!

---

<div class="post-metadata">

**Author:** ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)\
**Post date:** [March 13, 2026, 6:59am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/7 "2026-03-13T06:59:56Z")

</div>

> [@aaryav-3](#):
>
> _Memory lifecycle:_ HDF5 and FFTW land on explicit manual lifecycle (`h5open_f`/`h5close_f`, `fftw_plan_*`/`fftw_destroy_plan`), and the Qiskit C API follows the same pattern with paired `qk_*_new`/`qk_*_free` per handle type. A thin ISO\_C\_BINDING mirror could expose those directly, OR we add a higher-level derived-type wrapper with `FINAL` on top, the way `qiskit-cpp`adds RAII over the same raw C handles. The latter is more ergonomic, but I’m curious to hear from people, why manual lifecycle is otherwise preferred in certain cases? where does the distinction lie in either approach?

I would say that both approaches are valid and complementary for a robust design. If I take your reference to HDF5, you could see this as the first layer which exposes the raw functional approach but which can be hard to approach by end users. Then, a second layer of abstraction can be built on top, for instance [GitHub - geospace-code/h5fortran: Lightweight HDF5 polymorphic Fortran: h5write() h5read() · GitHub](https://github.com/geospace-code/h5fortran) this library exposes a high-level API which is easier to understand by the end users.

So, one idea could be that you first expose the C API with a module, say:

```Fortran
module qiskit_c_kernels
use iso_c_binding
implicit none
private

interface
   subroutine qk_<*>_new_f( ..., ...) bind(c,name=qk_<*>_new)
   end subroutine
    ...
end interface
public :: qk_<*>_new_f
end module

```

And then, a higher level module which `use`s your C exposed kernels to propose an easier to use API.

> [@aaryav-3](#):
>
> _Memory layout:_ C is row-major, Fortran is column-major. A Fortran routine receiving a matrix from C will silently treat it as transposed. Do we mandate a layout convention, expose stride parameters (control to the caller), or absorb a transpose inside the wrapper (simple, but 2x memory usage)? Each of these creates a tradeoff between ergonomics, memory overhead, and where the responsibility sits (user vs. binding).

If you don’t need to expose strided subsections of matrices, I would suggest to: expose directly the matrices “as is”, document that the Fortran API is receiving the raw data so it will be viewed as transposed, and adapt the subsequent algebraic procedures to apply any required operator having this prior knowledge. Limit copies if possible.

I’m pretty sure that some might disagree with this view, but well, just an idea.

---

<div class="post-metadata">

**Author:** ![aaryav-3](https://avatars.discourse-cdn.com/v4/letter/a/e5b9ba/32.png) [@aaryav-3](https://fortran-lang.discourse.group/u/aaryav-3)\
**Post date:** [March 17, 2026, 6:18am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/8 "2026-03-17T06:18:24Z")

</div>

For context, since it’s relevant to the discussion:

> _Qiskit is essentially a quantum compiler stack. You write quantum programs in terms of abstract circuits and operators, and Qiskit handles everything between that description and actual hardware execution, optimizing and transforming circuits to match specific device constraints, and dispatching to real quantum processors through a standardized interface. The performance-critical parts of this pipeline are written in Rust, and the C API exposes those internals directly, covering the full workflow from circuit construction through compilation to execution._

Now, to clarify the scope of what we’re exploring here, all the required physics is already handled. The no-cloning theorem, measurement collapse, etc. is intrinsic to and enforced by quantum hardware itself when circuits are actually executed. The [rust-native compiler](https://github.com/Qiskit/qiskit/tree/main/crates)optimizes and re-writes these quantum circuits to match the constraints of quantum computing hardware.  
What we’re building is simply a bridge to reach those internals from Fortran, in the same way qiskit-cpp does from C++.  
The architecture we have in mind is two layers:

1. A thin ISO\_C\_BINDING layer that maps Fortran calls directly to the C API functions (qk\_circuit\_new, qk\_obs\_\*, etc.)

2. A Fortran-idiomatic module layer on top: derived types, ergonomic interfaces, Fortran array semantics, etc. to make the API feel native to someone writing HPC code

The goal is that an existing Fortran HPC code could call a quantum subroutine the same way it calls LAPACK today, without the caller ever needing to think about what’s happening in the Rust layer. That was really the intent behind starting this thread: to discuss what that API layer should look like, and to discuss, validate, and collectively shape the architecture.

---

<div class="post-metadata">

**Author:** ![aaryav-3](https://avatars.discourse-cdn.com/v4/letter/a/e5b9ba/32.png) [@aaryav-3](https://fortran-lang.discourse.group/u/aaryav-3)\
**Post date:** [March 17, 2026, 10:31am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/9 "2026-03-17T10:31:23Z")

</div>

Thank you for the clarification! We can drive the 2 level, FFI and API layers we had in mind, both exposed publicly to the end user, the former wrapping c functions as is (shifting the optics to not just interface data structures, but also fit into utility), and lifetime agnostic, the latter ergonomic and with explicit allocation and deallocation of resources (using `final` or creating and calling explicit `*_free` functions). But I was wondering what exactly would the caveats be with such an approach? Some I can think of:

- Perhaps there may be edge-cases which involves double `free`ing of the same resource, mixing FFI (`qk_*_free`) + ergonomic API. Does Fortran’s `type(c_ptr)` provide ways to track ownership to avoid this?
- If the entire purpose of language bindings is to integrate external libraries ergonomically into the target ecosystem, shall we really design Fortran bindings that require every user to manually handle row/column-major mismatches when calling standard Fortran libraries (BLAS/LAPACK/MPI)? Shouldn’t our binding layer absorb this impedance mismatch? is there perhaps a different approach to transposition? maybe we expose stride parameters, or is `copy-on-write`(CoW) a viable solution, albeit eventually it’ll still take the same memory?

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [March 17, 2026, 4:52pm UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/10 "2026-03-17T16:52:34Z")

</div>

> [@aaryav-3](#):
>
> is there perhaps a different approach to transposition?

This has been suggested before, outside the context of quantum computing. One suggestion is to have an intrinsic `shallow_transpose(A)` type of operator that operates only on the array metadata to transpose the argument. This would be a pointer-like function. The cost for invoking the function would be independent of the number of elements in the array. This would of course simplify interlanguage operability (e.g. with C), but it would also be a useful feature on its own, entirely within fortran. I remember someone implemented this in gfortran just to demonstrate that the idea works. In a simple pointer assignment

```auto
B => shallow_transpose(A)

```

the elements of `B(:,:)` would point to the same memory locations as the elements of `A(:,:)`, but with the rows and columns switched. When used as a subprogram argument

```auto
call subxxx(..., shallow_transpose(A), ...)

```

It would result in a modifiable actual argument where the elements of `A(:,:)` are modified directly, not through a temporary copy.

In principle, it could be generalized to higher rank arrays, and it could allow array slices as its argument, giving the programmer much flexibility when operating on array arguments stored in various ways.

---

<div class="post-metadata">

**Author:** ![eelis](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@eelis](https://fortran-lang.discourse.group/u/eelis)\
**Post date:** [March 18, 2026, 9:57am UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/11 "2026-03-18T09:57:39Z")

</div>

I think the vision is great and it will be a great solution to many! Thank you for the effort!

However, I want to clarify a couple of points:

1. I view Qiskit more like LLVM IR (backend) rather than a high-level full stack compiler (including the rust-native “compiler” that you mention)
2. There will be, and actually there are already some, high-level compilers: Qrisp, Q# and Qmod, to name of few
3. In your plan you are not addressing the issues I mention (imposing rules of quantum physics at the compiler level) and below, I will give you a couple of examples of mistakes that would not be caught at compile time

Illegal copy:

```fortran
type(qbit) :: q1, q2

call init(q1)

q2 = q1 ! attempt to copy quantum state

```

a quantum-aware compiler would say something like:

Error: assignment of quantum object ‘q1’ to ‘q2’ is not allowed  
Reason: quantum states cannot be copied (no-cloning constraint)

Use collapsed value:

```fortran
type(qbit) :: q
integer :: result

call hadamard(q)
call measure(q, result)

call hadamard(q) ! using collapsed state as if still quantum

```

a quantum-aware compiler would say:

Error: quantum object ‘q’ used after measurement  
Note: measurement consumes the quantum state

This would be analogous to using an ALLOCATABLE value after DEALLOCATE

Aliasing:

```fortran
type(qbit) :: q

call init(q)

call entangle(q, q) ! same qubit used twice

```

QA compiler:

Error: operation ‘entangle’ requires distinct qubits  
But argument 1 and 2 alias the same object

Leak:

```fortran
type(qbit) :: q

call init(q)
! program ends without measurement or reset

```

QA compiler:

Warning: quantum object ‘q’ goes out of scope without being measured or reset

Illegal branching:

```fortran
type(qbit) :: q

call hadamard(q)

if (q == 1) then ! illegal quantum state inspection
    call something()
end if

```

QA compiler:

Error: quantum object ‘q’ cannot be used in classical condition  
Hint: measure the qubit before branching

As you can see, these examples show that a quantum-aware compiler is eventually needed if one wants to use the full power of a compiler to enforce the rules of quantum computing. Hence, I think it is very important for an HPC language to have language extension for quantum computing.

Another thing is the low leveledness of Qiskit. Consider Grover

```python
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator

qc = QuantumCircuit(2, 2)

# Step 1: Superposition
qc.h([0, 1])

# Step 2: Oracle (mark |11>)
qc.cz(0, 1)

# Step 3: Diffusion operator
qc.h([0, 1])
qc.x([0, 1])
qc.cz(0, 1)
qc.x([0, 1])
qc.h([0, 1])

# Step 4: Measure
qc.measure([0, 1], [0, 1])

# Simulate
sim = AerSimulator()
result = sim.run(qc).result()
counts = result.get_counts()

print(counts)

```

Compare with Qrisp (huge shift in abstraction)

```python
from qrisp import QuantumVariable, grover

# Define a 2-qubit quantum variable
qv = QuantumVariable(2)

# Define oracle as a function
def oracle(qv):
    return qv == 3 # |11⟩

# Run Grover's algorithm
result = grover(qv, oracle)

print(result)

```

But I don’t want to discourage you, what you are doing is important and very useful for sure! I just want to increase the awareness of what is out there and what I think will be the direction where quantum languages are going. I believe Fortran has all the capacity to fulfill the requirements of quantum awareness and if it does it right (and hopefully fast), it can increase its relevance in HPC field.

---

<div class="post-metadata">

**Author:** ![aaryav-3](https://avatars.discourse-cdn.com/v4/letter/a/e5b9ba/32.png) [@aaryav-3](https://fortran-lang.discourse.group/u/aaryav-3)\
**Post date:** [March 23, 2026, 8:11pm UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/12 "2026-03-23T20:11:54Z")

</div>

Thank you for the detailed response, these are valid points and worth addressing directly.

> [@eelis](#):
>
> I view Qiskit more like LLVM IR (backend) rather than a high-level full stack compiler (including the rust-native “compiler” that you mention)

That’s actually a fair characterisation of where Qiskit sits in the stack. It operates at the level of gates, circuits, and transpilation passes, closer to an IR than a high-level quantum language.

> [@eelis](#):
>
> There will be, and actually there are already some, high-level compilers: Qrisp, Q# and Qmod, to name of few

The examples you give of Qrisp vs raw Qiskit illustrate this well, and the higher-level compilers you mention (Qrisp, Q#, Qmod) are the right comparison for what a truly quantum-aware language would look like.

> [@eelis](#):
>
> In your plan you are not addressing the issues I mention (imposing rules of quantum physics at the compiler level) and below, I will give you a couple of examples of mistakes that would not be caught at compile time

The examples you give are precise, but they assume a mental model where qubits are live quantum state objects that can be invalidated or illegally copied at runtime. Qiskit operates at a different abstraction level, a qubit in a circuit is a classical index into a circuit description, not a live quantum state. The quantum physics constraints are enforced by the hardware at execution time. The quantum-aware compiler of the kind you’re describing would sit above Qiskit in the stack, at a high-level, as you have mentioned.

What we’re building sits at the IR level, a clean compiled-language interface to Qiskit’s gate-level abstraction, which is the missing piece for the HPC community today. The language-level quantum awareness you’re describing is a genuine next objective, perhaps built around the core SDK, for applicational specificity, and arguably the more consequential conversation.

---

<div class="post-metadata">

**Author:** ![gronki](https://avatars.discourse-cdn.com/v4/letter/g/a88e4f/32.png) [@gronki](https://fortran-lang.discourse.group/u/gronki)\
**Post date:** [March 25, 2026, 3:33pm UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/13 "2026-03-25T15:33:08Z")

</div>

> [@aaryav-3](#):
>
> _Memory lifecycle:_ HDF5 and FFTW land on explicit manual lifecycle (`h5open_f`/`h5close_f`, `fftw_plan_*`/`fftw_destroy_plan`), and the Qiskit C API follows the same pattern with paired `qk_*_new`/`qk_*_free` per handle type. A thin ISO\_C\_BINDING mirror could expose those directly, OR we add a higher-level derived-type wrapper with `FINAL` on top, the way `qiskit-cpp`adds RAII over the same raw C handles. The latter is more ergonomic, but I’m curious to hear from people, why manual lifecycle is otherwise preferred in certain cases? where does the distinction lie in either approach?

I would be extremely cautious reagarding the use of `final` procedures. Almost no compiler supports them reliably. They may not be called or may be called twice, in practice. I would really suggest staying away in trying to wrap memory management in Fortran OOP features: too dangerous.

---

<div class="post-metadata">

**Author:** ![aaryav-3](https://avatars.discourse-cdn.com/v4/letter/a/e5b9ba/32.png) [@aaryav-3](https://fortran-lang.discourse.group/u/aaryav-3)\
**Post date:** [June 1, 2026, 1:47pm UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/14 "2026-06-01T13:47:58Z")

</div>

The initial release is live!  
you can find it [here](https://fortran-lang.discourse.group/t/qiskit-fortran-initial-release/10937).

Thank you so much for this insightful discussion. Questions raised here, still hold relevance against subsequent releases.

---

<div class="post-metadata">

**Author:** ![ZaneHam](https://avatars.discourse-cdn.com/v4/letter/z/51bf81/32.png) [@ZaneHam](https://fortran-lang.discourse.group/u/ZaneHam)\
**Post date:** [June 1, 2026, 11:15pm UTC](https://fortran-lang.discourse.group/t/quantum-programming-using-fortran/10776/15 "2026-06-01T23:15:03Z")

</div>

Hello!

I’ve actually got parts of SLATEC “running” on quantum computers (well at least a circuit) on a compiler I wrote, and it works up until the I/O layer, so I have been running some F77 on IBM\_Marrakesh. I will be honest I do use the free plan with my allocated 10 minutes so I’m constrained by the resources I have access to. If you need any help on the project, I’d be more than happy to help. Love Fortran and it would be great to give it the first-class treatment.
