Coverage Report

Created: 2026-09-14 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tensor_fuzzer.cc
Line
Count
Source
1
// Copyright 2026 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <fuzzer/FuzzedDataProvider.h>
16
#include <unsupported/Eigen/CXX11/Tensor>
17
18
namespace {
19
20
static constexpr int kMaxDimensions = 5;
21
static constexpr int kMaxDimSize = 10;
22
23
template <typename Scalar>
24
343
void fuzzTensor(FuzzedDataProvider* stream) {
25
343
  int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions);
26
343
  Eigen::array<Eigen::Index, kMaxDimensions> dims;
27
2.05k
  for (int i = 0; i < kMaxDimensions; ++i) {
28
1.71k
    if (i < numDims) {
29
446
      dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize);
30
1.26k
    } else {
31
1.26k
      dims[i] = 1;
32
1.26k
    }
33
1.71k
  }
34
35
  // We'll use a fixed rank for simplicity in templating, but varied sizes.
36
343
  Eigen::Tensor<Scalar, 3> tensor(
37
343
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
38
343
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
39
343
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize));
40
  
41
49.0k
  for (Eigen::Index i = 0; i < tensor.size(); ++i) {
42
    if constexpr (std::is_integral_v<Scalar>) {
43
      tensor(i) = stream->ConsumeIntegral<Scalar>();
44
48.6k
    } else {
45
48.6k
      tensor(i) = stream->ConsumeFloatingPoint<Scalar>();
46
48.6k
    }
47
48.6k
  }
48
49
  // Basic operations
50
343
  (void)tensor.maximum();
51
343
  (void)tensor.minimum();
52
343
  (void)tensor.sum();
53
343
  (void)tensor.mean();
54
55
  // Chipping
56
343
  if (tensor.dimension(0) > 0) {
57
343
    (void)tensor.chip(0, 0);
58
343
  }
59
60
  // Shuffling
61
343
  Eigen::array<int, 3> shuffle_dims = {1, 0, 2};
62
343
  (void)tensor.shuffle(shuffle_dims);
63
64
  // Striding
65
343
  Eigen::array<Eigen::Index, 3> strides = {2, 1, 1};
66
343
  (void)tensor.stride(strides);
67
343
}
tensor_fuzzer.cc:void (anonymous namespace)::fuzzTensor<float>(FuzzedDataProvider*)
Line
Count
Source
24
171
void fuzzTensor(FuzzedDataProvider* stream) {
25
171
  int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions);
26
171
  Eigen::array<Eigen::Index, kMaxDimensions> dims;
27
1.02k
  for (int i = 0; i < kMaxDimensions; ++i) {
28
855
    if (i < numDims) {
29
222
      dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize);
30
633
    } else {
31
633
      dims[i] = 1;
32
633
    }
33
855
  }
34
35
  // We'll use a fixed rank for simplicity in templating, but varied sizes.
36
171
  Eigen::Tensor<Scalar, 3> tensor(
37
171
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
38
171
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
39
171
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize));
40
  
41
21.9k
  for (Eigen::Index i = 0; i < tensor.size(); ++i) {
42
    if constexpr (std::is_integral_v<Scalar>) {
43
      tensor(i) = stream->ConsumeIntegral<Scalar>();
44
21.7k
    } else {
45
21.7k
      tensor(i) = stream->ConsumeFloatingPoint<Scalar>();
46
21.7k
    }
47
21.7k
  }
48
49
  // Basic operations
50
171
  (void)tensor.maximum();
51
171
  (void)tensor.minimum();
52
171
  (void)tensor.sum();
53
171
  (void)tensor.mean();
54
55
  // Chipping
56
171
  if (tensor.dimension(0) > 0) {
57
171
    (void)tensor.chip(0, 0);
58
171
  }
59
60
  // Shuffling
61
171
  Eigen::array<int, 3> shuffle_dims = {1, 0, 2};
62
171
  (void)tensor.shuffle(shuffle_dims);
63
64
  // Striding
65
171
  Eigen::array<Eigen::Index, 3> strides = {2, 1, 1};
66
171
  (void)tensor.stride(strides);
67
171
}
tensor_fuzzer.cc:void (anonymous namespace)::fuzzTensor<double>(FuzzedDataProvider*)
Line
Count
Source
24
172
void fuzzTensor(FuzzedDataProvider* stream) {
25
172
  int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions);
26
172
  Eigen::array<Eigen::Index, kMaxDimensions> dims;
27
1.03k
  for (int i = 0; i < kMaxDimensions; ++i) {
28
860
    if (i < numDims) {
29
224
      dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize);
30
636
    } else {
31
636
      dims[i] = 1;
32
636
    }
33
860
  }
34
35
  // We'll use a fixed rank for simplicity in templating, but varied sizes.
36
172
  Eigen::Tensor<Scalar, 3> tensor(
37
172
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
38
172
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
39
172
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize));
40
  
41
27.1k
  for (Eigen::Index i = 0; i < tensor.size(); ++i) {
42
    if constexpr (std::is_integral_v<Scalar>) {
43
      tensor(i) = stream->ConsumeIntegral<Scalar>();
44
26.9k
    } else {
45
26.9k
      tensor(i) = stream->ConsumeFloatingPoint<Scalar>();
46
26.9k
    }
47
26.9k
  }
48
49
  // Basic operations
50
172
  (void)tensor.maximum();
51
172
  (void)tensor.minimum();
52
172
  (void)tensor.sum();
53
172
  (void)tensor.mean();
54
55
  // Chipping
56
172
  if (tensor.dimension(0) > 0) {
57
172
    (void)tensor.chip(0, 0);
58
172
  }
59
60
  // Shuffling
61
172
  Eigen::array<int, 3> shuffle_dims = {1, 0, 2};
62
172
  (void)tensor.shuffle(shuffle_dims);
63
64
  // Striding
65
172
  Eigen::array<Eigen::Index, 3> strides = {2, 1, 1};
66
172
  (void)tensor.stride(strides);
67
172
}
68
69
} // namespace
70
71
3.02k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
72
3.02k
  FuzzedDataProvider stream(data, size);
73
74
3.02k
  uint8_t type = stream.ConsumeIntegral<uint8_t>();
75
3.02k
  switch (type % 2) {
76
1.64k
    case 0:
77
1.64k
      fuzzTensor<float>(&stream);
78
1.64k
      break;
79
1.38k
    case 1:
80
1.38k
      fuzzTensor<double>(&stream);
81
1.38k
      break;
82
3.02k
  }
83
84
3.02k
  return 0;
85
3.02k
}