Files
dmlc--dgl/python/dgl/distgnn/tools/tools.py
T
2026-07-13 13:35:51 +08:00

163 lines
4.2 KiB
Python

r"""
Copyright (c) 2021 Intel Corporation
\file distgnn/tools/tools.py
\brief Tools for use in Libra graph partitioner.
\author Vasimuddin Md <vasimuddin.md@intel.com>
"""
import os
import random
import requests
import torch as th
from scipy.io import mmread
import dgl
from dgl.base import DGLError
from dgl.data.utils import load_graphs, save_graphs, save_tensors
def rep_per_node(prefix, num_community):
"""
Used on Libra partitioned data.
This function reports number of split-copes per node (replication) of
a partitioned graph
Parameters
----------
prefix: Partition folder location (contains replicationlist.csv)
num_community: number of partitions or communities
"""
ifile = os.path.join(prefix, "replicationlist.csv")
fhandle = open(ifile, "r")
r_dt = {}
fline = fhandle.readline() ## reading first line, contains the comment.
print(fline)
for line in fhandle:
if line[0] == "#":
raise DGLError("[Bug] Read Hash char in rep_per_node func.")
node = line.strip("\n")
if r_dt.get(node, -100) == -100:
r_dt[node] = 1
else:
r_dt[node] += 1
fhandle.close()
## sanity checks
for v in r_dt.values():
if v >= num_community:
raise DGLError(
"[Bug] Unexpected event in rep_per_node() in tools.py."
)
return r_dt
def download_proteins():
"""
Downloads the proteins dataset
"""
print("Downloading dataset...")
print("This might a take while..")
url = "https://portal.nersc.gov/project/m1982/GNN/"
file_name = "subgraph3_iso_vs_iso_30_70length_ALL.m100.propermm.mtx"
url = url + file_name
try:
req = requests.get(url)
except:
raise DGLError(
"Error: Failed to download Proteins dataset!! Aborting.."
)
with open("proteins.mtx", "wb") as handle:
handle.write(req.content)
def proteins_mtx2dgl():
"""
This function converts Proteins dataset from mtx to dgl format.
"""
print("Converting mtx2dgl..")
print("This might a take while..")
a_mtx = mmread("proteins.mtx")
coo = a_mtx.tocoo()
u = th.tensor(coo.row, dtype=th.int64)
v = th.tensor(coo.col, dtype=th.int64)
g = dgl.DGLGraph()
g.add_edges(u, v)
n = g.num_nodes()
feat_size = 128 ## arbitrary number
feats = th.empty([n, feat_size], dtype=th.float32)
## arbitrary numbers
train_size = 1000000
test_size = 500000
val_size = 5000
nlabels = 256
train_mask = th.zeros(n, dtype=th.bool)
test_mask = th.zeros(n, dtype=th.bool)
val_mask = th.zeros(n, dtype=th.bool)
label = th.zeros(n, dtype=th.int64)
for i in range(train_size):
train_mask[i] = True
for i in range(test_size):
test_mask[train_size + i] = True
for i in range(val_size):
val_mask[train_size + test_size + i] = True
for i in range(n):
label[i] = random.choice(range(nlabels))
g.ndata["feat"] = feats
g.ndata["train_mask"] = train_mask
g.ndata["test_mask"] = test_mask
g.ndata["val_mask"] = val_mask
g.ndata["label"] = label
return g
def save(g, dataset):
"""
This function saves input dataset to dgl format
Parameters
----------
g : graph to be saved
dataset : output folder name
"""
print("Saving dataset..")
part_dir = os.path.join("./" + dataset)
node_feat_file = os.path.join(part_dir, "node_feat.dgl")
part_graph_file = os.path.join(part_dir, "graph.dgl")
os.makedirs(part_dir, mode=0o775, exist_ok=True)
save_tensors(node_feat_file, g.ndata)
save_graphs(part_graph_file, [g])
print("Graph saved successfully !!")
def load_proteins(dataset):
"""
This function downloads, converts, and load Proteins graph dataset
Parameter
---------
dataset: output folder name
"""
part_dir = dataset
graph_file = os.path.join(part_dir + "/graph.dgl")
if not os.path.exists("proteins.mtx"):
download_proteins()
if not os.path.exists(graph_file):
g = proteins_mtx2dgl()
save(g, dataset)
## load
graph = load_graphs(graph_file)[0][0]
return graph