Issue with Pennylane wrapped Numpy import

I am creating a list of graphs as a part of this demonstration. I have some data from which I am generating some graphs. Here’s the code for it:

def generate_graphs(n_graphs, n_nodes):

datapoints = []
for _ in range(n_graphs):

    #load the processed data
    data_graph = get_data(n_nodes, full_data)[0]
    
    #Arrays used to assign weights to the graphs
    importance = get_data(n_nodes, full_data)[1]
    duration = get_data(n_nodes, full_data)[2]
    
    
    graph_point = nx.Graph()
    graph_point.add_nodes_from(np.arange(n_nodes))
    for i in range(n_nodes):
        for j in range(i+1, n_nodes):
            graph_point.add_edge(i, j, weight = np.minimum(importance.data[i]*duration.data[j], importance.data[j]*duration.data[i]))
    datapoints.append(graph_point)
return datapoints

After this, I move on to draw the graphs as done in the tutorial:

# Define parameters of the graphs
n_graphs = 10
n_nodes = 3
graphs = generate_graphs(n_graphs, n_nodes)
nx.draw(graphs[0])

This is the output that I get:
image

Now, I am not sure why I don’t see the edges. In addition, I have 4 nodes instead of 3. Besides, when I import numpy as np instead of from pennylane import numpy as np, I do not face this issue and the graph comes out correctly. Please let me know where I might be going wrong.

Hi @kabirkhanna85, thanks for sharing your work!

We’ve taken a look at your generate_graphs function and it seems to work :slight_smile: Since we don’t have your data or the get_data_4cut_SC1 function you are using we’ve replaced importance and duration with a numpy array of random floats:

def check_code_with_random_weights(n_graphs, n_nodes):
    
    datapoints = []
    for _ in range(n_graphs):

        importance = np.random.uniform(low=0, high=1, size=(n_nodes,))
        duration = np.random.uniform(low=0, high=1, size=(n_nodes,))
        
        graph_point = nx.Graph()
        graph_point.add_nodes_from(np.arange(n_nodes))
        for i in range(n_nodes):
            for j in range(i+1, n_nodes):
                graph_point.add_edge(i, j, weight = np.minimum(importance[i]*duration[j], importance[j]*duration[i]))
        datapoints.append(graph_point)

    return datapoints

then drawing the graphs using the same code as you have been using gives a graph of 3 nodes and edges are displayed:

With this, it would be worth checking the form of the data you are using for your graph edges and also making sure your pennylane install is up to date using: pip install pennylane --upgrade.

Let us know if you have any further questions!

This is what happens when I run the exact same code:

There’s always double the number of nodes. The connected subgraph is what the code should give out but it gives these extra disconnected nodes. However, the edge data reads correctly as you can see from the screenshot.

Besides as I pointed out earlier, when I import numpy as np I get the right output, even for my original input with the data. Here’s the output with the import numpy as np using the code that you ran:

I am not sure what is the issue. I tried running this code with pennylane version 13.0 and 14.0 and I face the same issue. I set up a new environment and started fresh by downloading only the required packages once again. Still the same issue.

Okay so I think I figured what the issue is. G.add_nodes_from seems to require a numpy array and does not work with the tensor that pennylane generates with np.arange. This works instead:

def check_code_with_random_weights(n_graphs, n_nodes):

datapoints = []
for _ in range(n_graphs):

    importance = np.random.uniform(low=0, high=1, size=(n_nodes,))
    duration = np.random.uniform(low=0, high=1, size=(n_nodes,))
    
    
    graph_point = nx.Graph()
    
    
    graph_point.add_nodes_from(range(n_nodes))
    for i in range(n_nodes):
        for j in range(i+1, n_nodes):
            graph_point.add_edge(i, j, weight = np.minimum(importance[i]*duration[j], importance[j]*duration[i]))
    datapoints.append(graph_point)

return datapoints

Hi @kabirkhanna85, sorry that the from pennylane import numpy as np case was overlooked. We have since replicated the graph output with double the nodes.

When adding tensor objects as nodes using the add_nodes_from() method, it looks to be well behaved:

>>> graph_point.add_nodes_from(np.arange(3))
>>> print(graph_point.nodes)

[tensor(0, requires_grad=True), tensor(1, requires_grad=True), tensor(2, requires_grad=True)]

giving 3 nodes as expected.

The issue seems to be in the nx.draw() method when the nodes are tensor objects. We will look into this further and let you know what we find.

Thanks again for pointing this out!

Sure! Thank you for looking into it :slight_smile:

Hi @kabirkhanna85, following on from our discussion an issue has been raised here.

Thanks for sharing your results on this, let us know if there’s anything else we can help out with!