Skip to content

add off diagonal approximation #11

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

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
56 changes: 30 additions & 26 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,27 @@ jobs:
- name: "Ubuntu OpenMPI g++"
CC_COMPILER: gcc
CXX_COMPILER: g++
container: "ubuntu_openmpi"
container: "ubuntu_gcc_openmpi"
MPIEXEC_PREFLAGS: "--allow-run-as-root --oversubscribe"
USE_SANITIZER: ""
CMAKE_BUILD_TYPE: Release
DOCKER_OPTIONS: " "
DOCKER_OPTIONS: "--cap-add SYS_PTRACE"
CODE_COVERAGE: "OFF"

- name: "Ubuntu OpenMPI clang++"
CC_COMPILER: clang
CXX_COMPILER: clang++
container: "ubuntu_openmpi"
container: "ubuntu_clang_openmpi"
MPIEXEC_PREFLAGS: "--allow-run-as-root --oversubscribe"
USE_SANITIZER: ""
CMAKE_BUILD_TYPE: Release
DOCKER_OPTIONS: " "
DOCKER_OPTIONS: "--cap-add SYS_PTRACE"
CODE_COVERAGE: "OFF"

- name: "Ubuntu MPICH g++"
CC_COMPILER: gcc
CXX_COMPILER: g++
container: "ubuntu_mpich"
container: "ubuntu_gcc_mpich"
MPIEXEC_PREFLAGS: ""
CMAKE_BUILD_TYPE: Debug
DOCKER_OPTIONS: " "
Expand All @@ -58,35 +58,37 @@ jobs:
- name: "Ubuntu MPICH clang++"
CC_COMPILER: clang
CXX_COMPILER: clang++
container: "ubuntu_mpich"
container: "ubuntu_clang_mpich"
MPIEXEC_PREFLAGS: ""
CMAKE_BUILD_TYPE: Release
DOCKER_OPTIONS: " "
CODE_COVERAGE: "OFF"

# Hangs on github
# - name: "Debian OpenMPI g++"
# CC_COMPILER: gcc
# CXX_COMPILER: g++
# container: "debian_openmpi"
# MPIEXEC_PREFLAGS: "--allow-run-as-root --oversubscribe --mca btl_vader_single_copy_mechanism none"
# USE_SANITIZER: ""
# CMAKE_BUILD_TYPE: Debug
# DOCKER_OPTIONS: "--cap-add SYS_PTRACE"

# - name: "Debian OpenMPI clang++"
# CC_COMPILER: clang
# CXX_COMPILER: clang++
# container: "debian_openmpi"
# MPIEXEC_PREFLAGS: "--allow-run-as-root --oversubscribe --mca btl_vader_single_copy_mechanism none"
# USE_SANITIZER: ""
# CMAKE_BUILD_TYPE: Debug
# DOCKER_OPTIONS: "--cap-add SYS_PTRACE"
- name: "Debian OpenMPI g++"
CC_COMPILER: gcc
CXX_COMPILER: g++
container: "debian_gcc_openmpi"
MPIEXEC_PREFLAGS: "--allow-run-as-root --oversubscribe"
USE_SANITIZER: ""
CMAKE_BUILD_TYPE: Release
DOCKER_OPTIONS: "--cap-add SYS_PTRACE"
CODE_COVERAGE: "OFF"

- name: "Debian OpenMPI clang++"
CC_COMPILER: clang
CXX_COMPILER: clang++
container: "debian_clang_openmpi"
MPIEXEC_PREFLAGS: "--allow-run-as-root --oversubscribe"
USE_SANITIZER: ""
CMAKE_BUILD_TYPE: Release
DOCKER_OPTIONS: "--cap-add SYS_PTRACE"
CODE_COVERAGE: "OFF"

