Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9e97327
Update README with infor about how to install natively on macOS
dieriver May 1, 2026
29edbd6
Fix event-based ping-pong examples to correctly transition between st…
dieriver May 8, 2026
6d0cb45
Only start used nodes when using "run_application" helper
dieriver May 8, 2026
9948421
Use twisted's "pollreactor" on macOS environments
dieriver May 8, 2026
cea8d1b
Avoid using port 8021, taken by a system service in macOS
dieriver May 11, 2026
9718855
Backend processes are started only for the requested nodes to run. Th…
dieriver May 11, 2026
63b10b2
Implement max number of attempts to connect to other backend processe…
dieriver May 11, 2026
52710b1
Use twisted "pollreactor" in Linux for improved performance
dieriver May 11, 2026
9876ae8
Readme and linter changes
dieriver May 11, 2026
c3e810e
Change simulaqron reset behaviour to not reset settings by default.
dieriver May 11, 2026
96d2622
Rethink "simulaqron reset" cli subcommand. It now allows to kill hang…
dieriver May 11, 2026
7e547d9
Separate reset options into several subcommands to improve clarity of…
dieriver May 12, 2026
e4ec788
Add deeper explanation when "simulaqron start" fails, and how the use…
dieriver May 12, 2026
25fc6b9
Add documentation about general architecture of a SimulaQron App, the…
dieriver May 13, 2026
78b5121
Clarify documentation about when and how to run "simulaqron reset"
dieriver May 13, 2026
81f654d
Consolidate the location of the simulaqron log files
dieriver May 13, 2026
189cf54
Add "troubleshooting" section in simulaqron documentation
dieriver May 14, 2026
e276a8f
Add installation issues section in the "troubleshooting" part of the …
dieriver May 14, 2026
65e75aa
Add "libomp" library dependency in macOS environments.
dieriver May 15, 2026
ef940b9
Typos fix
dieriver May 15, 2026
83fa1b6
Refactorize GitHub workflow
dieriver May 15, 2026
905bccd
Fix installation of projectq and qutip in Makefile
dieriver May 15, 2026
be18152
Fix bug in Makefile
dieriver May 15, 2026
b5bcb56
Fix network start/stop tests
dieriver May 15, 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
18 changes: 3 additions & 15 deletions .github/workflows/actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,18 @@ jobs:
with:
python-version: "3.12"
- run: |
make install
make lint-deps
make lint

tests:
name: Run tests
tests-examples:
name: Run tests and examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/setup-python@master
with:
python-version: "3.12"
- run: |
make install
make test-deps
make tests

examples:
name: Run examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/setup-python@master
with:
python-version: "3.12"
- run: |
make install
make examples
20 changes: 17 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
CHANGELOG
=========

