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 | } |