- name: "Debian MPICH g++"
CC_COMPILER: gcc
CXX_COMPILER: g++
container: "debian_mpich"
container: "debian_gcc_mpich"
MPIEXEC_PREFLAGS: ""
CMAKE_BUILD_TYPE: Release
DOCKER_OPTIONS: " "
Expand All @@ -95,7 +97,7 @@ jobs:
- name: "Debian MPICH clang++"
CC_COMPILER: clang
CXX_COMPILER: clang++
container: "debian_mpich"
container: "debian_clang_mpich"
MPIEXEC_PREFLAGS: ""
CMAKE_BUILD_TYPE: Release
DOCKER_OPTIONS: " "
Expand All @@ -115,7 +117,7 @@ jobs:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
steps:
- name: Checkout htool-python
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: "true"

Expand All @@ -141,7 +143,9 @@ jobs:

- name: Check format
if: matrix.CODE_COVERAGE == 'ON'
# https://github.com/actions/checkout/pull/762
run: |
git config --global --add safe.directory `pwd`
cd build
make format
make cmake-format
Expand Down
2 changes: 1 addition & 1 deletion lib/htool
Submodule htool updated 54 files
+35 −35 .github/workflows/CI.yml
+6 −4 CHANGELOG.md
+17 −14 examples/compression_comparison.cpp
+2 −2 examples/smallest_example.cpp
+2 −2 examples/visucluster.cpp
+41 −2 include/htool/blocks/blocks.hpp
+34 −0 include/htool/blocks/dense_block_data.hpp
+19 −0 include/htool/blocks/virtual_block_data.hpp
+1 −1 include/htool/clustering/bounding_box_1.hpp
+7 −10 include/htool/clustering/cluster.hpp
+1 −1 include/htool/clustering/pca.hpp
+18 −23 include/htool/clustering/virtual_cluster.hpp
+42 −47 include/htool/lrmat/lrmat.hpp
+1 −1 include/htool/lrmat/partialACA.hpp
+1 −1 include/htool/lrmat/sympartialACA.hpp
+1 −0 include/htool/lrmat/virtual_lrmat_generator.hpp
+1 −1 include/htool/multi/multilrmat/multipartialACA.hpp
+11 −8 include/htool/solvers/coarse_space.hpp
+401 −295 include/htool/types/hmatrix.hpp
+52 −140 include/htool/types/matrix.hpp
+64 −0 include/htool/types/off_diagonal_approximation_with_hmatrix.hpp
+0 −176 include/htool/types/sparsematrix.hpp
+13 −7 include/htool/types/virtual_hmatrix.hpp
+28 −0 include/htool/types/virtual_off_diagonal_approximation.hpp
+1 −1 include/htool/wrappers/wrapper_blas.hpp
+2 −2 include/htool/wrappers/wrapper_mpi.hpp
+4 −4 tests/functional_tests/blocks/test_blocks.hpp
+3 −0 tests/functional_tests/clustering/test_cluster_global.hpp
+1 −1 tests/functional_tests/clustering/test_cluster_local.hpp
+3 −3 tests/functional_tests/lrmat/test_lrmat.hpp
+8 −8 tests/functional_tests/lrmat/test_lrmat_SVD.cpp
+6 −7 tests/functional_tests/lrmat/test_lrmat_fullACA.cpp
+6 −7 tests/functional_tests/lrmat/test_lrmat_partialACA.cpp
+6 −7 tests/functional_tests/lrmat/test_lrmat_sympartialACA.cpp
+44 −7 tests/functional_tests/solvers/test_solver_ddm.hpp
+12 −2 tests/functional_tests/solvers/test_solver_ddm_non_symmetric_multi_rhs.cpp
+13 −2 tests/functional_tests/solvers/test_solver_ddm_non_symmetric_single_rhs.cpp
+11 −2 tests/functional_tests/solvers/test_solver_ddm_symmetric_multi_rhs.cpp
+11 −2 tests/functional_tests/solvers/test_solver_ddm_symmetric_single_rhs.cpp
+0 −15 tests/functional_tests/types/test_matrix.cpp
+2 −1 tests/functional_tests/types/virtual_hmatrix/hmatrix/CMakeLists.txt
+30 −10 tests/functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_mat_prod_complex_double.cpp
+22 −6 tests/functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_mat_prod_double.cpp
+10 −10 ...functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_mat_transp_prod_complex_double.cpp
+6 −6 tests/functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_mat_transp_prod_double.cpp
+30 −10 tests/functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_vec_prod_complex_double.cpp
+18 −6 tests/functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_vec_prod_double.cpp
+10 −10 ...functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_vec_transp_prod_complex_double.cpp
+6 −6 tests/functional_tests/types/virtual_hmatrix/hmatrix/hmatrix_product/test_hmat_vec_transp_prod_double.cpp
+1 −0 tests/functional_tests/types/virtual_hmatrix/hmatrix/test_hmat_cluster.hpp
+8 −8 tests/functional_tests/types/virtual_hmatrix/hmatrix/test_hmat_permutation.cpp
+1 −1 tests/functional_tests/types/virtual_hmatrix/hmatrix/test_hmat_save.cpp
+2 −2 tests/functional_tests/types/virtual_hmatrix/hmatrix/test_hmat_to_dense.cpp
+45 −11 tests/functional_tests/types/virtual_hmatrix/test_virtual_hmat_product.hpp
6 changes: 3 additions & 3 deletions src/htool/cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ using namespace htool;

