class_docstr: Array represents an abstracted array allocation. It can be instantiated by
  itself or can be instantiated by ``__cuda_array_interface__`` or
  ``__array_interface__`` compliant arrays, in which case it'll keep a
  reference to that data underneath. Also can be created from a pointer,
  specifying the characteristics of the array, in that case the owner of the
  data referred to by the pointer should be specified explicitly.
  
  Parameters
  ----------
  
  data : rmm.DeviceBuffer, cudf.Buffer, array_like, int, bytes, bytearray or           memoryview
      An array-like object or integer representing a
      device or host pointer to pre-allocated memory.
  owner : object, optional
      Python object to which the lifetime of the memory
      allocation is tied. If provided, a reference to this
      object is kept in this Buffer.
  dtype : data-type, optional
      Any object that can be interpreted as a numpy or cupy data type.
  shape : int or tuple of ints, optional
      Shape of created array.
  order: string, optional
      Whether to create a F-major or C-major array.
  mem_type: {'host', 'device'}, optional
      Whether data are on host or device.
  validate: bool, default=None
      Whether or not to check final array attributes against input options.
      If None, validation will occur only for CumlArray input and input that
      does not implement the array interface protocol and for which
      additional options were explicitly specified.
  
  Attributes
  ----------
  
  ptr : int
      Pointer to the data
  size : int
      Size of the array data in bytes
  _owner : Python Object
      Object that owns the data of the array
  shape : tuple of ints
      Shape of the array
  order : {'F', 'C'}
      'F' or 'C' to indicate Fortran-major or C-major order of the array
  strides : tuple of ints
      Strides of the data
  mem_type : MemoryType
      Memory type for how data are stored
  __array_interface__ : dictionary
      ``__array_interface__`` to interop with other libraries. This
      attribute is only present if data are host-accessible.
  __cuda_array_interface__ : dictionary
      ``__cuda_array_interface__`` to interop with other libraries. This
      attribute is only present if data are device-accessible.
  
  Notes
  -----
  
  cuml Array is not meant as an end-user array library. It is meant for
  cuML/RAPIDS developer consumption. Therefore it contains the minimum
  functionality. Its functionality is hidden by base.pyx to provide
  automatic output format conversion so that the users see the important
  attributes in whatever format they prefer.
  
  Todo: support cuda streams in the constructor. See:
  https://github.com/rapidsai/cuml/issues/1712
  https://github.com/rapidsai/cuml/pull/1396
