Skip to content

Commit 42c6f44

Browse files
authored
[SYCL] Detach allocas from their dependencies regardless of linked alloca presence (#4573)
cleanupCommandsForRecord() removed allocation commands from the users of their dependencies only when there was a linked alloca command present. This has caused dangling pointers in the graph which resulted in invalid reads hence sporadic segfaults. This PR detaches alloca commands from their dependencies regardless of whether a linked alloca is present or not.
1 parent 6051fd6 commit 42c6f44

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

sycl/source/detail/scheduler/graph_builder.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1027,18 +1027,18 @@ void Scheduler::GraphBuilder::cleanupCommandsForRecord(
10271027
AllocaCmd->MUsers.clear();
10281028
}
10291029

1030-
// Linked alloca's share dependencies. Unchain from deps linked alloca's.
1031-
// Any cmd of the alloca - linked_alloca may be used later on.
1030+
// Make sure the Linked Allocas are marked visited by the previous walk.
1031+
// Remove allocation commands from the users of their dependencies.
10321032
for (AllocaCommandBase *AllocaCmd : AllocaCommands) {
10331033
AllocaCommandBase *LinkedCmd = AllocaCmd->MLinkedAllocaCmd;
10341034

10351035
if (LinkedCmd) {
10361036
assert(LinkedCmd->MMarks.MVisited);
1037-
1038-
for (DepDesc &Dep : AllocaCmd->MDeps)
1039-
if (Dep.MDepCommand)
1040-
Dep.MDepCommand->MUsers.erase(AllocaCmd);
10411037
}
1038+
1039+
for (DepDesc &Dep : AllocaCmd->MDeps)
1040+
if (Dep.MDepCommand)
1041+
Dep.MDepCommand->MUsers.erase(AllocaCmd);
10421042
}
10431043

10441044
// Traverse the graph using BFS

sycl/unittests/scheduler/MemObjCommandCleanup.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
using namespace cl::sycl;
1313

14-
TEST_F(SchedulerTest, MemObjCommandCleanup) {
14+
TEST_F(SchedulerTest, MemObjCommandCleanupAllocaUsers) {
1515
MockScheduler MS;
1616
buffer<int, 1> BufA(range<1>(1));
1717
buffer<int, 1> BufB(range<1>(1));
@@ -51,3 +51,31 @@ TEST_F(SchedulerTest, MemObjCommandCleanup) {
5151
EXPECT_EQ(MockDirectUser->MDeps[0].MDepCommand, MockAllocaB.get());
5252
EXPECT_TRUE(IndirectUserDeleted);
5353
}
54+
55+
TEST_F(SchedulerTest, MemObjCommandCleanupAllocaDeps) {
56+
MockScheduler MS;
57+
buffer<int, 1> Buf(range<1>(1));
58+
detail::Requirement MockReq = getMockRequirement(Buf);
59+
std::vector<detail::Command *> AuxCmds;
60+
detail::MemObjRecord *MemObjRec = MS.getOrInsertMemObjRecord(
61+
detail::getSyclObjImpl(MQueue), &MockReq, AuxCmds);
62+
63+
// Create a fake alloca.
64+
detail::AllocaCommand *MockAllocaCmd =
65+
new detail::AllocaCommand(detail::getSyclObjImpl(MQueue), MockReq);
66+
MemObjRec->MAllocaCommands.push_back(MockAllocaCmd);
67+
68+
// Add another mock command and add MockAllocaCmd as its user.
69+
MockCommand DepCmd(detail::getSyclObjImpl(MQueue), MockReq);
70+
addEdge(MockAllocaCmd, &DepCmd, nullptr);
71+
72+
// Check that DepCmd.MUsers size reflect the dependency properly.
73+
ASSERT_EQ(DepCmd.MUsers.size(), 1U);
74+
ASSERT_EQ(DepCmd.MUsers.count(MockAllocaCmd), 1U);
75+
76+
MS.cleanupCommandsForRecord(MemObjRec);
77+
MS.removeRecordForMemObj(detail::getSyclObjImpl(Buf).get());
78+
79+
// Check that DepCmd has its MUsers field cleared.
80+
ASSERT_EQ(DepCmd.MUsers.size(), 0U);
81+
}

0 commit comments

Comments
 (0)