Skip to content

Commit

Permalink
Merge pull request #1867 from pbalcer/v2-events
Browse files Browse the repository at this point in the history
initial v2 event pool implementation
  • Loading branch information
pbalcer authored Jul 23, 2024
2 parents 95a0f7b + 2062c1b commit 1b8ee0d
Show file tree
Hide file tree
Showing 16 changed files with 848 additions and 1 deletion.
4 changes: 4 additions & 0 deletions source/adapters/level_zero/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <ze_api.h>
#include <zes_api.h>

#include "adapters/level_zero/platform.hpp"
#include "common.hpp"

enum EventsScope {
Expand Down Expand Up @@ -219,4 +220,7 @@ struct ur_device_handle_t_ : _ur_object {
ZeCache<struct ze_global_memsize> ZeGlobalMemSize;
ZeCache<ZeStruct<ze_mutable_command_list_exp_properties_t>>
ZeDeviceMutableCmdListsProperties;

// unique ephemeral identifer of the device in the adapter
DeviceId Id;
};
15 changes: 15 additions & 0 deletions source/adapters/level_zero/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,24 @@ ur_result_t ur_platform_handle_t_::populateDeviceCacheIfNeeded() {
return UR_RESULT_ERROR_UNKNOWN;
}
DeviceCachePopulated = true;

size_t id = 0;
for (auto &dev : URDevicesCache) {
dev->Id = id++;
}

return UR_RESULT_SUCCESS;
}

ur_device_handle_t ur_platform_handle_t_::getDeviceById(DeviceId id) {
for (auto &dev : URDevicesCache) {
if (dev->Id == id) {
return dev.get();
}
}
return nullptr;
}

// Returns plugin specific backend option.
// Current support is only for optimization options.
// Return '-ze-opt-disable' for frontend_option = -O0.
Expand Down
5 changes: 5 additions & 0 deletions source/adapters/level_zero/platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
#pragma once

#include "common.hpp"
#include "ur_api.h"
#include "ze_api.h"

struct ur_device_handle_t_;

typedef size_t DeviceId;

