prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Data Batch problem in PyG
  ### 🐛 Describe the bug
  
  Hi. I am a computational physics researcher and was using PyG very well.
  my pyg code was working well a few weeks ago, but now that I run my code, it is not working anymore without any changes.
  
  the problem is like below.
  I have many material structures and in my "custom_dataset" class, these are preprocessed and all graph informations (node features, edge features, edge index etc) are inserted into "Data" object in PyTorch geometric.
  You can see that each preprocessed sample with index $i$ was printed normal "Data" object in pyg
  
  ![캡처2](https://user-images.githubusercontent.com/76824867/175221069-874bf9b1-308b-4d99-8459-b3479307e78a.PNG)
  
  But When I insert my custom dataset class into pyg DataLoader and I did like below,
  
  ``` Python
  sample = next(iter(train_loader)) # batch sample
  ```
  
  batch sample is denoted by "DataDataBatch". I didn't see this kind of object name.
  and i can't use "sample.x' or "sample.edge_index" command. Instead I need to do like this
  
  ![캡처3](https://user-images.githubusercontent.com/76824867/175222628-75eee3a2-869a-4c80-8dd5-5f0f160682f0.PNG)
  
  I want to use expressions like "sample.x", "sample.edge_index" or "sample.edge_attr" as like before. 
  I expect your kind explanations. Thank you.
  
  
  ### Environment
  
  * PyG version: `2.0.5`
  * PyTorch version: `1.11.0+cu113`
  * OS: `GoogleColab Pro Plus`
  * Python version: `Python 3.7.13 in colab`
  * CUDA/cuDNN version:
  * How you installed PyTorch and PyG (`conda`, `pip`, source): 
  ``` python
  # Install required packages.
  import os
  import torch
  os.environ['TORCH'] = torch.__version__
  print(torch.__version__)
  !pip install -q torch-scatter -f https://data.pyg.org/whl/torch-${TORCH}.html
  !pip install -q torch-sparse -f https://data.pyg.org/whl/torch-${TORCH}.html
  !pip install -q git+https://github.com/pyg-team/pytorch_geometric.git
  !pip install -q pymatgen==2020.11.11  
  ```
  * Any other relevant information (*e.g.*, version of `torch-scatter`):
  
  
  </issue>
  <code>
  [start of torch_geometric/loader/dataloader.py]
  1 from collections.abc import Mapping, Sequence
  2 from typing import List, Optional, Union
  3 
  4 import torch.utils.data
  5 from torch.utils.data.dataloader import default_collate
  6 
  7 from torch_geometric.data import Batch, Dataset
  8 from torch_geometric.data.data import BaseData
  9 
  10 
  11 class Collater:
  12     def __init__(self, follow_batch, exclude_keys):
  13         self.follow_batch = follow_batch
  14         self.exclude_keys = exclude_keys
  15 
  16     def __call__(self, batch):
  17         elem = batch[0]
  18         if isinstance(elem, BaseData):
  19             return Batch.from_data_list(batch, self.follow_batch,
  20                                         self.exclude_keys)
  21         elif isinstance(elem, torch.Tensor):
  22             return default_collate(batch)
  23         elif isinstance(elem, float):
  24             return torch.tensor(batch, dtype=torch.float)
  25         elif isinstance(elem, int):
  26             return torch.tensor(batch)
  27         elif isinstance(elem, str):
  28             return batch
  29         elif isinstance(elem, Mapping):
  30             return {key: self([data[key] for data in batch]) for key in elem}
  31         elif isinstance(elem, tuple) and hasattr(elem, '_fields'):
  32             return type(elem)(*(self(s) for s in zip(*batch)))
  33         elif isinstance(elem, Sequence) and not isinstance(elem, str):
  34             return [self(s) for s in zip(*batch)]
  35 
  36         raise TypeError(f'DataLoader found invalid type: {type(elem)}')
  37 
  38     def collate(self, batch):  # Deprecated...
  39         return self(batch)
  40 
  41 
  42 class DataLoader(torch.utils.data.DataLoader):
  43     r"""A data loader which merges data objects from a
  44     :class:`torch_geometric.data.Dataset` to a mini-batch.
  45     Data objects can be either of type :class:`~torch_geometric.data.Data` or
  46     :class:`~torch_geometric.data.HeteroData`.
  47 
  48     Args:
  49         dataset (Dataset): The dataset from which to load the data.
  50         batch_size (int, optional): How many samples per batch to load.
  51             (default: :obj:`1`)
  52         shuffle (bool, optional): If set to :obj:`True`, the data will be
  53             reshuffled at every epoch. (default: :obj:`False`)
  54         follow_batch (List[str], optional): Creates assignment batch
  55             vectors for each key in the list. (default: :obj:`None`)
  56         exclude_keys (List[str], optional): Will exclude each key in the
  57             list. (default: :obj:`None`)
  58         **kwargs (optional): Additional arguments of
  59             :class:`torch.utils.data.DataLoader`.
  60     """
  61     def __init__(
  62         self,
  63         dataset: Union[Dataset, List[BaseData]],
  64         batch_size: int = 1,
  65         shuffle: bool = False,
  66         follow_batch: Optional[List[str]] = None,
  67         exclude_keys: Optional[List[str]] = None,
  68         **kwargs,
  69     ):
  70 
  71         if 'collate_fn' in kwargs:
  72             del kwargs['collate_fn']
  73 
  74         # Save for PyTorch Lightning < 1.6:
  75         self.follow_batch = follow_batch
  76         self.exclude_keys = exclude_keys
  77 
  78         super().__init__(
  79             dataset,
  80             batch_size,
  81             shuffle,
  82             collate_fn=Collater(follow_batch, exclude_keys),
  83             **kwargs,
  84         )
  85
  [end of torch_geometric/loader/dataloader.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/torch_geometric/loader/dataloader.py b/torch_geometric/loader/dataloader.py
  --- a/torch_geometric/loader/dataloader.py
  +++ b/torch_geometric/loader/dataloader.py
  @@ -1,4 +1,5 @@
   from collections.abc import Mapping, Sequence
  +from inspect import signature
   from typing import List, Optional, Union
   
   import torch.utils.data
  @@ -39,6 +40,28 @@
           return self(batch)
   
   
  +# PyG 'Data' objects are subclasses of MutableMapping, which is an
  +# instance of collections.abc.Mapping. Currently, PyTorch pin_memory
  +# for DataLoaders treats the returned batches as Mapping objects and
  +# calls `pin_memory` on each element in `Data.__dict__`, which is not
  +# desired behavior if 'Data' has a `pin_memory` function. We patch
  +# this behavior here by monkeypatching `pin_memory`, but can hopefully patch
  +# this in PyTorch in the future:
  +__torch_pin_memory = torch.utils.data._utils.pin_memory.pin_memory
  +__torch_pin_memory_params = signature(__torch_pin_memory).parameters
  +
  +
  +def pin_memory(data, device=None):
  +    if hasattr(data, "pin_memory"):
  +        return data.pin_memory()
  +    if len(__torch_pin_memory_params) > 1:
  +        return __torch_pin_memory(data, device)
  +    return __torch_pin_memory(data)
  +
  +
  +torch.utils.data._utils.pin_memory.pin_memory = pin_memory
  +
  +
   class DataLoader(torch.utils.data.DataLoader):
       r"""A data loader which merges data objects from a
       :class:`torch_geometric.data.Dataset` to a mini-batch.
  
verification_info: {"golden_diff": "diff --git a/torch_geometric/loader/dataloader.py b/torch_geometric/loader/dataloader.py\n--- a/torch_geometric/loader/dataloader.py\n+++ b/torch_geometric/loader/dataloader.py\n@@ -1,4 +1,5 @@\n from collections.abc import Mapping, Sequence\n+from inspect import signature\n from typing import List, Optional, Union\n \n import torch.utils.data\n@@ -39,6 +40,28 @@\n         return self(batch)\n \n \n+# PyG 'Data' objects are subclasses of MutableMapping, which is an\n+# instance of collections.abc.Mapping. Currently, PyTorch pin_memory\n+# for DataLoaders treats the returned batches as Mapping objects and\n+# calls `pin_memory` on each element in `Data.__dict__`, which is not\n+# desired behavior if 'Data' has a `pin_memory` function. We patch\n+# this behavior here by monkeypatching `pin_memory`, but can hopefully patch\n+# this in PyTorch in the future:\n+__torch_pin_memory = torch.utils.data._utils.pin_memory.pin_memory\n+__torch_pin_memory_params = signature(__torch_pin_memory).parameters\n+\n+\n+def pin_memory(data, device=None):\n+    if hasattr(data, \"pin_memory\"):\n+        return data.pin_memory()\n+    if len(__torch_pin_memory_params) > 1:\n+        return __torch_pin_memory(data, device)\n+    return __torch_pin_memory(data)\n+\n+\n+torch.utils.data._utils.pin_memory.pin_memory = pin_memory\n+\n+\n class DataLoader(torch.utils.data.DataLoader):\n     r\"\"\"A data loader which merges data objects from a\n     :class:`torch_geometric.data.Dataset` to a mini-batch.\n", "issue": "Data Batch problem in PyG\n### \ud83d\udc1b Describe the bug\n\nHi. I am a computational physics researcher and was using PyG very well.\r\nmy pyg code was working well a few weeks ago, but now that I run my code, it is not working anymore without any changes.\r\n\r\nthe problem is like below.\r\nI have many material structures and in my \"custom_dataset\" class, these are preprocessed and all graph informations (node features, edge features, edge index etc) are inserted into \"Data\" object in PyTorch geometric.\r\nYou can see that each preprocessed sample with index $i$ was printed normal \"Data\" object in pyg\r\n\r\n![\ucea1\ucc982](https://user-images.githubusercontent.com/76824867/175221069-874bf9b1-308b-4d99-8459-b3479307e78a.PNG)\r\n\r\nBut When I insert my custom dataset class into pyg DataLoader and I did like below,\r\n\r\n``` Python\r\nsample = next(iter(train_loader)) # batch sample\r\n```\r\n\r\nbatch sample is denoted by \"DataDataBatch\". I didn't see this kind of object name.\r\nand i can't use \"sample.x' or \"sample.edge_index\" command. Instead I need to do like this\r\n\r\n![\ucea1\ucc983](https://user-images.githubusercontent.com/76824867/175222628-75eee3a2-869a-4c80-8dd5-5f0f160682f0.PNG)\r\n\r\nI want to use expressions like \"sample.x\", \"sample.edge_index\" or \"sample.edge_attr\" as like before. \r\nI expect your kind explanations. Thank you.\r\n\n\n### Environment\n\n* PyG version: `2.0.5`\r\n* PyTorch version: `1.11.0+cu113`\r\n* OS: `GoogleColab Pro Plus`\r\n* Python version: `Python 3.7.13 in colab`\r\n* CUDA/cuDNN version:\r\n* How you installed PyTorch and PyG (`conda`, `pip`, source): \r\n``` python\r\n# Install required packages.\r\nimport os\r\nimport torch\r\nos.environ['TORCH'] = torch.__version__\r\nprint(torch.__version__)\r\n!pip install -q torch-scatter -f https://data.pyg.org/whl/torch-${TORCH}.html\r\n!pip install -q torch-sparse -f https://data.pyg.org/whl/torch-${TORCH}.html\r\n!pip install -q git+https://github.com/pyg-team/pytorch_geometric.git\r\n!pip install -q pymatgen==2020.11.11  \r\n```\r\n* Any other relevant information (*e.g.*, version of `torch-scatter`):\r\n\n", "before_files": [{"content": "from collections.abc import Mapping, Sequence\nfrom typing import List, Optional, Union\n\nimport torch.utils.data\nfrom torch.utils.data.dataloader import default_collate\n\nfrom torch_geometric.data import Batch, Dataset\nfrom torch_geometric.data.data import BaseData\n\n\nclass Collater:\n    def __init__(self, follow_batch, exclude_keys):\n        self.follow_batch = follow_batch\n        self.exclude_keys = exclude_keys\n\n    def __call__(self, batch):\n        elem = batch[0]\n        if isinstance(elem, BaseData):\n            return Batch.from_data_list(batch, self.follow_batch,\n                                        self.exclude_keys)\n        elif isinstance(elem, torch.Tensor):\n            return default_collate(batch)\n        elif isinstance(elem, float):\n            return torch.tensor(batch, dtype=torch.float)\n        elif isinstance(elem, int):\n            return torch.tensor(batch)\n        elif isinstance(elem, str):\n            return batch\n        elif isinstance(elem, Mapping):\n            return {key: self([data[key] for data in batch]) for key in elem}\n        elif isinstance(elem, tuple) and hasattr(elem, '_fields'):\n            return type(elem)(*(self(s) for s in zip(*batch)))\n        elif isinstance(elem, Sequence) and not isinstance(elem, str):\n            return [self(s) for s in zip(*batch)]\n\n        raise TypeError(f'DataLoader found invalid type: {type(elem)}')\n\n    def collate(self, batch):  # Deprecated...\n        return self(batch)\n\n\nclass DataLoader(torch.utils.data.DataLoader):\n    r\"\"\"A data loader which merges data objects from a\n    :class:`torch_geometric.data.Dataset` to a mini-batch.\n    Data objects can be either of type :class:`~torch_geometric.data.Data` or\n    :class:`~torch_geometric.data.HeteroData`.\n\n    Args:\n        dataset (Dataset): The dataset from which to load the data.\n        batch_size (int, optional): How many samples per batch to load.\n            (default: :obj:`1`)\n        shuffle (bool, optional): If set to :obj:`True`, the data will be\n            reshuffled at every epoch. (default: :obj:`False`)\n        follow_batch (List[str], optional): Creates assignment batch\n            vectors for each key in the list. (default: :obj:`None`)\n        exclude_keys (List[str], optional): Will exclude each key in the\n            list. (default: :obj:`None`)\n        **kwargs (optional): Additional arguments of\n            :class:`torch.utils.data.DataLoader`.\n    \"\"\"\n    def __init__(\n        self,\n        dataset: Union[Dataset, List[BaseData]],\n        batch_size: int = 1,\n        shuffle: bool = False,\n        follow_batch: Optional[List[str]] = None,\n        exclude_keys: Optional[List[str]] = None,\n        **kwargs,\n    ):\n\n        if 'collate_fn' in kwargs:\n            del kwargs['collate_fn']\n\n        # Save for PyTorch Lightning < 1.6:\n        self.follow_batch = follow_batch\n        self.exclude_keys = exclude_keys\n\n        super().__init__(\n            dataset,\n            batch_size,\n            shuffle,\n            collate_fn=Collater(follow_batch, exclude_keys),\n            **kwargs,\n        )\n", "path": "torch_geometric/loader/dataloader.py"}]}