Esempio n. 1
0
def new_backend_tensor(
    x,
    dtype=None,
    device=None,
    requires_grad: bool = None,
    copy: bool = False,
    pin_memory: bool = False,
):
    kwargs = update_with_backend_values(requires_grad=requires_grad,
                                        device=device,
                                        copy=copy,
                                        dtype=dtype)
    if Backend.is_numpy():
        return new_numpy_array(x,
                               dtype=kwargs.get("dtype"),
                               copy=kwargs.get("copy"))
    elif Backend.is_torch():
        return new_torch_tensor(
            x,
            dtype=kwargs.get("dtype"),
            copy=kwargs.get("copy"),
            device=kwargs.get("device"),
            requires_grad=kwargs.get("requires_grad"),
            pin_memory=pin_memory,
        )
Esempio n. 2
0
def hash_type():
    funcs = {
        "numpy":
        lambda x: numpy.dtype("<U64")
        if Backend.use_true_hash() else numpy.uint64,
        "torch":
        lambda x: torch.int64,
    }
    return Backend.execute(None, funcs)
Esempio n. 3
0
def copy_torch(x: torch.Tensor, requires_grad, device=None) -> torch.Tensor:
    grad = requires_grad if requires_grad is not None else Backend.requires_grad(
    )
    device = torch.device(
        device) if device is not None else Backend.get_device()
    new_tensor = x.clone()
    if device is not None and new_tensor.device == device:
        new_tensor = new_tensor.to(device)
    if grad is not None and not grad:
        new_tensor = new_tensor.detach()
    return new_tensor
Esempio n. 4
0
def to_torch(x,
             requires_grad: bool = None,
             device: str = None,
             copy: bool = False):
    use_grad = requires_grad if requires_grad is not None else Backend.requires_grad(
    )
    device = device if device is not None else Backend.get_device()
    if isinstance(x, torch.Tensor):
        return (copy_torch(x, device=device, requires_grad=use_grad)
                if copy else _assign_device_and_grad(
                    x, device=device, requires_grad=use_grad))
    return new_torch_tensor(x, device=device, copy=copy)
Esempio n. 5
0
def __new_getattr(name):
    if name in DATA_TYPE_NAMES:
        return getattr(_data_types, name)()
    elif name in AVAILABLE_FUNCTIONS:
        return getattr(API, name)
    try:
        return __old_getattr(name)
    except AttributeError as e:
        if Backend.is_numpy():
            val = getattr(numpy, name)
            return __backend_wrap(val) if callable(val) else val
        elif Backend.is_torch():
            val = getattr(torch, name)
            return __backend_wrap(val) if callable(val) else val
        raise e
Esempio n. 6
0
    def random_nodes_generator(self, return_children: bool = False) -> NodeDataGenerator:
        """
        Return a generator that yields the data of all the nodes sampling them at random.

        Each value yielded corresponds to the data associated with one node and the \
        edge connecting to one of its children. The edge data will be assigned \
        to the parent node of the edge. This means the edge data of each node \
        contains the data associated with the transition to a child.

        Args:
            return_children: If ``True`` the data corresponding to the child of \
                            each node in the path will also be returned.

        Yields:
            tuple of dictionaries containing the data for each node and edge \
            sampled at random.

            If ``return_children`` is ``False`` it will yield (node_data, \
            edge_data).
            If ``return_children`` is ``True`` it will yield (node_data, \
            edge_data, next_node_data).

        """
        with Backend.use_backend("numpy"):
            permutaion = random_state.permutation(list(self.data.nodes))
        for next_node in permutaion:
            if next_node == self.root_id:
                continue
            node = self.get_parent(next_node)
            yield self._one_node_tuples(node, next_node, return_children)
Esempio n. 7
0
def copy(x, requires_grad: bool = None):
    if x is None:
        return
    if not dtype.is_tensor(x):
        x = JudoTensor(x)

    funcs = {
        "numpy": lambda x: x.copy(),
        "torch": lambda x: copy_torch(x, requires_grad),
    }
    return Backend.execute(x, funcs)
Esempio n. 8
0
 def iterate_batches(self, batch_size: int, as_dict: bool = True):
     with Backend.use_backend("numpy"):
         indexes = random_state.permutation(range(len(self)))
         for i in range(0, len(self), batch_size):
             batch_ix = indexes[i:i + batch_size]
             data = tuple(
                 [getattr(self, val)[batch_ix] for val in self.names])
             if as_dict:
                 yield dict(zip(self.names, data))
             else:
                 yield data
Esempio n. 9
0
 def iterate_values(self,
                    randomize: bool = False) -> Iterable[Tuple[Tensor]]:
     """
     Return a generator that yields a tuple containing the data of each state \
     stored in the memory.
     """
     indexes = range(len(self))
     if randomize:
         with Backend.use_backend("numpy"):
             indexes = random_state.permutation(indexes)
     for i in indexes:
         yield tuple([getattr(self, val)[i] for val in self.names])