struct ur_platform_handle_t_ : public _ur_platform {
ur_platform_handle_t_(ze_driver_handle_t Driver)
: ZeDriver{Driver}, ZeApiVersion{ZE_API_VERSION_CURRENT} {}
Expand Down Expand Up @@ -53,6 +56,8 @@ struct ur_platform_handle_t_ : public _ur_platform {
// Check the device cache and load it if necessary.
ur_result_t populateDeviceCacheIfNeeded();

ur_device_handle_t getDeviceById(DeviceId);

// Return the PI device from cache that represents given native device.
// If not found, then nullptr is returned.
ur_device_handle_t getDeviceFromNativeHandle(ze_device_handle_t);
Expand Down
34 changes: 34 additions & 0 deletions source/adapters/level_zero/v2/event.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===--------- event.cpp - Level Zero Adapter -----------------------------===//
//
// Copyright (C) 2024 Intel Corporation
//
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
// Exceptions. See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "event.hpp"
#include "adapters/level_zero/v2/event_provider.hpp"
#include "ze_api.h"

namespace v2 {
void ur_event::attachZeHandle(event_allocation event) {
type = event.type;
zeEvent = std::move(event.borrow);
}

event_borrowed ur_event::detachZeHandle() {
// consider make an abstraction for regular/counter based
// events if there's more of this type of conditions
if (type == event_type::EVENT_REGULAR) {
zeEventHostReset(zeEvent.get());
}
auto e = std::move(zeEvent);
zeEvent = nullptr;

return e;
}

ze_event_handle_t ur_event::getZeEvent() { return zeEvent.get(); }

} // namespace v2
34 changes: 34 additions & 0 deletions source/adapters/level_zero/v2/event.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===--------- event.hpp - Level Zero Adapter -----------------------------===//
//
// Copyright (C) 2024 Intel Corporation
//
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
// Exceptions. See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#pragma once

#include <stack>

#include <ur/ur.hpp>
#include <ur_api.h>
#include <ze_api.h>

#include "event_provider.hpp"

namespace v2 {

class ur_event {
public:
void attachZeHandle(event_allocation);
event_borrowed detachZeHandle();

ze_event_handle_t getZeEvent();

private:
event_type type;
event_borrowed zeEvent;
};

} // namespace v2
43 changes: 43 additions & 0 deletions source/adapters/level_zero/v2/event_pool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===--------- event_pool.cpp - Level Zero Adapter ------------------------===//
//
// Copyright (C) 2024 Intel Corporation
//
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
// Exceptions. See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "ur_api.h"
#include <event_pool.hpp>

namespace v2 {

static constexpr size_t EVENTS_BURST = 64;

ur_event *event_pool::allocate() {
if (freelist.empty()) {
auto start = events.size();
auto end = start + EVENTS_BURST;
events.resize(end);
for (; start < end; ++start) {
freelist.push_back(&events.at(start));
}
}

auto event = freelist.back();

auto ZeEvent = provider->allocate();
event->attachZeHandle(std::move(ZeEvent));

freelist.pop_back();

return event;
}

void event_pool::free(ur_event *event) {
auto _ = event->detachZeHandle();

freelist.push_back(event);
}

} // namespace v2
52 changes: 52 additions & 0 deletions source/adapters/level_zero/v2/event_pool.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//===--------- event_pool.hpp - Level Zero Adapter ------------------------===//
//
// Copyright (C) 2024 Intel Corporation
//
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
// Exceptions. See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#pragma once

#include <memory>
#include <mutex>
#include <stack>

#include <unordered_map>
#include <ur/ur.hpp>
#include <ur_api.h>
#include <vector>
#include <ze_api.h>

#include "../device.hpp"
#include "common.hpp"
#include "event.hpp"
#include "event_provider.hpp"

namespace v2 {

class event_pool {
public:
event_pool(std::unique_ptr<event_provider> Provider)
: provider(std::move(Provider)){};

event_pool(event_pool &&other) = default;
event_pool &operator=(event_pool &&other) = default;

event_pool(const event_pool &) = delete;
event_pool &operator=(const event_pool &) = delete;

DeviceId Id() { return provider->device()->Id; };

ur_event *allocate();
void free(ur_event *event);

private:
std::deque<ur_event> events;
std::vector<ur_event *> freelist;

std::unique_ptr<event_provider> provider;
};

} // namespace v2
45 changes: 45 additions & 0 deletions source/adapters/level_zero/v2/event_pool_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===--------- event_pool_cache.cpp - Level Zero Adapter ------------------===//
//
// Copyright (C) 2024 Intel Corporation
//
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
// Exceptions. See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "event_pool_cache.hpp"
#include "device.hpp"
#include "platform.hpp"

namespace v2 {

event_pool_cache::event_pool_cache(size_t max_devices,
ProviderCreateFunc ProviderCreate)
: providerCreate(ProviderCreate) {
pools.resize(max_devices);
}

event_pool_cache::~event_pool_cache() {}

event_pool_borrowed event_pool_cache::borrow(DeviceId id) {
std::unique_lock<ur_mutex> Lock(mutex);

if (id >= pools.size()) {
return nullptr;
}

auto &vec = pools[id];
if (vec.empty()) {
vec.emplace_back(std::make_unique<event_pool>(providerCreate(id)));
}

auto pool = vec.back().release();
vec.pop_back();

return event_pool_borrowed(pool, [this](event_pool *pool) {
std::unique_lock<ur_mutex> Lock(mutex);
pools[pool->Id()].emplace_back(pool);
});
}

} // namespace v2
47 changes: 47 additions & 0 deletions source/adapters/level_zero/v2/event_pool_cache.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//===--------- event_pool_cache.hpp - Level Zero Adapter ------------------===//
//
// Copyright (C) 2024 Intel Corporation
//
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
// Exceptions. See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#pragma once

#include <functional>
#include <memory>
#include <mutex>
#include <stack>

#include <unordered_map>
#include <ur/ur.hpp>
#include <ur_api.h>
#include <ze_api.h>

#include "../device.hpp"
#include "event_pool.hpp"
#include "event_provider.hpp"

namespace v2 {

using event_pool_borrowed =
std::unique_ptr<event_pool, std::function<void(event_pool *)>>;

class event_pool_cache {
public:
using ProviderCreateFunc =
std::function<std::unique_ptr<event_provider>(DeviceId)>;

event_pool_cache(size_t max_devices, ProviderCreateFunc);
~event_pool_cache();

event_pool_borrowed borrow(DeviceId);

private:
ur_mutex mutex;
ProviderCreateFunc providerCreate;
std::vector<std::vector<std::unique_ptr<event_pool>>> pools;
};

} // namespace v2
41 changes: 41 additions & 0 deletions source/adapters/level_zero/v2/event_provider.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===--------- command_list_cache.hpp - Level Zero Adapter ---------------===//
//
// Copyright (C) 2024 Intel Corporation
//
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
// Exceptions. See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#pragma once

#include <memory>
#include <mutex>
#include <stack>

#include <unordered_map>
#include <ur/ur.hpp>
#include <ur_api.h>
#include <vector>
#include <ze_api.h>

namespace v2 {

enum event_type { EVENT_REGULAR, EVENT_COUNTER };

using event_borrowed =
std::unique_ptr<_ze_event_handle_t, std::function<void(ze_event_handle_t)>>;

struct event_allocation {
event_type type;
event_borrowed borrow;
};

class event_provider {
public:
virtual ~event_provider() = default;
virtual event_allocation allocate() = 0;
virtual ur_device_handle_t device() = 0;
};

} // namespace v2
Loading

0 comments on commit 1b8ee0d

Please sign in to comment.