-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Bogdan Pereanu <[email protected]>
- Loading branch information
Showing
10 changed files
with
301 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (C) 2018-2024 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
#include <mutex> | ||
|
||
#include "intel_npu/config/config.hpp" | ||
#include "intel_npu/utils/zero/zero_init.hpp" | ||
#include "openvino/runtime/common.hpp" | ||
#include "openvino/runtime/itensor.hpp" | ||
#include "openvino/runtime/so_ptr.hpp" | ||
|
||
namespace intel_npu { | ||
|
||
class ZeroTensor final : public ov::ITensor { | ||
public: | ||
ZeroTensor(const std::shared_ptr<ZeroInitStructsHolder>& init_structs, | ||
const ov::element::Type element_type, | ||
const ov::Shape& shape, | ||
const ov::Allocator& allocator); | ||
|
||
void* data(const ov::element::Type& element_type) const override; | ||
|
||
const ov::element::Type& get_element_type() const override; | ||
|
||
const ov::Shape& get_shape() const override; | ||
|
||
void set_shape(ov::Shape new_shape) override; | ||
|
||
const ov::Strides& get_strides() const override; | ||
|
||
~ZeroTensor(); | ||
|
||
private: | ||
static void initialize_elements(void* data, const ov::element::Type& element_type, const ov::Shape& shape); | ||
void update_strides() const; | ||
size_t get_capacity() const; | ||
size_t get_bytes_capacity() const; | ||
void destroy_elements(size_t begin_ind, size_t end_ind); | ||
void destroy_memory(); | ||
|
||
std::shared_ptr<ZeroInitStructsHolder> _init_structs; | ||
|
||
ov::element::Type _element_type; | ||
ov::Shape _shape; | ||
ov::Shape _capacity; | ||
mutable ov::Strides _strides; | ||
mutable std::once_flag _strides_once; | ||
ov::Allocator _allocator; | ||
void* _ptr = nullptr; | ||
}; | ||
|
||
} // namespace intel_npu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
// Copyright (C) 2018-2024 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#include "zero_tensor.hpp" | ||
|
||
#include "openvino/core/type/element_iterator.hpp" | ||
#include "openvino/runtime/properties.hpp" | ||
#include "openvino/runtime/tensor.hpp" | ||
|
||
namespace intel_npu { | ||
|
||
ZeroTensor::ZeroTensor(const std::shared_ptr<ZeroInitStructsHolder>& init_structs, | ||
const ov::element::Type element_type, | ||
const ov::Shape& shape, | ||
const ov::Allocator& allocator) | ||
: _init_structs(init_structs), | ||
_element_type{element_type}, | ||
_shape{shape}, | ||
_capacity{_shape}, | ||
_strides{}, | ||
_strides_once{}, | ||
_allocator{allocator} { | ||
OPENVINO_ASSERT(_element_type != ov::element::undefined && _element_type.is_static()); | ||
OPENVINO_ASSERT(allocator, "Allocator was not initialized"); | ||
const auto byte_size = ov::element::get_memory_size(_element_type, shape_size(_shape)); | ||
auto data = const_cast<ov::Allocator&>(_allocator).allocate(byte_size); | ||
OPENVINO_ASSERT(byte_size == 0 || data != nullptr, "Failed to allocate memory"); | ||
initialize_elements(data, element_type, _shape); | ||
_ptr = data; | ||
} | ||
|
||
void* ZeroTensor::data(const ov::element::Type& element_type) const { | ||
if (element_type != ov::element::undefined && element_type != ov::element::dynamic && | ||
(element_type.bitwidth() != get_element_type().bitwidth() || | ||
element_type.is_real() != get_element_type().is_real() || | ||
(element_type == ov::element::string && get_element_type() != ov::element::string) || | ||
(element_type != ov::element::string && get_element_type() == ov::element::string))) { | ||
OPENVINO_THROW("Tensor data with element type ", | ||
get_element_type(), | ||
", is not representable as pointer to ", | ||
element_type); | ||
} | ||
return _ptr; | ||
} | ||
|
||
const ov::element::Type& ZeroTensor::get_element_type() const { | ||
return _element_type; | ||
} | ||
|
||
const ov::Shape& ZeroTensor::get_shape() const { | ||
return _shape; | ||
} | ||
|
||
void ZeroTensor::update_strides() const { | ||
if (_element_type.bitwidth() < 8) | ||
return; | ||
|
||
auto& shape = get_shape(); | ||
if (_strides.empty() && !shape.empty()) { | ||
_strides.resize(shape.size()); | ||
_strides.back() = shape.back() == 0 ? 0 : _element_type.size(); | ||
std::transform(shape.crbegin(), | ||
shape.crend() - 1, | ||
_strides.rbegin(), | ||
_strides.rbegin() + 1, | ||
std::multiplies<size_t>()); | ||
} | ||
} | ||
|
||
const ov::Strides& ZeroTensor::get_strides() const { | ||
OPENVINO_ASSERT(_element_type.bitwidth() >= 8, | ||
"Could not get strides for types with bitwidths less then 8 bit. Tensor type: ", | ||
_element_type); | ||
std::call_once(_strides_once, &ZeroTensor::update_strides, this); | ||
return _strides; | ||
} | ||
|
||
void ZeroTensor::initialize_elements(void* data, const ov::element::Type& element_type, const ov::Shape& shape) { | ||
if (element_type == ov::element::Type_t::string) { | ||
auto num_elements = shape_size(shape); | ||
auto string_ptr = static_cast<std::string*>(data); | ||
std::uninitialized_fill_n(string_ptr, num_elements, std::string()); | ||
} | ||
} | ||
|
||
size_t ZeroTensor::get_capacity() const { | ||
return shape_size(_capacity); | ||
} | ||
|
||
size_t ZeroTensor::get_bytes_capacity() const { | ||
return ov::element::get_memory_size(get_element_type(), get_capacity()); | ||
} | ||
|
||
void ZeroTensor::destroy_elements(size_t begin_ind, size_t end_ind) { | ||
// it removes elements from tail | ||
if (get_element_type() == ov::element::Type_t::string) { | ||
auto strings = static_cast<std::string*>(_ptr); | ||
for (size_t ind = begin_ind; ind < end_ind; ++ind) { | ||
using std::string; | ||
strings[ind].~string(); | ||
} | ||
} | ||
} | ||
|
||
void ZeroTensor::destroy_memory() { | ||
destroy_elements(0, get_capacity()); | ||
_allocator.deallocate(_ptr, get_bytes_capacity()); | ||
_ptr = nullptr; | ||
} | ||
|
||
void ZeroTensor::set_shape(ov::Shape new_shape) { | ||
if (_shape == new_shape) | ||
return; | ||
|
||
_shape = std::move(new_shape); | ||
|
||
if (get_size() > get_capacity()) { | ||
if (!_init_structs->getMutableCommandListVersion()) { | ||
OPENVINO_THROW("Cannot set a larger shape with this driver version."); | ||
} | ||
|
||
destroy_memory(); | ||
|
||
// allocate buffer and initialize objects from scratch | ||
_capacity = _shape; | ||
_ptr = _allocator.allocate(get_bytes_capacity()); | ||
initialize_elements(_ptr, _element_type, _shape); | ||
} | ||
|
||
_strides.clear(); | ||
update_strides(); | ||
} | ||
|
||
ZeroTensor::~ZeroTensor() { | ||
destroy_memory(); | ||
} | ||
|
||
} // namespace intel_npu |
Oops, something went wrong.