Skip to content

Commit

Permalink
Test against nightly PyTorch releases (#7036)
Browse files Browse the repository at this point in the history
  • Loading branch information
rusty1s authored Mar 25, 2023
1 parent a51e1db commit c78c5b2
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 42 deletions.
9 changes: 9 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,21 @@ runs:
setup.py
- name: Install PyTorch ${{ inputs.torch-version }}+${{ inputs.cuda-version }}
if: ${{ inputs.torch-version != 'nightly' }}
run: |
pip install torch==${{ inputs.torch-version }} --extra-index-url https://download.pytorch.org/whl/${{ inputs.cuda-version }}
python -c "import torch; print('PyTorch:', torch.__version__)"
python -c "import torch; print('CUDA:', torch.version.cuda)"
shell: bash

- name: Install PyTorch ${{ inputs.torch-version }}+${{ inputs.cuda-version }}
if: ${{ inputs.torch-version == 'nightly' }}
run: |
pip install --pre torch --extra-index-url https://download.pytorch.org/whl/nightly/${{ inputs.cuda-version }}
python -c "import torch; print('PyTorch:', torch.__version__)"
python -c "import torch; print('CUDA:', torch.version.cuda)"
shell: bash

- name: Install extension packages
if: ${{ inputs.full_install == 'true' }}
run: |
Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/latest_testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Testing PyTorch nightly

on: # yamllint disable-line rule:truthy
push:
branches:
- master
pull_request:

jobs:

latest_pytest:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 40

# Skip workflow if only certain files have been changed.
- name: Get changed files
id: changed-files-specific
uses: tj-actions/changed-files@v34
with:
files: |
benchmark/**
conda/**
docker/**
docs/**
examples/**
graphgym/**
CHANGELOG.md
- name: Setup packages
if: steps.changed-files-specific.outputs.only_changed != 'true'
uses: ./.github/actions/setup
with:
torch-version: nightly
full_install: false

- name: Install main package
if: steps.changed-files-specific.outputs.only_changed != 'true'
run: |
pip install -e .[full,test]
- name: Run tests
if: steps.changed-files-specific.outputs.only_changed != 'true'
run: |
pytest test/test_debug.py
pytest test/test_experimental.py
pytest test/test_home.py
pytest test/test_seed.py
pytest test/test_typing.py
pytest test/contrib/
# pytest test/data/
pytest test/datasets/
pytest test/explain/
pytest test/graphgym/
pytest test/io/
# pytest test/loader/
# pytest test/nn/
pytest test/profile/
pytest test/sampler/
pytest test/testing/
# pytest test/transforms/
pytest test/utils/
pytest test/visualization/
13 changes: 11 additions & 2 deletions test/profile/test_profile_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import torch
from torch.nn import Linear
from torch_sparse import SparseTensor

from torch_geometric.data import Data
from torch_geometric.profile import (
Expand All @@ -15,7 +14,8 @@
byte_to_megabyte,
medibyte_to_megabyte,
)
from torch_geometric.testing import onlyCUDA
from torch_geometric.testing import onlyCUDA, withPackage
from torch_geometric.typing import SparseTensor


def test_count_parameters():
Expand All @@ -28,6 +28,15 @@ def test_get_model_size():


def test_get_data_size():
x = torch.randn(10, 128)
data = Data(x=x, y=x)

data_size = get_data_size(data)
assert data_size == 10 * 128 * 4


@withPackage('torch_sparse')
def test_get_data_size_with_sparse_tensor():
x = torch.randn(10, 128)
row, col = torch.randint(0, 10, (2, 100), dtype=torch.long)
adj_t = SparseTensor(row=row, col=col, value=None, sparse_sizes=(10, 10))
Expand Down
17 changes: 10 additions & 7 deletions test/utils/test_assortativity.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import pytest
import torch
from torch_sparse import SparseTensor

import torch_geometric.typing
from torch_geometric.typing import SparseTensor
from torch_geometric.utils import assortativity


Expand All @@ -12,16 +13,18 @@ def test_assortativity():
out = assortativity(edge_index)
assert pytest.approx(out, abs=1e-5) == 1.0

adj = SparseTensor.from_edge_index(edge_index, sparse_sizes=[6, 6])
out = assortativity(adj)
assert pytest.approx(out, abs=1e-5) == 1.0
if torch_geometric.typing.WITH_TORCH_SPARSE:
adj = SparseTensor.from_edge_index(edge_index, sparse_sizes=[6, 6])
out = assortativity(adj)
assert pytest.approx(out, abs=1e-5) == 1.0

# Completely disassortative graph:
edge_index = torch.tensor([[0, 1, 2, 3, 4, 5, 5, 5, 5, 5],
[5, 5, 5, 5, 5, 0, 1, 2, 3, 4]])
out = assortativity(edge_index)
assert pytest.approx(out, abs=1e-5) == -1.0

adj = SparseTensor.from_edge_index(edge_index, sparse_sizes=[6, 6])
out = assortativity(adj)
assert pytest.approx(out, abs=1e-5) == -1.0
if torch_geometric.typing.WITH_TORCH_SPARSE:
adj = SparseTensor.from_edge_index(edge_index, sparse_sizes=[6, 6])
out = assortativity(adj)
assert pytest.approx(out, abs=1e-5) == -1.0
15 changes: 10 additions & 5 deletions test/utils/test_homophily.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import pytest
import torch
from torch_sparse import SparseTensor

import torch_geometric.typing
from torch_geometric.typing import SparseTensor
from torch_geometric.utils import homophily


Expand All @@ -10,19 +11,23 @@ def test_homophily():
y = torch.tensor([0, 0, 0, 0, 1])
batch = torch.tensor([0, 0, 0, 1, 1])
row, col = edge_index
adj = SparseTensor(row=row, col=col, sparse_sizes=(5, 5))
if torch_geometric.typing.WITH_TORCH_SPARSE:
adj = SparseTensor(row=row, col=col, sparse_sizes=(5, 5))

method = 'edge'
assert pytest.approx(homophily(edge_index, y, method=method)) == 0.75
assert pytest.approx(homophily(adj, y, method=method)) == 0.75
if torch_geometric.typing.WITH_TORCH_SPARSE:
assert pytest.approx(homophily(adj, y, method=method)) == 0.75
assert homophily(edge_index, y, batch, method).tolist() == [1., 0.]

method = 'node'
assert pytest.approx(homophily(edge_index, y, method=method)) == 0.6
assert pytest.approx(homophily(adj, y, method=method)) == 0.6
if torch_geometric.typing.WITH_TORCH_SPARSE:
assert pytest.approx(homophily(adj, y, method=method)) == 0.6
assert homophily(edge_index, y, batch, method).tolist() == [1., 0.]

method = 'edge_insensitive'
assert pytest.approx(homophily(edge_index, y, method=method)) == 0.1999999
assert pytest.approx(homophily(adj, y, method=method)) == 0.1999999
if torch_geometric.typing.WITH_TORCH_SPARSE:
assert pytest.approx(homophily(adj, y, method=method)) == 0.1999999
assert homophily(edge_index, y, batch, method).tolist() == [0., 0.]
3 changes: 2 additions & 1 deletion test/utils/test_segment.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import pytest
import torch

from torch_geometric.testing import withCUDA
from torch_geometric.testing import withCUDA, withPackage
from torch_geometric.utils import segment


@withCUDA
@withPackage('torch_scatter')
@pytest.mark.parametrize('reduce', ['sum', 'mean', 'min', 'max'])
def test_segment(device, reduce):
src = torch.randn(20, 16, device=device)
Expand Down
24 changes: 17 additions & 7 deletions test/utils/test_softmax.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest
import torch

import torch_geometric
import torch_geometric.typing
from torch_geometric.profile import benchmark
from torch_geometric.utils import softmax

Expand All @@ -12,12 +13,17 @@ def test_softmax():

out = softmax(src, index)
assert out.tolist() == [0.5, 0.5, 1, 1]
assert softmax(src, None, ptr).tolist() == out.tolist()
if torch_geometric.typing.WITH_TORCH_SCATTER:
assert softmax(src, None, ptr).tolist() == out.tolist()
else:
with pytest.raises(ImportError):
softmax(src, None, ptr)

src = src.view(-1, 1)
out = softmax(src, index)
assert out.tolist() == [[0.5], [0.5], [1], [1]]
assert softmax(src, None, ptr).tolist() == out.tolist()
if torch_geometric.typing.WITH_TORCH_SCATTER:
assert softmax(src, None, ptr).tolist() == out.tolist()

jit = torch.jit.script(softmax)
assert torch.allclose(jit(src, index), out)
Expand Down Expand Up @@ -46,19 +52,23 @@ def test_softmax_dim():

src = torch.randn(4)
assert torch.allclose(softmax(src, index, dim=0), src.softmax(dim=0))
assert torch.allclose(softmax(src, ptr=ptr, dim=0), src.softmax(dim=0))
if torch_geometric.typing.WITH_TORCH_SCATTER:
assert torch.allclose(softmax(src, ptr=ptr, dim=0), src.softmax(dim=0))

src = torch.randn(4, 16)
assert torch.allclose(softmax(src, index, dim=0), src.softmax(dim=0))
assert torch.allclose(softmax(src, ptr=ptr, dim=0), src.softmax(dim=0))
if torch_geometric.typing.WITH_TORCH_SCATTER:
assert torch.allclose(softmax(src, ptr=ptr, dim=0), src.softmax(dim=0))

src = torch.randn(4, 4)
assert torch.allclose(softmax(src, index, dim=-1), src.softmax(dim=-1))
assert torch.allclose(softmax(src, ptr=ptr, dim=-1), src.softmax(dim=-1))
if torch_geometric.typing.WITH_TORCH_SCATTER:
assert torch.allclose(softmax(src, ptr=ptr, dim=-1), src.softmax(-1))

src = torch.randn(4, 4, 16)
assert torch.allclose(softmax(src, index, dim=1), src.softmax(dim=1))
assert torch.allclose(softmax(src, ptr=ptr, dim=1), src.softmax(dim=1))
if torch_geometric.typing.WITH_TORCH_SCATTER:
assert torch.allclose(softmax(src, ptr=ptr, dim=1), src.softmax(dim=1))


if __name__ == '__main__':
Expand Down
10 changes: 7 additions & 3 deletions test/utils/test_sparse.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import torch
from torch_sparse import SparseTensor

import torch_geometric.typing
from torch_geometric.testing import is_full_test
from torch_geometric.typing import SparseTensor
from torch_geometric.utils import (
dense_to_sparse,
is_sparse,
Expand Down Expand Up @@ -57,17 +57,21 @@ def test_is_torch_sparse_tensor():
x = torch.randn(5, 5)

assert not is_torch_sparse_tensor(x)
assert not is_torch_sparse_tensor(SparseTensor.from_dense(x))
assert is_torch_sparse_tensor(x.to_sparse())

if torch_geometric.typing.WITH_TORCH_SPARSE:
assert not is_torch_sparse_tensor(SparseTensor.from_dense(x))


def test_is_sparse():
x = torch.randn(5, 5)

assert not is_sparse(x)
assert is_sparse(SparseTensor.from_dense(x))
assert is_sparse(x.to_sparse())

if torch_geometric.typing.WITH_TORCH_SPARSE:
assert is_sparse(SparseTensor.from_dense(x))


def test_to_torch_coo_tensor():
edge_index = torch.tensor([
Expand Down
33 changes: 19 additions & 14 deletions test/utils/test_spmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import torch
from torch import Tensor

import torch_geometric.typing
from torch_geometric.profile import benchmark
from torch_geometric.testing import withCUDA, withPackage
from torch_geometric.typing import SparseTensor
Expand All @@ -17,21 +18,23 @@ def test_spmm_basic(device, reduce):
src = torch.randn(5, 4, device=device)
other = torch.randn(4, 8, device=device)

out1 = src @ other
out1 = (src @ other) / (src.size(1) if reduce == 'mean' else 1)
out2 = spmm(src.to_sparse_csr(), other, reduce=reduce)
out3 = spmm(SparseTensor.from_dense(src), other, reduce=reduce)
assert out1.size() == (5, 8)
if reduce == 'sum':
assert torch.allclose(out1, out2, atol=1e-6)
assert torch.allclose(out1, out3, atol=1e-6)
assert torch.allclose(out2, out3, atol=1e-6)
assert torch.allclose(out1, out2, atol=1e-6)
if torch_geometric.typing.WITH_TORCH_SPARSE:
out3 = spmm(SparseTensor.from_dense(src), other, reduce=reduce)
assert torch.allclose(out2, out3, atol=1e-6)

# Test `mean` reduction with isolated nodes:
src[0] = 0.
out1 = (src @ other) / (4. if reduce == 'mean' else 1.)
out2 = spmm(src.to_sparse_csr(), other, reduce=reduce)
out3 = spmm(SparseTensor.from_dense(src), other, reduce=reduce)
assert out1.size() == (5, 8)
assert torch.allclose(out2, out3, atol=1e-6)
assert torch.allclose(out1, out2, atol=1e-6)
if torch_geometric.typing.WITH_TORCH_SPARSE:
out3 = spmm(SparseTensor.from_dense(src), other, reduce=reduce)
assert torch.allclose(out2, out3, atol=1e-6)


@withCUDA
Expand All @@ -46,8 +49,10 @@ def test_spmm_reduce(device, reduce):
spmm(src.to_sparse_csr(), other, reduce)
else:
out1 = spmm(src.to_sparse_csr(), other, reduce)
out2 = spmm(SparseTensor.from_dense(src), other, reduce=reduce)
assert torch.allclose(out1, out2)
assert out1.size() == (5, 8)
if torch_geometric.typing.WITH_TORCH_SPARSE:
out2 = spmm(SparseTensor.from_dense(src), other, reduce=reduce)
assert torch.allclose(out1, out2)


@withCUDA
Expand Down Expand Up @@ -91,13 +96,13 @@ def jit_torch(src: Tensor, other: Tensor, reduce: str) -> Tensor:
other = torch.randn(4, 8)

out1 = src @ other
out2 = jit_torch_sparse(SparseTensor.from_dense(src), other, reduce=reduce)
out3 = jit_torch(src.to_sparse_csr(), other, reduce)
out2 = jit_torch(src.to_sparse_csr(), other, reduce)
assert out1.size() == (5, 8)
if reduce == 'sum':
assert torch.allclose(out1, out2, atol=1e-6)
assert torch.allclose(out1, out3, atol=1e-6)
assert torch.allclose(out2, out3, atol=1e-6)
if torch_geometric.typing.WITH_TORCH_SPARSE:
out3 = jit_torch_sparse(SparseTensor.from_dense(src), other, reduce)
assert torch.allclose(out2, out3, atol=1e-6)


if __name__ == '__main__':
Expand Down
Loading

0 comments on commit c78c5b2

Please sign in to comment.