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

Builtins frontend #22007

Closed
wants to merge 26 commits into from
Closed

Builtins frontend #22007

wants to merge 26 commits into from

Conversation

illia-bab
Copy link
Contributor

No description provided.

@illia-bab illia-bab requested a review from AnnaTz August 16, 2023 10:47
@github-actions
Copy link
Contributor

Thanks for contributing to Ivy! 😊👏
Here are some of the important points from our Contributing Guidelines 📝:
1. Feel free to ignore the run_tests (1), run_tests (2), … jobs, and only look at the display_test_results job. 👀 It contains the following two sections:
- Combined Test Results: This shows the results of all the ivy tests that ran on the PR. ✔️
- New Failures Introduced: This lists the tests that are passing on main, but fail on the PR Fork. Please try to make sure that there are no such tests. 💪
2. The lint / Check formatting / check-formatting tests check for the formatting of your code. 📜 If it fails, please check the exact error message in the logs and fix the same. ⚠️🔧
3. Finally, the test-docstrings / run-docstring-tests check for the changes made in docstrings of the functions. This may be skipped, as well. 📚
Happy coding! 🎉👨‍💻



def _infer_return_array(x: Iterable) -> Callable:
# get module path
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a docstring that explains what this decorator does overall? It is not very obvious when it should be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function should always be used within @to_ivy_arrays_and_back decorator to infer the return array type. Let's consider the jax frontend. In this case, if decorator receives jax.Array, its frontend implementation or list the output will always be converted to a frontend implementation of jax.Array. However, in case of builtins the behaviour changes to: almost_any_array -> ivy.Array -> almost_any_array. In other words, we need to track what array to convert back to. So, if our built-in function recieves np.ndarray or its frontend implementation, the output will be converted to np_frontend.ndarray and so on. It also has a default behaviour. By default we convert the output to a frontend implementation of array which corresponds to current backend. This was done to cover the cases, when function accepts scalar arguments, but returns an array. For example, range. But yeah I will add a docstring.

@illia-bab illia-bab requested a review from AnnaTz August 18, 2023 10:47
return x.ivy_array

# convert native arrays and lists to ivy arrays
elif isinstance(x, ivy.NativeArray):
Copy link
Contributor

@AnnaTz AnnaTz Aug 23, 2023

Choose a reason for hiding this comment

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

If we want lists to get converted, we have to change this to else.
I think however that ivy functions can already handle array-likes, in which case you would just need to change the comment, not the condition.

Copy link
Contributor Author

@illia-bab illia-bab Aug 23, 2023

Choose a reason for hiding this comment

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

Yeah, I just forgot to modify the comment.


jax.config.update("jax_enable_x64", True)

ret, frontend_array = fn(*args, **kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

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

The way inputs_to_ivy_arrays and outputs_to_frontend_arrays have been designed right now they can't be used individually. They would only work when used together in to_ivy_arrays_and_back.
E.g. ret, frontend_array = fn(*args, **kwargs) would cause an error if fn was an unwrapped frontend function because there would not be a frontend_array returned.



def to_ivy_arrays_and_back(fn: Callable) -> Callable:
return outputs_to_frontend_arrays(inputs_to_ivy_arrays(fn))
Copy link
Contributor

@AnnaTz AnnaTz Aug 23, 2023

Choose a reason for hiding this comment

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

  • Make another wrapper inside here like:
@functools.wraps(fn) 
def _to_ivy_arrays_and_back(*args, **kwargs):
  • Move the frontend_array = _infer_return_array(args[0]) if len(args) != 0 else None there.
  • Call inputs_to_ivy_arrays, and then call outputs_to_frontend_arrays passing frontend_array.
  • You will need to add frontend_array as a new argument like outputs_to_frontend_arrays(fn: Callable, frontend_array: str).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I'll try this approach!

@illia-bab illia-bab closed this by deleting the head repository Aug 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants