Skip to content

Enable sampling multiple nodes per "example" #155

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions graphlearn_torch/python/sampler/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ def __getitem__(self, index: Union[torch.Tensor, Any]) -> 'NodeSamplerInput':
if not isinstance(index, torch.Tensor):
index = torch.tensor(index, dtype=torch.long)
index = index.to(self.node.device)
return NodeSamplerInput(self.node[index], self.input_type)
return NodeSamplerInput(self.node[index].view(-1), self.input_type)

def __len__(self):
return self.node.numel()
return self.node.shape[0]

def share_memory(self):
self.node.share_memory_()
Expand Down
59 changes: 59 additions & 0 deletions test/python/test_sampler_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import unittest

import torch
from torch.testing import assert_close

from graphlearn_torch.sampler.base import NodeSamplerInput


def _assert_tensor_equal(tensor1, tensor2):
assert_close(tensor1, tensor2, rtol=0, atol=0)


class TestSamplerBase(unittest.TestCase):

def test_node_sampler_input_int_index(self):
input_data = NodeSamplerInput(node=torch.arange(10))
_assert_tensor_equal(input_data[0].node, torch.tensor([0]))

def test_node_sampler_input_tensor_index(self):
input_data = NodeSamplerInput(node=torch.arange(10))
with self.subTest("scalar tensor input"):
_assert_tensor_equal(input_data[torch.tensor(0)].node, torch.tensor([0]))

with self.subTest("slice tensor input"):
_assert_tensor_equal(input_data[torch.tensor([0, 1])].node, torch.tensor([0, 1]))

def test_node_sampler_input_multiple_examples(self):
input_data = NodeSamplerInput(node=torch.tensor([[0, 1, 2], [3, 4, 5]]))
self.assertEqual(len(input_data), 2)

with self.subTest("scalar tensor input"):
_assert_tensor_equal(input_data[torch.tensor(0)].node, torch.tensor([0, 1, 2]))

with self.subTest("slice tensor input"):
_assert_tensor_equal(
input_data[torch.tensor([0, 1])].node, torch.tensor([0, 1, 2, 3, 4, 5])
)

# Also test with dataloader - since that's how we actually use this
with self.subTest("dataloader"):
loader = torch.utils.data.DataLoader(torch.arange(2))
expected_data = torch.tensor([[0, 1, 2], [3, 4, 5]])

self.assertEqual(len(loader), len(expected_data))
for data, expected in zip(loader, expected_data):
_assert_tensor_equal(input_data[data].node, expected)

# Also test with dataloader - since that's how we actually use this
with self.subTest("dataloader - batched"):
loader = torch.utils.data.DataLoader(torch.arange(2), batch_size=2)
expected_data = torch.tensor([[0, 1, 2, 3, 4, 5]])

self.assertEqual(len(loader), len(expected_data))
for data, expected in zip(loader, expected_data):
_assert_tensor_equal(input_data[data].node, expected)


if __name__ == "__main__":
unittest.main()
Loading