Skip to content

Commit

Permalink
Merge branch 'master' of github.com:samthakur587/ivy
Browse files Browse the repository at this point in the history
  • Loading branch information
samthakur587 committed Jun 27, 2023
2 parents 02f0091 + ceada10 commit 0b88f49
Show file tree
Hide file tree
Showing 61 changed files with 1,521 additions and 679 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

..
⚠️ **Warning**: The compiler and the transpiler are not publicly available yet, so certain parts of this README won't work as expected as of now!
🚀 We are granting pilot access to **Ivy's Compiler and Transpiler** to some users, `join the waitlist <https://console.unify.ai/>`_ if you want to test them out!


.. image:: https://github.com/unifyai/unifyai.github.io/blob/master/img/externally_linked/logo_dark.png?raw=true#gh-dark-mode-only
Expand Down
1 change: 1 addition & 0 deletions docs/overview/background/standardization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Won’t adding a new “unified” framework just make the problem even worse…
.. image:: https://github.com/unifyai/unifyai.github.io/blob/master/img/externally_linked/background/standardization/how_standards_proliferate.png?raw=true
:align: center
:width: 70%
:target: https://xkcd.com/927/

Complimentary vs Competitive
----------------------------
Expand Down
13 changes: 13 additions & 0 deletions docs/overview/contributing/setting_up.rst
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,19 @@ Windows
a. In the left panel select "System Interpreter".
b. For Interpreter, select the default option which will be "/usr/bin/python3" the select "Create".
#. Opening "Edit Run/Debug configurations" dialog -> "Edit Configurations..." and making sure that "Working directory" is empty in case of getting the "Can't run process: the working directory '\ivy' is invalid, it needs to be an absolute path" error.
#. Everyone using PyCharm with the latest docker image and facing issues after setting up everything. All you need to do is add the paths here once, and then go to :code:`File--> Save all` for this configuration to persist. Just as shown in the image below, The paths would be:

.. code-block:: none
/opt/fw/numpy
/opt/fw/jax
/opt/fw/tensorflow
/opt/fw/torch
/opt/fw/paddle
/opt/fw/mxnet
.. image:: https://github.com/unifyai/unifyai.github.io/blob/master/img/externally_linked/contributing/setting_up/pycharm_with_docker/docker_newimage_fix.png?raw=true
:width: 420

Once these steps are finished, your interpreter should be set up correctly!
If Docker's latest version causes error, try using an earlier version by visiting `Docker release note <https://docs.docker.com/desktop/release-notes/>`_.
Expand Down
7 changes: 5 additions & 2 deletions docs/overview/deep_dive/ivy_tests.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ Ivy Tests
.. _`dtype_values_axis`: https://github.com/unifyai/ivy/blob/e50f71e283313caa9737f3c284496022ac67b58b/ivy_tests/test_ivy/helpers/hypothesis_helpers/array_helpers.py#L235
.. _`array_values`: https://github.com/unifyai/ivy/blob/e50f71e283313caa9737f3c284496022ac67b58b/ivy_tests/test_ivy/helpers/hypothesis_helpers/array_helpers.py#L543
.. _`CI Pipeline`: https://unify.ai/docs/ivy/deep_dive/continuous_integration.html#ci-pipeline
.. _`setting up`: https://unify.ai/docs/ivy/contributing/setting_up.html#setting-up-testing
.. _`Setting Up Testing in PyCharm`: https://unify.ai/docs/ivy/overview/contributing/setting_up.html#setting-up-testing-in-pycharm
.. _`Setting up for Free`: https://unify.ai/docs/ivy/overview/contributing/setting_up.html#setting-up-for-free


On top of the Array API `test suite`_, which is included as a submodule mapped to the folder :code:`test_array_api`, there is also a collection of Ivy tests, located in subfolder `test_ivy`_.
Expand Down Expand Up @@ -764,7 +765,9 @@ The CI Pipeline runs the entire collection of Ivy Tests for the module that is b
You will need to make sure the Ivy Test is passing for each Ivy function you introduce/modify.
If a test fails on the CI, you can see details about the failure under `Details -> Run Ivy <module> Tests` as shown in `CI Pipeline`_.

You can also run the tests locally before making a PR. See the relevant `setting up`_ section for instructions on how to do so.
You can also run the tests locally before making a PR. The instructions differ according to the IDE you are using. For
PyCharm and Visual Studio Code you can refer to the `Setting Up Testing in PyCharm`_ section and `Setting up for Free`_
section respectively.

