Coverage Report

Created: 2026-10-05 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
341
void fuzzTensor(FuzzedDataProvider* stream) {
25
341
  int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions);
26
341
  Eigen::array<Eigen::Index, kMaxDimensions> dims;
27
2.04k
  for (int i = 0; i < kMaxDimensions; ++i) {
28
1.70k
    if (i < numDims) {
29
424
      dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize);
30
1.28k
    } else {
31
1.28k
      dims[i] = 1;
32
1.28k
    }
33
1.70k
  }
34
35
  // We'll use a fixed rank for simplicity in templating, but varied sizes.
36
341
  Eigen::Tensor<Scalar, 3> tensor(
37
341
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
38
341
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
39
341
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize));
40
  
41
39.3k
  for (Eigen::Index i = 0; i < tensor.size(); ++i) {
42
    if constexpr (std::is_integral_v<Scalar>) {
43
      tensor(i) = stream->ConsumeIntegral<Scalar>();
44
38.9k
    } else {
45
38.9k
      tensor(i) = stream->ConsumeFloatingPoint<Scalar>();
46
38.9k
    }
47
38.9k
  }
48
49
  // Basic operations
50
341
  (void)tensor.maximum();
51
341
  (void)tensor.minimum();
52
341
  (void)tensor.sum();
53
341
  (void)tensor.mean();
54
55
  // Chipping
56
341
  if (tensor.dimension(0) > 0) {
57
341
    (void)tensor.chip(0, 0);
58
341
  }
59
60
  // Shuffling
61
341
  Eigen::array<int, 3> shuffle_dims = {1, 0, 2};
62
341
  (void)tensor.shuffle(shuffle_dims);
63
64
  // Striding
65
341
  Eigen::array<Eigen::Index, 3> strides = {2, 1, 1};
66
341
  (void)tensor.stride(strides);
67
341
}
tensor_fuzzer.cc:void (anonymous namespace)::fuzzTensor<float>(FuzzedDataProvider*)
Line
Count
Source
24
175
void fuzzTensor(FuzzedDataProvider* stream) {
25
175
  int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions);
26
175
  Eigen::array<Eigen::Index, kMaxDimensions> dims;
27
1.05k
  for (int i = 0; i < kMaxDimensions; ++i) {
28
875
    if (i < numDims) {
29
211
      dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize);
30
664
    } else {
31
664
      dims[i] = 1;
32
664
    }
33
875
  }
34
35
  // We'll use a fixed rank for simplicity in templating, but varied sizes.
36
175
  Eigen::Tensor<Scalar, 3> tensor(
37
175
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
38
175
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
39
175
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize));
40
  
41
14.7k
  for (Eigen::Index i = 0; i < tensor.size(); ++i) {
42
    if constexpr (std::is_integral_v<Scalar>) {
43
      tensor(i) = stream->ConsumeIntegral<Scalar>();
44
14.5k
    } else {
45
14.5k
      tensor(i) = stream->ConsumeFloatingPoint<Scalar>();
46
14.5k
    }
47
14.5k
  }
48
49
  // Basic operations
50
175
  (void)tensor.maximum();
51
175
  (void)tensor.minimum();
52
175
  (void)tensor.sum();
53
175
  (void)tensor.mean();
54
55
  // Chipping
56
175
  if (tensor.dimension(0) > 0) {
57
175
    (void)tensor.chip(0, 0);
58
175
  }
59
60
  // Shuffling
61
175
  Eigen::array<int, 3> shuffle_dims = {1, 0, 2};
62
175
  (void)tensor.shuffle(shuffle_dims);
63
64
  // Striding
65
175
  Eigen::array<Eigen::Index, 3> strides = {2, 1, 1};
66
175
  (void)tensor.stride(strides);
67
175
}
tensor_fuzzer.cc:void (anonymous namespace)::fuzzTensor<double>(FuzzedDataProvider*)
Line
Count
Source
24
166
void fuzzTensor(FuzzedDataProvider* stream) {
25
166
  int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions);
26
166
  Eigen::array<Eigen::Index, kMaxDimensions> dims;
27
996
  for (int i = 0; i < kMaxDimensions; ++i) {
28
830
    if (i < numDims) {
29
213
      dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize);
30
617
    } else {
31
617
      dims[i] = 1;
32
617
    }
33
830
  }
34
35
  // We'll use a fixed rank for simplicity in templating, but varied sizes.
36
166
  Eigen::Tensor<Scalar, 3> tensor(
37
166
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
38
166
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize),
39
166
      stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize));
40
  
41
24.6k
  for (Eigen::Index i = 0; i < tensor.size(); ++i) {
42
    if constexpr (std::is_integral_v<Scalar>) {
43
      tensor(i) = stream->ConsumeIntegral<Scalar>();
44
24.4k
    } else {
45
24.4k
      tensor(i) = stream->ConsumeFloatingPoint<Scalar>();
46
24.4k
    }
47
24.4k
  }
48
49
  // Basic operations
50
166
  (void)tensor.maximum();
51
166
  (void)tensor.minimum();
52
166
  (void)tensor.sum();
53
166
  (void)tensor.mean();
54
55
  // Chipping
56
166
  if (tensor.dimension(0) > 0) {
57
166
    (void)tensor.chip(0, 0);
58
166
  }
59
60
  // Shuffling
61
166
  Eigen::array<int, 3> shuffle_dims = {1, 0, 2};
62
166
  (void)tensor.shuffle(shuffle_dims);
63
64
  // Striding
65
166
  Eigen::array<Eigen::Index, 3> strides = {2, 1, 1};
66
166
  (void)tensor.stride(strides);
67
166
}
68
69
} // namespace
70
71
3.06k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
72
3.06k
  FuzzedDataProvider stream(data, size);
73
74
3.06k
  uint8_t type = stream.ConsumeIntegral<uint8_t>();
75
3.06k
  switch (type % 2) {
76
1.67k
    case 0:
77
1.67k
      fuzzTensor<float>(&stream);
78
1.67k
      break;
79
1.39k
    case 1:
80
1.39k
      fuzzTensor<double>(&stream);
81
1.39k
      break;
82
3.06k
  }
83
84
3.06k
  return 0;
85
3.06k
}