Skip to content

Commit 479004f

Browse files
committed
Add namespaces fp and matrix
1 parent c31ac6d commit 479004f

3 files changed

Lines changed: 75 additions & 63 deletions

File tree

include/gemmi.hpp

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* Floating-point traits and functions *
2222
***************************************/
2323

24+
namespace fp {
25+
2426
/**
2527
* @brief Traits describing IEEE-754 layout properties for a floating-point type.
2628
*
@@ -67,6 +69,8 @@ int getStoredFloatingPointExponent(fp_t value) {
6769
std::max(std::numeric_limits<fp_t>::min_exponent, std::ilogb(std::abs(value)) + 1);
6870
}
6971

72+
} // namespace fp
73+
7074
/******************************
7175
* Global configuration enums *
7276
******************************/
@@ -83,6 +87,8 @@ enum class normalisationDimension {
8387
* Matrix view *
8488
***************/
8589

90+
namespace matrix {
91+
8692
/**
8793
* @brief Enum to specify the layout of the matrix in memory.
8894
*/
@@ -284,6 +290,8 @@ MatrixView<const value_t> makeConstMatrixView(MatrixView<value_t> view) {
284290
return MatrixView<const value_t>(view.data, view.rows, view.cols, view.layout);
285291
}
286292

293+
} // namespace matrix
294+
287295
/***********************
288296
* Multiterm emulation *
289297
***********************/
@@ -412,8 +420,8 @@ struct DerivedParameters {
412420
* @throws std::invalid_argument if any runtime constraint is violated.
413421
*/
414422
template <typename fp_t, typename splitint_t, typename accumulator_t>
415-
DerivedParameters deriveParameters(MatrixView<const fp_t> A,
416-
MatrixView<const fp_t> B,
423+
DerivedParameters deriveParameters(matrix::MatrixView<const fp_t> A,
424+
matrix::MatrixView<const fp_t> B,
417425
const config& config) {
418426

419427
// Compile-time type checks.
@@ -501,7 +509,7 @@ struct OperandPreparationConfig {
501509
*/
502510
template <typename splitint_t, typename fp_t>
503511
struct preparedOperand {
504-
MatrixView<const fp_t> matrix; ///< View of original matrix.
512+
matrix::MatrixView<const fp_t> matrix; ///< View of original matrix.
505513
OperandPreparationConfig prepConfig; ///< Configuration for operand preparation.
506514

507515
std::vector<splitint_t> memory; ///< Memory to store the split slices.
@@ -644,7 +652,7 @@ void computeNormalisationVectors(preparedOperand<splitint_t, fp_t>& operand) {
644652
// NOTE 1: This is not the technique used in uoi24.
645653
// NOTE 2: I use exponents instead of powers of 2, as I need the former
646654
// to shift correctly.
647-
operand.scalingExponents[outer] = getStoredFloatingPointExponent(operand.powersVector[outer]);
655+
operand.scalingExponents[outer] = fp::getStoredFloatingPointExponent(operand.powersVector[outer]);
648656
operand.powersVector[outer] = std::ldexp(1.0, operand.scalingExponents[outer]);
649657
}
650658
}
@@ -656,18 +664,21 @@ void computeNormalisationVectors(preparedOperand<splitint_t, fp_t>& operand) {
656664
* matrix, which is used in the splitting algorithms. It extracts the significand
657665
* and sign of each element in the row/column, and stores them in the provided vectors.
658666
*
667+
* The `fraction` and `sign` vectors must be pre-sized to `operand.innerDimension()`
668+
* before calling this function.
669+
*
659670
* @tparam splitint_t Type used to store the integer slices.
660671
* @tparam fp_t Floating-point type of the matrix elements.
661672
* @param fraction Vector to store the fixed-point representation of the elements.
662673
* @param sign Vector to store the signs of the elements.
663674
* @param i The index of the row/column for which to compute the fixed-point representation.
664675
*/
665676
template <typename splitint_t, typename fp_t>
666-
void computeFixedPointRepresentationVector(std::vector<typename FloatingPointTraits<fp_t>::StorageType> &fraction,
677+
void computeFixedPointRepresentationVector(std::vector<typename fp::FloatingPointTraits<fp_t>::StorageType> &fraction,
667678
std::vector<bool> &sign, size_t outer,
668679
const preparedOperand<splitint_t, fp_t>& operand) {
669-
using uint_t = typename FloatingPointTraits<fp_t>::StorageType;
670-
constexpr size_t numSignificandBits = FloatingPointTraits<fp_t>::numSignificandBits;
680+
using uint_t = typename fp::FloatingPointTraits<fp_t>::StorageType;
681+
constexpr size_t numSignificandBits = fp::FloatingPointTraits<fp_t>::numSignificandBits;
671682
for (size_t inner = 0; inner < operand.innerDimension(); inner++) {
672683
fp_t value = operand.operand(outer, inner);
673684
fraction[inner] = std::bit_cast<uint_t>(value);
@@ -696,10 +707,10 @@ void computeFixedPointRepresentationVector(std::vector<typename FloatingPointTra
696707
*/
697708
template <typename splitint_t, typename fp_t>
698709
void computeSplitsWithTruncation(preparedOperand<splitint_t, fp_t>& operand) {
699-
using uint_t = typename FloatingPointTraits<fp_t>::StorageType;
710+
using uint_t = typename fp::FloatingPointTraits<fp_t>::StorageType;
700711

701712
// Compute splits one row/column at a time.
702-
constexpr size_t numSignificandBits = FloatingPointTraits<fp_t>::numSignificandBits;
713+
constexpr size_t numSignificandBits = fp::FloatingPointTraits<fp_t>::numSignificandBits;
703714
auto bitsPerSlice = operand.prepConfig.bitsPerSlice;
704715
std::vector<uint_t> fraction (operand.innerDimension());
705716
std::vector<bool> sign (operand.innerDimension());
@@ -714,7 +725,7 @@ void computeSplitsWithTruncation(preparedOperand<splitint_t, fp_t>& operand) {
714725
for (size_t inner = 0; inner < operand.innerDimension(); inner++) {
715726
// NOTE: I could have a special path for 0.
716727
int16_t shiftCounter = numSignificandBits - bitsPerSlice;
717-
int currentExponent = getStoredFloatingPointExponent(operand.operand(outer, inner));
728+
int currentExponent = fp::getStoredFloatingPointExponent(operand.operand(outer, inner));
718729
int16_t exponentDifference = operand.scalingExponents[outer] - currentExponent;
719730
for (size_t slice = 0; slice < operand.prepConfig.numSplits; slice++) {
720731
if (exponentDifference > (signed)bitsPerSlice) {
@@ -755,11 +766,11 @@ void computeSplitsWithTruncation(preparedOperand<splitint_t, fp_t>& operand) {
755766
*/
756767
template <typename splitint_t, typename fp_t>
757768
void computeSplitsWithUnsignedEncoding(preparedOperand<splitint_t, fp_t>& operand) {
758-
using uint_t = typename FloatingPointTraits<fp_t>::StorageType;
769+
using uint_t = typename fp::FloatingPointTraits<fp_t>::StorageType;
759770
using wideint_t = std::conditional_t<(sizeof(splitint_t) < sizeof(int)), int, std::intmax_t>;
760771

761772
// Compute splits one row/column at a time.
762-
constexpr size_t numSignificandBits = FloatingPointTraits<fp_t>::numSignificandBits;
773+
constexpr size_t numSignificandBits = fp::FloatingPointTraits<fp_t>::numSignificandBits;
763774
auto bitsPerSlice = operand.prepConfig.bitsPerSlice;
764775
std::vector<uint_t> fraction (operand.innerDimension());
765776
std::vector<bool> sign (operand.innerDimension());
@@ -786,7 +797,7 @@ void computeSplitsWithUnsignedEncoding(preparedOperand<splitint_t, fp_t>& operan
786797

787798
// NOTE: I could have a special path for 0.
788799
int16_t shiftCounter;
789-
int currentExponent = getStoredFloatingPointExponent(operand.operand(outer, inner));
800+
int currentExponent = fp::getStoredFloatingPointExponent(operand.operand(outer, inner));
790801
int16_t exponentDifference = operand.scalingExponents[outer] - currentExponent;
791802

792803
splitint_t value = 0;
@@ -914,7 +925,7 @@ void computeSplitsWithRoundToNearest(preparedOperand<splitint_t, fp_t>& operand)
914925
for (size_t outer = 0; outer < operand.outerDimension(); outer++) {
915926
// Compute exponent in signed arithmetic to avoid wraparound when
916927
// bitsPerSlice * (slice + 1) approaches numSignificandBits.
917-
int exponent = static_cast<int>(FloatingPointTraits<fp_t>::numSignificandBits) - static_cast<int>(bitsPerSlice * (slice + 1)) + 1;
928+
int exponent = static_cast<int>(fp::FloatingPointTraits<fp_t>::numSignificandBits) - static_cast<int>(bitsPerSlice * (slice + 1)) + 1;
918929
fp_t sigma = std::ldexp(0.75, exponent) * operand.powersVector[outer];
919930
for (size_t inner = 0; inner < operand.innerDimension(); inner++) {
920931
auto matrixIndex = operand.operandIndex(outer, inner);
@@ -934,7 +945,7 @@ void computeSplitsWithRoundToNearest(preparedOperand<splitint_t, fp_t>& operand)
934945
* @tparam fp_t Floating-point type of the matrix elements.
935946
*/
936947
template <typename splitint_t, typename fp_t>
937-
preparedOperand<splitint_t, fp_t> prepareOperand(MatrixView<const fp_t> matrix,
948+
preparedOperand<splitint_t, fp_t> prepareOperand(matrix::MatrixView<const fp_t> matrix,
938949
const OperandPreparationConfig& prepConfig) {
939950
preparedOperand<splitint_t, fp_t> operand;
940951
operand.matrix = matrix;
@@ -1032,6 +1043,7 @@ inline multiplicationSchedule makeSchedule(const config& config) {
10321043

10331044
return schedule;
10341045
}
1046+
10351047
/**
10361048
* @brief Compute the exact integer GEMM (General Matrix-Matrix Multiplication).
10371049
*
@@ -1048,11 +1060,11 @@ template <typename splitint_t, typename accumulator_t, typename fp_t>
10481060
void computeExactIntegerGEMM(const preparedOperand<splitint_t, fp_t> &A,
10491061
const preparedOperand<splitint_t, fp_t> &B,
10501062
std::vector<accumulator_t> &C,
1051-
const matrixLayout layoutC,
1063+
const matrix::matrixLayout layoutC,
10521064
size_t iBlock, size_t jBlock) {
10531065
for (size_t row = 0; row < A.rows(); row++) {
10541066
for (size_t col = 0; col < B.cols(); col++) {
1055-
auto index = (layoutC == matrixLayout::columnMajor) ? (row + col * A.rows()) : (col + row * B.cols());
1067+
auto index = (layoutC == matrix::matrixLayout::columnMajor) ? (row + col * A.rows()) : (col + row * B.cols());
10561068
for (size_t ell = 0; ell < A.innerDimension(); ell++) {
10571069
C[index] += A.splitValue(row, ell, iBlock) * B.splitValue(col, ell, jBlock);
10581070
}
@@ -1084,7 +1096,7 @@ template <typename splitint_t, typename accumulator_t, typename fp_t>
10841096
std::vector<fp_t> computeProductsWithFloatingPointAccumulation(const preparedOperand<splitint_t, fp_t> &A,
10851097
const preparedOperand<splitint_t, fp_t> &B,
10861098
const multiplicationSchedule &schedule,
1087-
const matrixLayout layoutC) {
1099+
const matrix::matrixLayout layoutC) {
10881100
auto numSplitsA = A.prepConfig.numSplits;
10891101
auto numSplitsB = B.prepConfig.numSplits;
10901102
std::vector<fp_t> C (A.rows() * B.cols(), 0.0);
@@ -1098,7 +1110,7 @@ std::vector<fp_t> computeProductsWithFloatingPointAccumulation(const preparedOpe
10981110
computeExactIntegerGEMM<splitint_t, accumulator_t, fp_t>(A, B, accumulator, layoutC, Aindex, Bindex);
10991111
for (size_t row = 0; row < A.rows(); row++) {
11001112
for (size_t col = 0; col < B.cols(); col++) {
1101-
auto index = (layoutC == matrixLayout::columnMajor) ? (row + col * A.rows()) : (col + row * B.cols());
1113+
auto index = (layoutC == matrix::matrixLayout::columnMajor) ? (row + col * A.rows()) : (col + row * B.cols());
11021114
fp_t scaledSum = std::ldexp(static_cast<fp_t>(accumulator[index]), -totalShift);
11031115
fp_t scalingFactor = A.powersVector[row] * B.powersVector[col];
11041116
C[index] += scaledSum * scalingFactor;
@@ -1137,7 +1149,7 @@ template <typename splitint_t, typename accumulator_t, typename fp_t>
11371149
std::vector<fp_t> computeProductsWithIntegerAccumulation(const preparedOperand<splitint_t, fp_t> &A,
11381150
const preparedOperand<splitint_t, fp_t> &B,
11391151
const multiplicationSchedule &schedule,
1140-
const matrixLayout layoutC) {
1152+
const matrix::matrixLayout layoutC) {
11411153
auto numSplitsA = A.prepConfig.numSplits;
11421154
auto numSplitsB = B.prepConfig.numSplits;
11431155

@@ -1160,7 +1172,7 @@ std::vector<fp_t> computeProductsWithIntegerAccumulation(const preparedOperand<s
11601172
// Scale the accumulated products and accumulate in floating-point arithmetic across diagonals.
11611173
for (size_t row = 0; row < A.rows(); row++) {
11621174
for (size_t col = 0; col < B.cols(); col++) {
1163-
auto index = (layoutC == matrixLayout::columnMajor) ? (row + col * A.rows()) : (col + row * B.cols());
1175+
auto index = (layoutC == matrix::matrixLayout::columnMajor) ? (row + col * A.rows()) : (col + row * B.cols());
11641176
fp_t scaledSum = std::ldexp(static_cast<fp_t>(accumulator[index]), -totalShift);
11651177
fp_t scalingFactor = A.powersVector[row] * B.powersVector[col];
11661178
C[index] += scaledSum * scalingFactor;
@@ -1191,15 +1203,15 @@ std::vector<fp_t> computeProductsWithIntegerAccumulation(const preparedOperand<s
11911203
* @return Resulting matrix product.
11921204
*/
11931205
template <typename fp_t, typename splitint_t, typename accumulator_t>
1194-
std::vector<fp_t> gemmi (const std::vector<fp_t> &A, const matrixLayout layoutA,
1195-
const std::vector<fp_t> &B, const matrixLayout layoutB,
1206+
std::vector<fp_t> gemmi (const std::vector<fp_t> &A, const matrix::matrixLayout layoutA,
1207+
const std::vector<fp_t> &B, const matrix::matrixLayout layoutB,
11961208
const size_t m, const size_t k, const size_t n,
1197-
const matrixLayout layoutC,
1209+
const matrix::matrixLayout layoutC,
11981210
const multiterm::config &config) {
11991211

12001212
// Build matrix views.
1201-
auto viewA = makeMatrixView(A, m, k, layoutA);
1202-
auto viewB = makeMatrixView(B, k, n, layoutB);
1213+
auto viewA = matrix::makeMatrixView(A, m, k, layoutA);
1214+
auto viewB = matrix::makeMatrixView(B, k, n, layoutB);
12031215

12041216
// Validate inputs and derive execution parameters.
12051217
auto derivedParameters = multiterm::deriveParameters<fp_t, splitint_t, accumulator_t>(viewA, viewB, config);
@@ -1226,11 +1238,11 @@ std::vector<fp_t> gemmi (const std::vector<fp_t> &A, const matrixLayout layoutA,
12261238
}
12271239

12281240
template <typename fp_t, typename splitint_t, typename accumulator_t>
1229-
std::vector<fp_t> gemmi (const std::vector<fp_t> &A, const matrixLayout layoutA,
1230-
const std::vector<fp_t> &B, const matrixLayout layoutB,
1241+
std::vector<fp_t> gemmi (const std::vector<fp_t> &A, const matrix::matrixLayout layoutA,
1242+
const std::vector<fp_t> &B, const matrix::matrixLayout layoutB,
12311243
const size_t m, const size_t k, const size_t n, const size_t numSplits) {
12321244
return gemmi <fp_t, splitint_t, accumulator_t> (A, layoutA, B, layoutB, m, k, n,
1233-
matrixLayout::columnMajor,
1245+
matrix::matrixLayout::columnMajor,
12341246
multiterm::config{numSplits, numSplits,
12351247
multiterm::splittingStrategy::roundToNearest,
12361248
multiterm::multiplicationStrategy::reduced,

0 commit comments

Comments
 (0)