Esempio n. 10
0
 def get_function(name):
     if name in functions.fractalai.AVAILABLE_FUNCTIONS:
         return getattr(functions.fractalai, name)
     elif name in functions.batching.AVAILABLE_FUNCTIONS:
         return getattr(functions.batching, name)
     elif name in functions.images.AVAILABLE_FUNCTIONS:
         return getattr(functions.images, name)
     elif name in functions.notebook.AVAILABLE_FUNCTIONS:
         return getattr(functions.notebook, name)
     elif Backend.is_numpy():
         backend = functions.numpy
     else:
         backend = functions.pytorch
     return getattr(backend, name)
Esempio n. 11
0
def to_backend(x: "Tensor",
               requires_grad: bool = None,
               device: str = None,
               copy: bool = None) -> Tensor:
    kwargs = update_with_backend_values(requires_grad=requires_grad,
                                        device=device,
                                        copy=copy)
    if Backend.is_numpy():
        return to_numpy(x, kwargs.get("copy"))
    return to_torch(
        x,
        requires_grad=kwargs.get("requires_grad"),
        device=kwargs.get("device"),
        copy=kwargs.get("copy"),
    )
Esempio n. 12
0
def to_node_id(x):
    if Backend.is_numpy():
        return str(x) if Backend.use_true_hash() else int(x)
    elif Backend.is_torch():
        return int(x)
Esempio n. 13
0
def float64():
    funcs = {
        "numpy": lambda x: numpy.float64,
        "torch": lambda x: torch.float64
    }
    return Backend.execute(None, funcs)
Esempio n. 14
0
def int32():
    funcs = {"numpy": lambda x: numpy.int32, "torch": lambda x: torch.int32}
    return Backend.execute(None, funcs)
Esempio n. 15
0
def uint8():
    funcs = {"numpy": lambda x: numpy.uint8, "torch": lambda x: torch.uint8}
    return Backend.execute(None, funcs)
Esempio n. 16
0
def bool():
    funcs = {"numpy": lambda x: numpy.bool_, "torch": lambda x: torch.bool}
    return Backend.execute(None, funcs)
Esempio n. 17
0
 def uses_true_hash(self) -> bool:
     return Backend.use_true_hash()
Esempio n. 18
0
 def permutation(x):
     idx = torch.randperm(x.shape[0])
     sample = x[idx].to(Backend.get_device()).detach()
     return to_backend(sample)
Esempio n. 19
0
def update_with_backend_values(**kwargs):
    user_kwargs = {k: v for k, v in kwargs.items() if v is not None}
    backend_kwargs = Backend.get_backend_state()
    backend_kwargs.update(user_kwargs)
    return backend_kwargs
Esempio n. 20
0
 def true_hash_tensor(cls, x):
     funcs = {
         "numpy": cls.hash_numpy,
         "torch": cls.hash_torch,
     }
     return Backend.execute(x, funcs)
Esempio n. 21
0
def as_tensor(x, *args, **kwargs):
    funcs = {
        "numpy": lambda x: numpy.ascontiguousarray(x, *args, **kwargs),
        "torch": lambda x: torch.as_tensor(x, *args, **kwargs),
    }
    return Backend.execute(x, funcs)
Esempio n. 22
0
def astype(x, dtype):
    funcs = {
        "numpy": lambda x: x.astype(dtype),
        "torch": lambda x: x.to(dtype),
    }
    return Backend.execute(x, funcs)
Esempio n. 23
0
 def __getattr__(cls, item):
     funcs = {
         "numpy": lambda x: getattr(cls._numpy_random_state, x),
         "torch": lambda x: getattr(cls._torch_random_state, x),
     }
     return Backend.execute(item, funcs)
Esempio n. 24
0
class Hasher:

    _true_hash = bool(Backend.use_true_hash())

    def __init__(self, seed: int = 0):
        self._seed = seed
        if self._true_hash:
            self.pool = Pool()

    @property
    def uses_true_hash(self) -> bool:
        return self._true_hash

    @staticmethod
    def hash_numpy(x: numpy.ndarray) -> int:
        """Return a value that uniquely identifies a numpy array."""
        x = x.astype("|S576") if x.dtype == "O" else x
        return xxhash.xxh64_hexdigest(x.tobytes())

    @staticmethod
    def hash_torch(x):
        bytes = judo.to_numpy(x).tobytes()
        return xxhash.xxh32_intdigest(bytes)

    @classmethod
    def true_hash_tensor(cls, x):
        funcs = {
            "numpy": cls.hash_numpy,
            "torch": cls.hash_torch,
        }
        return Backend.execute(x, funcs)

    def get_one_id(self):
        self._seed += 1
        return self._seed

    def get_array_of_ids(self, n: int):
        ids = numpy.arange(n) + self._seed + 1
        self._seed += n + 1
        return judo.as_tensor(ids)

    def hash_tensor(self, x):
        if self._true_hash:
            return self.true_hash_tensor(x)
        return 0

    def hash_walkers(self, x):
        if self._true_hash:
            # hashes = self.pool.map(self.true_hash_tensor, x)
            hashes = [self.true_hash_tensor(x_i) for x_i in x]
            return judo.as_tensor(hashes)
        return self.get_array_of_ids(x.shape[0])

    def hash_state(self, state):
        if self._true_hash:
            _hash = hash(
                tuple([
                    self.hash_tensor(x)
                    if k in state._tensor_names else hash(x)
                    for k, x in state.items()
                ]))
            return _hash
        return 0