- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I previously posted a similar question but not really get a solution. Suppose I need to call a function object and its member function in a kernel:
____________________
Q.submit([&](sycl::handler& h) {
sycl::accessor A(B, h);
h.parallel_for(size, [=](auto& idx) {
my_class& mc_ref =A[idx];
mc_ref.update(); //call member function of my_class
}
);
});
________
According to SYCL specifications, I need to define "my_class" and corresponding member function "my_class::update()" in one header, like
in "my_class.h"_____________
class my_class{
.....
void update() { .... ; return; }
.....
};
________________
Hoever, if I separate definition from class declaration, like
in "my_class.h"_____________
class my_class{
.....
void update() ;
.....
};
in "my_class.cpp"_____________
void my_class::update() { ... ; return;}
___________________________
It would generate compiler error : SYCL kernel cannot call an undefined function without SYCL_EXTERNAL attribute, since the member function is now defined under a different translation unit.
My question is that if there is anyway, or how can I declare "SYCL_EXTERNAL" in this situation so that I can separate class definiton from declaration ??
I need to do this because my code is a little compilcated, and in "my_class" there would be another class objects. (I usually manage data and abstration by C++ class).
If I put all defitions of member functions in one header file, it would be more than 5k lines... which I think is a little crazy and hard to read.
Could anyone provide me an example or some suggestions on how to organize my program in this case?
Thanks so much!
__________
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for posting in Intel Communities.
>>My question is that if there is anyway, or how can I declare "SYCL_EXTERNAL" in this situation so that I can separate class definiton from declaration ??
Yes, you can provide function declaration in a class and it's definition in another file but as per SYCL specifications, the function will come under different translation unit. Please make sure to include "SYCL_EXTERNAL" before function declaration in your header file.
Please go through the modified code files to understand it better.
main.cpp
#include "my_class1.h"
int main()
{
size_t N = 4;
sycl::buffer<int> B(N);
{
sycl::host_accessor a(B, sycl::write_only);
for (int i = 0; i < N; i++) {
a[i] = i;
}
}
queue Q;
Q.submit([&](sycl::handler& h) {
sycl::accessor A(B, h);
h.parallel_for(N, [=](item<1> i) {
my_class mc_ref;
mc_ref.update(A, i); //call member function of my_class
});
});
host_accessor h{B};
for(int i=0;i<N;i++)
std::cout<<h[i]<<" ";
return 0;
}
my_class.cpp
#include "my_class1.h"
//Methods
void my_class::update(cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write> A, cl::sycl::item<1> i)
{
int idx=i.get_id();
A[idx]=A[idx]+1;
}
my_class1.h
#pragma once
#include<iostream>
#include<CL/sycl.hpp>
using namespace sycl;
class my_class{
public:
//extern
SYCL_EXTERNAL void update(cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write> A, cl::sycl::item<1> i);
};
Hope this resolves your issue, if you still face any issues please share the sample reproducer code with us.
Thanks & regards,
Shaik Rabiya
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for posting in Intel Communities.
>>My question is that if there is anyway, or how can I declare "SYCL_EXTERNAL" in this situation so that I can separate class definiton from declaration ??
Yes, you can provide function declaration in a class and it's definition in another file but as per SYCL specifications, the function will come under different translation unit. Please make sure to include "SYCL_EXTERNAL" before function declaration in your header file.
Please go through the modified code files to understand it better.
main.cpp
#include "my_class1.h"
int main()
{
size_t N = 4;
sycl::buffer<int> B(N);
{
sycl::host_accessor a(B, sycl::write_only);
for (int i = 0; i < N; i++) {
a[i] = i;
}
}
queue Q;
Q.submit([&](sycl::handler& h) {
sycl::accessor A(B, h);
h.parallel_for(N, [=](item<1> i) {
my_class mc_ref;
mc_ref.update(A, i); //call member function of my_class
});
});
host_accessor h{B};
for(int i=0;i<N;i++)
std::cout<<h[i]<<" ";
return 0;
}
my_class.cpp
#include "my_class1.h"
//Methods
void my_class::update(cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write> A, cl::sycl::item<1> i)
{
int idx=i.get_id();
A[idx]=A[idx]+1;
}
my_class1.h
#pragma once
#include<iostream>
#include<CL/sycl.hpp>
using namespace sycl;
class my_class{
public:
//extern
SYCL_EXTERNAL void update(cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write> A, cl::sycl::item<1> i);
};
Hope this resolves your issue, if you still face any issues please share the sample reproducer code with us.
Thanks & regards,
Shaik Rabiya
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks so much, Shaik!
I tried your code and it works.
The reason I got stuck here is because I always think "extern" can only be used for a variable or a function, instead of a class member function....
I know that my question is very fundamental and is probably not worth for you spending time to provide an answer : )
Anyway, really thanks!
Best regards,
PC
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for accepting our solution. If you need any additional information, please post a new question as this thread will no longer be monitored by Intel.
Thanks & Regards,
Shaik Rabiya

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page