Add support for QVM's shared memory mode
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.5k
- Forks
- 358
- Avg merge
- 1d 58m
- Merged PRs (30d)
- 4
Description
Shared memory mode allows lots of great benefits for high-performance users of the QVM.
-
It allows the wavefunction to be shared across several processes in parallel.
-
It allows incremental computation of the wavefunction with successive calls to
.runand friends. -
It gives NumPy access to the wavefunction.
-
It allows manual state preparation/initialization.
Shared memory mode is and has been supported by the QVM (--shared) for quite some time, but it's not available in pyQuil since we've only recently released the SDK. The proposal is to add this to pyQuil, probably as a part of wavefunction simulator, but maybe elsewhere.
The following script is a PoC, but is outdated against current pyQuil and is Python 2. It prepares a 4q wavefunction in the W-state, and then inverts the bitstrings with X gates.
#!/usr/bin/env python
### shared_qvm.py
###
### Author: Robert Smith
###
### Copyright (c) 2017-2019 Rigetti Computing
### This file shows a minimal example of how to use the --shared
### option with QVM from Python.
from __future__ import print_function
import posix_ipc as pos
import mmap
import ctypes
import numpy as np
import socket
import json
import sys
from pyquil.api import QVMConnection
from pyquil.quil import Program
from pyquil.gates import X
def query_length_offset(name):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('/tmp/' + name)
s.sendall("?")
message, peer = s.recvfrom(4096)
length, offset = message.split(',')
return int(length), int(offset)
def retrieve_wavefunction(name):
length, offset = query_length_offset(name)
shm = pos.SharedMemory(name)
m = mmap.mmap(shm.fd, shm.size)
# get the pointer to what appear to be an array of bytes
ptr = ctypes.POINTER(ctypes.c_ubyte)(ctypes.c_void_p.from_buffer(m, offset))
# cast to array of complex double floats
ptr = ctypes.cast(ptr, np.ctypeslib.ndpointer(shape=(length,), dtype=np.complex128))
return np.ctypeslib.as_array(ptr)
# Example use of this interface.
if __name__ == '__main__':
if len(sys.argv) != 2:
print('Syntax: shared_qvm.py <name>')
sys.exit(1)
name = sys.argv[1]
cxn = QVMConnection(sync_endpoint='http://127.0.0.1:5000')
wf = retrieve_wavefunction(name)
print("Initial wavefunction:")
print(wf)
print("Initializing to W state.")
wf[0b0000] = 0j
wf[0b0001] = (1+0j)/np.sqrt(4)
wf[0b0010] = (1+0j)/np.sqrt(4)
wf[0b0100] = (1+0j)/np.sqrt(4)
wf[0b1000] = (1+0j)/np.sqrt(4)
print(wf)
print("Evolving with X3X2X1X0 via QVM. Quil program is:")
p = Program().inst([X(q) for q in range(4)])
print(p)
cxn.run(p, [0])
print("Printing evolved state.")
for b in range(len(wf)):
if not np.isclose(wf[b], 0j):
print("{0:04b} => {1}".format(b, wf[b]))
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the shared_qvm.py proof-of-concept and the pyquil.api.QVMConnection entry point, then inspect the wavefunction simulator area mentioned in the proposal. Compare the current Python 3 API with the outdated script and determine how the QVM --shared mode should be exposed. Done means pyQuil supports shared wavefunctions, incremental runs, NumPy access, and manual state initialization with suitable tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- numpy, python
- Domain
- quantum-computing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100