class_docstr_tok: ["Array","represents","an","abstracted","array","allocation",".","It","can","be","instantiated","by","itself","or","can","be","instantiated","by","``","__cuda_array_interface__","``","or","``","__array_interface__","``","compliant","arrays",",","in","which","case","it","'ll","keep","a","reference","to","that","data","underneath",".","Also","can","be","created","from","a","pointer",",","specifying","the","characteristics","of","the","array",",","in","that","case","the","owner","of","the","data","referred","to","by","the","pointer","should","be","specified","explicitly",".","Parameters","--","--","--","--","--","data",":","rmm.DeviceBuffer",",","cudf.Buffer",",","array_like",",","int",",","bytes",",","bytearray","or","memoryview","An","array-like","object","or","integer","representing","a","device","or","host","pointer","to","pre-allocated","memory",".","owner",":","object",",","optional","Python","object","to","which","the","lifetime","of","the","memory","allocation","is","tied",".","If","provided",",","a","reference","to","this","object","is","kept","in","this","Buffer",".","dtype",":","data-type",",","optional","Any","object","that","can","be","interpreted","as","a","numpy","or","cupy","data","type",".","shape",":","int","or","tuple","of","ints",",","optional","Shape","of","created","array",".","order",":","string",",","optional","Whether","to","create","a","F-major","or","C-major","array",".","mem_type",":","{","'host","'",",","'device","'","}",",","optional","Whether","data","are","on","host","or","device",".","validate",":","bool",",","default=None","Whether","or","not","to","check","final","array","attributes","against","input","options",".","If","None",",","validation","will","occur","only","for","CumlArray","input","and","input","that","does","not","implement","the","array","interface","protocol","and","for","which","additional","options","were","explicitly","specified",".","Attributes","--","--","--","--","--","ptr",":","int","Pointer","to","the","data","size",":","int","Size","of","the","array","data","in","bytes","_owner",":","Python","Object","Object","that","owns","the","data","of","the","array","shape",":","tuple","of","ints","Shape","of","the","array","order",":","{","'","F","'",",","'","C","'","}","'","F","'","or","'","C","'","to","indicate","Fortran-major","or","C-major","order","of","the","array","strides",":","tuple","of","ints","Strides","of","the","data","mem_type",":","MemoryType","Memory","type","for","how","data","are","stored","__array_interface__",":","dictionary","``","__array_interface__","``","to","interop","with","other","libraries",".","This","attribute","is","only","present","if","data","are","host-accessible",".","__cuda_array_interface__",":","dictionary","``","__cuda_array_interface__","``","to","interop","with","other","libraries",".","This","attribute","is","only","present","if","data","are","device-accessible",".","Notes","--","--","-","cuml","Array","is","not","meant","as","an","end-user","array","library",".","It","is","meant","for","cuML\/RAPIDS","developer","consumption",".","Therefore","it","contains","the","minimum","functionality",".","Its","functionality","is","hidden","by","base.pyx","to","provide","automatic","output","format","conversion","so","that","the","users","see","the","important","attributes","in","whatever","format","they","prefer",".","Todo",":","support","cuda","streams","in","the","constructor",".","See",":","https",":","\/\/github.com\/rapidsai\/cuml\/issues\/1712","https",":","\/\/github.com\/rapidsai\/cuml\/pull\/1396"]
code: def __init__(
      self,
      data=None,
      index=None,
      owner=None,
      dtype=None,
      shape=None,
      order=None,
      strides=None,
      mem_type=None,
      validate=None,
  ):
      if dtype is not None:
          dtype = GlobalSettings().xpy.dtype(dtype)
  
      self._index = index
      if mem_type is not None:
          mem_type = MemoryType.from_str(mem_type)
      self._mem_type = mem_type
  
      if hasattr(data, "__cuda_array_interface__"):
          # using CuPy allows processing delayed array wrappers
          # like cumlarray without added complexity
          data = cp.asarray(data)
          # need to reshape if user requests specific shape
          if shape is not None:
              data = data.reshape(shape)
          self._array_interface = data.__cuda_array_interface__
          if mem_type in (None, MemoryType.mirror):
              self._mem_type = MemoryType.device
          self._owner = data
      else:  # Not a CUDA array object
          if hasattr(data, "__array_interface__"):
              self._array_interface = data.__array_interface__
              self._mem_type = MemoryType.host
              self._owner = data
          else:  # Must construct array interface
              if dtype is None:
                  if hasattr(data, "dtype"):
                      dtype = data.dtype
                  else:
                      raise ValueError(
                          "Must specify dtype when data is passed as a"
                          " {}".format(type(data))
                      )
              if isinstance(data, (CudfBuffer, DeviceBuffer)):
                  self._mem_type = MemoryType.device
              elif mem_type is None:
                  if GlobalSettings().memory_type in (
                      None,
                      MemoryType.mirror,
                  ):
                      raise ValueError(
                          "Must specify mem_type when data is passed as a"
                          " {}".format(type(data))
                      )
                  self._mem_type = GlobalSettings().memory_type
  
              try:
                  data = data.ptr
                  if shape is None:
                      shape = (data.size,)
                  self._owner = data
              except AttributeError:  # Not a buffer object
                  pass
              if isinstance(data, int):
                  self._owner = owner
              else:
                  if self._mem_type is None:
                      cur_xpy = GlobalSettings().xpy
                  else:
                      cur_xpy = self._mem_type.xpy
                  # Assume integers are pointers. For everything else,
                  # convert it to an array and retry
                  try:
                      new_data = cur_xpy.frombuffer(data, dtype=dtype)
                  except TypeError:
                      new_data = cur_xpy.asarray(data, dtype=dtype)
                  if shape is not None:
                      new_order = order if order is not None else "C"
                      new_data = cur_xpy.reshape(
                          new_data, shape, order=new_order
                      )
                  if index is None:
                      try:
                          self._index = data.index
                      except AttributeError:
                          pass
                  return self.__init__(
                      data=new_data,
                      index=self._index,
                      owner=owner,
                      dtype=dtype,
                      shape=shape,
                      order=order,
                      mem_type=mem_type,
                  )
  
              if shape is None:
                  raise ValueError(
                      "shape must be specified when data is passed as a"
                      " pointer"
                  )
              if strides is None:
                  try:
                      if len(shape) == 0:
                          strides = None
                      elif len(shape) == 1:
                          strides == (dtype.itemsize,)
                  except TypeError:  # Shape given as integer
                      strides = (dtype.itemsize,)
              if strides is None:
                  strides = _order_to_strides(order, shape, dtype)
  
              self._array_interface = {
                  "shape": shape,
                  "strides": strides,
                  "typestr": dtype.str,
                  "data": (data, False),
                  "version": 3,
              }
      # Derive any information required for attributes that has not
      # already been derived
      if mem_type in (None, MemoryType.mirror):
          if self._mem_type in (None, MemoryType.mirror):
              raise ValueError(
                  "Could not infer memory type from input data. Pass"
                  " mem_type explicitly."
              )
          mem_type = self._mem_type
  
      if self._array_interface["strides"] is None:
          try:
              self._array_interface["strides"] = data.strides
          except AttributeError:
              self._array_interface["strides"] = strides
  
      if (
          isinstance(data, CumlArray)
          or not (
              hasattr(data, "__array_interface__")
              or hasattr(data, "__cuda_array_interface__")
          )
      ) and (
          dtype is not None and shape is not None and order is not None
      ):
          self._array_interface["shape"] = shape
          self._array_interface["strides"] = strides
      else:
          if validate is None:
              validate = True
  
      array_strides = self._array_interface["strides"]
      if array_strides is not None:
          array_strides = host_xpy.array(array_strides)
  
      if (
          array_strides is None
          or len(array_strides) == 1
          or host_xpy.all(array_strides[1:] == array_strides[:-1])
      ) and order not in ("K", None):
          self._order = order
      else:
          self._order = _determine_memory_order(
              self._array_interface["shape"],
              self._array_interface["strides"],
              self._array_interface["typestr"],
              default=order,
          )
  
      # Validate final data against input arguments
      if validate:
          if mem_type != self._mem_type:
              raise MemoryTypeError(
                  "Requested mem_type inconsistent with input data object"
              )
          if (
              dtype is not None
              and dtype.str != self._array_interface["typestr"]
          ):
              raise ValueError(
                  "Requested dtype inconsistent with input data object"
              )
          if owner is not None and self._owner is not owner:
              raise ValueError(
                  "Specified owner object does not seem to match data"
              )
          if shape is not None:
              shape_arr = host_xpy.array(shape)
              if len(shape_arr.shape) == 0:
                  shape_arr = host_xpy.reshape(shape_arr, (1,))
  
              if not host_xpy.array_equal(
                  host_xpy.array(self._array_interface["shape"]),
                  shape_arr,
              ):
                  raise ValueError(
                      "Specified shape inconsistent with input data object"
                  )
          if (
              strides is not None
              and self._array_interface["strides"] is not None
              and not host_xpy.array_equal(
                  host_xpy.array(self._array_interface["strides"]),
                  host_xpy.array(strides),
              )
          ):
              raise ValueError(
                  "Specified strides inconsistent with input data object"
              )
          if (
              order is not None
              and order != "K"
              and self._order != order
          ):
              raise ValueError(
                  "Specified order inconsistent with array stride"
              )
  
imports: import copy
  import operator
  import pickle
  from cuml.internals.global_settings import GlobalSettings
  from cuml.internals.logger import debug
  from cuml.internals.mem_type import MemoryType, MemoryTypeError
  from cuml.internals.memory_utils import class_with_cupy_rmm, with_cupy_rmm
  from cuml.internals.safe_imports import cpu_only_import, cpu_only_import_from, gpu_only_import, gpu_only_import_from, null_decorator, return_false, safe_import, safe_import_from
  from typing import Tuple
label_desc: Use image node_id 1 to create a new CumlArray object  with example: obj = CumlArray(data, index, owner, dtype, shape, order, strides, mem_type, validate)