Search code examples
c++listeigeneigen3opennn

Pass List to Function Requiring std::initializer_list<std::initializer_list< type > >?


I'm using OpenNN to write a proof of concept right now, and I'm having an issue with declaring inputs for a Tensor.

From the OpenNN website we see that the neural net accepts a Tensor input

Tensor<type, 2> inputs(1,9);
inputs.setValues({{type(4),type(3),type(3),type(2),type(3),type(4),type(3),type(2),type(1)}});
neural_network.calculate_outputs(inputs);

I did figure out a workaround to convert a vector to a tensor, but it's long and a little tedious.

I then attempted to pass a vector of a vector, a brace enclosed vector, a brace enclosed array, a dynamically allocated array of the list of values.

The error:

cannot convert '<brace-enclosed initializer list>' to 'const Eigen::internal::Initializer<Eigen::Tensor<long long unsigned int, 2>, 2>::InitList&' {aka 'const std::initializer_list<std::initializer_list<long long unsigned int> >&'}

The error continues to just be a variation of (Type does not match type) The code to reproduce the error (assuming you've gotten the OpenNN library setup.

Tensor<uint64_t, 2> createFilledTensor(int index)
{ 
   uint64_t * inList = new uint64_t[index]();
    for(int i = 0; i < index; i++)
    {
        inList[i] = 356534563546356;
    }

    Tensor<uint64_t, 2> inputs(1, index);

    inputs.setValues({inList});
    return inputs;
}

Also, feel it's worth noting, right now the data doesn't matter as I am trying to figure out HOW to get it to the tensor.


Solution

  • EDIT:

    Found a relevant post here

    This solution is more for anyone else that comes around and my question can't be answered;

    I solved this problem as follows:

    namespace Eigen {
      template < typename T >
      decltype(auto) TensorLayoutSwap(T&& t)
      {
        return Eigen::TensorLayoutSwapOp<typename std::remove_reference<T>::type>(t);
      }
    }
    
    Eigen::Tensor<uint64_t, 2> createDataSetFromPair(std::pair<std::vector<uint64_t>, int> data)
    {
        Eigen::Tensor<uint64_t, 2> dataTensor(1,data.second);
        auto mapped_t = Eigen::TensorMap<Eigen::Tensor<uint64_t, 2, Eigen::RowMajor>>(&(data.first)[0], data.first.size(), 1);
    
        return Eigen::TensorLayoutSwap(mapped_t);
    }
    

    where pair(vec is the data list, and int is the amount of data being processed. I did this for my personal use as it has special application for what I'm doing, but I believe you could use vec.size() and only need a vector as a param