Skip to content

Commit 0867a38

Browse files
Ivan Karachunromanovvlad
authored andcommitted
[SYCL] Fixed copying subbuffer between different contexts (#1005)
Fixed an issue when no alloca command for subbuffer was found while performing copying of memory between different contexts. Now if an allocation command for a subbuffer is not found for the source context graph builder uses an allocation command for the whole buffer. Signed-off-by: Ivan Karachun <[email protected]>
1 parent fca1736 commit 0867a38

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

sycl/source/detail/scheduler/graph_builder.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,16 +232,31 @@ Command *Scheduler::GraphBuilder::insertMemoryMove(MemObjRecord *Record,
232232

233233
AllocaCommandBase *AllocaCmdSrc =
234234
findAllocaForReq(Record, Req, Record->MCurContext);
235+
if (!AllocaCmdSrc && IsSuitableSubReq(Req)) {
236+
// Since no alloca command for the sub buffer requirement was found in the
237+
// current context, need to find a parent alloca command for it (it must be
238+
// there)
239+
auto IsSuitableAlloca = [Record, Req](AllocaCommandBase *AllocaCmd) {
240+
bool Res = sameCtx(AllocaCmd->getQueue()->get_context_impl(),
241+
Record->MCurContext) &&
242+
// Looking for a parent buffer alloca command
243+
AllocaCmd->getType() == Command::CommandType::ALLOCA;
244+
return Res;
245+
};
246+
const auto It =
247+
std::find_if(Record->MAllocaCommands.begin(),
248+
Record->MAllocaCommands.end(), IsSuitableAlloca);
249+
AllocaCmdSrc = (Record->MAllocaCommands.end() != It) ? *It : nullptr;
250+
}
235251
if (!AllocaCmdSrc)
236252
throw runtime_error("Cannot find buffer allocation");
237253
// Get parent allocation of sub buffer to perform full copy of whole buffer
238254
if (IsSuitableSubReq(Req)) {
239255
if (AllocaCmdSrc->getType() == Command::CommandType::ALLOCA_SUB_BUF)
240256
AllocaCmdSrc =
241257
static_cast<AllocaSubBufCommand *>(AllocaCmdSrc)->getParentAlloca();
242-
else
243-
assert(
244-
!"Inappropriate alloca command. AllocaSubBufCommand was expected.");
258+
else if (AllocaCmdSrc->getSYCLMemObj() != Req->MSYCLMemObj)
259+
assert(!"Inappropriate alloca command.");
245260
}
246261

247262
Command *NewCmd = nullptr;

sycl/test/basic_tests/buffer/subbuffer.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,37 @@ void copyBlock() {
247247
}
248248
}
249249

250+
void checkMultipleContexts() {
251+
constexpr int N = 64;
252+
int a[N] = {0};
253+
{
254+
sycl::queue queue1;
255+
sycl::queue queue2;
256+
sycl::buffer<int, 1> buf(a, sycl::range<1>(N));
257+
sycl::buffer<int, 1> subbuf1(buf, sycl::id<1>(0), sycl::range<1>(N / 2));
258+
sycl::buffer<int, 1> subbuf2(buf, sycl::id<1>(N / 2),
259+
sycl::range<1>(N / 2));
260+
queue1.submit([&](sycl::handler &cgh) {
261+
auto bufacc = subbuf1.get_access<sycl::access::mode::read_write>(cgh);
262+
cgh.parallel_for<class sub_buffer_1>(
263+
sycl::range<1>(N / 2), [=](sycl::id<1> idx) { bufacc[idx[0]] = 1; });
264+
});
265+
266+
queue2.submit([&](sycl::handler &cgh) {
267+
auto bufacc = subbuf2.get_access<sycl::access::mode::read_write>(cgh);
268+
cgh.parallel_for<class sub_buffer_2>(
269+
sycl::range<1>(N / 2), [=](sycl::id<1> idx) { bufacc[idx[0]] = 2; });
270+
});
271+
}
272+
assert(a[N / 2 - 1] == 1 && a[N / 2] == 2 && "Sub buffer data loss");
273+
}
274+
250275
int main() {
251276
cl::sycl::queue q;
252277
check1DSubBuffer(q);
253278
checkHostAccessor(q);
254279
checkExceptions();
255280
copyBlock();
281+
checkMultipleContexts();
256282
return 0;
257283
}

0 commit comments

Comments
 (0)