2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2024-09-13 22:30:14 +08:00
|
|
|
* Copyright (C) 2018-2024 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/debug_helpers.h"
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2022-04-07 21:09:40 +08:00
|
|
|
#include <algorithm>
|
2022-11-23 23:09:23 +08:00
|
|
|
#include <cstdint>
|
2020-02-25 05:07:46 +08:00
|
|
|
#include <limits>
|
feature: Affinity mask plus ReturnSubDevicesAsApiDevices
When using ReturnSubDevicesAsApiDevices=1 to have
sub-devices-as-root-devices, then the driver should read the values
passed in the mask as those corresponding to the physical
sub-devices.
For instance, in a dual system with multi-tile device, we would have:
card 0, tile 0
card 0, tile 1
card 1, tile 0
card 1, tile 1
With:
ReturnSubDevicesAsApiDevices=0
ZE_AFFINITY_MASK=0,1
Then all tiles in card 0 and card 1 need to be exposed.
With:
ReturnSubDevicesAsApiDevices=1
ZE_AFFINITY_MASK=0,3
Then card 0 tile 0, and card 1 tile 1 need to be exposed.
Related-To: NEO-7137
Signed-off-by: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
2023-02-02 10:54:47 +08:00
|
|
|
#include <tuple>
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <vector>
|
|
|
|
|
2023-11-30 18:36:43 +08:00
|
|
|
template <size_t onStackCapacity>
|
2020-02-25 05:07:46 +08:00
|
|
|
struct StackVecSize {
|
|
|
|
static constexpr size_t max32 = std::numeric_limits<uint32_t>::max();
|
|
|
|
static constexpr size_t max16 = std::numeric_limits<uint16_t>::max();
|
|
|
|
static constexpr size_t max8 = std::numeric_limits<uint8_t>::max();
|
|
|
|
|
2023-11-30 18:36:43 +08:00
|
|
|
using SizeT = std::conditional_t<(onStackCapacity < max8), uint8_t,
|
|
|
|
std::conditional_t<(onStackCapacity < max16), uint16_t,
|
|
|
|
std::conditional_t<(onStackCapacity < max32), uint32_t, size_t>>>;
|
2020-02-25 05:07:46 +08:00
|
|
|
};
|
|
|
|
|
2023-11-30 18:36:43 +08:00
|
|
|
template <typename DataType, size_t onStackCapacity,
|
|
|
|
typename StackSizeT = typename StackVecSize<onStackCapacity>::SizeT>
|
2022-05-10 01:40:30 +08:00
|
|
|
class StackVec { // NOLINT(clang-analyzer-optin.performance.Padding)
|
2017-12-21 07:45:38 +08:00
|
|
|
public:
|
2023-11-30 18:36:43 +08:00
|
|
|
using value_type = DataType; // NOLINT(readability-identifier-naming)
|
2020-02-25 05:07:46 +08:00
|
|
|
using SizeT = StackSizeT;
|
2023-11-30 18:36:43 +08:00
|
|
|
using iterator = DataType *; // NOLINT(readability-identifier-naming)
|
|
|
|
using const_iterator = const DataType *; // NOLINT(readability-identifier-naming)
|
|
|
|
using reverse_iterator = std::reverse_iterator<iterator>; // NOLINT(readability-identifier-naming)
|
|
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>; // NOLINT(readability-identifier-naming)
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2023-11-30 18:36:43 +08:00
|
|
|
static constexpr SizeT onStackCaps = onStackCapacity;
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec() {
|
2024-09-13 22:30:14 +08:00
|
|
|
switchToStackMem();
|
2020-02-25 05:07:46 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
template <typename ItType>
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec(ItType beginIt, ItType endIt) {
|
2024-09-13 22:30:14 +08:00
|
|
|
switchToStackMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t count = (endIt - beginIt);
|
2023-11-30 18:36:43 +08:00
|
|
|
if (count > onStackCapacity) {
|
2017-12-21 07:45:38 +08:00
|
|
|
dynamicMem = new std::vector<DataType>(beginIt, endIt);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (beginIt != endIt) {
|
|
|
|
push_back(*beginIt);
|
|
|
|
++beginIt;
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
onStackSize = static_cast<SizeT>(count);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec(const StackVec &rhs) {
|
2024-09-13 22:30:14 +08:00
|
|
|
switchToStackMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
if (onStackCaps < rhs.size()) {
|
|
|
|
dynamicMem = new std::vector<DataType>(rhs.begin(), rhs.end());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
|
|
|
|
explicit StackVec(size_t initialSize)
|
|
|
|
: StackVec() {
|
2024-09-13 22:30:14 +08:00
|
|
|
switchToStackMem();
|
2018-01-05 19:54:12 +08:00
|
|
|
resize(initialSize);
|
|
|
|
}
|
|
|
|
|
2019-01-28 21:26:33 +08:00
|
|
|
StackVec(std::initializer_list<DataType> init) {
|
2024-09-13 22:30:14 +08:00
|
|
|
switchToStackMem();
|
2019-01-28 21:26:33 +08:00
|
|
|
reserve(init.size());
|
|
|
|
for (const auto &obj : init) {
|
|
|
|
push_back(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
StackVec &operator=(const StackVec &rhs) {
|
2021-07-23 02:51:08 +08:00
|
|
|
if (this == &rhs) {
|
|
|
|
return *this;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
clear();
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
this->dynamicMem->assign(rhs.begin(), rhs.end());
|
2017-12-21 07:45:38 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (onStackCaps < rhs.size()) {
|
|
|
|
this->dynamicMem = new std::vector<DataType>(rhs.begin(), rhs.end());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec(StackVec &&rhs) {
|
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
|
|
|
if (rhs.usesDynamicMem()) {
|
|
|
|
this->dynamicMem = rhs.dynamicMem;
|
2024-09-13 22:30:14 +08:00
|
|
|
rhs.switchToStackMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
rhs.clear();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
StackVec &operator=(StackVec &&rhs) {
|
2021-07-23 02:51:08 +08:00
|
|
|
if (this == &rhs) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
clear();
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (rhs.usesDynamicMem()) {
|
|
|
|
if (usesDynamicMem()) {
|
|
|
|
delete this->dynamicMem;
|
|
|
|
}
|
|
|
|
this->dynamicMem = rhs.dynamicMem;
|
2024-09-13 22:30:14 +08:00
|
|
|
rhs.switchToStackMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
this->dynamicMem->assign(rhs.begin(), rhs.end());
|
2017-12-21 07:45:38 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
rhs.clear();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:51:53 +08:00
|
|
|
template <typename RhsT>
|
|
|
|
void swap(RhsT &rhs) {
|
|
|
|
if (this->usesDynamicMem() && rhs.usesDynamicMem()) {
|
|
|
|
this->dynamicMem->swap(*rhs.dynamicMem);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
size_t smallerSize = this->size() < rhs.size() ? this->size() : rhs.size();
|
|
|
|
size_t i = 0;
|
|
|
|
for (; i < smallerSize; ++i) {
|
|
|
|
std::swap((*this)[i], rhs[i]);
|
|
|
|
}
|
|
|
|
if (this->size() == smallerSize) {
|
|
|
|
auto biggerSize = rhs.size();
|
|
|
|
for (; i < biggerSize; ++i) {
|
|
|
|
this->push_back(std::move(rhs[i]));
|
|
|
|
}
|
|
|
|
rhs.resize(smallerSize);
|
|
|
|
} else {
|
|
|
|
auto biggerSize = this->size();
|
|
|
|
for (; i < biggerSize; ++i) {
|
|
|
|
rhs.push_back(std::move((*this)[i]));
|
|
|
|
}
|
|
|
|
this->resize(smallerSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
~StackVec() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
delete dynamicMem;
|
|
|
|
return;
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
clearStackObjects();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t size() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->size();
|
|
|
|
}
|
|
|
|
return onStackSize;
|
|
|
|
}
|
|
|
|
|
2019-10-28 02:48:26 +08:00
|
|
|
bool empty() const {
|
|
|
|
return 0U == size();
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t capacity() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->capacity();
|
|
|
|
}
|
2023-11-30 18:36:43 +08:00
|
|
|
return onStackCapacity;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void reserve(size_t newCapacity) {
|
|
|
|
if (newCapacity > onStackCaps) {
|
|
|
|
ensureDynamicMem();
|
|
|
|
dynamicMem->reserve(newCapacity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
dynamicMem->clear();
|
|
|
|
return;
|
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
clearStackObjects();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
void push_back(const DataType &v) { // NOLINT(readability-identifier-naming)
|
2022-07-20 23:05:27 +08:00
|
|
|
isDynamicMemNeeded();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
dynamicMem->push_back(v);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType(v);
|
2017-12-21 07:45:38 +08:00
|
|
|
++onStackSize;
|
|
|
|
}
|
|
|
|
|
2022-07-20 23:05:27 +08:00
|
|
|
void push_back(DataType &&v) { // NOLINT(readability-identifier-naming)
|
|
|
|
isDynamicMemNeeded();
|
|
|
|
|
|
|
|
if (usesDynamicMem()) {
|
|
|
|
dynamicMem->push_back(std::move(v));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType(std::move(v));
|
|
|
|
++onStackSize;
|
|
|
|
}
|
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
void pop_back() { // NOLINT(readability-identifier-naming)
|
2020-05-25 22:39:16 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
dynamicMem->pop_back();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
UNRECOVERABLE_IF(0 == onStackSize);
|
|
|
|
|
|
|
|
clearStackObjects(onStackSize - 1, 1U);
|
|
|
|
--onStackSize;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
DataType &operator[](std::size_t idx) {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return (*dynamicMem)[idx];
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
return *(reinterpret_cast<DataType *>(onStackMemRawBytes) + idx);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-03-03 02:51:53 +08:00
|
|
|
DataType &at(std::size_t idx) { return this->operator[](idx); }
|
|
|
|
|
|
|
|
const DataType &at(std::size_t idx) const { return this->operator[](idx); }
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
const DataType &operator[](std::size_t idx) const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return (*dynamicMem)[idx];
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
return *(reinterpret_cast<const DataType *>(onStackMemRawBytes) + idx);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
iterator begin() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<DataType *>(onStackMemRawBytes);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-12-17 22:23:35 +08:00
|
|
|
reverse_iterator rbegin() {
|
|
|
|
return reverse_iterator(end());
|
|
|
|
}
|
|
|
|
|
|
|
|
const_reverse_iterator crbegin() const {
|
|
|
|
return const_reverse_iterator(end());
|
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
const_iterator begin() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<const DataType *>(onStackMemRawBytes);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
iterator end() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data() + dynamicMem->size();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-12-17 22:23:35 +08:00
|
|
|
reverse_iterator rend() {
|
|
|
|
return reverse_iterator(begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
const_reverse_iterator crend() const {
|
|
|
|
return const_reverse_iterator(begin());
|
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
const_iterator end() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data() + dynamicMem->size();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<const DataType *>(onStackMemRawBytes) + onStackSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
void resize(size_t newSize) {
|
|
|
|
this->resizeImpl(newSize, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void resize(size_t newSize, const DataType &value) {
|
|
|
|
resizeImpl(newSize, &value);
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
bool usesDynamicMem() const {
|
2024-09-13 22:30:14 +08:00
|
|
|
return reinterpret_cast<uintptr_t>(this->onStackMem) != reinterpret_cast<uintptr_t>(onStackMemRawBytes) && this->dynamicMem;
|
2020-02-25 05:07:46 +08:00
|
|
|
}
|
|
|
|
|
2020-10-16 18:41:41 +08:00
|
|
|
auto data() {
|
2020-06-09 20:17:19 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
return dynamicMem->data();
|
|
|
|
}
|
2020-10-16 18:41:41 +08:00
|
|
|
return reinterpret_cast<DataType *>(onStackMemRawBytes);
|
2020-06-09 20:17:19 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
private:
|
2023-11-30 18:36:43 +08:00
|
|
|
template <typename RhsDataType, size_t rhsOnStackCapacity, typename RhsStackSizeT>
|
2022-03-03 02:51:53 +08:00
|
|
|
friend class StackVec;
|
2020-02-25 05:07:46 +08:00
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
void resizeImpl(size_t newSize, const DataType *value) {
|
|
|
|
// new size does not fit into internal mem
|
|
|
|
if (newSize > onStackCaps) {
|
2017-12-21 07:45:38 +08:00
|
|
|
ensureDynamicMem();
|
2018-01-05 19:54:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// memory already backed by stl vector
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2018-01-05 19:54:12 +08:00
|
|
|
if (value != nullptr) {
|
|
|
|
dynamicMem->resize(newSize, *value);
|
|
|
|
} else {
|
|
|
|
dynamicMem->resize(newSize);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-09-19 17:45:55 +08:00
|
|
|
auto currentSize = std::min(onStackSize, onStackCaps);
|
|
|
|
if (newSize <= currentSize) {
|
2018-01-05 19:54:12 +08:00
|
|
|
// trim elements
|
2024-09-19 17:45:55 +08:00
|
|
|
clearStackObjects(newSize, currentSize - newSize);
|
2020-02-25 05:07:46 +08:00
|
|
|
onStackSize = static_cast<SizeT>(newSize);
|
2018-01-05 19:54:12 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add new elements
|
|
|
|
if (value != nullptr) {
|
|
|
|
// copy-construct elements
|
|
|
|
while (onStackSize < newSize) {
|
2020-02-25 05:07:46 +08:00
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType(*value);
|
2018-01-05 19:54:12 +08:00
|
|
|
++onStackSize;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// default-construct elements
|
|
|
|
while (onStackSize < newSize) {
|
2020-02-25 05:07:46 +08:00
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType();
|
2018-01-05 19:54:12 +08:00
|
|
|
++onStackSize;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-20 23:05:27 +08:00
|
|
|
void isDynamicMemNeeded() {
|
|
|
|
if (onStackSize == onStackCaps) {
|
|
|
|
ensureDynamicMem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
void ensureDynamicMem() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dynamicMem = new std::vector<DataType>();
|
|
|
|
if (onStackSize > 0) {
|
|
|
|
dynamicMem->reserve(onStackSize);
|
|
|
|
for (auto it = reinterpret_cast<DataType *>(onStackMemRawBytes), end = reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize; it != end; ++it) {
|
|
|
|
dynamicMem->push_back(std::move(*it));
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
clearStackObjects();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
void clearStackObjects() {
|
|
|
|
clearStackObjects(0, onStackSize);
|
|
|
|
onStackSize = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void clearStackObjects(size_t offset, size_t count) {
|
|
|
|
UNRECOVERABLE_IF(offset + count > onStackSize);
|
2020-02-25 05:07:46 +08:00
|
|
|
for (auto it = reinterpret_cast<DataType *>(onStackMemRawBytes) + offset, end = reinterpret_cast<DataType *>(onStackMemRawBytes) + offset + count; it != end; ++it) {
|
2017-12-21 07:45:38 +08:00
|
|
|
it->~DataType();
|
|
|
|
}
|
|
|
|
}
|
2024-09-13 22:30:14 +08:00
|
|
|
void switchToStackMem() {
|
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
union {
|
|
|
|
std::vector<DataType> *dynamicMem;
|
|
|
|
DataType *onStackMem;
|
|
|
|
};
|
|
|
|
|
2023-08-25 17:01:12 +08:00
|
|
|
alignas(alignof(DataType)) char onStackMemRawBytes[sizeof(DataType[onStackCaps])];
|
2020-02-25 05:07:46 +08:00
|
|
|
SizeT onStackSize = 0U;
|
2017-12-21 07:45:38 +08:00
|
|
|
};
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
namespace {
|
|
|
|
static_assert(sizeof(StackVec<char, 1U>::SizeT) == 1u, "");
|
|
|
|
static_assert(sizeof(StackVec<char, 7U>) <= 16u, "");
|
|
|
|
static_assert(sizeof(StackVec<uint32_t, 3U>) <= 24u, "");
|
|
|
|
} // namespace
|
|
|
|
|
2023-11-30 18:36:43 +08:00
|
|
|
template <typename T, size_t lhsStackCaps, size_t rhsStackCaps>
|
|
|
|
bool operator==(const StackVec<T, lhsStackCaps> &lhs,
|
|
|
|
const StackVec<T, rhsStackCaps> &rhs) {
|
2018-01-05 19:54:12 +08:00
|
|
|
if (lhs.size() != rhs.size()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto lhsIt = lhs.begin();
|
|
|
|
auto lhsEnd = lhs.end();
|
|
|
|
auto rhsIt = rhs.begin();
|
|
|
|
|
|
|
|
for (; lhsIt != lhsEnd; ++lhsIt, ++rhsIt) {
|
|
|
|
if (*lhsIt != *rhsIt) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-28 21:26:33 +08:00
|
|
|
|
2023-11-30 18:36:43 +08:00
|
|
|
template <typename T, size_t lhsStackCaps, size_t rhsStackCaps>
|
|
|
|
bool operator!=(const StackVec<T, lhsStackCaps> &lhs,
|
|
|
|
const StackVec<T, rhsStackCaps> &rhs) {
|
2019-01-28 21:26:33 +08:00
|
|
|
return false == (lhs == rhs);
|
|
|
|
}
|
2022-04-07 21:09:40 +08:00
|
|
|
|
2023-11-30 18:36:43 +08:00
|
|
|
constexpr size_t maxRootDeviceIndices = 16;
|
|
|
|
class RootDeviceIndicesContainer : protected StackVec<uint32_t, maxRootDeviceIndices> {
|
2023-06-12 21:52:45 +08:00
|
|
|
public:
|
2023-11-30 18:36:43 +08:00
|
|
|
using StackVec<uint32_t, maxRootDeviceIndices>::StackVec;
|
|
|
|
using StackVec<uint32_t, maxRootDeviceIndices>::at;
|
|
|
|
using StackVec<uint32_t, maxRootDeviceIndices>::begin;
|
|
|
|
using StackVec<uint32_t, maxRootDeviceIndices>::end;
|
|
|
|
using StackVec<uint32_t, maxRootDeviceIndices>::size;
|
|
|
|
using StackVec<uint32_t, maxRootDeviceIndices>::operator[];
|
2023-06-12 21:52:45 +08:00
|
|
|
|
|
|
|
inline void pushUnique(uint32_t rootDeviceIndex) {
|
2023-09-05 23:33:39 +08:00
|
|
|
if (indexPresent.size() <= rootDeviceIndex) {
|
|
|
|
indexPresent.resize(rootDeviceIndex + 1);
|
|
|
|
}
|
|
|
|
if (!indexPresent[rootDeviceIndex]) {
|
2023-06-12 21:52:45 +08:00
|
|
|
push_back(rootDeviceIndex);
|
2023-09-05 23:33:39 +08:00
|
|
|
indexPresent[rootDeviceIndex] = 1;
|
2023-06-12 21:52:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2023-11-30 18:36:43 +08:00
|
|
|
StackVec<int8_t, maxRootDeviceIndices> indexPresent;
|
2023-06-12 21:52:45 +08:00
|
|
|
};
|
2023-11-30 18:36:43 +08:00
|
|
|
using RootDeviceIndicesMap = StackVec<std::tuple<uint32_t, uint32_t>, maxRootDeviceIndices>;
|