Re-Running Failed Ivy Tests
---------------------------
Expand Down
2 changes: 2 additions & 0 deletions ivy/data_classes/array/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,8 @@ def __deepcopy__(self, memodict={}):
return to_ivy(copy.deepcopy(self._data))

def __len__(self):
if not len(self._data.shape):
return 0
try:
return len(self._data)
except TypeError:
Expand Down
7 changes: 4 additions & 3 deletions ivy/func_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,18 @@ def try_array_function_override(func, overloaded_args, types, args, kwargs):

def _get_first_array(*args, **kwargs):
# ToDo: make this more efficient, with function ivy.nested_nth_index_where
array_fn = ivy.is_array if "array_fn" not in kwargs else kwargs["array_fn"]
arr = None
if args:
arr_idxs = ivy.nested_argwhere(args, ivy.is_array, stop_after_n_found=1)
arr_idxs = ivy.nested_argwhere(args, array_fn, stop_after_n_found=1)
if arr_idxs:
arr = ivy.index_nest(args, arr_idxs[0])
else:
arr_idxs = ivy.nested_argwhere(kwargs, ivy.is_array, stop_after_n_found=1)
arr_idxs = ivy.nested_argwhere(kwargs, array_fn, stop_after_n_found=1)
if arr_idxs:
arr = ivy.index_nest(kwargs, arr_idxs[0])
elif kwargs:
arr_idxs = ivy.nested_argwhere(kwargs, ivy.is_array, stop_after_n_found=1)
arr_idxs = ivy.nested_argwhere(kwargs, array_fn, stop_after_n_found=1)
if arr_idxs:
arr = ivy.index_nest(kwargs, arr_idxs[0])
return arr
Expand Down
7 changes: 5 additions & 2 deletions ivy/functional/backends/jax/sorting.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ def argsort(
stable: bool = True,
out: Optional[JaxArray] = None,
) -> JaxArray:
x = -1 * jnp.searchsorted(jnp.unique(x), x) if descending else x
kind = "stable" if stable else "quicksort"
return jnp.argsort(x, axis, kind=kind)
return (
jnp.argsort(-x, axis=axis, kind=kind)
if descending
else jnp.argsort(x, axis=axis, kind=kind)
)


