code: def test_homo_neighbor_loader_basic(
      device,
      subgraph_type,
      dtype,
      filter_per_worker,
  ):
      if dtype != torch.int64 and not torch_geometric.typing.WITH_PT20:
          return
      induced = SubgraphType.induced
      if (
          subgraph_type == SubgraphType.induced
          and not WITH_TORCH_SPARSE
      ):
          return
      if dtype != torch.int64 and (
          not WITH_PYG_LIB or subgraph_type == induced
      ):
          return
  
      torch.manual_seed(12345)
  
      data = Data()
  
      data.x = torch.arange(100, device=device)
      data.edge_index = get_random_edge_index(
          100, 100, 500, dtype, device
      )
      data.edge_attr = torch.arange(500, device=device)
  
      loader = NeighborLoader(
          data,
          num_neighbors=[5] * 2,
          batch_size=20,
          subgraph_type=subgraph_type,
          filter_per_worker=filter_per_worker,
      )
  
      assert str(loader) == "NeighborLoader()"
      assert len(loader) == 5
  
      batch = loader([0])
      assert isinstance(batch, Data)
      assert batch.n_id[:1].tolist() == [0]
  
      for i, batch in enumerate(loader):
          assert isinstance(batch, Data)
          assert batch.x.device == device
          assert batch.x.size(0) <= 100
          assert batch.n_id.size() == (batch.num_nodes,)
          assert batch.input_id.numel() == batch.batch_size == 20
          assert batch.x.min() >= 0 and batch.x.max() < 100
          assert isinstance(batch.edge_index, EdgeIndex)
          batch.edge_index.validate()
          size = (batch.num_nodes, batch.num_nodes)
          assert batch.edge_index.sparse_size() == size
          assert batch.edge_index.sort_order == "col"
          assert batch.edge_index.device == device
          assert batch.edge_index.min() >= 0
          assert batch.edge_index.max() < batch.num_nodes
          assert batch.edge_attr.device == device
          assert batch.edge_attr.size(0) == batch.edge_index.size(1)
  
          # Input nodes are always sampled first:
          assert torch.equal(
              batch.x[: batch.batch_size],
              torch.arange(
                  i * batch.batch_size,
                  (i + 1) * batch.batch_size,
                  device=device,
              ),
          )
  
          if subgraph_type != SubgraphType.bidirectional:
              assert batch.e_id.size() == (batch.num_edges,)
              assert batch.edge_attr.min() >= 0
              assert batch.edge_attr.max() < 500
  
              assert is_subset(
                  batch.edge_index.to(torch.int64),
                  data.edge_index.to(torch.int64),
                  batch.x,
                  batch.x,
              )
  
imports: import os.path
  import numpy
  import pytest
  import torch
  import torch_geometric.typing
  from torch_geometric import EdgeIndex
  from torch_geometric.data import Data, HeteroData
  from torch_geometric.loader import NeighborLoader
  from torch_geometric.nn import GraphConv, to_hetero
  from torch_geometric.sampler.base import SubgraphType
  from torch_geometric.testing import MyFeatureStore, MyGraphStore, get_random_edge_index, get_random_tensor_frame, onlyLinux, onlyNeighborSampler, onlyOnline, withCUDA, withPackage
  from torch_geometric.typing import WITH_EDGE_TIME_NEIGHBOR_SAMPLE, WITH_PYG_LIB, WITH_TORCH_SPARSE, WITH_WEIGHTED_NEIGHBOR_SAMPLE, TensorFrame
  from torch_geometric.utils import is_undirected, sort_edge_index, to_torch_csr_tensor, to_undirected
label_desc: Use image node_id 2 for calling a global function with example usage: test_homo_neighbor_loader_basic(device, subgraph_type, dtype, filter_per_worker) without return types