serizba / cppflow

Run TensorFlow models in C++ without installation and without Bazel
https://serizba.github.io/cppflow/
MIT License
779 stars 177 forks source link

Added tensor constructors and get_raw_data to work with pointers of p… #202

Open sohailreddy opened 2 years ago

sohailreddy commented 2 years ago

Since most scientific computing codes don't use std::vector and use their own containers, new tensor constructor and get_raw_data functions were added to work with pointers of primitive types.

serizba commented 2 years ago

Hi @sohailrreddy, great work! Definitely something interesting and required by many of us!

I think that with your changes now it would be better if the old std::vector<T> tensor::get_data() uses the new T *tensor::get_raw_data(), as they share most of the body. What do you think?

Thanks!

sohailreddy commented 2 years ago

Hi @serizba , Great point!! I updated the tensor::get_data() to use tensor::get_raw_data(size_t &size). Had to make some more changes since we need to know the size of the pointer to convert to the std::vector. Also added a default/empty constructor for cppflow::model, so that we can declare it without needing to initialize

Let me know what you think!

serizba commented 1 year ago

Good work! Sorry for not attending this earlier. I will fix the conflicts myself and merge it. This is required.

sohailreddy commented 1 year ago

Thanks for taking care of this @serizba Any idea when it'll make it into the main branch? We have some projects that would like to use it

DemO-O-On commented 1 year ago

Hello, I'm a newbuy in C++ and I have a question: can I create cppflow::tensor from 2-dimensional vector or array? I've tried

std::vector<std::vector<int64_t>> data {{1,2,3}, {4,5,6}};

std::vector<int64_t> shape{2,3};

auto b = cppflow::tensor(data, shape);

but it dropped me

terminate called after throwing an instance of 'std::runtime_error'
  what():  Could not deduce type! type_name: St6vectorIxSaIxEE

What am I doing wrong?

sohailreddy commented 1 year ago

It won't work with multi-dimensional vector/array as inputs. You would need to create a single vector containing all the elements of the multi-dim. vector (or tensor) and then pass the pointer to this raw data, along with the length of each dimension to the cppflow::tensor() constructor.

std::vector<int64_t> shape{2,3};
std::vector<int64_t> long_vector(6);  // Length should be product of all dims
auto b = cppflow::tensor(long_vector.data(), shape);
DemO-O-On commented 1 year ago

I've tried this, but it thorws an error

1.cpp:16:55: error: no matching function for call to 'cppflow::tensor::tensor(long long int*, std::vector<long long int>&)'
   16 |     auto b = cppflow::tensor(long_vector.data(), shape);
      |                                                       ^
In file included from libs/cppflow/model.h:56,
                 from libs/cppflow/cppflow.h:42,
                 from 1.cpp:2:
libs/cppflow/tensor.h:88:3: note: candidate: 'template<class T> cppflow::tensor::tensor(const T&)'
   88 |   tensor(const T& value);
      |   ^~~~~~

P.S.

Full code:

#include <iostream>
#include <cppflow/cppflow.h>
#include <vector>

// g++ -Ilibs/tf/include -Ilibs -Llibs/tf/lib 1.cpp -ltensorflow -o 1.exe

int main() {
    cppflow::model model("tf_saved_model");
    std::vector<int64_t> shape{2,3};
    std::vector<int64_t> long_vector(6);  // Length should be product of all dims
    auto b = cppflow::tensor(long_vector.data(), shape);
    std::cout << b << std::endl;
}

P.P.S. The most weird thing is this error:

libs/cppflow/tensor.h:72:3: note: candidate: 'template<class T> cppflow::tensor::tensor(const std::vector<T>&, const std::vector<long long int>&)'
   72 |   tensor(const std::vector<T>& values, const std::vector<int64_t>& shape);
      |   ^~~~~~

As I think, these lines have to work while cppflow::tensor(long_vector.data(), shape). But I don't know why they don't work