Coverage Report

Created: 2026-05-16 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dense_solver_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 <Eigen/Core>
17
#include <Eigen/QR>
18
#include <Eigen/LU>
19
#include <Eigen/Cholesky>
20
#include <Eigen/Eigenvalues>
21
#include <Eigen/SVD>
22
23
namespace {
24
25
static constexpr Eigen::Index kEigenTestMaxSize = 32;
26
27
template <typename Scalar>
28
0
void fuzzQR(FuzzedDataProvider* stream) {
29
0
  Eigen::Index rows = stream->ConsumeIntegralInRange<Eigen::Index>(1, kEigenTestMaxSize);
30
0
  Eigen::Index cols = stream->ConsumeIntegralInRange<Eigen::Index>(1, kEigenTestMaxSize);
31
32
0
  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> m(rows, cols);
33
0
  for (Eigen::Index i = 0; i < m.size(); ++i) {
34
0
    m(i) = stream->ConsumeFloatingPoint<Scalar>();
35
0
  }
36
37
  // HouseholderQR
38
0
  Eigen::HouseholderQR<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> qr(m);
39
0
  (void)qr.householderQ();
40
0
  (void)qr.matrixQR().template triangularView<Eigen::Upper>();
41
42
  // ColPivHouseholderQR
43
0
  Eigen::ColPivHouseholderQR<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> cpqr(m);
44
0
  (void)cpqr.rank();
45
0
  (void)cpqr.isInvertible();
46
47
  // FullPivHouseholderQR
48
0
  Eigen::FullPivHouseholderQR<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> fpqr(m);
49
0
  (void)fpqr.rank();
50
0
  (void)fpqr.isInvertible();
51
0
}
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzQR<float>(FuzzedDataProvider*)
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzQR<double>(FuzzedDataProvider*)
52
53
template <typename Scalar>
54
0
void fuzzLU(FuzzedDataProvider* stream) {
55
0
  Eigen::Index size = stream->ConsumeIntegralInRange<Eigen::Index>(1, kEigenTestMaxSize);
56
0
  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> m(size, size);
57
0
  for (Eigen::Index i = 0; i < m.size(); ++i) {
58
0
    m(i) = stream->ConsumeFloatingPoint<Scalar>();
59
0
  }
60
61
  // PartialPivLU
62
0
  Eigen::PartialPivLU<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> plu(m);
63
0
  (void)plu.determinant();
64
0
  (void)plu.inverse();
65
66
  // FullPivLU
67
0
  Eigen::FullPivLU<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> flu(m);
68
0
  (void)flu.determinant();
69
0
  (void)flu.inverse();
70
0
  (void)flu.rank();
71
0
}
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzLU<float>(FuzzedDataProvider*)
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzLU<double>(FuzzedDataProvider*)
72
73
template <typename Scalar>
74
0
void fuzzCholesky(FuzzedDataProvider* stream) {
75
0
  Eigen::Index size = stream->ConsumeIntegralInRange<Eigen::Index>(1, kEigenTestMaxSize);
76
0
  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> m(size, size);
77
0
  for (Eigen::Index i = 0; i < m.size(); ++i) {
78
0
    m(i) = stream->ConsumeFloatingPoint<Scalar>();
79
0
  }
80
81
  // LLT
82
0
  Eigen::LLT<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> llt(m);
83
0
  if (llt.info() == Eigen::Success) {
84
0
    (void)llt.matrixL();
85
0
    (void)llt.matrixU();
86
0
    Eigen::Matrix<Scalar, Eigen::Dynamic, 1> b = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>::Random(size);
87
0
    (void)llt.solve(b);
88
0
  }
89
90
  // LDLT
91
0
  Eigen::LDLT<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> ldlt(m);
92
0
  if (ldlt.info() == Eigen::Success) {
93
0
    (void)ldlt.matrixL();
94
0
    (void)ldlt.matrixU();
95
0
    (void)ldlt.vectorD();
96
0
    (void)ldlt.isPositive();
97
0
    (void)ldlt.isNegative();
98
0
    Eigen::Matrix<Scalar, Eigen::Dynamic, 1> b = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>::Random(size);
99
0
    (void)ldlt.solve(b);
100
0
  }
101
0
}
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzCholesky<float>(FuzzedDataProvider*)
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzCholesky<double>(FuzzedDataProvider*)
102
103
template <typename Scalar>
104
0
void fuzzEigenvalues(FuzzedDataProvider* stream) {
105
0
  Eigen::Index size = stream->ConsumeIntegralInRange<Eigen::Index>(1, kEigenTestMaxSize);
106
0
  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> m(size, size);
107
0
  for (Eigen::Index i = 0; i < m.size(); ++i) {
108
0
    m(i) = stream->ConsumeFloatingPoint<Scalar>();
109
0
  }
110
111
  // EigenSolver
112
0
  Eigen::EigenSolver<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> es(m);
113
0
  if (es.info() == Eigen::Success) {
114
0
    (void)es.eigenvalues();
115
0
    (void)es.eigenvectors();
116
0
  }
117
118
  // SelfAdjointEigenSolver (on a symmetric matrix)
119
0
  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> symm = m + m.transpose();
120
0
  Eigen::SelfAdjointEigenSolver<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> saes(symm);
121
0
  if (saes.info() == Eigen::Success) {
122
0
    (void)saes.eigenvalues();
123
0
    (void)saes.eigenvectors();
124
0
  }
125
0
}
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzEigenvalues<float>(FuzzedDataProvider*)
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzEigenvalues<double>(FuzzedDataProvider*)
126
127
template <typename Scalar>
128
0
void fuzzSVD(FuzzedDataProvider* stream) {
129
0
  Eigen::Index rows = stream->ConsumeIntegralInRange<Eigen::Index>(1, kEigenTestMaxSize);
130
0
  Eigen::Index cols = stream->ConsumeIntegralInRange<Eigen::Index>(1, kEigenTestMaxSize);
131
0
  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> m(rows, cols);
132
0
  for (Eigen::Index i = 0; i < m.size(); ++i) {
133
0
    m(i) = stream->ConsumeFloatingPoint<Scalar>();
134
0
  }
135
136
  // JacobiSVD
137
0
  Eigen::JacobiSVD<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> svd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
138
0
  if (svd.info() == Eigen::Success) {
139
0
    (void)svd.singularValues();
140
0
    (void)svd.matrixU();
141
0
    (void)svd.matrixV();
142
0
  }
143
144
  // BDCSVD
145
0
  Eigen::BDCSVD<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>> bdcsvd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
146
0
  if (bdcsvd.info() == Eigen::Success) {
147
0
    (void)bdcsvd.singularValues();
148
0
    (void)bdcsvd.matrixU();
149
0
    (void)bdcsvd.matrixV();
150
0
  }
151
0
}
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzSVD<float>(FuzzedDataProvider*)
Unexecuted instantiation: dense_solver_fuzzer.cc:void (anonymous namespace)::fuzzSVD<double>(FuzzedDataProvider*)
152
153
} // namespace
154
155
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
156
  FuzzedDataProvider stream(data, size);
