NVIDIA / MinkowskiEngine

Minkowski Engine is an auto-diff neural network library for high-dimensional sparse tensors
https://nvidia.github.io/MinkowskiEngine
Other
2.43k stars 360 forks source link

TypeError when calling sparse_quantize with tensors #474

Closed anandcu3 closed 2 years ago

anandcu3 commented 2 years ago

In lines,

https://github.com/NVIDIA/MinkowskiEngine/blob/2f31bc51e0abdf89ed20730e531480df1b2cc64a/MinkowskiEngine/utils/quantization.py#L284

and

https://github.com/NVIDIA/MinkowskiEngine/blob/2f31bc51e0abdf89ed20730e531480df1b2cc64a/MinkowskiEngine/utils/quantization.py#L286

is_cuda is a boolean variable and not a callable method. This line raises the following error because of this issue:

File "/opt/conda/lib/python3.8/site-packages/MinkowskiEngine/utils/quantization.py", line 284, in sparse_quantize
not discrete_coordinates.is_cuda()
TypeError: 'bool' object is not callable

This happens when the collate function is used along with labels in them.

diagnostics.py output:

==========System==========
--
Linux-5.11.0-1028-aws-x86_64-with-glibc2.10
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.6 LTS"
3.8.13 \| packaged by conda-forge \| (default, Mar 25 2022, 06:04:10)
[GCC 10.3.0]
==========Pytorch==========
1.10.1
torch.cuda.is_available(): True
==========NVIDIA-SMI==========
/usr/bin/nvidia-smi
Driver Version 470.57.02
CUDA Version 11.4
VBIOS Version 94.02.75.00.01
Image Version G133.0210.00.02
GSP Firmware Version N/A
==========NVCC==========
/opt/conda/bin/nvcc
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Mon_May__3_19:15:13_PDT_2021
Cuda compilation tools, release 11.3, V11.3.109
Build cuda_11.3.r11.3/compiler.29920130_0
==========CC==========
/usr/bin/c++
c++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
==========MinkowskiEngine==========
0.5.4
MinkowskiEngine compiled with CUDA Support: True
NVCC version MinkowskiEngine is compiled: 11030
CUDART version MinkowskiEngine is compiled: 11030

Reproducable Code:

import numpy as np
from torch.utils.data import Dataset, DataLoader
import MinkowskiEngine as ME
import torch

class RandomLineDataset(Dataset):

    # Warning: read using mutable obects for default input arguments in python.
    def __init__(
        self,
        angle_range_rad=[-np.pi, np.pi],
        line_params=[
            -1,  # Start
            1,  # end
        ],
        is_linear_noise=True,
        dataset_size=100,
        num_samples=10000,
        quantization_size=0.005,
    ): 

        self.angle_range_rad = angle_range_rad
        self.is_linear_noise = is_linear_noise
        self.line_params = line_params
        self.dataset_size = dataset_size
        self.rng = np.random.RandomState(0)

        self.num_samples = num_samples
        self.num_data = int(0.2 * num_samples)
        self.num_noise = num_samples - self.num_data

        self.quantization_size = quantization_size

    def __len__(self):
        return self.dataset_size

    def _uniform_to_angle(self, u):
        return (self.angle_range_rad[1] - self.angle_range_rad[0]) * u + self.angle_range_rad[0]

    def _sample_noise(self, num, noise_params):
        noise = noise_params[0] + self.rng.randn(num, 1) * noise_params[1]
        return noise

    def _sample_xs(self, num):
        """Return random numbers between line_params[0], line_params[1]"""
        return (self.line_params[1] - self.line_params[0]) * self.rng.rand(num, 1) + self.line_params[0]

    def __getitem__(self, i):
        # Regardless of the input index, return randomized data
        angle, intercept = np.tan(self._uniform_to_angle(self.rng.rand())), self.rng.rand()

        # Line as x = cos(theta) * t, y = sin(theta) * t + intercept and random t's
        # Drop some samples
        xs_data = self._sample_xs(self.num_data)
        ys_data = angle * xs_data + intercept + self._sample_noise(self.num_data, [0, 0.1])

        noise = 4 * (self.rng.rand(self.num_noise, 2) - 0.5)

        # Concatenate data
        input = np.vstack([np.hstack([xs_data, ys_data]), noise])
        feats = input
        labels = np.vstack([np.ones((self.num_data, 1)), np.zeros((self.num_noise, 1))]).astype(np.int32)

        input = torch.Tensor(input)
        feats = torch.Tensor(feats)
        labels = torch.Tensor(labels)
        # Quantize the input
        discrete_coords, unique_feats, unique_labels = ME.utils.sparse_quantize(
            coordinates=input,
            features=feats,
            labels=labels,
            quantization_size=self.quantization_size,
            ignore_label=-100,
        )

        return (
            discrete_coords,
            unique_feats,
            unique_labels,
        )
train_dataset = RandomLineDataset()
train_loader = DataLoader(train_dataset, batch_size=1, collate_fn=ME.utils.batch_sparse_collate)
for coords, feats, labels in train_loader:
    print(coords.shape, feats.shape, labels.shape)
    break

Error Traceback:

Traceback (most recent call last):
File "/opt/conda/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/opt/conda/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/valohai/repository/me_scripts/test.py", line 87, in <module>
for coords, feats, labels in train_loader:
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 521, in __next__
data = self._next_data()
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 561, in _next_data
data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/_utils/fetch.py", line 49, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/_utils/fetch.py", line 49, in <listcomp>
data = [self.dataset[idx] for idx in possibly_batched_index]
File "/valohai/repository/me_scripts/test.py", line 70, in __getitem__
discrete_coords, unique_feats, unique_labels = ME.utils.sparse_quantize(
File "/opt/conda/lib/python3.8/site-packages/MinkowskiEngine/utils/quantization.py", line 284, in sparse_quantize
not discrete_coordinates.is_cuda()
TypeError: 'bool' object is not callable
Traceback (most recent call last):
File "/opt/conda/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/opt/conda/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/valohai/repository/me_scripts/classifier_train.py", line 157, in <module>
fire.Fire(main)
File "/opt/conda/lib/python3.8/site-packages/fire/core.py", line 141, in Fire
component_trace = _Fire(component, args, parsed_flag_args, context, name)
File "/opt/conda/lib/python3.8/site-packages/fire/core.py", line 466, in _Fire
component, remaining_args = _CallAndUpdateTrace(
File "/opt/conda/lib/python3.8/site-packages/fire/core.py", line 681, in _CallAndUpdateTrace
component = fn(*varargs, **kwargs)
File "/valohai/repository/me_scripts/classifier_train.py", line 143, in main
for coords, features, labels in train_loader:
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 521, in __next__
data = self._next_data()
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 561, in _next_data
data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/_utils/fetch.py", line 49, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File "/opt/conda/lib/python3.8/site-packages/torch/utils/data/_utils/fetch.py", line 49, in <listcomp>
data = [self.dataset[idx] for idx in possibly_batched_index]
File "/valohai/repository/me_scripts/classifier_train.py", line 119, in __getitem__
coordinates, features, y = ME.utils.sparse_quantize(coordinates, features=features, labels=y, device=self.device, quantization_size=self.voxel_size)
File "/opt/conda/lib/python3.8/site-packages/MinkowskiEngine/utils/quantization.py", line 284, in sparse_quantize
not discrete_coordinates.is_cuda()
TypeError: 'bool' object is not callable
anandcu3 commented 2 years ago

Workaround: Use numpy arrays instead of Tensors when using with labels