 Alright everyone, I'd like to introduce our next speaker, Axel. Axel is currently doing a PhD in quantum information theory, with a focus on quantum networks at QTech in Delft. And that basically means that he's developing the tomorrow's or the future version of the internet, which would be a quantum internet. And he's an active developer on the Quantum Open Source Project Simulacron, which he's going to talk about, but also Q-Elk and CQC Python. And he gave a talk at last year's FOSSTEM, and today he's going to talk about this project Simulacron, a simulator for developing quantum internet software. So please welcome Axel. Thank you. It's really great to be back here. As mentioned I was here last year, and it's really nice to be back because last year I got really motivated on making Simulacron, which I'm going to present better and easier to use. So since then there's a lot of things that happened. For example, it's much more easy to install. It's now a package on PyPy, and there's a command line interface, so it's very easy to use, which I will show later in this talk. And maybe as Mark mentioned, one should not apologize in a talk, but I should maybe apologize because this track is called Quantum Computing, and I won't talk about Quantum Computing. I'll talk about Quantum Networks. And this is joint work with my professor, Stephanie Vayner. Is there some feedback? It's okay. Maybe I shouldn't talk too loud. Yeah, so let's get started. So as mentioned, I'm in Q-Tec, in Delft, as my last year in my PhD. And we're also part of the Quantum Internet Alliance in Europe, KIA. So in Delft, we're trying to build a Quantum Network. And maybe just to get a feeling for... Is it okay? Yeah. Just to get a feeling for who's in the audience, who ever heard about the notion of a Quantum Network before? A few? Okay, that's excellent. Then I can maybe, by the end of this talk, we will have a lot more that knows about Quantum Networks. So in a very simple picture, a Quantum Network is essentially a set of small quantum computers connected by quantum channels so they can exchange qubits and they can generate entanglement between each other. And at Q-Tec, we're not only thinking about this sort of theoretically, but we're actually building such a network at the moment in the Netherlands between four cities. So between Delft, Leiden, The Hague, and Amsterdam. And we currently have essentially a link between Delft and The Hague, and we're starting to testing it now. It's essentially a measurement point in Rijswijk, which is between Delft and The Hague. And this is a distance of roughly 25 kilometers. And then we will extend this to also have a link to Amsterdam, which is roughly 50 kilometers. So this is coming up. So you might ask, okay, why do we want to build a Quantum Network? Why is this interesting? And the reason, of course, is that we can do a lot of cool things if we have such a network, that a lot of applications for Quantum Network. And is there anyone that, for example, knows one application that you can run on a Quantum Network, which you can't do on a classical network? Perfect. So the most famous is, of course, Quantum Key Distribution, which is very nice to have being able to generate key which you can use for secure communication. But this is not the only one. There's a lot of other things that you can, for example, have better synchronization of clocks. You can extend the baseline of telescopes. You can do blind Quantum Computation and a lot more things like secret sharing, anonymous transfer, and so on. And essentially all of these things, what we need is entanglement. And this is basically the fundamental operation that a Quantum Network enables you to do. So maybe in comparison to a classical network, where essentially the fundamental operation is to send a classical message from one node to another. You might then think that, okay, in a Quantum Network, the fundamental operation is to send a qubit from one node to another. But in our view, this is not really the case. So here the fundamental operation is to generate entanglement. And the reason being that you can then use this entanglement to send qubits using teleportation. Now, we don't want to just build a Quantum Network, a small Quantum Network, but we want to go further. So we want to have a scalable design and be able to have essentially a Quantum Internet in the end. And furthermore, we don't want this to be essentially a large, hard-coded experiment, but this should be a universal programmable network where you can run any application you want. And it's more, it's essentially a service provided for anyone that wants to run an application. But for this, we need a lot of things to help you abstract, for example, the hardware away. So you shouldn't have to think about how do we encode qubits, how do we generate entanglement, all these things. So one thing that we need is, for example, a Quantum Network stack. Similarly to, for example, TCP IP in the classical network that abstracts certain functionalities away for you. And we have a proposal for such a Quantum Network stack. And also protocols for a, so a link layer protocol and a network layer protocol, network layer protocol that generates entanglement between, in the link layer protocol between nodes that are directly connected. And the network layer protocol generates entanglement between nodes that are not directly connected in the network. Now, a network stack is not the only thing you need that connects essentially an application and a hardware, because you also want to do, for example, gates, local gates on your nodes. And for this, we need essentially a full-fledged operating system between an application and hardware that enables you to do generate entanglement, do local gates, do scheduling of applications, do memory management, et cetera, et cetera. And what this does enables you to do is to, you as a programmer that wants to write some application, you don't need to think about what is actually the hardware in this network and how it's physically implemented. So the hardware might be nitrogen vacancies in diamonds or ion traps or atomic ensembles or whatever. You don't need to know about this. And in a more expanded picture, essentially, we envision that the, we call it the QNOTOS or the Quantum Node Operating System essentially has different, you could call it drivers for different hardware. So it has a hardware abstraction layer for, for example, these envy centers or ion traps, which is specific to that hardware. So that's maybe very nice, but then you might think, okay, I want to write one of these applications. How do I then communicate with this operating system? And this is where CQC comes in. And this is an interface that we defined. It stands for the Classical Quantum Combiner CQC. And this specifies essentially what instructions should an application send to the QNOTOS to specify what it wants to do. And our goal is not only to have this in an abstract world in simulation, but the network we are building should be compatible with this CQC interface. So you as a user, perhaps, could write an application on your own and then communicate with this network using CQC. CQC is essentially an instruction set. We defined the set of instructions encoded in some binary format. So it's not really meant to be used directly, but we written essentially libraries, which enables you to write an application that's in a more easy way that essentially then creates these CQC instructions for you. So for example, we have one which is maybe the most easy to use. One library in Python where you can write your applications. They send out CQC instructions. But CQC is essentially, it's both hardware independent, but it's also language independent. So we also have, oh, I should maybe, it was a wrong order here. So you might wonder, okay, I want to write one of these applications today, but we don't have this network yet. And this is exactly where CQC comes in. So it's a replacement for now until we have the actual hardware to write these applications. And it can understand this CQC interface. So you can already now today write your application using this Python library. It sends out CQC instructions and sends these to CQC. But we also have libraries, for example, in C, in Rust. And what's nice with this is that we can have essentially a community. So people can develop their own libraries in possible other languages. So there's also now actually an implementation in Java from Johan Voss at Glue on HQ, which is an open pool request at the moment for their simulator, Strange. There was also an implementation in Go during one of our hackathons we organized. I'm not sure it was fully finished. And I don't know exact status of this. But I think it's somewhere out there. But if you have another favorite language and you want to write your library, that's really great. So not only can CQC talk to Simulacron, but it can also talk to other simulators, which understands CQC. So at QTech, we also have a different simulator which is called NetSquid, which is actually a discrete event simulator for quantum networks. And maybe some of you have heard about, for example, NS3 for classical networks, which also does a discrete event simulation. And this is the world's first discrete event simulator for quantum networks. And it's hopefully going to be released in the coming months. And it's currently in beta. But of course, as I mentioned, in the future, when we have hardware, you should also be able to communicate with the hardware using CQC. So you can already today write your application in one of these languages. And without much change, when we have the hardware, you can then run your application on this hardware. So I'm saying without much change, because we have not maybe found the perfect version of CQC. It's currently in version two. We're working on version three at the moment, which has some more improvements in, for example, memory management and how you can maybe do classical logic in your program. So maybe more about Simulacron. So what's cool about Simulacron is not only that it understands CQC, but it's actually a distributed simulation. So I can install it on my laptop. You can install it on your laptops. And we can together simulate a quantum network using classical communication in the background. So we can set up a network like this on maybe three computers. We all run our own application that specifies certain gates or generates entanglement. And then we can simulate this together. So you might then wonder, okay, we have a quantum network, so there should be entanglement between our laptops, but these are classical computers. So how can we have entanglement in such a network? And what we essentially do is we simulate this with classical communication between our computers that essentially simulates the entanglement. And this works in a way such that any qubits that are entangled will be simulated on one of our computers. We might not know which one. But if I have a qubit on the simulator on my laptop, you have qubits similar on your laptop and they get entangled, one of them will move to either mine or to yours and stay in a combined state. And this is where the classical communication comes in. I won't go too much into the detail of this, but if you're interested, you can look more in the documentation where we essentially have the notion of virtual qubits, which are essentially pointers to the actual simulated qubits, which might live on another node in the network. And we tried to develop this in a kind of modular way. So the way we represent qubits are kind of detached from this distributed simulation. So we have different implementations of how we actually represent these qubits. So the first backend we used was using full density matrices, actually using Qtip. And if you're more interested in Qtip, there will be a talk, I think the next or the one after by Boxy. We also have backends essentially using Kets or vectors, which is using project Q. And we have our own version of stabilizing formalism, which is, of course, you can simulate efficiently in the number of qubits. And we can kind of see the implication of choosing which formalism you want to simulate by looking at this graph. So here's the regenerated GSS states, which is kind of a large entangled state, and you measure it. And this on the y axis, we have how much time it takes. And you can clearly see that both density matrices in Kets have an exponential scaling, the number of qubits, while it's maybe hard to see it's looks kind of flat, the stabilizer formula is essentially cubic in the number of qubits. And I should say this is not a comparison of different simulators, it's purely about which formalism you use. Yes, okay. So I thought that would give a demo. This is maybe a, let's see if this was a stupid idea or not. If everything goes wrong, then at least I tried, but okay, so let me see if I can bring up my terminal. Okay. Is this visible in the back? Let me know otherwise. So to get started, I want to show you all everything from scratch. So I will make a fresh virtual environment in Python. And just as a unrelated sign out, if you ever struggled with virtual environments in Python, check out my tool, which I call Manven, which is very nice to create temporary virtual environments. But first, we make a temporary virtual environments. So now we're completely fresh. We don't have essentially many packages installed here. So this is how you get started. And let's now install Simulacrum. So it will pull down some packages. And one of these packages it actually uses is CQC, which is this interface that we can communicate with Simulacrum. So now we have Simulacrum. Let's clear this. And we can then use our, this command line tool. So you can just run Simulacrum. It has a few commands. It's quite simple. What we can do, for example, is to look at settings. So there are a few different settings. For example, how many qubits should each node have? For example, which back end do we want to use? So by default, the back end is Stabilizer Formalism. But we can see, for example, we can choose Stabilizer Formalism, pretty cute, or cute tip. See how I'm doing on the time. So another thing we can see is we can specify a network configuration file that describes how does the network we want to simulate look like? Essentially, what's the addresses of the nodes? What's the topology? And I can show you an example of how this looks like. It's basically just a JSON file. So let me go to the documentation. Let me zoom in a bit. So here is how you can configure a simulated network. Let me go down to here. So here's an example of, basically, you write a JSON file that specifies essentially your IP address and port numbers of your simulated nodes since they can be on different computers. And you can also then specify a topology of your network. If you don't give it anything, by default, it's fully connected. But otherwise, you can specify essentially a JSONC matrix. In this case, Alice is connected to Bob. Bob is connected to Alice and Charlie, and so on. But that's how you define your simulation. So let's now get started. So by default, we have, we will have five nodes. You can see this by doing nodes and the ones to nodes in the network. So we have Alice, Bob, Charlie, David, and Eve fully connected. And now let's start Simulacron. So it asks you if you want to replace your configuration file, you can force to do this. It's not relevant. So now Simulacron is started. So it's running in the background. And maybe let me remind you of this picture, this big screen, this picture that we have here. So Simulacron acts as the backend as the server. So it's running in the background. And we can now write our application that actually sends the CTC messages to the simulation. In this case, actually, just using a TCP socket and sending these messages. So what we can now do is to just start Python in interactive mode. And we can import from CQC, a CQC connection, and a qubit. So the CQC connection enables us to connect to Simulacron. And in this case, we can, for example, be, say, we're now the node Alice. So we can start one of these CQC connection. And we're Alice. And I don't want to clutter my screen with a lot of debugging messages. So I set the log level to essentially only errors. So now we have a connection. And now we want to create a qubit. So we can create a qubit by essentially giving it the connection. And the reason for this is that whenever we then do an operation on this qubit, it will use the connection to send down the instruction to the hardware, or in this case, the simulation, to do the corresponding operation that we gave it. So now we have a qubit. We can, for example, do a Hadamard. And as I mentioned now, a message is sent down to the backend. Do a Hadamard. Hadamard is done. And we get a reply back, okay, it's finished. How am I on time? Good. So I think it's been 20 minutes. Okay, perfect. So this is one node. But the point is that we now have a network, right? So let's have another node. So I open up a new pane here that you could also think about that. Let's think that this new window is actually on a different computer. It's a completely different process. And since we made this, the Python environment, we should also activate it here. So I activated the last activated environment, this temporary environment. And we can now open Python. And then in the same, import this CPC connection and the qubit. Cool. So let's say that in this case now we're Bob. So we make a CPC connection, which is Bob. I don't want any log. Okay, cool. So now we have Alice and Bob. And let's create an entanglement between Alice and Bob. So on Alice we can say create an EPR pair with Bob. And we will then get a qubit. And let's call this qubit's EPR. On Bob's side, we will also get a qubit. Let's call it also EPR. These are actually different qubits. And Bob will receive grits. So now we have a qubit on Alice and a qubit on Bob. They are entangled, but they are simulated entangled. We can also get some information about this entanglement. So entanglement info. Let's print this. It has some information about the entanglement. So in this network stack that we are developing, entanglement gets essentially an ID that you can use to identify who am I entangled with and which entanglement is it, so that their nodes can agree on which entanglement pair to use in the network. And we can, for example, also see who am I entangled with. So in this slow case here with Bob, we have a qubit entangled with Alice. And let's now use this entangled pair to teleport a qubit. And so we want to teleport this qubit's queue that we already have. And maybe for you who know about this, let's remind you how you do teleportation. So we have some bell pair and some qubits we want to teleport. We do a C-naught and a hardboard and we measure our qubits and send classical messages to the other node to apply certain corrections. If you don't know this, it's fine. I just want to show you how it works. So let's do this. Let's do a C-naught between the qubits we want to teleport and the EPR pair. Let's do a Hadamard on the first qubit. Let's measure it and save the measurement outcome. In this case, do a zero. Let's measure the other one. It's also zero. Okay, maybe a bit boring. It's more exciting if you had to do a correction. So these are the measurement outcomes and we now need to send these to Bob because Bob needs to do the correction. So we can do this. We can say, Alice, send a classical message to Bob with the two measurement outcomes. And what Bob can undo is to receive these classical messages. And okay, they were both zero in this case. But for example, if one of them was one, we might have to do an X correction on the qubit of Bob. In this case, we didn't. So since the qubit we teleported was actually in the plus states, if we now measure this qubit, we should randomly get zero or one. And let's measure this. Okay, it was randomly one. Of course, we all see now that it's random. Of course, you cannot see this by just doing it one time. You have to do it many times and see that it's roughly one half, zero and one. But let me maybe go to an example. So how you would actually do this is not do it directly in the terminal. You can write a script. Let's say a Python script. In this case, Alice, you open up a Z connection to the back end. You maybe generate an EPR pair in qubits and so on. And in this case, we actually open up a Z connection in a context, which is a Python concept. And the reason is that when you then close this connection, or when it goes out of scope, it is closed and qubits get cleared up. But we written this two applications for Alice and Bob. And we can now run these with this run script, but essentially just puts these two processes in the background. So let's do this run. Okay, cool. So now we teleported once more. Alice measurement outcomes. Teleportation was again 0, 0. And both measurement outcome was 0. If you do this many times, 0, 0, 1, 0, 1. Okay, it's random. Cool. So that's how we use Simulacron. And let me go back to this. So if you want to know more about Simulacron, you can go to our web page. There's also links to the actual code and the documentation. And if you want to write your own library in some other language, let's communicate with CQC. That's great. And also if you want to connect this with your simulator, that's maybe even better. And we're happy for any contribution or questions or thoughts. And with this, I would like to thank you. And if there's any questions. So the question is not for the simulation, but for the real network. So you mentioned these two ways to build a network. The ion connector and the other one. And which states are the network between the your diversity and the other one? And which method do you use? Yeah, so for this network that we're building in the Netherlands at the moment, this will use these NV centers or nitrogen vacancies in diamonds. Because they are very nice in the sense that they have, they essentially have an electron, which you can entangle with another electron in another NV center. And around the electron there's a bunch of carbon spins, which you can use to store qubits. And they have a very long coherence time. So they are nice because you can both optically entangle these qubits, but you can also store them for a long time and do gates on them. So that's why they're very interesting for this scenario. They might not, they might be harder to scale. You might not be able to build a quantum computer with NV centers. But for many of our applications in a quantum network, we don't need many qubits and we don't need fault tolerance. We just need a handful of qubits to do QTD for example. Yeah, yeah, yeah. Any other questions? No? Okay, and let's thank the speaker. Thanks.