def sort(
Expand Down
7 changes: 5 additions & 2 deletions ivy/functional/backends/numpy/sorting.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ def argsort(
stable: bool = True,
out: Optional[np.ndarray] = None,
) -> np.ndarray:
x = -1 * np.searchsorted(np.unique(x), x) if descending else x
kind = "stable" if stable else "quicksort"
return np.argsort(x, axis, kind=kind)
return (
np.argsort(-x, axis=axis, kind=kind)
if descending
else np.argsort(x, axis=axis, kind=kind)
)


def sort(
Expand Down
2 changes: 1 addition & 1 deletion ivy/functional/backends/tensorflow/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ def isinf(
return tf.zeros_like(x, tf.bool)


@with_unsupported_dtypes({"2.12.0 and below": ("complex",)}, backend_version)
@with_unsupported_dtypes({"2.12.0 and below": ("complex", "bool")}, backend_version)
def isnan(
x: Union[tf.Tensor, tf.Variable],
/,
Expand Down
28 changes: 1 addition & 27 deletions ivy/functional/frontends/jax/numpy/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,30 +125,4 @@ def tensorinv(a, ind=2):

@to_ivy_arrays_and_back
def cond(x, p=None):
for a in x:
if a.size == 0 and ivy.prod(a.shape[-2:]) == 0:
raise ValueError("Arrays cannot be empty")
if p in (None, 2):
s = ivy.svd(x, compute_uv=False)
return s[..., 0] / s[..., -1]
elif p == -2:
s = ivy.svd(x, compute_uv=False)
r = s[..., -1] / s[..., 0]
else:
if ivy.get_num_dims(x) < 2:
raise ValueError(
"%d-dimensional array given. Array must be at least two-dimensional"
% ivy.get_num_dims(x)
)
m, n = ivy.shape(x)[-2:]
if m != n:
raise ValueError("Last 2 dimensions of the array must be square")
invx = ivy.inv(x)
r = ivy.matrix_norm(x, ord=p, axis=(-2, -1)) * ivy.norm(
invx, ord=p, axis=(-2, -1)
)
# Convert nans to infs unless the original array had nan entries
orig_nan_check = ivy.full_like(r, ~ivy.isnan(r).any())
nan_mask = ivy.logical_and(ivy.isnan(r), ~ivy.isnan(x).any(axis=(-2, -1)))
r = ivy.where(orig_nan_check, ivy.where(nan_mask, ivy.inf, r), r)
return r
return ivy.cond(x, p=p)
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,29 @@ def _divmod(
out=out,
)
return ret


@handle_numpy_out
@handle_numpy_dtype
@to_ivy_arrays_and_back
@handle_numpy_casting
@from_zero_dim_arrays_to_scalar
def remainder(
x1,
x2,
/,
out=None,
*,
where=True,
casting="same_kind",
order="K",
dtype=None,
subok=True,
):
if dtype:
x1 = ivy.astype(ivy.array(x1), ivy.as_ivy_dtype(dtype))
x2 = ivy.astype(ivy.array(x2), ivy.as_ivy_dtype(dtype))
ret = ivy.remainder(x1, x2, out=out)
if ivy.is_array(where):
ret = ivy.where(where, ret, ivy.default(out, ivy.zeros_like(ret)), out=out)
return ret
36 changes: 36 additions & 0 deletions ivy/functional/frontends/paddle/nn/functional/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,39 @@ def cosine_similarity(x1, x2, *, axis=1, eps=1e-08):

cosine = numerator / denominator
return cosine


def get_mask(shape, device, prob, seed=None):
mask = ivy.where(
ivy.random_uniform(shape=shape, device=device, seed=seed) < prob,
0.0,
1.0,
)
return mask


@with_supported_dtypes({"2.4.1 and below": ("float32", "float64")}, "paddle")
@to_ivy_arrays_and_back
def dropout(x, p=0.5, axis=None, training=True, mode="upscale_in_train", name=None):
if axis > 1:
raise ValueError("Axis value can only be 0 or 1 or None.")
elif axis is None or (isinstance(axis, list) and len(axis) == 2):
mask = get_mask(shape=x.shape, device=ivy.dev(x), prob=p, seed=None)
elif axis == 0:
mask = get_mask(shape=(x.shape[0], 1), device=ivy.dev(x), prob=p)
mask = ivy.broadcast_to(mask, x.shape)
elif axis == 1:
mask = get_mask(shape=(1, x.shape[1]), device=ivy.dev(x), prob=p)
mask = ivy.broadcast_to(mask, x.shape)
if mode == "upscale_in_train":
if training:
out = ivy.multiply(x, mask)
ret = ivy.multiply(out, 1.0 / (1.0 - p))
else:
ret = x
else:
if training:
ret = ivy.multiply(x, mask)
else:
ret = ivy.multiply(x, (1.0 - p))
return ret
45 changes: 45 additions & 0 deletions ivy/functional/frontends/paddle/nn/functional/loss.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import ivy
from ivy.func_wrapper import with_supported_dtypes
import ivy.functional.frontends.paddle as paddle
from ivy.utils.exceptions import handle_exceptions
from ivy.functional.frontends.paddle.func_wrapper import (
inputs_to_ivy_arrays,
to_ivy_arrays_and_back,
)


Expand Down Expand Up @@ -43,3 +45,46 @@ def binary_cross_entropy_with_logits(
ret = ivy.multiply(weight, ret)
ret = reduction(ret).astype(label.dtype)
return paddle.to_tensor(ret.reshape([-1]))


@handle_exceptions
@to_ivy_arrays_and_back
@with_supported_dtypes({"2.5.0 and below": ("float32", "float64")}, "paddle")
def cosine_embedding_loss(
input1, input2, label, margin=0.0, reduction="mean", name=None
):
if len(label.shape) != 1:
raise ValueError("1D target tensor expected, multi-target not supported")

if input1.shape != input2.shape:
raise ValueError(
"the shape of input tensor 1 should be equal to input tensor 2, but found"
" inputs with different sizes"
)

if len(input1.shape) > 2:
raise ValueError(
"1D target tensor expects 1D or 2D input tensors, but found inputs with"
" different sizes"
)

prod_sum = (input1 * input2).sum(axis=-1)
mag_square1 = ivy.square(input1).sum(axis=-1) + 1e-11
mag_square2 = ivy.square(input2).sum(axis=-1) + 1e-11
denom = ivy.sqrt(mag_square1 * mag_square2)
cos = prod_sum / denom
zeros = ivy.zeros_like(cos)
pos = 1 - cos
neg = ivy.clip(cos - margin, 0, 0)
out_pos = ivy.where(label == 1, pos, zeros)
out_neg = ivy.where(label == -1, neg, zeros)
out = out_pos + out_neg

if reduction == "none":
pass
if reduction == "mean":
out = ivy.mean(out)
elif reduction == "sum":
out = ivy.sum(out)

return out
5 changes: 5 additions & 0 deletions ivy/functional/frontends/paddle/tensor/creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,8 @@ def empty(shape, dtype=None):
@to_ivy_arrays_and_back
def eye(num_rows, num_columns=None, dtype=None, name=None):
return ivy.eye(num_rows, num_columns, dtype=dtype)


@to_ivy_arrays_and_back
def empty_like(x, dtype=None, name=None):
return ivy.empty_like(x, dtype=dtype)
9 changes: 9 additions & 0 deletions ivy/functional/frontends/paddle/tensor/manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,12 @@ def concat(x, axis, name=None):
@to_ivy_arrays_and_back
def tile(x, repeat_times, name=None):
return ivy.tile(x, repeats=repeat_times)


@with_unsupported_dtypes(
{"2.5.0 and below": ("int16", "complex64", "complex128")},
"paddle",
)
@to_ivy_arrays_and_back
def split(x, num_or_sections, axis=0, name=None):
return ivy.split(x, num_or_size_splits=num_or_sections, axis=axis)
48 changes: 44 additions & 4 deletions ivy/functional/frontends/paddle/tensor/math.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# global
import ivy
from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes
from ivy.functional.frontends.paddle.func_wrapper import (
to_ivy_arrays_and_back,
)
from ivy.functional.frontends.paddle.func_wrapper import to_ivy_arrays_and_back


@with_unsupported_dtypes({"2.5.0 and below": ("float16", "bfloat16")}, "paddle")
Expand Down Expand Up @@ -128,7 +126,13 @@ def pow(x, y, name=None):
return ivy.pow(x, y)


@with_unsupported_dtypes({"2.5.0 and below": ("float16", "bfloat16")}, "paddle")
@with_unsupported_dtypes({"2.4.2 and below": ("int16", "float16")}, "paddle")
@to_ivy_arrays_and_back
def conj(x, name=None):
return ivy.conj(x)


@with_unsupported_dtypes({"2.4.2 and below": ("float16", "bfloat16")}, "paddle")
@to_ivy_arrays_and_back
def floor(x, name=None):
return ivy.floor(x)
Expand Down Expand Up @@ -164,12 +168,24 @@ def deg2rad(x, name=None):
return ivy.deg2rad(x)


@with_unsupported_dtypes({"2.5.0 and below": ("float16", "bfloat16")}, "paddle")
@to_ivy_arrays_and_back
def gcd(x, y, name=None):
return ivy.gcd(x, y)


@with_unsupported_dtypes({"2.5.0 and below": ("float16", "bfloat16")}, "paddle")
@to_ivy_arrays_and_back
def tan(x, name=None):
return ivy.tan(x)


@with_unsupported_dtypes({"2.4.2 and below": ("float16", "bfloat16")}, "paddle")
@to_ivy_arrays_and_back
def atan2(x, y, name=None):
return ivy.atan2(x, y)


@with_supported_dtypes({"2.5.0 and below": ("float32", "float64")}, "paddle")
@to_ivy_arrays_and_back
def square(x, name=None):
Expand All @@ -178,6 +194,12 @@ def square(x, name=None):

@with_unsupported_dtypes({"2.5.0 and below": ("float16", "bfloat16")}, "paddle")
@to_ivy_arrays_and_back
def sign(x, name=None):
return ivy.sign(x)


@with_unsupported_dtypes({"2.4.2 and below": ("float16", "bfloat16")}, "paddle")
@to_ivy_arrays_and_back
def neg(x, name=None):
return ivy.negative(x)

Expand All @@ -188,6 +210,24 @@ def exp(x, name=None):
return ivy.exp(x)


@with_supported_dtypes(
{
"2.4.2 and below": (
"float32",
"float64",
"int32",
"int64",
"complex64",
"complex128",
)
},
"paddle",
)
@to_ivy_arrays_and_back
def cumprod(x, dim=None, dtype=None, name=None):
return ivy.cumprod(x, axis=dim, dtype=dtype)


@with_unsupported_dtypes({"2.5.0 and below": ("float16", "bfloat16")}, "paddle")
@to_ivy_arrays_and_back
def reciprocal(x, name=None):
Expand Down
Loading

0 comments on commit 0b88f49

Please sign in to comment.