Advanced Usage¶
Running with Jupyter Notebook¶
The Classiq SDK automatically identifies whether it runs in Jupyter Notebook, and adjusts accordingly. However, if Classiq does not identify Jupyter, you can execute this code snippet:
import classiq
classiq.enable_jupyter_notebook()
Configuration¶
There are multiple ways to configure the SDK.
- Configuration file: A file with .ini or .yaml style syntax. For example:
Multiple locations are checked1 according to the following order:
classiq-host: "https://myclassiqbackend.com"
/etc/classiq/config.ini
/etc/classiq.conf
~/.config/classiq/config.ini
~/.config/classiq.conf
classiq/config.ini
- Command line argument
- Environment variables
-
Dynamic configuration: You can configure the SDK within the Python script. Create a
Configuration
object (defined inclassiq.config
) and pass it on as an argument to the functionclassiq.configure
, as in the example below.import classiq conf = classiq.Configuration(host="https://myclassiqbackend.com") classiq.configure(conf=conf)
These configuration options are supported:
- classiq-host - This flag determines the backend host URL. By default, the SDK works against the Classiq public domain, but you might want to reconfigure it to work against a different URL.
- classiq-config-file - This flag determines the configuration file used by the SDK.
By default, the SDK looks for a configuration file under
/classiq/config.ini
, but you can configure a different path using either command line arguments or environment variables. - classiq-skip-check-host - This flag disables the validation of the SDK version. By default, the SDK checks that it is compatible with the backend version when the connection between them is established. If this flag is present, this check is suppressed.
Concurrent Programming¶
All the Python SDK functions have both synchronous (sync) and asynchronous (async) versions.
The async versions are named function_async
.
For example, model.synthesize
is the sync version, and model.synthesize_async
is the async version.
Synchronous functions work like typical Python functions, and block the execution until they finish. Asynchronous functions can be executed concurrently for increased efficiency. Refer to Python docs - asyncio.
Example¶
This example generates and executes multiple circuits concurrently, cutting execution time by half:
- Synchronous code executes the second circuit only after the first one finishes.
- Asynchronous code runs them in parallel.
import asyncio
from classiq import Model, RegisterUserInput, Executor
from classiq.builtin_functions import ArithmeticOracle, GroverOperator
from classiq.execution import (
ExecutionPreferences,
AmplitudeAmplification,
)
async def execute_circuit(expression, preferences):
print(f"Setting up circuit: {expression=}")
oracle_params = ArithmeticOracle(
expression=expression,
definitions=dict(
a=RegisterUserInput(size=4),
b=RegisterUserInput(size=4, is_signed=True),
),
uncomputation_method="optimized",
qubit_count=25,
)
grover_params = GroverOperator(oracle_params=oracle_params)
model = Model()
model.GroverOperator(grover_params)
circuit = await model.synthesize_async()
print(f"Circuit generation complete! {expression=}")
result = await Executor(preferences=preferences).execute_async(circuit)
print(f"Circuit execution done! {expression=}")
print(f"\tResult: {result.result}")
async def main():
expressions = [
"a + b == 7 and a & b == 8",
"a + b == 5 and a & b == 2",
]
preferences = ExecutionPreferences(
amplitude_amplification=AmplitudeAmplification(
growth_rate=2, sample_from_iterations=False
)
)
all_circuit_executors = await asyncio.gather(
*[execute_circuit(expression, preferences) for expression in expressions]
)
print("Done!")
asyncio.run(main())
Possible output:
Setting up circuit: expression='a + b == 7 and a & b == 8'
Setting up circuit: expression='a + b == 5 and a & b == 2'
Circuit generation complete! expression='a + b == 7 and a & b == 8'
Circuit generation complete! expression='a + b == 5 and a & b == 2'
Circuit execution done! expression='a + b == 7 and a & b == 8'
Result: {'a': 14.0, 'b': -7.0}
Circuit execution done! expression='a + b == 5 and a & b == 2'
Result: {'a': 2.0, 'b': 3.0}
Done!
-
The
/etc
folder is commonly used for system-wide configuration,~/.config
is for user-wide configuration, andclassiq/config.ini
is relative to the current working directory. ↩