diff --git a/benchmarks/libraries/qibo.py b/benchmarks/libraries/qibo.py index fba8e09..dc25eaa 100644 --- a/benchmarks/libraries/qibo.py +++ b/benchmarks/libraries/qibo.py @@ -4,9 +4,24 @@ class Qibo(abstract.AbstractBackend): - def __init__(self, max_qubits="0", backend="qibojit", platform=None, accelerators=""): + def __init__(self, max_qubits="0", backend="qibojit", platform=None, accelerators="",expectation=None,computation_settings=None): import qibo - qibo.set_backend(backend=backend, platform=platform) + + runcard=None + + if computation_settings is not None: + import json + + with open(computation_settings, 'r') as f: + runcard = json.load(f) + + if runcard["expectation_enabled"]==True: + expectation = True + + qibo.set_backend(backend=backend, platform=platform, runcard=runcard) + else: + qibo.set_backend(backend=backend, platform=platform) + from qibo import models self.name = "qibo" self.qibo = qibo @@ -14,6 +29,8 @@ def __init__(self, max_qubits="0", backend="qibojit", platform=None, accelerator self.__version__ = qibo.__version__ self.max_qubits = int(max_qubits) self.accelerators = self._parse_accelerators(accelerators) + self.expectation_flag = expectation + self.backend_name_str = backend def from_qasm(self, qasm): circuit = self.models.Circuit.from_qasm(qasm, accelerators=self.accelerators) @@ -24,10 +41,35 @@ def from_qasm(self, qasm): circuit = circuit.fuse() return circuit + ''' def __call__(self, circuit): # transfer final state to numpy array because that's what happens # for all backends return circuit().state(numpy=True) + ''' + def __call__(self, circuit): + # transfer final state to numpy array because that's what happens + # for all backends + if self.backend_name_str == "qibojit" and self.expectation_flag is not None: + from qibo.symbols import X,Y,Z,I + from qibo.hamiltonians import SymbolicHamiltonian + import numpy as np + from qibo.backends import GlobalBackend + backend = GlobalBackend() + # self.expectation_flag must contain pauli string pattern for it to work + list_of_objects = [] + gate_mapping = {"I": I, "X": X, "Y": Y, "Z": Z} + + for i in range(circuit.nqubits): + gate = gate_mapping[self.expectation_flag[i % len(self.expectation_flag)]] + list_of_objects.append(gate(i)) + obs = np.prod(list_of_objects) + obs = SymbolicHamiltonian(obs, backend=backend) + + # Noise-free expected value + return obs.expectation(backend.execute_circuit(circuit).state()) + else: + return circuit().state(numpy=True) def transpose_state(self, x): return x diff --git a/benchmarks/scripts.py b/benchmarks/scripts.py index c05f7ba..6596c3b 100644 --- a/benchmarks/scripts.py +++ b/benchmarks/scripts.py @@ -2,7 +2,6 @@ import time from benchmarks.logger import JsonLogger - def circuit_benchmark(nqubits, backend, circuit_name, circuit_options=None, nreps=1, nshots=None, transfer=False, precision="double", memory=None, threading=None, @@ -133,6 +132,117 @@ def library_benchmark(nqubits, library, circuit_name, circuit_options=None, logs.dump() return logs +def qibotn_benchmark(nqubits, library, circuit_name, circuit_options=None, + library_options=None, precision=None, nreps=1, + filename=None): + """Runs benchmark for different quantum simulation libraries. + + See ``benchmarks/compare.py`` for documentation of each argument. + """ + from mpi4py import MPI # this line initializes MPI + import numpy as np + import cupy as cp + + try: + # Try to create MPI.COMM_WORLD + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + except MPI.Exception: + # MPI is not available or not launched deliberately, set rank to 0 + rank = 0 + + if rank == 0: + logs = JsonLogger(filename) + logs.log(nqubits=nqubits, nreps=nreps) + + if rank == 0: + start_time = time.time() + from benchmarks import libraries + backend = libraries.get(library, library_options) + if rank == 0: + logs.log(import_time=time.time() - start_time) + logs.log(library_options=library_options) + if precision is not None: + + backend.set_precision(precision) + backend.expectation_flag + + if rank == 0: + logs.log(library=backend.name, + precision=backend.get_precision(), + device=backend.get_device(), + version=backend.__version__) + + from benchmarks import circuits + gates = circuits.get(circuit_name, nqubits, circuit_options) + #gates = circuits.get(circuit_name, nqubits, circuit_options, True) #use qibo gate + + if rank == 0: + logs.log(circuit=circuit_name, circuit_options=str(gates)) + start_time = time.time() + circuit = backend.from_qasm(gates.to_qasm()) + + if rank == 0: + logs.log(creation_time=time.time() - start_time) + + start_time = time.time() + result = backend(circuit) + if rank == 0: + logs.log(dry_run_time=time.time() - start_time) + dtype = str(result.dtype) + del(result) + + if rank == 0: + simulation_times = [] + if backend.expectation_flag is not None: + expectation_result = [] + for _ in range(nreps): + if rank == 0: + start_time = time.time() + result = backend(circuit) + if isinstance(result, cp.ndarray): + result = cp.asnumpy(result) + else: + result = np.array([result]) + + if rank == 0: + simulation_times.append(time.time() - start_time) + #if _==0: + #modified_string = library_options.replace("=", "_") + #modified_string = modified_string.replace(",", "") + #filename = modified_string+str(circuit.nqubits)+".dat" + #np.savetxt(filename,result) + #print(result) + if backend.expectation_flag is not None: + magnitude = np.abs(result[0]) + magnitude_list = magnitude.tolist() + + expectation_result.append(magnitude_list) + ''' + else: + components = library_options.split(',') + + # Iterate through the components to find the one that starts with "platform=" + for component in components: + if component.startswith("platform="): + # Extract the platform value + platform_value = component.split('=')[1] + print("Platform:", platform_value) + break + output_text = backend.name + '_' + circuit_name + '_' +platform_value + '_' +str(nqubits) + '.npz' + np.savez(output_text, result) + ''' + del(result) + + if rank == 0: + logs.log(dtype=dtype, simulation_times=simulation_times) + logs.average("simulation_times") + if backend.expectation_flag is not None: + logs.log(dtype=dtype, expectation_result=expectation_result) + logs.average("expectation_result") + logs.dump() + return logs + def evolution_benchmark(nqubits, dt, solver, backend, platform=None, nreps=1, precision="double", dense=False, diff --git a/benchmarks/scripts_qibotn.py b/benchmarks/scripts_qibotn.py new file mode 100644 index 0000000..0fcef85 --- /dev/null +++ b/benchmarks/scripts_qibotn.py @@ -0,0 +1,261 @@ +"""Benchmark scripts.""" +import time +from benchmarks.logger import JsonLogger + + +def qibotn_benchmark_mpi(nqubits, library, circuit_name, circuit_options=None, + library_options=None, precision=None, nreps=1, + filename=None): + """Runs benchmark for different quantum simulation libraries. + + See ``benchmarks/compare.py`` for documentation of each argument. + """ + from mpi4py import MPI # this line initializes MPI + import numpy as np + import cupy as cp + #import socket + + try: + # Try to create MPI.COMM_WORLD + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + #hostname = socket.gethostname() + #device_id = rank % cp.cuda.runtime.getDeviceCount() + except MPI.Exception: + # MPI is not available or not launched deliberately, set rank to 0 + rank = 0 + + # logs = JsonLogger(filename) + if rank == 0: + logs = JsonLogger(filename) + logs.log(nqubits=nqubits, nreps=nreps) + + if rank == 0: + start_time = time.time() + from benchmarks import libraries + backend = libraries.get(library, library_options) + if rank == 0: + logs.log(import_time=time.time() - start_time) + logs.log(library_options=library_options) + if precision is not None: + + backend.set_precision(precision) + + if rank == 0: + logs.log(library=backend.name, + precision=backend.get_precision(), + device=backend.get_device(), + version=backend.__version__) + + + from benchmarks import circuits + gates = circuits.get(circuit_name, nqubits, circuit_options) + #gates = circuits.get(circuit_name, nqubits, circuit_options, True) #use qibo gate + + if rank == 0: + logs.log(circuit=circuit_name, circuit_options=str(gates)) + start_time = time.time() + circuit = backend.from_qasm(gates.to_qasm()) + + if rank == 0: + logs.log(creation_time=time.time() - start_time) + start_time = time.time() + + # mem_avail = cp.cuda.Device(device_id).mem_info[0] + # formatted_string = f"{hostname}/{device_id}/{rank}/{mem_avail}" + # logs.log(hostname_id_rank_mem=formatted_string) + + # result = backend(circuit) + result = 0 # No dry run for qibotn + if rank == 0: + logs.log(dry_run_time=time.time() - start_time) + # dtype = str(result.dtype) + + del(result) + mem_avail_list=[] + if rank == 0: + simulation_times = [] + if backend.expectation_flag is not None: + expectation_result = [] + for _ in range(nreps): + # mem_avail = cp.cuda.Device(device_id).mem_info[0] + # formatted_string = f"{hostname}/{device_id}/{rank}/{mem_avail}" + # mem_avail_list.append(formatted_string) + + if rank == 0: + start_time = time.time() + result = backend(circuit) + dtype = str(result.dtype) + + # result, rank = expectation_pauli_tn_MPI(circuit,"complex128","XXXZ") + if isinstance(result, cp.ndarray): + result = cp.asnumpy(result) + else: + result = np.array([result]) + + if rank == 0: + simulation_times.append(time.time() - start_time) + #if _==0: + #modified_string = library_options.replace("=", "_") + #modified_string = modified_string.replace(",", "") + #filename = modified_string+str(circuit.nqubits)+".dat" + #np.savetxt(filename,result) + #print(result) + if backend.expectation_flag is not None: + # magnitude = np.abs(result[0]) + magnitude = np.abs(result) + + magnitude_list = magnitude.tolist() + + expectation_result.append(magnitude_list) + ''' + else: + components = library_options.split(',') + + # Iterate through the components to find the one that starts with "platform=" + for component in components: + if component.startswith("platform="): + # Extract the platform value + platform_value = component.split('=')[1] + print("Platform:", platform_value) + break + output_text = backend.name + '_' + circuit_name + '_' +platform_value + '_' +str(nqubits) + '.npz' + np.savez(output_text, result) + ''' + del(result) + # logs.log(mem_ava=mem_avail_list) + + if rank == 0: + logs.log(dtype=dtype, simulation_times=simulation_times) + logs.average("simulation_times") + if backend.expectation_flag is not None: + logs.log(dtype=dtype, expectation_result=expectation_result) + logs.average("expectation_result") + logs.dump() + return logs + +def qibotn_benchmark_single(nqubits, library, circuit_name, circuit_options=None, + library_options=None, precision=None, nreps=1, + filename=None): + """Runs benchmark for different quantum simulation libraries. + + See ``benchmarks/compare.py`` for documentation of each argument. + """ + from mpi4py import MPI # this line initializes MPI + import numpy as np + import cupy as cp + import socket + + try: + # Try to create MPI.COMM_WORLD + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + hostname = socket.gethostname() + device_id = rank % cp.cuda.runtime.getDeviceCount() + except MPI.Exception: + # MPI is not available or not launched deliberately, set rank to 0 + rank = 0 + logs = JsonLogger(filename) + + if rank == 0: + #logs = JsonLogger(filename) + logs.log(nqubits=nqubits, nreps=nreps) + + if rank == 0: + start_time = time.time() + from benchmarks import libraries + backend = libraries.get(library, library_options) + if rank == 0: + logs.log(import_time=time.time() - start_time) + logs.log(library_options=library_options) + if precision is not None: + + backend.set_precision(precision) + backend.expectation_flag + + if rank == 0: + logs.log(library=backend.name, + precision=backend.get_precision(), + device=backend.get_device(), + version=backend.__version__) + + from benchmarks import circuits + gates = circuits.get(circuit_name, nqubits, circuit_options) + #gates = circuits.get(circuit_name, nqubits, circuit_options, True) #use qibo gate + + if rank == 0: + logs.log(circuit=circuit_name, circuit_options=str(gates)) + start_time = time.time() + circuit = backend.from_qasm(gates.to_qasm()) + + if rank == 0: + logs.log(creation_time=time.time() - start_time) + start_time = time.time() + + # mem_avail = cp.cuda.Device(device_id).mem_info[0] + # formatted_string = f"{hostname}/{device_id}/{rank}/{mem_avail}" + # logs.log(hostname_id_rank_mem=formatted_string) + + result = backend(circuit) + + if rank == 0: + logs.log(dry_run_time=time.time() - start_time) + dtype = str(result.dtype) + del(result) + mem_avail_list=[] + if rank == 0: + simulation_times = [] + if backend.expectation_flag is not None: + expectation_result = [] + for _ in range(nreps): + # mem_avail = cp.cuda.Device(device_id).mem_info[0] + # formatted_string = f"{hostname}/{device_id}/{rank}/{mem_avail}" + # mem_avail_list.append(formatted_string) + + if rank == 0: + start_time = time.time() + # result = backend(circuit) + result=0 + if isinstance(result, cp.ndarray): + result = cp.asnumpy(result) + else: + result = np.array([result]) + + if rank == 0: + simulation_times.append(time.time() - start_time) + #if _==0: + #modified_string = library_options.replace("=", "_") + #modified_string = modified_string.replace(",", "") + #filename = modified_string+str(circuit.nqubits)+".dat" + #np.savetxt(filename,result) + #print(result) + if backend.expectation_flag is not None: + magnitude = np.abs(result[0]) + magnitude_list = magnitude.tolist() + + expectation_result.append(magnitude_list) + ''' + else: + components = library_options.split(',') + + # Iterate through the components to find the one that starts with "platform=" + for component in components: + if component.startswith("platform="): + # Extract the platform value + platform_value = component.split('=')[1] + print("Platform:", platform_value) + break + output_text = backend.name + '_' + circuit_name + '_' +platform_value + '_' +str(nqubits) + '.npz' + np.savez(output_text, result) + ''' + del(result) + # logs.log(mem_ava=mem_avail_list) + + if rank == 0: + logs.log(dtype=dtype, simulation_times=simulation_times) + logs.average("simulation_times") + if backend.expectation_flag is not None: + logs.log(dtype=dtype, expectation_result=expectation_result) + logs.average("expectation_result") + logs.dump() + return logs \ No newline at end of file diff --git a/compare.py b/compare.py index d6c0065..ce80b6e 100644 --- a/compare.py +++ b/compare.py @@ -1,6 +1,7 @@ """Launches the circuit benchmark script for user given arguments.""" import argparse -from benchmarks.scripts import library_benchmark +from benchmarks.scripts import library_benchmark, qibotn_benchmark + parser = argparse.ArgumentParser() @@ -38,8 +39,7 @@ help="Directory of file to save the logs in json format. " "If not given the logs will only be printed and not saved.") - if __name__ == "__main__": args = vars(parser.parse_args()) args["circuit_name"] = args.pop("circuit") - library_benchmark(**args) + qibotn_benchmark(**args) diff --git a/compare_qibotn.py b/compare_qibotn.py new file mode 100644 index 0000000..8831bbc --- /dev/null +++ b/compare_qibotn.py @@ -0,0 +1,46 @@ +"""Launches the circuit benchmark script for user given arguments.""" +import argparse +from benchmarks.scripts_qibotn import qibotn_benchmark_mpi + +# import logging +# logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M:%S') + +parser = argparse.ArgumentParser() +parser.add_argument("--nqubits", default=10, type=int, + help="Number of qubits in the circuit.") +parser.add_argument("--library", default="qibo", type=str, + help="Quantum simulation library to use in benchmark. " + "See README for the list of available libraries.") +parser.add_argument("--library-options", default=None, type=str, + help="String with options for the library. " + "It should have the form 'arg1=value1,arg2=value2,...'. " + "Each library supports different options.") + +parser.add_argument("--circuit", default="qft", type=str, + help="Type of circuit to use. See README for the list of " + "available circuits.") +parser.add_argument("--circuit-options", default=None, type=str, + help="String with options for circuit creation. " + "It should have the form 'arg1=value1,arg2=value2,...'. " + "See README for the list of arguments that are " + "available for each circuit.") +parser.add_argument("--precision", default=None, type=str, + help="Numerical precision of the simulation. " + "Choose between 'double' and 'single'.") + +parser.add_argument("--nreps", default=1, type=int, + help="Number of repetitions of the circuit execution. " + "Dry run is not included.") +#parser.add_argument("--transfer", action="store_true", +# help="If used the final state array is converted to numpy. " +# "If the simulation device is GPU this requires a " +# "transfer from GPU memory to CPU.") + +parser.add_argument("--filename", default=None, type=str, + help="Directory of file to save the logs in json format. " + "If not given the logs will only be printed and not saved.") + +if __name__ == "__main__": + args = vars(parser.parse_args()) + args["circuit_name"] = args.pop("circuit") + qibotn_benchmark_mpi(**args) \ No newline at end of file diff --git a/cu_tensornet_expectation.json b/cu_tensornet_expectation.json new file mode 100644 index 0000000..1c124dc --- /dev/null +++ b/cu_tensornet_expectation.json @@ -0,0 +1 @@ +{"MPI_enabled": false, "MPS_enabled": false, "NCCL_enabled": false, "expectation_enabled": true} diff --git a/cu_tensornet_mpi_expectation.json b/cu_tensornet_mpi_expectation.json new file mode 100644 index 0000000..079958f --- /dev/null +++ b/cu_tensornet_mpi_expectation.json @@ -0,0 +1 @@ +{"MPI_enabled": true, "MPS_enabled": false, "NCCL_enabled": false, "expectation_enabled": true} diff --git a/cu_tensornet_nccl_expectation.json b/cu_tensornet_nccl_expectation.json new file mode 100644 index 0000000..3dd9e5c --- /dev/null +++ b/cu_tensornet_nccl_expectation.json @@ -0,0 +1 @@ +{"MPI_enabled": false, "MPS_enabled": false, "NCCL_enabled": true, "expectation_enabled": true} diff --git a/environment.yml b/environment.yml index 142b656..82585da 100644 --- a/environment.yml +++ b/environment.yml @@ -6,9 +6,9 @@ dependencies: - pip - numpy=1.21 - pip: - - qibo==0.1.7rc1 - - qibotf==0.0.4rc1 - - qibojit==0.0.4rc0 + - qibo==0.1.11 + - qibotf==0.0.6 + - qibojit==0.0.7 - qiskit==0.34.1 - qiskit-aer-gpu==0.10.2 - qulacs==0.3.0 diff --git a/plot_pathfinding_metric.py b/plot_pathfinding_metric.py new file mode 100644 index 0000000..3c433c8 --- /dev/null +++ b/plot_pathfinding_metric.py @@ -0,0 +1,480 @@ +from plots.utils import load_data + +import matplotlib +import matplotlib.pyplot as plt +import seaborn as sns +from matplotlib.patches import Patch +matplotlib.rcParams['mathtext.fontset'] = 'cm' +matplotlib.rcParams['font.family'] = 'STIXGeneral' +import pandas as pd + +save = True # if ``True`` plots will be saved in the current directory as pdfs + + +def plot_scaling_expectation(input1, input2, input3, circuit, quantity, precision="double", fontsize=30, legend=True, save=False): + + + combine_data = input1 + combine_data2 = input2 + combine_data3 = input3 + + matplotlib.rcParams["font.size"] = fontsize + # Prepare GPU data + condition = (combine_data["circuit"] == circuit) & (combine_data["precision"] == precision) + condition2 = (combine_data2["circuit"] == circuit) & (combine_data2["precision"] == precision) + condition3 = (combine_data3["circuit"] == circuit) & (combine_data3["precision"] == precision) + + data = {} + data["qibotn MPI"] = combine_data[(combine_data["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition] + data["qibotn NCCL"] = combine_data[(combine_data["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json") & condition] + data["qibotn"] = combine_data[(combine_data["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json") & condition] + data["qibojit numba"] = combine_data[(combine_data["library_options"] == "backend=qibojit,platform=numba,expectation=XXXZ") & condition] + + data2 = {} + data2["qibotn MPI"] = combine_data2[(combine_data2["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition2] + data2["qibotn NCCL"] = combine_data2[(combine_data2["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json") & condition2] + data2["qibotn"] = combine_data2[(combine_data2["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json") & condition2] + data2["qibojit numba"] = combine_data2[(combine_data2["library_options"] == "backend=qibojit,platform=numba,expectation=XXXZ") & condition2] + + data3 = {} + data3["qibotn MPI"] = combine_data3[(combine_data3["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition3] + data3["qibotn NCCL"] = combine_data3[(combine_data3["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json") & condition3] + data3["qibotn"] = combine_data3[(combine_data3["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json") & condition3] + data3["qibojit numba"] = combine_data3[(combine_data3["library_options"] == "backend=qibojit,platform=numba,expectation=XXXZ") & condition3] + + # Plot data + cpu_cp = sns.color_palette("Oranges", 7) + gpu_cp = sns.color_palette("Purples", 7) + gpu_cp2 = sns.color_palette("Greens", 7) + gpu_cp3 = sns.color_palette("Reds", 7) + + plt.figure(figsize=(16, 9)) + + + plt.semilogy(data["qibotn"]["nqubits"], data["qibotn"][quantity], + color=cpu_cp[3], linewidth=1.5, label="1x1 gpu", marker=".", markersize=10) + plt.semilogy(data["qibotn MPI"]["nqubits"], data["qibotn MPI"][quantity], + color=gpu_cp[3], linewidth=1.5, label="1x8 gpu MPI", marker=".", markersize=10) + # plt.semilogy(data["qibotn NCCL"]["nqubits"], data["qibotn NCCL"][quantity], + # color=gpu_cp[5], linewidth=1.5, label="1x8 gpu NCCL", marker=".", markersize=10) + + plt.semilogy(data2["qibotn MPI"]["nqubits"], data2["qibotn MPI"][quantity], + color=gpu_cp2[3], linewidth=1.5, label="2x8 gpu MPI", marker=".", markersize=10) + plt.semilogy(data3["qibotn MPI"]["nqubits"], data3["qibotn MPI"][quantity], + color=gpu_cp3[3], linewidth=1.5, label="4x8 gpu MPI", marker=".", markersize=10) + + # plt.semilogy(data["qibojit numba"]["nqubits"], data["qibojit numba"][quantity], + # color=cpu_cp[2], linewidth=1.5, label="CPU", marker=".", markersize=10) + + # plt.ylim(bottom=1e-4, top=1e3) + # plt.xlim(left=0, right=1750) + # plt.xlim(left=0, right=60) + + #plt.xlim(right=31) + + plt.title(f"Expectation: {circuit}, depth {5}, {precision} precision") + plt.xlabel("Number of qubits") + if quantity == "total_dry_time": + plt.ylabel("Total dry run time (sec)") + elif quantity == "total_simulation_time": + plt.ylabel("Total simulation time (sec)") + elif quantity == "simulation_times_mean": + plt.ylabel("Simulation times mean (sec)") + if legend: + plt.legend(fontsize="small") + if save: + plt.savefig(f"qibo_scaling_{circuit}_{quantity}_{precision}_ex.pdf", bbox_inches="tight") + else: + plt.show() + +def plot_pathfinding_data(input1, input2, input3, circuit, quantity, precision="double", fontsize=30, legend=True, save=False): + num_reps=3 + num_pathfinding_per_rep=4 #equivalent to total number of GPUs + combine_data = input1 + combine_data2 = input2 + combine_data3 = input3 + + matplotlib.rcParams["font.size"] = fontsize + # Prepare GPU data + condition = (combine_data["circuit"] == circuit) & (combine_data["precision"] == precision) + condition2 = (combine_data2["circuit"] == circuit) & (combine_data2["precision"] == precision) + condition3 = (combine_data3["circuit"] == circuit) & (combine_data3["precision"] == precision) + + data = {} + data["qibotn MPI"] = combine_data[(combine_data["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition] + data2 = {} + data2["qibotn MPI"] = combine_data2[(combine_data2["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition2] + data3 = {} + data3["qibotn MPI"] = combine_data3[(combine_data3["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition3] + + # Plot data + + color_1x1 = sns.color_palette("Oranges", 7) + color_1x4 = sns.color_palette("Purples", 7) + color_2x4 = sns.color_palette("Greens", 7) + color_4x4 = sns.color_palette("Reds", 7) + + def extract_metric(data,rep_index,metric_of_interest): + #metric of interest 0: num slices, 1: opt cost, 2: largest intermediate, 3: time + metric_list_total=[] + metric_max=[] + metric_min=[] + metric_max_index=[] + metric_min_index=[] + for each_record in range(len(data["qibotn MPI"]['nqubits'])): + each_rep = data["qibotn MPI"][quantity][each_record][rep_index][0] + split_data = [each_rep[i:i + 4] for i in range(0, len(each_rep), 4)] + metric_list=[] + for each_gpu in range(len(split_data)): + metric_list.append(split_data[each_gpu][metric_of_interest]) + metric_list_total.append(metric_list) + max_value = max(metric_list) + max_value_index = metric_list.index(max_value) + min_value = min(metric_list) + min_value_index = metric_list.index(min_value) + metric_max.append(max_value) + metric_min.append(min_value) + metric_max_index.append(max_value_index) + metric_min_index.append(min_value_index) + + return metric_list_total, metric_max, metric_min, metric_max_index, metric_min_index + + def extract_metric_with_index_of_interest(data,rep_index,metric_of_interest,index_of_interest): + #metric of interest 0: num slices, 1: opt cost, 2: largest intermediate, 3: time + metric_list_total=[] + metric_max=[] + metric_min=[] + metric_selected=[] + + for each_record in range(len(data["qibotn MPI"]['nqubits'])): + each_rep = data["qibotn MPI"][quantity][each_record][rep_index][0] + split_data = [each_rep[i:i + 4] for i in range(0, len(each_rep), 4)] + metric_list=[] + for each_gpu in range(len(split_data)): + metric_list.append(split_data[each_gpu][metric_of_interest]) + metric_list_total.append(metric_list) + max_value = max(metric_list) + interest_value = metric_list[(index_of_interest[each_record])] + min_value = min(metric_list) + + metric_max.append(max_value) + metric_min.append(min_value) + metric_selected.append(interest_value) + + return metric_list_total, metric_max, metric_min, metric_selected + + rep_data = 0 + rep_data2 = 1 + rep_data3 = 0 + + data_opt_cost_original, max_cost, min_cost,max_cost_index, min_cost_index = extract_metric(data,rep_data,1) + data_opt_cost = [list(i) for i in zip(*data_opt_cost_original)] + + data_opt_cost_original2, max_cost2, min_cost2, max_cost_index2, min_cost_index2 = extract_metric(data2,rep_data2,1) + data_opt_cost2 = [list(i) for i in zip(*data_opt_cost_original2)] + + data_opt_cost_original3, max_cost3, min_cost3, max_cost_index3, min_cost_index3 = extract_metric(data3,rep_data3,1) + data_opt_cost3 = [list(i) for i in zip(*data_opt_cost_original3)] + + ##### + data_num_slices_original, _, _,selected1 = extract_metric_with_index_of_interest(data,rep_data,0,min_cost_index) + data_num_slices = [list(i) for i in zip(*data_num_slices_original)] + + data_num_slices_original2, _, _, selected2= extract_metric_with_index_of_interest(data2,rep_data2,0,min_cost_index2) + data_num_slices2 = [list(i) for i in zip(*data_num_slices_original2)] + + data_num_slices_original3, _, _, selected3 = extract_metric_with_index_of_interest(data3,rep_data3,0,min_cost_index3) + data_num_slices3 = [list(i) for i in zip(*data_num_slices_original3)] + + ####_time + data_time_original, max_cost_time, min_cost_time,max_cost_index_time, min_cost_index_time = extract_metric(data,rep_data,3) + data_time = [list(i) for i in zip(*data_time_original)] + + data_time_original2, max_cost2_time, min_cost2_time, max_cost_index2_time, min_cost_index2_time = extract_metric(data2,rep_data2,3) + data_time2 = [list(i) for i in zip(*data_time_original2)] + + data_time_original3, max_cost3_time, min_cost3_time, max_cost_index3_time, min_cost_index3_time = extract_metric(data3,rep_data3,3) + data_time3 = [list(i) for i in zip(*data_time_original3)] + + # for i in range(len(data_opt_cost)): + # print("max", max_cost[i],"min",min_cost[i],data_opt_cost[i]) + # print("1x4",data["qibotn MPI"]["nqubits"]) + # print("2x4",data2["qibotn MPI"]["nqubits"]) + # print("4x4",data3["qibotn MPI"]["nqubits"]) + + + #### PLOT COST OF PATH #### + plt.figure(figsize=(16, 9)) + + color4x4=3 + # 4x4 + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[0], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[1], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[2], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[3], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[4], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[5], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[6], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[7], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[8], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[9], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[10], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[11], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[12], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[13], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[14], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_opt_cost3[15], + color=color_4x4[color4x4], marker=".", s=100) + + # 2x4 + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[0], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[1], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[2], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[3], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[4], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[5], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[6], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_opt_cost2[7], + color=color_2x4[2], marker=".", s=100) + + + + # 1x4 + plt.scatter(data["qibotn MPI"]["nqubits"], data_opt_cost[0], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_opt_cost[1], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_opt_cost[2], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_opt_cost[3], + color=color_1x4[2],marker=".", s=100) + + # Best path + plt.semilogy(data["qibotn MPI"]["nqubits"], min_cost, + color=color_1x4[3], label="1x4 selected", linewidth=1.5, marker="x", markersize=10) + # Best path + plt.semilogy(data2["qibotn MPI"]["nqubits"], min_cost2, + color=color_2x4[3], label="2x4 selected",linewidth=1.5, marker="x", markersize=10) + # Best path + plt.semilogy(data3["qibotn MPI"]["nqubits"], min_cost3, + color=color_4x4[3], label="4x4 selected",linewidth=1.5, marker="x", markersize=10) + + plt.xlim(left=0, right=305) + + plt.title(f"Cost of Paths Found: {circuit}, depth {5}, {precision} precision") + plt.xlabel("Number of qubits") + plt.ylabel("FLOP") + if legend: + plt.legend(fontsize="small") + if save: + plt.savefig(f"qibo_scaling_{circuit}_{quantity}_{precision}_pathfinding.pdf", bbox_inches="tight") + else: + plt.show() + +#### PLOT NUM OF SLICES #### + plt.figure(figsize=(16, 9)) + + color4x4=3 + # 4x4 + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[0], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[1], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[2], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[3], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[4], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[5], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[6], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[7], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[8], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[9], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[10], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[11], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[12], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[13], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[14], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_num_slices3[15], + color=color_4x4[color4x4], marker=".", s=100) + + + # 2x4 + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[0], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[1], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[2], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[3], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[4], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[5], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[6], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_num_slices2[7], + color=color_2x4[2], marker=".", s=100) + + + # 1x4 + plt.scatter(data["qibotn MPI"]["nqubits"], data_num_slices[0], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_num_slices[1], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_num_slices[2], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_num_slices[3], + color=color_1x4[2],marker=".", s=100) + + # Best path + plt.semilogy(data["qibotn MPI"]["nqubits"], selected1, + color=color_1x4[3], label="1x4 selected", linewidth=1.5, marker="x", markersize=10) + # Best path + plt.semilogy(data2["qibotn MPI"]["nqubits"], selected2, + color=color_2x4[3], label="2x4 selected",linewidth=1.5, marker="x", markersize=10) + # Best path + plt.semilogy(data3["qibotn MPI"]["nqubits"], selected3, + color=color_4x4[3], label="4x4 selected",linewidth=1.5, marker="x", markersize=10) + + plt.xlim(left=0, right=305) + + plt.title(f"Slicing: {circuit}, depth {5}, {precision} precision") + plt.xlabel("Number of qubits") + plt.ylabel("Number of slices") + if legend: + plt.legend(fontsize="small") + if save: + plt.savefig(f"qibo_scaling_{circuit}_{quantity}_{precision}_slicing.pdf", bbox_inches="tight") + else: + plt.show() + +#### PLOT Time PF #### + plt.figure(figsize=(16, 9)) + + color4x4=3 + # 4x4 + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[0], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[1], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[2], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[3], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[4], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[5], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[6], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[7], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[8], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[9], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[10], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[11], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[12], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[13], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[14], + color=color_4x4[color4x4], marker=".", s=100) + plt.scatter(data3["qibotn MPI"]["nqubits"], data_time3[15], + color=color_4x4[color4x4], marker=".", s=100) + + + # 2x4 + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[0], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[1], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[2], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[3], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[4], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[5], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[6], + color=color_2x4[2], marker=".", s=100) + plt.scatter(data2["qibotn MPI"]["nqubits"], data_time2[7], + color=color_2x4[2], marker=".", s=100) + + + # 1x4 + plt.scatter(data["qibotn MPI"]["nqubits"], data_time[0], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_time[1], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_time[2], + color=color_1x4[2], marker=".", s=100) + plt.scatter(data["qibotn MPI"]["nqubits"], data_time[3], + color=color_1x4[2],marker=".", s=100) + + # Best path + plt.semilogy(data["qibotn MPI"]["nqubits"], max_cost_time, + color=color_1x4[3], label="1x4 selected", linewidth=1.5, marker="x", markersize=10) + # Best path + plt.semilogy(data2["qibotn MPI"]["nqubits"], max_cost2_time, + color=color_2x4[3], label="2x4 selected",linewidth=1.5, marker="x", markersize=10) + # Best path + plt.semilogy(data3["qibotn MPI"]["nqubits"], max_cost3_time, + color=color_4x4[3], label="4x4 selected",linewidth=1.5, marker="x", markersize=10) + + plt.xlim(left=0, right=305) + + plt.title(f"Pathfinding Time: {circuit}, depth {5}, {precision} precision") + plt.xlabel("Number of qubits") + plt.ylabel("Pathfinding Time (sec)") + if legend: + plt.legend(fontsize="small") + if save: + plt.savefig(f"qibo_scaling_{circuit}_{quantity}_{precision}_pftime.pdf", bbox_inches="tight") + else: + plt.show() + +data1 = load_data("/home/project/11003124/tankya/costa1/qibojit-benchmarks/qibotn_pathfind_double_1x4_variational_d5.dat") +data2 = load_data("/home/project/11003124/tankya/costa1/qibojit-benchmarks/qibotn_pathfind_double_2x4_variational_d5.dat") +data3 = load_data("/home/project/11003124/tankya/costa1/qibojit-benchmarks/qibotn_pathfind_double_4x4_variational_d5_old.dat") + +plot_pathfinding_data(data1,data2,data3,"variational", "expectation_result","double", legend=True, save=save) diff --git a/plot_result_quad.py b/plot_result_quad.py new file mode 100644 index 0000000..cfcdf61 --- /dev/null +++ b/plot_result_quad.py @@ -0,0 +1,135 @@ +from plots.utils import load_data + +import matplotlib +import matplotlib.pyplot as plt +import seaborn as sns +from matplotlib.patches import Patch +matplotlib.rcParams['mathtext.fontset'] = 'cm' +matplotlib.rcParams['font.family'] = 'STIXGeneral' +import pandas as pd + +save = True # if ``True`` plots will be saved in the current directory as pdfs + + +def plot_scaling_expectation(input1, input2, input3,input4, circuit, quantity, precision="double", fontsize=30, legend=True, save=False): + + + combine_data = input1 + combine_data2 = input2 + combine_data3 = input3 + combine_data4 = input4 + + matplotlib.rcParams["font.size"] = fontsize + # Prepare GPU data + condition = (combine_data["circuit"] == circuit) & (combine_data["precision"] == precision) + condition2 = (combine_data2["circuit"] == circuit) & (combine_data2["precision"] == precision) + condition3 = (combine_data3["circuit"] == circuit) & (combine_data3["precision"] == precision) + condition4 = (combine_data4["circuit"] == circuit) & (combine_data4["precision"] == precision) + + data = {} + data["qibotn MPI"] = combine_data[(combine_data["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition] + data["qibotn NCCL"] = combine_data[(combine_data["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json") & condition] + data["qibotn"] = combine_data[(combine_data["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json") & condition] + data["qibojit numba"] = combine_data[(combine_data["library_options"] == "backend=qibojit,platform=numba,expectation=XXXZ") & condition] + + data2 = {} + data2["qibotn MPI"] = combine_data2[(combine_data2["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition2] + data2["qibotn NCCL"] = combine_data2[(combine_data2["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json") & condition2] + data2["qibotn"] = combine_data2[(combine_data2["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json") & condition2] + data2["qibojit numba"] = combine_data2[(combine_data2["library_options"] == "backend=qibojit,platform=numba,expectation=XXXZ") & condition2] + + data3 = {} + data3["qibotn MPI"] = combine_data3[(combine_data3["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition3] + data3["qibotn NCCL"] = combine_data3[(combine_data3["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json") & condition3] + data3["qibotn"] = combine_data3[(combine_data3["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json") & condition3] + data3["qibojit numba"] = combine_data3[(combine_data3["library_options"] == "backend=qibojit,platform=numba,expectation=XXXZ") & condition3] + + data4 = {} + data4["qibotn MPI"] = combine_data4[(combine_data4["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json") & condition4] + data4["qibotn NCCL"] = combine_data4[(combine_data4["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json") & condition4] + data4["qibotn"] = combine_data4[(combine_data4["library_options"] == "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json") & condition4] + data4["qibojit numba"] = combine_data4[(combine_data4["library_options"] == "backend=qibojit,platform=numba,expectation=XXXZ") & condition4] + + # Plot data + cpu_cp = sns.color_palette("Oranges", 7) + gpu_cp = sns.color_palette("Purples", 7) + gpu_cp2 = sns.color_palette("Greens", 7) + gpu_cp3 = sns.color_palette("Reds", 7) + gpu_cp4 = sns.color_palette("Blues", 7) + plt.figure(figsize=(16, 9)) + + # 24 hours in seconds + seconds_in_24_hours = 24 * 60 * 60 + + # Plotting the horizontal dashed line + plt.axhline(y=seconds_in_24_hours, color='r', linestyle='--', linewidth=1.5, label='24 hours') + + plt.semilogy(data["qibotn"]["nqubits"], data["qibotn"][quantity], + color=cpu_cp[3], linewidth=1.5, label="1x1 gpu", marker=".", markersize=10) + plt.semilogy(data2["qibotn MPI"]["nqubits"], data2["qibotn MPI"][quantity], + color=gpu_cp[3], linewidth=1.5, label="1x4 gpu MPI", marker=".", markersize=10) + # plt.semilogy(data["qibotn NCCL"]["nqubits"], data["qibotn NCCL"][quantity], + # color=gpu_cp[5], linewidth=1.5, label="1x8 gpu NCCL", marker=".", markersize=10) + + plt.semilogy(data3["qibotn MPI"]["nqubits"], data3["qibotn MPI"][quantity], + color=gpu_cp2[3], linewidth=1.5, label="2x4 gpu MPI", marker=".", markersize=10) + plt.semilogy(data4["qibotn MPI"]["nqubits"], data4["qibotn MPI"][quantity], + color=gpu_cp3[3], linewidth=1.5, label="4x4 gpu MPI", marker=".", markersize=10) + # plt.semilogy(data4["qibotn MPI"]["nqubits"], data4["qibotn MPI"][quantity], + # color=gpu_cp5[3], linewidth=1.5, label="4x8 gpu MPI", marker=".", markersize=10) + + # plt.semilogy(data["qibojit numba"]["nqubits"], data["qibojit numba"][quantity], + # color=cpu_cp[2], linewidth=1.5, label="CPU", marker=".", markersize=10) + + # plt.ylim(bottom=1e-4, top=1e3) + # plt.xlim(left=0, right=1750) + # plt.xlim(left=0, right=60) + + #plt.xlim(right=31) + + plt.title(f"Expectation: {circuit}, depth {5}, {precision} precision") + plt.xlabel("Number of qubits") + if quantity == "total_dry_time": + plt.ylabel("Total dry run time (sec)") + elif quantity == "total_simulation_time": + plt.ylabel("Total simulation time (sec)") + elif quantity == "simulation_times_mean": + plt.ylabel("Simulation times mean (sec)") + if legend: + plt.legend(fontsize="small") + if save: + plt.savefig(f"qibo_scaling_{circuit}_{quantity}_{precision}_ex.pdf", bbox_inches="tight") + else: + plt.show() + + +# data1 = load_data("/home/user3/qibotn_benchmarks/qibojit-benchmarks/qibotn_expectation_double_1x8_var.dat") +# plot_scaling_expectation(data1,"variational", "simulation_times_mean","double", legend=True, save=save) + +# data1 = load_data("/home/user3/qibotn_benchmarks/qibojit-benchmarks/qibotn_expectation_double_1x8_sup.dat") +# plot_scaling_expectation(data1,"supremacy", "simulation_times_mean","double", legend=True, save=save) + +# data1 = load_data("/home/user3/qibotn_benchmarks/qibojit-benchmarks/qibotn_expectation_double_1x8_qft.dat") +# data1 = load_data("/home/user3/qibotn_benchmarks/qibojit-benchmarks/qibotn_expectation_double_1x8_sup.dat") +# data1 = load_data("/home/user3/qibotn_benchmarks/qibojit-benchmarks/qibotn_expectation_double_1x8_var.dat") +data1 = load_data("/home/project/11003124/tankya/costa1/qibojit-benchmarks/qibotn_expectation_double_1x1_variational_d5.dat") +data2 = load_data("/home/project/11003124/tankya/costa1/qibojit-benchmarks/qibotn_expectation_double_1x4_variational_d5.dat") +data3 = load_data("/home/project/11003124/tankya/costa1/qibojit-benchmarks/qibotn_expectation_double_2x4_variational_d5.dat") +data4 = load_data("/home/project/11003124/tankya/costa1/qibojit-benchmarks/qibotn_expectation_double_4x4_variational_d5.dat") + +plot_scaling_expectation(data1,data2,data3,data4,"variational", "simulation_times_mean","double", legend=True, save=save) + +#1x4 Missing value + +{"datetime": "2024-07-13 01:38:18", "nqubits": 10, "nreps": 1, "import_time": 2.0695817470550537, "library_options": "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json", "library": "qibo", "precision": "double", "device": "/CPU:0", "version": "0.2.5", "circuit": "variational", "circuit_options": "nqubits=10, nlayers=5, seed=123", "creation_time": 0.12717008590698242, "dry_run_time": 4.76837158203125e-07, "dtype": "complex128", "simulation_times": [2.722426176071167], "simulation_times_mean": 2.722426176071167, "simulation_times_std": 0.0, "expectation_result": [[[0.044218473681389266]]], "expectation_result_mean": 0.044218473681389266, "expectation_result_std": 0.0} + +{"datetime": "2024-07-13 01:38:18", "nqubits": 40, "nreps": 1, "import_time": 2.0695817470550537, "library_options": "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json", "library": "qibo", "precision": "double", "device": "/CPU:0", "version": "0.2.5", "circuit": "variational", "circuit_options": "nqubits=40, nlayers=5, seed=123", "creation_time": 0.12717008590698242, "dry_run_time": 4.76837158203125e-07, "dtype": "complex128", "simulation_times": [92.54630327224731], "simulation_times_mean": 92.54630327224731, "simulation_times_std": 0.0, "expectation_result": [[[1.0185800644540888e-06]]], "expectation_result_mean": 1.0185800644540888e-06, "expectation_result_std": 0.0} + +{"datetime": "2024-07-13 01:38:18", "nqubits": 60, "nreps": 1, "import_time": 2.0695817470550537, "library_options": "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json", "library": "qibo", "precision": "double", "device": "/CPU:0", "version": "0.2.5", "circuit": "variational", "circuit_options": "nqubits=60, nlayers=5, seed=123", "creation_time": 0.12717008590698242, "dry_run_time": 4.76837158203125e-07, "dtype": "complex128", "simulation_times": [271.3857560157776], "simulation_times_mean": 271.3857560157776, "simulation_times_std": 0.0, "expectation_result": [[[5.877344374846953e-11]]], "expectation_result_mean": 5.877344374846953e-11, "expectation_result_std": 0.0} + +{"datetime": "2024-07-13 01:38:18", "nqubits": 80, "nreps": 1, "import_time": 2.0695817470550537, "library_options": "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json", "library": "qibo", "precision": "double", "device": "/CPU:0", "version": "0.2.5", "circuit": "variational", "circuit_options": "nqubits=80, nlayers=5, seed=123", "creation_time": 0.12717008590698242, "dry_run_time": 4.76837158203125e-07, "dtype": "complex128", "simulation_times": [1084.1304409503937], "simulation_times_mean": 1084.1304409503937, "simulation_times_std": 0.0, "expectation_result": [[[5.36328554751669e-16]]], "expectation_result_mean": 5.36328554751669e-16, "expectation_result_std": 0.0} + +{"datetime": "2024-07-13 01:38:18", "nqubits": 110, "nreps": 1, "import_time": 2.0695817470550537, "library_options": "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json", "library": "qibo", "precision": "double", "device": "/CPU:0", "version": "0.2.5", "circuit": "variational", "circuit_options": "nqubits=110, nlayers=5, seed=123", "creation_time": 0.12717008590698242, "dry_run_time": 4.76837158203125e-07, "dtype": "complex128", "simulation_times": [9504.664041519165], "simulation_times_mean": 9504.664041519165, "simulation_times_std": 0.0, "expectation_result": [[[3.446458226795824e-19]]], "expectation_result_mean": 3.446458226795824e-19, "expectation_result_std": 0.0} + +{"datetime": "2024-07-13 01:38:18", "nqubits": 130, "nreps": 1, "import_time": 2.0695817470550537, "library_options": "backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json", "library": "qibo", "precision": "double", "device": "/CPU:0", "version": "0.2.5", "circuit": "variational", "circuit_options": "nqubits=130, nlayers=5, seed=123", "creation_time": 0.12717008590698242, "dry_run_time": 4.76837158203125e-07, "dtype": "complex128", "simulation_times": [14543.339746236801], "simulation_times_mean": 14543.339746236801, "simulation_times_std": 0.0, "expectation_result": [[[1.789240796703424e-20]]], "expectation_result_mean": 1.789240796703424e-20, "expectation_result_std": 0.0} + diff --git a/scripts/cu_tensornet_expectation.json b/scripts/cu_tensornet_expectation.json new file mode 100644 index 0000000..1c124dc --- /dev/null +++ b/scripts/cu_tensornet_expectation.json @@ -0,0 +1 @@ +{"MPI_enabled": false, "MPS_enabled": false, "NCCL_enabled": false, "expectation_enabled": true} diff --git a/scripts/cu_tensornet_mpi_expectation.json b/scripts/cu_tensornet_mpi_expectation.json new file mode 100644 index 0000000..079958f --- /dev/null +++ b/scripts/cu_tensornet_mpi_expectation.json @@ -0,0 +1 @@ +{"MPI_enabled": true, "MPS_enabled": false, "NCCL_enabled": false, "expectation_enabled": true} diff --git a/scripts/cu_tensornet_nccl_expectation.json b/scripts/cu_tensornet_nccl_expectation.json new file mode 100644 index 0000000..3dd9e5c --- /dev/null +++ b/scripts/cu_tensornet_nccl_expectation.json @@ -0,0 +1 @@ +{"MPI_enabled": false, "MPS_enabled": false, "NCCL_enabled": true, "expectation_enabled": true} diff --git a/scripts/qibotn.sh b/scripts/qibotn.sh new file mode 100755 index 0000000..378e134 --- /dev/null +++ b/scripts/qibotn.sh @@ -0,0 +1,36 @@ +#! /usr/bin/bash +# Script for 2-nodes-4-GPUs (2x4) configuration +# Command-line parameters +: "${circuit:=variational}" +: "${precision:=double}" +: "${nreps:=3}" +: "${filename:=qibotn_expectation_double_2x4.dat}" + +node_list=/nodelist_2x4 #file containing the IP address of the resources, omit this if it is running on single-node-multi-gpu + +for (nqubits = 10; nqubits <= 8000; nqubits += 100) +do + #echo '{"MPI_enabled": true, "MPS_enabled": false, "NCCL_enabled": false, "expectation_enabled": true}' > cu_tensornet_mpi_expectation.json #can be pre-generated or can include it in script. Here is using pre-generated. + mpirun -np 8 -hostfile $node_list python compare.py --circuit variational --circuit-options nlayers=3 --nqubits 4$nqubits --filename $filename \ + --library-options backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_mpi_expectation.json \ + --nreps $nreps --precision $precision +echo + #echo '{"MPI_enabled": false, "MPS_enabled": false, "NCCL_enabled": true, "expectation_enabled": true}' > cu_tensornet_nccl_expectation.json + mpirun -np 8 -hostfile $node_list python compare.py --circuit variational --circuit-options nlayers=3 --nqubits $nqubits --filename $filename \ + --library-options backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_nccl_expectation.json \ + --nreps $nreps --precision $precision +echo + #echo '{"MPI_enabled": false, "MPS_enabled": false, "NCCL_enabled": false, "expectation_enabled": true}' > cu_tensornet_expectation.json + python compare.py --circuit variational --circuit-options nlayers=3 --nqubits $nqubits --filename $filename \ + --library-options backend=qibotn,platform=cutensornet,computation_settings=cu_tensornet_expectation.json \ + --nreps $nreps --precision $precision +echo + python compare.py --circuit variational --circuit-options nlayers=3 --nqubits $nqubits --filename $filename \ + --library-options backend=qibojit,platform=numba,expectation="XXXZ" \ + --nreps $nreps --precision $precision +echo +done + +: <<'END_COMMENT' + +END_COMMENT