Skip to content

Commit 605b4d6

Browse files
committed
Replace dynamically allocated IntSimdMatrix instances by constants
Two header files are no longer needed and could be removed. Signed-off-by: Stefan Weil <[email protected]>
1 parent 26be7c5 commit 605b4d6

11 files changed

+35
-105
lines changed

CMakeLists.txt

-2
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,6 @@ install(FILES
356356
src/arch/dotproductavx.h
357357
src/arch/dotproductsse.h
358358
src/arch/intsimdmatrix.h
359-
src/arch/intsimdmatrixavx2.h
360-
src/arch/intsimdmatrixsse.h
361359
src/arch/simddetect.h
362360

363361
#from ccmain/makefile.am

src/arch/Makefile.am

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ endif
1111
pkginclude_HEADERS =
1212

1313
noinst_HEADERS = dotproduct.h dotproductavx.h dotproductsse.h
14-
noinst_HEADERS += intsimdmatrix.h intsimdmatrixavx2.h intsimdmatrixsse.h
14+
noinst_HEADERS += intsimdmatrix.h
1515
noinst_HEADERS += simddetect.h
1616

1717
noinst_LTLIBRARIES = libtesseract_native.la

src/arch/intsimdmatrix.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,26 @@
1818

1919
#include "intsimdmatrix.h"
2020
#include "genericvector.h" // for GenericVector
21-
#include "intsimdmatrixavx2.h" // for IntSimdMatrixAVX2
22-
#include "intsimdmatrixsse.h" // for IntSimdMatrixSSE
2321
#include "matrix.h" // for GENERIC_2D_ARRAY
2422
#include "simddetect.h" // for SIMDDetect
2523

2624
namespace tesseract {
2725

26+
const IntSimdMatrix IntSimdMatrix::IntSimdMatrixNative =
27+
IntSimdMatrix(1, 1, 1, 1, 1, {});
28+
2829
// Factory makes and returns an IntSimdMatrix (sub)class of the best
2930
// available type for the current architecture.
3031
/* static */
3132
const IntSimdMatrix* IntSimdMatrix::GetFastestMultiplier() {
3233
const IntSimdMatrix* multiplier;
3334
if (SIMDDetect::IsAVX2Available()) {
34-
multiplier = new IntSimdMatrixAVX2();
35+
multiplier = &IntSimdMatrixAVX2;
3536
} else if (SIMDDetect::IsSSEAvailable()) {
36-
multiplier = new IntSimdMatrixSSE();
37+
multiplier = &IntSimdMatrixSSE;
3738
} else {
3839
// Default c++ implementation.
39-
multiplier = new IntSimdMatrix(1, 1, 1, 1, 1, {});
40+
multiplier = &IntSimdMatrixNative;
4041
}
4142
return multiplier;
4243
}

src/arch/intsimdmatrix.h

+4
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ class IntSimdMatrix {
115115
const GenericVector<double>& scales, const int8_t* u,
116116
double* v) const;
117117

118+
static const IntSimdMatrix IntSimdMatrixAVX2;
119+
static const IntSimdMatrix IntSimdMatrixSSE;
120+
static const IntSimdMatrix IntSimdMatrixNative;
121+
118122
protected:
119123
// Rounds the input up to a multiple of the given factor.
120124
static int Roundup(int input, int factor) {

src/arch/intsimdmatrixavx2.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// limitations under the License.
1717
///////////////////////////////////////////////////////////////////////
1818

19-
#include "intsimdmatrixavx2.h"
19+
#include "intsimdmatrix.h"
2020

2121
#ifdef __AVX2__
2222
#include <immintrin.h>
@@ -269,14 +269,12 @@ static void PartialMatrixDotVector8(const int8_t* wi, const double* scales,
269269
namespace tesseract {
270270
#endif // __AVX2__
271271

272-
IntSimdMatrixAVX2::IntSimdMatrixAVX2()
273272
#ifdef __AVX2__
274-
: IntSimdMatrix(kNumOutputsPerRegister, kMaxOutputRegisters, kNumInputsPerRegister, kNumInputsPerGroup, kNumInputGroups, {PartialMatrixDotVector64, PartialMatrixDotVector32,
275-
PartialMatrixDotVector16, PartialMatrixDotVector8})
273+
const IntSimdMatrix IntSimdMatrix::IntSimdMatrixAVX2 =
274+
IntSimdMatrix(kNumOutputsPerRegister, kMaxOutputRegisters, kNumInputsPerRegister, kNumInputsPerGroup, kNumInputGroups, {PartialMatrixDotVector64, PartialMatrixDotVector32,
275+
PartialMatrixDotVector16, PartialMatrixDotVector8});
276276
#else
277-
: IntSimdMatrix(1, 1, 1, 1, 1, {})
277+
const IntSimdMatrix IntSimdMatrix::IntSimdMatrixAVX2 = IntSimdMatrix(1, 1, 1, 1, 1, {});
278278
#endif // __AVX2__
279-
{
280-
}
281279

282280
} // namespace tesseract.

src/arch/intsimdmatrixavx2.h

-33
This file was deleted.

src/arch/intsimdmatrixsse.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// limitations under the License.
1616
///////////////////////////////////////////////////////////////////////
1717

18-
#include "intsimdmatrixsse.h"
18+
#include "intsimdmatrix.h"
1919

2020
#include <cstdint>
2121
#include "dotproductsse.h"
@@ -33,13 +33,12 @@ static void PartialMatrixDotVector1(const int8_t* wi, const double* scales,
3333
}
3434
#endif // __SSE4_1__
3535

36-
IntSimdMatrixSSE::IntSimdMatrixSSE()
3736
#ifdef __SSE4_1__
38-
: IntSimdMatrix(1, 1, 1, 1, 1, {PartialMatrixDotVector1})
37+
const IntSimdMatrix IntSimdMatrix::IntSimdMatrixSSE =
38+
IntSimdMatrix(1, 1, 1, 1, 1, {PartialMatrixDotVector1});
3939
#else
40-
: IntSimdMatrix(1, 1, 1, 1, 1, {})
40+
const IntSimdMatrix IntSimdMatrix::IntSimdMatrixSSE =
41+
IntSimdMatrix(1, 1, 1, 1, 1, {});
4142
#endif // __SSE4_1__
42-
{
43-
}
4443

4544
} // namespace tesseract.

src/arch/intsimdmatrixsse.h

-32
This file was deleted.

src/lstm/weightmatrix.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void WeightMatrix::ConvertToInt() {
143143
}
144144
wf_.Resize(1, 1, 0.0);
145145
int_mode_ = true;
146-
multiplier_.reset(IntSimdMatrix::GetFastestMultiplier());
146+
multiplier_ = IntSimdMatrix::GetFastestMultiplier();
147147
multiplier_->Init(wi_, shaped_w_);
148148
}
149149

@@ -196,7 +196,7 @@ bool WeightMatrix::DeSerialize(bool training, TFile* fp) {
196196
if (int_mode_) {
197197
if (!wi_.DeSerialize(fp)) return false;
198198
if (!scales_.DeSerialize(fp)) return false;
199-
multiplier_.reset(IntSimdMatrix::GetFastestMultiplier());
199+
multiplier_ = IntSimdMatrix::GetFastestMultiplier();
200200
multiplier_->Init(wi_, shaped_w_);
201201
} else {
202202
if (!wf_.DeSerialize(fp)) return false;

src/lstm/weightmatrix.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class TransposedArray : public GENERIC_2D_ARRAY<double> {
6464
// backward steps with the matrix and updates to the weights.
6565
class WeightMatrix {
6666
public:
67-
WeightMatrix() : int_mode_(false), use_adam_(false) {}
67+
WeightMatrix() : int_mode_(false), use_adam_(false), multiplier_(nullptr) {}
6868
// Sets up the network for training. Initializes weights using weights of
6969
// scale `range` picked according to the random number generator `randomizer`.
7070
// Note the order is outputs, inputs, as this is the order of indices to
@@ -179,7 +179,7 @@ class WeightMatrix {
179179
// The weights matrix reorganized in whatever way suits this instance.
180180
std::vector<int8_t> shaped_w_;
181181
// Holds the optimal integer multiplier for this machine.
182-
std::unique_ptr<const IntSimdMatrix> multiplier_;
182+
const IntSimdMatrix* multiplier_;
183183
};
184184

185185
} // namespace tesseract.

unittest/intsimdmatrix_test.cc

+10-15
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
#include <memory>
1919
#include "genericvector.h"
2020
#include "include_gunit.h"
21-
#include "intsimdmatrixavx2.h"
22-
#include "intsimdmatrixsse.h"
2321
#include "matrix.h"
2422
#include "simddetect.h"
2523
#include "tprintf.h"
@@ -56,21 +54,21 @@ class IntSimdMatrixTest : public ::testing::Test {
5654
}
5755
return v;
5856
}
59-
// Tests a range of sizes and compares the results against the base_ version.
60-
void ExpectEqualResults(const IntSimdMatrix* matrix) {
57+
// Tests a range of sizes and compares the results against the generic version.
58+
void ExpectEqualResults(const IntSimdMatrix& matrix) {
6159
double total = 0.0;
6260
for (int num_out = 1; num_out < 130; ++num_out) {
6361
for (int num_in = 1; num_in < 130; ++num_in) {
6462
GENERIC_2D_ARRAY<int8_t> w = InitRandom(num_out, num_in + 1);
65-
std::vector<int8_t> u = RandomVector(num_in, *matrix);
63+
std::vector<int8_t> u = RandomVector(num_in, matrix);
6664
GenericVector<double> scales = RandomScales(num_out);
6765
std::vector<double> base_result(num_out);
6866
std::vector<int8_t> dummy;
69-
base_.MatrixDotVector(w, dummy, scales, u.data(), base_result.data());
67+
IntSimdMatrix::IntSimdMatrixNative.MatrixDotVector(w, dummy, scales, u.data(), base_result.data());
7068
std::vector<double> test_result(num_out);
7169
std::vector<int8_t> shaped_wi;
72-
matrix->Init(w, shaped_wi);
73-
matrix->MatrixDotVector(w, shaped_wi, scales, u.data(), test_result.data());
70+
matrix.Init(w, shaped_wi);
71+
matrix.MatrixDotVector(w, shaped_wi, scales, u.data(), test_result.data());
7472
for (int i = 0; i < num_out; ++i) {
7573
EXPECT_FLOAT_EQ(base_result[i], test_result[i]) << "i=" << i;
7674
total += base_result[i];
@@ -82,13 +80,12 @@ class IntSimdMatrixTest : public ::testing::Test {
8280
}
8381

8482
TRand random_;
85-
IntSimdMatrix base_ = IntSimdMatrix(1, 1, 1, 1, 1, {});
8683
};
8784

8885
// Test the C++ implementation without SIMD.
8986
TEST_F(IntSimdMatrixTest, C) {
90-
std::unique_ptr<IntSimdMatrix> matrix(new IntSimdMatrix());
91-
ExpectEqualResults(matrix.get());
87+
static const IntSimdMatrix matrix(1, 1, 1, 1, 1, {});
88+
ExpectEqualResults(matrix);
9289
}
9390

9491
// Tests that the SSE implementation gets the same result as the vanilla.
@@ -99,8 +96,7 @@ TEST_F(IntSimdMatrixTest, SSE) {
9996
tprintf("No SSE found! Not Tested!");
10097
return;
10198
}
102-
std::unique_ptr<IntSimdMatrix> matrix(new IntSimdMatrixSSE());
103-
ExpectEqualResults(matrix.get());
99+
ExpectEqualResults(IntSimdMatrix::IntSimdMatrixSSE);
104100
}
105101

106102
// Tests that the AVX2 implementation gets the same result as the vanilla.
@@ -111,8 +107,7 @@ TEST_F(IntSimdMatrixTest, AVX2) {
111107
tprintf("No AVX2 found! Not Tested!");
112108
return;
113109
}
114-
std::unique_ptr<IntSimdMatrix> matrix(new IntSimdMatrixAVX2());
115-
ExpectEqualResults(matrix.get());
110+
ExpectEqualResults(IntSimdMatrix::IntSimdMatrixAVX2);
116111
}
117112

118113
} // namespace

0 commit comments

Comments
 (0)