From 97e690cb8916745f28c8731a863a29a1635a3e46 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Fri, 25 Sep 2020 12:10:17 +0300 Subject: [PATCH 01/14] [SYCL] Improve testing of host-task Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 192 +++++++++++++++++++++- 1 file changed, 183 insertions(+), 9 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index 3f981058c02b..cecd1958d7df 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -1,20 +1,42 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out %threads_lib -lOpenCL -// RUN: %CPU_RUN_PLACEHOLDER %t.out -// RUN: %GPU_RUN_PLACEHOLDER %t.out -// RUN: %ACC_RUN_PLACEHOLDER %t.out +// RUN: %clangxx -std=c++14 -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out 1 +// RUN: %GPU_RUN_PLACEHOLDER %t.out 1 +// RUN: %ACC_RUN_PLACEHOLDER %t.out 1 + +// RUN: %CPU_RUN_PLACEHOLDER %t.out 2 +// RUN: %GPU_RUN_PLACEHOLDER %t.out 2 +// RUN: %ACC_RUN_PLACEHOLDER %t.out 2 + +// RUN: %CPU_RUN_PLACEHOLDER %t.out 3 +// RUN: %GPU_RUN_PLACEHOLDER %t.out 3 +// RUN: %ACC_RUN_PLACEHOLDER %t.out 3 + +// RUN: %CPU_RUN_PLACEHOLDER %t.out 4 +// RUN: %GPU_RUN_PLACEHOLDER %t.out 4 +// RUN: %ACC_RUN_PLACEHOLDER %t.out 4 #include +#include +#include +#include +#include using namespace cl::sycl; using namespace cl::sycl::access; static constexpr size_t BUFFER_SIZE = 1024; +static auto EH = [](exception_list EL) { + for (const std::exception_ptr &E : EL) { + throw E; + } +}; + // Check that a single host-task with a buffer will work void test1() { buffer Buffer{BUFFER_SIZE}; - queue Q; + queue Q(EH); Q.submit([&](handler &CGH) { auto Acc = Buffer.get_access(CGH); @@ -22,13 +44,16 @@ void test1() { // A no-op }); }); + + Q.wait_and_throw(); } +// Check that a host task after the kernel (deps via buffer) will work void test2() { buffer Buffer1{BUFFER_SIZE}; buffer Buffer2{BUFFER_SIZE}; - queue Q; + queue Q(EH); Q.submit([&](handler &CGH) { auto Acc = Buffer1.template get_access(CGH); @@ -55,10 +80,159 @@ void test2() { assert(Acc[Idx] == 123); } } + + Q.wait_and_throw(); } -int main() { - test1(); - test2(); +// Host-task depending on another host-task via both buffers and +// handler::depends_on() should not hang +void test3() { + queue Q(EH); + + static constexpr size_t BufferSize = 10 * 1024; + + buffer B0{range<1>{BufferSize}}; + buffer B1{range<1>{BufferSize}}; + buffer B2{range<1>{BufferSize}}; + buffer B3{range<1>{BufferSize}}; + buffer B4{range<1>{BufferSize}}; + buffer B5{range<1>{BufferSize}}; + buffer B6{range<1>{BufferSize}}; + buffer B7{range<1>{BufferSize}}; + buffer B8{range<1>{BufferSize}}; + buffer B9{range<1>{BufferSize}}; + + std::vector Deps; + + for (size_t Idx = 0; Idx < 10; ++Idx) { + event E = Q.submit([&](handler &CGH) { + CGH.depends_on(Deps); + + std::cout << "Submit: " << Idx << std::endl; + + auto Acc0 = B0.get_access(CGH); + auto Acc1 = B1.get_access(CGH); + auto Acc2 = B2.get_access(CGH); + auto Acc3 = B3.get_access(CGH); + auto Acc4 = B4.get_access(CGH); + auto Acc5 = B5.get_access(CGH); + auto Acc6 = B6.get_access(CGH); + auto Acc7 = B7.get_access(CGH); + auto Acc8 = B8.get_access(CGH); + auto Acc9 = B9.get_access(CGH); + + CGH.codeplay_host_task([=] { + uint64_t X = 0; + + X ^= reinterpret_cast(&Acc0[Idx + 0]); + X ^= reinterpret_cast(&Acc1[Idx + 1]); + X ^= reinterpret_cast(&Acc2[Idx + 2]); + X ^= reinterpret_cast(&Acc3[Idx + 3]); + X ^= reinterpret_cast(&Acc4[Idx + 4]); + X ^= reinterpret_cast(&Acc5[Idx + 5]); + X ^= reinterpret_cast(&Acc6[Idx + 6]); + X ^= reinterpret_cast(&Acc7[Idx + 7]); + X ^= reinterpret_cast(&Acc8[Idx + 8]); + X ^= reinterpret_cast(&Acc9[Idx + 9]); + + std::cout << " Start " << Idx << " (" << X << ")" << std::endl; + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + std::cout << " End " << Idx << std::endl; + }); + }); + + Deps = {E}; + } + + Q.wait_and_throw(); +} + +// Host-task depending on another host-task via handler::depends_on() only +// should not hang +void test4() { + queue Q(EH); + + static constexpr size_t BufferSize = 10 * 1024; + + buffer B0{range<1>{BufferSize}}; + buffer B1{range<1>{BufferSize}}; + buffer B2{range<1>{BufferSize}}; + buffer B3{range<1>{BufferSize}}; + buffer B4{range<1>{BufferSize}}; + buffer B5{range<1>{BufferSize}}; + + // This host task should be submitted without hesitation + event E1 = Q.submit([&](handler &CGH) { + std::cout << "Submit 1" << std::endl; + + auto Acc0 = B0.get_access(CGH); + auto Acc1 = B1.get_access(CGH); + auto Acc2 = B2.get_access(CGH); + + CGH.codeplay_host_task([=]{ + Acc0[0] = 1; + Acc1[0] = 2; + Acc2[0] = 3; + }); + }); + + // This host task is going to depend on blocked empty node of the first + // host-task (via buffer #2). Still this one should be enqueued. + event E2 = Q.submit([&](handler &CGH) { + std::cout << "Submit 2" << std::endl; + + auto Acc2 = B2.get_access(CGH); + auto Acc3 = B3.get_access(CGH); + + CGH.codeplay_host_task([=] { + Acc2[1] = 1; + Acc3[1] = 2; + }); + }); + + // This host-task only depends on the second host-task via + // handler::depends_on(). This one should not hang and should be enqueued + // after host-task #2. + event E3 = Q.submit([&](handler &CGH) { + CGH.depends_on(E2); + + std::cout << "Submit 3" << std::endl; + + auto Acc4 = B4.get_access(CGH); + auto Acc5 = B5.get_access(CGH); + + CGH.codeplay_host_task([=] { + Acc4[2] = 1; + Acc5[2] = 2; + }); + }); + + Q.wait_and_throw(); +} + +int main(int Argc, const char *Argv[]) { + if (Argc < 2) + return 1; + + int TestIdx = std::stoi(Argv[1]); + + switch (TestIdx) { + case 1: + test1(); + break; + case 2: + test2(); + break; + case 3: + test3(); + break; + case 4: + test4(); + break; + default: + return 1; + } + return 0; } From 14e951710dd1537677551d9fe54ff583e09a1471 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Fri, 25 Sep 2020 12:10:54 +0300 Subject: [PATCH 02/14] [SYCL] Disable test-case as it hangs now Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index cecd1958d7df..026c5a821a1b 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -11,9 +11,9 @@ // RUN: %GPU_RUN_PLACEHOLDER %t.out 3 // RUN: %ACC_RUN_PLACEHOLDER %t.out 3 -// RUN: %CPU_RUN_PLACEHOLDER %t.out 4 -// RUN: %GPU_RUN_PLACEHOLDER %t.out 4 -// RUN: %ACC_RUN_PLACEHOLDER %t.out 4 +// RUNx: %CPU_RUN_PLACEHOLDER %t.out 4 +// RUNx: %GPU_RUN_PLACEHOLDER %t.out 4 +// RUNx: %ACC_RUN_PLACEHOLDER %t.out 4 #include #include From 299797bcdd00c00cb94d1ed18758dfad4d986699 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Fri, 25 Sep 2020 12:17:30 +0300 Subject: [PATCH 03/14] Address style issues Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index 026c5a821a1b..d91ef2e9f946 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include using namespace cl::sycl; using namespace cl::sycl::access; @@ -170,7 +170,7 @@ void test4() { auto Acc1 = B1.get_access(CGH); auto Acc2 = B2.get_access(CGH); - CGH.codeplay_host_task([=]{ + CGH.codeplay_host_task([=] { Acc0[0] = 1; Acc1[0] = 2; Acc2[0] = 3; @@ -218,20 +218,20 @@ int main(int Argc, const char *Argv[]) { int TestIdx = std::stoi(Argv[1]); switch (TestIdx) { - case 1: - test1(); - break; - case 2: - test2(); - break; - case 3: - test3(); - break; - case 4: - test4(); - break; - default: - return 1; + case 1: + test1(); + break; + case 2: + test2(); + break; + case 3: + test3(); + break; + case 4: + test4(); + break; + default: + return 1; } return 0; From e7797f4b021a0453a3b296a398623ae79d81d3f2 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Fri, 25 Sep 2020 17:29:37 +0300 Subject: [PATCH 04/14] [SYCL] Improve testing of host-task Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index d91ef2e9f946..ccae5c8b6607 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -104,7 +104,11 @@ void test3() { std::vector Deps; - for (size_t Idx = 0; Idx < 10; ++Idx) { + using namespace std::chrono_literals; + static constexpr size_t Count = 10; + + auto Start = std::chrono::steady_clock::now(); + for (size_t Idx = 0; Idx < Count; ++Idx) { event E = Q.submit([&](handler &CGH) { CGH.depends_on(Deps); @@ -134,11 +138,6 @@ void test3() { X ^= reinterpret_cast(&Acc7[Idx + 7]); X ^= reinterpret_cast(&Acc8[Idx + 8]); X ^= reinterpret_cast(&Acc9[Idx + 9]); - - std::cout << " Start " << Idx << " (" << X << ")" << std::endl; - using namespace std::chrono_literals; - std::this_thread::sleep_for(100ms); - std::cout << " End " << Idx << std::endl; }); }); @@ -146,6 +145,11 @@ void test3() { } Q.wait_and_throw(); + auto End = std::chrono::steady_clock::now(); + + constexpr auto Threshold = 2s; + + assert(End - Start < Threshold && "Host tasks were waiting for too long"); } // Host-task depending on another host-task via handler::depends_on() only From f0fce8fff3bee656171dfb4a51a0ec6404feaca1 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Fri, 25 Sep 2020 17:36:46 +0300 Subject: [PATCH 05/14] [SYCL] Remove unwanted include Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index ccae5c8b6607..9afb14d3f359 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include using namespace cl::sycl; From c94a24559f947b71d9dfd2ee7d1d52e50825a9e6 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Fri, 25 Sep 2020 17:39:22 +0300 Subject: [PATCH 06/14] [SYCL] Use default C++ std Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index 9afb14d3f359..ca355bcb4b65 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -std=c++14 -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out // RUN: %CPU_RUN_PLACEHOLDER %t.out 1 // RUN: %GPU_RUN_PLACEHOLDER %t.out 1 // RUN: %ACC_RUN_PLACEHOLDER %t.out 1 From 8666752831366e86cbebda3ad4d84f5cdce8b439 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Mon, 28 Sep 2020 17:36:13 +0300 Subject: [PATCH 07/14] [SYCL] Improve testing of host task Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 191 ++++++++++++++++++---- 1 file changed, 156 insertions(+), 35 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index ca355bcb4b65..aba34f069d36 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -15,9 +15,22 @@ // RUNx: %GPU_RUN_PLACEHOLDER %t.out 4 // RUNx: %ACC_RUN_PLACEHOLDER %t.out 4 +// RUNx: %CPU_RUN_PLACEHOLDER %t.out 5 +// RUNx: %GPU_RUN_PLACEHOLDER %t.out 5 +// RUNx: %ACC_RUN_PLACEHOLDER %t.out 5 + +// RUNx: %CPU_RUN_PLACEHOLDER %t.out 6 +// RUNx: %GPU_RUN_PLACEHOLDER %t.out 6 +// RUNx: %ACC_RUN_PLACEHOLDER %t.out 6 + +// RUNx: %CPU_RUN_PLACEHOLDER %t.out 7 +// RUNx: %GPU_RUN_PLACEHOLDER %t.out 7 +// RUNx: %ACC_RUN_PLACEHOLDER %t.out 7 + #include #include #include +#include #include using namespace cl::sycl; @@ -103,7 +116,6 @@ void test3() { std::vector Deps; - using namespace std::chrono_literals; static constexpr size_t Count = 10; auto Start = std::chrono::steady_clock::now(); @@ -146,6 +158,7 @@ void test3() { Q.wait_and_throw(); auto End = std::chrono::steady_clock::now(); + using namespace std::chrono_literals; constexpr auto Threshold = 2s; assert(End - Start < Threshold && "Host tasks were waiting for too long"); @@ -153,7 +166,7 @@ void test3() { // Host-task depending on another host-task via handler::depends_on() only // should not hang -void test4() { +void test4(size_t Count = 1) { queue Q(EH); static constexpr size_t BufferSize = 10 * 1024; @@ -165,51 +178,150 @@ void test4() { buffer B4{range<1>{BufferSize}}; buffer B5{range<1>{BufferSize}}; - // This host task should be submitted without hesitation - event E1 = Q.submit([&](handler &CGH) { - std::cout << "Submit 1" << std::endl; + for (size_t Idx = 1; Idx <= Count; ++Idx) { + // This host task should be submitted without hesitation + event E1 = Q.submit([&](handler &CGH) { + std::cout << "Submit 1" << std::endl; - auto Acc0 = B0.get_access(CGH); - auto Acc1 = B1.get_access(CGH); - auto Acc2 = B2.get_access(CGH); + auto Acc0 = B0.get_access(CGH); + auto Acc1 = B1.get_access(CGH); + auto Acc2 = B2.get_access(CGH); - CGH.codeplay_host_task([=] { - Acc0[0] = 1; - Acc1[0] = 2; - Acc2[0] = 3; + CGH.codeplay_host_task([=] { + Acc0[0] = 1 * Idx; + Acc1[0] = 2 * Idx; + Acc2[0] = 3 * Idx; + }); }); - }); - // This host task is going to depend on blocked empty node of the first - // host-task (via buffer #2). Still this one should be enqueued. - event E2 = Q.submit([&](handler &CGH) { - std::cout << "Submit 2" << std::endl; + // This host task is going to depend on blocked empty node of the first + // host-task (via buffer #2). Still this one should be enqueued. + event E2 = Q.submit([&](handler &CGH) { + std::cout << "Submit 2" << std::endl; - auto Acc2 = B2.get_access(CGH); - auto Acc3 = B3.get_access(CGH); + auto Acc2 = B2.get_access(CGH); + auto Acc3 = B3.get_access(CGH); - CGH.codeplay_host_task([=] { - Acc2[1] = 1; - Acc3[1] = 2; + CGH.codeplay_host_task([=] { + Acc2[1] = 1 * Idx; + Acc3[1] = 2 * Idx; + }); }); - }); - // This host-task only depends on the second host-task via - // handler::depends_on(). This one should not hang and should be enqueued - // after host-task #2. - event E3 = Q.submit([&](handler &CGH) { - CGH.depends_on(E2); + // This host-task only depends on the second host-task via + // handler::depends_on(). This one should not hang and should be eexecuted + // after host-task #2. + event E3 = Q.submit([&](handler &CGH) { + CGH.depends_on(E2); - std::cout << "Submit 3" << std::endl; + std::cout << "Submit 3" << std::endl; - auto Acc4 = B4.get_access(CGH); - auto Acc5 = B5.get_access(CGH); + auto Acc4 = B4.get_access(CGH); + auto Acc5 = B5.get_access(CGH); - CGH.codeplay_host_task([=] { - Acc4[2] = 1; - Acc5[2] = 2; + CGH.codeplay_host_task([=] { + Acc4[2] = 1 * Idx; + Acc5[2] = 2 * Idx; + }); }); - }); + } + + Q.wait_and_throw(); +} + +// Host-task depending on another host-task via handler::depends_on() only +// should not hang. A bit more complicated case with kernels depending on +// host-task being involved. +void test5(size_t Count = 1) { + queue Q(EH); + + static constexpr size_t BufferSize = 10 * 1024; + + buffer B0{range<1>{BufferSize}}; + buffer B1{range<1>{BufferSize}}; + buffer B2{range<1>{BufferSize}}; + buffer B3{range<1>{BufferSize}}; + buffer B4{range<1>{BufferSize}}; + buffer B5{range<1>{BufferSize}}; + + using namespace std::chrono_literals; + + for (size_t Idx = 1; Idx <= Count; ++Idx) { + // This host task should be submitted without hesitation + Q.submit([&](handler &CGH) { + std::cout << "Submit HT-1" << std::endl; + + auto Acc0 = B0.get_access(CGH); + + CGH.codeplay_host_task([=] { + std::this_thread::sleep_for(2s); + Acc0[0] = 1 * Idx; + }); + }); + + Q.submit([&](handler &CGH) { + std::cout << "Submit Kernel-1" << std::endl; + + auto Acc0 = B0.get_access(CGH); + + CGH.single_task([=] { + Acc0[1] = 1 * Idx; + }); + }); + + Q.submit([&](handler &CGH) { + std::cout << "Submit Kernel-2" << std::endl; + + auto Acc1 = B1.get_access(CGH); + + CGH.single_task([=] { + Acc1[2] = 1 * Idx; + }); + }); + + Q.submit([&](handler &CGH) { + std::cout << "Submit HT-2" << std::endl; + + auto Acc2 = B2.get_access(CGH); + + CGH.codeplay_host_task([=] { + std::this_thread::sleep_for(2s); + Acc2[3] = 1 * Idx; + }); + }); + + // This host task is going to depend on blocked empty node of the second + // host-task (via buffer #0). Still this one should be enqueued. + event EHT3 = Q.submit([&](handler &CGH) { + std::cout << "Submit HT-3" << std::endl; + + auto Acc0 = B0.get_access(CGH); + auto Acc1 = B1.get_access(CGH); + auto Acc2 = B2.get_access(CGH); + + CGH.codeplay_host_task([=] { + std::this_thread::sleep_for(2s); + Acc0[4] = 1 * Idx; + Acc1[4] = 2 * Idx; + Acc2[4] = 3 * IDx; + }); + }); + + // This host-task only depends on the third host-task via + // handler::depends_on(). This one should not hang and should be executed + // after host-task #3. + Q.submit([&](handler &CGH) { + std::cout << "Submit HT-4" << std::endl; + + CGH.depends_on(EHT3); + + auto Acc5 = B5.get_access(CGH); + + CGH.codeplay_host_task([=] { + Acc5[5] = 1 * IDx; + }); + }); + } Q.wait_and_throw(); } @@ -233,6 +345,15 @@ int main(int Argc, const char *Argv[]) { case 4: test4(); break; + case 5: + test5(); + break; + case 6: + test4(10); + break; + case 7: + test5(10); + break; default: return 1; } From d291557ed08cb456c527ef2c3721ceb31328f6de Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Mon, 28 Sep 2020 17:51:33 +0300 Subject: [PATCH 08/14] Fix syntax issue Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index aba34f069d36..dc05e98469fb 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -303,7 +303,7 @@ void test5(size_t Count = 1) { std::this_thread::sleep_for(2s); Acc0[4] = 1 * Idx; Acc1[4] = 2 * Idx; - Acc2[4] = 3 * IDx; + Acc2[4] = 3 * Idx; }); }); @@ -318,7 +318,7 @@ void test5(size_t Count = 1) { auto Acc5 = B5.get_access(CGH); CGH.codeplay_host_task([=] { - Acc5[5] = 1 * IDx; + Acc5[5] = 1 * Idx; }); }); } From 5aba995a5ce3cdb90b12cfa1b883a1cbece4e246 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Tue, 29 Sep 2020 16:29:43 +0300 Subject: [PATCH 09/14] Fix style issues Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index dc05e98469fb..4616983fff4f 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -274,9 +274,7 @@ void test5(size_t Count = 1) { auto Acc1 = B1.get_access(CGH); - CGH.single_task([=] { - Acc1[2] = 1 * Idx; - }); + CGH.single_task([=] { Acc1[2] = 1 * Idx; }); }); Q.submit([&](handler &CGH) { @@ -317,9 +315,7 @@ void test5(size_t Count = 1) { auto Acc5 = B5.get_access(CGH); - CGH.codeplay_host_task([=] { - Acc5[5] = 1 * Idx; - }); + CGH.codeplay_host_task([=] { Acc5[5] = 1 * Idx; }); }); } From ceb54104822c81f23d5278dc5bad79df1d6d1ac1 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Tue, 29 Sep 2020 16:30:00 +0300 Subject: [PATCH 10/14] Set name for magic constant Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index 4616983fff4f..539d8aef69ec 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -245,6 +245,7 @@ void test5(size_t Count = 1) { buffer B5{range<1>{BufferSize}}; using namespace std::chrono_literals; + constexpr auto SleepFor = 1s; for (size_t Idx = 1; Idx <= Count; ++Idx) { // This host task should be submitted without hesitation @@ -254,7 +255,7 @@ void test5(size_t Count = 1) { auto Acc0 = B0.get_access(CGH); CGH.codeplay_host_task([=] { - std::this_thread::sleep_for(2s); + std::this_thread::sleep_for(SleepFor); Acc0[0] = 1 * Idx; }); }); @@ -283,7 +284,7 @@ void test5(size_t Count = 1) { auto Acc2 = B2.get_access(CGH); CGH.codeplay_host_task([=] { - std::this_thread::sleep_for(2s); + std::this_thread::sleep_for(SleepFor); Acc2[3] = 1 * Idx; }); }); @@ -298,7 +299,7 @@ void test5(size_t Count = 1) { auto Acc2 = B2.get_access(CGH); CGH.codeplay_host_task([=] { - std::this_thread::sleep_for(2s); + std::this_thread::sleep_for(SleepFor); Acc0[4] = 1 * Idx; Acc1[4] = 2 * Idx; Acc2[4] = 3 * Idx; From 94982ee7421960f36c38a5c4096b24bf377ac54a Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Tue, 29 Sep 2020 17:38:38 +0300 Subject: [PATCH 11/14] Split tests to distinct files Signed-off-by: Sergey Kanaev --- .../host-task-dependency2.cpp | 86 ++++++++ .../host-task-dependency3.cpp | 117 +++++++++++ .../host-task-dependency4.cpp | 31 +++ sycl/test/host-interop-task/host-task.cpp | 188 ------------------ 4 files changed, 234 insertions(+), 188 deletions(-) create mode 100644 sycl/test/host-interop-task/host-task-dependency2.cpp create mode 100644 sycl/test/host-interop-task/host-task-dependency3.cpp create mode 100644 sycl/test/host-interop-task/host-task-dependency4.cpp diff --git a/sycl/test/host-interop-task/host-task-dependency2.cpp b/sycl/test/host-interop-task/host-task-dependency2.cpp new file mode 100644 index 000000000000..c926cb1c1216 --- /dev/null +++ b/sycl/test/host-interop-task/host-task-dependency2.cpp @@ -0,0 +1,86 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out + +// RUNx: %CPU_RUN_PLACEHOLDER %t.out +// RUNx: %GPU_RUN_PLACEHOLDER %t.out +// RUNx: %ACC_RUN_PLACEHOLDER %t.out + +// RUNx: %CPU_RUN_PLACEHOLDER %t.out 10 +// RUNx: %GPU_RUN_PLACEHOLDER %t.out 10 +// RUNx: %ACC_RUN_PLACEHOLDER %t.out 10 + +#include +#include + +// Host-task depending on another host-task via handler::depends_on() only +// should not hang +void test(size_t Count) { + queue Q(EH); + + static constexpr size_t BufferSize = 10 * 1024; + + buffer B0{range<1>{BufferSize}}; + buffer B1{range<1>{BufferSize}}; + buffer B2{range<1>{BufferSize}}; + buffer B3{range<1>{BufferSize}}; + buffer B4{range<1>{BufferSize}}; + buffer B5{range<1>{BufferSize}}; + + for (size_t Idx = 1; Idx <= Count; ++Idx) { + // This host task should be submitted without hesitation + event E1 = Q.submit([&](handler &CGH) { + std::cout << "Submit 1" << std::endl; + + auto Acc0 = B0.get_access(CGH); + auto Acc1 = B1.get_access(CGH); + auto Acc2 = B2.get_access(CGH); + + CGH.codeplay_host_task([=] { + Acc0[0] = 1 * Idx; + Acc1[0] = 2 * Idx; + Acc2[0] = 3 * Idx; + }); + }); + + // This host task is going to depend on blocked empty node of the first + // host-task (via buffer #2). Still this one should be enqueued. + event E2 = Q.submit([&](handler &CGH) { + std::cout << "Submit 2" << std::endl; + + auto Acc2 = B2.get_access(CGH); + auto Acc3 = B3.get_access(CGH); + + CGH.codeplay_host_task([=] { + Acc2[1] = 1 * Idx; + Acc3[1] = 2 * Idx; + }); + }); + + // This host-task only depends on the second host-task via + // handler::depends_on(). This one should not hang and should be eexecuted + // after host-task #2. + event E3 = Q.submit([&](handler &CGH) { + CGH.depends_on(E2); + + std::cout << "Submit 3" << std::endl; + + auto Acc4 = B4.get_access(CGH); + auto Acc5 = B5.get_access(CGH); + + CGH.codeplay_host_task([=] { + Acc4[2] = 1 * Idx; + Acc5[2] = 2 * Idx; + }); + }); + } + + Q.wait_and_throw(); +} + +int main(int Argc, const char *Argv[]) { + size_t Count = 1; + if (Argc > 1) + Count = std::stoi(Argv[1]); + + test(Count); + return 0; +} diff --git a/sycl/test/host-interop-task/host-task-dependency3.cpp b/sycl/test/host-interop-task/host-task-dependency3.cpp new file mode 100644 index 000000000000..96858544421e --- /dev/null +++ b/sycl/test/host-interop-task/host-task-dependency3.cpp @@ -0,0 +1,117 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out + +// RUNx: %CPU_RUN_PLACEHOLDER %t.out +// RUNx: %GPU_RUN_PLACEHOLDER %t.out +// RUNx: %ACC_RUN_PLACEHOLDER %t.out + +// RUNx: %CPU_RUN_PLACEHOLDER %t.out 10 +// RUNx: %GPU_RUN_PLACEHOLDER %t.out 10 +// RUNx: %ACC_RUN_PLACEHOLDER %t.out 10 + +#include +#include +#include +#include + +// Host-task depending on another host-task via handler::depends_on() only +// should not hang. A bit more complicated case with kernels depending on +// host-task being involved. +void test(size_t Count) { + queue Q(EH); + + static constexpr size_t BufferSize = 10 * 1024; + + buffer B0{range<1>{BufferSize}}; + buffer B1{range<1>{BufferSize}}; + buffer B2{range<1>{BufferSize}}; + buffer B3{range<1>{BufferSize}}; + buffer B4{range<1>{BufferSize}}; + buffer B5{range<1>{BufferSize}}; + + using namespace std::chrono_literals; + constexpr auto SleepFor = 1s; + + for (size_t Idx = 1; Idx <= Count; ++Idx) { + // This host task should be submitted without hesitation + Q.submit([&](handler &CGH) { + std::cout << "Submit HT-1" << std::endl; + + auto Acc0 = B0.get_access(CGH); + + CGH.codeplay_host_task([=] { + std::this_thread::sleep_for(SleepFor); + Acc0[0] = 1 * Idx; + }); + }); + + Q.submit([&](handler &CGH) { + std::cout << "Submit Kernel-1" << std::endl; + + auto Acc0 = B0.get_access(CGH); + + CGH.single_task([=] { + Acc0[1] = 1 * Idx; + }); + }); + + Q.submit([&](handler &CGH) { + std::cout << "Submit Kernel-2" << std::endl; + + auto Acc1 = B1.get_access(CGH); + + CGH.single_task([=] { Acc1[2] = 1 * Idx; }); + }); + + Q.submit([&](handler &CGH) { + std::cout << "Submit HT-2" << std::endl; + + auto Acc2 = B2.get_access(CGH); + + CGH.codeplay_host_task([=] { + std::this_thread::sleep_for(SleepFor); + Acc2[3] = 1 * Idx; + }); + }); + + // This host task is going to depend on blocked empty node of the second + // host-task (via buffer #0). Still this one should be enqueued. + event EHT3 = Q.submit([&](handler &CGH) { + std::cout << "Submit HT-3" << std::endl; + + auto Acc0 = B0.get_access(CGH); + auto Acc1 = B1.get_access(CGH); + auto Acc2 = B2.get_access(CGH); + + CGH.codeplay_host_task([=] { + std::this_thread::sleep_for(SleepFor); + Acc0[4] = 1 * Idx; + Acc1[4] = 2 * Idx; + Acc2[4] = 3 * Idx; + }); + }); + + // This host-task only depends on the third host-task via + // handler::depends_on(). This one should not hang and should be executed + // after host-task #3. + Q.submit([&](handler &CGH) { + std::cout << "Submit HT-4" << std::endl; + + CGH.depends_on(EHT3); + + auto Acc5 = B5.get_access(CGH); + + CGH.codeplay_host_task([=] { Acc5[5] = 1 * Idx; }); + }); + } + + Q.wait_and_throw(); +} + +int main(int Argc, const char *Argv[]) { + size_t Count = 1; + if (Argc > 1) + Count = std::stoi(Argv[1]); + + test(Count); + return 0; +} diff --git a/sycl/test/host-interop-task/host-task-dependency4.cpp b/sycl/test/host-interop-task/host-task-dependency4.cpp new file mode 100644 index 000000000000..b3f26107b94a --- /dev/null +++ b/sycl/test/host-interop-task/host-task-dependency4.cpp @@ -0,0 +1,31 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out + +// RUNx: %CPU_RUN_PLACEHOLDER %t.out +// RUNx: %GPU_RUN_PLACEHOLDER %t.out +// RUNx: %ACC_RUN_PLACEHOLDER %t.out + +#include + +cl::sycl::event submit(cl::sycl::queue &Q, cl::sycl::buffer &B) { + return queue.submit([&](cl::sycl::handler &CGH) { + auto A = B.template get_access(cgh); + CGH.codeplay_host_task([=]() { (void)A; }); + }); +} + +int main() { + cl::sycl::queue Q; + cl::sycl::buffer A{&status, 1}; + cl::sycl::vector_class Events; + + Events.push_back(submit(Q, A)); + Events.push_back(submit(Q, A)); + Q.submit([&](sycl::handler &CGH) { + CGH.depends_on(Events); + CGH.codeplay_host_task([&](){ + printf("all done\n"); + }); + }).wait_and_throw(); + + return 0; +} diff --git a/sycl/test/host-interop-task/host-task.cpp b/sycl/test/host-interop-task/host-task.cpp index 539d8aef69ec..85b92e71e756 100644 --- a/sycl/test/host-interop-task/host-task.cpp +++ b/sycl/test/host-interop-task/host-task.cpp @@ -11,26 +11,9 @@ // RUN: %GPU_RUN_PLACEHOLDER %t.out 3 // RUN: %ACC_RUN_PLACEHOLDER %t.out 3 -// RUNx: %CPU_RUN_PLACEHOLDER %t.out 4 -// RUNx: %GPU_RUN_PLACEHOLDER %t.out 4 -// RUNx: %ACC_RUN_PLACEHOLDER %t.out 4 - -// RUNx: %CPU_RUN_PLACEHOLDER %t.out 5 -// RUNx: %GPU_RUN_PLACEHOLDER %t.out 5 -// RUNx: %ACC_RUN_PLACEHOLDER %t.out 5 - -// RUNx: %CPU_RUN_PLACEHOLDER %t.out 6 -// RUNx: %GPU_RUN_PLACEHOLDER %t.out 6 -// RUNx: %ACC_RUN_PLACEHOLDER %t.out 6 - -// RUNx: %CPU_RUN_PLACEHOLDER %t.out 7 -// RUNx: %GPU_RUN_PLACEHOLDER %t.out 7 -// RUNx: %ACC_RUN_PLACEHOLDER %t.out 7 - #include #include #include -#include #include using namespace cl::sycl; @@ -164,165 +147,6 @@ void test3() { assert(End - Start < Threshold && "Host tasks were waiting for too long"); } -// Host-task depending on another host-task via handler::depends_on() only -// should not hang -void test4(size_t Count = 1) { - queue Q(EH); - - static constexpr size_t BufferSize = 10 * 1024; - - buffer B0{range<1>{BufferSize}}; - buffer B1{range<1>{BufferSize}}; - buffer B2{range<1>{BufferSize}}; - buffer B3{range<1>{BufferSize}}; - buffer B4{range<1>{BufferSize}}; - buffer B5{range<1>{BufferSize}}; - - for (size_t Idx = 1; Idx <= Count; ++Idx) { - // This host task should be submitted without hesitation - event E1 = Q.submit([&](handler &CGH) { - std::cout << "Submit 1" << std::endl; - - auto Acc0 = B0.get_access(CGH); - auto Acc1 = B1.get_access(CGH); - auto Acc2 = B2.get_access(CGH); - - CGH.codeplay_host_task([=] { - Acc0[0] = 1 * Idx; - Acc1[0] = 2 * Idx; - Acc2[0] = 3 * Idx; - }); - }); - - // This host task is going to depend on blocked empty node of the first - // host-task (via buffer #2). Still this one should be enqueued. - event E2 = Q.submit([&](handler &CGH) { - std::cout << "Submit 2" << std::endl; - - auto Acc2 = B2.get_access(CGH); - auto Acc3 = B3.get_access(CGH); - - CGH.codeplay_host_task([=] { - Acc2[1] = 1 * Idx; - Acc3[1] = 2 * Idx; - }); - }); - - // This host-task only depends on the second host-task via - // handler::depends_on(). This one should not hang and should be eexecuted - // after host-task #2. - event E3 = Q.submit([&](handler &CGH) { - CGH.depends_on(E2); - - std::cout << "Submit 3" << std::endl; - - auto Acc4 = B4.get_access(CGH); - auto Acc5 = B5.get_access(CGH); - - CGH.codeplay_host_task([=] { - Acc4[2] = 1 * Idx; - Acc5[2] = 2 * Idx; - }); - }); - } - - Q.wait_and_throw(); -} - -// Host-task depending on another host-task via handler::depends_on() only -// should not hang. A bit more complicated case with kernels depending on -// host-task being involved. -void test5(size_t Count = 1) { - queue Q(EH); - - static constexpr size_t BufferSize = 10 * 1024; - - buffer B0{range<1>{BufferSize}}; - buffer B1{range<1>{BufferSize}}; - buffer B2{range<1>{BufferSize}}; - buffer B3{range<1>{BufferSize}}; - buffer B4{range<1>{BufferSize}}; - buffer B5{range<1>{BufferSize}}; - - using namespace std::chrono_literals; - constexpr auto SleepFor = 1s; - - for (size_t Idx = 1; Idx <= Count; ++Idx) { - // This host task should be submitted without hesitation - Q.submit([&](handler &CGH) { - std::cout << "Submit HT-1" << std::endl; - - auto Acc0 = B0.get_access(CGH); - - CGH.codeplay_host_task([=] { - std::this_thread::sleep_for(SleepFor); - Acc0[0] = 1 * Idx; - }); - }); - - Q.submit([&](handler &CGH) { - std::cout << "Submit Kernel-1" << std::endl; - - auto Acc0 = B0.get_access(CGH); - - CGH.single_task([=] { - Acc0[1] = 1 * Idx; - }); - }); - - Q.submit([&](handler &CGH) { - std::cout << "Submit Kernel-2" << std::endl; - - auto Acc1 = B1.get_access(CGH); - - CGH.single_task([=] { Acc1[2] = 1 * Idx; }); - }); - - Q.submit([&](handler &CGH) { - std::cout << "Submit HT-2" << std::endl; - - auto Acc2 = B2.get_access(CGH); - - CGH.codeplay_host_task([=] { - std::this_thread::sleep_for(SleepFor); - Acc2[3] = 1 * Idx; - }); - }); - - // This host task is going to depend on blocked empty node of the second - // host-task (via buffer #0). Still this one should be enqueued. - event EHT3 = Q.submit([&](handler &CGH) { - std::cout << "Submit HT-3" << std::endl; - - auto Acc0 = B0.get_access(CGH); - auto Acc1 = B1.get_access(CGH); - auto Acc2 = B2.get_access(CGH); - - CGH.codeplay_host_task([=] { - std::this_thread::sleep_for(SleepFor); - Acc0[4] = 1 * Idx; - Acc1[4] = 2 * Idx; - Acc2[4] = 3 * Idx; - }); - }); - - // This host-task only depends on the third host-task via - // handler::depends_on(). This one should not hang and should be executed - // after host-task #3. - Q.submit([&](handler &CGH) { - std::cout << "Submit HT-4" << std::endl; - - CGH.depends_on(EHT3); - - auto Acc5 = B5.get_access(CGH); - - CGH.codeplay_host_task([=] { Acc5[5] = 1 * Idx; }); - }); - } - - Q.wait_and_throw(); -} - int main(int Argc, const char *Argv[]) { if (Argc < 2) return 1; @@ -339,18 +163,6 @@ int main(int Argc, const char *Argv[]) { case 3: test3(); break; - case 4: - test4(); - break; - case 5: - test5(); - break; - case 6: - test4(10); - break; - case 7: - test5(10); - break; default: return 1; } From 993fcf22650830b070ca40db75170bc88af74fb7 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Tue, 29 Sep 2020 17:43:34 +0300 Subject: [PATCH 12/14] Fix style issues Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task-dependency4.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sycl/test/host-interop-task/host-task-dependency4.cpp b/sycl/test/host-interop-task/host-task-dependency4.cpp index b3f26107b94a..8b352fd55d3e 100644 --- a/sycl/test/host-interop-task/host-task-dependency4.cpp +++ b/sycl/test/host-interop-task/host-task-dependency4.cpp @@ -22,9 +22,7 @@ int main() { Events.push_back(submit(Q, A)); Q.submit([&](sycl::handler &CGH) { CGH.depends_on(Events); - CGH.codeplay_host_task([&](){ - printf("all done\n"); - }); + CGH.codeplay_host_task([&] { printf("all done\n"); }); }).wait_and_throw(); return 0; From 0802c2617adbf98d5079219c4c2d5913427f68ad Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Tue, 29 Sep 2020 17:49:05 +0300 Subject: [PATCH 13/14] Fix style issues Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task-dependency3.cpp | 4 +--- sycl/test/host-interop-task/host-task-dependency4.cpp | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sycl/test/host-interop-task/host-task-dependency3.cpp b/sycl/test/host-interop-task/host-task-dependency3.cpp index 96858544421e..304533162ac5 100644 --- a/sycl/test/host-interop-task/host-task-dependency3.cpp +++ b/sycl/test/host-interop-task/host-task-dependency3.cpp @@ -49,9 +49,7 @@ void test(size_t Count) { auto Acc0 = B0.get_access(CGH); - CGH.single_task([=] { - Acc0[1] = 1 * Idx; - }); + CGH.single_task([=] { Acc0[1] = 1 * Idx; }); }); Q.submit([&](handler &CGH) { diff --git a/sycl/test/host-interop-task/host-task-dependency4.cpp b/sycl/test/host-interop-task/host-task-dependency4.cpp index 8b352fd55d3e..9170662a2a88 100644 --- a/sycl/test/host-interop-task/host-task-dependency4.cpp +++ b/sycl/test/host-interop-task/host-task-dependency4.cpp @@ -21,9 +21,9 @@ int main() { Events.push_back(submit(Q, A)); Events.push_back(submit(Q, A)); Q.submit([&](sycl::handler &CGH) { - CGH.depends_on(Events); - CGH.codeplay_host_task([&] { printf("all done\n"); }); - }).wait_and_throw(); + CGH.depends_on(Events); + CGH.codeplay_host_task([&] { printf("all done\n"); }); + }).wait_and_throw(); return 0; } From 2b9b541c761b9f71b9bc56145fcb82875303c6bd Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Tue, 29 Sep 2020 18:15:30 +0300 Subject: [PATCH 14/14] Fix build issues Signed-off-by: Sergey Kanaev --- sycl/test/host-interop-task/host-task-dependency2.cpp | 11 +++++++++++ sycl/test/host-interop-task/host-task-dependency3.cpp | 11 +++++++++++ sycl/test/host-interop-task/host-task-dependency4.cpp | 7 ++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/sycl/test/host-interop-task/host-task-dependency2.cpp b/sycl/test/host-interop-task/host-task-dependency2.cpp index c926cb1c1216..4e0e76b1bcdd 100644 --- a/sycl/test/host-interop-task/host-task-dependency2.cpp +++ b/sycl/test/host-interop-task/host-task-dependency2.cpp @@ -11,6 +11,17 @@ #include #include +using namespace cl::sycl; +using namespace cl::sycl::access; + +static constexpr size_t BUFFER_SIZE = 1024; + +static auto EH = [](exception_list EL) { + for (const std::exception_ptr &E : EL) { + throw E; + } +}; + // Host-task depending on another host-task via handler::depends_on() only // should not hang void test(size_t Count) { diff --git a/sycl/test/host-interop-task/host-task-dependency3.cpp b/sycl/test/host-interop-task/host-task-dependency3.cpp index 304533162ac5..b6e7adf3e163 100644 --- a/sycl/test/host-interop-task/host-task-dependency3.cpp +++ b/sycl/test/host-interop-task/host-task-dependency3.cpp @@ -13,6 +13,17 @@ #include #include +using namespace cl::sycl; +using namespace cl::sycl::access; + +static constexpr size_t BUFFER_SIZE = 1024; + +static auto EH = [](exception_list EL) { + for (const std::exception_ptr &E : EL) { + throw E; + } +}; + // Host-task depending on another host-task via handler::depends_on() only // should not hang. A bit more complicated case with kernels depending on // host-task being involved. diff --git a/sycl/test/host-interop-task/host-task-dependency4.cpp b/sycl/test/host-interop-task/host-task-dependency4.cpp index 9170662a2a88..600ec43cac93 100644 --- a/sycl/test/host-interop-task/host-task-dependency4.cpp +++ b/sycl/test/host-interop-task/host-task-dependency4.cpp @@ -7,15 +7,16 @@ #include cl::sycl::event submit(cl::sycl::queue &Q, cl::sycl::buffer &B) { - return queue.submit([&](cl::sycl::handler &CGH) { - auto A = B.template get_access(cgh); + return Q.submit([&](cl::sycl::handler &CGH) { + auto A = B.template get_access(CGH); CGH.codeplay_host_task([=]() { (void)A; }); }); } int main() { cl::sycl::queue Q; - cl::sycl::buffer A{&status, 1}; + int Status = 0; + cl::sycl::buffer A{&Status, 1}; cl::sycl::vector_class Events; Events.push_back(submit(Q, A));