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

WIP: Refactor #1

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1a5bd3a
Rename cpp files
vadithya1989 Sep 25, 2019
3ffff71
Merge branch 'master' into devel
vadithya1989 Nov 25, 2019
56d5044
unit test working
vadithya1989 Dec 9, 2019
d8fd172
using const Matrix wherever possible
vadithya1989 Dec 9, 2019
0e803fa
Readme first
vadithya1989 Dec 10, 2019
5792d2a
readme 2nd ver
vadithya1989 Dec 10, 2019
5b3e090
updated travis recipe
felipeZ Dec 10, 2019
7ad9120
removed atlas from travis
felipeZ Dec 10, 2019
ce71664
cloned elemental in TRAVIS HOME
felipeZ Dec 10, 2019
0ae3c8d
fixed typo downloading elemental
felipeZ Dec 10, 2019
5d42ab5
fixed typo cloning elemental
felipeZ Dec 10, 2019
652c341
used pure debug to build elemental
felipeZ Dec 10, 2019
5294bff
readme 3rd version
vadithya1989 Dec 10, 2019
1834da3
Merge branch 'devel' of https://github.com/NLESC-JCER/eigensolverElem…
vadithya1989 Dec 10, 2019
3ca3e0c
install dependencies from toolchain
felipeZ Dec 10, 2019
07fa96e
Merge branch 'devel' of https://github.com/NLESC-JCER/eigensolverElem…
felipeZ Dec 10, 2019
8cd549d
added gfortran
felipeZ Dec 10, 2019
86b6142
fixed typo
felipeZ Dec 10, 2019
86273ea
added gfortran_lib path
felipeZ Dec 10, 2019
7ef12f2
added install prefix
felipeZ Dec 10, 2019
3785829
defined gfortran path
felipeZ Dec 10, 2019
26dc711
check for gfortran
felipeZ Dec 10, 2019
33072f2
check for gfortran
felipeZ Dec 10, 2019
ed4d426
fixed typo installing elemental
felipeZ Dec 10, 2019
05a9d68
do not build C interface
felipeZ Dec 10, 2019
d19c6b1
do not build C interface
felipeZ Dec 10, 2019
49ea247
don't build blas
felipeZ Dec 10, 2019
a96ad1c
don't build parmetis
felipeZ Dec 10, 2019
f345865
dont build openblas
felipeZ Dec 10, 2019
e162dcd
output matrix size
vadithya1989 Dec 12, 2019
6d90055
added tolerence criterion
vadithya1989 Dec 16, 2019
583aedb
refactored eigenValueSolver.hpp
vadithya1989 Dec 17, 2019
82a3109
removed .vscode
vadithya1989 Dec 17, 2019
3337581
refactored initialize, subspaceProblem and expandSearchSpace until da…
vadithya1989 Dec 18, 2019
30ef296
fixed davidson correction, block implementation to be fixed
vadithya1989 Dec 18, 2019
76a7b2c
Completely refactored, davidson working. To do: 1. Use one V instead …
vadithya1989 Dec 30, 2019
fb7c4e9
Davison eigenvalue solver working with restart
vadithya1989 Jan 8, 2020
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ lib/

#clang
clang.sh

#visual studio
.vscode
25 changes: 20 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
sudo: true
sudo: false

language: cpp

os:
- linux

addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- cmake
- libblas-dev
- liblapack-dev
- gfortran-7
- libopenmpi-dev

dist: bionic

