diff options
| author | Eric Dao <eric@erickhangdao.com> | 2025-03-10 17:54:31 -0400 |
|---|---|---|
| committer | Eric Dao <eric@erickhangdao.com> | 2025-03-10 17:54:31 -0400 |
| commit | ab224e2e6ba65f5a369ec392f99cd8845ad06c98 (patch) | |
| tree | a1e757e9341863ed52b8ad4c5a1c45933aab9da4 /python/openvino/runtime/streaming/image_streaming_app/uio | |
| parent | 40da1752f2c8639186b72f6838aa415e854d0b1d (diff) | |
| download | thesis-master.tar.gz thesis-master.tar.bz2 thesis-master.zip | |
Diffstat (limited to 'python/openvino/runtime/streaming/image_streaming_app/uio')
4 files changed, 299 insertions, 0 deletions
diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/CMakeLists.txt b/python/openvino/runtime/streaming/image_streaming_app/uio/CMakeLists.txt new file mode 100644 index 0000000..4c445a2 --- /dev/null +++ b/python/openvino/runtime/streaming/image_streaming_app/uio/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright 2023 Intel Corporation +# +# This software and the related documents are Intel copyrighted materials, +# and your use of them is governed by the express license under which they +# were provided to you ("License"). Unless the License provides otherwise, +# you may not use, modify, copy, publish, distribute, disclose or transmit +# this software or the related documents without Intel's prior written +# permission. +# +# This software and the related documents are provided as is, with no express +# or implied warranties, other than those that are expressly stated in the +# License. + +project(uio) + +set(header_files "") +set(source_files "") + +# specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# Header files +set(header_files ${header_files} "include/IUioDevice.h") +set(header_files ${header_files} "source/UioDevice.h") + +# Source files +set(source_files ${source_files} "source/UioDevice.cpp") + +set(all_files ${header_files} ${source_files}) + +add_library(${PROJECT_NAME} STATIC ${all_files}) + +# Include directories +target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/include/IUioDevice.h b/python/openvino/runtime/streaming/image_streaming_app/uio/include/IUioDevice.h new file mode 100644 index 0000000..9b964a7 --- /dev/null +++ b/python/openvino/runtime/streaming/image_streaming_app/uio/include/IUioDevice.h @@ -0,0 +1,40 @@ +// Copyright 2023 Intel Corporation. +// +// This software and the related documents are Intel copyrighted materials, +// and your use of them is governed by the express license under which they +// were provided to you ("License"). Unless the License provides otherwise, +// you may not use, modify, copy, publish, distribute, disclose or transmit +// this software or the related documents without Intel's prior written +// permission. +// +// This software and the related documents are provided as is, with no express +// or implied warranties, other than those that are expressly stated in the +// License. + +#pragma once +#include <filesystem> +#include <memory> +#include <string> +#include <vector> + +namespace UIO { +class DeviceItem { + public: + std::string _name; + uint32_t _index; + std::string _indexedName; + std::filesystem::path _rootPath; +}; + +class IDevice { + public: + static std::shared_ptr<IDevice> Load(const std::string& deviceName, uint32_t index = 0); + static std::vector<DeviceItem> GetDevices(); + + virtual uint32_t Read(uint32_t registerIndex) = 0; + virtual void Write(uint32_t registerIndex, uint32_t value) = 0; + virtual void ReadBlock(void* host_addr, size_t offset, size_t size) = 0; + virtual void WriteBlock(const void* host_addr, size_t offset, size_t size) = 0; +}; + +} // namespace UIO diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.cpp b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.cpp new file mode 100644 index 0000000..d1b5d17 --- /dev/null +++ b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.cpp @@ -0,0 +1,168 @@ +// Copyright 2023 Intel Corporation. +// +// This software and the related documents are Intel copyrighted materials, +// and your use of them is governed by the express license under which they +// were provided to you ("License"). Unless the License provides otherwise, +// you may not use, modify, copy, publish, distribute, disclose or transmit +// this software or the related documents without Intel's prior written +// permission. +// +// This software and the related documents are provided as is, with no express +// or implied warranties, other than those that are expressly stated in the +// License. + +#include "UioDevice.h" +#include <fcntl.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> +#include <filesystem> +#include <fstream> + +namespace UIO { +static const std::string uioDriverFolder = "/sys/class/uio"; + +std::shared_ptr<IDevice> IDevice::Load(const std::string& deviceName, uint32_t index) { + std::vector<DeviceItem> deviceItems = GetDevices(); + std::string indexedDeviceName = deviceName + std::to_string(index); + + for (auto& deviceItem : deviceItems) { + if (deviceItem._indexedName == indexedDeviceName) { + auto spUioDevice = std::make_shared<Device>(deviceItem); + return spUioDevice->IsValid() ? spUioDevice : nullptr; + } + } + + return nullptr; +} + +std::vector<DeviceItem> IDevice::GetDevices() { + std::vector<DeviceItem> deviceItems; + + for (const auto& entry : std::filesystem::directory_iterator(uioDriverFolder)) { + // Filter out uio* + if (entry.is_directory()) { + std::filesystem::path filePath = entry.path(); + std::string stem = filePath.filename(); + if (stem.substr(0, 3) == "uio") { + std::string indexedDeviceName = Device::ReadStringFromFile(filePath / "name"); + if (not indexedDeviceName.empty()) { + std::string deviceName; + uint32_t index = 0; + Device::SplitIndexedDeviceName(indexedDeviceName, deviceName, index); + deviceItems.push_back({deviceName, index, indexedDeviceName, filePath}); + } + } + } + } + + return deviceItems; +} + +/////////////////////////////////////////////////////////////////////////// + +Device::Device(const DeviceItem& deviceItem) : _deviceItem(deviceItem) { MapRegion(); } + +Device::~Device() { UnmapRegion(); } + +bool Device::IsValid() { return (_fd >= 0); } + +uint32_t Device::Read(uint32_t registerIndex) { + if (registerIndex >= _maximumRegisterIndex) return 0; + + uint32_t* pRegister = (uint32_t*)_pPtr; + + uint32_t value = pRegister[registerIndex]; + return value; +} + +void Device::Write(uint32_t registerIndex, uint32_t value) { + if (registerIndex < _maximumRegisterIndex) { + uint32_t* pRegister = (uint32_t*)_pPtr; + pRegister[registerIndex] = value; + } +} + +void Device::ReadBlock(void* pHostDestination, size_t offset, size_t size) { + if ((offset + size) < _size) { + uint8_t* pDeviceMem = (uint8_t*)_pPtr + offset; + ::memcpy(pHostDestination, pDeviceMem, size); + } +} + +void Device::WriteBlock(const void* pHostSourceAddress, size_t offset, size_t size) { + if ((offset + size) < _size) { + uint8_t* pDeviceMem = (uint8_t*)_pPtr + offset; + ::memcpy(pDeviceMem, pHostSourceAddress, size); + } +} + +uint64_t Device::ReadValueFromFile(const std::filesystem::path& path) { + std::string line = ReadStringFromFile(path); + int base = (line.substr(0, 2) == "0x") ? 16 : 10; + return std::stoull(line, nullptr, base); +} + +std::string Device::ReadStringFromFile(const std::filesystem::path& path) { + std::ifstream inputStream(path); + if (inputStream.good()) { + std::string line; + std::getline(inputStream, line); + return line; + } + return ""; +} + +bool Device::MapRegion() { + _size = ReadValueFromFile(_deviceItem._rootPath / "maps/map0/size"); + _offset = ReadValueFromFile(_deviceItem._rootPath / "maps/map0/offset"); + _physicalAddress = ReadValueFromFile(_deviceItem._rootPath / "maps/map0/addr"); + _maximumRegisterIndex = _size / sizeof(uint32_t); + + std::filesystem::path uioDevicePath = "/dev"; + std::filesystem::path uioDeviceId = _deviceItem._rootPath.stem(); + uioDevicePath /= uioDeviceId; + + _fd = ::open(uioDevicePath.c_str(), O_RDWR); + if (_fd < 0) { + return false; + } + + // Map the region into userspace + _pBase = (uint8_t*)::mmap(NULL, (size_t)_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0); + if (_pBase == MAP_FAILED) { + return false; + } + + // CST base address is at _pBase + _offset + _pPtr = (uint32_t*)(_pBase + _offset); + + return true; +}; + +void Device::UnmapRegion() { + int r = 0; + if (_pBase) { + r = ::munmap(_pBase, _size); + _pBase = nullptr; + } + + if (_fd >= 0) { + r = ::close(_fd); + _fd = -1; + } + (void)r; +} + +void Device::SplitIndexedDeviceName(const std::string& indexedDeviceName, std::string& deviceName, uint32_t& index) { + int32_t len = static_cast<int32_t>(indexedDeviceName.length()); + int32_t nDecimals = 0; + for (int32_t i = (len - 1); i >= 0; i--) { + if (::isdigit(indexedDeviceName[i])) nDecimals++; + } + + deviceName = indexedDeviceName.substr(0, len - nDecimals); + index = std::stoul(indexedDeviceName.substr(len - nDecimals)); +} + +} // namespace UIO diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.h b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.h new file mode 100644 index 0000000..49c6f51 --- /dev/null +++ b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.h @@ -0,0 +1,56 @@ +// Copyright 2023 Intel Corporation. +// +// This software and the related documents are Intel copyrighted materials, +// and your use of them is governed by the express license under which they +// were provided to you ("License"). Unless the License provides otherwise, +// you may not use, modify, copy, publish, distribute, disclose or transmit +// this software or the related documents without Intel's prior written +// permission. +// +// This software and the related documents are provided as is, with no express +// or implied warranties, other than those that are expressly stated in the +// License. + +#pragma once + +#include <filesystem> +#include <memory> +#include <string> +#include <vector> +#include "IUioDevice.h" + +namespace UIO { +class Device : public IDevice { + public: + Device(const DeviceItem& deviceItem); + ~Device(); + + // IDevice interface + uint32_t Read(uint32_t registerIndex) override; + void Write(uint32_t registerIndex, uint32_t value) override; + void ReadBlock(void* host_addr, size_t offset, size_t size) override; + void WriteBlock(const void* host_addr, size_t offset, size_t size) override; + + bool IsValid(); + static uint64_t ReadValueFromFile(const std::filesystem::path& path); + static std::string ReadStringFromFile(const std::filesystem::path& path); + static void SplitIndexedDeviceName(const std::string& indexedDeviceName, std::string& deviceName, uint32_t& index); + + private: + Device() = delete; + Device(Device const&) = delete; + void operator=(Device const&) = delete; + + bool MapRegion(); + void UnmapRegion(); + + DeviceItem _deviceItem; + uint32_t _maximumRegisterIndex = 0; + int _fd = -1; // File pointer to UIO - Used to indicate the the Device is valid + uint64_t _physicalAddress = 0; + uint64_t _size = 0; // Size of the mmapped region + uint64_t _offset = 0; // Offset of the first register + uint8_t* _pBase = nullptr; // Base of the mmapped region + uint32_t* _pPtr = nullptr; // The first register +}; +} // namespace UIO |
