Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PyG #93

Merged
merged 59 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
5d82d97
change python tests/test_a_star/prepare_for_test.py to python pygmtoo…
heatingma Aug 1, 2023
4c05275
add bdist_wheel
heatingma Aug 1, 2023
4155230
delete test/test_a_star
heatingma Aug 1, 2023
b083a7b
add astar ori_files
heatingma Aug 1, 2023
678a49e
Create publish_req.txt
heatingma Aug 1, 2023
6cf8381
Delete a_star.tar.gz
heatingma Aug 1, 2023
3678388
version is a23
heatingma Aug 1, 2023
ef3f41c
Update setup.py
heatingma Aug 1, 2023
439c757
delete some notes
heatingma Aug 1, 2023
6e0ea0e
add alternate url to fix download problem
heatingma Aug 2, 2023
18d3873
add return
heatingma Aug 3, 2023
be38bf0
fix the md5 problem with genn_astar pretrained models
heatingma Aug 3, 2023
d07498e
add the missed ','
heatingma Aug 3, 2023
b5f3133
fix the "diff=200.0" problem
heatingma Aug 3, 2023
57230e8
swap the url and the url_alter
heatingma Aug 3, 2023
55379dc
change the astar_pretrain_path
heatingma Aug 3, 2023
bde8106
Revert "swap the url and the url_alter"
heatingma Aug 4, 2023
220f782
Revert "change the astar_pretrain_path"
heatingma Aug 4, 2023
3143592
change the pretrained path
heatingma Aug 4, 2023
61181f8
only small files has url_alter
heatingma Aug 4, 2023
0642a14
add new url for pretrained modles
heatingma Aug 4, 2023
0eec2ee
add new download pretrained models' paths for jittor backend
heatingma Aug 4, 2023
52143ae
add new download pretrained models' paths for jittor backend
heatingma Aug 4, 2023
329a115
add new download pretrained models' paths for jittor backend
heatingma Aug 4, 2023
f3a78c0
add new download path for pytorch backend pretrained models
heatingma Aug 4, 2023
d8f821b
add new download path for paddle backend
heatingma Aug 4, 2023
c368697
delete some unused url
heatingma Aug 5, 2023
0ae85c7
add new alternate download path for cie and pca
heatingma Aug 5, 2023
35a4e02
don't test neural_solvers now
heatingma Aug 5, 2023
6f42e7c
only test neural_solvers
heatingma Aug 5, 2023
62f2bef
only test neural_solvers
heatingma Aug 5, 2023
9c76481
only test neural_solvers
heatingma Aug 5, 2023
a591e7e
only test neural
heatingma Aug 5, 2023
ceeaf60
add the forget ","
heatingma Aug 5, 2023
18c98a9
add all tests
heatingma Aug 5, 2023
f408a51
add new url_path and change the download func
heatingma Aug 6, 2023
7e4a9de
delete dropout, trust_fact and no_pred_size for astar
heatingma Aug 7, 2023
6e6f773
delete dropout for genn_astar
heatingma Aug 7, 2023
a3ef42e
delete some parameters for astar and genn_astar
heatingma Aug 7, 2023
86ab428
Merge branch 'Thinklab-SJTU:main' into main
heatingma Aug 7, 2023
ba4d408
python
heatingma Aug 8, 2023
6df2f3f
Merge branch 'Thinklab-SJTU:main' into main
heatingma Aug 8, 2023
66a4b05
Merge branch 'Thinklab-SJTU:main' into main
heatingma Aug 22, 2023
37f88af
Merge branch 'Thinklab-SJTU:main' into main
heatingma Sep 4, 2023
8616fb4
change a_star to astar
heatingma Sep 12, 2023
de06854
change the function name "astar" from cython to "c_astar"
heatingma Oct 5, 2023
b0c8c0d
fix: 'module' object is not callable
heatingma Oct 5, 2023
57b0c26
change astar to c_astar
heatingma Oct 5, 2023
3a1373a
Merge branch 'Thinklab-SJTU:main' into main
heatingma Oct 11, 2023
086e182
Merge branch 'Thinklab-SJTU:main' into main
heatingma Nov 7, 2023
ed731b3
Merge branch 'Thinklab-SJTU:main' into main
heatingma Dec 1, 2023
e6237d9
Fix: for the same k, node_cost is double counted
heatingma Dec 1, 2023
cfe5b5d
Merge branch 'main' of https://github.com/heatingma/pygmtools
heatingma Dec 1, 2023
8bb5841
Add alter urls for datasets
heatingma Dec 2, 2023
1b44be0
fix: No such file or directory: 'data/SPair-71k/Layout/small/trn.txt'
heatingma Dec 2, 2023
b69de38
Merge branch 'Thinklab-SJTU:main' into main
heatingma Dec 7, 2023
a07035f
Merge branch 'Thinklab-SJTU:main' into main
heatingma Dec 12, 2023
fd122a0
support pyg
heatingma Dec 27, 2023
e743cbb
fix "Support for PyG"
heatingma Dec 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 110 additions & 9 deletions pygmtools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1347,9 +1347,9 @@
###################################################


