Skip to content

Commit

Permalink
Merge pull request #6 from KPRoche/KPRoche-real-backends
Browse files Browse the repository at this point in the history
Kp roche real backends
  • Loading branch information
KPRoche authored Oct 3, 2019
2 parents 292f6a8 + 1f037a4 commit f72c1d4
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 33 deletions.
106 changes: 78 additions & 28 deletions QuantumRaspberryTie.qiskit.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
# or older (0.2) IBMQ object
# October 2019 -- will attempt to load SenseHat and connect to hardware.
# If that fails, then loads and launches SenseHat emulator for display instead
# October 2019 -- added extra command line parameters. Can force use of Sensehat emulator, or specify backend
# (specifying use of a non-simulator backend will disable loop)
#----------------------------------------------------------------------


Expand All @@ -42,37 +44,63 @@
print(" ....qiskit.providers JobStatus")
from qiskit.providers import JobStatus
IBMQVersion = qiskit.__qiskit_version__
# This is temporary because the libraries are changing again
import warnings
print(" ....warnings")
import warnings


# Now we are going to try to instantiate the SenseHat.
# if it fails, we'll try loading the emulator
#Check any command arguments to see if we're forcing the emulator or changing the backend
UseEmulator = False
print(sys.argv)
print ("Number of arguments: ",len(sys.argv))
# look for a filename option or other starting parameters
qasmfileinput='expt.qasm'
if (len(sys.argv)>1):
for p in range (1, len(sys.argv)):
parameter = sys.argv[p]
if type(parameter) is str:
print("Parameter ",p," ",parameter)
if '-e' in parameter: UseEmulator = True
elif ':' in parameter:
token = parameter.split(':')[0]
value = parameter.split(':')[1]
if '-b' in token: backendparm = value
elif '-f' in token: qasmfileinput = value
else:
#print (type(sys.argv[1]))
qasmfileinput=parameter


# Now we are going to try to instantiate the SenseHat, unless we have asked for the emulator.
# if it fails, we'll try loading the emulator
SenseHatEMU = False
print ("... importing SenseHat and looking for hardware")
try:
from sense_hat import SenseHat
hat = SenseHat() # instantiating hat right away so we can use it in functions
except:
print ("... problem finding SenseHat")
print(" ....trying SenseHat Emulator instead")
if not UseEmulator:
print ("... importing SenseHat and looking for hardware")
try:
from sense_hat import SenseHat
hat = SenseHat() # instantiating hat right away so we can use it in functions
except:
print ("... problem finding SenseHat")
UseEmulator = True
print(" ....trying SenseHat Emulator instead")

if UseEmulator:
print ("....importing SenseHat Emulator")
from sense_emu import SenseHat # class for controlling the SenseHat
hat = SenseHat() # instantiating hat emulator so we can use it in functions
while not SenseHatEMU:
try:
hat.set_imu_config(True,True,True) #initialize the accelerometer simulation
except:
time.sleep(1)
sleep(1)
else:
SenseHatEMU = True



# some variables and settings we are going to need as we start up

print("Setting up...")
# This (hiding deprecation warnings) is temporary because the libraries are changing again
warnings.filterwarnings("ignore", category=DeprecationWarning)
Looping = True # this will be set false after the first go-round if a real backend is called
angle = 180
result = None
runcounter=0
Expand Down Expand Up @@ -301,16 +329,16 @@ def orient():
#def loadQASMfile():

scriptfolder = os.path.dirname(os.path.realpath("__file__"))
print(sys.argv)
print ("Number of arguments: ",len(sys.argv))
#print(sys.argv)
#print ("Number of arguments: ",len(sys.argv))
# look for a filename option
if (len(sys.argv) > 1) and type(sys.argv[1]) is str:
#if (len(sys.argv) > 1) and type(sys.argv[1]) is str:
#print (type(sys.argv[1]))
qasmfilename=sys.argv[1]
print ("input arg:",qasmfilename)
if (qasmfilename == '16'): qasmfilename='expt16.qasm'
else:
qasmfilename='expt.qasm'
# qasmfilename=sys.argv[1]
# print ("input arg:",qasmfilename)
if (qasmfileinput == '16'): qasmfilename='expt16.qasm'
else: qasmfilename = qasmfileinput
#qasmfilename='expt.qasm'

