Path: blob/main/qaoa-for-max-cut/Example-02-step-1.py
579 views
# SPDX-License-Identifier: Apache-2.0 AND CC-BY-NC-4.01#2# Licensed under the Apache License, Version 2.0 (the "License");3# you may not use this file except in compliance with the License.4# You may obtain a copy of the License at5#6# http://www.apache.org/licenses/LICENSE-2.07#8# Unless required by applicable law or agreed to in writing, software9# distributed under the License is distributed on an "AS IS" BASIS,10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11# See the License for the specific language governing permissions and12# limitations under the License.1314# Defining functions to generate the Hamiltonian and Kernel for a given graph15# Necessary packages16import networkx as nx17from networkx import algorithms18from networkx.algorithms import community19import cudaq20from cudaq import spin21from cudaq.qis import *22import numpy as np23from typing import List, Tuple24from mpi4py import MPI2526# Getting information about platform27cudaq.set_target("nvidia")28target = cudaq.get_target()2930# Setting up MPI31comm = MPI.COMM_WORLD32rank = comm.Get_rank()33num_qpus = comm.Get_size()3435#######################################################36# Step 137#######################################################38# Function to return a dictionary of subgraphs of the input graph39# using the greedy modularity maximization algorithm4041def subgraphpartition(G,n):42"""Divide the graph up into at most n subgraphs4344Parameters45----------46G: networkX.Graph47Graph that we want to subdivdie48n : int49n is the maximum number of subgraphs in the partition50Returns51-------52dict of str : networkX.Graph53Dictionary of networkX graphs with a string as the key54"""55greedy_partition = community.greedy_modularity_communities(G, weight=None, resolution=1.1, cutoff=1, best_n=n)56number_of_subgraphs = len(greedy_partition)5758graph_dictionary = {}59graph_names=[]60for i in range(number_of_subgraphs):61name='G'+str(i)62graph_names.append(name)6364for i in range(number_of_subgraphs):65nodelist = sorted(list(greedy_partition[i]))66graph_dictionary[graph_names[i]] = nx.subgraph(G, nodelist)6768return(graph_dictionary)697071if rank ==0:72# Defining the example graph73# Random graph parameters74n = 30 # numnber of nodes75m = 70 # number of edges76seed = 20160 # seed random number generators for reproducibility7778# Use seed for reproducibility79sampleGraph2 = nx.gnm_random_graph(n, m, seed=seed)8081# Subdividing the graph82num_subgraphs_limit = min(12, len(sampleGraph2.nodes())) # maximum number of subgraphs for the partition83subgraph_dictionary = subgraphpartition(sampleGraph2,num_subgraphs_limit)8485# Assign the subgraphs to the QPUs86number_of_subgraphs = len(sorted(subgraph_dictionary))87number_of_subgraphs_per_qpu = int(np.ceil(number_of_subgraphs/num_qpus))8889keys_on_qpu ={}9091for q in range(num_qpus):92keys_on_qpu[q]=[]93for k in range(number_of_subgraphs_per_qpu):94if (k*num_qpus+q < number_of_subgraphs):95key = sorted(subgraph_dictionary)[k*num_qpus+q]96keys_on_qpu[q].append(key)97print(keys_on_qpu[q],'=subgraph problems to be computed on processor',q)9899# Distribute the subgraph data to the QPUs100for i in range(num_qpus):101subgraph_to_qpu ={}102for k in keys_on_qpu[i]:103subgraph_to_qpu[k]= subgraph_dictionary[k]104if i != 0:105comm.send(subgraph_to_qpu, dest=i, tag=rank)106print("{} sent by processor {}".format(subgraph_to_qpu, rank))107else:108assigned_subgraph_dictionary = subgraph_to_qpu109else:110# Receive the subgraph data111assigned_subgraph_dictionary= comm.recv(source=0, tag=0)112print("Processor {} received {} from processor {}".format(rank,assigned_subgraph_dictionary, 0))113114115116117