def __init__(
        self,
        D: int = 0,
        num_threads: int = -1,
        coordinate_map_type: CoordinateMapType = None,
        allocator_type: GPUMemoryAllocatorType = None,
        minkowski_algorithm: MinkowskiAlgorithm = None,
    ):
        r"""

        :attr:`D`: The order, or dimension of the coordinates.
        """
        global _coordinate_map_type, _allocator_type, _minkowski_algorithm
        if D < 1:
            raise ValueError(f"Invalid rank D > 0, D = {D}.")
        if num_threads < 0:
            num_threads = min(CPU_COUNT, 20)
        if coordinate_map_type is None:
            coordinate_map_type = _coordinate_map_type
        if allocator_type is None:
            allocator_type = _allocator_type
        if minkowski_algorithm is None:
            minkowski_algorithm = _minkowski_algorithm

        postfix = ""
        if coordinate_map_type == CoordinateMapType.CPU:
            postfix = "CPU"
        else:
            assert (
                _C.is_cuda_available()
            ), "The MinkowskiEngine was compiled with CPU_ONLY flag. If you want to compile with CUDA support, make sure `torch.cuda.is_available()` is True when you install MinkowskiEngine."

            postfix = "GPU" + ("_default" if allocator_type
                               == GPUMemoryAllocatorType.CUDA else "_c10")

        self.D = D
        self.minkowski_algorithm = minkowski_algorithm
        self._CoordinateManagerClass = getattr(
            _C, "CoordinateMapManager" + postfix)
        self._manager = self._CoordinateManagerClass(minkowski_algorithm,
                                                     num_threads)
    MinkowskiStackSum,
    MinkowskiStackMean,
    MinkowskiStackVar,
    cat,
    mean,
    var,
    to_sparse,
    to_sparse_all,
    dense_coordinates,
)

from MinkowskiOps import _sum as sum

import MinkowskiFunctional

import MinkowskiEngine.utils as utils

import MinkowskiEngine.modules as modules

from sparse_matrix_functions import (
    spmm,
    MinkowskiSPMMFunction,
    MinkowskiSPMMAverageFunction,
)

if not is_cuda_available():
    warnings.warn(" ".join([
        "The MinkowskiEngine was compiled with CPU_ONLY flag.",
        "If you want to compile with CUDA support, make sure `torch.cuda.is_available()` is True when you install MinkowskiEngine.",
    ]))
import MinkowskiEngineBackend._C as _C
from MinkowskiEngineBackend._C import (
    CoordinateMapKey,
    GPUMemoryAllocatorType,
    CoordinateMapType,
    MinkowskiAlgorithm,
    RegionType,
)

CPU_COUNT = os.cpu_count()
if "OMP_NUM_THREADS" in os.environ:
    CPU_COUNT = int(os.environ["OMP_NUM_THREADS"])

_allocator_type = GPUMemoryAllocatorType.PYTORCH
_coordinate_map_type = (CoordinateMapType.CUDA
                        if _C.is_cuda_available() else CoordinateMapType.CPU)
_minkowski_algorithm = MinkowskiAlgorithm.DEFAULT


def set_coordinate_map_type(coordinate_map_type: CoordinateMapType):
    r"""Set the default coordinate map type.

    The MinkowskiEngine automatically set the coordinate_map_type to CUDA if
    a NVIDIA GPU is available. To control the
    """
    global _coordinate_map_type
    _coordinate_map_type = coordinate_map_type


def set_gpu_allocator(backend: GPUMemoryAllocatorType):
    r"""Set the GPU memory allocator