def test_api_auth_token(self):
     '''
     Authentication with Quantum Experience Platform
     '''
     api = IBMQuantumExperience(API_TOKEN)
     credential = api._check_credentials()
     self.assertTrue(credential)
Example #2
0
    def setUp(self):
        self.api = IBMQuantumExperience(API_TOKEN)
        self.qasm = """IBMQASM 2.0;

include "qelib1.inc";
qreg q[5];
creg c[5];
u2(-4*pi/3,2*pi) q[0];
u2(-3*pi/2,2*pi) q[0];
u3(-pi,0,-pi) q[0];
u3(-pi,0,-pi/2) q[0];
u2(pi,-pi/2) q[0];
u3(-pi,0,-pi/2) q[0];
measure q -> c;
"""

        self.qasms = [{
            "qasm": self.qasm
        }, {
            "qasm":
            """IBMQASM 2.0;

include "qelib1.inc";
qreg q[5];
creg c[3];
creg f[2];
x q[0];
measure q[0] -> c[0];
measure q[2] -> f[0];
"""
        }]

        self.q_obj = json.load(open(dir_path + '/q_obj.json'))
 def test_api_device_calibration(self):
     '''
     Check the calibration of a real chip
     '''
     api = IBMQuantumExperience(API_TOKEN)
     calibration = api.device_calibration()
     self.assertIsNotNone(calibration)
Example #4
0
 def test_api_device_status(self):
     '''
     Check the status of the real chip
     '''
     api = IBMQuantumExperience(API_TOKEN)
     is_available = api.device_status()
     self.assertIsNotNone(is_available)
 def test_api_devices_availables(self):
     '''
     Check the devices availables
     '''
     api = IBMQuantumExperience(API_TOKEN)
     devices = api.available_devices()
     self.assertGreaterEqual(len(devices), 2)
 def test_api_device_status(self):
     '''
     Check the status of a real chip
     '''
     api = IBMQuantumExperience(API_TOKEN)
     is_available = api.device_status()
     self.assertIsNotNone(is_available)
 def test_api_devices_availables(self):
     '''
     Check the devices availables
     '''
     api = IBMQuantumExperience(API_TOKEN)
     devices = api.available_devices()
     self.assertGreaterEqual(len(devices), 2)
Example #8
0
 def test_api_auth_token(self):
     '''
     Authentication with Quantum Experience Platform
     '''
     api = IBMQuantumExperience(API_TOKEN)
     credential = api._check_credentials()
     self.assertTrue(credential)
 def test_api_device_calibration(self):
     '''
     Check the calibration of a real chip
     '''
     api = IBMQuantumExperience(API_TOKEN)
     calibration = api.device_calibration()
     self.assertIsNotNone(calibration)
 def test_api_device_parameters(self):
     '''
     Check the parameters of calibration of a real chip
     '''
     api = IBMQuantumExperience(API_TOKEN)
     parameters = api.device_parameters()
     self.assertIsNotNone(parameters)
Example #11
0
def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('--apiToken')
    parser.add_argument('--url', nargs='?',
                        default='https://quantumexperience.ng.bluemix.net/api')
    parser.add_argument('--hub', nargs='?', default=None)
    parser.add_argument('--group', nargs='?', default=None)
    parser.add_argument('--project', nargs='?', default=None)

    args = vars(parser.parse_args())

    if (args['url'] is None):
        args['url'] = 'https://quantumexperience.ng.bluemix.net/api'

    if (args['hub'] is None) or (args['group'] is None) or (args['project'] is None):
        api = IBMQuantumExperience(args['apiToken'], {'url': args['url']})
        register(args['apiToken'], args['url'])
    else:
        api = IBMQuantumExperience(args['apiToken'], {
                                   'url': args['url'], 'hub': args['hub'], 'group': args['group'], 'project': args['project']})
        register(args['apiToken'], args['url'], args['hub'],
                 args['group'], args['project'])

    backs = available_backends()

    for back in backs:
        try:
            back_status = api.backend_status(back)
            print(json.dumps(back_status, indent=2, sort_keys=True))
        except:
            pass
Example #12
0
def mermin_test_comp(shots, basis):

    api = IBMQuantumExperience(API_TOKEN)
    device = 'real'
    n = len(basis)

    i = 0
    if n == 5:
        #Experiment registers and setup
        qasm = """IBMQASM 2.0;include "qelib1.inc";qreg q[5];creg c[5];h q[1];cx q[1],q[0];h q[1];h q[4];cx q[4],q[0];h q[3];h q[4];cx q[3],q[0];h q[2];h q[3];cx q[2],q[0];h q[2];h q[0];"""
    elif n == 4:
        i = 1
        qasm = """IBMQASM 2.0;include "qelib1.inc";qreg q[5];creg c[5];h q[1];x q[0];h q[3];h q[4];cx q[1],q[0];cx q[3],q[0];cx q[4],q[0];h q[1];h q[0];h q[3];h q[4];"""
    else:
        qasm = """IBMQASM 2.0;include "qelib1.inc";qreg q[5];creg c[5];h q[2];h q[1];x q[0];cx q[1],q[0];cx q[2],q[0];h q[2];h q[1];h q[0];"""

    for term in basis:
        if term == 'Y' or term == 'y':
            qasm += "sdg q[" + str(i) + "];"
        i += 1

    if n == 5:
        qasm += "h q[2];h q[1];h q[0];h q[3];h q[4];measure q[2] -> c[0];measure q[1] -> c[1];measure q[0] -> c[2];measure q[3] -> c[3];measure q[4] -> c[4];"
    elif n == 4:
        qasm += "h q[1];h q[0];h q[3];h q[4];measure q[1] -> c[1];measure q[0] -> c[2];measure q[3] -> c[3];measure q[4] -> c[4];"
    else:
        qasm += "h q[2];h q[1];h q[0];measure q[2] -> c[0];measure q[1] -> c[1];measure q[0] -> c[2];"

    exp = api.run_experiment(qasm, device, shots)
    return exp, basis
Example #13
0
def run_challenge(trials, flipped, device):
    '''
    Coin toss challenge on the quantum computer.

    Open QASM:
    
        IBMQASM 2.0;
        include "qelib1.inc";
        qreg q[1]; //define 1 quibit register
        creg c[1]; //define 1 classical register
        h q[0]; //perfrom hadamard on q[0]
        x q[0]; //perform NOT on q[0] (if random toss results in 1)
        h q[0]; //perfrom hadamard on q[0] again
        measure q[0] -> c[0]; //measure q[0] into c0[0]
    '''
    heads = 0
    tails = 0
    api = IBMQuantumExperience(API_TOKEN)

    for trial in range(trials):
        if (flipped and random_toss() == True):
            tails += 1
        else:
            heads += 1

    exp_heads = api.run_experiment(heads_qasm, device, heads)
    exp_tails = api.run_experiment(tails_qasm, device, tails)

    return exp_heads, exp_tails, heads, tails
Example #14
0
    def set_api(self, token, url, verify=True):
        """ Setup the API.

        Fills the __ONLINE_BACKENDS, __api, and __api_config variables.
        Does not catch exceptions from IBMQuantumExperience.

        Args:
            token (str): The token used to register on the online backend such
                as the quantum experience.
            url (str): The url used for online backend such as the quantum
                experience.
            verify (bool): If False, ignores SSL certificates errors.
        Raises:
            ConnectionError: if the API instantiation failed.
        """
        try:
            self.__api = IBMQuantumExperience(token, {"url": url}, verify)
        except Exception as ex:
            raise ConnectionError(
                "Couldn't connect to IBMQuantumExperience server: {0}".format(
                    ex))
        qiskit.backends.discover_remote_backends(self.__api)
        self.__ONLINE_BACKENDS = self.online_backends()
        self.__api_config["token"] = token
        self.__api_config["url"] = {"url": url}
