Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
882478c
Added minimal support for fortran kernels.
Feb 11, 2026
271b3e2
[WIP] added initial fortran wrapper functions around fortran-c interf…
Feb 13, 2026
6f060b1
[WIP] users can define quantum kernels using only fortran types.
Feb 13, 2026
c359761
Cleaned up code. Added fortran bindings to QASM gates.
Feb 13, 2026
bf5b32f
Restructured project (added fortran directory in host and device). Ad…
Feb 13, 2026
8ae2767
Cleaned up code. Added plus and zero state qft examples written in fo…
Feb 13, 2026
b92759f
Changed integer type of the qubit index.
Feb 16, 2026
536929b
Abstracted away getting c funptr to kernel. Added WIP for heat equati…
Feb 17, 2026
9a616b0
Fixed interface to accept classical register of short integer (kind=2…
Feb 17, 2026
0c11443
Fixed quantum kernel registration. Cleaned up examples.
Feb 19, 2026
d22b903
Added the rest of device operations to fortran interface.
Feb 19, 2026
90d31a5
Added the rest of host operations.
Feb 19, 2026
2680352
Cleaned up commented code.
Feb 19, 2026
a50d0d3
Restructured placement of fortran modules.
Feb 19, 2026
401b6ca
Added extra validation on the executor handle.
Feb 20, 2026
6ec56dd
Added additional helper functions for allocating and freeing executor…
Feb 20, 2026
ce73fd4
Renamed cq executor derived type and added functions for allocating a…
Feb 20, 2026
73d29ee
Changed binding to reflect C function name change. Added bindings to …
Feb 20, 2026
e56760c
Changed binding name to reflect C function name change.
Feb 20, 2026
b084645
Added tests for fortran interface related to host operations.
Feb 20, 2026
d3bee4c
Removed unused file.
Feb 20, 2026
d0937ac
Created utility module for fortran tests.
Feb 20, 2026
dc1c65e
Added tests for fortran interface device ops.
Feb 23, 2026
46b7354
Added tests for fortran interface qasm gates.
Feb 23, 2026
1343773
Cleaned up the code, added comments, corrected types in the interface.
Feb 24, 2026
9738792
Removed draft, fortran-based, heat equation example.
Feb 24, 2026
1dfc350
Fixed default build options in CMakeLists.
Feb 24, 2026
f3007f5
analog/simulator.c: updated call to applyTrotterizedPauliStrSumGadget
otbrown Mar 11, 2026
dbe3dff
CI: set to use cq-simbe branch from otbrown repo, and updated install…
otbrown Mar 11, 2026
ad63137
CMake: moved to include everything in cq-simbe rather than using sub-…
otbrown Mar 12, 2026
2847a9b
CMake: added some comments to explain the mildly arcane Fortran bits
otbrown Mar 12, 2026
94d1344
CI: enabled Fortran tests
otbrown Mar 12, 2026
d1bc7c0
cq.f90: WIP changing types to use ISO C kinds for interop
otbrown Mar 12, 2026
203e65d
test_executors.c: removed tests which were not super informative and …
otbrown Mar 13, 2026
f8d9324
cq.f90: fixed c-binding-type warnings
otbrown Mar 23, 2026
2e4f36c
CMake: added -Wimplicit-interface to Fortran sources
otbrown Mar 23, 2026
26a89eb
Analog: protected unused functions with NDEBUG
otbrown Mar 23, 2026
a019cc5
Changed quantum kernel interface to take NMEASURE as parameter, fixin…
Mar 25, 2026
672a374
Added missing intents to fortran interface.
Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/test-CQ-SimBE.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
- name: Checkout QuEST
run: |
cd ${{ env.DEPENDENCY_DIR }}
git clone https://github.com/QuEST-Kit/QuEST.git
git clone https://github.com/otbrown/QuEST.git
cd QuEST
git fetch
git checkout -b devel origin/devel
git checkout -b cq-simbe origin/cq-simbe

- name: Checkout Unity
run: |
Expand Down Expand Up @@ -92,7 +92,7 @@ jobs:
-B ${DEPENDENCY_DIR}/QuEST/build
-S ${DEPENDENCY_DIR}/QuEST
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_INSTALL_PREFIX=${DEPENDENCY_INSTALL_DIR}
-DCMAKE_INSTALL_PREFIX=${DEPENDENCY_INSTALL_DIR}/quest

- name: Configure Unity
run:
Expand Down Expand Up @@ -200,6 +200,7 @@ jobs:
-DENABLE_TESTING=On
-DBUILD_EXAMPLES=On
-DFORCE_BUILD_VQE=On
-DBUILD_FORTRAN_INTERFACE=On
-DQuEST_DIR=${DEPENDENCY_INSTALL_DIR}/quest/lib/cmake/QuEST
-Dunity_DIR=${DEPENDENCY_INSTALL_DIR}/Unity/lib/cmake/unity
-DNLopt_DIR=${DEPENDENCY_INSTALL_DIR}/nlopt/lib/cmake/nlopt
Expand Down
36 changes: 35 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ option(
OFF
)

option(
BUILD_FORTRAN_INTERFACE
"Build with Fortran interface. Turned OFF by default."
OFF
)

# Dependencies

find_package(Threads REQUIRED)
Expand All @@ -58,6 +64,32 @@ target_include_directories(cq-simbe

target_link_libraries(cq-simbe PRIVATE Threads::Threads QuEST::QuEST)

if (BUILD_FORTRAN_INTERFACE)
enable_language(Fortran)

# Fortran_PREPROCESS adds the C preprocessor flag when compiling fortran
# Fortran_MODULE_DIRECTORY sets where compiled module files are placed
set_target_properties(cq-simbe
PROPERTIES
Fortran_PREPROCESS ON
Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/include
)

target_include_directories(cq-simbe
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/fortran>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/build/include>
)

target_compile_options(cq-simbe
PRIVATE
$<$<COMPILE_LANGUAGE:Fortran>:-Wimplicit-interface>
)

# add the cq module file
target_sources(cq-simbe PRIVATE ${PROJECT_SOURCE_DIR}/include/fortran/cq.f90)
endif()

add_subdirectory(src)

if (ENABLE_TESTING)
Expand All @@ -70,4 +102,6 @@ endif()

if (BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
endif()


4 changes: 4 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ if (${NLopt_FOUND} OR FORCE_BUILD_VQE)
else()
message(STATUS "Could not find NLopt: skipping VQE example. Try FORCE_BUILD_VQE=ON if needed.")
endif()

if(BUILD_FORTRAN_INTERFACE)
add_subdirectory(fortran)
endif()
2 changes: 1 addition & 1 deletion examples/analog/qaa.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#define CQ_ADDR_GLOBAL 0
#define CQ_ADDR_LOCAL 1

cq_status quantum_adiabatic_algo(const size_t NQUBITS, qubit *qr, cstate * cr, qkern_map * reg)
cq_status quantum_adiabatic_algo(const size_t NQUBITS, qubit *qr, const size_t NMEASURE, cstate * cr, qkern_map * reg)
{
CQ_REGISTER_KERNEL(reg);
set_qureg(qr, 0, NQUBITS);
Expand Down
27 changes: 27 additions & 0 deletions examples/fortran/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
find_library(MATHS_LIBRARY m REQUIRED)

add_executable(zero-qft
zero_qft.f90
utils.f90
)

target_link_libraries(zero-qft
PRIVATE
CQ-SIMBE::cq-simbe
${MATHS_LIBRARY}
)

set_target_properties(zero-qft PROPERTIES Fortran_PREPROCESS ON)

add_executable(plus-qft
plus_qft.f90
utils.f90
)

target_link_libraries(plus-qft
PRIVATE
CQ-SIMBE::cq-simbe
${MATHS_LIBRARY}
)

set_target_properties(plus-qft PROPERTIES Fortran_PREPROCESS ON)
100 changes: 100 additions & 0 deletions examples/fortran/plus_qft.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
program plus_qft
use cq
#include "cqf.h"
use example_utils
implicit none

integer :: ireturn, freturn, alloc_status, free_status, reg_status, qrun_status
integer(kind=8) :: NQUBITS, NSHOTS, NMEASURE
type(qubit) :: qrc
integer(kind=2), allocatable, target :: cr(:)

NQUBITS = 10
NSHOTS = 10
NMEASURE = NQUBITS

write(*,'(A)') 'before init'

ireturn = cq_init(0)

write(*,'(A,I4)') 'cq_init returned: ',ireturn

alloc_status = cq_alloc_qureg(qrc, NQUBITS)

write(*,'(A,I4)') 'alloc_qureg returned: ', alloc_status

allocate(cr(NMEASURE * NSHOTS))

CALL cq_init_creg(NMEASURE * NSHOTS, -1, cr)

write(*,'(A)') 'after init_creg'

reg_status = cq_register_qkern(plus_state_qft)

write(*,'(A,I4)') 'after register_qkern: ', reg_status

qrun_status = cq_sm_qrun(plus_state_qft, qrc, NQUBITS, cr, NMEASURE, NSHOTS)

write(*,'(A,I4)') 'after sm_qrun: ', qrun_status

CALL report_results(cr, NMEASURE, NSHOTS)

write(*,'(A)') 'after report results'

free_status = cq_free_qureg(qrc)

write(*,'(A,I4)') 'free_status returned: ', free_status

freturn = cq_finalise(0)

write(*,'(A,I4)') 'cq_finalise returned: ',freturn

write(*,'(A)') 'after finalise'

contains

subroutine qft(NQUBITS, qr)
implicit none
integer(kind=8), value :: NQUBITS
type(qubit), value :: qr
integer(kind=8) :: i, j
integer :: status
real(8), parameter :: PI = 3.1415926535897932384626433832795028841971694
real(8) :: angle

do i = 0, NQUBITS - 1
status = cq_hadamard(qr, i)
do j = i + 1, NQUBITS - 1
angle = PI / (2.0 ** j)
status = cq_cphase(qr, j, i, angle)
end do
end do

do i = 0, (NQUBITS / 2) - 1
j = NQUBITS - (i + 1)
status = cq_swap(qr, i, j)
end do
end subroutine qft

function plus_state_qft(NQUBITS, qr, NMEASURE, cr, reg) bind(C) result(status)
implicit none
integer(kind=8), value :: NQUBITS
type(qubit), value :: qr
integer(kind=8), value :: NMEASURE
integer(kind=2), intent(inout) :: cr(0:NMEASURE)
type(qkern_map), value :: reg
integer(kind=8) :: i
integer :: status
integer(kind=8) :: STATE_IDX = 0
CQ_REGISTER_KERNEL("plus_state_qft", reg)
status = cq_set_qureg(qr, STATE_IDX, NQUBITS)

do i = 0, NQUBITS-1
status = cq_hadamard(qr, i)
end do

call qft(NQUBITS, qr)
status = cq_measure_qureg(qr, NQUBITS, cr)
end function plus_state_qft

end program
23 changes: 23 additions & 0 deletions examples/fortran/utils.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module example_utils
use cq
implicit none

contains
subroutine report_results(cr, NMEASURE, NSHOTS)
implicit none
integer(kind=8), value :: NMEASURE
integer(kind=8), value :: NSHOTS
integer(kind=2) :: cr(0:NMEASURE * NSHOTS)
integer(kind=8) :: i, j

write(*,'(A)') 'Reporting measurement outcomes:'
do i = 0, NSHOTS-1, 1
write(*,'(A, I4, A)') 'Shot ', i, ': '
do j = (i) * NMEASURE, (i+1) * NMEASURE - 2, 1
write(*, '(I4, A)', advance='no') cr(j), ' '
end do
write(*,'(I4, A)') cr((i+1) * NMEASURE - 1), ' '
end do
end subroutine report_results

end module
98 changes: 98 additions & 0 deletions examples/fortran/zero_qft.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
program zero_qft
use cq
#include "cqf.h"
use example_utils
implicit none

integer :: ireturn, freturn, alloc_status, free_status, reg_status, qrun_status
integer(kind=8) :: NQUBITS, NSHOTS, NMEASURE
type(qubit) :: qrc
integer(kind=2), allocatable, target :: cr(:)

NQUBITS = 10
NSHOTS = 10
NMEASURE = NQUBITS

write(*,'(A)') 'before init'

ireturn = cq_init(0)

write(*,'(A,I4)') 'cq_init returned: ',ireturn

alloc_status = cq_alloc_qureg(qrc, NQUBITS)

write(*,'(A,I4)') 'alloc_qureg returned: ', alloc_status

allocate(cr(NMEASURE * NSHOTS))

CALL cq_init_creg(NMEASURE * NSHOTS, -1, cr)

write(*,'(A)') 'after init_creg'


reg_status = cq_register_qkern(zero_state_qft)

write(*,'(A,I4)') 'after register_qkern: ', reg_status

qrun_status = cq_sm_qrun(zero_state_qft, qrc, NQUBITS, cr, NMEASURE, NSHOTS)

write(*,'(A,I4)') 'after sm_qrun: ', qrun_status

CALL report_results(cr, NMEASURE, NSHOTS)

write(*,'(A)') 'after report results'

free_status = cq_free_qureg(qrc)

write(*,'(A,I4)') 'free_status returned: ', free_status

freturn = cq_finalise(0)

write(*,'(A,I4)') 'cq_finalise returned: ',freturn

write(*,'(A)') 'after finalise'

contains

subroutine qft(NQUBITS, qr)
implicit none
integer(kind=8), value :: NQUBITS
type(qubit), value :: qr
integer(kind=8) :: i, j
integer :: status
real(8), parameter :: PI = 3.1415926535897932384626433832795028841971694
real(8) :: angle

do i = 0, NQUBITS - 1
status = cq_hadamard(qr, i)
do j = i + 1, NQUBITS - 1
angle = PI / (2 ** j)
status = cq_cphase(qr, j, i, angle)
end do
end do

do i = 0, (NQUBITS / 2) - 1
j = NQUBITS - (i + 1)
status = cq_swap(qr, i, j)
end do
end subroutine qft

function zero_state_qft(NQUBITS, qr, NMEASURE, cr, reg) bind(C) result(status)
implicit none
integer(kind=8), value :: NQUBITS
type(qubit), value :: qr
integer(kind=8), value :: NMEASURE
integer(kind=2), intent(inout) :: cr(0:NMEASURE)
type(qkern_map), value :: reg
integer(kind=8) :: i
integer :: status
integer(kind=8) :: STATE_IDX = 0
CQ_REGISTER_KERNEL("zero_state_qft", reg)
status = cq_set_qureg(qr, STATE_IDX, NQUBITS)

call qft(NQUBITS, qr)

status = cq_measure_qureg(qr, NQUBITS, cr)
end function zero_state_qft

end program
6 changes: 3 additions & 3 deletions examples/qft/qft-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void full_qft_circuit(const size_t NQUBITS, qubit * qr) {
}

cq_status zero_init_full_qft(
const size_t NQUBITS, qubit * qr, cstate * cr, qkern_map * reg) {
const size_t NQUBITS, qubit * qr, const size_t NMEASURE, cstate * cr, qkern_map * reg) {
CQ_REGISTER_KERNEL(reg)

// Prepare state
Expand All @@ -57,7 +57,7 @@ const size_t NQUBITS, qubit * qr, cstate * cr, qkern_map * reg) {
}

cq_status plus_init_full_qft(
const size_t NQUBITS, qubit * qr, cstate * cr, qkern_map * reg) {
const size_t NQUBITS, qubit * qr, const size_t NMEASURE, cstate * cr, qkern_map * reg) {
CQ_REGISTER_KERNEL(reg);

// Prepare state
Expand All @@ -73,4 +73,4 @@ const size_t NQUBITS, qubit * qr, cstate * cr, qkern_map * reg) {
measure_qureg(qr, NQUBITS, cr);

return CQ_SUCCESS;
}
}
6 changes: 3 additions & 3 deletions examples/qft/qft.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
void report_results(cstate const * const CR, const size_t NMEASURE,
const size_t NSHOTS);
void full_qft_circuit(const size_t NQUBITS, qubit * qr);
cq_status zero_init_full_qft(const size_t NQUBITS, qubit * qr, cstate * cr,
cq_status zero_init_full_qft(const size_t NQUBITS, qubit * qr, const size_t NMEASURE, cstate * cr,
qkern_map * reg);
cq_status plus_init_full_qft(const size_t NQUBITS, qubit * qr, cstate * cr,
cq_status plus_init_full_qft(const size_t NQUBITS, qubit * qr, const size_t NMEASURE, cstate * cr,
qkern_map * reg);

#endif
#endif
Loading
Loading