def build_aff_mat_from_networkx(G1:nx.Graph, G2:nx.Graph, node_aff_fn=None, edge_aff_fn=None, backend=None):
def build_aff_mat_from_networkx(G1: nx.Graph, G2: nx.Graph, node_aff_fn=None, edge_aff_fn=None, backend=None):
r"""
Convert networkx object to Adjacency matrix
Convert networkx object to affinity matrix

:param G1: networkx object, whose type must be networkx.Graph
:param G2: networkx object, whose type must be networkx.Graph
Expand Down Expand Up @@ -1381,7 +1381,7 @@
# Obtain Affinity Matrix
>>> K = pygm.utils.build_aff_mat_from_networkx(G1, G2)
>>> K.shape
(20,20)
(20, 20)

# The affinity matrices K can be further processed by GM solvers
"""
Expand All @@ -1397,7 +1397,7 @@

def build_aff_mat_from_graphml(G1_path, G2_path, node_aff_fn=None, edge_aff_fn=None, backend=None):
r"""
Convert networkx object to Adjacency matrix
Convert networkx object to affinity matrix

:param G1_path: The file path of the graphml object
:param G2_path: The file path of the graphml object
Expand Down Expand Up @@ -1427,7 +1427,7 @@
# Obtain Affinity Matrix
>>> K = pygm.utils.build_aff_mat_from_graphml(G1_path, G2_path)
>>> K.shape
(121,121)
(121, 121)

# The affinity matrices K can be further processed by GM solvers
"""
Expand All @@ -1441,9 +1441,9 @@
return K


def from_networkx(G:nx.Graph):
def from_networkx(G: nx.Graph):
r"""
Convert networkx object to Adjacency matrix
Convert networkx object to adjacency matrix

:param G: networkx object, whose type must be networkx.Graph
:return: the adjacency matrix corresponding to the networkx object
Expand Down Expand Up @@ -1522,7 +1522,7 @@

def from_graphml(filename):
r"""
Convert graphml object to Adjacency matrix
Convert graphml object to adjacency matrix

:param filename: graphml file path
:return: the adjacency matrix corresponding to the graphml object
Expand All @@ -1545,7 +1545,7 @@

>>> G1 = pygm.utils.from_graphml(G2_path)
>>> G2.shape
(11,11)
(11, 11)
"""
if not filename.endswith('.graphml'):
raise ValueError("File name should end with '.graphml'")
Expand Down Expand Up @@ -1591,3 +1591,104 @@
"""
nx.write_graphml(to_networkx(adj_matrix, backend), filename)


###################################################
# Support PyG #
###################################################


def build_aff_mat_from_pyg(G1, G2, node_aff_fn=None, edge_aff_fn=None, backend=None):
r"""
Convert torch_geometric.data.Data object to affinity matrix

:param G1: Graph object, whose type must be torch_geometric.data.Data
:param G2: Graph object, whose type must be torch_geometric.data.Data
:param node_aff_fn: (default: inner_prod_aff_fn) the node affinity function with the characteristic
``node_aff_fn(2D Tensor, 2D Tensor) -> 2D Tensor``, which accepts two node feature tensors and
outputs the node-wise affinity tensor. See :func:`~pygmtools.utils.inner_prod_aff_fn` as an
example.
:param edge_aff_fn: (default: inner_prod_aff_fn) the edge affinity function with the characteristic
``edge_aff_fn(2D Tensor, 2D Tensor) -> 2D Tensor``, which accepts two edge feature tensors and
outputs the edge-wise affinity tensor. See :func:`~pygmtools.utils.inner_prod_aff_fn` as an
example.
:param backend: (default: ``pygmtools.BACKEND`` variable) the backend for computation.
:return: the affinity matrix corresponding to the networkx object G1 and G2

.. dropdown:: Example

::

>>> import networkx as nx
>>> from torch_geometric.data import Data
>>> import pygmtools as pygm
>>> pygm.set_backend('pytorch')

# Generate Graph object
>>> x1 = torch.rand((4, 2), dtype=torch.float)
>>> e1 = torch.tensor([[0, 0, 1, 1, 2, 2, 3], [1, 2, 0, 2, 0, 3, 1]], dtype=torch.long)
>>> G1 = Data(x=x1, edge_index=e1)
>>> x2 = torch.rand((5, 2), dtype=torch.float)
>>> e2 = torch.tensor([[0, 0, 1, 1, 2, 2, 3, 4, 4], [1, 3, 2, 3, 1, 3, 4, 2, 3]], dtype=torch.long)
>>> G2 = Data(x=x2, edge_index=e2)

# Obtain Affinity Matrix
>>> K = pygm.utils.build_aff_mat_from_pyg(G1, G2)
>>> K.shape
(20, 20)

# The affinity matrices K can be further processed by GM solvers
"""
from torch_geometric.data import Data
assert type(G1) == Data, f"G1 must be torch_geometric.data.Data"
assert type(G2) == Data, f"G2 must be torch_geometric.data.Data"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace assert with ValueError