Example #15
0
def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('--apiToken')
    parser.add_argument('--url', nargs='?',
                        default='https://quantumexperience.ng.bluemix.net/api')
    parser.add_argument('--hub', nargs='?', default=None)
    parser.add_argument('--group', nargs='?', default=None)
    parser.add_argument('--project', nargs='?', default=None)

    args = vars(parser.parse_args())

    if (args['url'] is None):
        args['url'] = 'https://quantumexperience.ng.bluemix.net/api'

    if (args['hub'] is None) or (args['group'] is None) or (args['project'] is None):
        api = IBMQuantumExperience(args['apiToken'], {'url': args['url']})
    else:
        api = IBMQuantumExperience(args['apiToken'], {
                                   'url': args['url'], 'hub': args['hub'], 'group': args['group'], 'project': args['project']})

    jobs = api.get_jobs()

    pending_jobs = []
    for job in jobs:
        if job['status'] == 'PENDING':
            pending_jobs.append(job)

    print(json.dumps(pending_jobs, indent=2, sort_keys=True))
Example #16
0
def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('--apiToken')
    parser.add_argument('--url',
                        nargs='?',
                        default='https://quantumexperience.ng.bluemix.net/api')
    parser.add_argument('--hub', nargs='?', default=None)
    parser.add_argument('--group', nargs='?', default=None)
    parser.add_argument('--project', nargs='?', default=None)

    args = vars(parser.parse_args())

    if (args['url'] is None):
        args['url'] = 'https://quantumexperience.ng.bluemix.net/api'

    if ((args['hub'] is None) or (args['group'] is None)
            or (args['project'] is None)):
        api = IBMQuantumExperience(args['apiToken'], {'url': args['url']})
    else:
        api = IBMQuantumExperience(
            args['apiToken'], {
                'url': args['url'],
                'hub': args['hub'],
                'group': args['group'],
                'project': args['project']
            })

    credits = api.get_my_credits()
    print(json.dumps(credits, indent=2, sort_keys=True))
 def test_api_device_parameters(self):
     '''
     Check the parameters of calibration of a real chip
     '''
     api = IBMQuantumExperience(API_TOKEN)
     parameters = api.device_parameters()
     self.assertIsNotNone(parameters)
Example #18
0
def test_api_auth_token():
    '''
    Authentication with Quantum Experience Platform
    '''
    api = IBMQuantumExperience(API_TOKEN)
    credential = api.check_credentials()

    return credential
Example #19
0
 def test_api_run_experiment(self):
     '''
     Check run an experiment by user authenticated
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm = "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
     device = 'simulator'
     shots = 1
     experiment = api.run_experiment(qasm, device, shots)
     self.assertIsNotNone(experiment['status'])
Example #20
0
 def test_api_run_experiment_fail_device(self):
     '''
     Check run an experiment by user authenticated is not runned because the device is not exist
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm = "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
     device = '5qreal'
     shots = 1
     experiment = api.run_experiment(qasm, device, shots)
     self.assertIsNotNone(experiment['error'])
 def test_api_run_experiment(self):
     '''
     Check run an experiment by user authenticated
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm = "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
     device = 'simulator'
     shots = 1
     experiment = api.run_experiment(qasm, device, shots)
     self.assertIsNotNone(experiment['status'])
 def test_api_run_experiment_fail_device(self):
     '''
     Check run an experiment by user authenticated is not runned because the device is not exist
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm = "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
     device = '5qreal'
     shots = 1
     experiment = api.run_experiment(qasm, device, shots)
     self.assertIsNotNone(experiment['error'])
