Skip to content

[SYCL] Add half non-assign math operators #6061

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

Merged
merged 9 commits into from
May 9, 2022

Conversation

AidanBeltonS
Copy link
Contributor

@AidanBeltonS AidanBeltonS commented Apr 26, 2022

This PR adds missing half operations +-*/.

There are existing operations for the legacy class host_half_impl, however these were not extended to the half class. These operations were being performed as floating point operations via the implicit floating conversion. This results in the output being a float not half type.

The template is limited to arithmetic types to prevent ambiguous templating.
A minor change to built-in __fract is needed to ensure fmin is not ambiguous.

llvm-test-suite PR: intel/llvm-test-suite#1012
Fixes: #6028

Copy link
Contributor

@v-klochkov v-klochkov left a comment

Choose a reason for hiding this comment

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

Thank you for doing this fix. I have some questions though.
Also, please add a LIT test to this PR.

@rolandschulz - would you please take a look at this fix?

__SYCL_CONSTEXPR_HALF friend half operator op(const half &lhs, \
const half &rhs) { \
half rtn = lhs; \
rtn op1 rhs; \
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
rtn op1 rhs; \
rtn op_eq rhs; \

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@AidanBeltonS
Copy link
Contributor Author

Also, please add a LIT test to this PR.

I have added a test to check for different output types for various inputs.

OP(+, +=)
OP(-, -=)
OP(*, *=)
OP(/, /=)
Copy link
Contributor

@dkhaldi dkhaldi Apr 27, 2022

Choose a reason for hiding this comment

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

Can you also add support for:
OP(bool, ==)
OP(bool, !=)
OP(bool, <)
OP(bool, >)
OP(bool, <=)
OP(bool, >=)

?
Like this, we will have a more complete list similar to what we have for bfloat16 support currently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added the logical operators and expanded the test

rolandschulz
rolandschulz previously approved these changes Apr 27, 2022
rolandschulz
rolandschulz previously approved these changes Apr 27, 2022
v-klochkov
v-klochkov previously approved these changes Apr 28, 2022
dkhaldi
dkhaldi previously approved these changes Apr 28, 2022
Copy link
Contributor

@dkhaldi dkhaldi left a comment

Choose a reason for hiding this comment

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

Thank you for adding the missing operators

@AidanBeltonS AidanBeltonS dismissed stale reviews from dkhaldi, v-klochkov, and rolandschulz via fb7f65c May 2, 2022 09:33
@AidanBeltonS AidanBeltonS force-pushed the fix_half_operators branch from aa1ccc1 to fb7f65c Compare May 2, 2022 09:33
@AidanBeltonS
Copy link
Contributor Author

/verify with intel/llvm-test-suite#1012

@AidanBeltonS
Copy link
Contributor Author

Some llvm-test-suite tests were failing due to the half changes. I have updated the test-suite to resolve the issues. The changes relate to ambiguous namespaces with ESIMD and an increase in check tolerance now that 16-bit operations are being performed.

llvm-test-suite PR: intel/llvm-test-suite#1012

Comment on lines 16 to 24
static_assert(std::is_same_v<decltype(T1(1) + sycl::half(1)), T_rtn>);
static_assert(std::is_same_v<decltype(T1(1) - sycl::half(1)), T_rtn>);
static_assert(std::is_same_v<decltype(T1(1) * sycl::half(1)), T_rtn>);
static_assert(std::is_same_v<decltype(T1(1) / sycl::half(1)), T_rtn>);

static_assert(std::is_same_v<decltype(sycl::half(1) + T1(1)), T_rtn>);
static_assert(std::is_same_v<decltype(sycl::half(1) - T1(1)), T_rtn>);
static_assert(std::is_same_v<decltype(sycl::half(1) * T1(1)), T_rtn>);
static_assert(std::is_same_v<decltype(sycl::half(1) / T1(1)), T_rtn>);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we outline that into a helper called from both host/device code to avoid duplication?

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, that would make the code much clearer. I have updated the test.

void check_half_math_operator_types(sycl::queue Queue) {

// Test on host
static_assert(std::is_same_v<decltype(T1(1) + sycl::half(1)), T_rtn>);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: that could also be (I think)

decltype(std::declval<T1>() + std::declval<sycl::half>())

But it's probably not worth decreased signal/noise ratio to be that pedantic here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines 46 to 58
static_assert(std::is_same_v<decltype(T1(1) == sycl::half(1)), bool>);
static_assert(std::is_same_v<decltype(T1(1) != sycl::half(1)), bool>);
static_assert(std::is_same_v<decltype(T1(1) > sycl::half(1)), bool>);
static_assert(std::is_same_v<decltype(T1(1) < sycl::half(1)), bool>);
static_assert(std::is_same_v<decltype(T1(1) <= sycl::half(1)), bool>);
static_assert(std::is_same_v<decltype(T1(1) <= sycl::half(1)), bool>);

static_assert(std::is_same_v<decltype(sycl::half(1) == T1(1)), bool>);
static_assert(std::is_same_v<decltype(sycl::half(1) != T1(1)), bool>);
static_assert(std::is_same_v<decltype(sycl::half(1) > T1(1)), bool>);
static_assert(std::is_same_v<decltype(sycl::half(1) < T1(1)), bool>);
static_assert(std::is_same_v<decltype(sycl::half(1) <= T1(1)), bool>);
static_assert(std::is_same_v<decltype(sycl::half(1) <= T1(1)), bool>);
Copy link
Contributor

Choose a reason for hiding this comment

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

Likewise about helper routine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated same as above.

}

template <typename T1>
void check_half_logical_operator_types(sycl::queue Queue) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I am very surprised copy-ctor isn't deleted... Regardless of what the standard says, can we turn this into a reference?

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 that makes sense, I have adjusted this to be pass by reference.

@AidanBeltonS
Copy link
Contributor Author

/verify with intel/llvm-test-suite#1012

@AidanBeltonS
Copy link
Contributor Author

@pvchupin would it be possible to find out what is failing in the llvm-test-suite when run with the intel/llvm-test-suite#1012 changes? Thank you.

@pvchupin
Copy link
Contributor

pvchupin commented May 9, 2022

@pvchupin would it be possible to find out what is failing in the llvm-test-suite when run with the intel/llvm-test-suite#1012 changes? Thank you.

It actually didn't run and failed earlier due to some infrastructure issue. Tagging @tfzhu.

@pvchupin
Copy link
Contributor

pvchupin commented May 9, 2022

@AidanBeltonS, I'm restarting it now.

@pvchupin
Copy link
Contributor

pvchupin commented May 9, 2022

@AidanBeltonS, restart passed, I'll merge both this and test changes.

pvchupin pushed a commit to intel/llvm-test-suite that referenced this pull request May 9, 2022
This PR makes some small changes due to the introduction of some missing operators.
It changes the namespaces in ext_math.cpp as it was ambiguous as to if the sycl::abs() or sycl::ext::intel::esimd::abs() function should be used.

There is also an adjustment of the load store's check tolerance. The checks tolerance is slightly increased, as previously these operations would have been performed as 32-bit floats.

Depends on: intel/llvm#6061
@pvchupin pvchupin merged commit 059efbc into intel:sycl May 9, 2022
@yanfeng3721
Copy link
Contributor

@AidanBeltonS , could you please check the following post commit error in Windows Build? Thanks.
https://github.com/intel/llvm/runs/6361728718?check_suite_focus=true

[2700/2961] Building CXX object tools\sycl\source\CMakeFiles\sycl_object.dir\detail\reduction.cpp.obj
Alignment of class vec is not in accordance with SYCL specification requirements, a limitation of the MSVC compiler(Error C2719).Requested alignment applied, limited at 64.

@pvchupin
Copy link
Contributor

I think real issue is this one:

D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(230): error C2220: the following warning is treated as an error
D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(230): warning C4804: '-': unsafe use of type 'bool' in operation
D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(24): warning C4804: '-': unsafe use of type 'bool' in operation
D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(155): note: see reference to function template instantiation 'T cl::__host_std::`anonymous-namespace'::__vFOrdEqualcl::sycl::cl_half(T,T)' being compiled
with
[
T=cl::sycl::cl_half
]

@yanfeng3721
Copy link
Contributor

I think real issue is this one:

D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(230): error C2220: the following warning is treated as an error
D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(230): warning C4804: '-': unsafe use of type 'bool' in operation
D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(24): warning C4804: '-': unsafe use of type 'bool' in operation
D:\github_work\llvm\llvm\src\sycl\source\detail\builtins_relational.cpp(155): note: see reference to function template instantiation 'T cl::__host_std::`anonymous-namespace'::__vFOrdEqualcl::sycl::cl_half(T,T)' being compiled
with
[
T=cl::sycl::cl_half
]

Thanks for correction, I did not notice "Error C2719" exist before this commit.

pvchupin pushed a commit that referenced this pull request May 10, 2022
This PR adds a static cast to builtins_relational functions which apply a negative operation to a boolean type.
This is only applied to functions which are specialised for cl_half. The cast prevents windows error message C4804.

This resolves a windows build issue introduced by #6061
@pvchupin
Copy link
Contributor

@AidanBeltonS, it seems there was some collision of this change with recent pulldown. Can you please take a look at the latest post-commit issue?
https://github.com/intel/llvm/runs/6377899714?check_suite_focus=true

aelovikov-intel pushed a commit to aelovikov-intel/llvm that referenced this pull request Mar 27, 2023
This PR makes some small changes due to the introduction of some missing operators.
It changes the namespaces in ext_math.cpp as it was ambiguous as to if the sycl::abs() or sycl::ext::intel::esimd::abs() function should be used.

There is also an adjustment of the load store's check tolerance. The checks tolerance is slightly increased, as previously these operations would have been performed as 32-bit floats.

Depends on: intel#6061
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.

sycl::half arithmetic operator promotes results to float
7 participants