diff --git a/nersc/single_circuits/LK_CPU-vs-GPU.png b/nersc/single_circuits/LK_CPU-vs-GPU.png new file mode 100644 index 0000000..a7aa469 Binary files /dev/null and b/nersc/single_circuits/LK_CPU-vs-GPU.png differ diff --git a/nersc/single_circuits/LK_qjit-compile.png b/nersc/single_circuits/LK_qjit-compile.png new file mode 100644 index 0000000..0ae2f44 Binary files /dev/null and b/nersc/single_circuits/LK_qjit-compile.png differ diff --git a/nersc/single_circuits/LK_qjit-vs-base.png b/nersc/single_circuits/LK_qjit-vs-base.png new file mode 100644 index 0000000..505b6d5 Binary files /dev/null and b/nersc/single_circuits/LK_qjit-vs-base.png differ diff --git a/nersc/single_circuits/README.md b/nersc/single_circuits/README.md new file mode 100644 index 0000000..3fed3fa --- /dev/null +++ b/nersc/single_circuits/README.md @@ -0,0 +1,286 @@ + +# Benchmarking quantum circuits + + +## Run with Python `venv` + +### `lightning-kokkos` from pypi wheels + +Python venv with pypi wheels +``` +cd /global/common/software/m4693/ + +module load python +mkdir -p venv +python -m venv venv/qml_LK +source venv/qml_LK/bin/activate + +cd /global/cfs/cdirs/m4693/qml-benchmarks-devel +pip install -e . # --user + +pip install ray # for other experiments + +pip install pennylane-lightning +pip install pennylane-lightning[kokkos] + +pip install pennylane-catalyst +``` + +Start interactive job on CPU node for testing +``` bash +salloc -q interactive -C cpu -t 0:30:00 -A m4693 + +# and execute in this interactive session: + +source /global/common/software/m4693/venv/qml_LK/bin/activate +cd nersc/ + +# to restrict the number of threads: +export OMP_NUM_THREADS=32 +python3 single_circuits/demo_variational.py -q lightning.qubit -n 15,20 -r +``` + +Stats on interactive CPU node (nid004079) +``` +> Weights as native numpy arrays +lightning.qubit + 15 - 0.1 s + 20 - 3.3 s + 21 - 7 s + 22 - 16 s + 23 - 35 s +lightning.kokkos + 23 - 1 s + 25 - 5 s (7 s with 32 threads) + 26 - 34 s + +> Benchmarking numpy/qml.numpy, gradients with "adjoint" +> no-grad: qml.np.array(requires_grad=True) but no jacobian requested +lightning.qubit + numpy qml.np qml.np qjit qjit qjit + no-grad grad comp no-grad grad + 15 - 0.14 0.16 1.3 10.4 0.1 error + 16 - 0.24 0.25 2.0 11.6 0.2 + 17 - 0.44 0.42 3.7 12.8 0.3 + 20 - 3.75 3.74 32.6 19.8 3.4 +> NotImplementedError: Converting dtype('O') to a ctypes type +lightning.kokkos (with 32 threads) + numpy qml.np qml.np qjit qjit qjit + no-grad grad comp no-grad grad + 15 - 0.1 0.1 0.7 10.3 0.0 + 20 - 0.3 0.3 2.4 16.6 0.3 + 23 - 1.4 1.4 15.1 21.5 1.3 + 25 - 6.9 6.9 101.1 30.7 7.3 + +> Benchmarking numpy/qml.numpy, gradients with "finite-diff" +lightning.qubit + numpy qml.np qml.np qjit qjit qjit + no-grad grad comp no-grad grad + 15 - 0.1 0.2 - 9.9 0.0 42.3 + 16 - 0.1 0.3 - 11.1 0.1 87.7 + 17 - 0.3 0.4 - 12.3 0.2 + 20 - 2.6 3.0 - 18.2 2.5 + +lightning.kokkos (with 32 threads) + numpy qml.np qml.np qjit qjit qjit + no-grad grad comp no-grad grad + 15 - 0.1 0.1 - 10.1 0.0 27.3 + 20 - 0.2 0.3 - 16.1 0.3 189.4 + 23 - 1.3 1.5 - 21.3 1.4 - + 25 - 6.5 6.6 - 30.4 7.6 - +``` + +### `lightning-kokkos` from source with CUDA + +lightning-kokkos with GPU +- https://pypi.org/project/PennyLane-Lightning-Kokkos/ +- https://docs.pennylane.ai/projects/lightning/en/stable/lightning_kokkos/installation.html +- https://github.com/PennyLaneAI/lightning-on-hpc/blob/main/DataCollection/distributed/LUMI_LKOKKOS_VQE/README.md- + +``` bash +cd /global/common/software/m4693/ + +module load cudatoolkit + +module load python +mkdir -p venv +python -m venv venv/qml_LK_GPU +source venv/qml_LK_GPU/bin/activate + +python -m pip install pip==22.0 + +git clone https://github.com/PennyLaneAI/pennylane-lightning.git +cd pennylane-lightning + +git checkout v0.36.0 + +pip install -r requirements.txt +pip install ray + +# pip install pennylane-catalyst # [added later] + +# install lightning-qubit as prerequisite +CXX=$(which CC) python -m pip install -e . --verbose + +CXX=$(which CC) CMAKE_ARGS="-DKokkos_ENABLE_OPENMP=ON -DKokkos_ENABLE_CUDA=ON -DKokkos_ARCH_AMPERE80:BOOL=ON -DCMAKE_CXX_COMPILER=$(which CC)" PL_BACKEND="lightning_kokkos" python -m pip install . --verbose +``` + +Start interactive job on GPU node for testing +``` bash +salloc -q interactive -C gpu -t 0:30:00 -A m4693 + +# and execute in this interactive session: + +source /global/common/software/m4693/venv/qml_LK_GPU/bin/activate +cd nersc/ + +# to restrict the number of threads: +#export OMP_NUM_THREADS=1 + +python3 single_circuits/demo_variational.py -q lightning.kokkos -n 20,25 -r +``` + +Stats on interactive GPU node (nid200381) +``` +lightning.kokkos + 23 - s + 25 - 3 s + 26 - 6 s + 27 - 12 s + 28 - 25 s + +> Benchmarking numpy/qml.numpy, gradients +> no-grad: qml.np.array(requires_grad=True) but no jacobian requested +lightning.kokkos + numpy qml.np jacobian qjit qjit qjit + no-grad grad comp no-grad grad + 22 - s 2 s 5 s 20 s 1 s + 23 - s 4 s 9 s + 25 - 3 s 18 s 37 s 50 s 24 s + 26 - 6 s + 27 - 12 s + 28 - 25 s +> Kokkos::Cuda ERROR: Failed to call Kokkos::Cuda::finalize() + +> Benchmarking numpy/qml.numpy, gradients with "finite-diff" +lightning.kokkos + numpy qml.np qml.np qjit qjit qjit + no-grad grad comp no-grad grad + 15 - 10.3 0.1 52.7 + 20 - 16.5 0.4 + 22 - 0.3 0.5 - 20.4 1.1 + 23 - 0.6 0.8 - 22.9 2.8 + 25 - 2.6 2.9 - 49.1 24.0 + 26 - 5.6 5.8 - + +``` + +Run batch of circuits in parallel +``` bash +# @ray.remote(num_gpus=0.5) has same runtime than num_gpus=1 +time python3 single_circuits/batch_variational.py -n 26 -s 4 + +# move task to background and monitor GPU usage +nvidia-smi +``` + +Stats on 1 interactive GPU node +``` +ray_init in 7 to 15 s +> How long does 1 circuit run on its GPU? +25 features + samples run_time run_time/sample*gpu + - 3 + 16 32 8 +26 features + samples run_time run_time/sample*gpu + - 6 + 4 10 10 + 8 23 11 + 16 39 10 + 32 77 10 +> create dev 1.8 s +> create circuit < 1 ms +27 features + samples run_time run_time/sample*gpu + - 12 + 4 16 16 + 8 31 15 +> Overhead of 4 s per circuit with Ray +> This includes creating dev + circuit + +30 features + samples run_time run_time/sample*gpu + - n.a. + 4 120 120 +> create dev 3.3 s +> create circuit < 1 ms + +> Run r circuits sequentially within 1 ray job: +batch_variational.py -n 26 -s 32 -r 8 + total: 48.949 s + per_circuit: 6.119 s +> per circuit runtime is equivalent to run w/o ray +``` + +## Run in `podman` containers + +Prerequisite: Make sure to have datasets available in `single_circuits/linearly_separable`. + +Start interactive job on CPU node for testing +``` bash +salloc -q interactive -C cpu -t 0:30:00 -A m4693 + +# and execute in this interactive session: + +IMG=tgermain/ubu22-pennylane-ray + +# For preliminary testing whether image is available on node: +CFSH=/global/cfs/cdirs/m4693 # CFS home +REPO_DIR=$CFSH/qml-benchmarks-devel # qml-benchmark repo +ROOT_DIR=$REPO_DIR/nersc/root # to access local python packages +WORK_DIR=$REPO_DIR/nersc # to store output files +# Mount /tmp to avoid following error with Ray: +# ValueError: Can't find a `node_ip_address.json` file + +podman-hpc run -it \ + --net host \ + --volume /tmp:/tmp \ + --volume $ROOT_DIR:/root \ + --volume $REPO_DIR:/qml-benchmarks \ + --volume $WORK_DIR:/work_dir \ + --workdir /work_dir \ + -e HDF5_USE_FILE_LOCKING='FALSE' \ + --shm-size=10.24gb \ + $IMG bash + +# Then execute in container, in `work_dir/`: + +python3 single_circuits/circuit_variational.py --model IQPVariationalClassifier --numFeatures 21 --inputPath single_circuits/linearly_separable/ + +python3 single_circuits/demo_variational.py + +# exit container + +# Run container interactively with wrapper +./wrap_podman.sh $IMG "python3 single_circuits/demo_variational.py" +``` + +## Plot benchmarks + +``` +cd /global/common/software/m4693/ + +module load python +mkdir -p venv + +python -m venv venv/qml_plot +source venv/qml_plot/bin/activate + +pip install matplotlib pandas +``` + +``` +source /global/common/software/m4693/venv/qml_plot/bin/activate + +``` \ No newline at end of file diff --git a/nersc/single_circuits/batch_variational.py b/nersc/single_circuits/batch_variational.py new file mode 100644 index 0000000..d06d7a4 --- /dev/null +++ b/nersc/single_circuits/batch_variational.py @@ -0,0 +1,165 @@ + +''' +https://docs.ray.io/en/latest/ray-core/tasks.html#ray-remote-functions +https://docs.ray.io/en/latest/ray-core/patterns/limit-running-tasks.html +''' + +import argparse +import time + +import numpy as np +import ray + +import pennylane as qml + +# TODO: fix hanging run with qml.np +#from pennylane import numpy as np + +from datetime import datetime + +def get_parser(): + parser = argparse.ArgumentParser() + parser.add_argument('-n', '--numFeatures', type=int, default=15, help="dataset dimension ") + parser.add_argument('-s', '--numSamples', type=int, default=4, help="number of sample circuits (in one batch)") + parser.add_argument('-r', '--numRuns', type=int, default=1, help="number of circuit run sequentially within one ray job") + parser.add_argument('-d', '--dryRun', action='store_true', help="print specs only, no circuit execution") + args = parser.parse_args() + return args + +args = get_parser() + +def print_elapsed(name, t1, t2): + print("%s: %.3 s" % (name, (t2 - t1).total_seconds())) + +def print_per_circuit(name, t1, t2, n_circuits, n_gpus=4): + seconds = (t2 - t1).total_seconds() / n_circuits * n_gpus + print("%s: %.3f s" % (name, seconds)) + +# Model parameters available in config originate from circuit_variational.py. +catalog = { + 15: {'n_features': 15, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (15,), 'num_wires': 15, 'num_gates': 1800, 'depth': 267}, + 20: {'n_features': 20, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (20,), 'num_wires': 20, 'num_gates': 2900, 'depth': 310}, + 21: {'n_features': 21, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (21,), 'num_wires': 21, 'num_gates': 3150, 'depth': 321}, + 22: {'n_features': 22, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (22,), 'num_wires': 22, 'num_gates': 3410, 'depth': 333}, + 23: {'n_features': 23, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (23,), 'num_wires': 23, 'num_gates': 3680, 'depth': 346}, + 24: {'n_features': 24, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (24,), 'num_wires': 24, 'num_gates': 3960, 'depth': 358}, + 25: {'n_features': 25, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (25,), 'num_wires': 25, 'num_gates': 4250, 'depth': 371}, + 26: {'n_features': 26, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (26,), 'num_wires': 26, 'num_gates': 4550, 'depth': 383}, + 27: {'n_features': 27, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (27,), 'num_wires': 27, 'num_gates': 4860, 'depth': 396}, + 28: {'n_features': 28, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (28,), 'num_wires': 28, 'num_gates': 5180, 'depth': 409}, + 29: {'n_features': 29, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (29,), 'num_wires': 29, 'num_gates': 5510, 'depth': 423}, + 30: {'n_features': 30, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (30,), 'num_wires': 30, 'num_gates': 5850, 'depth': 435}, +} + +config = dict(catalog[args.numFeatures]) + +config['device'] = 'lightning.kokkos' +config['n_samples'] = args.numSamples +config['n_circ_per_job'] = args.numRuns + +n_features = config['n_features'] +n_layers = config['n_layers'] +n_repeats = config['n_repeats'] + +class VariationalModel: + + def __init__(self, n_features, n_layers, n_repeats, x): + self.n_qubits_ = n_features + self.n_layers = n_layers + self.repeats = n_repeats + self.params_ = None + + self.initialize_params() + + def initialize_params(self): + weights = 2 * np.pi * np.random.uniform(size=(self.n_layers, self.n_qubits_, 3)) + weights = np.array(weights) # requires_grad=True # + + self.params_ = {"weights": weights} + + def create_circuit(self, dev, x): + + @qml.qnode(dev) # diff_method="adjoint" # + def circuit(params, x): + """ + The variational circuit from the plots. Uses an IQP data embedding. + We use the same observable as in the plots. + """ + qml.IQPEmbedding(x, wires=range(self.n_qubits_), n_repeats=self.repeats) + qml.StronglyEntanglingLayers( + params["weights"], wires=range(self.n_qubits_), imprimitive=qml.CZ + ) + return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)) + + return circuit + +train_shape = (config['sample_shape'][0], config['n_samples']) + +X = np.random.rand(*train_shape) +x = X[:, 0] + +model = VariationalModel(n_features, n_layers, n_repeats, x) + +if args.dryRun: + print('inspecting circuit()') + dev = qml.device(config['device'], wires=n_features) + circuit = model.create_circuit(dev, x) + specs = qml.specs(circuit, expansion_strategy='device')( + model.params_, x[np.newaxis, :]) + print({ + 'n_features': n_features, + 'n_layers': model.n_layers, + 'n_repeats': model.repeats, + 'n_params': len(model.params_), + 'sample_shape': X.shape, + 'device_name': specs['device_name'], + 'gradient_fn': specs['gradient_fn'], + 'num_wires': specs['resources'].num_wires, + 'num_gates': specs['resources'].num_gates, + 'depth': specs['resources'].depth, + }) + exit(0) + +@ray.remote(num_gpus=1) +def exec_circuit(model, x, n_circuits): + # device creation must be in remote function, + # because Lightning is not pickable + t_start = datetime.now() + dev = qml.device(config['device'], wires=n_features) + t_end = datetime.now() + print_elapsed('create_dev', t_start, t_end) + t_start = datetime.now() + circuit = model.create_circuit(dev, x[:, 0]) + t_end = datetime.now() + print_elapsed('create_circuit', t_start, t_end) + + for i in range(n_circuits): + expval = circuit(model.params_, x[:, i]) + # TODO: activate gradients + #grads = qml.jacobian(circuit)(model.params_, x) + + return expval + +print('ray init()') +t_start = datetime.now() +ray.init() +t_end = datetime.now() +print_elapsed('ray_init', t_start, t_end) + +print('running circuit()') +t_start = datetime.now() + +n_cpj = config['n_circ_per_job'] +n_jobs = config['n_samples'] // n_cpj +print('n_jobs:', n_jobs) +result_refs = [] +for i in range(n_jobs): + result_refs.append( + exec_circuit.remote(model, X[:, i * n_cpj: (i + 1) * n_cpj], n_cpj)) + +res = ray.get(result_refs) + +t_end = datetime.now() +#print(res) +print_elapsed('total', t_start, t_end) +print_per_circuit('per_circuit', t_start, t_end, config['n_samples']) diff --git a/nersc/single_circuits/circuit_variational.py b/nersc/single_circuits/circuit_variational.py new file mode 100644 index 0000000..39711e4 --- /dev/null +++ b/nersc/single_circuits/circuit_variational.py @@ -0,0 +1,183 @@ + +from datetime import datetime + +import argparse +import csv +import os +import subprocess +import time +import yaml + +from pprint import pprint + +import jax +import jax.numpy as jnp +import numpy as np + +import pennylane as qml + +import qml_benchmarks + +from qml_benchmarks.hyperparam_search_utils import read_data + +def get_parser(): + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2, 3, 4], help="increase output verbosity", + default=1, dest='verb') + parser.add_argument("--inputPath", default='linearly_separable/', help='input data location') + parser.add_argument('-n', '--numFeatures', type=int, default=2, help="dataset dimension ") + parser.add_argument('-m', '--model', help="model: IQPVariationalClassifier, QuantumMetricLearner") + parser.add_argument('-d', '--dryRun', action='store_true', help="print specs only, no circuit execution") + + args = parser.parse_args() + + print('myArg-program:', parser.prog) + for arg in vars(args): print('myArg:', arg, getattr(args, arg)) + + # assert os.path.exists(args.outPath) + return args + + +# ================================= +# ================================= +# M A I N +# ================================= +# ================================= +if __name__ == "__main__": + args = get_parser() + + #define model + if args.model == 'QuantumMetricLearner': + from qml_benchmarks.models.quantum_metric_learning import QuantumMetricLearner as Model + elif args.model == 'IQPVariationalClassifier': + from qml_benchmarks.models.iqp_variational import IQPVariationalClassifier as Model + else: + raise ValueError('unknown model %s' % args.model) + + #implementation attributes of model + use_jax = True + vmap = True + jit = True + max_steps = 100 #the number of gradient descent steps to use to estimate the step time + model_settings = {'use_jax': use_jax, 'vmap': vmap, 'jit': jit, 'max_steps': max_steps} + + perf_ind_name = 'JAX' #a name for the performance indicator used for naming files + n_trials = 1 #number of trials to average over + n_test = -1 #number of test set points. For full test set use n_test = -1 + ################################# + + n_features = args.numFeatures # dataset dimension + model_name = Model().__class__.__name__ + + # get the 'worst case' hyperparameter settings for the model (those that require the most resources) + with open('performance_indicators/hyperparam_settings.yaml', "r") as file: + hp_settings = yaml.safe_load(file) + + hyperparams = {**hp_settings[model_name], **model_settings} + print(hyperparams) + + hyperparams['dev_type'] = 'lightning.qubit' + + assert os.path.exists(args.inputPath) + # inpF1=f'../../paper/benchmarks/linearly_separable/linearly_separable_{n_features}d_train.csv' + inpF1 = os.path.join(args.inputPath, 'linearly_separable_%dd_train.csv' % (n_features)) + inpF2 = inpF1.replace('train', 'test') + print('M:inpF1', inpF1) + X_train, y_train = read_data(inpF1) + print('M:inpF2', inpF2) + X_test, y_test = read_data(inpF2) + + if n_test != -1: + X_test = X_test[:n_test] + y_test = y_test[:n_test] + + first_train_steps = [] + av_consec_train_steps = [] + predict_times = [] + + model = Model(**hyperparams) + + def init_circuit(X, y): + # Derived from: `model.fit(X_train, y_train)` + model.initialize(n_features=X.shape[1], classes=np.unique(y)) + return model.circuit + + circuit = init_circuit(X_train, y_train) + + ''' + def initialize_params(self): + weights = 2 * np.pi * np.random.uniform(size=(self.n_layers, self.n_qubits_, 3)) + weights = jnp.array(weights) + + self.params_ = {"weights": weights} + + params = model.params_ + x = X_batch + + @qml.qnode(dev, **self.qnode_kwargs) + def circuit(params, x): + """ + The variational circuit from the plots. Uses an IQP data embedding. + We use the same observable as in the plots. + """ + qml.IQPEmbedding(x, wires=range(self.n_qubits_), n_repeats=self.repeats) + qml.StronglyEntanglingLayers( + params["weights"], wires=range(self.n_qubits_), imprimitive=qml.CZ + ) + return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)) + ''' + + X = X_train[0] + y = y_train[0] + + def print_elapsed(t1, t2): + print("%.6f s" % ((t2 - t1).total_seconds())) + + specs = qml.specs(circuit, expansion_strategy='device')(model.params_, X) + #pprint(specs) + print({ + 'n_features': args.numFeatures, + 'n_layers': model.n_layers, + 'n_repeats': model.repeats, + 'n_params': len(model.params_), + 'sample_shape': X.shape, + 'device_name': specs['device_name'], + 'gradient_fn': specs['gradient_fn'], + 'num_wires': specs['resources'].num_wires, + 'num_gates': specs['resources'].num_gates, + 'depth': specs['resources'].depth, + }) + + if args.dryRun: + exit(0) + + print('M:executing circuit') + t_start = datetime.now() + + for trial in range(n_trials): + jax.clear_caches() + + expval = circuit(model.params_, X) + grads = qml.jacobian(circuit)(model.params_, X) + + t_end = datetime.now() + print_elapsed(t_start, t_end) + + # {'n_features': 15, 'n_layers': 15, 'n_params': 1, 'sample_shape': (15,)} + + # {'num_features': 15, 'num_wires': 15, 'num_gates': 1800, 'depth': 267} + # {'num_features': 20, 'num_wires': 20, 'num_gates': 2900, 'depth': 310} + # {'num_features': 21, 'num_wires': 21, 'num_gates': 3150, 'depth': 321} + # {'num_features': 22, 'num_wires': 22, 'num_gates': 3410, 'depth': 333} + + # default.qubit + # 15d - 10 s + # 20d - 45 s + + # lightning.qubit + # 15d - 0.4 s + # 20d - 5 s + # 21d - 10 s + # 22d - 22 s + + print('M:done') diff --git a/nersc/single_circuits/demo_variational.py b/nersc/single_circuits/demo_variational.py new file mode 100644 index 0000000..157009e --- /dev/null +++ b/nersc/single_circuits/demo_variational.py @@ -0,0 +1,205 @@ + +''' +Demo of IQPVariationalClassifier using qml.IQPEmbedding and qml.StronglyEntanglingLayers. +''' + +import argparse +import os +import subprocess + +import pennylane as qml +import catalyst + +from datetime import datetime + +def get_parser(): + parser = argparse.ArgumentParser() + parser.add_argument('-n', '--numFeatures', type=str, default='15', help="dataset dimension(s) (comma separated list)") + parser.add_argument('-q', '--device', default='lightning.qubit', help="quantum device e.g. lightning.qubit") + parser.add_argument('-g', '--gradients', action='store_true', help="request gradients wrt. all weights") + parser.add_argument('-j', '--jit', action='store_true', help="JIT with Catalyst") + parser.add_argument('--numpy', action='store_true', help="use numpy instead of pennylane.numpy") + parser.add_argument('-d', '--dryRun', action='store_true', help="print specs only, no circuit execution") + parser.add_argument('-r', '--report', action='store_true', help="print for report") + args = parser.parse_args() + return args + +args = get_parser() + +def print_elapsed(prefix, t1, t2): + print("%s%6.1f s" % (prefix, (t2 - t1).total_seconds())) + +# Model parameters available in config originate from circuit_variational.py. +catalog = { + 10: {'n_features': 10, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (10,), 'num_wires': 10, 'num_gates': 950, 'depth': 198}, + 15: {'n_features': 15, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (15,), 'num_wires': 15, 'num_gates': 1800, 'depth': 267}, + 16: {'n_features': 16, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (16,), 'num_wires': 16, 'num_gates': 2000, 'depth': 281}, + 17: {'n_features': 17, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (17,), 'num_wires': 17, 'num_gates': 2210, 'depth': 282}, + 18: {'n_features': 18, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (18,), 'num_wires': 18, 'num_gates': 2430, 'depth': 289}, + 19: {'n_features': 19, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (19,), 'num_wires': 19, 'num_gates': 2660, 'depth': 299}, + 20: {'n_features': 20, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (20,), 'num_wires': 20, 'num_gates': 2900, 'depth': 310}, + 21: {'n_features': 21, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (21,), 'num_wires': 21, 'num_gates': 3150, 'depth': 321}, + 22: {'n_features': 22, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (22,), 'num_wires': 22, 'num_gates': 3410, 'depth': 333}, + 23: {'n_features': 23, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (23,), 'num_wires': 23, 'num_gates': 3680, 'depth': 346}, + 24: {'n_features': 24, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (24,), 'num_wires': 24, 'num_gates': 3960, 'depth': 358}, + 25: {'n_features': 25, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (25,), 'num_wires': 25, 'num_gates': 4250, 'depth': 371}, + 26: {'n_features': 26, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (26,), 'num_wires': 26, 'num_gates': 4550, 'depth': 383}, + 27: {'n_features': 27, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (27,), 'num_wires': 27, 'num_gates': 4860, 'depth': 396}, + 28: {'n_features': 28, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (28,), 'num_wires': 28, 'num_gates': 5180, 'depth': 409}, + 29: {'n_features': 29, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (29,), 'num_wires': 29, 'num_gates': 5510, 'depth': 423}, + 30: {'n_features': 30, 'n_layers': 15, 'n_repeats': 10, 'n_params': 1, 'sample_shape': (30,), 'num_wires': 30, 'num_gates': 5850, 'depth': 435}, +} + +if args.numpy: + import numpy as np +else: + from pennylane import numpy as np # + from jax import numpy as jnp # + +if args.jit: + qjit = catalyst.qjit +else: + def qjit(func): + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + return wrapper + +class VariationalModel: + + def __init__(self, dev, n_features, n_layers, n_repeats, x): + self.dev = dev + self.n_qubits_ = n_features + self.n_layers = n_layers + self.repeats = n_repeats + self.params_ = None + + self.initialize_params() + self.create_circuit(x) + + def initialize_params(self): + weights = 2 * np.pi * np.random.uniform(size=(self.n_layers, self.n_qubits_, 3)) + if args.numpy: + weights = np.array(weights) + else: + if args.jit: + weights = jnp.array(weights) # + else: + weights = np.array(weights, requires_grad=True) # + self.params_ = {"weights": weights} + + def create_circuit(self, x): + + @qjit + @qml.qnode(self.dev, grad_on_execution=False) # + def circuit(weights, x): + """ + The variational circuit from the plots. Uses an IQP data embedding. + We use the same observable as in the plots. + """ + qml.IQPEmbedding(x, wires=range(self.n_qubits_), n_repeats=self.repeats) + qml.StronglyEntanglingLayers( + weights, wires=range(self.n_qubits_), imprimitive=qml.CZ + ) + return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)) + + self.circuit = circuit + + +def benchmark(numFeatures): + + config = dict(catalog[numFeatures]) + + config['device'] = args.device + if not args.report: + print('device:', args.device) + + n_features = config['n_features'] + n_layers = config['n_layers'] + n_repeats = config['n_repeats'] + + dev = qml.device(config['device'], wires=n_features) + + X = np.random.rand(*config['sample_shape']) + + model = VariationalModel(dev, n_features, n_layers, n_repeats, X) + circuit = model.circuit + + if args.dryRun: + print('inspecting circuit()') + specs = qml.specs(circuit, expansion_strategy='device')(model.params_, X) + print({ + 'n_features': n_features, + 'n_layers': model.n_layers, + 'n_repeats': model.repeats, + 'n_params': model.params_["weights"].size, + 'sample_shape': X.shape, + 'device_name': specs['device_name'], + 'gradient_fn': specs['gradient_fn'], + 'num_wires': specs['resources'].num_wires, + 'num_gates': specs['resources'].num_gates, + 'depth': specs['resources'].depth, + }) + exit(0) + + if not args.report: + print('running circuit()') + + weights = model.params_["weights"] + + if args.gradients: + if args.jit: + @qml.qjit + def run_grad(weights, x): + grads = catalyst.grad(circuit, method="fd")(weights, x) + return grads + else: + raise NotImplementedError('gradients w/o qjit') + + if args.jit: + # First run. Includes compilation if JIT. + t_start = datetime.now() + expval = circuit(weights, X) + t_end = datetime.now() + #print_elapsed('%2d ' % n_features, t_start, t_end) + first_time = (t_end - t_start).total_seconds() + else: + first_time = 0.0 + + #factor = 1.01 + #X_2 = X * factor + #params_2 = {"weights": model.params_["weights"] * factor} + + t_start = datetime.now() + expval = circuit(weights, X) + if args.gradients: + grads = run_grad(weights, X) + t_end = datetime.now() + #print_elapsed('%2d ' % n_features, t_start, t_end) + second_time = (t_end - t_start).total_seconds() + + #print(expval) + + return_code = subprocess.call( + "nvidia-smi", shell=True, + stdout=subprocess.DEVNULL, + stderr=subprocess.STDOUT) + + n_threads = os.getenv('OMP_NUM_THREADS', '0') + + tokens = [ + args.device, + 'GPU' if return_code == 0 else 'CPU', + n_threads, + 'grad' if args.gradients else '-', + 'qjit' if args.jit else '-', + 'np' if args.numpy else '-', + '%d' % n_features, + '%.3f' % first_time, + '%.3f' % second_time, + ] + + print(','.join(tokens)) + + +for numFeatures in args.numFeatures.split(','): + benchmark(int(numFeatures)) diff --git a/nersc/single_circuits/demo_variational.sh b/nersc/single_circuits/demo_variational.sh new file mode 100644 index 0000000..707b4ff --- /dev/null +++ b/nersc/single_circuits/demo_variational.sh @@ -0,0 +1,8 @@ +#!/bin/bash -e + +#for NQ in 15 16 17 20; do # lightning.qubit +#for NQ in 15 20 23 25; do # lightning.kokkos CPU +for NQ in 15 20 22 23 25 26; do # lightning.kokkos GPU + #echo $NQ + python3 demo_variational.py -n $NQ -r $* 2>/dev/null +done diff --git a/nersc/single_circuits/minimal_variational.py b/nersc/single_circuits/minimal_variational.py new file mode 100644 index 0000000..6d32fa0 --- /dev/null +++ b/nersc/single_circuits/minimal_variational.py @@ -0,0 +1,36 @@ + +import functools + +import numpy as np +from jax import numpy as jnp + +import pennylane as qml +import catalyst + +from catalyst import qjit + +n_qubits_ = 4 + +x = np.random.rand(n_qubits_) + +#shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=n_qubits_) +shape = (2, 4, 3) +params = jnp.array(np.random.random(size=shape)) + +dev = qml.device("lightning.qubit", wires=n_qubits_) + +@qjit +def run_circuit(params, x): + + @qml.qnode(dev) # diff_method="adjoint" | "finite-diff" | "backprop" + #@functools.partial(qml.devices.preprocess.decompose, stopping_condition = lambda obj: obj.name not in ['Rot', 'StronglyEntanglingLayers'], max_expansion=3) + def circuit(params, x): + qml.IQPEmbedding(x, wires=range(n_qubits_), n_repeats=2) + qml.StronglyEntanglingLayers( + params, wires=range(n_qubits_), imprimitive=qml.CZ + ) + return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)) + + catalyst.grad(circuit, method="fd")(params, x) # method="fd" + +run_circuit(params, x) diff --git a/nersc/single_circuits/plot_variational.ipynb b/nersc/single_circuits/plot_variational.ipynb new file mode 100644 index 0000000..0d814dc --- /dev/null +++ b/nersc/single_circuits/plot_variational.ipynb @@ -0,0 +1,173 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "45198aed-7b98-44e7-b7eb-f0769de20953", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1e7c6c27-08e6-49b8-9251-39fda429ce0a", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.read_csv('report.csv')\n", + "#print(df)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4e177c0a-058a-401e-8c31-968448e9230f", + "metadata": {}, + "outputs": [], + "source": [ + "def plot(df, cond, label, var='exec'):\n", + " if cond is None:\n", + " _df = df\n", + " else:\n", + " _df = df[cond]\n", + " n_qubits = _df['qubits']\n", + " exec_time = _df[var]\n", + " plt.plot(n_qubits, exec_time, label=label)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2b315f1b-008a-49c4-8294-19131d034e66", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_LK_CPU = df[(df['dev'] == 'lightning.kokkos') & (df['jit'] == '-') & (df['hw'] == 'CPU')]\n", + "df_LK_GPU = df[(df['dev'] == 'lightning.kokkos') & (df['jit'] == '-') & (df['hw'] == 'GPU')]\n", + "\n", + "plot(df_LK_CPU, (df_LK_CPU['threads'] == 16), 'LK 16th')\n", + "plot(df_LK_CPU, (df_LK_CPU['threads'] == 32), 'LK 32th')\n", + "plot(df_LK_CPU, (df_LK_CPU['threads'] == 64), 'LK 64th')\n", + "plot(df_LK_GPU, None, 'LK GPU')\n", + "plt.ylabel('execution')\n", + "\n", + "plt.xlabel('#qubits')\n", + "plt.yscale('log')\n", + "plt.grid()\n", + "plt.legend(framealpha=1)\n", + "\n", + "plt.savefig('LK_CPU-vs-GPU.png')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6db2cccd-95a5-41bb-92b6-57725e1bba6f", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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8wdKdOria6+9RmBgIJs2baJataKtC+Ht7c2XX36Jv78/jRo14tVXX+Xpp5/mtddew2q1cvvttxe4/ssvv6RatWokJSXRuHFj9u7dS7169ejQoQMWi4WYmJj8axctWsTy5cs5cuQIPj4+ALzzzjtMnjyZiRMn8sgjj5TYZxcRcTcOh8GHc7bz/qytADwZkcTQ1Lex2HMgMg76joNKVU2usnTo1pgUqkePHmRkZPDmm28W+TnNmjXD398///HVV19Nenp6fq/Otm3b6Nu3L3Xq1CEoKIhatWoBsHfvXsA5iDsxMZH69eszZMgQZsyYkf9aa9euJT09napVqxIQEJD/Z9euXQVur4mIyKXJyMnjie9X54egj+quYOiJN5whqP6NcP+UChuCQD1CJcvL39kzY9Z7l6CuXbsyePBgevbsicPhYPTo0Zf9mrfccgsxMTF89tlnRERE4HA4aNy4cf44opYtW7Jr1y7++OMPZs2axV133UW3bt2YOHEi6enp1KhRo9BZa5UrV77s2kRE3NHe45k88u1KNh86hY8H/Fp/Jg12fuU82foBuOHtcr1GUFFU7E9X1iyWcruyZmF69OjBb7/9xq233ophGHzwwQcXvH7t2rVkZWXh5+cHwNKlSwkICCAqKorjx4+zZcsWPvvsM6655hrAebvrn4KCgujTpw99+vThjjvu4Prrr+fEiRO0bNmSQ4cO4enpmd+TJCIixffX9mM88cNqUjJtRARYmRr9AyE7pzhPdnkJrvlXhZgefzEKQm4qNTWVxMTEAseqVq16zqDobt26MXXqVG655RYcDgdjxow572vm5uby4IMP8uKLL7J7925efvllBg0ahNVqpUqVKlStWpX//e9/1KhRg7179/Lss88WeP57771HjRo1aNGiBVarlQkTJhAeHk7lypXp1q0bV199Nb169eK///0vV155JQcOHGDatGn07t2b1q3L1yZ/IiJmMQyDr//azWvTNmF3GFwd4cnYSqPx2bkYrJ7ONYKa9zW7zDKjIOSm5s2bR4sWLQoce/DBB/n888/PubZLly5MmzaNm2++GcMwGDNmDJZC/pXQtWtX6tWrR8eOHcnJyaFv376MHDkSAKvVyk8//cSQIUNo3Lgx9evX54MPPqBTp075zw8MDOS///0v27Ztw8PDg7i4OH7//XesVudQtt9//50XXniBgQMHcvToUcLDw+nYsSNhYWEl1zAiIhVYTp6DF35dx/iV+wAY0NiLEWkvY01OAu8AuOsbqNvV5CrLlsUwDMPsIlzVmVljqampBAUFFTiXmZnJpk2baNiwYYEBwuI6Svt7ZLPZ+P3337nxxhvx8vIq8devSNRWRae2Kjq1VdHZbDZ+mvw7vxypyprkVKwW+G9Hb27f9CSWtP0QEAb3TIAazcwutURc6Pf3P6lHSEREpIJLOpjGO+s9SM1NJcjXk2+62mi+6EHISYXQK+GeiVAl5uIvVAEpCImIiFRgqZk2Hv1uDam5Fq6oVokf2x2g+qwnwZ4LUVdB3x/B330XpVUQEhERqaAMw+D5Ses5lJZDNV+D31quxv/PV5wnG9wMt38OXn7mFmkyBSEREZEKauKqfUxbfxAvq8H/Kn+D//w/nSfaPArXvwVWD3MLdAEKQpfJ4XCYXYKch743IuLOdh/L4OUpGwEYX2sqLQ6cDkHdX4V2Q9xijaCi0BYbhUhISCA2Npa4uLjzXuPt7Q04NycV13Tme3PmeyUi4i5sdgdPjnNunnpHZBrND44DIO/Wj6D9kwpBf6MeoUIUZdNVT09PQkND2b9/PwABAQH5692IuRwOB+np6ezfv5/Q0FA8PfVjLiLuZfSsbaxNTiHI14M3/H/AcszBgcpxVGtyl9mluRz9hrgM0dHRAPlhSFxLaGho/vdIRMRdLNt5nIR52wH44urj+CxZgOHhzcaIu+lkbmkuSUHoMlgsFmJiYqhZs2b+xqHlnc1mY/HixbRv375cL1Dm7e2tniARcTupWTaGj1+LYcDdLcKI2/ISAI62j5OZVc3k6lyTflOUAE9PzwrzS9dms2Gz2fD39y/XQUhExN0YhsELk9azPyWLmKr+vBLxF2zaAZWq42g3FGYvNLtEl6RBLSIiIhXAL6v3M3XdQTysFsb0jMZn0TvOE11HgE+gucW5MAUhERGRcm7P8QxG/LoBgGHd6tFk6xjn9hnhTaH5PSZX59oUhERERMoxm93Bkz8lkpFrp03tEB5vmA2rxjpP3vB/oBnNF1QxBraIiIi4qQ9nbyMxOYVAX0/ev6sZHlPuBsMBsb0gpp3Z5bk8xUQREZFyavmuE4yZ65wq/2bvJtQ8PBd2zQcPH+cK0nJRCkIiIiLlUGqWjWHjEnEYcHvLSG5pVBX+fMF5st0gqBJjboHlhIKQiIhIOWMYBi9N3sD+lCyiQ/x5pWcjWPYpnNwFAWHQYZjZJZYbCkIiIiLlzOTE/UxZewAPq4XRdzcnwHYSFrztPNn1ZU2XvwQaLC0iIlKO7D2eyUuTnbvKD+1ajxbRVeC3JyEnDWo0h2Z9zS2wnFGPkIiISDmRZ3cwdNwa0nPyiKtVhSc614VD62H1N84Lrv+PpstfIrWWiIhIOfHhnO2s3ptCoI8n7/dpjocFmP6cc7p8o94Qc7XZJZY7CkIiIiLlwMrdJ/hwzjYAXu/dmMgq/rB5GuxeqOnyl0FBSERExMWlZdsYenqq/G0tatKzeU3Iy4EZLzovaDcYKkebW2Q5pSBUiISEBGJjY4mLizO7FBEREUZM3sC+k1lEhfg5p8oDLPvk9HT5cE2XvwwKQoWIj48nKSmJFStWmF2KiIi4uclr9jM50TlVflSfFgT6ekH6EZh/erp8t5fBJ8DcIssxBSEREREXlXwik5cmO3eVH9KlHq1iqjhPzHkdck9BRAtoereJFZZ/CkIiIiIuyDlVPpFTOXm0jqlCfOcrnCcOrtN0+RKk1hMREXFBY+ZuZ9Wek/lT5T09rGAYzunyGND4doi+yuwyyz0FIRERERezas8JPpjtnCr/Wq/GRIX4O09s+g32LAJPX+j2iokVVhwKQiIiIi7k1N+myvdqHkGvFjWdJwpMlx8ClaPMK7ICURASERFxIS//upHkE1lEVvHj1V6Nz55Y+hGk7IHAGtD+SfMKrGAUhERERFzEr4n7+WXNfqwWGNWnOUG+Xs4Tpw7DgnecX3cbqenyJUhBSERExAUkn8jkxUnOqfKDu9Sjda2QsyfnvAa56VCzFTS5y6QKKyYFIREREZPl2R0MOz1VvmV0ZQZ3qXv25MG1sOY759eaLl/i1JoiIiIm+2jeDlbuOUmAjyej727hnCoP/5gufwdEtTG1zopIQUhERMREq/eeZHT+VPlGZ6fKAyT9CnsWg6cfdNd0+dKgICQiImKSU9k2hv6UiN1hcGuzCHo1r3n2pC0bZr7k/Lr9EAiONKfICk5BSERExCQvT9nI3hOZ1Kzsx2u9GmOxWM6eXJoAKXshMELT5UuRgpCIiIgJpqw9wC+rT0+Vv7s5wX5eZ0+eOgQL33N+3W0keFcypUZ3oCAkIiJSxvadzOSFSesBGNS5LnF/nyoPMPvMdPnW0OROEyp0HwpCIiIiZcjuMBg+bi2nsvNoEV2ZIV3rFbzgwBpI/N75tabLlzq1roiISBn6eN52lu8+QSVvD0ad2VX+jL9Pl29yF0TFmVanu1AQEhERKSNr9p7k/VnOqfKv9mxMTNV/jP1Jmgx7lziny3d7uewLdEMKQiIiImUgPSePoeOcU+VvblqD21rWLHiBLQtmjHB+3WGopsuXEQUhERGRMjByykb2HHdOlX+jd5OCU+UBliRA6l4IqgnthphTpBtSEBIRESllU9cdYOKqfVgt8H6ff0yVB0g7+Lfp8q+At/+5LyKlQkFIRESkFO1PyeL5X5xT5Z/oVJc2tUPOvWjOa2DLgMg4aHJHGVfo3twiCPXu3ZsqVapwxx364RIRkbJjdxgMG5dIWnYezaIq82S3eudetH91weny/7xlJqXKLYLQk08+yTfffGN2GSIi4mY+mb+D5bucU+VH92mOl8c/fu3mT5cHmvaByNZlX6Sbc4sg1KlTJwIDA80uQ0RE3Mja5BTen7kVgJG3NqJWaCHbZGz8BZKXgpc/dNV0eTO4fBBasGABt9xyCxEREVgsFiZPnnzONQkJCdSqVQtfX1/atm3L8uXLy75QERGR0zJy8njypzXkOQxualqDO1oVMhXelgUzT4ef9kMhuOa510ipc/kglJGRQbNmzUhISCj0/Lhx4xg+fDgvv/wyq1evplmzZlx33XUcOXKkjCsVERFxeuW3jew+nklEsC9v9ipkqjzAX2MgNRmCIqHd4LIvUgDwNLuAi7nhhhu44YYbznv+vffe4+GHH2bgwIEAfPLJJ0ybNo0vv/ySZ5999pLeKycnh5ycnPzHaWlpANhsNmw2WzGqL3/OfE53+byXQ21VdGqrolNbFZ2rttUfGw4xfuU+LBb47+2N8fcqpMZTB/Fc9B4WIK/LSxgWLyjFz+GqbVVaLuVzunwQupDc3FxWrVrFc889l3/MarXSrVs3lixZcsmv99Zbb/HKK6+cc3zGjBn4+7vXmg4zZ840u4RyQ21VdGqrolNbFZ0rtdWJHHh7rQdgoWuEg+OblvL7pnOva7HnU6JtmZyoVJeFu31hz+9lUp8rtVVpyszMLPK15ToIHTt2DLvdTlhYWIHjYWFhbN68Of9xt27dWLt2LRkZGURGRjJhwgSuvvrqc17vueeeY/jw4fmP09LSiIqKokePHgQFBZXeB3EhNpuNmTNn0r17d7y8vC7+BDemtio6tVXRqa2KztXaKsdm5+7PV5BpT6NpzSA+eLjNubPEAMuB1XiuWQxA0F0fcWNEy1KvzdXaqrSduaNTFOU6CBXVrFmzinSdj48PPj4+5xz38vJyix+cv3PHz1xcaquiU1sVndqq6FyhrQzD4IVfk9hwII0q/l58dG8r/H3P/X2CYcCsl5xfN+uLZ0zbMq3TFdqqLFzKZ3T5wdIXEhoaioeHB4cPHy5w/PDhw4SHh5tUlYiIuJsflyczfqVzC40P+rYgssp5hlNs+BmSl52eLj+ibIuUQpXrIOTt7U2rVq2YPXt2/jGHw8Hs2bMLvfVVVAkJCcTGxhIXF1cSZYqISAW2Zu9JRk7ZCMBT19XnmnrVCr8wN/PsdPkOwyEooowqlAtx+Vtj6enpbN++Pf/xrl27SExMJCQkhOjoaIYPH07//v1p3bo1bdq0YdSoUWRkZOTPIiuO+Ph44uPjSUtLIzg4uCQ+hoiIVEDH0nN4/LvV5NodXNcojMevveL8Fy8ZA2n7IDgK2g0quyLlglw+CK1cuZLOnTvnPz4zmLl///6MHTuWPn36cPToUUaMGMGhQ4do3rw506dPP2cAtYiISEnKszsY9MNqDqVlU6daJd65s1nh6wUBpB2ARe87v+7+Cnj5lV2hckEuH4Q6deqEYRgXvGbQoEEMGqR0LSIiZef/pm9m6U7nPmL/u68Vgb4XGKA76xWwZULUVdDotrIrUi6qXI8REhERMcPUdQf4bOEuAN65sxl1q19gP8t9K2HdT86vr39Lu8u7GAWhQmiwtIiInM/Ww6d4ZuI6AB69tg43NKlx/osNA6af3uWgWT+oWfprBsmlURAqRHx8PElJSaxYscLsUkRExIWkZdt49NtVZObaaV+3Kk/3qH/hJ6yfCPtWgFclTZd3UQpCIiIiReBwGAwft5ZdxzKICPblg7tb4FnIytH5cjNh1unp8tcMg6AL9ByJaRSEREREiuCjeduZtekw3p5WPrmvFVUDClk5+u/++gDS9kNwNFytCT2uSkFIRETkIuZtOcK7M7cC8FrPRjSNrHzhJ6Tuh0WjnF9rurxLUxASERG5gOQTmTz5UyKGAX3bRNMnLvriT5o1EvKyILodNOpd6jVK8SkIFUKzxkREBCAr186j364iNctGs6jKjLw19uJPSl4B68cDFrj+TU2Xd3EKQoXQrDERETEMgxcmrSfpYBpVK3nz8T0t8fH0uPCTHI6z0+Wb3wMRLUq/ULksCkIiIiKF+HbpHn5Zsx+rBT7s14KIyhcZ5+Oww7RhsH8leAdA15fKplC5LC6/xYaIiEhZW7XnBK/+lgTAczc0pN0VoRd+gt0Gkx6DDRMBC9z0LgSGl36hctkUhERERP7myKlsHv9uNXkOg5ua1uCha2pf+Am2LJgwALZOB6sn3PYZNNZ+YuWFgpCIiMhpNruD+O9Xc+RUDvWqB/Df25uef0d5gJxT8GNf2L0QPH3hrm/hyh5lV7BcNgUhERGR096YtokVu08S6OPJp/e1opLPBX5NZp6A7+88Oyao3zio1aHsipUSocHShdD0eRER9/Nr4n7G/rUbgHfvakadagHnv/jUYRh7szME+VWB/lMUgsopBaFCaPq8iIh72XQwjX//7NxRflDnuvRodIGBzil74avr4chGCAiDAb9DzVZlVKmUNN0aExERt5aa6dxRPtvmoOOV1RjW/crzX3xsG3zTC9L2QeVouP9XCKlTZrVKyVMQEhERt+VwGAwdt4a9JzKJrOLH6D7N8bCeZ3D0ofXOEJR5DEKvhPsmQ3DNsixXSoGCkIiIuK3Rs7cxd8tRfDytfHJvK6pU8i78wuTl8P0dkJ0K4U3hvklQ6SJrC0m5oCAkIiJuafamw4yevQ2AN3o3oXHN4MIv3DEXfroHbBkQdZVzdphf5bIrVEqVgpCIiLid3ccyGDouEYD7rorhjlaRhV+4eZpzsUR7LlzRBfp8B96VyqxOKX0KQiIi4lYyc/N47LtVnMrOo2V0ZV66+Tw7yq8b79w2w7BDw1vg9i/A06dsi5VSp+nzhdA6QiIiFZNhGDz783o2HzpFaIAPH9/bCm/PQn4VrvgcfnnEGYKa9YM7xioEVVAKQoXQOkIiIhXTV4t3M2XtATytFj66pyVhQb7nXrTofZj2L8CANo9AzwTw0A2UikrfWRERcQvLdh7njd83AfD8jQ1pUzuk4AWGAbNfhUXvOR9f8xR0eREutNeYlHsKQiIiUuEdSs0m/oc12B0GPZtHMLB9rYIXOBzwxzOw4jPn426vQIehZV2mmEBBSEREKrTcPAePf7+KY+k5NAgP5K3bmhTcUd6eB7/Gw7qfAAvc9C7EPWhavVK2FIRERKRCe21qEmv2phDk69xR3t/7b7/68nJg4gOweSpYPKD3p9D0TvOKlTKnICQiIhXWxFX7+HbpHgBG3d2cmKp/WwMoN8O5UOLOueDhA3eOhQY3mlOomEZBSEREKqQN+1N5YdJ6AIZ2q0eXBmFnT2alwA93QfIy8KoEfX+AOp1MqVPMpSAkIiIVzsmMXB79dhU5eQ66NKjOkC71zp5MPwrf9XZuouobDPf8DFFaN85dKQiJiEiFYncYDPlpDftTsoip6s/7dzXHemZH+dT98E1POL4NKlVz7iAf3tjUesVcWlCxEFpZWkSk/Hpv5hYWbjuGr5dzR/lgfy/nieM74MvrnSEoKBIGTlcIEgWhwmhlaRGR8unPjYdImLsDgP+7vSkNawQ5TxxOgq9ugNS9EHIFPDAdQuuaWKm4Ct0aExGRCmHH0XT+NX4tAAPb16Jn85rOE/tXwXe3Q9ZJCGsM902CgOomViquREFIRETKvfScPB77dhXpOXm0qRXC8zc2dJ7YtRB+vBty0yEyDu6ZAH5VzC1WXIqCkIiIlGuGYfDMxHVsO5JOWJAPY+5pgZeHFbb+CePvh7xsqN0R7v4RfALMLldcjMYIiYhIufbF4j38vv4QXh4WPrqnFdUDfWHDz/BTP2cIqn8j9JugECSFUo+QiIiUW1tTLXy8dCsAI26OpVVMFVj1Nfz2JGBAkzuh18fg4WVuoeKy1CMkIiLl0sHUbMZuteIw4LaWNbn3qhj4awz8NgQwoPUD0Pt/CkFyQeoREhGRciclM5dHv1tDRp6FhuGBvNmrMZZ5/4H5/3Fe0P5J6PYK/H2XeZFCKAiJiEi5kppp474vlrPp0CkCvAwS+jbFd85LsPQj5wVdR8A1/zK3SCk3FIRERKTcSMu2cf+Xy1i/P5Uq/l48WjeDWn89D2u/d15ww9vQ9hFzi5RyRUFIRETKhVPZNvp/uZy1+5wh6Lv7m1J58n1YU5aDxQo9P4Lmfc0uU8oZDZYuhPYaExFxLek5eQz4agVr9qZQ2d+LH++PpeGCx6iZshzD6gV3fq0QJMWiIFQI7TUmIuI6MnLyGPjVclbtOUmQryfj7wyjwdTbsO6cS57VG3ufHyD2VrPLlHJKt8ZERMRlZebmMXDsClbsPkmgryeTboIrpvSCrBMYgTVYFPE47et0NrtMKcfUIyQiIi4pK9fOg2NXsnzXCQJ9PJl2zR6u+OMeyDoBES3JGziTVP9aZpcp5Vyxe4S2bdvG3LlzOXLkCA6Ho8C5ESNGXHZhIiLivrJtdh7+ZiVLdh4nyMfKzCazCFv4P+fJRr2dq0XrpoaUgGL9FH322Wc8/vjjhIaGEh4ejuVvC1ZZLBYFIRERKbYzIWjR9mNU885lZvR3VN4wy3ny2meh07POhRJtNnMLlQqhWEHo9ddf54033uDf//53SdcjIiJuLCfPzqPfrmLhtmPU9T7BlKpj8E/eDJ6+0DMBmtxhdolSwRQrCJ08eZI777yzpGsRERE3lpNn5/HvVjN/61Gu8trON/6j8T55HALC4O4fILK12SVKBVSswdJ33nknM2bMKOlaRETETeXmOYj/fg1zNh/hDq+/+MHrdbyzj0N4E3h4jkKQlJpi9QjVrVuXl156iaVLl9KkSRO8vAru7DtkyJASKU5ERCo+m93B4B9XM3vTQf7t/TOPWyeBA2hwM/T+FHwCzC5RKrBiBaH//e9/BAQEMH/+fObPn1/gnMViURASEZEisdkdDPlxDQs27uFj70+43rrceaLDMOgyAqxa5UVKV7GC0K5du0q6DhERcTN5dgdDxyWyekMSE3zepbFlF3h4wy0faLsMKTOXvQiDYRgABabQi4iIXEie3cHw8WvZu34xU3zeIcySAv6hcPf3EH2V2eWJGyl2n+M333xDkyZN8PPzw8/Pj6ZNm/Ltt9+WZG0iIlIB2R0GT01Yi239JMZ7v+oMQdUaOgdFKwRJGStWj9B7773HSy+9xKBBg2jfvj0AixYt4rHHHuPYsWMMGzasRIsUEZGKwe4weHpCIpHrE3jKe4LzYL0ecPsX4BtkbnHilooVhD788EM+/vhj7r///vxjt956K40aNWLkyJEKQiIicg6Hw+DFCSvouOFlenn95Tx4VTz0eA2sHuYWJ26rWEHo4MGDtGvX7pzj7dq14+DBg5ddlIiIVCwOh8Gb4+dxV9JTtPDYjsPiifXmd6HVALNLEzdXrDFCdevWZfz48eccHzduHPXq1bvsokREpOIwDIOEnyYxcNODtLBuJ9crCOv9kxSCxCUUq0folVdeoU+fPixYsCB/jNDixYuZPXt2oQGpvElISCAhIQG73W52KSIi5ZphGPzwzSc8sPNlKllyOBVQm8CBP0PVK8wuTQQoZo/Q7bffzrJlywgNDWXy5MlMnjyZ0NBQli9fTu/evUu6xjIXHx9PUlISK1asMLsUEZFyy3A4mPXZ8/Td+RyVLDkcDr2awPi5CkHiUoq9jlCrVq347rvvSrIWERGpIAxbNms/eYDux6eBBbbH3E3d+8eAh9fFnyxShoochNLS0ggKCsr/+kLOXCciIu7HSD9K8qd30PxUInmGlcRGz9L6rn+bXZZIoYochKpUqcLBgwepXr06lStXLnQlacMwsFgsGlsjIuKmjMNJpH55O9E5B0gz/FkR9x5db9Z2GeK6ihyE5syZQ0hICABz584ttYJERKR8MrbOIHfcACrbM9jtCGPtNZ/Qs3sXs8sSuaAiB6Frr702/+vatWsTFRV1Tq+QYRgkJyeXXHUiIuL6DAOWfYIx/Xl8cLDU0ZCdnT+mX+cWZlcmclHFmjVWu3Ztjh49es7xEydOULt27csuSkREygm7DaYOg+nPYsXBT3mdSOr6tUKQlBvFmjV2ZizQP6Wnp+Pr63vZRYmISDmQeQIm9IddC3AYFt7I60f17sN59Nq6ZlcmUmSXFISGDx8OgMVi4aWXXsLf3z//nN1uZ9myZTRv3rxECxQRERd0bDv8cBec2EG64csQ2yBa9+jLo50UgqR8uaQgtGbNGsDZI7R+/Xq8vb3zz3l7e9OsWTOeeuqpkq1QRERcy855MP5+yE5lnxHKg7lPcUv3bjyhECTl0CUFoTOzxQYOHMjo0aO1XpCIiLtZ8QX8/jQYdlY56vFI7nDu69aaQV20z6SUT8UaI/TVV1+VdB0iIuLK7Hkw4wVY9gkAv9g78JztIR7tEsvQbleaXJxI8RUrCHXpcuF1IebMmVOsYkRExAVlnoCfH4IdswH4r+0uPrL35IlOdRnWXSFIyrdiBaFmzZoVeGyz2UhMTGTDhg3079+/RAoTEREXsGmqc3p8xhHyPHyJz3qMPx1tePTaOjx9Xf1CZxCLlCfFCkLvv/9+ocdHjhxJenr6ZRUkIiIuIPME/PEMrJ8AQGpAHfodf4iNRi0evqY2z17fQCFIKoRiLah4Pvfeey9ffvllSb6kiIiUtU1TIaEtrJ+AYbGyJnogbY6PYKNRi4Hta/H8jQ0VgqTCKFaP0PksWbJECyqKiJRXGcedvUAbJgLgCK3Pe/7DGLPVOUN4QLtajLg5ViFIKpRiBaHbbrutwGPDMDh48CArV67kpZdeKpHCRESkDCVNgWnDIeMoWDxIax3Pvds6s25rFp5WCy/fEsu9V8UoBEmFU6wgFBwcXOCx1Wqlfv36vPrqq/To0aNEChMRkTKQcRx+fwo2/uJ8XK0ha+PeZOCfdk5kZFG1kjcf3dOStnWqmlunSCnROkIiIu4q6VeYOhwyj4HFA6P9UL7x6cOrk3dgdxg0qRnMp/e1IqKyn9mVipSaYgWhFStW4HA4aNu2bYHjy5Ytw8PDg9atW5dIcSIiUgoyjjlXhz7TC1Q9lpybPuT5ZV78vHo7AL1b1OSt25rg6+VhYqEipa9Ys8bi4+NJTk4+5/j+/fuJj4+/7KJERKSUbJzsnBG28ReweMA1T3Gwzx/c9Vs2P6/eh4fVwks3x/LeXc0UgsQtFKtHKCkpiZYtW55zvEWLFiQlJV12USIiUsIyjsG0f0HSZOfj6rHQ6yNW5Mbw+McrOJaeS2V/LxL6taR93VBTSxUpS8XqEfLx8eHw4cPnHD948CCeniU6I19ERC7XxkmQ0MYZgiwe0PFpeGQe3+0Noe//lnIsPZcG4YH8NqiDQpC4nWIFoR49evDcc8+RmpqafywlJYXnn3+e7t27l1hxJWHq1KnUr1+fevXq8fnnn5tdjohI2Uk/CuPvhwkDIPM4VG8ED88ht+PzPDdlKy9O3kCew+CmpjX45Yl2RIX4m12xSJkrVvfNO++8Q8eOHYmJiaFFixYAJCYmEhYWxrfffluiBV6OvLw8hg8fzty5cwkODqZVq1b07t2bqlU1DVREKrgNvzinxWcePz0W6F/Q8WmOZDp4/LOlrNpzEosFnrmuAY9dW0frA4nbKlYQqlmzJuvWreP7779n7dq1+Pn5MXDgQPr27YuXl1dJ11hsy5cvp1GjRtSsWROAG264gRkzZtC3b1+TKxMRKSXpR+H3fzmnxgOENYaeCRDRnMTkFB79diWH03II8vXkg74t6FS/urn1ipis2AN6KlWqxCOPPFKStZxjwYIFvP3226xatYqDBw8yadIkevXqVeCahIQE3n77bQ4dOkSzZs348MMPadOmDQAHDhzID0HgDHD79+8v1ZpFRExhGM6ZYNOegqwTYPV09gJd8xR4ejN+ZTIvTtpArt1BveoB/O/+1tQOrWR21SKmK3YQ+vbbb/n000/ZuXMnS5YsISYmhvfff586derQs2fPEikuIyODZs2a8cADD5yzrQfAuHHjGD58OJ988glt27Zl1KhRXHfddWzZsoXq1S/9Xzk5OTnk5OTkP05LSwPAZrNhs9mK/0HKkTOf010+7+VQWxWd2qroitVW6UfwmP4M1i1TATCqNyLvlg8hvCm2PAdvTV3Pt0v3AtC9YXX+e3tjAnw8y/33Qz9XRedubXUpn9NiGIZxqW/w8ccfM2LECIYOHcrrr7/Oxo0bqVOnDmPHjuXrr79m7ty5l/qSFy/UYjmnR6ht27bExcUxZswYABwOB1FRUQwePJhnn32Wv/76i7fffptJkyYBMHToUNq0aUO/fv0KfY+RI0fyyiuvnHP8hx9+wN9fgwhFxMUYBjVTltEk+Rt87Ok48GBr+C1sDbsVw+pJug2+2urB9jTn+J8bIu30iDSwajiQVHCZmZn069eP1NRUgoKCLnhtsYJQbGwsb775Jr169SIwMJC1a9dSp04dNmzYQKdOnTh27Fixiz9vof8IQrm5ufj7+zNx4sQC4ah///6kpKTw66+/kpeXR8OGDZk3b17+YOm//vrrvIOlC+sRioqK4tixYxdtyIrCZrMxc+ZMunfv7lLjvVyR2qro1FZFV+S2OqcXqPHpXqAmAGw8kMYTPyRyIDWbSj4evHt7E7o2rFjjgfRzVXTu1lZpaWmEhoYWKQgV69bYrl278meL/Z2Pjw8ZGRnFeclLduzYMex2O2FhYQWOh4WFsXnzZgA8PT1599136dy5Mw6Hg2eeeeaCM8Z8fHzw8fE557iXl5db/OD8nTt+5uJSWxWd2qrozttWhgEbfnbOCMs66RwL1PFpLB2G4+XpDcDkNfv598/ryMlzUDu0Ep/d34q61QPL+BOUHf1cFZ27tNWlfMZiBaHatWuTmJhITExMgePTp0+nYcOGxXnJUnPrrbdy6623ml2GiMjlO3UYpg2Hzc5eIMKaQK+PoEZTAPLsDv5v+mY+W7gLgM71qzHq7hYE+1X8X3wixVWsIDR8+HDi4+PJzs7GMAyWL1/Ojz/+yFtvvVVmixaGhobi4eFxzgrXhw8fJjw8/LJeOyEhgYSEBOx2+2W9johIiTAMWD8R/nj6b71Az8A1w8HDGXJOZuQy+Mc1LNruHJowqHNdhnW/Eg8NCBK5oGIFoYceegg/Pz9efPHF/AFJERERjB49mrvvvrukayyUt7c3rVq1Yvbs2fljhBwOB7Nnz2bQoEGX9drx8fHEx8eTlpZGcHBwCVQrIlJMpw7D1GGwZZrzcXgT6PVx/lgggE0H03jk25Ukn8jC39uDd+5sxo1NaphUsEj5Uuzp8/fccw/33HMPmZmZpKenF2u6+sWkp6ezffv2/Me7du0iMTGRkJAQoqOjGT58OP3796d169a0adOGUaNGkZGRwcCBA0u8FhGRMmUYsG48/P40ZKeA1QuufQY6DMvvBQL4ff1B/jV+LVk2O1Ehfnx2f2sahLvH5A6RklCsIDRy5EhGjBiB1WrF398/f2p5amoqjz32GD/++GOJFLdy5Uo6d+6c/3j48OGAc2bY2LFj6dOnD0ePHmXEiBEcOnSI5s2bM3369HMGUIuIlCc+thQ8JtwH26Y7D4Q3Pd0L1Dj/GrvD4L2ZW0iYuwOAa+qF8mHfFlT29zajZJFyq1hB6IsvvmDGjBl899131KlTB4B58+Zx//33X/b4nL/r1KkTF5vdP2jQoMu+FSYi4hIcDizrfqLLpuew2jNO9wL9GzoMLdALlJplY+hPa5i75SgAj3SswzPX1cfTo1j7aIu4tWL9X7Nu3ToiIyNp3rw5n332GU8//TQ9evTgvvvu46+//irpGkVEKr7di+HzLnj+NghvewZGeFN4ZB5c+3SBELT9yCl6Jyxm7paj+HhaGX13c56/saFCkEgxFatHqEqVKowfP57nn3+eRx99FE9PT/744w+6du1a0vWZQrPGRKTMHN8BM0fkT4k3vCuxqeqN1Ov/AV6+BVe0n5l0mGHjEknPyaNmZT8+va8VjWtqQofI5Sj2PyE+/PBDRo8eTd++falTpw5Dhgxh7dq1JVmbaeLj40lKSmLFihVmlyIiFVXmCfjjWUho4wxBFiu0Gkje4yvYFn5LgV4gh8Ng9KxtPPzNStJz8riqTghTBrVXCBIpAcXqEbr++utZsWIFX3/9NXfccQdZWVkMHz6cq666ildeeYVnnnmmpOsUEakY8nJhxWcw//8gO9V5rG536PEaVG8I/9gsMj0nj+HjEpmR5FwzbUC7WrxwU0O8dCtMpEQUKwjZ7XbWr19PREQEAH5+fnz88cfcfPPNPPTQQwpCIiL/ZBiwaQrMfBlOOld+pnojZwCqW/iwgl3HMnjkm5VsO5KOt6eVN3o15s7WUWVYtEjFV6wgNHPmTBYuXMgzzzzDjh07mDhxIjVr1uTEiROMHz++pGsUESnf9q2CGS/A3iXOx5WqQ5cXocW9YPUo9Cnztx5l2IT1nMrOIzzIl0/ua0XzqMplV7OImyhW3+rPP//Mddddh5+fH2vWrMnfsT01NZW33nqrRAs0Q0JCArGxscTFxZldioiUZynJ8PND8HkXZwjy9IOOT8OQ1dCqf6EhyDAMZu638PB3aziVnUermCpMGdxeIUiklBQrCL3++ut88sknfPbZZwV2eG3fvj2rV68useLMosHSInJZstNg1kj4sBWsn+A81qwvDF7l7AnyKXwn+IycPIaOX8fUvR4YBvRrG82PD19F9UDfsqtdxM0U69bYli1b6Nix4znHg4ODSUlJudyaRETKJ3serP4a5r4Jmc7NT4npANe9DhEtLvjUHUfTeezbVWw7ko6HxeDlW2K5v12dMihaxL0VKwiFh4ezfft2atWqVeD4okWL8leaFhFxG4YB22bCzJfg6GbnsZArnAOh698IlgvvAP/nxkP8a/xa0nPyCAv0oW9MBn3jNChapCwUKwg9/PDDPPnkk3z55ZdYLBYOHDjAkiVLeOqpp3jppZdKukYREdd1aAPMeBF2znU+9qsC1z4LrR8Azwvv+2V3GLwzYwsfz3PuF9amdgij7mzCioWzS7tqETmtWEHo2WefxeFw0LVrVzIzM+nYsSM+Pj489dRTDB48uKRrFBFxPacOwZzXIfF7MBzOfcHaPgodn3KGoYs4kZHLkB/XsGi78xbaQx1q8+8bGoBDK9qLlKViBSGLxcILL7zA008/zfbt20lPTyc2NpaAgICSrk9ExLXkZsKSMbBoFNgynMdie0G3kRBSu0gvsTY5hSe+X83+lCz8vT34v9ubcksz57psNgUhkTJVrCB0hre3N7GxsSVVi8vQXmMicg6HA9b9BLNfg1MHnMdqtobr3oDoq4r8Mj8t38uIXzeSa3dQO7QSn97XiivDCp9FJiKl77KCUEUVHx9PfHw8aWlpBAdrLx8Rt7drAfz5Ahxa53wcHA3dXobGt190IPQZ2TY7L/+6kXErkwHoERvGO3c1I8jX6yLPFJHSpCAkInI+x7Y5d4bf8rvzsU8QXDMc2j4OXkVf22ffyUye+H416/alYrXAU9fV57GOV2C1Fi1EiUjpURASEfmnjOPOTVFXfgGOPLB4QOuB0Ok5qBR6SS+1cNtRhvy4hpOZNqr4e/Fh35Z0qHdpryEipUdBSETkjLwcWPYpLHgHck7vDF/vOud6QNXqX9JLORwGH8/fwbsztuAwoGlkMB/d05LIKv6lULiIFJeCkIiIYUDSZOfO8Cl7nMfCmjhXhK7T6ZJfLi3bxr/Gr2Vm0mEA7o6LYuStjfD1KnyDVRExj4KQiLi35BXOneGTlzkfB4RD15ece4OdZ2f4C9l6+BSPfbuKnccy8Paw8mrPRtzdJrqEixaRkqIgJCLu6dB6WPQ+bPjZ+djLH9oNgXaDwad4a6L9tvYAz0xcR5bNTs3Kfnx0T0uaadd4EZemIFQIrSMkUkFlpzqDz+pv4MCa0wct0Pwe6PICBEUU62Vtdgf/+WMzXyzaBUCHuqF80LcFIZUuvMWGiJhPQagQWkdIpAIxDNi71Bl+Nk6CvCzncasX1L8BOj4NNZoW++WPnMpm0A9rWL7rBABPdLqCf/Woj4emxouUCwpCIlIxpR+BtT/C6m/h+Lazx0PrQ8v7odndlzwV/p9W7TnBE9+v5nBaDgE+nrxzZzOubxx+mYWLSFlSEBKRisNhh+2zYfXXsHW6cw0gcI7/aXwbtLgfotoUeTXo8zEMg2+W7OG1qUnkOQzqVQ/gk/tacUU17bcoUt4oCIlI+XdyN6z5DtZ8f3YfMHDuBdbyPmh0G/gGlchbZeXaeX7Seiat2Q/ATU1r8N/bm1LJR3+dipRH+j9XRMonWzZsnuoc+7Nr/tnjflWg6d3OABTWqETfcs/xDB79dhWbD53Cw2rhuRsa8GCH2lgus4dJRMyjICQi5cvhjc7ws24cZJ08e7xOZ2f4aXAzePqU+NvO2XyYoT8lkpadR2iAN2P6teSqOlVL/H1EpGwpCImI68tOc057X/Mt7F919nhQTefU9xb3QJVapfLWDofB6NnbGD3bOeC6ZXRlPrqnFeHBRd90VURcl4KQiLgmw3Cu9nxm2rst03nc6gn1b3TO/LqiS7FWfy6qlMxcho5LZN6WowDcf3UML94Ui7entdTeU0TKloKQiLiW9KPOae9rvoVjW88eD70SWtzn3PoioFqpl7HxQCqPfbeK5BNZ+HhaebN3E25vFVnq7ysiZUtBqBBaWVqkjDnssGOOs/dny+8Fp703us059ieq7WVPey+qn1ft4/lJ68nJcxAd4s/H97akUYQWVxWpiBSECqGVpUXKyMk9kPi9c+p72v6zx2u2cvb+NL69xKa9F0VunoPXpibx7VLnDvSd61djVJ8WBPt7lVkNIlK2FIREpGzl5Zye9v4t7JwHGM7jflWgaR9nAApvXOZlHUrN5vHvV7FmbwoWCzzZtR5DutTDqq0yRCo0BSERKROBWfuwznwB1k+ArBNnT9S+1jnwucHN4GXOTKwlO44z+MfVHEvPJcjXk9F3t6Bzg+qm1CIiZUtBSERKT9pB2DgJj3Xj6XJwzdnjgRHOKe/N74GQ2qaVZxgGny/cxX+mb8buMGhYI4hP7m1JTNVKptUkImVLQUhESlbGcdj0K2z4BXYvAgysgAMPqH891lYDoG7XUp327nAYZOfZybY5yLbZybbZyck787WD7Dw7OTY7v609yLT1BwG4rUVN3ujdBD/v0qtLRFyPgpCIXL7sNNg8zbno4c65Z2d9AUS1xdagF1OSA4jr1hs7VrIPZ5wTSgoElQLnHKdDzemvbfZ/HD97/ZnXybU7ily6p9XCiFtiue+qGG2VIeKGFIREpHhyM2Hbn87ws3UG2HPOngtv6pzx1fg2lp8MYPAPqzl8KgcSF5R5mV4eFnw9PfDx8sDXy4rv6f/6eHpQxd+bxzvVoVVMSJnXJSKuQUFIRIouL9e53s+Gn53r/eSmnz1XtR40ucMZgELrATBx1T6e+2UpNrtzZpiXhwVfLw98PAuGEl9Pj9PHncd8zpzzPP31P68/fa3P6Wv+fsx5zdmw46FZXyJyAQpCInJhDjvsXugMP0lTIDvl7LngaGh8mzMAhTXOX/DQ4TB4e8YWPp63A4DrG4XRpdJ+et9yI15eWpNHRFyHgpCInMswIHm5M/xsnAQZR86eCwiDRr2h8R0Q2fqc1Z4zc/MYNi6RPzceBmBwl7oMurY206fvR0TE1SgIiYiTYcCh9bBhImyYBKl7z57zrQyxPZ09PzHtzzvj61BqNg9+vYKNB9Lw9rDyf3c0oXeLSGw2W9l8BhGRS6QgVAjtNSZu5dg2WD/R2ftzfNvZ494B0OAm55ifOp3B0/uCL7NuXwoPfb2SI6dyqFrJm0/va0XrWhqELCKuTUGoENprTCq8lL3O4LPhZ2cv0BkePnDldc7wc+V14OVXpJf7Y/1Bho1PJNvm4MqwAL7oH0dUiH8pFS8iUnIUhETcxanDzvE+G36GfcvPHrd6whVdnOGn/o2XtMmpYRh8NG8Hb/+5BYBO9avxYd8WBPpqQLSIlA8KQiIVWeYJ2PSbc9zP7kVgnFlo0AK1OjjDT2xP8L/0W1g5eXae+3k9v6xxDoIe2L4WL9zYEE8Pawl+ABGR0qUgJFLR5JyCLX84x/3smF1wlefIuNPhpxcE1Sj2WxxLz+HRb1exas9JPKwWXrm1EfdeFXP5tYuIlDEFIZHyzDDg5C44kAgH1jj/7FsBedlnrwlr4lzrp/FtUKXWZb/l1sOneGDsCvadzCLQ15OP72lFh3qhl/26IiJmUBASKS8MwznI+cAaOJh4OvgkFlzg8IyQK86u8lytfomVMG/LEQb9sIb0nDxiqvrzRf846lYPKLHXFxEpawpCIq7IMCBt/9mwc6a3J+vEudd6eDtXdY5o4fxTsxVUb3jOQoeXV47B13/t5tWpSTgMaFM7hE/vbUWVSheeUi8i4uoUhERcQdrBs2HnTG9PxtFzr7N6QVjs2dAT0QKqNbzoGj+Xw2Z38MpvG/luqXOBxbtaR/J6ryZ4e2pQtIiUfwpCImUt/cjZ0HOmtyf90LnXWTygeixEND8besIagadPmZWammVj0A+rWbjtGBYLPHt9Ax7pWAdLCfY2iYiYSUFIpDRlHCt4a+tgovOW1z9ZrFCtQcGenrBGRV7QsDTsPpbBg1+vYMfRDPy8PBh9d3N6NAo3rR4RkdKgICRSUjJP/G0Q8xo4sLbgfl35LBB6ZcHQE94YvCuVdcXntXTncR77bhUpmTZqBPvyef/WNIrQKusiUvEoCIkUhz0Py57F1D08DY9ffnYGoJQ9hV9bte4/Qk8T8Aks03IvxfiVybwwaT02u0GzyGA+u7811YN8zS5LRKRUKAiJFFVeLuyaD0m/wuZpeGadoBHAgb9dE1IHajQ/G3pqNAXf8tGT4nAY/N+fm/l0/k4Abmpag3fvbIavV+E7zYuIVAQKQiIXYsuGHXOc4WfLH5CTmn/K8AvhgM8VhLe4AY+oVlCjGfhVMbHY4svIyWPouERmJh0GYEjXegztWg+rVYOiRaRiUxAS+afcDNg2EzZNga1/Qm762XMBYdDwFmh4K3k127By+gxubHcjHl7ld5PRg6lZPDh2JUkH0/D2tPLf25vSq0VNs8sSESkTCkIiANlpsG0GJE2GbbMgL+vsuaCa0PBW5+akUW3AevpWkc1mSqklaW1yCg9/s5Ijp3IIDfDm0/ta0yqmfPZqiYgUh4KQuK+sk87bXUlTnJuT2nPPnqsc4ww+sT0hoiVYK97igdPWHWT4+ERy8hzUDwvk8/6tiQrxN7ssEZEypSBUiISEBBISErDb7WaXIiUt4xhsnuYc87NrfsGd2avWOx1+boXwpiW6RYUrMQyDMXO28+7MrQB0rl+ND/q2INC3/N7eExEpLgWhQsTHxxMfH09aWhrBweVjxo9cwKlDsOk355if3YvAcJw9V72RM/jE9nQuaFhBw88Z2TY7z/68jsmJzqluD7SvzQs3NcRDg6JFxE0pCEnFlLrPGX6SfoW9SwHj7LkazZzBp2FPCK1rWoll7Vh6Do98s5LVe1PwtFp4tWdj+rWNNrssERFTKQhJxXFil7PXJ2kK7F9Z8Fxk3OkBz7dClVqmlGemLYdO8cDYFexPySLI15OP721F+7qhZpclImI6BSEp345tc/b6JP0Kh9b97YQFoq8+3fNzMwRHmlai2eZuPsLgH9eQnpNHrar+fDEgjiuqBZhdloiIS1AQkvLFMODIJmfw2TQFjiSdPWfxgFodnL0+DW6BwDDz6nQBhmHw1eLdvD4tCYcBV9UJ4eN7WlGlkrfZpYmIuAwFIXF9hgEH156+7fUrHN9+9pzVC+pc6+z5qX8TVKpqXp0uxGZ38PKUjfywzLnpa5/WUbzWqzHenhVvGQARkcuhICSuxZbl7PE5vPH0nw3OP1knz17j4QN1uzrH/NS/vtxua1FaUjNtPPHDKhZvP47FAs/f0JCHrqmNpYLPiBMRKQ4FITGHYThndp0JOmeCz/HtBae3n+HpB/W6O3t+rrzOpXdvN9PWw6d47NtV7DyWgb+3B6PvbkH3WPe+RSgiciEKQlL6cjNO9/JsgEN/Cz1/28C0AP9QCG8MYY0hrJHzT7UG4OlTtnWXI7uPZfDB7G1MTtyPw4CIYF8+7x9HbESQ2aWJiLg0BSEpOQ4HpOw597bWiV0UWMfnDKsXVKt/NuyEnQ4/AdUr/MKGJSX5RCYfztnGz6v3Y3c427hHbBiv925M9UBfk6sTEXF9CkJSPDmn4HDSP25tJUHuqcKvDwgrGHbCGkHoleCpGUzFcSAlizFztzN+RTJ5pwNQlwbVGdbtSppEajV0EZGiUhCSC3M44OSuguN4Dq139vwUxsP7dC9Pk4I9PQHVyrbuCupwWjYfzd3Oj8uTybU7x1JdUy+UYd2vpGW0Bo2LiFwqBSFxsudB+iEsx3ZQ++gsPKbNhKObnOv02DILf05gxNmwE346+FStCx7avLOkHT2Vwyfzd/Dd0j3k5DkD0FV1QhjevT5taoeYXJ2ISPmlIOQubFnOWVopeyE1GVKSnY/PfJ22Hww7nkBTgH1/e66nr3Ow8t8HMFdvpDV7ysCJjFw+XbCDb/7aQ5bNDkDrmCoM73El7a7QFhkiIpdLQagiMAznOjv5Aedv/z3zdeaxi7+O1RMjqCaHHVWo1rgzHhFNnLe4QuqAh35UylJqpo3PFu7kq8W7yMh1BqBmUZX5V/cruaZeqNYEEhEpIfrtVh447HDq0N8Czt7TvTtnws4+yE2/+Ot4B0BwlHPfrcpRzq8rR589FhhOnt3Bst9/58bON+LhpVtcZS0t28aXi3bxxcJdnMrJA6BxzSCGd7+SzvWrKwCJiJQwBSFXYMs+fZtq77m3rFL3QtoBcORd/HUqVXMGmr8HnMpRZ4/5Vbn4tHR7IYsZSqnLyMlj7F+7+d+CnaRm2QBoEB7IsO5X0iM2TAFIRKSUKAiZIfMETB16tkcn4+jFn2PxgOCap3tvos726ARHng49keDlV+qlS8nKyrXz7dLdfDJ/JycycgGoWz2AYd2u5IbG4VitCkAiIqVJQcgMXv7OzUP/eezvASc/6Jz+OrAGWD3MqVdKXLbNzg/L9vLRvB0cS88BoHZoJZ7sWo9bmkXgoQAkIlImFITM4OULN79/+lbW6dtYRbltJeVeTp6d8SuSGTN3O4fTnAEoKsSPIV3q0btFTTw9tDu8iEhZUhAyS+sHzK5AypDN7mDiqn2MmbOd/SlZgHM/sMFd63FHq0i8FIBEREyhICRSivLsDiat2c8Hc7aRfMIZgMKCfBjUuS53xUXh46nbnSIiZlIQEikFdofBb2sPMHr2NnYdywAgNMCHJzpdQb+20fh6KQCJiLgCBSGREuRwGPyx4RCjZm1l2xHn2k4hlbx57No63HdVLfy8FYBERFyJWwSh3r17M2/ePLp27crEiRPNLkcqIMMwmJF0mPdnbmXzoVMABPt58UjHOvRvV4sAH7f4X01EpNxxi7+dn3zySR544AG+/vprs0uRCsYwYO6Wo3wwdwcb9qcBEOjjyUPX1GFgh1oE+Wp1bhERV+YWQahTp07MmzfP7DKkAjEMg4Xbj/H+Bg/2LF0DQCVvDwa2r83D19Qh2F8BSESkPDB9zu6CBQu45ZZbiIiIwGKxMHny5HOuSUhIoFatWvj6+tK2bVuWL19e9oWKnLb18Cn6f7WCB75ezZ50C35eVh69tg4L/92Fp66rrxAkIlKOmN4jlJGRQbNmzXjggQe47bbbzjk/btw4hg8fzieffELbtm0ZNWoU1113HVu2bKF69eoANG/enLy8c/fimjFjBhEREUWuJScnh5ycnPzHaWnOWx02mw2bzXapH61cOvM53eXzXooTGbl8MGcHP63ch91h4OVhoV11O6/1bU+NKpUAtdv56Oeq6NRWRae2Kjp3a6tL+ZwWwzCMUqzlklgsFiZNmkSvXr3yj7Vt25a4uDjGjBkDgMPhICoqisGDB/Pss88W+bXnzZvHmDFjLjhYeuTIkbzyyivnHP/hhx/w9/cv+geRCiXPAQsPWfhzn5Usu3P176YhDnrGOAj1Nbk4ERE5R2ZmJv369SM1NZWgoKALXmt6j9CF5ObmsmrVKp577rn8Y1arlW7durFkyZISf7/nnnuO4cOH5z9OS0sjKiqKHj16XLQhKwqbzcbMmTPp3r07Xl7ufYvHMAzmbD7K+39uZffxTAAahgfywo31aVs7RG11CdRWRae2Kjq1VdG5W1uduaNTFC4dhI4dO4bdbicsLKzA8bCwMDZv3lzk1+nWrRtr164lIyODyMhIJkyYwNVXX33OdT4+Pvj4+Jxz3MvLyy1+cP7OHT/z3206mMbr05JYvP044FwM8Znr6nN7q8hzNkR197a6FGqrolNbFZ3aqujcpa0u5TO6dBAqKbNmzTK7BCknjqXn8O6MrYxbsReHAd6eVh7qUJsnOtfVWkAiIhWQS//NHhoaioeHB4cPHy5w/PDhw4SHh5tUlVREOXl2vlq8mzFztpOe4xx4f1PTGjx7fQOiQjQ+TESkojJ9+vyFeHt706pVK2bPnp1/zOFwMHv27EJvbZWUhIQEYmNjiYuLK7X3ENdgGAZ/rD9I9/cW8J8/NpOek0fTyGAmPHY1Cf1aKgSJiFRwpvcIpaens3379vzHu3btIjExkZCQEKKjoxk+fDj9+/endevWtGnThlGjRpGRkcHAgQNLrab4+Hji4+NJS0sjODi41N5HzLVhfyqvTk1i+a4TAFQP9OHf1zegd4uaWP8xDkhERCom04PQypUr6dy5c/7jM7O2+vfvz9ixY+nTpw9Hjx5lxIgRHDp0iObNmzN9+vRzBlCLFNWRtGzembGFCav2YRjg42nl0Y51ePTaK6ikcUAiIm7F9L/1O3XqxMWWMho0aBCDBg0qo4qkosq22fli0S4+mrudjFw7AD2bR/DM9Q2oWdnP5OpERMQMpgchkdJmGAZT1x3kP39sZn9KFgDNoyrz0s2xtIqpYnJ1IiJiJgWhQiQkJJCQkIDdbje7FLlMa5NTeG1qEiv3nASgRrAv/76+Abc2i9A4IBERURAqjAZLl3+HUrP575+b+WX1fgD8vDx47NoreKRjHfy8PUyuTkREXIWCkFQoWbl2/rdgJ5/M30GWzdmjd1vLmjxzXQPCg7UxmIiIFKQgJBWCw2EwZe0B/m/6Zg6mZgPQKqYKI26OpVlUZXOLExERl6UgJOXe6r0nefW3JBKTUwCoWdmPZ29owM1Na2CxaByQiIicn4KQlFv7U7L4vz82M2XtAQD8vT2I71yXBzvUxtdL44BEROTiFIQKoVljri0jJ49P5+/g0wU7yclzYLHAna0ieapHfaoHaRyQiIgUnYJQITRrzDU5HAa/rNnP239u5nBaDgBtaocw4uZYGtfU90lERC6dgpCUCyt2n+C1qUms25cKQFSIH8/f0JDrG4drHJCIiBSbgpC4LMMwWLbrBJ8v3MWsTYcBCPDxZFCXugxoV0vjgERE5LIpCInLyc1zMG39Ab5YtIsN+9MAsFjg7rgohnevT7VAH5MrFBGRikJBSFzGyYxcfli+l2+W7M4fA+TjaeW2lpE82KEWdasHmlyhiIhUNApChdCssbK142g6Xy7axc+r95FtcwBQLdCH/lfH0K9tDCGVvE2uUEREKioFoUJo1ljpMwyDxduP88WinczdcjT/eGyNIB7sUJubm9XAx1NjgEREpHQpCEmZysmz82viAb5ctIvNh04BzvE/XRuE8WCH2lxVJ0SzwEREpMwoCEmZOJaew/dL9/Lt0t0cS88FnDvC39k6koHta1M7tJLJFYqIiDtSEJJSteXQKb5ctItJifvJzXOO/6kR7Ev/drXoGxdNsL+XyRWKiIg7UxCSEudwGMzfdpQvF+1i4bZj+cebRQbz4DV1uKFxOF4eVhMrFBERcVIQkhKTbbPzy+r9fLl4F9uPpANgtcB1jcJ5sENtWsVU0fgfERFxKQpCctmOpGXz7dI9fLd0DyczbYBzBeg+cVEMaFeLqBB/kysUEREpnIJQIbSOUNFsPJDKF4t28dvaA9jsBgCRVfwY0K4WfeKiCPTV+B8REXFtCkKF0DpC5+dwGMzZfIQvFu1iyc7j+cdbx1ThwQ616R4bhqfG/4iISDmhICRFkpmbx8RV+/hq8W52HcsAwMNq4cYmNXiwQ22aR1U2t0AREZFiUBCSCzqYmsXXf+3hx+V7Sc1yjv8J8vWkb9to+l9di4jKfiZXKCIiUnwKQlKodftS+XppMr+vP0iewzn+p1ZVfx7oUJvbW0ZSyUc/OiIiUv7pt5nkszsM/tx4mNEbPNi5ZFn+8avqhPBghzp0aVAdD6umv4uISMWhICRk5dqZuCqZzxftYs/xTMCCl4eFW5pG8ECH2jSuqQHjIiJSMSkIubHj6Tl8s2QP3y7dw4kM5/5flf28aBOSw4h+nYisGmhyhSIiIqVLQcgN7TqWwecLdzJx1T5yTu//FRXix0Md6tCrWRjzZs0gLMjX5CpFRERKn4KQG1m15ySfLdjJn0mHMJzjn2kWGcwjHa/g+sbheFgt2Gw2c4sUEREpQwpChahIK0s7HAazNh3mfwt2snLPyfzjXRpU55GOdWhbO0T7f4mIiNtSECpERVhZ+swGqJ8v3MnO0wsgentY6dUigoevqUO9MI3/ERERURCqYE5m5PLd0j18vWQ3x9KdA6ADfT2596oYBrarRXWN/REREcmnIFRBJJ/I5POFOxm/ch9ZNuctvZqV/XigQ236xEURoAUQRUREzqHfjuXcun0pfLpgJ3+sP8jpBaCJrRHEo9fW4cYmNfDSBqgiIiLnpSBUDjkcBvO2HuHT+TtZtutE/vGOV1bj0Y51aHdFVQ2AFhERKQIFoXIkJ8/Or2sO8NnCnWw7kg6Ap9XCrc2dA6Ab1ggyuUIREZHyRUGoHEjNsvH9sj2MXbybI6dyAAjw8aRf22gGtq9FjWDtAC8iIlIcCkIubN/JTL5avJuflu8lI9c5ADo8yJcHOtTi7jbRBPl6mVyhiIhI+aYg5II27E/ls4U7mbruIPbTI6AbhAfy8DV1uKVZBN6eGgAtIiJSEhSEXIRhGCzYdoz/LdjB4u3H84+3r1uVh6+pw7VXVtMAaBERkRKmIGSy3DwHv611DoDefOgUAB5WCzc1qcEjHevQuGb5XNlaRESkPFAQKkRZ7DV2KtvGj8v38uWi3RxKywbA39uDu+OieaBDLSKr+Jfae4uIiIiTglAhSnuvsc2H0rjz4yWcyskDoFqgDwPa1eLetjEE+2sAtIiISFlREDJB3WoBVK7kRViwL49cU4eeLSLw8fQwuywRERG3oyBkAk8PKz89cjU1gnyxWjUAWkRExCwKQiapWVmLIIqIiJhNC9KIiIiI21IQEhEREbelICQiIiJuS0FIRERE3JaCkIiIiLgtBSERERFxWwpCIiIi4rYUhERERMRtKQiJiIiI21IQEhEREbelICQiIiJuS0FIRERE3JaCkIiIiLgt7T5fiISEBBISEsjLywMgLS3N5IrKjs1mIzMzk7S0NLy8vMwux6WprYpObVV0aquiU1sVnbu11Znf24ZhXPRai1GUq9zUvn37iIqKMrsMERERKYbk5GQiIyMveI2C0AU4HA4OHDhAYGAgFovF7HLKRFpaGlFRUSQnJxMUFGR2OS5NbVV0aquiU1sVndqq6NytrQzD4NSpU0RERGC1XngUkG6NXYDVar1okqyogoKC3OJ/lpKgtio6tVXRqa2KTm1VdO7UVsHBwUW6ToOlRURExG0pCImIiIjbUhCSAnx8fHj55Zfx8fExuxSXp7YqOrVV0amtik5tVXRqq/PTYGkRERFxW+oREhEREbelICQiIiJuS0FIRERE3JaCkIiIiLgtBSE3tGDBAm655RYiIiKwWCxMnjz5nGs2bdrErbfeSnBwMJUqVSIuLo69e/eWfbEmu1hbpaenM2jQICIjI/Hz8yM2NpZPPvnEnGJN9tZbbxEXF0dgYCDVq1enV69ebNmypcA12dnZxMfHU7VqVQICArj99ts5fPiwSRWb52JtdeLECQYPHkz9+vXx8/MjOjqaIUOGkJqaamLV5ijKz9UZhmFwww03nPfvNXdQ1PZasmQJXbp0oVKlSgQFBdGxY0eysrJMqNh8CkJuKCMjg2bNmpGQkFDo+R07dtChQwcaNGjAvHnzWLduHS+99BK+vr5lXKn5LtZWw4cPZ/r06Xz33Xds2rSJoUOHMmjQIKZMmVLGlZpv/vz5xMfHs3TpUmbOnInNZqNHjx5kZGTkXzNs2DB+++03JkyYwPz58zlw4AC33XabiVWb42JtdeDAAQ4cOMA777zDhg0bGDt2LNOnT+fBBx80ufKyV5SfqzNGjRrlNtshnU9R2mvJkiVcf/319OjRg+XLl7NixQoGDRp00a0oKixD3BpgTJo0qcCxPn36GPfee685BbmwwtqqUaNGxquvvlrgWMuWLY0XXnihDCtzTUeOHDEAY/78+YZhGEZKSorh5eVlTJgwIf+aTZs2GYCxZMkSs8p0Cf9sq8KMHz/e8Pb2Nmw2WxlW5nrO11Zr1qwxatasaRw8eLDQ/1fdVWHt1bZtW+PFF180sSrX4qbxT87H4XAwbdo0rrzySq677jqqV69O27Zt3bab+WLatWvHlClT2L9/P4ZhMHfuXLZu3UqPHj3MLs10Z27jhISEALBq1SpsNhvdunXLv6ZBgwZER0ezZMkSU2p0Ff9sq/NdExQUhKene28RWVhbZWZm0q9fPxISEggPDzerNJf0z/Y6cuQIy5Yto3r16rRr146wsDCuvfZaFi1aZGaZplIQkgKOHDlCeno6//nPf7j++uuZMWMGvXv35rbbbmP+/Plml+dyPvzwQ2JjY4mMjMTb25vrr7+ehIQEOnbsaHZppnI4HAwdOpT27dvTuHFjAA4dOoS3tzeVK1cucG1YWBiHDh0yoUrXUFhb/dOxY8d47bXXeOSRR8q4OtdyvrYaNmwY7dq1o2fPniZW53oKa6+dO3cCMHLkSB5++GGmT59Oy5Yt6dq1K9u2bTOzXNO49z8t5BwOhwOAnj17MmzYMACaN2/OX3/9xSeffMK1115rZnku58MPP2Tp0qVMmTKFmJgYFixYQHx8PBEREQV6PtxNfHw8GzZscOt/ZRbVxdoqLS2Nm266idjYWEaOHFm2xbmYwtpqypQpzJkzhzVr1phYmWsqrL3O/B3/6KOPMnDgQABatGjB7Nmz+fLLL3nrrbdMqdVMCkJSQGhoKJ6ensTGxhY43rBhQ/1S+4esrCyef/55Jk2axE033QRA06ZNSUxM5J133nHbIDRo0CCmTp3KggULiIyMzD8eHh5Obm4uKSkpBXqFDh8+7La3M87XVmecOnWK66+/nsDAQCZNmoSXl5cJVbqG87XVnDlz2LFjxzk9jbfffjvXXHMN8+bNK9tCXcT52qtGjRoAhf4d744zg0G3xuQfvL29iYuLO2e65datW4mJiTGpKtdks9mw2WznzLTw8PDI/1eXOzEMg0GDBjFp0iTmzJlD7dq1C5xv1aoVXl5ezJ49O//Yli1b2Lt3L1dffXVZl2uqi7UVOHuCevTogbe3N1OmTHHLWZtw8bZ69tlnWbduHYmJifl/AN5//32++uorEyo218Xaq1atWkREROjv+L9Rj5AbSk9PZ/v27fmPd+3aRWJiIiEhIURHR/P000/Tp08fOnbsSOfOnZk+fTq//fabW/7L6mJtde211/L000/j5+dHTEwM8+fP55tvvuG9994zsWpzxMfH88MPP/Drr78SGBiYP+4nODgYPz8/goODefDBBxk+fDghISEEBQUxePBgrr76aq666iqTqy9bF2urMyEoMzOT7777jrS0NNLS0gCoVq0aHh4eZpZfpi7WVuHh4YX2KEZHRxcaMCu6i7WXxWLh6aef5uWXX6ZZs2Y0b96cr7/+ms2bNzNx4kSTqzeJqXPWxBRz5841gHP+9O/fP/+aL774wqhbt67h6+trNGvWzJg8ebJ5BZvoYm118OBBY8CAAUZERITh6+tr1K9f33j33XcNh8NhbuEmKKydAOOrr77KvyYrK8t44oknjCpVqhj+/v5G7969jYMHD5pXtEku1lbn+7kDjF27dplae1krys9VYc9x1+nzRW2vt956y4iMjDT8/f2Nq6++2li4cKE5BbsAi2EYRqmlLBEREREXpjFCIiIi4rYUhERERMRtKQiJiIiI21IQEhEREbelICQiIiJuS0FIRERE3JaCkIiIiLgtBSERERFxWwpCIuL2xo4de86mnf80cuRImjdvXib1iEjZURASEZd29OhRvL29ycjIwGazUalSJVN2yX7qqacKbBg7YMAAevXqVeZ1iEjJ0qarIuLSlixZQrNmzahUqRLLli3L3/C2rAUEBBAQEFDm7ysipUs9QiLi0v766y/at28PwKJFi/K/PmPbtm107NgRX19fYmNjmTlzJhaLhcmTJwMwb948LBYLKSkp+c9JTEzEYrGwe/fuAq81efJk6tWrh6+vL9dddx3Jycn55/5+a2zkyJF8/fXX/Prrr1gsFiwWC/PmzSM3N5dBgwZRo0YNfH19iYmJ4a233irxNhGRkqMeIRFxOXv37qVp06YAZGZm4uHhwdixY8nKysJisVC5cmX69evHmDFjuO222wgLC2PZsmWkpqYydOjQYr1nZmYmb7zxBt988w3e3t488cQT3H333SxevPica5966ik2bdpEWloaX331FQAhISF88MEHTJkyhfHjxxMdHU1ycnKBMCUirkdBSERcTkREBImJiaSlpdG6dWuWLVtGpUqVaN68OdOmTSM6OpqAgABmzZrF5s2b+fPPP4mIiADgzTff5IYbbrjk97TZbIwZM4a2bdsC8PXXX9OwYUOWL19OmzZtClwbEBCAn58fOTk5hIeH5x/fu3cv9erVo0OHDlgsFmJiYi6jFUSkLOjWmIi4HE9PT2rVqsXmzZuJi4ujadOmHDp0iLCwMDp27EitWrUIDQ1l06ZNREVF5YcggKuvvrrY7xkXF5f/uEGDBlSuXJlNmzYV+TUGDBhAYmIi9evXZ8iQIcyYMaNYtYhI2VGPkIi4nEaNGrFnzx5sNhsOh4OAgADy8vLIy8sjICCAmJgYNm7cWKTXslqd/94zDCP/mM1mK5W6W7Zsya5du/jjjz+YNWsWd911F926dWPixIml8n4icvnUIyQiLuf3338nMTGR8PBwvvvuOxITE2ncuDGjRo0iMTGR33//HYCGDRuSnJzMwYMH85+7dOnSAq9VrVo1gALXJCYmnvOeeXl5rFy5Mv/xli1bSElJoWHDhoXW6O3tjd1uP+d4UFAQffr04bPPPmPcuHH8/PPPnDhxougfXkTKlHqERMTlxMTEcOjQIQ4fPkzPnj2xWCxs3LiR22+/nRo1auRf161bN6688kr69+/P22+/TVpaGi+88EKB16pbty5RUVGMHDmSN954g61bt/Luu++e855eXl4MHjyYDz74AE9PTwYNGsRVV111zvigM2rVqsWff/7Jli1bqFq1KsHBwXz44YfUqFGDFi1aYLVamTBhAuHh4RddrFFEzKMeIRFxSfPmzSMuLg5fX1+WL19OZGRkgRAEzttekyZNIisrizZt2vDQQw/xxhtvFLjGy8uLH3/8kc2bN9O0aVP+7//+j9dff/2c9/P39+ff//43/fr1o3379gQEBDBu3Ljz1vfwww9Tv359WrduTbVq1Vi8eDGBgYH897//pXXr1sTFxbF7925+//33/NtzIuJ6LMbfb5yLiFQAFouFSZMmaeVnEbko/TNFRERE3JaCkIiIiLgtDZYWkQpHd/xFpKjUIyQiIiJuS0FIRERE3JaCkIiIiLgtBSERERFxWwpCIiIi4rYUhERERMRtKQiJiIiI21IQEhEREbf1/9S0lWUedjBAAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_LK = df[(df['dev'] == 'lightning.kokkos') & (df['threads'] == 32) & (df['hw'] == 'CPU')]\n", + "\n", + "plot(df_LK, (df_LK['jit'] == 'qjit'), 'LK qjit')\n", + "plot(df_LK, (df_LK['jit'] == '-'), 'LK base')\n", + "plt.ylabel('execution')\n", + "\n", + "plt.xlabel('#qubits')\n", + "plt.yscale('log')\n", + "plt.grid()\n", + "plt.legend(framealpha=1)\n", + "\n", + "plt.savefig('LK_qjit-vs-base.png')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "63f54b17-e320-47b8-ba2b-61ba502cf0c3", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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paWlhiRjxYoVhmEYRllZmeHv72/Mnj3b8Zzt27cbkow1a9aYFdMl/HiszuX99983AgICDKvV2oLJXM/5xurrr782kpKSjEOHDp3z76o3OtdY9evXz/h//+//mZjK9XhxxfNOdrtdn3zyiTp27KjRo0crNjZW/fr188rTwM4YOHCgFixYoMLCQhmGoS+++EK7du3SqFGjzI5mujPTLNHR0ZKkTZs2yWq1asSIEY7ndO7cWampqVqzZo0pGV3Fj8fqfM+JiIiQn59Xb0F4zrGqqqrS7bffrpycHMXHx5sVzeX8eKxKS0u1bt06xcbGauDAgYqLi9M111yjVatWmRnTdBQdL1NaWqqKigr96U9/0pgxY7Ro0SKNHz9eEyZM0IoVK8yO53JeeeUVZWRkKDk5WQEBARozZoxycnI0ePBgs6OZym6366GHHtKgQYN05ZVXSpKKi4sVEBCgqKioBs+Ni4tTcXGxCSldw7nG6seOHDmiP/zhD/r5z3/ewulcy/nG6uGHH9bAgQN1/fXXm5jOtZxrrPbt2ydJevLJJzVlyhQtXLhQmZmZGj58uHbv3m1mXFN59z8dvJDdbpckXX/99Xr44YclST179tRXX32l1157Tddcc42Z8VzOK6+8orVr12rBggVKS0vTypUrlZ2drcTExAZnLrxNdna2vvvuO6//l6IzLjZW5eXluu6665SRkaEnn3yyZcO5mHON1YIFC7Rs2TJ9/fXXJiZzPecaqzM/33/xi1/onnvukST16tVLS5cu1RtvvKFnn33WlKxmo+h4mZiYGPn5+SkjI6PB8S5duvBL60eqq6v13//935o3b56uu+46SVL37t2Vm5urv/71r15bdKZOnaqPP/5YK1euVHJysuN4fHy8amtrVVZW1uCsTklJiddON5xvrM44efKkxowZo/DwcM2bN0/+/v4mpHQN5xurZcuWae/evWedKbzxxht19dVXa/ny5S0b1AWcb6wSEhIk6Zw/373xqtozmLryMgEBAcrKyjrrksRdu3YpLS3NpFSuyWq1ymq1nnW1gq+vr+NfTt7EMAxNnTpV8+bN07Jly9S2bdsGj/fu3Vv+/v5aunSp49jOnTt18OBBDRgwoKXjmupiYyXVn8kZNWqUAgICtGDBAq+86lG6+Fj9+te/1jfffKPc3FzHf5L04osv6s033zQhsXkuNlbp6elKTEzk5/uPcEbHA1VUVGjPnj2Oj/Py8pSbm6vo6Gilpqbqscce0y233KLBgwdr6NChWrhwoT766COv/JfRxcbqmmuu0WOPPabg4GClpaVpxYoVevvtt/XCCy+YmNoc2dnZeu+99/Thhx8qPDzcse4mMjJSwcHBioyM1H333afp06crOjpaEREReuCBBzRgwAD179/f5PQt62JjdabkVFVV6Z133lF5ebnKy8slSW3atJGvr6+Z8VvUxcYqPj7+nGcEU1NTz1kgPdnFxspiseixxx7T73//e/Xo0UM9e/bUW2+9pR07dmjOnDkmpzeRqdd8oVl88cUXhqSz/ps0aZLjOf/85z+N9u3bG0FBQUaPHj2M+fPnmxfYRBcbq0OHDhmTJ082EhMTjaCgIKNTp07G888/b9jtdnODm+Bc4yTJePPNNx3Pqa6uNu6//36jVatWRkhIiDF+/Hjj0KFD5oU2ycXG6nzfd5KMvLw8U7O3NGe+r871Od54ebmzY/Xss88aycnJRkhIiDFgwADjyy+/NCewi7AYhmE0W4sCAAAwEWt0AACAx6LoAAAAj0XRAQAAHouiAwAAPBZFBwAAeCyKDgAA8FgUHQAA4LEoOgAAwGNRdAB4vJkzZ561KeSPPfnkk+rZs2eL5AHQcig6AEx1+PBhBQQEqLKyUlarVaGhoabstPzoo4822JB08uTJuuGGG1o8B4CmxaaeAEy1Zs0a9ejRQ6GhoVq3bp1jQ9WWFhYWprCwsBZ/XwDNizM6AEz11VdfadCgQZKkVatWOf58xu7duzV48GAFBQUpIyNDixcvlsVi0fz58yVJy5cvl8ViUVlZmeNzcnNzZbFYtH///gavNX/+fHXo0EFBQUEaPXq08vPzHY/9cOrqySef1FtvvaUPP/xQFotFFotFy5cvV21traZOnaqEhAQFBQUpLS1Nzz77bJOPCYCmwxkdAC3u4MGD6t69uySpqqpKvr6+mjlzpqqrq2WxWBQVFaXbb79dr776qiZMmKC4uDitW7dOJ06c0EMPPdSo96yqqtIzzzyjt99+WwEBAbr//vt16623avXq1Wc999FHH9X27dtVXl6uN998U5IUHR2tl19+WQsWLND777+v1NRU5efnNyhLAFwPRQdAi0tMTFRubq7Ky8vVp08frVu3TqGhoerZs6c++eQTpaamKiwsTEuWLNGOHTv0+eefKzExUZL0xz/+Uddee+0lv6fVatWrr76qfv36SZLeeustdenSRevXr1ffvn0bPDcsLEzBwcGqqalRfHy84/jBgwfVoUMHXXXVVbJYLEpLS7uMUQDQEpi6AtDi/Pz8lJ6erh07digrK0vdu3dXcXGx4uLiNHjwYKWnpysmJkbbt29XSkqKo+RI0oABAxr9nllZWY6PO3furKioKG3fvt3p15g8ebJyc3PVqVMnTZs2TYsWLWpUFgAthzM6AFpc165ddeDAAVmtVtntdoWFhamurk51dXUKCwtTWlqatm7d6tRr+fjU/3vNMAzHMavV2iy5MzMzlZeXp88++0xLlizRzTffrBEjRmjOnDnN8n4ALh9ndAC0uE8//VS5ubmKj4/XO++8o9zcXF155ZWaMWOGcnNz9emnn0qSunTpovz8fB06dMjxuWvXrm3wWm3atJGkBs/Jzc096z3r6uq0ceNGx8c7d+5UWVmZunTpcs6MAQEBstlsZx2PiIjQLbfcon/84x+aNWuWPvjgAx07dsz5Lx5Ai+KMDoAWl5aWpuLiYpWUlOj666+XxWLR1q1bdeONNyohIcHxvBEjRqhjx46aNGmS/vKXv6i8vFy/+c1vGrxW+/btlZKSoieffFLPPPOMdu3apeeff/6s9/T399cDDzygl19+WX5+fpo6dar69+9/1vqcM9LT0/X5559r586dat26tSIjI/XKK68oISFBvXr1ko+Pj2bPnq34+PiL3owQgHk4owPAFMuXL1dWVpaCgoK0fv16JScnNyg5Uv201Lx581RdXa2+ffvqZz/7mZ555pkGz/H399e///1v7dixQ927d9dzzz2n//mf/znr/UJCQvT444/r9ttv16BBgxQWFqZZs2adN9+UKVPUqVMn9enTR23atNHq1asVHh6uP//5z+rTp4+ysrK0f/9+ffrpp47pMwCux2L8cGIbANyAxWLRvHnzuHMxgIvinyEAAMBjUXQAAIDHYjEyALfDjDsAZ3FGBwAAeCyKDgAA8FgUHQAA4LEoOgAAwGNRdAAAgMei6AAAAI9F0QEAAB6LogMAADzW/wcy7kXah9Z6HwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_LK = df[(df['dev'] == 'lightning.kokkos') & (df['threads'] == 32) & (df['hw'] == 'CPU')]\n", + "\n", + "plot(df_LK, (df_LK['jit'] == 'qjit'), 'LK qjit', 'comp')\n", + "plt.ylabel('compilation')\n", + "\n", + "plt.xlabel('#qubits')\n", + "plt.yscale('log')\n", + "plt.grid()\n", + "plt.legend(framealpha=1)\n", + "\n", + "plt.savefig('LK_qjit-compile.png')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "adbd2db6-0b38-4c75-9f99-70fa5a225770", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/nersc/single_circuits/report.csv b/nersc/single_circuits/report.csv new file mode 100644 index 0000000..7027982 --- /dev/null +++ b/nersc/single_circuits/report.csv @@ -0,0 +1,57 @@ +dev,hw,threads,grad,jit,np,qubits,comp,exec +lightning.kokkos,CPU,16,-,-,-,15,0.000,0.125 +lightning.kokkos,CPU,16,-,-,-,20,0.000,0.401 +lightning.kokkos,CPU,16,-,-,-,21,0.000,0.679 +lightning.kokkos,CPU,16,-,-,-,22,0.000,1.186 +lightning.kokkos,CPU,16,-,-,-,23,0.000,2.182 +lightning.kokkos,CPU,16,-,-,-,24,0.000,4.614 +lightning.kokkos,CPU,16,-,-,-,25,0.000,10.505 +lightning.kokkos,CPU,16,-,-,-,26,0.000,32.876 +lightning.kokkos,CPU,16,-,-,-,27,0.000,76.580 +lightning.kokkos,CPU,32,-,-,-,15,0.000,0.128 +lightning.kokkos,CPU,32,-,-,-,16,0.000,0.142 +lightning.kokkos,CPU,32,-,-,-,17,0.000,0.166 +lightning.kokkos,CPU,32,-,-,-,18,0.000,0.220 +lightning.kokkos,CPU,32,-,-,-,19,0.000,0.262 +lightning.kokkos,CPU,32,-,-,-,20,0.000,0.353 +lightning.kokkos,CPU,32,-,-,-,21,0.000,0.494 +lightning.kokkos,CPU,32,-,-,-,22,0.000,0.801 +lightning.kokkos,CPU,32,-,-,-,23,0.000,1.423 +lightning.kokkos,CPU,32,-,-,-,24,0.000,2.934 +lightning.kokkos,CPU,32,-,-,-,25,0.000,6.621 +lightning.kokkos,CPU,32,-,-,-,26,0.000,29.947 +lightning.kokkos,CPU,32,-,-,-,27,0.000,64.426 +lightning.kokkos,CPU,64,-,-,-,15,0.000,0.135 +lightning.kokkos,CPU,64,-,-,-,20,0.000,0.341 +lightning.kokkos,CPU,64,-,-,-,21,0.000,0.474 +lightning.kokkos,CPU,64,-,-,-,22,0.000,0.653 +lightning.kokkos,CPU,64,-,-,-,23,0.000,1.052 +lightning.kokkos,CPU,64,-,-,-,24,0.000,2.247 +lightning.kokkos,CPU,64,-,-,-,25,0.000,5.124 +lightning.kokkos,CPU,64,-,-,-,26,0.000,33.576 +lightning.kokkos,CPU,64,-,-,-,27,0.000,72.099 +lightning.kokkos,GPU,0,-,-,-,15,0.000,0.118 +lightning.kokkos,GPU,0,-,-,-,20,0.000,0.224 +lightning.kokkos,GPU,0,-,-,-,21,0.000,0.280 +lightning.kokkos,GPU,0,-,-,-,22,0.000,0.477 +lightning.kokkos,GPU,0,-,-,-,23,0.000,0.759 +lightning.kokkos,GPU,0,-,-,-,24,0.000,1.451 +lightning.kokkos,GPU,0,-,-,-,25,0.000,2.858 +lightning.kokkos,GPU,0,-,-,-,26,0.000,5.795 +lightning.kokkos,GPU,0,-,-,-,27,0.000,12.113 +lightning.kokkos,GPU,0,-,-,-,28,0.000,25.542 +lightning.kokkos,GPU,0,-,-,-,29,0.000,54.042 +lightning.kokkos,GPU,0,-,-,-,30,0.000,114.467 +lightning.kokkos,CPU,32,-,qjit,-,15,10.045,0.029 +lightning.kokkos,CPU,32,-,qjit,-,16,11.415,0.043 +lightning.kokkos,CPU,32,-,qjit,-,17,12.532,0.063 +lightning.kokkos,CPU,32,-,qjit,-,18,13.544,0.103 +lightning.kokkos,CPU,32,-,qjit,-,19,15.033,0.160 +lightning.kokkos,CPU,32,-,qjit,-,20,16.750,0.331 +lightning.kokkos,CPU,32,-,qjit,-,21,18.347,0.341 +lightning.kokkos,CPU,32,-,qjit,-,22,20.144,0.671 +lightning.kokkos,CPU,32,-,qjit,-,23,22.126,1.345 +lightning.kokkos,CPU,32,-,qjit,-,24,24.765,3.227 +lightning.kokkos,CPU,32,-,qjit,-,25,31.732,9.668 +lightning.kokkos,CPU,32,-,qjit,-,26,58.165,32.451 +lightning.kokkos,CPU,32,-,qjit,-,27,92.592,65.517