Skip to content

Add sycl quick refs #179

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 5 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion Code_Exercises/Exercise_02_Hello_World/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,37 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.
*/

*
* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Include SYCL header
* #if __has_include(<SYCL/sycl.hpp>)
* #include <SYCL/sycl.hpp>
* #else
* #include <CL/sycl.hpp>
* #endif
*
*
* // Default construct a queue
* auto q = sycl::queue{};
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
* auto q = sycl::queue{};
* sycl::queue q;

*
* // Submit work to the queue
* q.submit([&](sycl::handler &cgh) {
* // COMMAND GROUP
* });
*
* // Within the command group you can
* // 1. Enqueue a command:
* cgh.single_task<class mykernel>([=] {
* // Do something
* });
*
* 2. Declare a sycl::stream for printing from device:
* auto os = sycl::stream{buf_size, wi_size, cgh};
*
*/

#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
Expand Down
40 changes: 40 additions & 0 deletions Code_Exercises/Exercise_05_Device_Selection/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,46 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.
*
* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Make a child class of sycl::device_selector
Copy link
Contributor

Choose a reason for hiding this comment

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

Obsolete. Use lambda instead.

Copy link
Contributor Author

@hdelan hdelan Aug 29, 2022

Choose a reason for hiding this comment

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

Lambdas currently not implemented for device selection in DPC++. Will raise an issue about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry actually implemented here intel/llvm#6486. Will change

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah this was introduced very recently in DPC++, so if all implementations support that now we should switch to that, if you want we could have a separate issue/PR for this as we'll likely want to update the lecture on device selection as well.

* class my_functor_selector : public sycl::device_selector {
* // Overload operator() for sycl::device.
* int operator()(const sycl::device& dev) const override {
* ...
* }
* }
* ...
* auto q = sycl::queue{my_functor_selector{}};
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* // Or use a function selector
* int my_function_selector(const sycl::device &d) {
* ...
* }
* ...
* auto q = sycl::queue{my_function_selector};
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* // Or use a lambda selector
* auto my_lambda_selector = [](const sycl::device &d) {
* ...
* };
* ...
* auto q = sycl::queue{my_lambda_selector};
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* // Query a device for some things:
* std::string vendor = dev.get_info<sycl::info::device::vendor>();
* std::string dev_name = dev.get_info<sycl::info::device::name>();
* std::string dev_driver_ver = dev.get_info<sycl::info::device::driver_version>();
*
*
*/

#define CATCH_CONFIG_MAIN
Expand Down
30 changes: 30 additions & 0 deletions Code_Exercises/Exercise_06_Vector_Add/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,36 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.

* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Default construct a queue
* auto q = sycl::queue{};
Copy link
Contributor

Choose a reason for hiding this comment

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

Idem

*
* // Declare a buffer pointing to ptr
* auto buf = sycl::buffer{ptr, sycl::range{n}};
*
* // Submit work to the queue
* q.submit([&](sycl::handler &cgh) {
* // COMMAND GROUP
* });
*
* // Within the command group you can
* // 1. Declare an accessor to a buffer
* auto read_write_acc = sycl::accessor{buf, cgh};
* auto read_acc = sycl::accessor{buf, cgh, sycl::read_only};
* auto write_acc = sycl::accessor{buf, cgh, sycl::write_only};
* auto no_init_acc = sycl::accessor{buf, cgh, sycl::no_init};
Copy link
Contributor

Choose a reason for hiding this comment

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

It is not clear what is the value of using the auto notation besides making the line longer. Otherwise there is get_access... ;-)

Copy link
Contributor Author

@hdelan hdelan Aug 26, 2022

Choose a reason for hiding this comment

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

I am a little bit biased - personally I feel that this notation is the easiest to read and make sense of. If we write:

sycl::accessor read_acc {buf, cgh, sycl::read_only};

I think the name of the variable is not as readable as the above notation.

Using the notation:

auto var_name = class{...};

is very consistent and readable. The start of the var name is always at the same (relative) col and always before an equals sign. I know this is a bit pedantic but I think it is justified! :)

Copy link
Contributor Author

@hdelan hdelan Aug 26, 2022

Choose a reason for hiding this comment

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

Also for learning reasons we only want to use auto if the type of the obj is self evident. So something like:

auto acc = buf.get_access<mode>(...);

Is not very useful. Moreover using the accessor constructor instead of get_access allows us to use CTAD, which is modern and clean!

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes you can write as you want anyway, at the end this is your code. :-)
Just that the sycl::accessor has been improved to have CTAD in SYCL 2020 often terser than the auto syntax with get_access.

* // 2. Enqueue a single task:
* cgh.single_task<class mykernel>([=]() {
* // Do something
* });
* // 3. Enqueue a parallel for:
* cgh.parallel_for<class mykernel>(sycl::range{n}, [=](sycl::id<1> i) {
* // Do something
* });
*
*/

#define CATCH_CONFIG_MAIN
Expand Down
45 changes: 43 additions & 2 deletions Code_Exercises/Exercise_09_Synchronization/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,53 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.

* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Default construct a queue
* auto q = sycl::queue{};
*
* // Declare a buffer pointing to ptr
* auto buf = sycl::buffer{ptr, sycl::range{n}};
*
* // Do a USM malloc_device
* auto ptr = sycl::malloc_device<T>(n, q);
*
* // Do a USM memcpy
* q.memcpy(dst_ptr, src_ptr, sizeof(T)*n);
*
* // Wait on a queue
* q.wait();
*
* // Submit work to the queue
* q.submit([&](sycl::handler &cgh) {
* // COMMAND GROUP
* });
*
*
* // Within the command group you can
* // 1. Declare an accessor to a buffer
* auto read_write_acc = sycl::accessor{buf, cgh};
* auto read_acc = sycl::accessor{buf, cgh, sycl::read_only};
* auto write_acc = sycl::accessor{buf, cgh, sycl::write_only};
* auto no_init_acc = sycl::accessor{buf, cgh, sycl::no_init};
* // 2. Enqueue a parallel for:
* cgh.parallel_for<class mykernel>(sycl::range{n},
* [=](sycl::id<1> i) { // Do something });
*
*
*/

#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

TEST_CASE("synchronization", "synchronization_source") {
// Use your code from Exercises 6 and 8 to start
TEST_CASE("synchronization_usm", "synchronization_source") {
// Use your code from Exercise 3 to start
REQUIRE(true);
}

TEST_CASE("synchronization_buffer_acc", "synchronization_source") {
// Use your code from Exercise 3 to start
REQUIRE(true);
}
43 changes: 43 additions & 0 deletions Code_Exercises/Exercise_10_Managing_Dependencies/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,49 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.

* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Default construct a queue
* auto q = sycl::queue{};
*
* // Declare a buffer pointing to ptr
* auto buf = sycl::buffer{ptr, sycl::range{n}};
*
* // Do a USM memcpy
* auto event = q.memcpy(dst_ptr, src_ptr, sizeof(T)*n);
* // Do a USM memcpy with dependent events
* auto event = q.memcpy(dst_ptr, src_ptr, sizeof(T)*n, {event1, event2});
*
* // Wait on an event
* event.wait();
*
* // Wait on a queue
* q.wait();
*
* // Submit work to the queue
* auto event = q.submit([&](sycl::handler &cgh) {
* // COMMAND GROUP
* });
*
*
* // Within the command group you can
* // 1. Declare an accessor to a buffer
* auto read_write_acc = sycl::accessor{buf, cgh};
* auto read_acc = sycl::accessor{buf, cgh, sycl::read_only};
* auto write_acc = sycl::accessor{buf, cgh, sycl::write_only};
* auto no_init_acc = sycl::accessor{buf, cgh, sycl::no_init};
* // 2. Enqueue a parallel for:
* // i: Without dependent events
* cgh.parallel_for<class mykernel>(sycl::range{n},
* [=](sycl::id<1> i) { // Do something });
* // ii: With dependent events
* cgh.parallel_for<class mykernel>(sycl::range{n},
* {event1, event2}, [=](sycl::id<1> i) {
* // Do something
* });
*
*/

#define CATCH_CONFIG_MAIN
Expand Down
47 changes: 47 additions & 0 deletions Code_Exercises/Exercise_11_In_Order_Queue/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,53 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.

* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Default construct a queue
* auto q = sycl::queue{};
*
* // Construct an in-order queue
* auto q = sycl::queue{sycl::default_selector{},
* {sycl::property::queue::in_order{}}};
*
* // Declare a buffer pointing to ptr
* auto buf = sycl::buffer{ptr, sycl::range{n}};
*
* // Do a USM memcpy
* auto event = q.memcpy(dst_ptr, src_ptr, sizeof(T)*n);
* // Do a USM memcpy with dependent events
* auto event = q.memcpy(dst_ptr, src_ptr, sizeof(T)*n, {event1, event2});
*
* // Wait on an event
* event.wait();
*
* // Wait on a queue
* q.wait();
*
* // Submit work to the queue
* auto event = q.submit([&](sycl::handler &cgh) {
* // COMMAND GROUP
* });
*
*
* // Within the command group you can
* // 1. Declare an accessor to a buffer
* auto read_write_acc = sycl::accessor{buf, cgh};
* auto read_acc = sycl::accessor{buf, cgh, sycl::read_only};
* auto write_acc = sycl::accessor{buf, cgh, sycl::write_only};
* auto no_init_acc = sycl::accessor{buf, cgh, sycl::no_init};
* // 2. Enqueue a parallel for:
* // i: Without dependent events
* cgh.parallel_for<class mykernel>(sycl::range{n},
* [=](sycl::id<1> i) { // Do something });
* // ii: With dependent events
* cgh.parallel_for<class mykernel>(sycl::range{n},
* {event1, event2}, [=](sycl::id<1> i) {
* // Do something
* });

*/

#define CATCH_CONFIG_MAIN
Expand Down
39 changes: 39 additions & 0 deletions Code_Exercises/Exercise_12_Temporary_Data/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,45 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.

* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Default construct a queue
* auto q = sycl::queue{};
*
* // Declare a buffer pointing to ptr
* auto buf = sycl::buffer{ptr, sycl::range{n}};
*
* // Declare a buffer using host ptr
* auto buf = sycl::buffer{ptr, sycl::range{n},
* {sycl::property::buffer::use_host_ptr{}}};
*
* // Declare a buffer relating to no host memory
* auto buf = sycl::buffer{sycl::range{n}};
*
* // Set final data of a buffer
* buf.set_final_data(host_ptr);
*
* // Set final data of a buffer to nullptr
* buf.set_final_data(nullptr);
*
* // Submit work to the queue
* q.submit([&](sycl::handler &cgh) {
* // COMMAND GROUP
* });
*
* // Within the command group you can
* // 1. Declare an accessor to a buffer
* auto read_write_acc = sycl::accessor{buf, cgh};
* auto read_acc = sycl::accessor{buf, cgh, sycl::read_only};
* auto write_acc = sycl::accessor{buf, cgh, sycl::write_only};
* auto no_init_acc = sycl::accessor{buf, cgh, sycl::no_init};
* // 2. Enqueue a parallel for:
* cgh.parallel_for<class mykernel>(sycl::range{n}, [=](sycl::id<1> i) {
* // Do something
* });
*
*/

#define CATCH_CONFIG_MAIN
Expand Down
34 changes: 34 additions & 0 deletions Code_Exercises/Exercise_13_Load_Balancing/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,40 @@

You should have received a copy of the license along with this
work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.

* SYCL Quick Reference
* ~~~~~~~~~~~~~~~~~~~~
*
* // Get all available devices
* auto devs = sycl::device::get_devices();
*
* // Construct a queue with a device
* auto q = sycl::queue{my_device};
*
* // Declare a buffer pointing to ptr
* auto buf = sycl::buffer{ptr, sycl::range{n}};
*
* // Submit work to the queue
* q.submit([&](sycl::handler &cgh) {
* // COMMAND GROUP
* });
*
* // Within the command group you can
* // 1. Declare an accessor to a buffer
* auto read_write_acc = sycl::accessor{buf, cgh};
* auto read_acc = sycl::accessor{buf, cgh, sycl::read_only};
* auto write_acc = sycl::accessor{buf, cgh, sycl::write_only};
* auto no_init_acc = sycl::accessor{buf, cgh, sycl::no_init};
* // 2. Enqueue a single task:
* cgh.single_task<class mykernel>([=]() {
* // Do something
* });
* // 3. Enqueue a parallel for:
* cgh.parallel_for<class mykernel>(sycl::range{n}, [=](sycl::id<1> i) {
* // Do something
* });
*

*/

#define CATCH_CONFIG_MAIN
Expand Down
Loading