Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 28 additions & 0 deletions .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Run Unit Test via Pytest

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8"]

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[dev]
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
- name: Test with pytest
run: |
coverage run -m pytest -v -s -p no:warnings
- name: Generate Coverage Report
run: |
coverage report -m
96 changes: 49 additions & 47 deletions benchmarking/gcn/seastar/train.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
import torch.nn as nn
import torch.nn.functional as F
from stgraph.graph.static.StaticGraph import StaticGraph
from stgraph.dataset.CoraDataLoader import CoraDataLoader
from utils import to_default_device, accuracy
from stgraph.dataset import CoraDataLoader
from utils import to_default_device, accuracy, generate_test_mask, generate_train_mask
from model import GCN

def main(args):

def main(args):
cora = CoraDataLoader(verbose=True)

# To account for the initial CUDA Context object for pynvml
tmp = StaticGraph([(0,0)], [1], 1)
tmp = StaticGraph([(0, 0)], [1], 1)

features = torch.FloatTensor(cora.get_all_features())
labels = torch.LongTensor(cora.get_all_targets())
train_mask = cora.get_train_mask()
test_mask = cora.get_test_mask()

train_mask = generate_train_mask(len(features), 0.6)
test_mask = generate_test_mask(len(features), 0.6)

train_mask = torch.BoolTensor(train_mask)
test_mask = torch.BoolTensor(test_mask)
Expand All @@ -47,7 +47,9 @@ def main(args):

# A simple sanity check
print("Measuerd Graph Size (pynvml): ", graph_mem, " B", flush=True)
print("Measuerd Graph Size (pynvml): ", (graph_mem)/(1024**2), " MB", flush=True)
print(
"Measuerd Graph Size (pynvml): ", (graph_mem) / (1024**2), " MB", flush=True
)

# normalization
degs = torch.from_numpy(g.weighted_in_degrees()).type(torch.int32)
Expand All @@ -58,23 +60,18 @@ def main(args):

num_feats = features.shape[1]
n_classes = int(max(labels) - min(labels) + 1)
print("Num Classes: ",n_classes)

model = GCN(g,
num_feats,
args.num_hidden,
n_classes,
args.num_layers,
F.relu)

print("Num Classes: ", n_classes)

model = GCN(g, num_feats, args.num_hidden, n_classes, args.num_layers, F.relu)

if cuda:
model.cuda()
loss_fcn = torch.nn.CrossEntropyLoss()

# use optimizer
optimizer = torch.optim.Adam(model.parameters(),
lr=args.lr,
weight_decay=args.weight_decay)
optimizer = torch.optim.Adam(
model.parameters(), lr=args.lr, weight_decay=args.weight_decay
)

# initialize graph
dur = []
Expand Down Expand Up @@ -106,40 +103,45 @@ def main(args):
dur.append(run_time_this_epoch)

train_acc = accuracy(logits[train_mask], labels[train_mask])
print('Epoch {:05d} | Time(s) {:.4f} | train_acc {:.6f} | Used_Memory {:.6f} mb '.format(
epoch, run_time_this_epoch, train_acc, (now_mem * 1.0 / (1024**2))
))
print(
"Epoch {:05d} | Time(s) {:.4f} | train_acc {:.6f} | Used_Memory {:.6f} mb ".format(
epoch, run_time_this_epoch, train_acc, (now_mem * 1.0 / (1024**2))
)
)

Used_memory /= (1024**3)
print('^^^{:6f}^^^{:6f}'.format(Used_memory, np.mean(dur)))
Used_memory /= 1024**3
print("^^^{:6f}^^^{:6f}".format(Used_memory, np.mean(dur)))


if __name__ == '__main__':
parser = argparse.ArgumentParser(description='GCN')
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="GCN")

# COMMENT IF SNOOP IS TO BE ENABLED
snoop.install(enabled=False)

