code: def as_ndarray(
      values: Tensor,
      dtype: Optional[np.dtype] = None,
      inplace: bool = True,
  ) -> ndarray:
      r"""Helper for going from torch.Tensor to numpy.ndarray.
  
      Args:
          values: Tensor to be converted to ndarray.
          dtype: Optional numpy.dtype for the converted tensor.
          inplace: Boolean indicating whether memory should be shared if possible.
  
      Returns:
          An ndarray with the same data as `values`.
      """
      with torch.no_grad():
          out = values.cpu()  # maybe transfer to cpu
  
          # Determine whether or not to `clone`
          if (
              # cond 1: are we not in `inplace` mode?
              not inplace
              # cond 2: did we already copy when calling `cpu` above?
              and out.device == values.device
              # cond 3: will we copy when calling `astype` below?
              and (
                  dtype is None
                  or out.dtype == torch_to_numpy_dtype_dict[dtype]
              )
          ):
              out = out.clone()
  
          # Convert to ndarray and maybe cast to `dtype`
          out = out.numpy()
          return out.astype(dtype, copy=False)
  
file_path: botorch/botorch/optim/utils/numpy_utils.py
imports: from __future__ import annotations
  from itertools import tee
  from typing import Callable, Dict, Iterator, Optional, Tuple, Union
  import numpy
  import torch
  from botorch.utils.types import NoneType
  from numpy import ndarray
  from torch import Tensor
label_desc: Use image node_id 1 for calling a global function with example usage: as_ndarray(values, dtype, inplace) and returns: out