For more details refer to the [documentation](https://softwarequtech.github.io/SimulaQron/html/index.html).

For more details refer to the [documentation](https://softwarequtech.github.io/SimulaQron/index.html).

2026-05-15 (v4.1.2)
-------------------
- Fix expected message exchange in event-based Ping-Pong examples.
- Only start required Virtual Nodes processes when starting SimulaQron backend instead of starting all the
nodes defined in the network configuration.
- macOS Support: use twisted's "pollreactor" in macOS platforms to correctly allow starting backend processes.
- Linux Support: use twisted's "pollreactor" in Linux platforms to improve performance.
- Avoid using port 8021, which is used by a system service in macOS platforms.
- Starting the SimulaQron backend now respects the "conn_max_retries" configuration when backend processes
try to connect to each other.
- CLI tool `simulaqron reset` no longer resets the SimulaQron settings by default. It is now separated into
several subcommands that can reset simulaqron settings, delete PID files and kill simulaqron backend
processes. Run `simulaqron reset -h` for more info.
- Log files can now be found inside the `/tmp/simulaqron` folder.

2026-04-23 (v4.1.1)
-------------------
- Update README file.
- Added `install-development` target in the Makefile to ease the process of installing development dependencies.
- Remove old "nativeMode" files after rename of the folder.
- Adjusted Dockerfile to use the lates PyPI deployed version of SimulaQron.
- Adjusted Dockerfile to use the latest PyPI deployed version of SimulaQron.
- Fixed GitHub workflow to automatically deploy documentation.

2026-04-16 (v4.1)
Expand Down
33 changes: 22 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ EXAMPLES_DIR = examples
SIMULAQRON_DIR = simulaqron
TEST_DIR = tests

# We use the Gitlab repo to look for already-compiled versions os projectq and qutip
GITLAB_REPO=$(shell curl --write-out '%{http_code}' --silent --output /dev/null https://gitlab.tudelft.nl/api/v4/projects/28442/packages/pypi/simple)

# IMPORTANT: For running in makefile, we need to use only 1 thread in OMP library
export OMP_NUM_THREADS=1

Expand All @@ -15,10 +18,22 @@ _delete_pyc:
_delete_pid:
@find ${SIMULAQRON_DIR} -name '*.pid' -delete

_install_projectq_qutip:
@if [ "${GITLAB_REPO}" = "200" ]; then \
${PYTHON} -m pip install projectq qutip --index-url https://gitlab.tudelft.nl/api/v4/projects/28442/packages/pypi/simple; \
else \
${PYTHON} -m pip install "setuptools<81" pybind11; \
${PYTHON} -m pip install "git+https://github.com/ProjectQ-Framework/ProjectQ.git@v0.8.0" --no-build-isolation; \
${PYTHON} -m pip install "qutip<5.0.0" --no-build-isolation; \
fi

lint-deps:
@${PYTHON} -m pip install .\[lint\]

lint:
@${PYTHON} -m flake8 ${SIMULAQRON_DIR} ${EXAMPLES_DIR} ${TEST_DIR}

test-deps:
test-deps: _install_projectq_qutip
@${PYTHON} -m pip install .\[test\]

requirements python-deps:
Expand All @@ -29,14 +44,7 @@ dev-deps:

install-development: dev-deps

install-optional: install
# Python setuptools 81 removed "dry_run" option when compiling C++ code
# this breaks the build of projectq
# As a hack, we install the bare minimum tools to build projectq, then
# we build and install it (ignoring any build requirement in the projectq
# package spec), and finally we install the rest of the optional requirements
@${PYTHON} -m pip install "setuptools<81" pybind11
@${PYTHON} -m pip install "git+https://github.com/ProjectQ-Framework/ProjectQ.git@v0.8.0" --no-build-isolation
install-optional: _install_projectq_qutip
@${PYTHON} -m pip install .\[opt\]

tests:
Expand All @@ -61,8 +69,11 @@ examples:
@cd examples/native-mode/teleport && bash terminate.sh && sleep 3
@echo "Chosen examples passed."

install: test-deps
@$(PYTHON) -m pip install -e . ${PIP_FLAGS}
install:
@$(PYTHON) -m pip install . ${PIP_FLAGS}

install-dev: install-optional
@${PYTHON} -m pip install -e .\[test,dev\]

_verified:
@echo "SimulaQron is verified!"
Expand Down
73 changes: 64 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SimulaQron - simple quantum network simulator (4.1.1)
# SimulaQron - simple quantum network simulator (4.1.2)

The purpose of this simulator of quantum network nodes is to allow you to develop new applications for
a future quantum internet, while we do not yet have real quantum network nodes available for testing.
Expand All @@ -10,6 +10,8 @@ See its documentation for how to use SimulaQron as a backend for running NetQASM

### Linux

#### Software dependencies

Before proceeding, make sure you install Python 3.12. Please note that Python 3.13 or newer *is not supported*.
To install Python 3.12 in Debian-based distributions, you can first add the "deadsnakes" repository:

Expand All @@ -22,25 +24,54 @@ Then you can install Python 3.12 and the Python development package:
```shell
sudo apt-get install python3.12-full python3.12-dev
```

Additionally, you will need the `build-essential` package, to install tools used when building some SimulaQron dependencies:

```shell
sudo apt-get install build-essential cmake vim linux-headers-generic
```
After this point, you should have all the required dependencies.


After this, you can install this repository by using the Makefile:
#### Create Python virtual environment (venv)

Before proceeding with the installation, create a python virtual environment (venv) and activate it:

```shell
make install
python3.12 -m venv simulaqron
source simulaqron/bin/activate
```


##### Installing from PyPI

Installing from PyPI is simple; once you activated your virtual environment, simply run:

```shell
pip install simulaqron
```

Which should install SimulaQron in its base backends. Additionally, to allow support for `projectq`, you might want
to install the optional dependencies:

```shell
pip install "simulaqron[opt]"
```


#### Installing from this repository

It is also possible to install SimulaQron directly from this repository. First, make sure you have checked out
this repository, then navigate to the root folder of SimulaQron's repository. Once there, you can install SimulaQron
by using the Makefile:

```shell
make install
```
Additionally, you can install SimulaQron with extra dependencies:
```shell
make install-optional
```


Finally, if you would like to contribute to the development of SimulaQron, please install the development dependencies:
```shell
make install-development
Expand All @@ -62,9 +93,33 @@ In Windows, SimulaQron can be installed in two similar ways:

### macOS

In macOS, the only supported way to install SimulaQron is by using a Virtual Machine. Considering this
please install a Virtual Machine Hypervisor such as [Oracle VirtualBox](https://www.virtualbox.org/wiki/Downloads),
and install a compatible operating system:
#### Native installation

SimulaQron has also been tested working on macOS Tahoe (26.5) on an M3 Pro CPU.

Before proceeding with the SimulaQron install, you need to install python 3.12, which is available from the
[Homebrew package manager](https://brew.sh/). Once that homebrew has been installed, you can install Python
3.12 using the following command:

```shell
brew install python@3.12 libomp
```

Additionally, to install the optional dependencies, you will need to install *XCode Command Line Tools*. To do
so, run the following command in a terminal:

```shell
xcode-select --install
```

And follow the instructions on the screen. After this, you can follow the instructions to install SimulaQron
either [from PyPI](#installing-from-pypi) or directly [from this repository](#installing-from-this-repository).


#### Using the provided virtual machines

It is also possible to install SimulaQron on macOS using a Virtual Machine. Considering this please install a
Virtual Machine Hypervisor such as [Oracle VirtualBox](https://www.virtualbox.org/wiki/Downloads), and install a compatible operating system:

* Intel-based Macs: This is the case for Mac computers with Intel processor.s You can directly install the ["amd64"
version of Ubuntu 24.04](https://ubuntu.com/download/desktop/thank-you?version=24.04.4&architecture=amd64&lts=true).
Expand Down Expand Up @@ -96,7 +151,7 @@ make tests_all


Documentation and examples are explained in the HTML documentation
https://softwarequtech.github.io/SimulaQron/html/index.html
https://softwarequtech.github.io/SimulaQron/index.html

For upcoming and previous changes see the file [CHANGELOG.md](CHANGELOG.md)

Expand Down
127 changes: 127 additions & 0 deletions docs/AppsArch.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
Architecture and Interactions of a SimulaQron App
=================================================

General Application Architecture
--------------------------------

The architecture of a SimulaQron application can be seen in the figure:

.. image:: figs/general-arch-1-node.png
:width: 500px
:align: center
:alt: SimulaQron Application Architecture with 1 node

When Alice needs to run a *local* quantum operation, it needs follow the process:

#. Alice creates a ``NetQASMConnection``. This opens a connection (a TCP socket) to Alice's backend, specifically to the
QNodeOS layer.
#. Alice uses the connection to perform quantum operations (allocate qubits, execute gates).
#. Quantum operations *are staged (buffered) in Alice application layer*. This means that *all quantum operations are not
immediately executed*.
#. At some point, Alice calls ``flush()`` on the connection. This invocation triggers the execution of *all the buffered
operations*.
#. ``flush()`` translates all the buffered operations into the NetQASM syntax, and groups them into a *NetQASM subroutine*.
The subroutine is then sent over the TCP connection to the QNodeOS layer.
#. The QNodeOS layer receives the NetQASM subroutine, parses it and executes the quantum operations.
#. To execute the quantum operations, the QNodeOS layer communicates with the Virtual Node layer, which is in charge
of the final simulation of the quantum hardware.
#. The execution is done using SimulaQron's *native interface*. This makes the QNodeOS server a translation layer
between NetQASM and SimulaQron's native interface.

In a scenario where more than one node is involved, it is required that the simulated quantum hardware to communicate
with other node's quantum hardware (for example, to create EPR pairs). This is done at Virtual Node level; each Virtual
Node instance keeps an open communication channel with its Virtual Node neighbours, so it can send signals and
information to "remote" nodes. Additionally, this open communication channel is also required due to SimulaQron's
distributed simulation nature. In this case, the general architecture can be seen in the following figure.

.. image:: figs/general-arch-2-nodes.png
:width: 700px
:align: center
:alt: SimulaQron Application Architecture with 2 nodes


Backend Processes Interactions
------------------------------

As explained in the previous section, SimulaQron requires a *backend* to be running when you are using quantum operations.
The SimulaQron backend can be started by using the ``simulaqron`` CLI tool - in particular, the ``simulaqron start``
subcommand.

The ``simulaqron start`` subcommand makes the CLI tool act as a *driver* whose only task is to spawn the backend
processes. SimulaQron uses *2 backend processes per node*:

* QNodeOS process: A server process that implements :doc:`the NetQASM Interface <NetQASM>`. The main purpose of this
process is to process all the NetQASM subroutines coming from the SimulaQron application, and execute them.
* Virtual Node process: The :ref:`*Virtual Quantum Node* <VNodes>`, a server process that pretends to be quantum
hardware.

The figure below depicts the process of executing ``simulaqron start --nodes=Alice,Bob`` (we assume that
the settings files are present in the current folder):

.. image:: figs/backend-startup.png
:width: 700px
:align: center
:alt: SimulaQron Application Architecture with 2 nodes

The startup of the backend perform the following operations:

#. The CLI tool (``simulaqron``) is invoked with the ``start`` subcommand. In this sense, the CLI tool becomes
the driver of the whole SimulaQron network backend.
#. The driver spawns the *virtual node* process for both Alice and Bob, and then it sleeps for a while to allow them
to correctly initialize.
#. When spawned, the virtual node processes setup the internals, and create a connection to *all* the quantum nodes
neighbours. In the depicted image, we see that Alice connects top Bob, but also Bob to Alice. This is needed since
any node can send a message (a command to execute quantum operations on a remote) to any of its neighbours. In an
:math:`n`-nodes configuration, the connections will create a clique graph. Being this said, there will be
:math:`n\times (n-1)` open connections among all the nodes.
#. After all the connections have been made, the Virtual Node processes will start accepting connections from their
respective QNodeOS nodes.
#. Once the drive process awakes again, it will spawn the *QNodeOS* processes.
#. When spawned, the QNodeOS processes perform their initialization, and connect to their respective Virtual Node
processes. This is needed since the QNodeOS processes will later send messages to the Virtual Node processes to
execute the quantum operations contained in a NetQASM subroutine. Please note that QNodeOS processes *only* connect
to their respective Virtual Node (Alice QNodeOS connect to and only to Alice Virtual Node process), so quantum
operations that will require update a qubit hosted by a remote node will trigger a message between Virtual Nodes
(i.e. the underlying Virtual Node connection is transparent for QNodeOS processes).
#. Once that each QNodeOS process is connected to their Virtual Node, they start listening to connections from the
application layer.
#. At this stage, the driver and all the spawned processes become daemons, and simply wait for activities in their
established connections. This is depicted by the dashed line in their respective timelines.

The interactions describes above summarize how the backend processes interact when starting a 2 nodes SimulaQron network.


Application Process Interaction
-------------------------------

Once the backend is running, the application processes (the python software that implements quantum programs) interact
with the backend processes to execute the quantum operations.

In general, the interactions are summarized in the following figure:

.. image:: figs/app-execution.png
:width: 700px
:align: center
:alt: SimulaQron Application Interaction with Backend

When the application process performs quantum operations, this is how they get executed:

#. The application process creates a ``NetQASMConnection`` object (henceforth named ``connection``), passing the
required argument (EPR Sockets, for example). By creating this object, the application process creates a TCP
connection with the respective QNodeOS process.
#. The application uses the ``connection`` object to create qubits, and apply quantum operations on the qubits.
#. The application process automatically *buffers* (stages) all these operations locally. This means that the
quantum operations *are not executed* immediately.
#. At some point, the application process invokes ``connection.flush()`` method, signaling the NetQASM library to
commit all the staged operations and send them for execution. To this end, the NetQASM library crates a *NetQASM
subroutine* which contains all the staged operations. The subroutine is then serialized, and sent over the TCP
connection to the QNodeOS process.
#. Once the QNodeOS process receives the NetQASM subroutine, the NetQASM subroutine get deserialized in the QNodeOS
process. This step allows the QNodeOS process to understand all the involved operations.
#. For each quantum operation, the QNodeOS process proceeds with its execution. This step involves invoking the right
remote calls on the Virtual Node process. Subsequentially (and due to SimulaQron distributed nature), executing one
quantum operation might trigger executing other operation on remote quantum nodes. This makes the "local" Virtual
Node process (the one that is executing the subroutine) to trigger other remote calls on remote nodes.
#. Once that all the quantum operations have been executed, the QNodeOS process determines the execution result of the
whole subroutine, and report it back to the application layer.
#. With this result, the application process continues executing the application program.
Loading