From 031ba0b12c1e496fe6f34a86fe7ac893fcab1459 Mon Sep 17 00:00:00 2001 From: Sohail Reddy Date: Wed, 22 Jun 2022 18:59:15 -0700 Subject: [PATCH 1/3] Added tensor constructors and get_raw_data to work with pointers of primitive types --- include/cppflow/tensor.h | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/include/cppflow/tensor.h b/include/cppflow/tensor.h index 345e5b2..2775688 100644 --- a/include/cppflow/tensor.h +++ b/include/cppflow/tensor.h @@ -35,6 +35,16 @@ namespace cppflow { template tensor(const std::vector& values, const std::vector& shape); + /** + * Creates a flat tensor with the given values, and specified length and shape + * @tparam T A type that can be convertible into a tensor + * @param values The values to be converted + * @param len The length of the converted tensor + * @param shape The shape of the converted tensor + */ + template + tensor(T *values, size_t len, const std::vector& shape); + /** * Creates a flat tensor with the given values * @tparam T A type that can be convertible into a tensor @@ -77,6 +87,13 @@ namespace cppflow { template std::vector get_data() const; + /** + * Converts the tensor into a pointer of primitive type T + * @tparam T The c++ type (must be equivalent to the tensor type) + * @return A pointer of type T representing the flat tensor + */ + template + T *get_raw_data() const; ~tensor() = default; tensor(const tensor &tensor) = default; @@ -140,6 +157,11 @@ namespace cppflow { tensor::tensor(const std::vector& values, const std::vector& shape) : tensor(deduce_tf_type(), values.data(), values.size() * sizeof(T), shape) {} + + template + tensor::tensor(T *values, size_t len, const std::vector& shape) : + tensor(deduce_tf_type(), values, len * sizeof(T), shape) {} + template tensor::tensor(const std::initializer_list& values) : tensor(std::vector(values), {(int64_t) values.size()}) {} @@ -240,6 +262,32 @@ namespace cppflow { return r; } + template + T *tensor::get_raw_data() const { + + // Check if asked datatype and tensor datatype match + if (this->dtype() != deduce_tf_type()) { + auto type1 = cppflow::to_string(deduce_tf_type()); + auto type2 = cppflow::to_string(this->dtype()); + auto error = "Datatype in function get_data (" + type1 + ") does not match tensor datatype (" + type2 + ")"; + throw std::runtime_error(error); + } + + + auto res_tensor = get_tensor(); + + // Check tensor data is not empty + auto raw_data = TF_TensorData(res_tensor.get()); + //this->error_check(raw_data != nullptr, "Tensor data is empty"); + + size_t size = TF_TensorByteSize(res_tensor.get()) / TF_DataTypeSize(TF_TensorType(res_tensor.get())); + + // Convert to correct type + const auto T_data = static_cast(raw_data); + + return T_data; + } + inline datatype tensor::dtype() const { return TFE_TensorHandleDataType(this->tfe_handle.get()); } From 115eb62731292cf414fbb12a33189f840c3c9b6c Mon Sep 17 00:00:00 2001 From: Sohail Reddy Date: Thu, 18 Aug 2022 18:32:23 -0700 Subject: [PATCH 2/3] Updated tensor::get_data to use the tensor::get_raw_data functionality. Now also return the size of the raw pointer Committer: Sohail Reddy --- include/cppflow/tensor.h | 60 +++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/include/cppflow/tensor.h b/include/cppflow/tensor.h index 2775688..a559387 100644 --- a/include/cppflow/tensor.h +++ b/include/cppflow/tensor.h @@ -80,20 +80,29 @@ namespace cppflow { datatype dtype() const; /** - * Converts the tensor into a C++ vector + * Converts the tensor into a pointer of primitive type T * @tparam T The c++ type (must be equivalent to the tensor type) - * @return A vector representing the flat tensor + * @return A pointer of type T representing the flat tensor */ template - std::vector get_data() const; + T *get_raw_data() const; /** * Converts the tensor into a pointer of primitive type T * @tparam T The c++ type (must be equivalent to the tensor type) * @return A pointer of type T representing the flat tensor + * @return The size of the array */ template - T *get_raw_data() const; + T *get_raw_data(size_t &size) const; + + /** + * Converts the tensor into a C++ vector + * @tparam T The c++ type (must be equivalent to the tensor type) + * @return A vector representing the flat tensor + */ + template + std::vector get_data() const; ~tensor() = default; tensor(const tensor &tensor) = default; @@ -235,57 +244,52 @@ namespace cppflow { return res; } + template - std::vector tensor::get_data() const { + T *tensor::get_raw_data(size_t &size) const { // Check if asked datatype and tensor datatype match if (this->dtype() != deduce_tf_type()) { auto type1 = cppflow::to_string(deduce_tf_type()); auto type2 = cppflow::to_string(this->dtype()); - auto error = "Datatype in function get_data (" + type1 + ") does not match tensor datatype (" + type2 + ")"; + auto error = "Datatype in function get_raw_data (" + type1 + ") does not match tensor datatype (" + type2 + ")"; throw std::runtime_error(error); } - auto res_tensor = get_tensor(); // Check tensor data is not empty auto raw_data = TF_TensorData(res_tensor.get()); //this->error_check(raw_data != nullptr, "Tensor data is empty"); - size_t size = TF_TensorByteSize(res_tensor.get()) / TF_DataTypeSize(TF_TensorType(res_tensor.get())); + // Get size of array + size = TF_TensorByteSize(res_tensor.get()) / TF_DataTypeSize(TF_TensorType(res_tensor.get())); // Convert to correct type const auto T_data = static_cast(raw_data); - std::vector r(T_data, T_data + size); - return r; + return T_data; } template T *tensor::get_raw_data() const { - // Check if asked datatype and tensor datatype match - if (this->dtype() != deduce_tf_type()) { - auto type1 = cppflow::to_string(deduce_tf_type()); - auto type2 = cppflow::to_string(this->dtype()); - auto error = "Datatype in function get_data (" + type1 + ") does not match tensor datatype (" + type2 + ")"; - throw std::runtime_error(error); - } - - - auto res_tensor = get_tensor(); - - // Check tensor data is not empty - auto raw_data = TF_TensorData(res_tensor.get()); - //this->error_check(raw_data != nullptr, "Tensor data is empty"); + // Get the raw data and return + size_t size = 0; + const auto T_data = this->get_raw_data(size); - size_t size = TF_TensorByteSize(res_tensor.get()) / TF_DataTypeSize(TF_TensorType(res_tensor.get())); + return T_data; + } - // Convert to correct type - const auto T_data = static_cast(raw_data); + template + std::vector tensor::get_data() const { + + // Get the raw data and size of array + size_t size = 0; + const auto T_data = this->get_raw_data(size); + std::vector r(T_data, T_data + size); - return T_data; + return r; } inline datatype tensor::dtype() const { From a2cd0e73c1010bf124c584fb9f58a90b661703cc Mon Sep 17 00:00:00 2001 From: Sohail Reddy Date: Thu, 18 Aug 2022 18:38:48 -0700 Subject: [PATCH 3/3] Added default constructor for cppflow::model class --- include/cppflow/model.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/cppflow/model.h b/include/cppflow/model.h index d3a8d3e..9b378b4 100644 --- a/include/cppflow/model.h +++ b/include/cppflow/model.h @@ -25,6 +25,7 @@ namespace cppflow { FROZEN_GRAPH, }; + model() = default; explicit model(const std::string& filename, const TYPE type=TYPE::SAVED_MODEL); std::vector get_operations() const;