Beispiel #1
0
def _datadesc(obj: Any):
    from dace import data
    if isinstance(obj, data.Data):
        return obj
    elif symbolic.issymbolic(obj):
        return data.Scalar(symbolic.symtype(obj))
    elif isinstance(obj, dtypes.typeclass):
        return data.Scalar(obj)
    return data.Scalar(dtypes.typeclass(type(obj)))
Beispiel #2
0
def create_datadescriptor(obj):
    """ Creates a data descriptor from various types of objects.
        @see: dace.data.Data
    """
    from dace import dtypes  # Avoiding import loops
    if isinstance(obj, Data):
        return obj
    elif hasattr(obj, '__descriptor__'):
        return obj.__descriptor__()
    elif hasattr(obj, 'descriptor'):
        return obj.descriptor
    elif isinstance(obj, (list, tuple, numpy.ndarray)):
        if isinstance(obj, (list, tuple)):  # Lists and tuples are cast to numpy
            obj = numpy.array(obj)

        if obj.dtype.fields is not None:  # Struct
            dtype = dtypes.struct(
                'unnamed', **{
                    k: dtypes.typeclass(v[0].type)
                    for k, v in obj.dtype.fields.items()
                })
        else:
            dtype = dtypes.typeclass(obj.dtype.type)
        return Array(dtype=dtype,
                     strides=tuple(s // obj.itemsize for s in obj.strides),
                     shape=obj.shape)
    # special case for torch tensors. Maybe __array__ could be used here for a more
    # general solution, but torch doesn't support __array__ for cuda tensors.
    elif type(obj).__module__ == "torch" and type(obj).__name__ == "Tensor":
        try:
            import torch
            return Array(dtype=dtypes.TORCH_DTYPE_TO_TYPECLASS[obj.dtype],
                         strides=obj.stride(),
                         shape=tuple(obj.shape))
        except ImportError:
            raise ValueError(
                "Attempted to convert a torch.Tensor, but torch could not be imported"
            )
    elif symbolic.issymbolic(obj):
        return Scalar(symbolic.symtype(obj))
    elif isinstance(obj, dtypes.typeclass):
        return Scalar(obj)
    elif obj in {int, float, complex, bool, None}:
        return Scalar(dtypes.typeclass(obj))
    elif callable(obj):
        # Cannot determine return value/argument types from function object
        return Scalar(dtypes.callback(None))
    return Scalar(dtypes.typeclass(type(obj)))
Beispiel #3
0
def _create_datadescriptor(obj):
    """ Creates a data descriptor from various types of objects.
        @see: dace.data.Data
    """
    if isinstance(obj, data.Data):
        return obj

    try:
        return obj.descriptor
    except AttributeError:
        if isinstance(obj, numpy.ndarray):
            return data.Array(dtype=types.typeclass(obj.dtype.type),
                              shape=obj.shape)
        if symbolic.issymbolic(obj):
            return data.Scalar(symbolic.symtype(obj))
        if isinstance(obj, types.typeclass):
            return data.Scalar(obj)
        return data.Scalar(types.typeclass(type(obj)))
Beispiel #4
0
def create_datadescriptor(obj):
    """ Creates a data descriptor from various types of objects.
        @see: dace.data.Data
    """
    from dace import dtypes  # Avoiding import loops
    if isinstance(obj, Data):
        return obj

    try:
        return obj.descriptor
    except AttributeError:
        if isinstance(obj, numpy.ndarray):
            return Array(dtype=dtypes.typeclass(obj.dtype.type),
                         shape=obj.shape)
        if symbolic.issymbolic(obj):
            return Scalar(symbolic.symtype(obj))
        if isinstance(obj, dtypes.typeclass):
            return Scalar(obj)
        return Scalar(dtypes.typeclass(type(obj)))
Beispiel #5
0
def create_datadescriptor(obj):
    """ Creates a data descriptor from various types of objects.
        @see: dace.data.Data
    """
    from dace import dtypes  # Avoiding import loops
    if isinstance(obj, Data):
        return obj
    elif hasattr(obj, '__descriptor__'):
        return obj.__descriptor__()
    elif hasattr(obj, 'descriptor'):
        return obj.descriptor
    elif isinstance(obj, (list, tuple, numpy.ndarray)):
        if isinstance(obj,
                      (list, tuple)):  # Lists and tuples are cast to numpy
            obj = numpy.array(obj)

        if obj.dtype.fields is not None:  # Struct
            dtype = dtypes.struct(
                'unnamed', **{
                    k: dtypes.typeclass(v[0].type)
                    for k, v in obj.dtype.fields.items()
                })
        else:
            dtype = dtypes.typeclass(obj.dtype.type)
        return Array(dtype=dtype,
                     strides=tuple(s // obj.itemsize for s in obj.strides),
                     shape=obj.shape)
    elif symbolic.issymbolic(obj):
        return Scalar(symbolic.symtype(obj))
    elif isinstance(obj, dtypes.typeclass):
        return Scalar(obj)
    elif obj in {int, float, complex, bool, None}:
        return Scalar(dtypes.typeclass(obj))
    elif callable(obj):
        # Cannot determine return value/argument types from function object
        return Scalar(dtypes.callback(None))
    return Scalar(dtypes.typeclass(type(obj)))
Beispiel #6
0
def create_datadescriptor(obj, no_custom_desc=False):
    """ Creates a data descriptor from various types of objects.
        @see: dace.data.Data
    """
    from dace import dtypes  # Avoiding import loops
    if isinstance(obj, Data):
        return obj
    elif not no_custom_desc and hasattr(obj, '__descriptor__'):
        return obj.__descriptor__()
    elif not no_custom_desc and hasattr(obj, 'descriptor'):
        return obj.descriptor
    elif isinstance(obj, (list, tuple, numpy.ndarray)):
        if isinstance(obj, (list, tuple)):  # Lists and tuples are cast to numpy
            obj = numpy.array(obj)

        if obj.dtype.fields is not None:  # Struct
            dtype = dtypes.struct('unnamed', **{k: dtypes.typeclass(v[0].type) for k, v in obj.dtype.fields.items()})
        else:
            dtype = dtypes.typeclass(obj.dtype.type)
        return Array(dtype=dtype, strides=tuple(s // obj.itemsize for s in obj.strides), shape=obj.shape)
    # special case for torch tensors. Maybe __array__ could be used here for a more
    # general solution, but torch doesn't support __array__ for cuda tensors.
    elif type(obj).__module__ == "torch" and type(obj).__name__ == "Tensor":
        try:
            # If torch is importable, define translations between typeclasses and torch types. These are reused by daceml.
            # conversion happens here in pytorch:
            # https://github.com/pytorch/pytorch/blob/143ef016ee1b6a39cf69140230d7c371de421186/torch/csrc/utils/tensor_numpy.cpp#L237
            import torch
            TYPECLASS_TO_TORCH_DTYPE = {
                dtypes.bool_: torch.bool,
                dtypes.int8: torch.int8,
                dtypes.int16: torch.int16,
                dtypes.int32: torch.int32,
                dtypes.int64: torch.int64,
                dtypes.uint8: torch.uint8,
                dtypes.float16: torch.float16,
                dtypes.float32: torch.float32,
                dtypes.float64: torch.float64,
                dtypes.complex64: torch.complex64,
                dtypes.complex128: torch.complex128,
            }

            TORCH_DTYPE_TO_TYPECLASS = {v: k for k, v in TYPECLASS_TO_TORCH_DTYPE.items()}

            return Array(dtype=TORCH_DTYPE_TO_TYPECLASS[obj.dtype], strides=obj.stride(), shape=tuple(obj.shape))
        except ImportError:
            raise ValueError("Attempted to convert a torch.Tensor, but torch could not be imported")
    elif dtypes.is_gpu_array(obj):
        interface = obj.__cuda_array_interface__
        dtype = dtypes.typeclass(numpy.dtype(interface['typestr']).type)
        itemsize = numpy.dtype(interface['typestr']).itemsize
        if len(interface['shape']) == 0:
            return Scalar(dtype, storage=dtypes.StorageType.GPU_Global)
        return Array(dtype=dtype,
                     shape=interface['shape'],
                     strides=(tuple(s // itemsize for s in interface['strides']) if interface['strides'] else None),
                     storage=dtypes.StorageType.GPU_Global)
    elif symbolic.issymbolic(obj):
        return Scalar(symbolic.symtype(obj))
    elif isinstance(obj, dtypes.typeclass):
        return Scalar(obj)
    elif (obj is int or obj is float or obj is complex or obj is bool or obj is None):
        return Scalar(dtypes.typeclass(obj))
    elif isinstance(obj, type) and issubclass(obj, numpy.number):
        return Scalar(dtypes.typeclass(obj))
    elif isinstance(obj, (Number, numpy.number, numpy.bool, numpy.bool_)):
        return Scalar(dtypes.typeclass(type(obj)))
    elif obj is type(None):
        # NoneType is void *
        return Scalar(dtypes.pointer(dtypes.typeclass(None)))
    elif callable(obj):
        # Cannot determine return value/argument types from function object
        return Scalar(dtypes.callback(None))
    elif isinstance(obj, str):
        return Scalar(dtypes.string())

    raise TypeError(f'Could not create a DaCe data descriptor from object {obj}. '
                    'If this is a custom object, consider creating a `__descriptor__` '
                    'adaptor method to the type hint or object itself.')
Beispiel #7
0
def create_datadescriptor(obj):
    """ Creates a data descriptor from various types of objects.
        @see: dace.data.Data
    """
    from dace import dtypes  # Avoiding import loops
    if isinstance(obj, Data):
        return obj
    elif hasattr(obj, '__descriptor__'):
        return obj.__descriptor__()
    elif hasattr(obj, 'descriptor'):
        return obj.descriptor
    elif isinstance(obj, (list, tuple, numpy.ndarray)):
        if isinstance(obj, (list, tuple)):  # Lists and tuples are cast to numpy
            obj = numpy.array(obj)

        if obj.dtype.fields is not None:  # Struct
            dtype = dtypes.struct(
                'unnamed', **{
                    k: dtypes.typeclass(v[0].type)
                    for k, v in obj.dtype.fields.items()
                })
        else:
            dtype = dtypes.typeclass(obj.dtype.type)
        return Array(dtype=dtype,
                     strides=tuple(s // obj.itemsize for s in obj.strides),
                     shape=obj.shape)
    # special case for torch tensors. Maybe __array__ could be used here for a more
    # general solution, but torch doesn't support __array__ for cuda tensors.
    elif type(obj).__module__ == "torch" and type(obj).__name__ == "Tensor":
        try:
            import torch
            return Array(dtype=dtypes.TORCH_DTYPE_TO_TYPECLASS[obj.dtype],
                         strides=obj.stride(),
                         shape=tuple(obj.shape))
        except ImportError:
            raise ValueError(
                "Attempted to convert a torch.Tensor, but torch could not be imported"
            )
    elif dtypes.is_gpu_array(obj):
        interface = obj.__cuda_array_interface__
        dtype = dtypes.typeclass(numpy.dtype(interface['typestr']).type)
        itemsize = numpy.dtype(interface['typestr']).itemsize
        if len(interface['shape']) == 0:
            return Scalar(dtype, storage=dtypes.StorageType.GPU_Global)
        return Array(dtype=dtype,
                     shape=interface['shape'],
                     strides=(tuple(s // itemsize for s in interface['strides'])
                              if interface['strides'] else None),
                     storage=dtypes.StorageType.GPU_Global)
    elif symbolic.issymbolic(obj):
        return Scalar(symbolic.symtype(obj))
    elif isinstance(obj, dtypes.typeclass):
        return Scalar(obj)
    elif (obj is int or obj is float or obj is complex or obj is bool
          or obj is None):
        return Scalar(dtypes.typeclass(obj))
    elif isinstance(obj, type) and issubclass(obj, numpy.number):
        return Scalar(dtypes.typeclass(obj))
    elif isinstance(obj, (Number, numpy.number, numpy.bool, numpy.bool_)):
        return Scalar(dtypes.typeclass(type(obj)))
    elif callable(obj):
        # Cannot determine return value/argument types from function object
        return Scalar(dtypes.callback(None))
    elif isinstance(obj, str):
        return Scalar(dtypes.string())

    raise TypeError(
        f'Could not create a DaCe data descriptor from object {obj}. '
        'If this is a custom object, consider creating a `__descriptor__` '
        'adaptor method to the type hint or object itself.')