#complete the path if necessary
if ('/' not in qasmfilename):
Expand All @@ -322,6 +350,11 @@ def orient():
if (not os.path.isfile(qasmfilename)):
print("QASM file not found... exiting.")
exit()

# Parse any other parameters:



# end DEF ----------------------

###############################################################
Expand Down Expand Up @@ -356,7 +389,7 @@ def ping(website='https://quantumexperience.ng.bluemix.net',repeats=1,wait=0.5,v
elif int(response.status_code) == 524: # Cloudflare: A Timeout occurred
msg = 'Cloudflare: A Timeout occurred'
if verbose: print(response.status_code,msg)
if repeats>1: time.sleep(wait)
if repeats>1: sleep(wait)

return int(response.status_code)
# end DEF ----------------------------------------------------------------
Expand All @@ -376,16 +409,31 @@ def startIBMQ():
print('IBMQ Provider v',IBMQP_Vers)
print ('Pinging IBM Quantum Experience before start')
p=ping('https://api.quantum-computing.ibm.com',1,0.5,True)

try:
print("requested backend: ",backendparm)
except:
sleep(0)

# specify the simulator as the backend
backend='ibmq_qasm_simulator'
if p==200:
if (IBMQP_Vers > 0.2): # The new authentication technique with provider as the object
provider0=IBMQ.load_account()
Q=provider0.get_backend(backend)
try:
Q=provider0.get_backend(backendparm)
except:
Q=provider0.get_backend(backend)
else:
interval = 300
else: # The older IBMQ authentication technique
IBMQ.load_accounts()
Q=IBMQ.get_backend(backend)

try:
Q=IBMQ.get_backend(backendparm)
except:
Q=IBMQ.get_backend(backend)
else:
interval = 300
else:
exit()
#-------------------------------------------------------------------------------
Expand Down Expand Up @@ -433,7 +481,7 @@ def startIBMQ():
rainbowTie.start() # start the display thread


while True:
while Looping:
runcounter += 1

try:
Expand All @@ -453,10 +501,12 @@ def startIBMQ():
print('Backend Status: ',backend_status.status_msg)
if Q.status().status_msg == 'active':

print(' executing quantum circuit...')
print(' executing quantum circuit... on ',Q.name())
print(qcirc)
try:
qjob=execute(qcirc, Q, shots=500, memory=False)
Looping = 'simul' in Q.name()
if runcounter < 3: print("Using ", Q.name(), " ... Looping is set ", Looping)
except:
print("connection problem... half a tick and we'll try again...")
sleep(.5)
Expand Down
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# quantum-raspberry-tie
Your Raspberry Pi running code on the IBM Q quantum processors via Python 3 -- with results displayed courtesy of the 8x8 LED array on a SenseHat (or SenseHat emulator)!
## Third Release: will fail over to SenseHat emulator if no SenseHat hardware is detected.
## Third Release: will fail over to SenseHat emulator if no SenseHat hardware is detected. You may opt to send your quantum circuit to an actual quantum processor backend at IBM Q instead of the simulator

This code is specifically designed to run on a Raspberry Pi 3 with the SenseHat installed. The 8x8 array on the SenseHat is used to display the results.
Alternatively, if no SenseHat is detected, it will launch and use the display on a SenseHat emulator session instead.
Expand All @@ -17,7 +17,7 @@ The 16 qubit display corresponds to a 16-qubit processor
<br /><img src='ibm_16_qubit_processor-100722935-large.3x2.jpg' width='200' alt='IBM 16 qubit processor' style='float:left;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img src='16-bitRpi-result.JPG' width='200' alt='16 qubit Output displayed on the SenseHat' style='float:right;'><br/>

Actual calculations are run using the quantum simulator backend for the quantum processor, to avoid overwhelming the physical processor in the IBM Q lab.
Actual calculations are run using the quantum simulator backend for the quantum processor, to avoid overwhelming the physical processor in the IBM Q lab, unless you specify a real backend using the *-b* parameter. **Specifying a backend other than the simulator will disable the looping component of this program and send the job only a single time to IBMQ.**

The programs can trigger a shutdown of the Raspberry Pi by means of pressing and holding the SenseHat Joystick button straight down. This is very useful when running as a headless demo from battery, as it provides a means of safely shutting down the Pi and avoiding SD card damage even without a screen and input device.

Expand Down Expand Up @@ -57,8 +57,8 @@ Download the source code for the QuantumRaspberryTie program and the code should
Be sure to download the OPENQASM files as well (_expt.qasm_ & _expt16.qasm_) for the probram and put them in the same directory as your source file.

# Versions
There is now a single version of the code, which can run in one of two modes.
Both require that the **sense-hat** and **qiskit** libraries be installed in order to function, and use the **threading**, **time**, and **datetime** modules.
There is now a single version of the code, which can run in one of two quantum processor-size modes.
Both require that the **sense-hat**, **sense-emu** and **qiskit** libraries be installed in order to function, and use the **threading**, **time**, and **datetime** modules.

## QuantumRaspberryTie.qiskit.py
This program tries to test its connection to the IBM Q website before making requests. It's designed to cope somewhat gracefully with what happens if you are running on batteries and your Raspberry Pi switches wireless access points as you move around, or are in a somewhat glitchy wifi environment. It also can now handle gracefully communications timeouts with the IBM Q backend, or the occasional glitch where the simulator queue status for a job gets stuck in "RUNNING" state.
Expand All @@ -71,7 +71,18 @@ To start the program, simply call it from its directory (on my system, the defau
will launch with the 16-qubit circuit
+ *python QuantumRaspberryTie* _yourprogram.qasm_
will launch and attempt to load the circuit specified in file _yourprogram.qasm_

## New command line parameters (can be stacked with spaces between them) ##
+ *-e*
will launch and force use of the SenseHat emulator even if the SenseHat hardware is present
+ *-b:backendname*
will attempt to use the IBM Q Experience backend *backendname* instead of the simulator.
If you use a non-simulator backend, the code will execute only once instead of looping.
if connection fails, it will fail back to the simulator
+ *-f:qasmfilename*
will attempt to load the circuit specified in the file *qasmfilename*
if it can't load the file, will fail back to *expt.qasm*

After loading libraries, the program checks the SenseHat accelerometer to see which way the Pi is oriented. If it is flat on a table, "up" will be towards the power and display connectors on the Pi. If you wish to change the display orientation, simply hold the pi in the orientation you want until an up arrow appears on the display. The program will now use that orientation until the next cycle.

The program then pings the IBM Q Experience website to make sure it has a connection; if not it will exit.
Expand All @@ -81,6 +92,7 @@ It then loads the OPENQASM code for the experiment from a separarate text file,
If the ping is good, it then connects to the IBM Quantum Experience API using your token and initializes the LED display (displaying a Q). It compiles the OPENQASM code into a "quantum circuit", echoes the quantum circuit drawing to the terminal. and then sends the quantum circuit to the processor to execute. While it waits for the response, it cycles the light display through a rainbow shift to indicate that the system is "thinking". Once the result is returned by the processor, the measured values of the qubits are displayed as either red (measured 0) or blue (measured 1).

The system will pause for a few seconds, then run the code again (flashing the Q as it starts) to display a new result. You may trigger a new run sooner by pressing the SenseHat joystick in any direction. If you want to change which way on the display is "up" simply hold the Pi in the correct orientation until the Q displays as the cycle starts (the position is measured before sending the job).
*If you specify one of the non-simulator backends using the **-b** option, the program will not run in a loop, but will instead exit after sending the quantum circuit to IBM Q and displaying the result once. This is to avoid burning up your "credits" in the IBM Q Experience.*

In each cycle, the status of the backend is checked and printed to the console, as is the quantum circuit diagram, then the probability value and measured bit pattern of the most-frequent result wich is used for the display

Expand Down

0 comments on commit f72c1d4

Please sign in to comment.