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

feature and fix: added support for casting modes to give the original… #23439

Closed
wants to merge 11 commits into from

Conversation

RickSanchezStoic
Copy link
Contributor

added support for casting modes to give the original expected output type, also modified promote_types to accept None

… expected output dtype, also modified promote_types to accept None
@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! 🎉👨‍💻

@@ -1162,9 +1162,13 @@ def _wrap_function(
return to_wrap


def casting_modes_ops(fn):
def casting_modes_ops(fn, dtype_determinator=None):
Copy link
Contributor

Choose a reason for hiding this comment

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

everything else looks great! let's probably rename the argument to ret_dtype_target or something which might be more informative, what do you think?
I'll request @MahmoudAshraf97's review as well on this PR, thanks for making the changes @RickSanchezStoic 💪

Comment on lines 1196 to 1203
if not to_cast and ret_dtype_target:
for arg in ret_dtype_target:
to_cast = ivy.promote_types(
to_cast,
ivy.dtype(
args[arg_names.index(arg)] if arg not in kwargs else kwargs[arg]
),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

this does not take into consideration when the inputs are python scalars or other objects that do not have a dtype attribute, we should stick to using promote_types_of_inputs to guarantee consistent results, also to prevent the existence of two identical promotion codes which will double the maintenance efforts

Copy link
Contributor

Choose a reason for hiding this comment

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

another problem is that this doesn't take into consideration default values that are optional but still affect the output dtype

Copy link
Contributor Author

Choose a reason for hiding this comment

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

promote_types_of_inputs will directly modify the inputs, which shouldn't be done here. The args that are being read here are the ones explicitly passed to the decorator and are supposed to have a type attribute. Lastly, we don't have any promotion rules for scalars( or do we have that?) and if they really do affect the output dtype then we have a problem. Can you post an example that does that?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hey @MahmoudAshraf97 I remember having this conversation a couple of days back but don't fully remember the specifics, could you please share an example where this would be applicable? Thanks and apologies 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

We do have promotion rules for scalars included in ivy.promote_types_of_inputs but not in the promotion table hence they are promoted to the default dtype in ivy.promote_types which will lead to an inconsistent promotion results

ivy.promote_types(float_scalar, float16) = float32
ivy.promote_types_of_inputs(float_scalar, float16) = float16

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually ivy.promote_types should always receive dtypes (ivy.Dtype or ivy.NativeDtype), so ideally the result from ivy.promote_types_of_inputs is the one which would be used anyway. So ideally float16 would be the promoted dtype as a result 😄

@MahmoudAshraf97
Copy link
Contributor

I think we will need a method to test if this decorator is working as expected or not, my suggestion is to enable testing functions using their unsupported dtypes, this will guarentee consistency with frameworks that do support these dtypes

Copy link
Contributor

@vedpatwardhan vedpatwardhan left a comment

Choose a reason for hiding this comment

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

Just a minor change, rest looks good to me. I agree with @MahmoudAshraf97, would be great to have tests for these too. Also, does this cover all the other corner cases we were discussing? Thanks 😄

ivy/func_wrapper.py Outdated Show resolved Hide resolved
@MahmoudAshraf97
Copy link
Contributor

Hey @RickSanchezStoic , I guess you reverted my commit when you committed, can you please revise?

Copy link
Contributor

@vedpatwardhan vedpatwardhan left a comment

Choose a reason for hiding this comment

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

Just requested a few changes! Let's focus on the functions which use ivy.promote_types_of_inputs for now for a version 0 as there isn't really an exhaustive way to test if there are issues in the output dtype for the other functions until we integrate casting modes into the tests (cc @sherry30), I'll also request @MahmoudAshraf97's review on this PR. Thanks @RickSanchezStoic 😄

if arg not in kwargs:
args[arg_names.index(arg)] = (
arg_mod
if not ivy.isarray(args[arg_names.index(arg)])
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be ivy.is_array instead of ivy.isarray

else:
kwargs[arg] = (
arg_mod
if not ivy.isarray(args[arg_names.index(arg)])
Copy link
Contributor

Choose a reason for hiding this comment

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

same here

@@ -1300,7 +1336,8 @@ def _wrapped(func):
if "frontends" in func.__module__:
# it's a frontend func, no casting modes for this
return func
return casting_modes_ops(func)

return casting_modes_ops(func, ret_dtype_target)
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 remove the blank line above this and pass ret_dtype_target as a keyword argument

ivy/functional/ivy/data_type.py Show resolved Hide resolved
@github-actions
Copy link
Contributor

github-actions bot commented Oct 6, 2023

Thank you for this PR, here is the CI results:


This pull request does not result in any additional test failures. Congratulations!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants