From 668e53e42e210d2cedf29281eb187e8d7f129651 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Tue, 18 Nov 2025 17:46:04 +0100 Subject: Working on tests in sycl --- modules/remote-sycl/.nix/derivation.nix | 2 +- modules/remote-sycl/c++/common.hpp | 1 + modules/remote-sycl/c++/data.hpp | 63 +++++++- modules/remote-sycl/tests/data.cpp | 110 ------------- modules/remote-sycl/tests/data.foo | 110 +++++++++++++ modules/remote-sycl/tests/data_ref.cpp | 18 +++ modules/remote-sycl/tests/mixed_precision.cpp | 217 -------------------------- modules/remote-sycl/tests/mixed_precision.foo | 217 ++++++++++++++++++++++++++ modules/remote-sycl/tests/sycl_basics.cpp | 31 ++-- 9 files changed, 422 insertions(+), 347 deletions(-) delete mode 100644 modules/remote-sycl/tests/data.cpp create mode 100644 modules/remote-sycl/tests/data.foo create mode 100644 modules/remote-sycl/tests/data_ref.cpp delete mode 100644 modules/remote-sycl/tests/mixed_precision.cpp create mode 100644 modules/remote-sycl/tests/mixed_precision.foo (limited to 'modules') diff --git a/modules/remote-sycl/.nix/derivation.nix b/modules/remote-sycl/.nix/derivation.nix index 688af18..5839acb 100644 --- a/modules/remote-sycl/.nix/derivation.nix +++ b/modules/remote-sycl/.nix/derivation.nix @@ -48,7 +48,7 @@ in stdenv.mkDerivation { scons prefix=$out build_benchmarks=${build_benchmarks} build_examples=${build_examples} install ''; - doCheck = false; + doCheck = true; checkPhase = '' export ACPP_APPDB_DIR=. scons test diff --git a/modules/remote-sycl/c++/common.hpp b/modules/remote-sycl/c++/common.hpp index 287075f..54a09d1 100644 --- a/modules/remote-sycl/c++/common.hpp +++ b/modules/remote-sycl/c++/common.hpp @@ -11,6 +11,7 @@ namespace saw { namespace rmt { struct Sycl {}; } + namespace encode { template struct Sycl {}; diff --git a/modules/remote-sycl/c++/data.hpp b/modules/remote-sycl/c++/data.hpp index 11dfbf2..e057766 100644 --- a/modules/remote-sycl/c++/data.hpp +++ b/modules/remote-sycl/c++/data.hpp @@ -57,7 +57,7 @@ public: return &(data_[0u]); } - const auto& get_internal_size() const { + auto get_internal_size() const { return size_; } @@ -112,4 +112,63 @@ private: return s; } }; -} + +template +class data>, encode::Sycl> { +public: + using Schema = schema::Ref>; +private: + data* internal_data_ptr_; + data, Encode> dims_; + data size_; + + uint64_t get_full_size() const { + uint64_t s = 1; + + for(uint64_t iter = 0; iter < Dim; ++iter){ + auto& dim_iter = dims_.at(data{iter}); + s *= dim_iter.get(); + } + + return s; + } +public: + data() = delete; + + data(ref, Encode>> ref_data__): + internal_data_ptr_{ref_data__().get_internal_data()}, + dims_{ref_data__().dims()}, + size_{ref_data__().size()} + {} +private: + template + uint64_t get_flat_index(const U& i) const { + static_assert( + std::is_same_v, Encode>> or + std::is_same_v>, + "Unsupported type" + ); + assert(data_.size() == get_full_size()); + uint64_t s = 0; + + uint64_t stride = 1; + + for(uint64_t iter = 0; iter < Dim; ++iter){ + uint64_t ind = [](auto val) -> uint64_t { + using V = std::decay_t; + if constexpr (std::is_same_v>){ + return val.get(); + }else if constexpr (std::is_same_v){ + return val; + }else{ + static_assert(always_false, "Cases exhausted"); + } + }(i.at(iter)); + assert(ind < dims_.at({iter}).get() ); + s += ind * stride; + stride *= dims_.at(iter).get(); + } + + return s; + } +}; diff --git a/modules/remote-sycl/tests/data.cpp b/modules/remote-sycl/tests/data.cpp deleted file mode 100644 index 798b7a5..0000000 --- a/modules/remote-sycl/tests/data.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include - -#include "../c++/transfer.hpp" -#include "../c++/remote.hpp" - -namespace { -namespace schema { -using namespace saw::schema; - -using TestStruct = Struct< - Member, - Member, - Member, "baz"> ->; -} - -SAW_TEST("SYCL Data Management"){ - using namespace saw; - - data host_data; - auto& foo = host_data.template get<"foo">(); - foo = 321u; - auto& bra = host_data.template get<"bra">(); - bra = 123; - auto& baz = host_data.template get<"baz">(); - baz = {1024}; - for(data i = 0; i < baz.size(); ++i){ - baz.at(i) = static_cast(i.get()*3); - } - - saw::event_loop loop; - saw::wait_scope wait{loop}; - - remote rmt; - - own> rmt_addr{}; - - rmt.resolve_address().then([&](auto addr){ - rmt_addr = std::move(addr); - }).detach(); - - wait.poll(); - SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); - - auto our_device = share>(); - auto& device = *our_device; - - auto data_srv = data_server, encode::Native, rmt::Sycl>{our_device}; - auto data_cl = data_client, encode::Native, rmt::Sycl>{data_srv}; - - auto eov = data_cl.send(host_data); - SAW_EXPECT(eov.is_value(), "Couldn't send data to SYCL"); - - auto& val = eov.get_value(); - - bool ran = false; - bool error_ran = false; - bool expected_values = true; - std::string err_msg; - - auto conv = data_cl.receive(val).then([&](auto dat) { - ran = true; - - auto& foo_b = dat.template get<"foo">(); - - if(foo != foo_b){ - expected_values = false; - err_msg = "foo not equal. "; - err_msg += std::to_string(foo.get()); - err_msg += " - "; - err_msg += std::to_string(foo_b.get()); - return; - } - - auto& bra_b = dat.template get<"bra">(); - if(bra != bra_b){ - expected_values = false; - err_msg = "bra not equal. "; - err_msg += std::to_string(bra.get()); - err_msg += " - "; - err_msg += std::to_string(bra_b.get()); - return; - } - - auto& baz_b = dat.template get<"baz">(); - if(baz.size() != baz_b.size()){ - expected_values = false; - err_msg = "baz not equal. "; - err_msg += std::to_string(baz.size().get()); - err_msg += " - "; - err_msg += std::to_string(baz_b.size().get()); - return; - } - }, [&](auto err){ - error_ran = true; - return std::move(err); - }); - - auto eob = conv.take(); - if(eob.is_error()){ - auto& err = eob.get_error(); - SAW_EXPECT(false, (std::string{"Conv value doesn't exist: "} + std::string{err.get_category()} + std::string{" - "} + std::string{err.get_message()})); - } - auto& bval = eob.get_value(); - - SAW_EXPECT(!error_ran, "Conveyor ran, but we got an error."); - SAW_EXPECT(ran, "Conveyor didn't run."); - SAW_EXPECT(expected_values, std::string{"Values are not equal. "} + err_msg); -} -} diff --git a/modules/remote-sycl/tests/data.foo b/modules/remote-sycl/tests/data.foo new file mode 100644 index 0000000..798b7a5 --- /dev/null +++ b/modules/remote-sycl/tests/data.foo @@ -0,0 +1,110 @@ +#include + +#include "../c++/transfer.hpp" +#include "../c++/remote.hpp" + +namespace { +namespace schema { +using namespace saw::schema; + +using TestStruct = Struct< + Member, + Member, + Member, "baz"> +>; +} + +SAW_TEST("SYCL Data Management"){ + using namespace saw; + + data host_data; + auto& foo = host_data.template get<"foo">(); + foo = 321u; + auto& bra = host_data.template get<"bra">(); + bra = 123; + auto& baz = host_data.template get<"baz">(); + baz = {1024}; + for(data i = 0; i < baz.size(); ++i){ + baz.at(i) = static_cast(i.get()*3); + } + + saw::event_loop loop; + saw::wait_scope wait{loop}; + + remote rmt; + + own> rmt_addr{}; + + rmt.resolve_address().then([&](auto addr){ + rmt_addr = std::move(addr); + }).detach(); + + wait.poll(); + SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); + + auto our_device = share>(); + auto& device = *our_device; + + auto data_srv = data_server, encode::Native, rmt::Sycl>{our_device}; + auto data_cl = data_client, encode::Native, rmt::Sycl>{data_srv}; + + auto eov = data_cl.send(host_data); + SAW_EXPECT(eov.is_value(), "Couldn't send data to SYCL"); + + auto& val = eov.get_value(); + + bool ran = false; + bool error_ran = false; + bool expected_values = true; + std::string err_msg; + + auto conv = data_cl.receive(val).then([&](auto dat) { + ran = true; + + auto& foo_b = dat.template get<"foo">(); + + if(foo != foo_b){ + expected_values = false; + err_msg = "foo not equal. "; + err_msg += std::to_string(foo.get()); + err_msg += " - "; + err_msg += std::to_string(foo_b.get()); + return; + } + + auto& bra_b = dat.template get<"bra">(); + if(bra != bra_b){ + expected_values = false; + err_msg = "bra not equal. "; + err_msg += std::to_string(bra.get()); + err_msg += " - "; + err_msg += std::to_string(bra_b.get()); + return; + } + + auto& baz_b = dat.template get<"baz">(); + if(baz.size() != baz_b.size()){ + expected_values = false; + err_msg = "baz not equal. "; + err_msg += std::to_string(baz.size().get()); + err_msg += " - "; + err_msg += std::to_string(baz_b.size().get()); + return; + } + }, [&](auto err){ + error_ran = true; + return std::move(err); + }); + + auto eob = conv.take(); + if(eob.is_error()){ + auto& err = eob.get_error(); + SAW_EXPECT(false, (std::string{"Conv value doesn't exist: "} + std::string{err.get_category()} + std::string{" - "} + std::string{err.get_message()})); + } + auto& bval = eob.get_value(); + + SAW_EXPECT(!error_ran, "Conveyor ran, but we got an error."); + SAW_EXPECT(ran, "Conveyor didn't run."); + SAW_EXPECT(expected_values, std::string{"Values are not equal. "} + err_msg); +} +} diff --git a/modules/remote-sycl/tests/data_ref.cpp b/modules/remote-sycl/tests/data_ref.cpp new file mode 100644 index 0000000..03afb8f --- /dev/null +++ b/modules/remote-sycl/tests/data_ref.cpp @@ -0,0 +1,18 @@ +#include + +#include "../c++/data.hpp" + +namespace { +namespace sch { +using namespace saw::schema; +} + +SAW_TEST("Data Ref Basics"){ + using namespace saw; + + acpp::sycl::queue sycl_q; + + data, encode::Sycl> dat{{{100u}},sycl_q}; + +} +} diff --git a/modules/remote-sycl/tests/mixed_precision.cpp b/modules/remote-sycl/tests/mixed_precision.cpp deleted file mode 100644 index 4a5218d..0000000 --- a/modules/remote-sycl/tests/mixed_precision.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include - -#include "../c++/data.hpp" -#include "../c++/device.hpp" -#include "../c++/remote.hpp" - -#include - -namespace { -namespace schema { -using namespace saw::schema; - -using TestMixedArray = Array< - MixedPrecision ->; - -using MixedFoo = Interface< - Member, "foo"> ->; - -using TestDoubleArray = Array< - Float64 ->; - -using DoubleFoo = Interface< - Member, "foo"> ->; - -using TestFloatArray = Array< - Float32 ->; - -using FloatFoo = Interface< - Member, "foo"> ->; -} - -constexpr uint64_t test_size = 64ul; - -SAW_TEST("SYCL Mixed Test"){ - using namespace saw; - - std::random_device r; - std::default_random_engine e1{r()}; - std::uniform_real_distribution<> dis{-1.0,1.0}; - - data host_data; - host_data = {test_size}; - for(uint64_t i = 0; i < test_size; ++i){ - host_data.at(i) = static_cast(dis(e1)); - } - - saw::event_loop loop; - saw::wait_scope wait{loop}; - - remote rmt; - - own> rmt_addr{}; - - rmt.resolve_address().then([&](auto addr){ - rmt_addr = std::move(addr); - }).detach(); - - wait.poll(); - SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); - - data> device_data{host_data}; - - cl::sycl::event ev; - - interface, cl::sycl::queue*> cl_iface { -[&](data>& in, cl::sycl::queue* cmd) -> error_or { - - ev = cmd->submit([&](cl::sycl::handler& h){ - - auto acc_buff = in.template access(h); - - h.parallel_for(cl::sycl::range<1>(test_size), [=] (cl::sycl::id<1> it){ - acc_buff[it[0u]] = acc_buff[it[0u]] * data{2.0}; - }); - }); - return saw::void_t{}; - } - }; - auto our_device = share>(); - auto& device = *our_device; - - cl_iface.template call <"foo">(device_data, &(device.get_handle())); - device.get_handle().wait(); - - { - auto end = ev.get_profiling_info(); - auto start = ev.get_profiling_info(); - - std::cout<<"Elapsed kernel time: "<< (end-start) / 1.0e9 << " seconds"< dis{-1.0,1.0}; - - data host_data; - host_data = {test_size}; - for(uint64_t i = 0; i < test_size; ++i){ - host_data.at(i) = static_cast(dis(e1)); - } - - saw::event_loop loop; - saw::wait_scope wait{loop}; - - remote rmt; - - own> rmt_addr{}; - - rmt.resolve_address().then([&](auto addr){ - rmt_addr = std::move(addr); - }).detach(); - - wait.poll(); - SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); - - data> device_data{host_data}; - - cl::sycl::event ev; - - interface, cl::sycl::queue*> cl_iface { -[&](data>& in, cl::sycl::queue* cmd) -> error_or { - - ev = cmd->submit([&](cl::sycl::handler& h){ - - auto acc_buff = in.template access(h); - - h.parallel_for(cl::sycl::range<1>(test_size), [=] (cl::sycl::id<1> it){ - acc_buff[it[0u]] = acc_buff[it[0u]] * data{2.0}; - }); - }); - return saw::void_t{}; - } - }; - auto our_device = share>(); - auto& device = *our_device; - - cl_iface.template call <"foo">(device_data, &(device.get_handle())); - device.get_handle().wait(); - - { - auto end = ev.get_profiling_info(); - auto start = ev.get_profiling_info(); - - std::cout<<"Elapsed kernel time: "<< (end-start) / 1.0e9 << " seconds"< dis{-1.0,1.0}; - - data host_data; - host_data = {test_size}; - for(uint64_t i = 0; i < test_size; ++i){ - host_data.at(i) = static_cast(dis(e1)); - } - - saw::event_loop loop; - saw::wait_scope wait{loop}; - - remote rmt; - - own> rmt_addr{}; - - rmt.resolve_address().then([&](auto addr){ - rmt_addr = std::move(addr); - }).detach(); - - wait.poll(); - SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); - - data> device_data{host_data}; - - cl::sycl::event ev; - - interface, cl::sycl::queue*> cl_iface { -[&](data>& in, cl::sycl::queue* cmd) -> error_or { - - ev = cmd->submit([&](cl::sycl::handler& h){ - - auto acc_buff = in.template access(h); - - h.parallel_for(cl::sycl::range<1>(test_size), [=] (cl::sycl::id<1> it){ - acc_buff[it[0u]] = acc_buff[it[0u]] * data{2.0}; - }); - }); - return saw::void_t{}; - } - }; - auto our_device = share>(); - auto& device = *our_device; - - cl_iface.template call <"foo">(device_data, &(device.get_handle())); - device.get_handle().wait(); - - { - auto end = ev.get_profiling_info(); - auto start = ev.get_profiling_info(); - - std::cout<<"Elapsed kernel time: "<< (end-start) / 1.0e9 << " seconds"< + +#include "../c++/data.hpp" +#include "../c++/device.hpp" +#include "../c++/remote.hpp" + +#include + +namespace { +namespace schema { +using namespace saw::schema; + +using TestMixedArray = Array< + MixedPrecision +>; + +using MixedFoo = Interface< + Member, "foo"> +>; + +using TestDoubleArray = Array< + Float64 +>; + +using DoubleFoo = Interface< + Member, "foo"> +>; + +using TestFloatArray = Array< + Float32 +>; + +using FloatFoo = Interface< + Member, "foo"> +>; +} + +constexpr uint64_t test_size = 64ul; + +SAW_TEST("SYCL Mixed Test"){ + using namespace saw; + + std::random_device r; + std::default_random_engine e1{r()}; + std::uniform_real_distribution<> dis{-1.0,1.0}; + + data host_data; + host_data = {test_size}; + for(uint64_t i = 0; i < test_size; ++i){ + host_data.at(i) = static_cast(dis(e1)); + } + + saw::event_loop loop; + saw::wait_scope wait{loop}; + + remote rmt; + + own> rmt_addr{}; + + rmt.resolve_address().then([&](auto addr){ + rmt_addr = std::move(addr); + }).detach(); + + wait.poll(); + SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); + + data> device_data{host_data}; + + cl::sycl::event ev; + + interface, cl::sycl::queue*> cl_iface { +[&](data>& in, cl::sycl::queue* cmd) -> error_or { + + ev = cmd->submit([&](cl::sycl::handler& h){ + + auto acc_buff = in.template access(h); + + h.parallel_for(cl::sycl::range<1>(test_size), [=] (cl::sycl::id<1> it){ + acc_buff[it[0u]] = acc_buff[it[0u]] * data{2.0}; + }); + }); + return saw::void_t{}; + } + }; + auto our_device = share>(); + auto& device = *our_device; + + cl_iface.template call <"foo">(device_data, &(device.get_handle())); + device.get_handle().wait(); + + { + auto end = ev.get_profiling_info(); + auto start = ev.get_profiling_info(); + + std::cout<<"Elapsed kernel time: "<< (end-start) / 1.0e9 << " seconds"< dis{-1.0,1.0}; + + data host_data; + host_data = {test_size}; + for(uint64_t i = 0; i < test_size; ++i){ + host_data.at(i) = static_cast(dis(e1)); + } + + saw::event_loop loop; + saw::wait_scope wait{loop}; + + remote rmt; + + own> rmt_addr{}; + + rmt.resolve_address().then([&](auto addr){ + rmt_addr = std::move(addr); + }).detach(); + + wait.poll(); + SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); + + data> device_data{host_data}; + + cl::sycl::event ev; + + interface, cl::sycl::queue*> cl_iface { +[&](data>& in, cl::sycl::queue* cmd) -> error_or { + + ev = cmd->submit([&](cl::sycl::handler& h){ + + auto acc_buff = in.template access(h); + + h.parallel_for(cl::sycl::range<1>(test_size), [=] (cl::sycl::id<1> it){ + acc_buff[it[0u]] = acc_buff[it[0u]] * data{2.0}; + }); + }); + return saw::void_t{}; + } + }; + auto our_device = share>(); + auto& device = *our_device; + + cl_iface.template call <"foo">(device_data, &(device.get_handle())); + device.get_handle().wait(); + + { + auto end = ev.get_profiling_info(); + auto start = ev.get_profiling_info(); + + std::cout<<"Elapsed kernel time: "<< (end-start) / 1.0e9 << " seconds"< dis{-1.0,1.0}; + + data host_data; + host_data = {test_size}; + for(uint64_t i = 0; i < test_size; ++i){ + host_data.at(i) = static_cast(dis(e1)); + } + + saw::event_loop loop; + saw::wait_scope wait{loop}; + + remote rmt; + + own> rmt_addr{}; + + rmt.resolve_address().then([&](auto addr){ + rmt_addr = std::move(addr); + }).detach(); + + wait.poll(); + SAW_EXPECT(rmt_addr, "Remote address hasn't been filled"); + + data> device_data{host_data}; + + cl::sycl::event ev; + + interface, cl::sycl::queue*> cl_iface { +[&](data>& in, cl::sycl::queue* cmd) -> error_or { + + ev = cmd->submit([&](cl::sycl::handler& h){ + + auto acc_buff = in.template access(h); + + h.parallel_for(cl::sycl::range<1>(test_size), [=] (cl::sycl::id<1> it){ + acc_buff[it[0u]] = acc_buff[it[0u]] * data{2.0}; + }); + }); + return saw::void_t{}; + } + }; + auto our_device = share>(); + auto& device = *our_device; + + cl_iface.template call <"foo">(device_data, &(device.get_handle())); + device.get_handle().wait(); + + { + auto end = ev.get_profiling_info(); + auto start = ev.get_profiling_info(); + + std::cout<<"Elapsed kernel time: "<< (end-start) / 1.0e9 << " seconds"<, "foo"> >; } +SAW_TEST("SYCL Basics"){ + using namespace saw; + + acpp::sycl::queue q; + data> host_data; +} + +/* SAW_TEST("SYCL Test Setup"){ using namespace saw; @@ -41,33 +49,21 @@ SAW_TEST("SYCL Test Setup"){ data> device_data{host_data}; - interface,cl::sycl::queue*> cl_iface { -[&](data>& in, cl::sycl::queue* cmd) -> error_or { + interface,acpp::sycl::queue*> cl_iface { +[&](data>& in, acpp::sycl::queue* cmd) -> error_or { - cmd->submit([&](cl::sycl::handler& h){ + cmd->submit([&](acpp::sycl::handler& h){ - auto acc_buff = in.template access(h); + auto acc_buff = in.template access(h); auto si = host_data.template get<"doubles">().size(); - h.parallel_for(cl::sycl::range<1>(si.get()), [=] (cl::sycl::id<1> it){ + h.parallel_for(acpp::sycl::range<1>(si.get()), [=] (acpp::sycl::id<1> it){ acc_buff[0u].template get<"foo">() = acc_buff[0u].template get<"doubles">().size(); auto& dbls = acc_buff[0u].template get<"doubles">(); dbls.at(it[0u]) = it[0u] * 2.0; }); }); - /* - cmd->submit([&](cl::sycl::handler& h){ - auto acc_buff = in.template access(h); - h.copy(acc_buff, &host_data); - }); - */ - - /** - cl::sycl::host_accessor result{in.get_handle()}; - std::cout<().get()<().get()<(device_data, &(device.get_handle())); device.get_handle().wait(); } +*/ } -- cgit v1.2.3