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 | 349 | void fuzzTensor(FuzzedDataProvider* stream) { |
25 | 349 | int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions); |
26 | 349 | Eigen::array<Eigen::Index, kMaxDimensions> dims; |
27 | 2.09k | for (int i = 0; i < kMaxDimensions; ++i) { |
28 | 1.74k | if (i < numDims) { |
29 | 479 | dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize); |
30 | 1.26k | } else { |
31 | 1.26k | dims[i] = 1; |
32 | 1.26k | } |
33 | 1.74k | } |
34 | | |
35 | | // We'll use a fixed rank for simplicity in templating, but varied sizes. |
36 | 349 | Eigen::Tensor<Scalar, 3> tensor( |
37 | 349 | stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize), |
38 | 349 | stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize), |
39 | 349 | stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize)); |
40 | | |
41 | 70.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 | 69.7k | } else { |
45 | 69.7k | tensor(i) = stream->ConsumeFloatingPoint<Scalar>(); |
46 | 69.7k | } |
47 | 69.7k | } |
48 | | |
49 | | // Basic operations |
50 | 349 | (void)tensor.maximum(); |
51 | 349 | (void)tensor.minimum(); |
52 | 349 | (void)tensor.sum(); |
53 | 349 | (void)tensor.mean(); |
54 | | |
55 | | // Chipping |
56 | 349 | if (tensor.dimension(0) > 0) { |
57 | 349 | (void)tensor.chip(0, 0); |
58 | 349 | } |
59 | | |
60 | | // Shuffling |
61 | 349 | Eigen::array<int, 3> shuffle_dims = {1, 0, 2}; |
62 | 349 | (void)tensor.shuffle(shuffle_dims); |
63 | | |
64 | | // Striding |
65 | 349 | Eigen::array<Eigen::Index, 3> strides = {2, 1, 1}; |
66 | 349 | (void)tensor.stride(strides); |
67 | 349 | } tensor_fuzzer.cc:void (anonymous namespace)::fuzzTensor<float>(FuzzedDataProvider*) Line | Count | Source | 24 | 177 | void fuzzTensor(FuzzedDataProvider* stream) { | 25 | 177 | int numDims = stream->ConsumeIntegralInRange<int>(1, kMaxDimensions); | 26 | 177 | Eigen::array<Eigen::Index, kMaxDimensions> dims; | 27 | 1.06k | for (int i = 0; i < kMaxDimensions; ++i) { | 28 | 885 | if (i < numDims) { | 29 | 253 | dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize); | 30 | 632 | } else { | 31 | 632 | dims[i] = 1; | 32 | 632 | } | 33 | 885 | } | 34 | | | 35 | | // We'll use a fixed rank for simplicity in templating, but varied sizes. | 36 | 177 | Eigen::Tensor<Scalar, 3> tensor( | 37 | 177 | stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize), | 38 | 177 | stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize), | 39 | 177 | stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize)); | 40 | | | 41 | 26.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 | 26.6k | } else { | 45 | 26.6k | tensor(i) = stream->ConsumeFloatingPoint<Scalar>(); | 46 | 26.6k | } | 47 | 26.6k | } | 48 | | | 49 | | // Basic operations | 50 | 177 | (void)tensor.maximum(); | 51 | 177 | (void)tensor.minimum(); | 52 | 177 | (void)tensor.sum(); | 53 | 177 | (void)tensor.mean(); | 54 | | | 55 | | // Chipping | 56 | 177 | if (tensor.dimension(0) > 0) { | 57 | 177 | (void)tensor.chip(0, 0); | 58 | 177 | } | 59 | | | 60 | | // Shuffling | 61 | 177 | Eigen::array<int, 3> shuffle_dims = {1, 0, 2}; | 62 | 177 | (void)tensor.shuffle(shuffle_dims); | 63 | | | 64 | | // Striding | 65 | 177 | Eigen::array<Eigen::Index, 3> strides = {2, 1, 1}; | 66 | 177 | (void)tensor.stride(strides); | 67 | 177 | } |
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 | 226 | dims[i] = stream->ConsumeIntegralInRange<Eigen::Index>(1, kMaxDimSize); | 30 | 634 | } else { | 31 | 634 | dims[i] = 1; | 32 | 634 | } | 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 | 43.2k | for (Eigen::Index i = 0; i < tensor.size(); ++i) { | 42 | | if constexpr (std::is_integral_v<Scalar>) { | 43 | | tensor(i) = stream->ConsumeIntegral<Scalar>(); | 44 | 43.1k | } else { | 45 | 43.1k | tensor(i) = stream->ConsumeFloatingPoint<Scalar>(); | 46 | 43.1k | } | 47 | 43.1k | } | 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 | 349 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
72 | 349 | FuzzedDataProvider stream(data, size); |
73 | | |
74 | 349 | uint8_t type = stream.ConsumeIntegral<uint8_t>(); |
75 | 349 | switch (type % 2) { |
76 | 177 | case 0: |
77 | 177 | fuzzTensor<float>(&stream); |
78 | 177 | break; |
79 | 172 | case 1: |
80 | 172 | fuzzTensor<double>(&stream); |
81 | 172 | break; |
82 | 349 | } |
83 | | |
84 | 349 | return 0; |
85 | 349 | } |