Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fixing pytest discovery issues #28158

Merged
merged 20 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ivy/functional/frontends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"sklearn": "1.3.0",
"xgboost": "1.7.6",
"torchvision": "0.15.2.",
"mindspore": "2.0.0",
}


Expand Down
6 changes: 3 additions & 3 deletions ivy/functional/frontends/jax/numpy/creation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ivy
from ivy.func_wrapper import with_unsupported_dtypes
from ivy.functional.frontends.jax.array import Array
import ivy.functional.frontends.jax.numpy as jnp_frontend
import ivy.functional.frontends.jax.numpy as jnp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we have to change the name of the import at either of the 2 places, I'd much rather do that in the test file instead. Sorry for the change of mind, could you please change it so that we do the jnp import in the test file and jnp_frontend import in the frontend file? Thanks @Vismay-dev 😄

Copy link
Contributor Author

@vismaysur vismaysur Feb 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vedpatwardhan it's the front end file import that's causing the error rather than the test file. Not the import itself but the use of this namespace jnp_frontend in the function setdiff1d".

This line https://github.com/unifyai/ivy/blob/d382882aafb0e19cccc8145cfcaa6cc4f53a77c4/ivy/functional/ivy/data_type.py#L192 checks for the keyword "frontend" in the base names of all the functions invoked in the frontend function setdiff1d. I'm not sure if this is an intentional design caveat of the current use of an AST, or just an unprecedented edge case.

Changing the import in the test file, as you originally pointed out, is not related to the error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's probably change the import in the frontend file to something like from ivy.functional.frontends.jax import where, unique similar to the other imports in the jax frontend if that fixes the issue 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vedpatwardhan that's causing a circular import error. the reason there's no circular import error for the other imports in the jax frontend is because those imported functions (for eg. promote_types_of_jax_inputs) have been defined in __init__.py for the frontends/jax/numpy frontend directory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed a change to data_type.py, does test collection now work with jnp_frontend in the frontend file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the test collection works with jnp_frontend now 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome! We can get the PR merged after the changes to the demos submodule are reverted. Feel free to request a review once you're done with that, thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vedpatwardhan all done!

from ivy.functional.frontends.jax.func_wrapper import (
to_ivy_arrays_and_back,
outputs_to_frontend_arrays,
Expand Down Expand Up @@ -270,7 +270,7 @@ def setdiff1d(ar1, ar2, assume_unique=False, *, size=None, fill_value=None):
if ivy.is_bool_dtype(ar1.dtype)
else ivy.to_scalar(ivy.min(ar1))
)
ar1 = jnp_frontend.unique(ar1, size=size and ar1.size, fill_value=val).ivy_array
ar1 = jnp.unique(ar1, size=size and ar1.size, fill_value=val).ivy_array
mask = in1d(ar1, ar2, invert=True).ivy_array
if size is None:
return ar1[mask]
Expand All @@ -281,7 +281,7 @@ def setdiff1d(ar1, ar2, assume_unique=False, *, size=None, fill_value=None):
mask = ivy.where(ivy.arange(ar1.size) < n_unique, mask, False)
return ivy.where(
ivy.arange(size) < mask.sum(dtype=ivy.int64),
ar1[jnp_frontend.where(mask, size=size)[0].ivy_array],
ar1[jnp.where(mask, size=size)[0].ivy_array],
fill_value,
)

Expand Down
21 changes: 19 additions & 2 deletions ivy/functional/frontends/tensorflow/keras/activations.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@
]


# --- Helpers --- #
# --------------- #


# note: defined to avoid AST call extraction of
# 'tf_frontend.keras.activations.__dict__.items()
# or 'tf_frontend.keras.activations.__dict__.values()'
def _get_tf_keras_activations():
return tf_frontend.keras.activations.__dict__.items()


# --- Main --- #
# ------------ #


@with_supported_dtypes(
{"2.15.0 and below": ("float16", "float32", "float64")},
"tensorflow",
Expand Down Expand Up @@ -132,13 +147,15 @@ def serialize(activation, use_legacy_format=False, custom_objects=None):
if custom_func == activation:
return name

tf_keras_frontend_activations = _get_tf_keras_activations()

# Check if the function is in the ACTIVATION_FUNCTIONS list
if activation.__name__ in ACTIVATION_FUNCTIONS:
return activation.__name__

# Check if the function is in the TensorFlow frontend activations
elif activation in tf_frontend.keras.activations.__dict__.values():
for name, tf_func in tf_frontend.keras.activations.__dict__.items():
elif activation in [fn for name, fn in tf_keras_frontend_activations]:
for name, tf_func in tf_keras_frontend_activations:
if tf_func == activation:
return name

Expand Down
6 changes: 5 additions & 1 deletion ivy/functional/ivy/data_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def _nested_get(f, base_set, merge_fn, get_fn, wrapper=set):
continue
is_frontend_fn = "frontend" in fn.__module__
is_backend_fn = "backend" in fn.__module__ and not is_frontend_fn
is_einops_fn = "einops" in fn.__name__
is_einops_fn = hasattr(fn, "__name__") and "einops" in fn.__name__
if is_backend_fn:
f_supported = get_fn(fn, False)
if hasattr(fn, "partial_mixed_handler"):
Expand Down Expand Up @@ -197,6 +197,10 @@ def _nested_get(f, base_set, merge_fn, get_fn, wrapper=set):
if "(" in key:
key = key.split("(")[0]
frontend_module = ".".join(key.split(".")[:-1])
if (
frontend_module == ""
): # single edge case: fn='frontend_outputs_to_ivy_arrays'
continue
frontend_fl = {key: frontend_fn}
res += list(
_get_functions_from_string(
Expand Down
2 changes: 1 addition & 1 deletion ivy/functional/ivy/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,7 @@ def _get_devices(fn: Callable, complement: bool = True) -> Tuple:

is_backend_fn = "backend" in fn.__module__
is_frontend_fn = "frontend" in fn.__module__
is_einops_fn = "einops" in fn.__name__
is_einops_fn = hasattr(fn, "__name__") and "einops" in fn.__name__
if not is_backend_fn and not is_frontend_fn and not is_einops_fn:
if complement:
supported = set(all_devices).difference(supported)
Expand Down
2 changes: 1 addition & 1 deletion ivy/functional/ivy/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -3989,7 +3989,7 @@ def _get_devices_and_dtypes(fn, recurse=True, complement=True):

is_frontend_fn = "frontend" in fn.__module__
is_backend_fn = "backend" in fn.__module__ and not is_frontend_fn
is_einops_fn = "einops" in fn.__name__
is_einops_fn = hasattr(fn, "__name__") and "einops" in fn.__name__
if not is_backend_fn and not is_frontend_fn and not is_einops_fn:
if complement:
all_comb = _all_dnd_combinations()
Expand Down
Loading