-
Notifications
You must be signed in to change notification settings - Fork 407
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
Add missing pow(Kokkos::complex) overloads #3868
Conversation
Kokkos::pow(Kokkos::complex<double>(2., 1.), 3)); | ||
ASSERT_EQ( | ||
Kokkos::pow(Kokkos::complex<double>(2., 1.), 3.), | ||
Kokkos::pow(Kokkos::complex<double>(2., 1.), Kokkos::complex<double>(3))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I omitted
diff --git a/core/src/Kokkos_Complex.hpp b/core/src/Kokkos_Complex.hpp
index 623700c2..9f14d762 100644
--- a/core/src/Kokkos_Complex.hpp
+++ b/core/src/Kokkos_Complex.hpp
@@ -773,6 +773,19 @@ struct promote_2 {
};
template <class T, class U>
using promote_2_t = typename promote_2<T, U>::type;
+// complex specializations
+template <class T, class U>
+struct promote_2<Kokkos::complex<T>, U> {
+ using type = Kokkos::complex<promote_2_t<T, U>>;
+};
+template <class T, class U>
+struct promote_2<T, Kokkos::complex<U>> {
+ using type = Kokkos::complex<promote_2_t<T, U>>;
+};
+template <class T, class U>
+struct promote_2<Kokkos::complex<T>, Kokkos::complex<U>> {
+ using type = Kokkos::complex<promote_2_t<T, U>>;
+};
} // namespace Impl
template <class T, class U>
on purpose because I thought it was not needed.
I expected the line above would call
kokkos/core/src/Kokkos_Complex.hpp
Lines 740 to 746 in 4258629
template <class T> | |
KOKKOS_INLINE_FUNCTION complex<T> pow(const complex<T>& x, | |
const complex<T>& y) { | |
using Kokkos::Experimental::log; | |
return x == T() ? T() : exp(y * log(x)); | |
} |
instead of
kokkos/core/src/Kokkos_Complex.hpp
Lines 785 to 790 in 4258629
template <class T, class U> | |
KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(const complex<T>& x, | |
const U& y) { | |
using type = Impl::promote_2_t<T, U>; | |
return pow(complex<type>(x), type(y)); | |
} |
like the error message suggests...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This surprised me too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nliber I think I understand now.
From Daveed'd book (2nd edition):
# 15.7.1 Immediate Context
SFINAE protects against attempts to form invalid types or expressions, including errors due to
ambiguities or access control violation that occurs within the *immediate context* of the function
template substitution. [...] Specifically, during function template substitution for the purpose
of deduction, anything that happens during the instantiation of
* the definition of a class template (i.e., its body and list of base classes),
* [...]
is not part of the immediate context of that function template substitution. [...]
So if substituting the template parameters of a function template declaration requires the
instantiation of the body of a class template because a member of that class is being referred to,
an error during that instantiation is not in the immediate context of the function template
substitution and is therefore a real error (even if another function template matches without
an error).
ef2d9fb
to
7e4787c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks OK to me.
7e4787c
to
259b1b7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @dalg24
Kokkos::pow(Kokkos::complex<double>(2., 1.), 3)); | ||
ASSERT_EQ( | ||
Kokkos::pow(Kokkos::complex<double>(2., 1.), 3.), | ||
Kokkos::pow(Kokkos::complex<double>(2., 1.), Kokkos::complex<double>(3))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This surprised me too.
diff --git a/core/src/Kokkos_Complex.hpp b/core/src/Kokkos_Complex.hpp
index a3f5c3a0..51eae71f 100644
--- a/core/src/Kokkos_Complex.hpp
+++ b/core/src/Kokkos_Complex.hpp
@@ -49,6 +49,7 @@
#include <Kokkos_NumericTraits.hpp>
#include <impl/Kokkos_Error.hpp>
#include <complex>
+#include <type_traits>
#include <iosfwd>
#ifdef KOKKOS_ENABLE_SYCL
@@ -727,9 +728,6 @@ KOKKOS_INLINE_FUNCTION complex<T> pow(const complex<T>& x, const T& y) {
template <class T>
KOKKOS_INLINE_FUNCTION complex<T> pow(const T& x, const complex<T>& y) {
- using Kokkos::Experimental::log;
- using Kokkos::Experimental::pow;
-
return pow(complex<T>(x), y);
}
@@ -769,29 +767,18 @@ struct promote_2 {
};
template <class T, class U>
using promote_2_t = typename promote_2<T, U>::type;
-// complex specializations
-template <class T, class U>
-struct promote_2<Kokkos::complex<T>, U> {
- using type = Kokkos::complex<promote_2_t<T, U>>;
-};
-template <class T, class U>
-struct promote_2<T, Kokkos::complex<U>> {
- using type = Kokkos::complex<promote_2_t<T, U>>;
-};
-template <class T, class U>
-struct promote_2<Kokkos::complex<T>, Kokkos::complex<U>> {
- using type = Kokkos::complex<promote_2_t<T, U>>;
-};
} // namespace Impl
-template <class T, class U>
+template <class T, class U,
+ class = std::enable_if_t<std::is_arithmetic<T>::value>>
KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
const T& x, const complex<U>& y) {
using type = Impl::promote_2_t<T, U>;
return pow(type(x), complex<type>(y));
}
-template <class T, class U>
+template <class T, class U,
+ class = std::enable_if_t<std::is_arithmetic<U>::value>>
KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(const complex<T>& x,
const U& y) {
using type = Impl::promote_2_t<T, U>; |
259b1b7
to
8e3cfee
Compare
Fix #3867
See https://eel.is/c++draft/complex.numbers#cmplx.over-3
I also added the
Kokkos::polar
free function which is provided in<complex>
https://eel.is/c++draft/complex.numbers#complex.value.ops