parser.add_argument("--dropout", type=float, default=0.5,
help="dropout probability")
parser.add_argument("--dataset", type=str,
help="Datset to train your model")
parser.add_argument("--gpu", type=int, default=0,
help="gpu")
parser.add_argument("--lr", type=float, default=1e-2,
help="learning rate")
parser.add_argument("--num_epochs", type=int, default=200,
help="number of training epochs")
parser.add_argument("--num_hidden", type=int, default=16,
help="number of hidden gcn units")
parser.add_argument("--num_layers", type=int, default=1,
help="number of hidden gcn layers")
parser.add_argument("--weight-decay", type=float, default=5e-4,
help="Weight for L2 loss")
parser.add_argument("--self-loop", action='store_true',
help="graph self-loop (default=False)")
parser.add_argument(
"--dropout", type=float, default=0.5, help="dropout probability"
)
parser.add_argument("--dataset", type=str, help="Datset to train your model")
parser.add_argument("--gpu", type=int, default=0, help="gpu")
parser.add_argument("--lr", type=float, default=1e-2, help="learning rate")
parser.add_argument(
"--num_epochs", type=int, default=200, help="number of training epochs"
)
parser.add_argument(
"--num_hidden", type=int, default=16, help="number of hidden gcn units"
)
parser.add_argument(
"--num_layers", type=int, default=1, help="number of hidden gcn layers"
)
parser.add_argument(
"--weight-decay", type=float, default=5e-4, help="Weight for L2 loss"
)
parser.add_argument(
"--self-loop", action="store_true", help="graph self-loop (default=False)"
)
parser.set_defaults(self_loop=False)
args = parser.parse_args()
print(args)

main(args)
main(args)
27 changes: 19 additions & 8 deletions benchmarking/gcn/seastar/utils.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import torch


def accuracy(logits, labels):
_, indices = torch.max(logits, dim=1)
correct = torch.sum(indices == labels)
return correct.item() * 1.0 / len(labels)


# GPU | CPU
def get_default_device():

if torch.cuda.is_available():
return torch.device('cuda:0')
return torch.device("cuda:0")
else:
return torch.device('cpu')
return torch.device("cpu")


def to_default_device(data):

if isinstance(data,(list,tuple)):
return [to_default_device(x,get_default_device()) for x in data]

return data.to(get_default_device(),non_blocking = True)
if isinstance(data, (list, tuple)):
return [to_default_device(x, get_default_device()) for x in data]

return data.to(get_default_device(), non_blocking=True)


def generate_train_mask(size: int, train_test_split: int) -> list:
cutoff = size * train_test_split
return [1 if i < cutoff else 0 for i in range(size)]


