View versus copy
NEML2 allows a tensor to be a view of an existing tensor. As the name suggests, a tensor view shares the same underlying data with the tensor it is viewing into. In other words, supporting tensor view avoids data copy. Moreover, tensor views optionally (and often) reinterpret the shape and/or striding of the original data, allowing for fast and memory efficient reshaping, slicing, and element-wise operations.
In fact, all indexing mechanisms covered in the previous tutorial are creating tensor views, i.e., zero copy, negligible allocation. In addition to those indexing API, NEML2 also provides flexible tensor reshaping API (documented in neml2::TensorBase).
Who touched my data?
Tensor views avoid explicit data copying, which means:
- Modification in the original data will be reflected by the tensor view
- Modifying data viewed by the tensor view will alter the original data
It is therefore important to understand the difference between view and copy, and when to declare ownership (copy, or clone) of the original data.
The following example demonstrates the two bullet points, i.e., "change in original data" <-> "change in data viewed by the tensor view".
C++ @source:src1
#include "neml2/tensors/Tensor.h"
using namespace indexing;
int
main()
{
auto a = Tensor::zeros({4, 3});
std::cout << "a =\n" << a << std::endl;
auto b = a.base_index({Slice(None, None, 2)});
std::cout <<
"b =\n" <<
b << std::endl;
std::cout << "\nAfter first modification" << std::endl;
std::cout <<
"a =\n" <<
a << std::endl;
std::cout <<
"b =\n" <<
b << std::endl;
std::cout << "\nAfter second modification" << std::endl;
std::cout <<
"a =\n" <<
a << std::endl;
std::cout <<
"b =\n" <<
b << std::endl;
}
constexpr double a
Definition crystallography.h:43
constexpr double b
Definition crystallography.h:44
Definition DiagnosticsInterface.cxx:30
@endsource
Output:
Python @source:src2
from neml2.tensors import Tensor
a = Tensor.zeros((4, 3))
print("a =")
print(a)
b = a.base[::2]
print("b =")
print(b)
a += 1.0
print("\nAfter first modification")
print("a =")
print(a)
print("b =")
print(b)
b += 1.0
print("\nAfter second modification")
print("a =")
print(a)
print("b =")
print(b)
@endsource
Output:
- Note
- The same statements/rules still hold when multiple tensor views are viewing into the same underlying data, even if they are views of different regions.