Repository: dmlc/dgl

Issue:
Loading regression datasets from dgl.data.TUDatasets throws an error
## 🐛 Bug

All regression datasets in TUdatasets throw an error when accessed through `dgl.data.TUDatasets`

## To Reproduce

The following shows an example for `alchemy_full` 

```
from dgl.data import TUDataset
TUDataset('alchemy_full')
```

which throws this error `FileNotFoundError: [Errno 2] No such file or directory: '/Users/henry/.dgl/alchemy_full/alchemy_full/alchemy_full_graph_labels.txt'`

The following shows the issue holds for all the regression datasets (this may take a while to run, it took about 30 minutes on my laptop):

```
from dgl.data import TUDataset

regression_datasets = ['alchemy_full', 'aspirin', 'benzene', 'ethanol', 'malonaldehyde', 
                       'naphthalene', 'QM9', 'salicylic_acid', 'toluene', 'uracil', 
                       'ZINC_full', 'ZINC_test', 'ZINC_train', 'ZINC_val']

error_messages = []

for dataset in regression_datasets:
    try:
        TUDataset(dataset)
    except FileNotFoundError as err:
        error_messages.append(err.__str__())
        
for error_message in error_messages:
    print(error_message)
```

The output of the above code is the following

```
[Errno 2] No such file or directory: '/Users/henry/.dgl/alchemy_full/alchemy_full/alchemy_full_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/aspirin/aspirin/aspirin_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/benzene/benzene/benzene_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ethanol/ethanol/ethanol_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/malonaldehyde/malonaldehyde/malonaldehyde_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/naphthalene/naphthalene/naphthalene_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/QM9/QM9/QM9_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/salicylic_acid/salicylic_acid/salicylic_acid_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/toluene/toluene/toluene_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/uracil/uracil/uracil_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_full/ZINC_full/ZINC_full_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_test/ZINC_test/ZINC_test_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_train/ZINC_train/ZINC_train_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_val/ZINC_val/ZINC_val_graph_labels.txt'
```

The code is trying to read the file `f"~/.dgl/{dataset}/{dataset}/{dataset}_graph_labels.txt"`  which I think only exists if the dataset is for classification. It looks like the file with the graph targets is given by `f"~/.dgl/{dataset}/{dataset}/{dataset}_graph_attributes.txt}"`.

The label should be a 1D tensor of size 1 for most of these datasets. I'm guessing for datasets like QM9 the expected behaviour would be a 1D tensor of size 19.

## Environment

 - DGL Version (e.g., 1.0): 0.6.1
 - Backend Library & Version (e.g., PyTorch 0.4.1, MXNet/Gluon 1.3): 1.8.1
 - OS (e.g., Linux): MacOS 10.15.7
 - How you installed DGL (`conda`, `pip`, source): conda
 - Python version: 3.8.8

Loading regression datasets from dgl.data.TUDatasets throws an error
## 🐛 Bug

All regression datasets in TUdatasets throw an error when accessed through `dgl.data.TUDatasets`

## To Reproduce

The following shows an example for `alchemy_full` 

```
from dgl.data import TUDataset
TUDataset('alchemy_full')
```

which throws this error `FileNotFoundError: [Errno 2] No such file or directory: '/Users/henry/.dgl/alchemy_full/alchemy_full/alchemy_full_graph_labels.txt'`

The following shows the issue holds for all the regression datasets (this may take a while to run, it took about 30 minutes on my laptop):

```
from dgl.data import TUDataset

regression_datasets = ['alchemy_full', 'aspirin', 'benzene', 'ethanol', 'malonaldehyde', 
                       'naphthalene', 'QM9', 'salicylic_acid', 'toluene', 'uracil', 
                       'ZINC_full', 'ZINC_test', 'ZINC_train', 'ZINC_val']

error_messages = []

for dataset in regression_datasets:
    try:
        TUDataset(dataset)
    except FileNotFoundError as err:
        error_messages.append(err.__str__())
        
for error_message in error_messages:
    print(error_message)
```

The output of the above code is the following

```
[Errno 2] No such file or directory: '/Users/henry/.dgl/alchemy_full/alchemy_full/alchemy_full_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/aspirin/aspirin/aspirin_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/benzene/benzene/benzene_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ethanol/ethanol/ethanol_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/malonaldehyde/malonaldehyde/malonaldehyde_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/naphthalene/naphthalene/naphthalene_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/QM9/QM9/QM9_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/salicylic_acid/salicylic_acid/salicylic_acid_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/toluene/toluene/toluene_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/uracil/uracil/uracil_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_full/ZINC_full/ZINC_full_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_test/ZINC_test/ZINC_test_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_train/ZINC_train/ZINC_train_graph_labels.txt'
[Errno 2] No such file or directory: '/Users/henry/.dgl/ZINC_val/ZINC_val/ZINC_val_graph_labels.txt'
```

