onnxruntime/winml/lib/Api.Image/ConverterResourceStore.cpp
Justin Chu eeef157888
Format c++ code under winml/ (#16660)
winml/ was previously excluded from lintrunner config. This change
includes the directory and adds the clang-format config file specific to
winml/ that fits existing style.

---------

Signed-off-by: Justin Chu <justinchu@microsoft.com>
2023-07-25 21:56:50 -07:00

90 lines
2.8 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "lib/Api.Image/pch.h"
#include "inc/ConverterResourceStore.h"
#include <winrt\windows.media.h>
#include <winrt\Windows.Graphics.Imaging.h>
#include <d3d11on12.h>
#include <d3d11_4.h>
using namespace _winml;
ConverterResources::ConverterResources(Pool& pool, ConverterResourceDescription& descriptor)
: Descriptor(descriptor),
Tensorizer(std::make_unique<VideoFrameToTensorConverter>()),
Detensorizer(std::make_unique<TensorToVideoFrameConverter>()),
m_pool(pool) {
}
void ConverterResources::ReturnToCache() {
if (auto pool = m_pool.lock()) {
pool->Store(shared_from_this());
}
}
ConverterResourceStore::ConverterResourceStore(size_t nCacheSize) : m_cacheSize(nCacheSize) {
}
std::shared_ptr<ConverterResources> ConverterResourceStore::Fetch(ConverterResourceDescription& descriptor) {
std::lock_guard<std::mutex> lock(m_mutex);
auto resource = FetchAndRemoveObject(descriptor);
if (resource == nullptr) {
// Create the resource
resource = ConverterResources::Create(shared_from_this(), descriptor);
}
return resource;
}
std::shared_ptr<ConverterResources> ConverterResourceStore::FetchAndRemoveObject(ConverterResourceDescription& desc) {
// Iterate through the resources and find all the resources which are completed and unallocate
auto foundIt = std::find_if(std::begin(m_objects), std::end(m_objects), [&](const auto& cachedObject) {
return desc == cachedObject.Resource->Descriptor;
});
if (foundIt == std::end(m_objects)) {
return nullptr;
} else {
std::shared_ptr<ConverterResources> object = foundIt->Resource;
// Remove the item from the cache so that it is not reused by another call
m_objects.erase(foundIt);
return object;
}
}
void ConverterResourceStore::Store(std::shared_ptr<ConverterResources> object) {
std::lock_guard<std::mutex> lock(m_mutex);
auto foundIt = std::find_if(std::begin(m_objects), std::end(m_objects), [&](const auto& cachedObject) {
return object == cachedObject.Resource;
});
if (foundIt == std::end(m_objects)) {
// If the resource is not already cached
if (m_objects.size() < m_cacheSize) {
// If the cache has free slots, then use one
m_objects.push_back(PoolObject{object, storeId++});
} else {
// If the cache has no free slots, then evict the oldest
EvictOldestPoolObject();
m_objects.push_back(PoolObject{object, storeId++});
}
}
}
void ConverterResourceStore::EvictOldestPoolObject() {
auto oldestIt =
std::min_element(std::begin(m_objects), std::end(m_objects), [&](const auto& left, const auto& right) {
return left.StoreId < right.StoreId;
});
// Remove the oldest item from the cache
m_objects.erase(oldestIt);
}