Skip to content
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

[SYCL] Store pointers to memory allocations instead of iterators #3860

Merged
merged 1 commit into from
Jun 1, 2021
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
7 changes: 3 additions & 4 deletions sycl/plugins/level_zero/pi_level_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,17 +940,16 @@ pi_result _pi_queue::executeCommandList(ze_command_list_handle_t ZeCommandList,

auto &Contexts = Device->Platform->Contexts;
for (auto &Ctx : Contexts) {
for (auto It = Ctx->MemAllocs.begin(); It != Ctx->MemAllocs.end();
It++) {
const auto &Pair = Kernel->MemAllocs.insert(It);
for (auto &Elem : Ctx->MemAllocs) {
const auto &Pair = Kernel->MemAllocs.insert(&Elem);
// Kernel is referencing this memory allocation from now.
// If this memory allocation was already captured for this kernel, it
// means that kernel is submitted several times. Increase reference
// count only once because we release all allocations only when
// SubmissionsCount turns to 0. We don't want to know how many times
// allocation was retained by each submission.
if (Pair.second)
It->second.RefCount++;
Elem.second.RefCount++;
}
}
Kernel->SubmissionsCount++;
Expand Down
33 changes: 15 additions & 18 deletions sycl/plugins/level_zero/pi_level_zero.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,30 +906,27 @@ struct _pi_kernel : _pi_object {

// Hash function object for the unordered_set below.
struct Hash {
size_t operator()(
const std::unordered_map<void *, MemAllocRecord>::iterator &It) const {
return std::hash<void *>()(It->first);
size_t operator()(const std::pair<void *const, MemAllocRecord> *P) const {
return std::hash<void *>()(P->first);
}
};

// If kernel has indirect access we need to make a snapshot of all existing
// memory allocations to defer deletion of these memory allocations to the
// moment when kernel execution has finished.
// We store iterators because iterator is not invalidated by insert/delete for
// std::map.
// Why need to take a snapshot instead of just reference-counting the
// allocations, because picture of active allocations can change during kernel
// execution (new allocations can be added) and we need to know which memory
// allocations were retained by this kernel to release them (and don't touch
// new allocations) at kernel completion.
// Same kernel may be submitted several times and retained allocations may be
// different at each submission. That's why we have a set of memory
// allocations here and increase ref count only once even if kernel is
// submitted many times. We don't want to know how many times and which
// allocations were retained by each submission. We release all allocations
// in the set only when SubmissionsCount == 0.
std::unordered_set<std::unordered_map<void *, MemAllocRecord>::iterator, Hash>
MemAllocs;
// We store pointers to the elements because pointers are not invalidated by
// insert/delete for std::unordered_map (iterators are invalidated). We need
// to take a snapshot instead of just reference-counting the allocations,
// because picture of active allocations can change during kernel execution
// (new allocations can be added) and we need to know which memory allocations
// were retained by this kernel to release them (and don't touch new
// allocations) at kernel completion. Same kernel may be submitted several
// times and retained allocations may be different at each submission. That's
// why we have a set of memory allocations here and increase ref count only
// once even if kernel is submitted many times. We don't want to know how many
// times and which allocations were retained by each submission. We release
// all allocations in the set only when SubmissionsCount == 0.
std::unordered_set<std::pair<void *const, MemAllocRecord> *, Hash> MemAllocs;

// Counter to track the number of submissions of the kernel.
// When this value is zero, it means that kernel is not submitted for an
Expand Down