-
Notifications
You must be signed in to change notification settings - Fork 6
Add initial marray implementation #12
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
Conversation
a6a11d4 to
2c06f31
Compare
|
@TApplencourt this PR is now ready for review, testing of the marray type has been added. |
|
@TApplencourt friendly ping to request a review on this |
|
Oh thanks a lot for the ping. I totally miss Aidan previous message! Sorry about that |
|
No problem :) |
|
Sorry, Didn't forget about this! Will find the time to review this week |
Update sycl_complex_marray branch
| sycl::marray<complex<T>, NumElements> | ||
| make_complex_marray(const sycl::marray<T, NumElements> &real, | ||
| const sycl::marray<T, NumElements> &imag) { | ||
| sycl::marray<complex<T>, NumElements> rtn; |
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.
Stupid question, but can we not have a new array constructor? (and not a free function)
| template <class T, std::size_t NumElements> | ||
| sycl::marray<complex<T>, NumElements> | ||
| make_complex_marray(const sycl::marray<T, NumElements> &real, const T &imag) { | ||
| sycl::marray<complex<T>, NumElements> rtn; | ||
|
|
||
| for (std::size_t i = 0; i < NumElements; ++i) { | ||
| rtn[i].real(real[i]); | ||
| rtn[i].imag(imag); | ||
| } | ||
|
|
||
| return rtn; | ||
| } | ||
|
|
||
| template <class T, std::size_t NumElements> | ||
| sycl::marray<complex<T>, NumElements> | ||
| make_complex_marray(const T &real, const sycl::marray<T, NumElements> &imag) { | ||
| sycl::marray<complex<T>, NumElements> rtn; | ||
|
|
||
| for (std::size_t i = 0; i < NumElements; ++i) { | ||
| rtn[i].real(real); | ||
| rtn[i].imag(imag[i]); | ||
| } | ||
|
|
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.
Do we really want those? They sound super ugly... (and lead to bug in user-code)
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.
Yes, we can remove all make_complex_marray implementations.
I'll generate the marray test cases using the GENERATE macro from catch2.
// Test cases
auto init_re = GENERATE(test_marray<T, NumElements>{
1.0, 4.42, -3, 4.0, 2.02, inf_val<T>, inf_val<T>, 2.02, nan_val<T>,
nan_val<T>, inf_val<T>, nan_val<T>, inf_val<T>, nan_val<T>});
auto init_im = GENERATE(test_marray<T, NumElements>{
1.0, 2.02, 3.5, -4.0, inf_val<T>, 4.42, nan_val<T>, 4.42, nan_val<T>,
nan_val<T>, inf_val<T>, nan_val<T>, inf_val<T>, nan_val<T>});
sycl::marray<sycl::ext::cplx::complex<T>, NumElements> cplx_input = sycl::ext::cplx::make_complex_marray(init_re.get(), init_im.get());
becomes
auto cplx_input = GENERATE(sycl::marray<sycl::ext::cplx::complex<T>, NumElements>{
sycl::ext::cplx::complex<T>{1.0, 1.0},
sycl::ext::cplx::complex<T>{4.42, 2.02},
sycl::ext::cplx::complex<T>{-3, 3.5},
sycl::ext::cplx::complex<T>{4.0, -4.0},
sycl::ext::cplx::complex<T>{2.02, inf_val<T>},
sycl::ext::cplx::complex<T>{inf_val<T>, 4.42},
sycl::ext::cplx::complex<T>{inf_val<T>, nan_val<T>},
sycl::ext::cplx::complex<T>{2.02, 4.42},
sycl::ext::cplx::complex<T>{nan_val<T>, nan_val<T>},
sycl::ext::cplx::complex<T>{nan_val<T>, nan_val<T>},
sycl::ext::cplx::complex<T>{inf_val<T>, inf_val<T>},
sycl::ext::cplx::complex<T>{nan_val<T>, nan_val<T>},
sycl::ext::cplx::complex<T>{inf_val<T>, inf_val<T>},
sycl::ext::cplx::complex<T>{nan_val<T>, nan_val<T>},
});
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! I would like to keep this namespace as small as possible. Extending CATCH2 Macro sound like a good path :)
|
|
||
| // Get | ||
|
|
||
| template <class T, std::size_t NumElements> |
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.
Should we have those free functions?
Why nover overlead .real() on marray to return those?
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 can also remove the Getter and Setter.
There is no real neither imag methods for the specialisation of the marray
Would you prefer not to have these functionalities on marray (just delete it)
Or implement real and imag methods on the marray specialization?
real() -> sycl::marray<T, NumElements> // getter
imag() -> sycl::marray<T, NumElements> // getter
real(sycl::marray<T, NumElements>) // setter
imag(sycl::marray<T, NumElements>) // setter
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.
@TApplencourt ☝️ ?
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.
Or implement real and imag methods on the marray specialization?
This sound cleaner to me! (sorry for the delay)
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.
Here's the list of all getters and setters proposed in this PR:
// getter functions
sycl::marray<T, NumElements> real();
sycl::marray<T, NumElements> imag();
T real(std::size_t index);
T imag(std::size_t index);
template <std::size_t... I> auto constexpr real(std::integer_sequence<std::size_t, I...> int_seq);
template <std::size_t... I> auto constexpr imag(std::integer_sequence<std::size_t, I...> int_seq)
// setter functions
void real(const sycl::marray<T, NumElements> &values);
void imag(const sycl::marray<T, NumElements> &values);
void real(const T &value);
void imag(const T &value);
void real(std::size_t index, const T &value);
void imag(std::size_t index, const T &value);
One problem with overloading the real and imag for both getters and
setters is that we will create an ambiguous situation since overload resolution
doesn't depend on return values, but only arguments.
- getter:
T real(std::size_t index); - setter:
void real(const T &value);
What we could do is to keep the getX and setX and overload them, or
other variants like implicit (ex: real) for getter and explicit
(ex: setReal) for setters.
What do you think?
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 think keeping real() / imag() as a getter is a good idea (it mimic std::complex )
(By the way, do we need real(std::size_t index) I guess we can always do a[i].real()?)
For setting, this is a good question... Can we just do like std::complex? Aka, just use &=?
If the user passes a std::marray<complex> we set both real and imaging, and if just a std::marray<float>, we set just the real part. If people want to set a particular value a[i]=23 should do the trick.
What do you think?
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.
Since we are starting to rethink the design of the marray implementation, I believe we should do this as part of the DPC++ and Khronos proposal.
I'll update the marray's DPC++ proposal, and I'll ping you there so we can continue our discussion together with the community as well.
Then, we'll take back the decision made in the proposal, and I'll update the implementation.
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.
Good idea; thanks a lot!
|
Thanks a lot, and sorry for all the |
| test_marray<T, NumElements> init_im1, \ | ||
| test_marray<T, NumElements> init_re2, \ | ||
| test_marray<T, NumElements> init_im2) { \ | ||
| auto *cplx_inout = sycl::malloc_shared< \ |
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.
Memory leak, cplx_inout is not freed
|
Due to the new PR introducing the restructured Please refer to the new PR #33, |
This PR adds the
marray<complex, N>specialization. Themarraycomplex specialization is added using a mixture of free functions and deleting non applicable operators. This causes themarrayinterface to deviate slightly for the original sycl interface. The marray class is added in the sycl namespace to allow for proper specialization.This additionally adds tests for the operators, interface, and free functions.