diff --git a/CMakeLists.txt b/CMakeLists.txt index cf098afa..16f5100d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,12 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -find_package (Eigen3 3.3.7 REQUIRED NO_MODULE) -message(STATUS "Found Eigen3 in: ${Eigen3_DIR}") +find_package (Eigen3 3.3.7 QUIET NO_MODULE) + +if (Eigen3_FOUND) + message(STATUS "Found Eigen3: ${Eigen3_DIR}") + add_definitions(-DEIGEN_FOUND) +endif() set(CMAKE_CXX_STANDARD 17 CACHE STRING "") diff --git a/README.md b/README.md index 681ea482..4b21cce3 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ If you're a C++ developer and require low-level control, optimization, or integr * GNU Make (4.2.1) * LLVM (17.0.6) - [src](https://github.com/llvm/llvm-project/tree/release/17.x), [release](https://releases.llvm.org/download.html#17.0.6) * Support for latest LLVM versions would be added soon -* Eigen library (3.3.7) +* Eigen library (3.3.7) (Optional) * Python (3.6.7) * Other python requirements * For training the vocabulary are available in [seed_embeddings/OpenKE/requirements.txt](./seed_embeddings/OpenKE/requirements.txt), and diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e8f5521a..e4c7adaa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,7 +30,9 @@ if(NOT LLVM_IR2VEC) add_library(objlib OBJECT ${libsrc}) set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1) - target_link_libraries (objlib Eigen3::Eigen) + if(Eigen3_FOUND) + target_link_libraries (objlib Eigen3::Eigen) + endif() add_library(${IR2VEC_LIB} SHARED $) add_library(${IR2VEC_LIB_STATIC} STATIC $) @@ -71,7 +73,9 @@ else() intrinsics_gen ) - target_link_libraries(LLVMIR2Vec PRIVATE Eigen3::Eigen) + if(Eigen3_FOUND) + target_link_libraries(LLVMIR2Vec PRIVATE Eigen3::Eigen) + endif() target_include_directories(LLVMIR2Vec PRIVATE ${LLVM_MAIN_INCLUDE_DIR}) target_include_directories(LLVMIR2Vec PRIVATE .) diff --git a/src/FlowAware.cpp b/src/FlowAware.cpp index 9e20ecad..bbf4664f 100644 --- a/src/FlowAware.cpp +++ b/src/FlowAware.cpp @@ -5,7 +5,11 @@ // file in the top-level directory for more details. // #include "FlowAware.h" +#ifdef EIGEN_FOUND +#include "VectorSolverEigen.h" +#else #include "VectorSolver.h" +#endif #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/MapVector.h" diff --git a/src/include/VectorSolverEigen.h b/src/include/VectorSolverEigen.h new file mode 100644 index 00000000..4ae901e2 --- /dev/null +++ b/src/include/VectorSolverEigen.h @@ -0,0 +1,63 @@ +// Copyright (c) 2021, S. VenkataKeerthy, Rohit Aggarwal +// Department of Computer Science and Engineering, IIT Hyderabad +// +// This software is available under the BSD 4-Clause License. Please see LICENSE +// file in the top-level directory for more details. +// +#ifndef __VECTOR_SOLVER_H__ +#define __VECTOR_SOLVER_H__ +#define EIGEN_MPL2_ONLY + +#include "Eigen/LU" +#include "Eigen/QR" +#include "llvm/ADT/SmallVector.h" +#include + +using namespace Eigen; +using namespace llvm; + +typedef std::vector> matrix; + +MatrixXd calculate(MatrixXd A, MatrixXd B) { + if (A.determinant() != 0) { + return A.fullPivHouseholderQr().solve(B); + } else { + // To-Do: perturb probabilities + llvm_unreachable("inconsistent/infinitely many solutions"); + } +} + +MatrixXd formMatrix(std::vector> a, int r, int l) { + MatrixXd M(r, l); + for (int i = 0; i < r; i++) + M.row(i) = VectorXd::Map(&a[i][0], a[i].size()); + + return M; +} + +matrix solve(matrix A, matrix B) { + int r = A.size(); + int c = A[0].size(); + MatrixXd mA(r, c); + mA = formMatrix(A, r, c); + + r = B.size(); + c = B[0].size(); + MatrixXd mB(r, c); + mB = formMatrix(B, r, c); + + r = A.size(); + MatrixXd x(r, c); + x = calculate(mA, mB); + std::vector> raw_data; + // raw_data.resize(x.rows()); + for (unsigned i = 0; i < x.rows(); i++) { + std::vector tmp; + tmp.resize(x.cols()); + VectorXd::Map(&tmp[0], x.cols()) = x.row(i); + raw_data.push_back(tmp); + } + return raw_data; +} + +#endif