-
Notifications
You must be signed in to change notification settings - Fork 71
Interfacing with C arrays and other external data
You can wrap C arrays as Fastor tensors and operate on them just like you would on Fastor's tensors without making any copies, using the Fastor::TensorMap
feature. For instance
double c_array[4] = {1,2,3,4};
TensorMap<double,4> tn1(c_array);
// You can now operate on tn1. This will also modify c_array
tn1 += 1;
// print c_array values now using println function
println<double,4>(c_array);
will give you
2 3 4 5
- If your Eigen matrices or Eigen tensors are row-major you can wrap them directly using
Fastor::TensorMap
and operate on them just like any other Fastor tensor.
Eigen::TensorFixedSize<double,Eigen::Sizes<2,3,4>, Eigen::RowMajor> ea;
std::iota(ea.data(),ea.data()+24,1.);
std::cout << "Eigen row-major tensor (ea)\n" << ea << std::endl;
TensorMap<double,2,3,4> fa(ea.data());
fa += 2;
std::cout << "Eigen row-major tensor modified by Fastor (ea+2) \n" << ea << std::endl;
Eigen row-major tensor (ea)
1 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 21 22 23 24
Eigen row-major tensor modified by Fastor (ea+2)
3 4 5 6 7 8 9 10 11 12 13 14
15 16 17 18 19 20 21 22 23 24 25 26
Note that Fastor::TensorMap
just wraps around existing data and does not make any copies so changing fa
in this case changes ea
. You can use Fastor::TensorMap
exactly like Fastor::Tensor
. It has almost all of the functionality of a Fastor::Tensor
.
- If your Eigen matrices/tensors are in column-major layout (Eigen's default), you have to construct a Fastor
Tensor
by specifying the layout to the constructor of the Tensor, for instance with Eigen matrices say
Eigen::Matrix<double,3,4> ea;
std::iota(ea.data(),ea.data()+12,1.);
std::cout << ea << std::endl;
1 4 7 10
2 5 8 11
3 6 9 12
Which is of course column-major. Now, to construct a Fastor Tensor
you do
Tensor<double,3,4> fa(ea.data(),Fastor::ColumnMajor);
You can perform computation on fa
now
fa += 2;
std::cout << fa << std::endl;
[ 3, 6, 9, 12]
[ 4, 7, 10, 13]
[ 5, 8, 11, 14]
To change back to Eigen matrix, it is necessary to convert back to row-major first and then use Eigen::Map
Tensor<double,3,4> fb = torowmajor(fa);
Eigen::Map<Eigen::Matrix<double,3,4>> eb(fb.data());
std::cout << eb << std::endl;
3 6 9 12
4 7 10 13
5 8 11 14
Otherwise Eigen will assume contiguity is in other axis and will swap the data for you. Note that all of these matrices are copies as Fastor internally treats everything as row-major, so changing fa
will not change ea
until you convert them back to Eigen matrices. This copy is really cheap though.
- There is also a free function
tocolumnmajor
that you can use after constructing aFastor::Tensor
Tensor<double,3,4> fa(ea.data());
Tensor<double,3,4> fb = tocolumnmajor(fa);
Certainly you can wrap Eigen::Tensor
s in the same fashion.