Skip to content

[SYCL] Test for fix of linked alloca's deps #1470

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 16 commits into from
Aug 3, 2020
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
5 changes: 5 additions & 0 deletions sycl/source/detail/scheduler/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@
/// clReleaseContext(ContextCPU);
/// \endcode

// For testing purposes
class MockScheduler;

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {
namespace detail {
Expand Down Expand Up @@ -576,6 +579,8 @@ class Scheduler {
friend class Command;

private:
friend class ::MockScheduler;

/// Searches for suitable alloca in memory record.
///
/// If none found, creates new one.
Expand Down
1 change: 1 addition & 0 deletions sycl/unittests/scheduler/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ add_sycl_unittest(SchedulerTests OBJECT
MemObjCommandCleanup.cpp
CommandsWaitForEvents.cpp
WaitAfterCleanup.cpp
LinkedAllocaDependencies.cpp
utils.cpp
)
96 changes: 96 additions & 0 deletions sycl/unittests/scheduler/LinkedAllocaDependencies.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//==------ LinkedAllocaDependencies.cpp --- Scheduler unit tests -----------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "SchedulerTest.hpp"
#include "SchedulerTestUtils.hpp"

using namespace cl::sycl;

class MemObjMock : public cl::sycl::detail::SYCLMemObjI {
public:
using ContextImplPtr = std::shared_ptr<cl::sycl::detail::context_impl>;

MemObjMock(const std::shared_ptr<cl::sycl::detail::MemObjRecord> &Record)
: SYCLMemObjI() {
MRecord = Record;
}

~MemObjMock() = default;

MemObjType getType() const override { return MemObjType::BUFFER; }

void *allocateMem(ContextImplPtr, bool, void *,
cl::sycl::detail::pi::PiEvent &) {
return nullptr;
}

void *allocateHostMem() { return nullptr; }
void releaseMem(ContextImplPtr, void *) {}
void releaseHostMem(void *) {}
size_t getSize() const override { return 10; }
};

TEST_F(SchedulerTest, LinkedAllocaDependencies) {
default_selector Selector{};
if (Selector.select_device().is_host()) {
std::cerr << "Not run due to host-only environment\n";
return;
}

// 1. create two commands: alloca + alloca and link them
// 2. call Scheduler::GraphBuilder::getOrCreateAllocaForReq
detail::Requirement Req = getMockRequirement();

cl::sycl::queue Queue1;
cl::sycl::detail::QueueImplPtr Q1 = cl::sycl::detail::getSyclObjImpl(Queue1);

sycl::device HostDevice;
std::shared_ptr<detail::queue_impl> DefaultHostQueue(new detail::queue_impl(
detail::getSyclObjImpl(HostDevice), /*AsyncHandler=*/{},
/*PropList=*/{}));

std::shared_ptr<cl::sycl::detail::MemObjRecord> Record{
new cl::sycl::detail::MemObjRecord(DefaultHostQueue->getContextImplPtr(),
10)};

MemObjMock MemObj(Record);
Req.MSYCLMemObj = &MemObj;

cl::sycl::detail::AllocaCommand AllocaCmd1(DefaultHostQueue, Req, false);
Record->MAllocaCommands.push_back(&AllocaCmd1);

MockCommand DepCmd(DefaultHostQueue, Req);
MockCommand DepDepCmd(DefaultHostQueue, Req);
DepCmd.MDeps.push_back({&DepDepCmd, DepDepCmd.getRequirement(), &AllocaCmd1});
DepDepCmd.MUsers.insert(&DepCmd);
Record->MWriteLeaves.push_back(&DepCmd);

MockScheduler MS;
cl::sycl::detail::Command *AllocaCmd2 =
MS.getOrCreateAllocaForReq(Record.get(), &Req, Q1);

ASSERT_TRUE(!!AllocaCmd1.MLinkedAllocaCmd)
<< "No link appeared in existing command";
ASSERT_EQ(AllocaCmd1.MLinkedAllocaCmd, AllocaCmd2) << "Invalid link appeared";
ASSERT_GT(AllocaCmd1.MUsers.count(AllocaCmd2), 0u)
<< "New alloca isn't in users of the old one";
ASSERT_GT(AllocaCmd2->MDeps.size(), 1u)
<< "No deps appeared in the new alloca";
ASSERT_GT(DepCmd.MUsers.count(AllocaCmd2), 0u)
<< "No deps appeared for leaves of record (i.e. deps of existing alloca)";
ASSERT_TRUE(std::find_if(AllocaCmd2->MDeps.begin(), AllocaCmd2->MDeps.end(),
[&](const cl::sycl::detail::DepDesc &Dep) -> bool {
return Dep.MDepCommand == &AllocaCmd1;
}) != AllocaCmd2->MDeps.end())
<< "No deps for existing alloca appeared in new alloca";
ASSERT_TRUE(std::find_if(AllocaCmd2->MDeps.begin(), AllocaCmd2->MDeps.end(),
[&](const cl::sycl::detail::DepDesc &Dep) -> bool {
return Dep.MDepCommand == &DepCmd;
}) != AllocaCmd2->MDeps.end())
<< "No deps for leaves (deps of existing alloca) appeared in new alloca";
}
7 changes: 7 additions & 0 deletions sycl/unittests/scheduler/SchedulerTestUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ class MockScheduler : public cl::sycl::detail::Scheduler {
cl::sycl::detail::BlockingT Blocking) {
return GraphProcessor::enqueueCommand(Cmd, EnqueueResult, Blocking);
}

cl::sycl::detail::AllocaCommandBase *
getOrCreateAllocaForReq(cl::sycl::detail::MemObjRecord *Record,
const cl::sycl::detail::Requirement *Req,
cl::sycl::detail::QueueImplPtr Queue) {
return MGraphBuilder.getOrCreateAllocaForReq(Record, Req, Queue);
}
};

void addEdge(cl::sycl::detail::Command *User, cl::sycl::detail::Command *Dep,
Expand Down