Expand All @@ -16,7 +24,14 @@ branches:
before_install:
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt-get update -q
- sudo apt-get install cmake libblas-dev liblapack-dev libopenmpi-dev
# Install elemental
- git clone --branch master git://github.com/elemental/Elemental.git ${HOME}/elemental
- ls /usr/lib/gcc/x86_64-linux-gnu/7
- |
cd ${HOME}/elemental &&
cmake -H. -Bbuild -DCMAKE_INSTALL_PREFIX=${HOME}/local -DCMAKE_Fortran_COMPILER=/usr/bin/gfortran-7 -DGFORTRAN_LIB=/usr/lib/gcc/x86_64-linux-gnu/7 -DEL_C_INTERFACE=OFF -DEL_BUILT_OPENBLAS=OFF &&
cmake --build build --target install
script:
- cmake -H. -Bbuild
- cmake --build build
- ctest --output-on-failure
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)
###############################################################################
# User input options
###############################################################################
option(ENABLE_TESTING "Build and enable tests" OFF)
option(ENABLE_TESTING "Build and enable tests" ON)
if(ENABLE_TESTING)
enable_testing()
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
endif(ENABLE_TESTING)

###############################################################################
# Dependencies
Expand Down
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Davidson Eigensolver
===================
This package contains a C++ implementation of the *Davidson diagonalization algorithms*.
Different schemas are available to compute the correction.

Available correction methods are:
* **davidson**: Diagonal-Preconditioned-Residue
* **jacobi**: Generalized Jacobi Davidson

