- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For Intel(R) oneAPI DPC++/C++ Compiler 2021.2.0 (2021.x.0.20210323), if one has a parent object that is not trivially copy-constructible, such as
std::pair<double, std::vector<double> > the_pair
then accessing the trivially copyable data member the_pair.first inside the kernel results in compile errors:
test.C:60:17: error: kernel parameter has non-trivially copy constructible class/struct type 'std::pair<double, std::vector<double>>'
data[i] = the_pair.first;
However adding an intermediate reference:
double &first_elem_ref = the_pair.first;
and accessing first_elem_ref inside the kernel is allowed. This suggests that the compiler is treating accesses to trivially copyable members by attempting to copy the entire object rather than just the member.
Attached is a simple demonstration. To use,
> make broken <-- error
> make working <--- no error
using the attached.
It seems to me that this should not be the intended behavior?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Rahul,
Thank you for your response. What I was trying to convey was that I believe the auto capture should only capture the actual data used in the kernel, in this case it should only copy the double "the_pair.first", but instead the compiler complains because it is trying to copy the entire object "the_pair" to the GPU, which contains a member which is not trivially copyable.
That being said, I have done a little research and it seems that the same behavior also applies for regular c++ lambdas, e.g.
struct my_struct{
double a;
my_struct() = default;
my_struct(const my_struct &r) = delete;
};
template<typename T>
void lambda_apply(const T&l){
l();
}
int main(void){
my_struct d;
d.a = 3.14;
double test;
double* test_p = &test;
lambda_apply([=]{ *test_p = d.a; });
return 0;
}
with g++ gives
test.cc:18:16: error: use of deleted function 'my_struct::my_struct(const my_struct&)'
18 | lambda_apply([=]{ *test_p = d.a; });
| ^~~~~~~~~~~~~~~~~~~~~
test.cc:4:3: note: declared here
4 | my_struct(const my_struct &r) = delete;
| ^~~~~~~~~
make: *** [Makefile:2: test] Error 1
Thus it seems that g++ also is trying to capture the entire object and not just the member. As such I will complain no further and will use the intermediate reference workaround if necessary.
Thanks,
Chris
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
>>This suggests that the compiler is treating accesses to trivially copyable members by attempting to copy the entire object rather than just the member.
Could you please let me know how did you arrive at this conclusion?
Alternatively, since you only require the data of the first pair to be read-only, instead of creating a reference variable, you may store the data in a temporary variable and assign that variable to data[i].
double first_elem = the_pair.first;
accelerator_for(i, 100, 1, {
#ifdef USE_BROKEN
data[i] = the_pair.first;
#else
data[i] = first_elem;
#endif
});
Let us know if you face any issues.
Thanks,
Rahul
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Rahul,
Thank you for your response. What I was trying to convey was that I believe the auto capture should only capture the actual data used in the kernel, in this case it should only copy the double "the_pair.first", but instead the compiler complains because it is trying to copy the entire object "the_pair" to the GPU, which contains a member which is not trivially copyable.
That being said, I have done a little research and it seems that the same behavior also applies for regular c++ lambdas, e.g.
struct my_struct{
double a;
my_struct() = default;
my_struct(const my_struct &r) = delete;
};
template<typename T>
void lambda_apply(const T&l){
l();
}
int main(void){
my_struct d;
d.a = 3.14;
double test;
double* test_p = &test;
lambda_apply([=]{ *test_p = d.a; });
return 0;
}
with g++ gives
test.cc:18:16: error: use of deleted function 'my_struct::my_struct(const my_struct&)'
18 | lambda_apply([=]{ *test_p = d.a; });
| ^~~~~~~~~~~~~~~~~~~~~
test.cc:4:3: note: declared here
4 | my_struct(const my_struct &r) = delete;
| ^~~~~~~~~
make: *** [Makefile:2: test] Error 1
Thus it seems that g++ also is trying to capture the entire object and not just the member. As such I will complain no further and will use the intermediate reference workaround if necessary.
Thanks,
Chris
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Since your issue is resolved, I will go ahead and close this thread from my end. Intel will no longer monitor this thread. Further interactions on this thread will be considered community only.
Thanks,
Rahul
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page