device/tensor.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | #include <cstddef> | ||
| 5 | #include <cstdint> | ||
| 6 | #include <stdexcept> | ||
| 7 | #include <type_traits> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include <dlpack/dlpack.h> | ||
| 11 | |||
| 12 | #if !defined(DLPACK_MAJOR_VERSION) || DLPACK_MAJOR_VERSION < 1 | ||
| 13 | #error "Chrono Batch Render needs DLPack 1.0 or later, but an older dlpack.h was included first" | ||
| 14 | #endif | ||
| 15 | |||
| 16 | #include "chrono_batch_render/device/operation.h" | ||
| 17 | #include "chrono_batch_render/device/ref.h" | ||
| 18 | #include "chrono_batch_render/export.h" | ||
| 19 | #include "chrono_batch_render/util/span.h" | ||
| 20 | |||
| 21 | namespace chrono::batch_render::device { | ||
| 22 | |||
| 23 | class Buffer; | ||
| 24 | class Device; | ||
| 25 | |||
| 26 | enum class DType : uint8_t { UInt8, UInt32, Float32, Float64, Int32, UInt64, Int64 }; | ||
| 27 | |||
| 28 | 154202 | constexpr uint32_t ElementBytes(DType dtype) { | |
| 29 | 154202 | return dtype == DType::UInt8 ? 1 | |
| 30 | : dtype == DType::Float64 || dtype == DType::UInt64 || dtype == DType::Int64 ? 8 | ||
| 31 | 154202 | : 4; | |
| 32 | } | ||
| 33 | |||
| 34 | template <class T> constexpr DType ElementType() { | ||
| 35 | if constexpr (std::is_same_v<T, uint8_t>) { | ||
| 36 | return DType::UInt8; | ||
| 37 | } else if constexpr (std::is_same_v<T, uint32_t>) { | ||
| 38 | return DType::UInt32; | ||
| 39 | } else if constexpr (std::is_same_v<T, float>) { | ||
| 40 | return DType::Float32; | ||
| 41 | } else if constexpr (std::is_same_v<T, double>) { | ||
| 42 | return DType::Float64; | ||
| 43 | } else if constexpr (std::is_same_v<T, int32_t>) { | ||
| 44 | return DType::Int32; | ||
| 45 | } else if constexpr (std::is_same_v<T, int64_t>) { | ||
| 46 | return DType::Int64; | ||
| 47 | } else { | ||
| 48 | static_assert(std::is_same_v<T, uint64_t>, "Tensors hold no elements of this type"); | ||
| 49 | return DType::UInt64; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | class CHRONO_BATCH_RENDER_API Tensor { | ||
| 54 | public: | ||
| 55 | Tensor(); | ||
| 56 | ~Tensor(); | ||
| 57 | Tensor(const Tensor& other); | ||
| 58 | Tensor(Tensor&& other) noexcept; | ||
| 59 | Tensor& operator=(const Tensor& other); | ||
| 60 | Tensor& operator=(Tensor&& other) noexcept; | ||
| 61 | Tensor(Ref<Buffer> buffer, uint64_t offset, DType dtype, std::vector<int64_t> shape, | ||
| 62 | std::vector<int64_t> strides = {}); | ||
| 63 | |||
| 64 | 197361 | bool Empty() const { | |
| 65 | 196606 | return m_buffer == nullptr; | |
| 66 | } | ||
| 67 | |||
| 68 | 274 | Buffer& GetBuffer() const { | |
| 69 | 287 | return *m_buffer; | |
| 70 | } | ||
| 71 | |||
| 72 | Device& GetDevice() const; | ||
| 73 | |||
| 74 | 242 | uint64_t Offset() const { | |
| 75 | 242 | return m_offset; | |
| 76 | } | ||
| 77 | |||
| 78 | uint64_t Address() const; | ||
| 79 | |||
| 80 | 241606 | DType Type() const { | |
| 81 | 241605 | return m_dtype; | |
| 82 | } | ||
| 83 | |||
| 84 | 275662 | Span<const int64_t> Shape() const { | |
| 85 | 275683 | return m_shape; | |
| 86 | } | ||
| 87 | |||
| 88 | 138330 | Span<const int64_t> Strides() const { | |
| 89 | 138317 | return m_strides; | |
| 90 | } | ||
| 91 | |||
| 92 | int64_t Elements() const; | ||
| 93 | Tensor Select(int64_t index) const; | ||
| 94 | |||
| 95 | std::vector<std::byte> ToHostBytes() const; | ||
| 96 | Download ToHostAsync() const; | ||
| 97 | DLTensor DLPack() const; | ||
| 98 | DLManagedTensorVersioned* Export() const; | ||
| 99 | |||
| 100 | 4040 | template <class T> std::vector<T> ToHost() const { | |
| 101 | 4040 | if (sizeof(T) != ElementBytes(m_dtype)) { | |
| 102 | 1 | throw std::invalid_argument("ToHost of a type unlike the tensor's elements"); | |
| 103 | } | ||
| 104 | 4039 | std::vector<T> values(static_cast<size_t>(Elements())); | |
| 105 | 4039 | if (!values.empty()) { | |
| 106 | 4039 | ReadInto(values.data()); | |
| 107 | } | ||
| 108 | 4039 | return values; | |
| 109 | ✗ | } | |
| 110 | |||
| 111 | private: | ||
| 112 | void ReadInto(void* out) const; | ||
| 113 | |||
| 114 | Ref<Buffer> m_buffer; | ||
| 115 | uint64_t m_offset = 0; | ||
| 116 | DType m_dtype = DType::Float32; | ||
| 117 | std::vector<int64_t> m_shape; | ||
| 118 | std::vector<int64_t> m_strides; | ||
| 119 | }; | ||
| 120 | |||
| 121 | } | ||
| 122 |