### Note:
The Davidson method is suitable for **diagonal-dominant symmetric matrices**, that are quite common
in certain scientific problems like [electronic structure](https://en.wikipedia.org/wiki/Electronic_structure). The Davidson method could be not practical
for other kind of symmetric matrices.i

Usage
-----
The following program calls the `solve` *subroutine* from the `davidson` module and computes
the lowest eigenvalue and corresponding eigenvector, using the *jacobi* correction method with a tolerance of `1e-8`.
```C++
eigenSolver<real> solver;
solver.solverOptions.numberOfEigenValues = numEig;
solver.solverOptions.tolerence = 1e-8;
solver.solverOptions.solver = "jacobi";
solver.solverOptions.sizeOfTheMatrix = A.Height();
solver.solve(A, grid);
```

The helper `generateDDHermitianMatrix` function generates a diagonal dominant matrix.

**Variables**:
* `A` (*in*) matrix to diagonalize
* `solver.eigenValues` (*out*) resulting eigenvalues
* `solver.eigenVectorsFull` (*out*) resulting eigenvectors
* `solver.SolverOptions.solver`(*in*) Either "davidson" or "jacobi"
* `solver.solverOptions.tolerance`(*in*) Numerical tolerance for convergence

### References:
* [Davidson diagonalization method and its applications to electronic structure calculations](https://www.semanticscholar.org/paper/DAVIDSON-DIAGONALIZATION-METHOD-AND-ITS-APPLICATION-Liao/5811eaf768d1a006f505dfe24f329874a679ba59)
* [Numerical Methods for Large Eigenvalue Problem](https://doi.org/10.1137/1.9781611970739)

Installation and Testing
------------------------

To compile execute:
```
cmake -H. -Bbuild && cmake --build build
```

To run the test:
```
cmake -H. -Bbuild -DENABLE_TEST=ON && cmake --build build
cd build && ctest -V
```

Dependencies
------------
This packages assumes that you have installed the following packages:
* A C++ compiler >= C++ 14
* [CMake](https://cmake.org/)
* [Elemental] (https://github.com/elemental/Elemental)
3 changes: 2 additions & 1 deletion clang.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
clang-format -i src/*.cpp
clang-format -i src/*.cc
clang-format -i src/tests/*.cc
clang-format -i include/*.hpp
122 changes: 66 additions & 56 deletions include/eigenValueSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,71 +21,81 @@

namespace eigenValueSolver {

template <typename real> class eigenSolver {
template <typename real>
class eigenSolver {

public:
/**
* Groups all the options for the solvers
*/
public:
// Groups all the options for the solvers
struct options {
std::string solver = "davidson"; // either davidson or jacobi
real tolerence = 1e-8; /** tolerence for convergence*/
int numberOfEigenValues = 1; /** number of eigen values to be calculated*/
int sizeOfTheMatrix = 100; /**Size of the input matrix*/
// Type of solver used - either "davidson" or "jacobi"
std::string solver = "davidson";

// Tolerence criterion for convergence
real tolerence = 1e-8;

// The number of eigen values to be calculated
int numberOfEigenValues = 1;

// Size of the input matrix
int sizeOfTheMatrix = 100;
};

// MEMBER VARIABLES

// Eigenvector matrix of the reduced problem
El::DistMatrix<real> eigenVectors;

// ritzVectors i.e. eigen vectors of the full matrix
El::DistMatrix<real> ritzVectors;

// Eigenvalues
El::DistMatrix<real, El::VR, El::STAR> eigenValues;

// The guess eigenspace
El::DistMatrix<real> V;

// A*V
El::DistMatrix<real> AV;

// The guess eigenspace per iteration
El::DistMatrix<real> Vsub;

// The correction vector
El::DistMatrix<real> correctionVector;

// The residual
El::DistMatrix<real> residual;

// Instance of the options struct
options solverOptions;
/**
* This function computes the eigen value-vector pairs for the input matrix
*/
void solve(El::DistMatrix<real> &, El::Grid &);

private:
int columnsOfSearchSpace = solverOptions.numberOfEigenValues *
2; /**The columns of the search space*/
/*************Initialise all the matrices necessary**************/
El::DistMatrix<real> searchSpace; /**Matrix that holds the search space*/
El::DistMatrix<real> searchSpacesub; /**Matrix that holds the search space*/
El::DistMatrix<real> correctionVector; /**a matrix that holds the k guess
eigen vectors each of size nx1*/
El::DistMatrix<real>
eigenVectors; /**s stores the current eigenvector matrix*/
El::DistMatrix<real, El::VR, El::STAR>
eigenValues; /**vector of eigen values*/
El::DistMatrix<real, El::VR, El::STAR>
eigenValues_old; /**vector of eigen values*/

// MEMBER FUNCTIONS
// This function computes the eigen value-vector pairs for the input matrix
void solve(const El::DistMatrix<real> &, El::Grid &);

private:
// The size of the search space
real sizeOfSearchSpace;

// Range to loop over just the required number of eigenvalues in theta
El::Range<int> begTheta;
El::Range<int> endTheta;
// El::Range<int> begTheta{0, solverOptions.numberOfEigenValues};
// El::Range<int> endTheta{0, 1};

/**
* This function initialises all the required matrices
*/
void initialise(El::Grid &);

/**
*Calculates the residual
*/
void calculateResidual();

/**
*Calculates the correction vector
*/
void calculateCorrectionVector();

/**
*Expands the search space with the correction vector
*/
void expandSearchSpace(int, El::DistMatrix<real> &, El::Grid &);

/**
* solve the subspace problem i.e. VTAV and eigenvalue/vectors
*/
void subspaceProblem(int, El::DistMatrix<real> &, El::Grid &);

// This function initialises all the required matrices
void initialise(El::Grid &, const El::DistMatrix<real> &);

// Calculates the residual
bool calculateResidual(int, El::Grid &);

// Calculates the correction vector
void calculateCorrectionVector(int, const El::DistMatrix<real> &, El::Grid &);

// Expands the search space with the correction vector
void expandSearchSpace(int &, const El::DistMatrix<real> &, El::Grid &);

// Solve the subspace problem i.e. VTAV and eigenvalue/vectors
void subspaceProblem(int, const El::DistMatrix<real> &, El::Grid &);
};
} // namespace eigenValueSolver
} // namespace eigenValueSolver

#endif /* eigenValueSolver_h */
8 changes: 6 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
add_library(eigenValueSolver eigenValueSolver.cpp)
add_executable(main main.cpp utils.cpp )
add_library(eigenValueSolver eigenValueSolver.cc utils.cc)
add_executable(main main.cc)

target_include_directories(eigenValueSolver
PUBLIC
Expand All @@ -13,3 +13,7 @@ target_link_libraries(eigenValueSolver
target_link_libraries(main
PUBLIC
eigenValueSolver)

if (ENABLE_TESTING)
add_subdirectory(tests)
endif()
Loading