The code is trying to read the file `f"~/.dgl/{dataset}/{dataset}/{dataset}_graph_labels.txt"`  which I think only exists if the dataset is for classification. It looks like the file with the graph targets is given by `f"~/.dgl/{dataset}/{dataset}/{dataset}_graph_attributes.txt}"`.

The label should be a 1D tensor of size 1 for most of these datasets. I'm guessing for datasets like QM9 the expected behaviour would be a 1D tensor of size 19.

## Environment

 - DGL Version (e.g., 1.0): 0.6.1
 - Backend Library & Version (e.g., PyTorch 0.4.1, MXNet/Gluon 1.3): 1.8.1
 - OS (e.g., Linux): MacOS 10.15.7
 - How you installed DGL (`conda`, `pip`, source): conda
 - Python version: 3.8.8



Discussion:

Resolving patch:
diff --git a/python/dgl/data/tu.py b/python/dgl/data/tu.py
--- a/python/dgl/data/tu.py
+++ b/python/dgl/data/tu.py
@@ -93,8 +93,17 @@ def process(self):
 
         DS_indicator = self._idx_from_zero(
             np.genfromtxt(self._file_path("graph_indicator"), dtype=int))
-        DS_graph_labels = self._idx_from_zero(
-            np.genfromtxt(self._file_path("graph_labels"), dtype=int))
+        if os.path.exists(self._file_path("graph_labels")):
+            DS_graph_labels = self._idx_from_zero(
+                np.genfromtxt(self._file_path("graph_labels"), dtype=int))
+            self.num_labels = max(DS_graph_labels) + 1
+            self.graph_labels = DS_graph_labels 
+        elif os.path.exists(self._file_path("graph_attributes")):
+            DS_graph_labels = np.genfromtxt(self._file_path("graph_attributes"), dtype=float)
+            self.num_labels = None
+            self.graph_labels = DS_graph_labels
+        else:
+            raise Exception("Unknown graph label or graph attributes")
 
         g = dgl_graph(([], []))
         g.add_nodes(int(DS_edge_list.max()) + 1)
@@ -109,8 +118,6 @@ def process(self):
                 self.max_num_node = len(node_idx[0])
 
         self.graph_lists = [g.subgraph(node_idx) for node_idx in node_idx_list]
-        self.num_labels = max(DS_graph_labels) + 1
-        self.graph_labels = DS_graph_labels
 
         try:
             DS_node_labels = self._idx_from_zero(
@@ -296,8 +303,18 @@ def process(self):
             loadtxt(self._file_path("A"), delimiter=",").astype(int))
         DS_indicator = self._idx_from_zero(
             loadtxt(self._file_path("graph_indicator"), delimiter=",").astype(int))
-        DS_graph_labels = self._idx_reset(
-            loadtxt(self._file_path("graph_labels"), delimiter=",").astype(int))
+        
+        if os.path.exists(self._file_path("graph_labels")):
+            DS_graph_labels = self._idx_reset(
+                loadtxt(self._file_path("graph_labels"), delimiter=",").astype(int))               
+            self.num_labels = max(DS_graph_labels) + 1
+            self.graph_labels = F.tensor(DS_graph_labels)     
+        elif os.path.exists(self._file_path("graph_attributes")):
+            DS_graph_labels = loadtxt(self._file_path("graph_attributes"), delimiter=",").astype(float)
+            self.num_labels = None
+            self.graph_labels = F.tensor(DS_graph_labels)     
+        else:
+            raise Exception("Unknown graph label or graph attributes")
 
         g = dgl_graph(([], []))
         g.add_nodes(int(DS_edge_list.max()) + 1)
@@ -311,8 +328,6 @@ def process(self):
             if len(node_idx[0]) > self.max_num_node:
                 self.max_num_node = len(node_idx[0])
 
-        self.num_labels = max(DS_graph_labels) + 1
-        self.graph_labels = F.tensor(DS_graph_labels)
 
         self.attr_dict = {
             'node_labels': ('ndata', 'node_labels'),


Test patch:
diff --git a/tests/compute/test_data.py b/tests/compute/test_data.py
--- a/tests/compute/test_data.py
+++ b/tests/compute/test_data.py
@@ -24,6 +24,12 @@ def test_gin():
         assert len(ds) == n_graphs, (len(ds), name)
 
 
+
+@unittest.skipIf(F._default_context_str == 'gpu', reason="Datasets don't need to be tested on GPU.")
+def test_tudataset_regression():    
+    ds = data.TUDataset('ZINC_test', force_reload=True)
+    assert len(ds) == 5000
+
 @unittest.skipIf(F._default_context_str == 'gpu', reason="Datasets don't need to be tested on GPU.")
 def test_data_hash():
     class HashTestDataset(data.DGLDataset):