1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/source/device/bcs_split.h"
#include "shared/source/command_stream/command_stream_receiver.h"
#include "level_zero/core/source/device/device_imp.h"
namespace L0 {
bool BcsSplit::setupDevice(uint32_t productFamily, bool internalUsage, const ze_command_queue_desc_t *desc, NEO::CommandStreamReceiver *csr) {
auto initializeBcsSplit = this->device.getNEODevice()->isBcsSplitSupported() &&
csr->getOsContext().getEngineType() == aub_stream::EngineType::ENGINE_BCS &&
!internalUsage;
if (!initializeBcsSplit) {
return false;
}
std::lock_guard<std::mutex> lock(this->mtx);
this->clientCount++;
if (!this->cmdQs.empty()) {
return true;
}
if (NEO::DebugManager.flags.SplitBcsMask.get() > 0) {
this->engines = NEO::DebugManager.flags.SplitBcsMask.get();
}
ze_command_queue_desc_t splitDesc;
memcpy(&splitDesc, desc, sizeof(ze_command_queue_desc_t));
splitDesc.mode = ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS;
for (uint32_t i = 0; i < NEO::bcsInfoMaskSize; i++) {
if (this->engines.test(i)) {
auto engineType = (i == 0u ? aub_stream::EngineType::ENGINE_BCS : aub_stream::EngineType::ENGINE_BCS1 + i - 1);
auto csr = this->device.getNEODevice()->getNearestGenericSubDevice(0u)->getEngine(static_cast<aub_stream::EngineType>(engineType), NEO::EngineUsage::Regular).commandStreamReceiver;
ze_result_t result;
auto commandQueue = CommandQueue::create(productFamily, &device, csr, &splitDesc, true, false, result);
UNRECOVERABLE_IF(result != ZE_RESULT_SUCCESS);
this->cmdQs.push_back(commandQueue);
}
}
return true;
}
void BcsSplit::releaseResources() {
std::lock_guard<std::mutex> lock(this->mtx);
this->clientCount--;
if (this->clientCount == 0u) {
for (auto cmdQ : cmdQs) {
cmdQ->destroy();
}
cmdQs.clear();
this->events.releaseResources();
}
}
size_t BcsSplit::Events::obtainForSplit(Context *context, size_t maxEventCountInPool) {
for (size_t i = 0; i < this->marker.size(); i++) {
auto ret = this->marker[i]->queryStatus();
if (ret == ZE_RESULT_SUCCESS) {
this->marker[i]->reset();
for (size_t j = 0; j < this->bcsSplit.cmdQs.size(); j++) {
this->subcopy[i * this->bcsSplit.cmdQs.size() + j]->reset();
}
return i;
}
}
return this->allocateNew(context, maxEventCountInPool);
}
size_t BcsSplit::Events::allocateNew(Context *context, size_t maxEventCountInPool) {
const size_t neededEvents = this->bcsSplit.cmdQs.size() + 1;
if (this->pools.empty() ||
this->createdFromLatestPool + neededEvents > maxEventCountInPool) {
ze_result_t result;
ze_event_pool_desc_t desc{};
desc.stype = ZE_STRUCTURE_TYPE_EVENT_POOL_DESC;
desc.count = static_cast<uint32_t>(maxEventCountInPool);
auto hDevice = this->bcsSplit.device.toHandle();
auto pool = EventPool::create(this->bcsSplit.device.getDriverHandle(), context, 1, &hDevice, &desc, result);
this->pools.push_back(pool);
this->createdFromLatestPool = 0u;
}
auto pool = this->pools[this->pools.size() - 1];
ze_event_desc_t desc{};
desc.stype = ZE_STRUCTURE_TYPE_EVENT_DESC;
desc.signal = ZE_EVENT_SCOPE_FLAG_DEVICE;
for (size_t i = 0; i < neededEvents; i++) {
desc.index = static_cast<uint32_t>(this->createdFromLatestPool++);
if (i == neededEvents - 1) {
desc.signal = ZE_EVENT_SCOPE_FLAG_HOST;
}
ze_event_handle_t hEvent;
pool->createEvent(&desc, &hEvent);
if (i == neededEvents - 1) {
this->marker.push_back(Event::fromHandle(hEvent));
} else {
this->subcopy.push_back(Event::fromHandle(hEvent));
}
}
return this->marker.size() - 1;
}
void BcsSplit::Events::releaseResources() {
for (auto &markerEvent : this->marker) {
markerEvent->destroy();
}
marker.clear();
for (auto &subcopyEvent : this->subcopy) {
subcopyEvent->destroy();
}
subcopy.clear();
for (auto &pool : this->pools) {
pool->destroy();
}
pools.clear();
}
} // namespace L0
|