def generate_test_mask(size: int, train_test_split: int) -> list:
cutoff = size * train_test_split
return [0 if i < cutoff else 1 for i in range(size)]
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ dependencies = [
[project.optional-dependencies]
dev = [
"black",
"pytest",
"pytest >= 7.4.3",
"pytest-cov >= 4.1.0",
"tqdm >= 4.64.1",
"build >= 0.10.0",
"gdown >= 4.6.6",
Expand Down
11 changes: 11 additions & 0 deletions stgraph/dataset/dynamic/england_covid_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class EnglandCovidDataLoader(STGraphDynamicDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand All @@ -65,6 +66,16 @@ def __init__(
"""COVID-19 cases in England's NUTS3 regions."""
super().__init__()

if not isinstance(lags, int):
raise TypeError("lags must be of type int")
if lags < 0:
raise ValueError("lags must be a positive integer")

if cutoff_time is not None and not isinstance(cutoff_time, int):
raise TypeError("cutoff_time must be of type int")
if cutoff_time is not None and cutoff_time < 0:
raise ValueError("cutoff_time must be a positive integer")

self.name = "England_COVID"
self._url = "https://raw.githubusercontent.com/benedekrozemberczki/pytorch_geometric_temporal/master/dataset/england_covid.json"
self._verbose = verbose
Expand Down
1 change: 1 addition & 0 deletions stgraph/dataset/static/cora_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class CoraDataLoader(STGraphStaticDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand Down
3 changes: 3 additions & 0 deletions stgraph/dataset/stgraph_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def __init__(self: STGraphDataset) -> None:

_load_dataset()
Loads the dataset from cache

"""
self.name = ""
self.gdata = {}
Expand Down Expand Up @@ -106,6 +107,7 @@ def _has_dataset_cache(self: STGraphDataset) -> bool:
# The dataset is cached, continue cached operations
else:
# The dataset is not cached, continue load and save operations

"""
user_home_dir = os.path.expanduser("~")
stgraph_dir = user_home_dir + "/.stgraph"
Expand All @@ -128,6 +130,7 @@ def _get_cache_file_path(self: STGraphDataset) -> str:
-------
str
The absolute path of the cached dataset file

"""
user_home_dir = os.path.expanduser("~")
stgraph_dir = user_home_dir + "/.stgraph"
Expand Down
1 change: 1 addition & 0 deletions stgraph/dataset/temporal/hungarycp_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class HungaryCPDataLoader(STGraphTemporalDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand Down
1 change: 1 addition & 0 deletions stgraph/dataset/temporal/metrla_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class METRLADataLoader(STGraphTemporalDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand Down
1 change: 1 addition & 0 deletions stgraph/dataset/temporal/montevideobus_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class MontevideoBusDataLoader(STGraphTemporalDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand Down
1 change: 1 addition & 0 deletions stgraph/dataset/temporal/pedalme_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class PedalMeDataLoader(STGraphTemporalDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand Down
1 change: 1 addition & 0 deletions stgraph/dataset/temporal/wikimath_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class WikiMathDataLoader(STGraphTemporalDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand Down
1 change: 1 addition & 0 deletions stgraph/dataset/temporal/windmilloutput_dataloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class WindmillOutputDataLoader(STGraphTemporalDataset):
The name of the dataset.
gdata : dict
Graph meta data.

"""

def __init__(
Expand Down
27 changes: 19 additions & 8 deletions tests/dataset/dynamic/test_EnglandCovidDataLoader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import numpy as np
import urllib.request
import pytest

from stgraph.dataset import EnglandCovidDataLoader

Expand Down Expand Up @@ -51,14 +50,26 @@ def EnglandCovidDataCheck(eng_covid: EnglandCovidDataLoader):
def test_EnglandCovidDataLoader():
eng_covid = EnglandCovidDataLoader(verbose=True)
eng_covid_1 = EnglandCovidDataLoader(cutoff_time=30)
eng_covid_2 = EnglandCovidDataLoader(
url="https://raw.githubusercontent.com/benedekrozemberczki/pytorch_geometric_temporal/master/dataset/england_covid.json"
)
eng_covid_3 = EnglandCovidDataLoader(lags=12)
# eng_covid_4 = EnglandCovidDataLoader(redownload=True)
eng_covid_4 = EnglandCovidDataLoader(redownload=True)

EnglandCovidDataCheck(eng_covid)
EnglandCovidDataCheck(eng_covid_1)
# EnglandCovidDataCheck(eng_covid_2)
EnglandCovidDataCheck(eng_covid_3)
# EnglandCovidDataCheck(eng_covid_4)
EnglandCovidDataCheck(eng_covid_4)

with pytest.raises(TypeError) as exec:
EnglandCovidDataLoader(lags="lags")
assert str(exec.value) == "lags must be of type int"

with pytest.raises(ValueError) as exec:
EnglandCovidDataLoader(lags=-1)
assert str(exec.value) == "lags must be a positive integer"

with pytest.raises(TypeError) as exec:
EnglandCovidDataLoader(cutoff_time="time")
assert str(exec.value) == "cutoff_time must be of type int"

with pytest.raises(ValueError) as exec:
EnglandCovidDataLoader(cutoff_time=-1)
assert str(exec.value) == "cutoff_time must be a positive integer"
7 changes: 2 additions & 5 deletions tests/dataset/static/test_CoraDataLoader.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ def CoraDataCheck(cora: CoraDataLoader):


def test_CoraDataLoader():
cora = CoraDataLoader()

cora_1 = CoraDataLoader(
url="https://raw.githubusercontent.com/bfGraph/STGraph-Datasets/main/cora.json",
)
cora = CoraDataLoader(verbose=True)
cora_1 = CoraDataLoader(redownload=True)

CoraDataCheck(cora)
CoraDataCheck(cora_1)
Loading