Implementation:NVIDIA DALI TensorView Tests
| Knowledge Sources | |
|---|---|
| Domains | Core, Testing |
| Last Updated | 2026-02-08 16:00 GMT |
Overview
This file contains Google Test suites for the TensorView and TensorListView classes, validating construction, addressing, type promotion, contiguity checks, reshape, and conversion between static and dynamic dimensionality.
Description
The TensorView and TensorListView test suite exercises DALI's non-owning tensor view abstractions. A TensorView<Backend, T, ndim> provides a typed, shaped pointer into existing data, while TensorListView extends this to batches of tensors with either contiguous or scattered data layouts.
The tests cover static and dynamic constructor variants, compile-time dimension inference (compile_time_size trait), element addressing via the operator() call operator (row-major indexing), type promotion from mutable to const views, static-to-dynamic and dynamic-to-static conversions via to_static, null pointer construction, contiguous and scattered data pointer layouts, move semantics that transfer underlying storage ownership, sub-tensor extraction via subtensor(), dimension collapsing on views, sample range slicing, contiguity and uniformity checks (is_contiguous, is_tensor), reshape operations including cross-sample splitting and merging, and reinterpret to a different element type.
A test fixture TensorListViewFromVectorOfTensorViewTest demonstrates constructing a TensorListView from a std::vector<TensorView> using make_tensor_list.
Usage
Use these tests as a reference when working with TensorView or TensorListView in DALI kernels. Run the test binary to verify that view construction, addressing arithmetic, and reshape logic remain correct after modifications to the core tensor view headers.
Code Reference
Source Location
- Repository: NVIDIA_DALI
- File: dali/core/tensor_view_test.cc
- Lines: 1-608
Signature
// Core types under test
template <typename Backend, typename DataType, int ndim>
struct TensorView;
template <typename Backend, typename DataType, int ndim = DynamicDimensions>
struct TensorListView;
// Key free functions tested
template <int ndim>
auto make_tensor_cpu(T *data, const std::array<int64_t, ndim> &shape);
template <int ndim>
auto make_tensor_list_cpu(T *data, const TensorListShape<ndim> &shape);
template <typename Backend, typename T, int ndim>
auto subtensor(const TensorView<Backend, T, ndim> &tv, int idx);
template <typename Backend, typename T, int ndim>
auto collapse_dim(const TensorView<Backend, T, ndim> &tv, int dim);
template <int out_dim, typename Backend, typename T, int ndim>
auto reshape(const TensorListView<Backend, T, ndim> &tlv,
const TensorListShape<out_dim> &shape, bool check);
template <typename U, typename Backend, typename T, int ndim>
auto reinterpret(const TensorListView<Backend, T, ndim> &tlv,
const TensorListShape<out_dim> &shape, bool check);
auto sample_range(const TensorListView &tlv, int start, int end, int stride = 1);
template <typename Backend, typename T, int ndim>
auto make_tensor_list(const std::vector<TensorView<Backend, T, ndim>> &tvs);
Import
#include <gtest/gtest.h>
#include <numeric>
#include <random>
#include <utility>
#include <algorithm>
#include "dali/core/tensor_shape.h"
#include "dali/core/tensor_view.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| N/A | N/A | N/A | Test file has no runtime inputs; tensor data and shapes are constructed inline within each TEST macro |
Outputs
| Name | Type | Description |
|---|---|---|
| Test results | Google Test assertions | PASS/FAIL verdicts for each test case validating TensorView and TensorListView behavior |
Usage Examples
Element addressing with TensorView
TensorView<EmptyBackendTag, int, 3> tv{static_cast<int*>(nullptr), {4, 100, 50}};
// Row-major addressing: tv(z, y, x) returns pointer offset
EXPECT_EQ(tv(0, 0, 0), static_cast<int*>(nullptr));
EXPECT_EQ(tv(1, 0, 0), static_cast<int*>(nullptr) + 5000);
EXPECT_EQ(tv(1, 1, 1), static_cast<int*>(nullptr) + 5051);
Contiguous TensorListView construction
int *base_ptr = ...;
TensorListView<EmptyBackendTag, int, 3> tlv{
base_ptr, {{4, 100, 50}, {2, 10, 5}, {4, 50, 25}, {4, 100, 50}}};
// Pointers are automatically computed from shape volumes
EXPECT_EQ(tlv[0].data, base_ptr);
EXPECT_EQ(tlv[1].data, base_ptr + 4 * 100 * 50);
Static-to-dynamic and back conversions
TensorView<EmptyBackendTag, int, 4> static_dim{ptr, {1, 2, 3, 4}};
TensorView<EmptyBackendTag, int, DynamicDimensions> dynamic_dim{static_dim};
TensorView<EmptyBackendTag, int, 4> back = dynamic_dim.to_static<4>();
Reshape a TensorListView
TensorListView<StorageCPU, int, 3> tlv = make_tensor_list_cpu(data, shape);
TensorListShape<3> new_shape = {{
{ 1, 3, 2 },
{ 1, 15, 2 },
{ 4, 1, 2 }
}};
auto reshaped = reshape(tlv, new_shape, /*check=*/true);
EXPECT_EQ(reshaped.shape, new_shape);