template <typename ClusterType>
void declare_Cluster(py::module &m, const std::string &className) {

py::class_<ClusterType, std::shared_ptr<ClusterType>, VirtualCluster> py_class(m, className.c_str());
py_class.def(py::init<int>());
py_class.def(
Expand Down Expand Up @@ -55,6 +54,7 @@ void declare_Cluster(py::module &m, const std::string &className) {
}
return py::array_t<int, py::array::f_style>(shape, masteroffset_raw.data());
});
py_class.def("get_global_perm", overload_cast_<int>()(&ClusterType::get_global_perm, py::const_));
py_class.def(
"display", [](ClusterType &self, py::array_t<double, py::array::f_style | py::array::forcecast> x, int depth, bool show, MPI_Comm_wrapper comm) {
int rankWorld;
Expand All @@ -74,7 +74,7 @@ void declare_Cluster(py::module &m, const std::string &className) {
// Permuted geometric points
for (int i = 0; i < size; ++i) {
for (int p = 0; p < space_dim; p++) {
output[i + size * p] = x.at(p, root->get_perm(i));
output[i + size * p] = x.at(p, root->get_global_perm(i));
}
}

Expand Down Expand Up @@ -143,4 +143,4 @@ void declare_Cluster(py::module &m, const std::string &className) {
py_class.def("set_minclustersize", &ClusterType::set_minclustersize);
}

#endif
#endif
2 changes: 1 addition & 1 deletion src/htool/ddm_solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@ void declare_DDM(py::module &m, const std::string &className) {
py_class.def("get_infos", &Class::get_infos);
}

#endif
#endif
62 changes: 17 additions & 45 deletions src/htool/hmatrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "lrmat_generator.hpp"
#include "matrix.hpp"
#include "misc.hpp"
#include "off_diagonal_approximation.hpp"
#include "wrapper_mpi.hpp"
#include <htool/htool.hpp>

Expand Down Expand Up @@ -48,6 +49,9 @@ void declare_HMatrix(py::module &m, const std::string &baseclassName, const std:
py_class.def("set_compression", [](Class &self, std::shared_ptr<VirtualLowRankGeneratorCpp<T>> mat) {
self.set_compression(mat);
});
py_class.def("set_off_diagonal_approximation", [](Class &self, std::shared_ptr<VirtualOffDiagonalApproximation<T>> mat) {
self.set_off_diagonal_approximation(mat);
});

// Getters
py_class.def_property_readonly("shape", [](const Class &self) {
Expand All @@ -57,6 +61,14 @@ void declare_HMatrix(py::module &m, const std::string &baseclassName, const std:
py_class.def("get_perm_s", overload_cast_<>()(&Class::get_perms, py::const_));
py_class.def("get_MasterOffset_t", overload_cast_<>()(&Class::get_MasterOffset_t, py::const_));
py_class.def("get_MasterOffset_s", overload_cast_<>()(&Class::get_MasterOffset_s, py::const_));
py_class.def("get_off_diagonal_geometries", [](const Class &self, const py::array_t<double, py::array::f_style> &xt, const py::array_t<double, py::array::f_style> &xs) {
int new_nc, new_nr, spatial_dimension;
self.get_off_diagonal_size(new_nr, new_nc);
spatial_dimension = self.get_target_cluster()->get_space_dim();
py::array_t<double, py::array::f_style> new_xs(std::array<long int, 2>{spatial_dimension, new_nc}), new_xt(std::array<long int, 2>{spatial_dimension, new_nr});
self.get_off_diagonal_geometries(xt.data(), xs.data(), new_xt.mutable_data(), new_xs.mutable_data());
return std::tuple<py::array_t<double, py::array::f_style>, py::array_t<double, py::array::f_style>>(new_xt, new_xs);
});

// Linear algebra
py_class.def("__mul__", [](const Class &self, std::vector<T> b) {
Expand Down Expand Up @@ -102,50 +114,9 @@ void declare_HMatrix(py::module &m, const std::string &baseclassName, const std:
// Plot pattern
py_class.def(
"display", [](const Class &self, bool show = true) {
const std::vector<LowRankMatrix<T> *> &lrmats = self.get_MyFarFieldMats();
const std::vector<SubMatrix<T> *> &dmats = self.get_MyNearFieldMats();

int nb = dmats.size() + lrmats.size();
int sizeworld = self.get_sizeworld();
int rankworld = self.get_rankworld();

int nbworld[sizeworld];
MPI_Allgather(&nb, 1, MPI_INT, nbworld, 1, MPI_INT, self.get_comm());
int nbg = 0;
for (int i = 0; i < sizeworld; i++) {
nbg += nbworld[i];
}

std::vector<int> buf(5 * nbg, 0);

for (int i = 0; i < dmats.size(); i++) {
const SubMatrix<T> &l = *(dmats[i]);
buf[5 * i] = l.get_offset_i();
buf[5 * i + 1] = l.nb_rows();
buf[5 * i + 2] = l.get_offset_j();
buf[5 * i + 3] = l.nb_cols();
buf[5 * i + 4] = -1;
}

for (int i = 0; i < lrmats.size(); i++) {
const LowRankMatrix<T> &l = *(lrmats[i]);
buf[5 * (dmats.size() + i)] = l.get_offset_i();
buf[5 * (dmats.size() + i) + 1] = l.nb_rows();
buf[5 * (dmats.size() + i) + 2] = l.get_offset_j();
buf[5 * (dmats.size() + i) + 3] = l.nb_cols();
buf[5 * (dmats.size() + i) + 4] = l.rank_of();
}

int displs[sizeworld];
int recvcounts[sizeworld];
displs[0] = 0;

for (int i = 0; i < sizeworld; i++) {
recvcounts[i] = 5 * nbworld[i];
if (i > 0)
displs[i] = displs[i - 1] + recvcounts[i - 1];
}
MPI_Gatherv(rankworld == 0 ? MPI_IN_PLACE : buf.data(), recvcounts[rankworld], MPI_INT, buf.data(), recvcounts, displs, MPI_INT, 0, self.get_comm());
int rankworld = self.get_rankworld();
std::vector<int> buf = self.get_output();
int nbg = buf.size() / 5;

if (rankworld == 0) {
// Import
Expand All @@ -158,6 +129,7 @@ void declare_HMatrix(py::module &m, const std::string &baseclassName, const std:
int nr = self.nb_rows();
int nc = self.nb_cols();
py::array_t<int> matrix({nr, nc});
matrix.attr("fill")(0);
py::array_t<bool> mask_matrix({nr, nc});
mask_matrix.attr("fill")(false);

Expand Down Expand Up @@ -246,7 +218,7 @@ void declare_HMatrix(py::module &m, const std::string &baseclassName, const std:
// Permuted geometric points
for (int i = 0; i < size; ++i) {
for (int p = 0; p < space_dim; p++) {
output[i + size * p] = points_target.at(p, root->get_perm(i));
output[i + size * p] = points_target.at(p, root->get_global_perm(i));
}
}

Expand Down
15 changes: 8 additions & 7 deletions src/htool/lrmat_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,28 @@ using namespace htool;
template <typename T>
class VirtualLowRankGeneratorCpp : public VirtualLowRankGenerator<T> {

py::array_t<T, py::array::f_style> mat_U, mat_V;
int rank;
mutable std::vector<py::array_t<T, py::array::f_style>> mats_U; // owned by Python
mutable std::vector<py::array_t<T, py::array::f_style>> mats_V; // owned by Python

public:
using VirtualLowRankGenerator<T>::VirtualLowRankGenerator;

void copy_low_rank_approximation(double epsilon, int M, int N, const int *const rows, const int *const cols, int &rank0, T **U, T **V, const VirtualGenerator<T> &A, const VirtualCluster &t, const double *const xt, const VirtualCluster &s, const double *const xs) const override {

build_low_rank_approximation(epsilon, rank0, A, std::vector<int>(rows, rows + M), std::vector<int>(cols, cols + N));
*U = new T[M * rank];
*V = new T[N * rank];
*U = mats_U.back().mutable_data();
*V = mats_V.back().mutable_data();
rank0 = rank;
std::copy_n(mat_U.data(), mat_U.size(), *U);
std::copy_n(mat_V.data(), mat_V.size(), *V);
}

bool is_htool_owning_data() const override { return false; }

// lcov does not see it because of trampoline I assume
virtual void build_low_rank_approximation(double epsilon, int rank, const VirtualGenerator<T> &A, const std::vector<int> &J, const std::vector<int> &K) const = 0; // LCOV_EXCL_LINE

void set_U(py::array_t<T, py::array::f_style> U0) { mat_U = U0; }
void set_V(py::array_t<T, py::array::f_style> V0) { mat_V = V0; }
void set_U(py::array_t<T, py::array::f_style> U0) { mats_U.push_back(U0); }
void set_V(py::array_t<T, py::array::f_style> V0) { mats_V.push_back(V0); }
void set_rank(int rank0) { rank = rank0; }
};

Expand Down
4 changes: 4 additions & 0 deletions src/htool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "hmatrix.hpp"
#include "lrmat_generator.hpp"
#include "matrix.hpp"
#include "off_diagonal_approximation.hpp"
#include "wrapper_mpi.hpp"

PYBIND11_MODULE(Htool, m) {
Expand All @@ -27,6 +28,9 @@ PYBIND11_MODULE(Htool, m) {
declare_HMatrix<double>(m, "HMatrixVirtual", "HMatrix");
declare_HMatrix<std::complex<double>>(m, "ComplexHMatrixVirtual", "ComplexHMatrix");

declare_VirtualOffDiagonalApproximation<double>(m, "VirtualOffDiagonalApproximation", "CustomOffDiagonalApproximation", "HMatrixOffDiagonalApproximation");
declare_VirtualOffDiagonalApproximation<std::complex<double>>(m, "ComplexVirtualOffDiagonalApproximation", "ComplexCustomOffDiagonalApproximation", "ComplexHMatrixOffDiagonalApproximation");

declare_DDM<double>(m, "DDM");
declare_DDM<std::complex<double>>(m, "ComplexDDM");
}
Loading