if backend is None:
backend = 'pytorch'
else:
assert backend == 'pytorch', f"Function 'build_aff_mat_from_pyg' only supports pytorch backend."

Check warning on line 1647 in pygmtools/utils.py

View check run for this annotation

Codecov / codecov/patch

pygmtools/utils.py#L1647

Added line #L1647 was not covered by tests
pygmtools.set_backend(backend)
node1 = G1.x
edge1 = G1.edge_attr
conn1 = G1.edge_index
node2 = G2.x
edge2 = G2.edge_attr
conn2 = G2.edge_index
K = build_aff_mat(node1, edge1, conn1, node2, edge2, conn2, node_aff_fn=node_aff_fn, edge_aff_fn=edge_aff_fn, backend=backend)
return K


def to_pyg(adj_matrix, backend=None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be "from_pyg" and "to_networkx", "to_graphml"?

"""
Convert adjacency matrix to torch_geometric.data.Data object

:param adj_matrix: the adjacency matrix to convert, whose type must be torch.Tensor
:param backend: (default: ``pygmtools.BACKEND`` variable) the backend for computation.
:return: the torch_geometric.data.Data object corresponding to the adjacency matrix

.. dropdown:: Example

::

>>> import torch
>>> import pygmtools as pygm
>>> pygm.set_backend('pytorch')

# Generate adjacency matrix
>>> adj_matrix = torch.rand((4, 4))

# Obtain torch_geometric.data.Data object
>>> pygm.utils.to_pyg(adj_matrix)
Data(edge_index=[16, 2], edge_attr=[16, 1])
"""
import torch
from torch_geometric.data import Data
if backend is None:
backend = 'pytorch'
else:
assert backend == 'pytorch', f"Function 'build_aff_mat_from_pyg' only supports pytorch backend."

Check warning on line 1687 in pygmtools/utils.py

View check run for this annotation

Codecov / codecov/patch

pygmtools/utils.py#L1687

Added line #L1687 was not covered by tests
pygmtools.set_backend(backend)
assert type(adj_matrix) == torch.Tensor, f"the adj_matrix's type must be torch.Tensor"

conn1, edge1 = dense_to_sparse(adj_matrix, backend=backend)
G = Data(x=None, edge_index=conn1, edge_attr=edge1)
return G

1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ easydict>=1.7
paddlepaddle==2.4.1
protobuf==3.19.5
torch
torch_geometric
tqdm
jittor==1.3.5.37
appdirs>=1.4.4
Expand Down
1 change: 1 addition & 0 deletions tests/requirements_win_mac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ easydict>=1.7
paddlepaddle==2.4.1
protobuf==3.19.5
torch
torch_geometric
tqdm
appdirs>=1.4.4
tensorflow==2.9.3
Expand Down
31 changes: 30 additions & 1 deletion tests/test_classic_solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,30 @@ def _test_graphml(graph_num_nodes, backends):
assert accuracy == 1, f'When testing the graphml function with rrwm algorithm, there is an error in accuracy, \
and the accuracy is {accuracy}, the num_node is {num_node},.'



# The testing function for networkx
def _test_pyg(graph_num_nodes, backends):
"""
Test the RRWM algorithm on pairs of isomorphic graphs using NetworkX
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NetworkX -> PyG


:param graph_num_nodes: list, the numbers of nodes in the graphs to test
"""
for working_backend in backends:
pygm.BACKEND = working_backend
for num_node in tqdm(graph_num_nodes):
As_b, X_gt = pygm.utils.generate_isomorphic_graphs(num_node)
X_gt = pygm.utils.to_numpy(X_gt, backend=working_backend)
A1 = As_b[0]
A2 = As_b[1]
G1 = pygm.utils.to_pyg(A1)
G2 = pygm.utils.to_pyg(A2)
K = pygm.utils.build_aff_mat_from_pyg(G1, G2)
X = pygm.rrwm(K, n1=num_node, n2=num_node)
accuracy = (pygm.utils.to_numpy(pygm.hungarian(X, num_node, num_node)) * X_gt).sum() / X_gt.sum()
assert accuracy == 1, f'When testing the networkx function with rrwm algorithm, there is an error in accuracy, \
and the accuracy is {accuracy}, the num_node is {num_node},.'


def test_hungarian(get_backend):
backends = get_backends(get_backend)
_test_classic_solver_on_linear_assignment(list(range(10, 30, 2)), list(range(30, 10, -2)), 10, pygm.hungarian, {
Expand Down Expand Up @@ -477,6 +500,11 @@ def test_graphml():
_test_graphml(list(range(10, 30, 2)), backends=backends)


def test_pyg():
backends = ['pytorch']
_test_pyg(list(range(10, 30, 2)), backends=backends)


if __name__ == '__main__':
test_hungarian('all')
test_sinkhorn('all')
Expand All @@ -486,3 +514,4 @@ def test_graphml():
test_astar('')
test_networkx()
test_graphml()
test_pyg()
Loading