157
158
  uint8_t type = stream.ConsumeIntegral<uint8_t>();
159
  // 0: QR<float>, 1: QR<double>, 2: LU<float>, 3: LU<double>,
160
  // 4: Cholesky<float>, 5: Cholesky<double>, 6: Eigenvalues<float>, 7: Eigenvalues<double>,
161
  // 8: SVD<float>, 9: SVD<double>
162
  switch (type % 10) {
163
    case 0:
164
      fuzzQR<float>(&stream);
165
      break;
166
    case 1:
167
      fuzzQR<double>(&stream);
168
      break;
169
    case 2:
170
      fuzzLU<float>(&stream);
171
      break;
172
    case 3:
173
      fuzzLU<double>(&stream);
174
      break;
175
    case 4:
176
      fuzzCholesky<float>(&stream);
177
      break;
178
    case 5:
179
      fuzzCholesky<double>(&stream);
180
      break;
181
    case 6:
182
      fuzzEigenvalues<float>(&stream);
183
      break;
184
    case 7:
185
      fuzzEigenvalues<double>(&stream);
186
      break;
187
    case 8:
188
      fuzzSVD<float>(&stream);
189
      break;
190
    case 9:
191
      fuzzSVD<double>(&stream);
192
      break;
193
  }
194
195
  return 0;
196
}