Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Architecture update #6

Merged
merged 11 commits into from
Apr 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions source/cpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ add_library(cpu semi_local.h
# disable vectorization: -fno-tree-vectorize

#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O0 -fopenmp -fno-tree-vectorize -fopt-info-vec-optimized-optimized -fopt-info-vec-optimized-all")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -fopenmp -march=native -O3 " )# ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -fopenmp -march=native -O1 " )# ")
# -I /home/garrancha/libs/boost_1_75_0/ -for boost libary
#add_executable(main main.cpp)
#target_link_libraries(main cpu)
Expand Down Expand Up @@ -81,13 +81,29 @@ add_executable(braid_multiplication_sequential_memory cpu_impl/braid_multiplicat
add_executable(braid_multiplication_sequential_precompute cpu_impl/braid_multiplication_sequential_precompute.cpp)
#


find_package(GTest REQUIRED )
include_directories(${GTEST_INCLUDE_DIRS})

add_executable(
ApproximateMatchingTest
test/ApproximateMatchingTest.cpp
)
target_link_libraries(ApproximateMatchingTest GTest::gtest GTest::gtest_main cpu )
target_include_directories(ApproximateMatchingTest PUBLIC cpu ${GTEST_INCLUDE_DIRS} )


function(generateTest testName executableName files)

add_executable(${executableName} ${files})
target_include_directories(${executableName} PUBLIC ${PROJECT_NAME} ${GTEST_INCLUDE_DIRS})
target_link_libraries(${executableName} GTest::gtest GTest::gtest_main ${PROJECT_NAME})
add_test(${testName} ${executableName})
endfunction()

generateTest(ApproximateMatching ApproximateMatchingTest test/ApproximateMatchingTest.cpp)

generateTest(SemiLocalLCS SemiLocalLCSTest test/SemiLocalLCS/SemiLocalLCSTest.cpp)

generateTest(StradyAnt StradyAntTest test/MongeMatrixMultiplication/SteadyAntTest.cpp)


generateTest(LCS LCSTest test/LCS/LCSTest.cpp)

#target_link_libraries(ApproximateMatchingTest GTest::gtest GTest::gtest_main cpu )
#target_include_directories(ApproximateMatchingTest PUBLIC cpu ${GTEST_INCLUDE_DIRS} )

147 changes: 147 additions & 0 deletions source/cpu/common/include/Permutations/DominanceSum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@

#include "Matrices.h"

namespace common {

enum Arrow {
TOP_LEFT,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTMO_RIGHT
};
enum Move {
LEFT,
UP,
DOWN,
RIGHT
};

/**
* Provides ability to perform incremental queries
*/
class IncrementalDominanceSum {


public:
/**
* @tparam arrow
* @tparam moveAction
* @param row
* @param col
* @param sum
* @param permMatrix
* @return
*/
template<Arrow arrow, Move moveAction,typename T>
static int move(int row, int col, int sum, const T &permMatrix) noexcept {
if constexpr(arrow == TOP_LEFT) {
if constexpr(moveAction == LEFT) {
if (col == 0) return sum;
auto rowCap = permMatrix.getRowByCol(col - 1);
if (rowCap >= row && rowCap != NOPOINT) sum++;
return sum;
}
if constexpr(moveAction == DOWN) {
if (row >= permMatrix.rows) return 0;
auto colCap = permMatrix.getColByRow(row);
if (colCap >= col && colCap != NOPOINT) sum--;
return sum;
}
if constexpr(moveAction == UP) {
if (row == 0) return sum;
auto colCap = permMatrix.getColByRow(row - 1);
if (colCap >= col && colCap != NOPOINT) sum++;
return sum;
}
if constexpr(moveAction == RIGHT) {
if (col >= permMatrix.cols) return 0;
auto rowCap = permMatrix.getRowByCol(col);
if (rowCap >= row && rowCap != NOPOINT) sum--;
return sum;
}
}

if constexpr(arrow == BOTTMO_RIGHT) {
if constexpr(moveAction == LEFT) {
if (col == 0) return sum;
auto rowCap = permMatrix.getRowByCol(col - 1);

if (rowCap != NOPOINT && rowCap < row) sum--;
return sum;
}
if constexpr(moveAction == DOWN) {
if (row >= permMatrix.rows) return 0;
auto colCap = permMatrix.getColByRow(row);
if (colCap < col && colCap != NOPOINT) sum++;
return sum;
}
if constexpr(moveAction == UP) {
if (row == 0) return sum;
auto colCap = permMatrix.getColByRow(row - 1);
if (colCap < col && colCap != NOPOINT) sum--;
return sum;
}
if constexpr(moveAction == RIGHT) {
if (col >= permMatrix.cols) return 0;
auto rowCap = permMatrix.getRowByCol(col);
if (rowCap < row && rowCap != NOPOINT) sum++;
return sum;
}
}

if constexpr(arrow == TOP_RIGHT) {
if constexpr(moveAction == LEFT) {
if (col == 0) return sum;
auto rowCap = permMatrix.getRowByCol(col - 1);
if (rowCap >= row && rowCap != NOPOINT) sum--;
return sum;
}
if constexpr(moveAction == DOWN) {
if (row >= permMatrix.rows) return 0;
auto colCap = permMatrix.getColByRow(row);
if (colCap < col && colCap != NOPOINT) sum--;
return sum;
}
if constexpr(moveAction == UP) {
if (row == 0) return sum;
auto colCap = permMatrix.getColByRow(row - 1);
if (colCap < col && colCap != NOPOINT) sum++;
return sum;
}
if constexpr(moveAction == RIGHT) {
if (col >= permMatrix.cols) return 0;
auto rowCap = permMatrix.getRowByCol(col);

if (rowCap >= row && rowCap != NOPOINT) sum++;
return sum;
}
}
}
};

/**
* Get dominance matrix of specified func operator( could left/right bottom/top arrow) from permutations matrix m
* @tparam Lambda
* @param m
* @param func
* @param outputDominanceMatrix
*/
template<typename Lambda>
inline void getDominanceSum(const Permutation &m, Lambda &&func, Matrix &outputDominanceMatrix) {
auto row_size = m.rows + 1;
auto col_size = m.cols + 1;

for (int row = 0; row < row_size; ++row) {
for (int col = 0; col < col_size; ++col) {
for (int i = 0; i < m.rows; ++i) {
auto row_pos_point = i;
auto col_pos_point = m.getColByRow(row_pos_point);
if (col_pos_point == NOPOINT) continue;
if (func(row_pos_point, col_pos_point, row, col) == true)
outputDominanceMatrix.setElementAt(row, col, outputDominanceMatrix.getElementAt(row, col) + 1);
}
}
}
}

};
175 changes: 175 additions & 0 deletions source/cpu/common/include/Permutations/Matrices.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#pragma once


#include <memory>

#define NOPOINT (-1) /*NOPOINT indicates that no non-zero element in matrix in specified position*/

namespace common {

/**
* Implementation of a permutation matrix is based on two arrays:
* the first array is mapping of non-zero entries in rows to its position in cols
* the second array is mapping of non-zero entries in cols to its position in rows
* Memory freed outised of class.
*/
class Permutation {
public:
Permutation() = default;
~Permutation() = default;
Permutation(int row, int col) :rows(row), cols(col) {
rowToCol.resize(row);
std::fill(rowToCol.begin(), rowToCol.end(), NOPOINT);
colToRow.resize(col);
std::fill(colToRow.begin(),colToRow.end(),NOPOINT);
};


bool operator==(const Permutation &other) const {
if (other.rows != rows || other.cols != cols) return false;
for (int i = 0; i < rows; ++i) if (getColByRow(i) != other.getColByRow(i)) return false;
for (int i = 0; i < cols; ++i) if (getRowByCol(i) != other.getRowByCol(i)) return false;
return true;
}


void fromPoints(const std::vector<std::pair<int, int>> &points) {
rows = points.size();
cols = points.size();
rowToCol.resize(points.size());
colToRow.resize(points.size());
for (auto &point: points) {
rowToCol[point.first] = point.second;
colToRow[point.second] = point.first;
}
}

/**
*
* Fills input vector with position pairs of non-zero entries in the current matrix aka (row_i,col_i)
* @param result std::vector<std::pair<int,int>>
* @return void
* NOTICE for square matrix only
*/
void toPoints(std::vector<std::pair<int, int>> &result) const {
for (int i = 0; i < cols; ++i) {
auto col = getColByRow(i);
if (col != NOPOINT) result.emplace_back(i, col);
}
}

inline void set(int row, int col) {
rowToCol[row] = col;
colToRow[col] = row;
}

inline void reset(int row, int col) {
if (rowToCol[col] == col) {
rowToCol[col] = NOPOINT;
colToRow[row] = NOPOINT;
}
}

int getElementAt(int row, int col) const { return (getColByRow(row) == col) ? 1 : 0; }


inline void resetAll() {
std::fill(rowToCol.begin(),rowToCol.end(),NOPOINT);
std::fill(colToRow.begin(),colToRow.end(),NOPOINT);
}

inline int getRowByCol(int col) const { return colToRow[col]; }

inline int getColByRow(int row) const { return rowToCol[row]; }




//TODO after refactoring move to sep instance
int m = 0;
int n = 0;
int rows;
int cols;
private:
std::vector<int> rowToCol;
std::vector<int> colToRow;
};

/**
* The class presents a simple 2d matrix with integer value entities. Used primarily for testing
*/
class Matrix {
private:
std::vector<int> arr;
public:

Matrix(int row_size, int col_size) {
rows = row_size;
cols = col_size;
arr.resize(row_size * col_size, 0);
}

int getElementAt(int row, int col) const { return arr[row * cols + col]; }

inline void setElementAt(int row, int col, int value) { arr[row * cols + col] = value; }

void getCrossDiffPermutation(Permutation &perm){
perm = Permutation(rows - 1, cols - 1);
for (int i = 0; i < rows - 1; ++i) {
for (int j = 0; j < cols - 1; ++j) {
auto crossDiff = (getElementAt(i, j + 1) + getElementAt(i + 1, j)) - (getElementAt(i, j) + getElementAt(i + 1, j + 1));
if (crossDiff == 1) perm.set(i, j);
}
}
}


int rows;
int cols;
};

/**
* Fill given zero permutation matrix randomly by given seed
* @param m
* @param rowSize
* @param colSize
* @param seed
*/
inline void fillPermutationMatrix(Permutation &m, int rowSize, int colSize) {

auto isUsed = new bool[colSize];
for (int i = 0; i < colSize; ++i) isUsed[i] = false;

auto activePts = colSize;

for (int row = 0; row < rowSize && activePts > 0; ++row) {
while (true) {
auto col = abs(rand()) % colSize;
if (!isUsed[col]) {
m.set(row, col);
isUsed[col] = true;
break;
}
}
activePts--;
}

delete[] isUsed;
}



template<typename Perm>
inline void debugPrint(const Perm& perm,std::ostream &os) {
for (int i = 0; i < perm.rows; ++i) {
for (int j = 0; j < perm.cols; ++j) {
os << perm.getElementAt(i, j);
}
os << std::endl;
}
}

}



Loading