Example #23
0
def computed_svetlichny():
    
    api = IBMQuantumExperience(API_TOKEN)
    device = 'ibmqx4'
    
    qasm = """IBMQASM 2.0;include "qelib1.inc";qreg q[5];creg c[5];h q[2];cx q[2],q[1];cx q[1],q[0];"""
    
    # The referee chooses a three bit string r s t uniformly from the set {000, 011, 101, 110}
    set = ['000', '001', '010', '011', '100', '101', '110', '111']
    referee = choice(set)
    i = 2 * int(referee[0]) - 1
    j = 2 * int(referee[1]) - 1
    k = 2 * int(referee[2]) - 1
    
    q = 0
    index = 0
    for val in referee:
        if val == '1':
            q += 1
        else:
            qasm += "sdg q[" + str(index) + "];"
        index += 1
    
    qasm += "h q[0];h q[1];h q[2];measure q[0] -> c[0];measure q[1] -> c[1];measure q[2] -> c[2];"
        
    exp = api.run_experiment(qasm, device, 1)
   
    state = print_results(exp)
    if(state is not None):
        state = state[2::]
        
        alice = int(state[2])
        bob = int(state[1])
        charlie = int(state[0])
        
        if alice == 0:
            alice = -1
        if bob == 0:
            bob = -1
        if charlie == 0:
            charlie = -1
        
        print("Referee: " + referee)
        print("i: " + str(i) + ", j: " + str(j) + ", k: " + str(k))
        print("q: " + str(q))
        print()
        print("Alice: " + str(alice))
        print("Bob: " + str(bob))
        print("Charlie: " + str(charlie))
        
        win = get_result(alice, bob, charlie, q)
        print("Win: " + str(win))
        return win
    else:
        return 0
 def test_api_run_experiment_with_seed(self):
     '''
     Check run an experiment with seed by user authenticated
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm = "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
     device = 'simulator'
     shots = 1
     seed = 815
     experiment = api.run_experiment(qasm, device, shots, seed=seed)
     self.assertEqual(int(experiment['result']['extraInfo']['seed']), seed)
 def test_api_run_experiment_with_seed(self):
     '''
     Check run an experiment with seed by user authenticated
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm = "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"
     device = 'simulator'
     shots = 1
     seed = 815
     experiment = api.run_experiment(qasm, device, shots, seed=seed)
     self.assertEqual(int(experiment['result']['extraInfo']['seed']), seed)
 def test_api_run_job_fail_device(self):
     '''
     Check run an job by user authenticated is not runned because the device is not exist
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm1 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"}
     qasm2 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nx q[0];\nmeasure q -> c;\n"}
     qasms = [qasm1, qasm2]
     device = 'real5'
     shots = 1
     job = api.run_job(qasms, device, shots)
     self.assertIsNotNone(job['error'])
 def test_api_run_job(self):
     '''
     Check run an job by user authenticated
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm1 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"}
     qasm2 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nx q[0];\nmeasure q -> c;\n"}
     qasms = [qasm1, qasm2]
     device = 'simulator'
     shots = 1
     job = api.run_job(qasms, device, shots)
     self.assertIsNotNone(job['status'])
 def test_api_run_job(self):
     '''
     Check run an job by user authenticated
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm1 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"}
     qasm2 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nx q[0];\nmeasure q -> c;\n"}
     qasms = [qasm1, qasm2]
     device = 'simulator'
     shots = 1
     job = api.run_job(qasms, device, shots)
     self.assertIsNotNone(job['status'])
 def test_api_run_job_fail_device(self):
     '''
     Check run an job by user authenticated is not runned because the device is not exist
     '''
     api = IBMQuantumExperience(API_TOKEN)
     qasm1 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n"}
     qasm2 = { "qasm": "IBMQASM 2.0;\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nx q[0];\nmeasure q -> c;\n"}
     qasms = [qasm1, qasm2]
     device = 'real5'
     shots = 1
     job = api.run_job(qasms, device, shots)
     self.assertIsNotNone(job['error'])
Example #30
0
def BB84(bitstring, use_real_quantum_computer=False, num_shots=1024):
    results = []
    backend = "simulator"
    if (use_real_quantum_computer):
        backend = "ibmqx4"

    #Set up API
    token = "fc5ece78b74c587781375562080c9045498ef906f494aae2a26598c42265083f1a7757f72b536431380d682d6ec9a18b1c40e21eeee3d350488bef58924c1cf0"
    api = IBMQuantumExperience(token)

    #Confirm enough credits remain if using a quantum computer
    if (backend != "simulator"):
        remaining_credits = (api.get_my_credits())["remaining"]
        print("Remaining credits: " + str(remaining_credits))
        if (remaining_credits < (len(bitstring) * 3)):
            print("Not enough credits remaining to use a quantum computer.")
            print("Reverting to simulation mode.")
            backend = "simulator"
        else:
            print(
                "Confirmed that there are enough credits remain to run the experiment."
            )

    #Run experiment
    for bit in bitstring:
        print("Sending \"" + bit + "\"")
        results.append(
            sendBoolBB84((bit == "1"),
                         api,
                         num_shots=num_shots,
                         backend=backend))

    print("Processing results...")
    total_SP = 0  #Success Probability, ie successful transmission
    total_IP = 0  #Invalid Probability, ie unsuccessful transmission
    total_CP = 0  #Corruption Probability, ie transmitted incorrect information
    for r in results:
        total_SP += r["Success Probability"]
        total_IP += r["Invalid Probability"]
        total_CP += r["Corruption Probability"]
    average_SP = total_SP / len(bitstring)
    average_IP = total_IP / len(bitstring)
    average_CP = total_CP / len(bitstring)

    print("\nResults:")
    print("Average success probability: " + str(average_SP))
    print("\tThis is the probability of a bit being transmitted successfully.")
    print("Average invalid probability: " + str(average_IP))
    print("\tThis is the probability of a bit failing to be transmitted.")
    print("Average corruption probability: " + str(average_CP))
    print("\tThis is the probability of a bit being transmitted incorrectly.")

    return
Example #31
0
def BB84(bitstring, use_real_quantum_computer = False, num_shots = 1024):
    results = []
    backend = "simulator"
    if (use_real_quantum_computer):
        backend = "ibmqx4"
    
    #Set up API
    token = ""
    api = IBMQuantumExperience(token)
    
    #Confirm that token has been set up
    if (token == "")
        print("API token has not been set up. Please enter it into the code in main.py")
        return
    
    #Confirm enough credits remain if using a quantum computer
    if (backend != "simulator"):
        remaining_credits = (api.get_my_credits())["remaining"]
        print("Remaining credits: " + str(remaining_credits))
        if (remaining_credits < (len(bitstring)*3)):
            print("Not enough credits remaining to use a quantum computer.")
            print("Reverting to simulation mode.")
            backend = "simulator"
        else:
            print("Confirmed that there are enough credits remain to run the experiment.")
            
    #Run experiment
    for bit in bitstring:
        print("Sending \"" + bit + "\"")
        results.append(sendBoolBB84( (bit=="1"), api, num_shots=num_shots, backend=backend))
    
    print("Processing results...")
    total_SP = 0        #Success Probability, ie successful transmission
    total_IP = 0        #Invalid Probability, ie unsuccessful transmission
    total_CP = 0        #Corruption Probability, ie transmitted incorrect information
    for r in results:
        total_SP += r["Success Probability"]
        total_IP += r["Invalid Probability"]
        total_CP += r["Corruption Probability"]
    average_SP = total_SP/len(bitstring)
    average_IP = total_IP/len(bitstring)
    average_CP = total_CP/len(bitstring)
    
    print("\nResults:")
    print("Average success probability: " + str(average_SP))
    print("\tThis is the probability of a bit being transmitted successfully.")
    print("Average invalid probability: " + str(average_IP))
    print("\tThis is the probability of a bit failing to be transmitted.")
    print("Average corruption probability: " + str(average_CP))
    print("\tThis is the probability of a bit being transmitted incorrectly.")
    
    return
Example #32
0
    def _authenticate(cls, token, url,
                      hub=None, group=None, project=None, proxies=None,
                      verify=True):
        """
        Authenticate against the IBMQuantumExperience API.

        Returns:
            IBMQuantumExperience.IBMQuantumExperience.IBMQuantumExperience:
                instance of the IBMQuantumExperience API.
        Raises:
            ConnectionError: if the authentication resulted in error.
        """
        try:
            config_dict = {
                'url': url,
            }
            # Only append hub/group/project if they are different than None.
            if all([hub, group, project]):
                config_dict.update({
                    'hub': hub,
                    'group': group,
                    'project': project
                })
            if proxies:
                config_dict['proxies'] = proxies
            return IBMQuantumExperience(token, config_dict, verify)
        except Exception as ex:
            root_exception = ex
            if 'License required' in str(ex):
                # For the 401 License required exception from the API, be
                # less verbose with the exceptions.
                root_exception = None
            raise ConnectionError("Couldn't connect to IBMQuantumExperience server: {0}"
                                  .format(ex)) from root_exception
Example #33
0
def register():
    global api
    if not api:
        api = IBMQuantumExperience(token=Qconfig.APItoken,
                                   config=Qconfig.config)
        backends = discover_remote_backends(api)
        print("Logged in. Possible backends: " + ", ".join(backends))
Example #34
0
    def _authenticate(cls, token, url, proxies=None, verify=True):
        """
        Authenticate against the IBMQuantumExperience API.

        Returns:
            IBMQuantumExperience.IBMQuantumExperience.IBMQuantumExperience:
                instance of the IBMQuantumExperience API.
        Raises:
            ConnectionError: if the authentication resulted in error.
        """
        try:
            config_dict = {
                'url': url,
            }
            if proxies:
                config_dict['proxies'] = proxies
            return IBMQuantumExperience(token, config_dict, verify)
        except Exception as ex:
            root_exception = ex
            if 'License required' in str(ex):
                # For the 401 License required exception from the API, be
                # less verbose with the exceptions.
                root_exception = None
            raise ConnectionError(
                "Couldn't connect to IBMQuantumExperience server: {0}".format(
                    ex)) from root_exception
Example #35
0
def compute():
    api = IBMQuantumExperience(TOKEN, CONFIG_URL)
    file_list = [z[2] for z in os.walk(PATH)][0]
    qasms = []
    completed_experiments = []
    for EXPERIMENT in file_list:
        with open(os.path.join(PATH, EXPERIMENT), 'r') as fopen:
            qasm = fopen.read()
            qasms.append(qasm)
            print "Running " + EXPERIMENT + "..."
            runit = api.run_experiment(qasm, DEVICE, SHOTS, EXPERIMENT,
                                       TIMEOUT)
            runit['fullname'] = os.path.join(PATH, EXPERIMENT)
            runit['name'] = EXPERIMENT
            completed_experiments.append(runit)
    exp_json = json.dumps(completed_experiments)
    with open(os.path.join(DATA_PATH, DATA_FILENAME), 'w') as fopen:
        fopen.write(exp_json)
Example #36
0
    def test_remote_backends_discover(self, QE_TOKEN, QE_URL):
        """Test if there are remote backends to be discovered.

        If all correct some should exists.
        """
        api = IBMQuantumExperience(QE_TOKEN, {'url': QE_URL})
        remote = qiskit.backends.discover_remote_backends(api)
        self.log.info(remote)
        self.assertTrue(remote)
Example #37
0
    def __init__(self,
                 q_jobs,
                 callback,
                 max_workers=1,
                 token=None,
                 url=None,
                 api=None):
        """
        Args:
            q_jobs (list(QuantumJob)): List of QuantumJob objects.
            callback (fn(results)): The function that will be called when all
                jobs finish. The signature of the function must be:
                fn(results)
                results: A list of Result objects.
            max_workers (int): The maximum number of workers to use.
            token (str): Server API token
            url (str): Server URL.
            api (IBMQuantumExperience): API instance to use. If set,
                /token/ and /url/ are ignored.
        """
        self.q_jobs = q_jobs
        self.max_workers = max_workers
        # check whether any jobs are remote
        self._local_backends = local_backends()
        self.online = any(qj.backend not in self._local_backends
                          for qj in q_jobs)
        self.futures = {}
        self.lock = Lock()
        # Set a default dummy callback just in case the user doesn't want
        # to pass any callback.
        self.callback = (lambda rs: ()) if callback is None else callback
        self.num_jobs = len(self.q_jobs)
        self.jobs_results = []
        if self.online:
            self._api = api if api else IBMQuantumExperience(
                token, {"url": url}, verify=True)
            self._online_backends = remote_backends(self._api)
            # Check for the existance of the backend
            for qj in q_jobs:
                if qj.backend not in self._online_backends + self._local_backends:
                    raise QISKitError("Backend %s not found!" % qj.backend)

            self._api_config = {}
            self._api_config["token"] = token
            self._api_config["url"] = {"url": url}
        else:
            self._api = None
            self._online_backends = None
            self._api_config = None
        if self.online:
            # I/O intensive -> use ThreadedPoolExecutor
            self.executor_class = futures.ThreadPoolExecutor
        else:
            # CPU intensive -> use ProcessPoolExecutor
            self.executor_class = futures.ProcessPoolExecutor
Example #38
0
def get_compiled_qasm(qp, name=None, backend="ibmqx5"):
    if name == None:
        name = get_name()
    global api
    if backend in ["ibmqx2", "ibmqx4", "ibmqx5"] and not api:
        api = IBMQuantumExperience(token=Qconfig.APItoken,
                                   config=Qconfig.config)
        backends = discover_remote_backends(api)
        print("Logged in. Possible backends: " + ", ".join(backends))
    qobj = qp.compile([name], backend=backend)
    return qp.get_compiled_qasm(qobj, name)
Example #39
0
    def test_get_backend_parameters(self, QE_TOKEN, QE_URL):
        """Test parameters.

        If all correct should return dictionary on length 4.
        """
        api = IBMQuantumExperience(QE_TOKEN, {'url': QE_URL})
        backend_list = qiskit.backends.discover_remote_backends(api)
        if backend_list:
            backend = backend_list[0]
        my_backend = qiskit.backends.get_backend_instance(backend)
        result = my_backend.parameters
        self.log.info(result)
        self.assertEqual(len(result), 4)
    def set_api(self, token, url, verify=True):
        """ Setup the API.

        Does not catch exceptions from IBMQuantumExperience.

        Args:
            Token (str): The token used to register on the online backend such
                as the quantum experience.
            URL (str): The url used for online backend such as the quantum
                experience.
            Verify (Boolean): If False, ignores SSL certificates errors.
        Returns:
            Nothing but fills the __ONLINE_BACKENDS, __api, and __api_config
        """
        try:
            self.__api = IBMQuantumExperience(token, {"url": url}, verify)
        except Exception as ex:
            raise ConnectionError("Couldn't connect to IBMQuantumExperience server: {0}"
                                  .format(ex))
        self.__ONLINE_BACKENDS = self.online_backends()
        self.__api_config["token"] = token
        self.__api_config["url"] = {"url": url}
    def set_api(self, token, url, verify=True):
        """ Setup the API.

        Does not catch exceptions from IBMQuantumExperience.

        Args:
            Token (str): The token used to register on the online backend such
                as the quantum experience.
            URL (str): The url used for online backend such as the quantum
                experience.
            Verify (Boolean): If False, ignores SSL certificates errors.
        Returns:
            Nothing but fills the __ONLINE_BACKENDS, __api, and __api_config
        """
        try:
            self.__api = IBMQuantumExperience(token, {"url": url}, verify)
        except Exception as ex:
            raise ConnectionError("Couldn't connect to IBMQuantumExperience server: {0}"
                              .format(ex))
        self.__ONLINE_BACKENDS = self.online_backends()
        self.__api_config["token"] = token
        self.__api_config["url"] = {"url": url}
    def set_api(self, token, url, verify=True):
        """ Setup the API.

        Fills the __ONLINE_BACKENDS, __api, and __api_config variables.
        Does not catch exceptions from IBMQuantumExperience.

        Args:
            token (str): The token used to register on the online backend such
                as the quantum experience.
            url (str): The url used for online backend such as the quantum
                experience.
            verify (bool): If False, ignores SSL certificates errors.
        Raises:
            ConnectionError: if the API instantiation failed.
        """
        try:
            self.__api = IBMQuantumExperience(token, {"url": url}, verify)
        except Exception as ex:
            raise ConnectionError("Couldn't connect to IBMQuantumExperience server: {0}"
                                  .format(ex))
        qiskit.backends.discover_remote_backends(self.__api)
        self.__ONLINE_BACKENDS = self.online_backends()
        self.__api_config["token"] = token
        self.__api_config["url"] = {"url": url}
 def test_api_last_codes(self):
     '''
     Check last code by user authenticated
     '''
     api = IBMQuantumExperience(API_TOKEN)
     self.assertIsNotNone(api.get_last_codes())
class QuantumProgram(object):
    """Quantum Program Class.

     Class internal properties.

     Elements that are not python identifiers or string constants are denoted
     by "--description (type)--". For example, a circuit's name is denoted by
     "--circuit name (string)--" and might have the value "teleport".

     Internal::

        __quantum_registers (list[dic]): An dictionary of quantum registers
            used in the quantum program.
            __quantum_registers =
                {
                --register name (string)--: QuantumRegistor,
                }
        __classical_registers (list[dic]): An ordered list of classical
            registers used in the quantum program.
            __classical_registers =
                {
                --register name (string)--: ClassicalRegistor,
                }
        __quantum_program (dic): An dictionary of quantum circuits
            __quantum_program =
                {
                --circuit name (string)--:  --circuit object --,
                }
        __init_circuit (obj): A quantum circuit object for the initial quantum
            circuit
        __ONLINE_BACKENDS (list[str]): A list of online backends
        __LOCAL_BACKENDS (list[str]): A list of local backends
     """
    # -- FUTURE IMPROVEMENTS --
    # TODO: for status results make ALL_CAPS (check) or some unified method
    # TODO: Jay: coupling_map, basis_gates will move into a config object
    # only exists once you set the api to use the online backends
    __api = {}
    __api_config = {}

    def __init__(self, specs=None):
        self.__quantum_registers = {}
        self.__classical_registers = {}
        self.__quantum_program = {}  # stores all the quantum programs
        self.__init_circuit = None  # stores the intial quantum circuit of the
        # program
        self.__ONLINE_BACKENDS = []  # pylint: disable=invalid-name
        self.__LOCAL_BACKENDS = qiskit.backends.local_backends()  # pylint: disable=invalid-name
        self.mapper = mapper
        if specs:
            self.__init_specs(specs)

        self.callback = None
        self.jobs_results = []
        self.jobs_results_ready_event = Event()
        self.are_multiple_results = False  # are we expecting multiple results?

    def enable_logs(self, level=logging.INFO):
        """Enable the console output of the logging messages.

        Enable the output of logging messages (above level `level`) to the
        console, by configuring the `qiskit` logger accordingly.

        Params:
            level (int): minimum severity of the messages that are displayed.

        Note:
            This is a convenience method over the standard Python logging
            facilities, and modifies the configuration of the 'qiskit.*'
            loggers. If finer control over the logging configuration is needed,
            it is encouraged to bypass this method.
        """
        # Update the handlers and formatters.
        set_qiskit_logger()
        # Set the logger level.
        logging.getLogger('qiskit').setLevel(level)

    def disable_logs(self):
        """Disable the console output of the logging messages.

        Disable the output of logging messages (above level `level`) to the
        console, by removing the handlers from the `qiskit` logger.

        Note:
            This is a convenience method over the standard Python logging
            facilities, and modifies the configuration of the 'qiskit.*'
            loggers. If finer control over the logging configuration is needed,
            it is encouraged to bypass this method.
        """
        unset_qiskit_logger()

    ###############################################################
    # methods to initiate an build a quantum program
    ###############################################################

    def __init_specs(self, specs):
        """Populate the Quantum Program Object with initial Specs.

        Args:
            specs (dict):
                    Q_SPECS = {
                        "circuits": [{
                            "name": "Circuit",
                            "quantum_registers": [{
                                "name": "qr",
                                "size": 4
                            }],
                            "classical_registers": [{
                                "name": "cr",
                                "size": 4
                            }]
                        }],
        """
        quantumr = []
        classicalr = []
        if "circuits" in specs:
            for circuit in specs["circuits"]:
                quantumr = self.create_quantum_registers(
                    circuit["quantum_registers"])
                classicalr = self.create_classical_registers(
                    circuit["classical_registers"])
                self.create_circuit(name=circuit["name"], qregisters=quantumr,
                                    cregisters=classicalr)
        # TODO: Jay: I think we should return function handles for the
        # registers and circuit. So that we dont need to get them after we
        # create them with get_quantum_register etc

    def create_quantum_register(self, name, size):
        """Create a new Quantum Register.

        Args:
            name (str): the name of the quantum register
            size (int): the size of the quantum register

        Returns:
            QuantumRegister: internal reference to a quantum register in __quantum_registers

        Raises:
            QISKitError: if the register already exists in the program.
        """
        if name in self.__quantum_registers:
            if size != len(self.__quantum_registers[name]):
                raise QISKitError("Can't make this register: Already in"
                                  " program with different size")
            logger.info(">> quantum_register exists: %s %s", name, size)
        else:
            self.__quantum_registers[name] = QuantumRegister(name, size)
            logger.info(">> new quantum_register created: %s %s", name, size)
        return self.__quantum_registers[name]

    def create_quantum_registers(self, register_array):
        """Create a new set of Quantum Registers based on a array of them.

        Args:
            register_array (list[dict]): An array of quantum registers in
                dictionay format::

                    "quantum_registers": [
                        {
                        "name": "qr",
                        "size": 4
                        },
                        ...
                    ]
        Returns:
            list(QuantumRegister): Array of quantum registers objects
        """
        new_registers = []
        for register in register_array:
            register = self.create_quantum_register(
                register["name"], register["size"])
            new_registers.append(register)
        return new_registers

    def create_classical_register(self, name, size):
        """Create a new Classical Register.

        Args:
            name (str): the name of the classical register
            size (int): the size of the classical register
        Returns:
            ClassicalRegister: internal reference to a classical register in __classical_registers

        Raises:
            QISKitError: if the register already exists in the program.
        """
        if name in self.__classical_registers:
            if size != len(self.__classical_registers[name]):
                raise QISKitError("Can't make this register: Already in"
                                  " program with different size")
            logger.info(">> classical register exists: %s %s", name, size)
        else:
            logger.info(">> new classical register created: %s %s", name, size)
            self.__classical_registers[name] = ClassicalRegister(name, size)
        return self.__classical_registers[name]

    def create_classical_registers(self, registers_array):
        """Create a new set of Classical Registers based on a array of them.

        Args:
            registers_array (list[dict]): An array of classical registers in
                dictionay fromat::

                    "classical_registers": [
                        {
                        "name": "qr",
                        "size": 4
                        },
                        ...
                    ]
        Returns:
            list(ClassicalRegister): Array of clasical registers objects
        """
        new_registers = []
        for register in registers_array:
            new_registers.append(self.create_classical_register(
                register["name"], register["size"]))
        return new_registers

    def create_circuit(self, name, qregisters=None, cregisters=None):
        """Create a empty Quantum Circuit in the Quantum Program.

        Args:
            name (str): the name of the circuit.
            qregisters (list(QuantumRegister)): is an Array of Quantum Registers by object
                reference
            cregisters (list(ClassicalRegister)): is an Array of Classical Registers by
                object reference

        Returns:
            QuantumCircuit: A quantum circuit is created and added to the Quantum Program
        """
        if not qregisters:
            qregisters = []
        if not cregisters:
            cregisters = []
        quantum_circuit = QuantumCircuit()
        if not self.__init_circuit:
            self.__init_circuit = quantum_circuit
        for register in qregisters:
            quantum_circuit.add(register)
        for register in cregisters:
            quantum_circuit.add(register)
        self.add_circuit(name, quantum_circuit)
        return self.__quantum_program[name]

    def add_circuit(self, name, quantum_circuit):
        """Add a new circuit based on an Object representation.

        Args:
            name (str): the name of the circuit to add.
            quantum_circuit (QuantumCircuit): a quantum circuit to add to the program-name
        """
        for qname, qreg in quantum_circuit.get_qregs().items():
            self.create_quantum_register(qname, len(qreg))
        for cname, creg in quantum_circuit.get_cregs().items():
            self.create_classical_register(cname, len(creg))
        self.__quantum_program[name] = quantum_circuit

    def load_qasm_file(self, qasm_file, name=None,
                       basis_gates='u1,u2,u3,cx,id'):
        """ Load qasm file into the quantum program.

        Args:
            qasm_file (str): a string for the filename including its location.
            name (str or None): the name of the quantum circuit after
                loading qasm text into it. If no name is give the name is of
                the text file.
            basis_gates (str): basis gates for the quantum circuit.
        Returns:
            str: Adds a quantum circuit with the gates given in the qasm file to the
            quantum program and returns the name to be used to get this circuit
        Raises:
            QISKitError: if the file cannot be read.
        """
        if not os.path.exists(qasm_file):
            raise QISKitError('qasm file "{0}" not found'.format(qasm_file))
        if not name:
            name = os.path.splitext(os.path.basename(qasm_file))[0]
        node_circuit = qasm.Qasm(filename=qasm_file).parse()  # Node (AST)
        logger.info("circuit name: " + name)
        logger.info("******************************")
        logger.info(node_circuit.qasm())
        # current method to turn it a DAG quantum circuit.
        unrolled_circuit = unroll.Unroller(node_circuit,
                                           unroll.CircuitBackend(basis_gates.split(",")))
        circuit_unrolled = unrolled_circuit.execute()
        self.add_circuit(name, circuit_unrolled)
        return name

    def load_qasm_text(self, qasm_string, name=None,
                       basis_gates='u1,u2,u3,cx,id'):
        """ Load qasm string in the quantum program.

        Args:
            qasm_string (str): a string for the file name.
            name (str or None): the name of the quantum circuit after loading qasm
                text into it. If no name is give the name is of the text file.
            basis_gates (str): basis gates for the quantum circuit.
        Returns:
            str: Adds a quantum circuit with the gates given in the qasm string to
            the quantum program.
        """
        node_circuit = qasm.Qasm(data=qasm_string).parse()  # Node (AST)
        if not name:
            # Get a random name if none is given
            name = "".join([random.choice(string.ascii_letters+string.digits)
                            for n in range(10)])
        logger.info("circuit name: " + name)
        logger.info("******************************")
        logger.info(node_circuit.qasm())
        # current method to turn it a DAG quantum circuit.
        unrolled_circuit = unroll.Unroller(node_circuit,
                                           unroll.CircuitBackend(basis_gates.split(",")))
        circuit_unrolled = unrolled_circuit.execute()
        self.add_circuit(name, circuit_unrolled)
        return name

    ###############################################################
    # methods to get elements from a QuantumProgram
    ###############################################################

    def get_quantum_register(self, name):
        """Return a Quantum Register by name.

        Args:
            name (str): the name of the quantum register
        Returns:
            QuantumRegister: The quantum register with this name
        Raises:
            KeyError: if the quantum register is not on the quantum program.
        """
        try:
            return self.__quantum_registers[name]
        except KeyError:
            raise KeyError('No quantum register "{0}"'.format(name))

    def get_classical_register(self, name):
        """Return a Classical Register by name.

        Args:
            name (str): the name of the classical register
        Returns:
            ClassicalRegister: The classical register with this name
        Raises:
            KeyError: if the classical register is not on the quantum program.
        """
        try:
            return self.__classical_registers[name]
        except KeyError:
            raise KeyError('No classical register "{0}"'.format(name))

    def get_quantum_register_names(self):
        """Return all the names of the quantum Registers."""
        return self.__quantum_registers.keys()

    def get_classical_register_names(self):
        """Return all the names of the classical Registers."""
        return self.__classical_registers.keys()

    def get_circuit(self, name):
        """Return a Circuit Object by name
        Args:
            name (str): the name of the quantum circuit
        Returns:
            QuantumCircuit: The quantum circuit with this name
        Raises:
            KeyError: if the circuit is not on the quantum program.
        """
        try:
            return self.__quantum_program[name]
        except KeyError:
            raise KeyError('No quantum circuit "{0}"'.format(name))

    def get_circuit_names(self):
        """Return all the names of the quantum circuits."""
        return self.__quantum_program.keys()

    def get_qasm(self, name):
        """Get qasm format of circuit by name.

        Args:
            name (str): name of the circuit

        Returns:
            str: The quantum circuit in qasm format
        """
        quantum_circuit = self.get_circuit(name)
        return quantum_circuit.qasm()

    def get_qasms(self, list_circuit_name):
        """Get qasm format of circuit by list of names.

        Args:
            list_circuit_name (list[str]): names of the circuit

        Returns:
            list(QuantumCircuit): List of quantum circuit in qasm format
        """
        qasm_source = []
        for name in list_circuit_name:
            qasm_source.append(self.get_qasm(name))
        return qasm_source

    def get_initial_circuit(self):
        """Return the initialization Circuit."""
        return self.__init_circuit

    ###############################################################
    # methods for working with backends
    ###############################################################

    def set_api(self, token, url, verify=True):
        """ Setup the API.

        Fills the __ONLINE_BACKENDS, __api, and __api_config variables.
        Does not catch exceptions from IBMQuantumExperience.

        Args:
            token (str): The token used to register on the online backend such
                as the quantum experience.
            url (str): The url used for online backend such as the quantum
                experience.
            verify (bool): If False, ignores SSL certificates errors.
        Raises:
            ConnectionError: if the API instantiation failed.
        """
        try:
            self.__api = IBMQuantumExperience(token, {"url": url}, verify)
        except Exception as ex:
            raise ConnectionError("Couldn't connect to IBMQuantumExperience server: {0}"
                                  .format(ex))
        qiskit.backends.discover_remote_backends(self.__api)
        self.__ONLINE_BACKENDS = self.online_backends()
        self.__api_config["token"] = token
        self.__api_config["url"] = {"url": url}

    def get_api_config(self):
        """Return the program specs."""
        return self.__api_config

    def get_api(self):
        """Returns a function handle to the API."""
        return self.__api

    def save(self, file_name=None, beauty=False):
        """ Save Quantum Program in a Json file.

        Args:
            file_name (str): file name and path.
            beauty (boolean): save the text with indent 4 to make it readable.

        Returns:
            dict: The dictionary with the status and result of the operation

        Raises:
            LookupError: if the file_name is not correct, or writing to the
                file resulted in an error.
        """
        if file_name is None:
            error = {"status": "Error", "result": "Not filename provided"}
            raise LookupError(error['result'])

        if beauty:
            indent = 4
        else:
            indent = 0

        elemements_to_save = self.__quantum_program
        elements_saved = {}

        for circuit in elemements_to_save:
            elements_saved[circuit] = {}
            elements_saved[circuit]["qasm"] = elemements_to_save[circuit].qasm()

        try:
            with open(file_name, 'w') as save_file:
                json.dump(elements_saved, save_file, indent=indent)
            return {'status': 'Done', 'result': elemements_to_save}
        except ValueError:
            error = {'status': 'Error', 'result': 'Some Problem happened to save the file'}
            raise LookupError(error['result'])

    def load(self, file_name=None):
        """ Load Quantum Program Json file into the Quantum Program object.

        Args:
            file_name (str): file name and path.

        Returns:
            dict: The dictionary with the status and result of the operation

        Raises:
            LookupError: if the file_name is not correct, or reading from the
                file resulted in an error.
        """
        if file_name is None:
            error = {"status": "Error", "result": "Not filename provided"}
            raise LookupError(error['result'])

        try:
            with open(file_name, 'r') as load_file:
                elemements_loaded = json.load(load_file)

            for circuit in elemements_loaded:
                circuit_qasm = elemements_loaded[circuit]["qasm"]
                elemements_loaded[circuit] = qasm.Qasm(data=circuit_qasm).parse()
            self.__quantum_program = elemements_loaded

            return {"status": 'Done', 'result': self.__quantum_program}

        except ValueError:
            error = {'status': 'Error', 'result': 'Some Problem happened to load the file'}
            raise LookupError(error['result'])

    def available_backends(self):
        """All the backends that are seen by QISKIT."""
        return self.__ONLINE_BACKENDS + self.__LOCAL_BACKENDS

    def online_backends(self):
        """Get the online backends.

        Queries network API if it exists and gets the backends that are online.

        Returns:
            list(str): List of online backends names if the online api has been set or an empty
                list if it has not been set.

        Raises:
            ConnectionError: if the API call failed.
        """
        if self.get_api():
            try:
                backends = self.__api.available_backends()
            except Exception as ex:
                raise ConnectionError("Couldn't get available backend list: {0}"
                                      .format(ex))
            return [backend['name'] for backend in backends]
        return []

    def online_simulators(self):
        """Gets online simulators via QX API calls.

        Returns:
            list(str): List of online simulator names.

        Raises:
            ConnectionError: if the API call failed.
        """
        online_simulators_list = []
        if self.get_api():
            try:
                backends = self.__api.available_backends()
            except Exception as ex:
                raise ConnectionError("Couldn't get available backend list: {0}"
                                      .format(ex))
            for backend in backends:
                if backend['simulator']:
                    online_simulators_list.append(backend['name'])
        return online_simulators_list

    def online_devices(self):
        """Gets online devices via QX API calls.

        Returns:
            list(str): List of online devices names.

        Raises:
            ConnectionError: if the API call failed.
        """
        devices = []
        if self.get_api():
            try:
                backends = self.__api.available_backends()
            except Exception as ex:
                raise ConnectionError("Couldn't get available backend list: {0}"
                                      .format(ex))
            for backend in backends:
                if not backend['simulator']:
                    devices.append(backend['name'])
        return devices

    def get_backend_status(self, backend):
        """Return the online backend status.

        It uses QX API call or by local backend is the name of the
        local or online simulator or experiment.

        Args:
            backend (str): The backend to check

        Returns:
            dict: {'available': True}

        Raises:
            ConnectionError: if the API call failed.
            ValueError: if the backend is not available.
        """

        if backend in self.__ONLINE_BACKENDS:
            try:
                return self.__api.backend_status(backend)
            except Exception as ex:
                raise ConnectionError("Couldn't get backend status: {0}"
                                      .format(ex))
        elif backend in self.__LOCAL_BACKENDS:
            return {'available': True}
        else:
            raise ValueError('the backend "{0}" is not available'.format(backend))

    def get_backend_configuration(self, backend, list_format=False):
        """Return the configuration of the backend.

        The return is via QX API call.

        Args:
            backend (str):  Name of the backend.
            list_format (bool): Struct used for the configuration coupling
                map: dict (if False) or list (if True).

        Returns:
            dict: The configuration of the named backend.

        Raises:
            ConnectionError: if the API call failed.
            LookupError: if a configuration for the named backend can't be
                found.
        """
        if self.get_api():
            configuration_edit = {}
            try:
                backends = self.__api.available_backends()
            except Exception as ex:
                raise ConnectionError("Couldn't get available backend list: {0}"
                                      .format(ex))
            for configuration in backends:
                if configuration['name'] == backend:
                    for key in configuration:
                        new_key = convert(key)
                        # TODO: removed these from the API code
                        if new_key not in ['id', 'serial_number', 'topology_id',
                                           'status', 'coupling_map']:
                            configuration_edit[new_key] = configuration[key]
                        if new_key == 'coupling_map':
                            if configuration[key] == 'all-to-all':
                                configuration_edit[new_key] = \
                                    configuration[key]
                            else:
                                if not list_format:
                                    cmap = mapper.coupling_list2dict(configuration[key])
                                else:
                                    cmap = configuration[key]
                                configuration_edit[new_key] = cmap
                    return configuration_edit
        else:
            return qiskit.backends.get_backend_configuration(backend)

    def get_backend_calibration(self, backend):
        """Return the online backend calibrations.

        The return is via QX API call.

        Args:
            backend (str):  Name of the backend.

        Returns:
            dict: The calibration of the named backend.

        Raises:
            ConnectionError: if the API call failed.
            LookupError: If a configuration for the named backend can't be
                found.
        """
        if backend in self.__ONLINE_BACKENDS:
            try:
                calibrations = self.__api.backend_calibration(backend)
            except Exception as ex:
                raise ConnectionError("Couldn't get backend calibration: {0}"
                                      .format(ex))
            calibrations_edit = {}
            for key, vals in calibrations.items():
                new_key = convert(key)
                calibrations_edit[new_key] = vals
            return calibrations_edit
        elif backend in self.__LOCAL_BACKENDS:
            return {'backend': backend, 'calibrations': None}
        else:
            raise LookupError(
                'backend calibration for "{0}" not found'.format(backend))

    def get_backend_parameters(self, backend):
        """Return the online backend parameters.

        The return is via QX API call.

        Args:
            backend (str):  Name of the backend.

        Returns:
            dict: The configuration of the named backend.

        Raises:
            ConnectionError: if the API call failed.
            LookupError: If a configuration for the named backend can't be
                found.
        """
        if backend in self.__ONLINE_BACKENDS:
            try:
                parameters = self.__api.backend_parameters(backend)
            except Exception as ex:
                raise ConnectionError("Couldn't get backend paramters: {0}"
                                      .format(ex))
            parameters_edit = {}
            for key, vals in parameters.items():
                new_key = convert(key)
                parameters_edit[new_key] = vals
            return parameters_edit
        elif backend in self.__LOCAL_BACKENDS:
            return {'backend': backend, 'parameters': None}
        else:
            raise LookupError(
                'backend parameters for "{0}" not found'.format(backend))

    ###############################################################
    # methods to compile quantum programs into qobj
    ###############################################################

    def compile(self, name_of_circuits, backend="local_qasm_simulator",
                config=None, basis_gates=None, coupling_map=None,
                initial_layout=None, shots=1024, max_credits=3, seed=None,
                qobj_id=None):
        """Compile the circuits into the exectution list.

        This builds the internal "to execute" list which is list of quantum
        circuits to run on different backends.

        Args:
            name_of_circuits (list[str]): circuit names to be compiled.
            backend (str): a string representing the backend to compile to
            config (dict): a dictionary of configurations parameters for the
                compiler
            basis_gates (str): a comma seperated string and are the base gates,
                               which by default are: u1,u2,u3,cx,id
            coupling_map (dict): A directed graph of coupling::

                {
                 control(int):
                     [
                         target1(int),
                         target2(int),
                         , ...
                     ],
                     ...
                }

                eg. {0: [2], 1: [2], 3: [2]}

            initial_layout (dict): A mapping of qubit to qubit::

                                  {
                                    ("q", strart(int)): ("q", final(int)),
                                    ...
                                  }
                                  eg.
                                  {
                                    ("q", 0): ("q", 0),
                                    ("q", 1): ("q", 1),
                                    ("q", 2): ("q", 2),
                                    ("q", 3): ("q", 3)
                                  }

            shots (int): the number of shots
            max_credits (int): the max credits to use 3, or 5
            seed (int): the intial seed the simulatros use
            qobj_id (str): identifier of the qobj.

        Returns:
            dict: the job id and populates the qobj::

            qobj =
                {
                    id: --job id (string),
                    config: -- dictionary of config settings (dict)--,
                        {
                        "max_credits" (online only): -- credits (int) --,
                        "shots": -- number of shots (int) --.
                        "backend": -- backend name (str) --
                        }
                    circuits:
                        [
                            {
                            "name": --circuit name (string)--,
                            "compiled_circuit": --compiled quantum circuit (JSON format)--,
                            "compiled_circuit_qasm": --compiled quantum circuit (QASM format)--,
                            "config": --dictionary of additional config settings (dict)--,
                                {
                                "coupling_map": --adjacency list (dict)--,
                                "basis_gates": --comma separated gate names (string)--,
                                "layout": --layout computed by mapper (dict)--,
                                "seed": (simulator only)--initial seed for the simulator (int)--,
                                }
                            },
                            ...
                        ]
                    }

        Raises:
            ValueError: if no names of the circuits have been specified.
            QISKitError: if any of the circuit names cannot be found on the
                Quantum Program.
        """
        # TODO: Jay: currently basis_gates, coupling_map, initial_layout,
        # shots, max_credits and seed are extra inputs but I would like
        # them to go into the config.

        qobj = {}
        if not qobj_id:
            qobj_id = "".join([random.choice(string.ascii_letters+string.digits)
                               for n in range(30)])
        qobj['id'] = qobj_id
        qobj["config"] = {"max_credits": max_credits, 'backend': backend,
                          "shots": shots}
        qobj["circuits"] = []

        if not name_of_circuits:
            raise ValueError('"name_of_circuits" must be specified')
        if isinstance(name_of_circuits, str):
            name_of_circuits = [name_of_circuits]
        for name in name_of_circuits:
            if name not in self.__quantum_program:
                raise QISKitError('circuit "{0}" not found in program'.format(name))
            if not basis_gates:
                basis_gates = "u1,u2,u3,cx,id"  # QE target basis
            # TODO: The circuit object going into this is to have .qasm() method (be careful)
            circuit = self.__quantum_program[name]
            dag_circuit, final_layout = openquantumcompiler.compile(circuit.qasm(),
                                                                    basis_gates=basis_gates,
                                                                    coupling_map=coupling_map,
                                                                    initial_layout=initial_layout,
                                                                    get_layout=True)
            # making the job to be added to qobj
            job = {}
            job["name"] = name
            # config parameters used by the runner
            if config is None:
                config = {}  # default to empty config dict
            job["config"] = copy.deepcopy(config)
            job["config"]["coupling_map"] = mapper.coupling_dict2list(coupling_map)
            # TODO: Jay: make config options optional for different backends
            # Map the layout to a format that can be json encoded
            list_layout = None
            if final_layout:
                list_layout = [[k, v] for k, v in final_layout.items()]
            job["config"]["layout"] = list_layout
            job["config"]["basis_gates"] = basis_gates
            if seed is None:
                job["config"]["seed"] = None
            else:
                job["config"]["seed"] = seed
            # the compiled circuit to be run saved as a dag
            job["compiled_circuit"] = openquantumcompiler.dag2json(dag_circuit,
                                                                   basis_gates=basis_gates)
            job["compiled_circuit_qasm"] = dag_circuit.qasm(qeflag=True)
            # add job to the qobj
            qobj["circuits"].append(job)
        return qobj

    def reconfig(self, qobj, backend=None, config=None, shots=None, max_credits=None, seed=None):
        """Change configuration parameters for a compile qobj. Only parameters which
        don't affect the circuit compilation can change, e.g., the coupling_map
        cannot be changed here!

        Notes:
            If the inputs are left as None then the qobj is not updated

        Args:
            qobj (dict): already compile qobj
            backend (str): see .compile
            config (dict): see .compile
            shots (int): see .compile
            max_credits (int): see .compile
            seed (int): see .compile

        Returns:
            qobj: updated qobj
        """
        if backend is not None:
            qobj['config']['backend'] = backend
        if shots is not None:
            qobj['config']['shots'] = shots
        if max_credits is not None:
            qobj['config']['max_credits'] = max_credits

        for circuits in qobj['circuits']:
            if seed is not None:
                circuits['seed'] = seed
            if config is not None:
                circuits['config'].update(config)

        return qobj

    def get_execution_list(self, qobj):
        """Print the compiled circuits that are ready to run.

        Note:
            This method is intended to be used during interactive sessions, and
            prints directly to stdout instead of using the logger.

        Returns:
            list(str): names of the circuits in `qobj`
        """
        if not qobj:
            print("no executions to run")
        execution_list = []

        print("id: %s" % qobj['id'])
        print("backend: %s" % qobj['config']['backend'])
        print("qobj config:")
        for key in qobj['config']:
            if key != 'backend':
                print(' ' + key + ': ' + str(qobj['config'][key]))
        for circuit in qobj['circuits']:
            execution_list.append(circuit["name"])
            print('  circuit name: ' + circuit["name"])
            print('  circuit config:')
            for key in circuit['config']:
                print('   ' + key + ': ' + str(circuit['config'][key]))
        return execution_list

    def get_compiled_configuration(self, qobj, name):
        """Get the compiled layout for the named circuit and backend.

        Args:
            name (str):  the circuit name
            qobj (dict): the qobj

        Returns:
            dict: the config of the circuit.

        Raises:
            QISKitError: if the circuit has no configurations
        """
        try:
            for index in range(len(qobj["circuits"])):
                if qobj["circuits"][index]['name'] == name:
                    return qobj["circuits"][index]["config"]
        except KeyError:
            raise QISKitError('No compiled configurations for circuit "{0}"'.format(name))

    def get_compiled_qasm(self, qobj, name):
        """Return the compiled cricuit in qasm format.

        Args:
            qobj (dict): the qobj
            name (str): name of the quantum circuit

        Returns:
            str: the QASM of the compiled circuit.

        Raises:
            QISKitError: if the circuit has no configurations
        """
        try:
            for index in range(len(qobj["circuits"])):
                if qobj["circuits"][index]['name'] == name:
                    return qobj["circuits"][index]["compiled_circuit_qasm"]
        except KeyError:
            raise QISKitError('No compiled qasm for circuit "{0}"'.format(name))

    ###############################################################
    # methods to run quantum programs
    ###############################################################

    def run(self, qobj, wait=5, timeout=60):
        """Run a program (a pre-compiled quantum program). This function will
        block until the Job is processed.

        The program to run is extracted from the qobj parameter.

        Args:
            qobj (dict): the dictionary of the quantum object to run.
            wait (int): Time interval to wait between requests for results
            timeout (int): Total time to wait until the execution stops

        Returns:
            Result: A Result (class).
        """
        self.callback = None
        self._run_internal([qobj],
                           wait=wait,
                           timeout=timeout)
        self.wait_for_results(timeout)
        return self.jobs_results[0]

    def run_batch(self, qobj_list, wait=5, timeout=120):
        """Run various programs (a list of pre-compiled quantum programs). This
        function will block until all programs are processed.

        The programs to run are extracted from qobj elements of the list.

        Args:
            qobj_list (list(dict)): The list of quantum objects to run.
            wait (int): Time interval to wait between requests for results
            timeout (int): Total time to wait until the execution stops

        Returns:
            list(Result): A list of Result (class). The list will contain one Result object
            per qobj in the input list.
        """
        self._run_internal(qobj_list,
                           wait=wait,
                           timeout=timeout,
                           are_multiple_results=True)
        self.wait_for_results(timeout)
        return self.jobs_results

    def run_async(self, qobj, wait=5, timeout=60, callback=None):
        """Run a program (a pre-compiled quantum program) asynchronously. This
        is a non-blocking function, so it will return inmediately.

        All input for run comes from qobj.

        Args:
            qobj(dict): the dictionary of the quantum object to
                run or list of qobj.
            wait (int): Time interval to wait between requests for results
            timeout (int): Total time to wait until the execution stops
            callback (fn(result)): A function with signature:
                    fn(result):
                    The result param will be a Result object.
        """
        self._run_internal([qobj],
                           wait=wait,
                           timeout=timeout,
                           callback=callback)

    def run_batch_async(self, qobj_list, wait=5, timeout=120, callback=None):
        """Run various programs (a list of pre-compiled quantum program)
        asynchronously. This is a non-blocking function, so it will return
        inmediately.

        All input for run comes from qobj.

        Args:
            qobj_list (list(dict)): The list of quantum objects to run.
            wait (int): Time interval to wait between requests for results
            timeout (int): Total time to wait until the execution stops
            callback (fn(results)): A function with signature:
                    fn(results):
                    The results param will be a list of Result objects, one
                    Result per qobj in the input list.
        """
        self._run_internal(qobj_list,
                           wait=wait,
                           timeout=timeout,
                           callback=callback,
                           are_multiple_results=True)

    def _run_internal(self, qobj_list, wait=5, timeout=60, callback=None,
                      are_multiple_results=False):

        self.callback = callback
        self.are_multiple_results = are_multiple_results

        q_job_list = []
        for qobj in qobj_list:
            q_job = QuantumJob(qobj, preformatted=True)
            q_job_list.append(q_job)

        job_processor = JobProcessor(q_job_list, max_workers=5,
                                     callback=self._jobs_done_callback)
        job_processor.submit()

    def _jobs_done_callback(self, jobs_results):
        """ This internal callback will be called once all Jobs submitted have
            finished. NOT every time a job has finished.

        Args:
            jobs_results (list): list of Result objects
        """
        if self.callback is None:
            # We are calling from blocking functions (run, run_batch...)
            self.jobs_results = jobs_results
            self.jobs_results_ready_event.set()
            return

        if self.are_multiple_results:
            self.callback(jobs_results)  # for run_batch_async() callback
        else:
            self.callback(jobs_results[0])  # for run_async() callback

    def wait_for_results(self, timeout):
        """Wait for all the results to be ready during an execution."""
        is_ok = self.jobs_results_ready_event.wait(timeout)
        self.jobs_results_ready_event.clear()
        if not is_ok:
            raise QISKitError('Error waiting for Job results: Timeout after {0} '
                              'seconds.'.format(timeout))

    def execute(self, name_of_circuits, backend="local_qasm_simulator",
                config=None, wait=5, timeout=60, basis_gates=None,
                coupling_map=None, initial_layout=None, shots=1024,
                max_credits=3, seed=None):

        """Execute, compile, and run an array of quantum circuits).

        This builds the internal "to execute" list which is list of quantum
        circuits to run on different backends.

        Args:
            name_of_circuits (list[str]): circuit names to be compiled.
            backend (str): a string representing the backend to compile to
            config (dict): a dictionary of configurations parameters for the
                compiler
            wait (int): Time interval to wait between requests for results
            timeout (int): Total time to wait until the execution stops
            basis_gates (str): a comma seperated string and are the base gates,
                               which by default are: u1,u2,u3,cx,id
            coupling_map (dict): A directed graph of coupling::

                                {
                                control(int):
                                    [
                                        target1(int),
                                        target2(int),
                                        , ...
                                    ],
                                    ...
                                }
                                eg. {0: [2], 1: [2], 3: [2]}
            initial_layout (dict): A mapping of qubit to qubit
                                  {
                                  ("q", strart(int)): ("q", final(int)),
                                  ...
                                  }
                                  eg.
                                  {
                                  ("q", 0): ("q", 0),
                                  ("q", 1): ("q", 1),
                                  ("q", 2): ("q", 2),
                                  ("q", 3): ("q", 3)
                                  }
            shots (int): the number of shots
            max_credits (int): the max credits to use 3, or 5
            seed (int): the intial seed the simulatros use

        Returns:
            Result: status done and populates the internal __quantum_program with the
            data
        """
        # TODO: Jay: currently basis_gates, coupling_map, intial_layout, shots,
        # max_credits, and seed are extra inputs but I would like them to go
        # into the config
        qobj = self.compile(name_of_circuits, backend=backend, config=config,
                            basis_gates=basis_gates,
                            coupling_map=coupling_map, initial_layout=initial_layout,
                            shots=shots, max_credits=max_credits, seed=seed)
        result = self.run(qobj, wait=wait, timeout=timeout)
        return result