Skip to content

Commit

Permalink
add all gemm operations and refactor linear algebra
Browse files Browse the repository at this point in the history
add hmatrix hmatrix prod

fixup

fixup
  • Loading branch information
PierreMarchand20 committed Mar 13, 2024
1 parent dd96716 commit d614322
Show file tree
Hide file tree
Showing 89 changed files with 4,341 additions and 714 deletions.
19 changes: 11 additions & 8 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,28 +132,31 @@ jobs:
# ref: 14d013835eceb940b9b51dd90462fe67834db777
fetch-depth: 0 # to get tags
- name: Checkout hpddm
uses: actions/checkout@v3
with:
path: "hpddm"
repository: hpddm/hpddm
ref: afb9562c9c6673d9ff760985b104ef8d4caa3621
run: |
git clone https://github.com/hpddm/hpddm.git hpddm
# cd hpddm & git checkout afb9562c9c6673d9ff760985b104ef8d4caa3621
# uses: actions/checkout@v3
# with:
# path: "hpddm"
# repository: hpddm/hpddm
# ref: afb9562c9c6673d9ff760985b104ef8d4caa3621

- name: Build tests
run: |
cd htool && mkdir build && cd build
cmake -DHTOOL_WITH_EXAMPLES=1 -DMPIEXEC_PREFLAGS="${{ matrix.MPIEXEC_PREFLAGS }}" -DUSE_SANITIZER=${{ matrix.USE_SANITIZER }} -DCMAKE_BUILD_TYPE=${{ matrix.CMAKE_BUILD_TYPE }} -DCODE_COVERAGE=${{ matrix.CODE_COVERAGE }} ../
make -j2 build-tests
make -j 4 build-tests
- name: Run tests
run: |
cd htool/build
export OMP_NUM_THREADS=2
${{ matrix.ASAN_OPTIONS }} ctest --output-on-failure
${{ matrix.ASAN_OPTIONS }} ctest -j 4 --output-on-failure
- name: Build examples
run: |
cd htool/build
make -j2 build-examples
make -j 4 build-examples
- name: Build documentation
run: |
Expand Down
4 changes: 2 additions & 2 deletions include/htool/distributed_operator/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class DefaultApproximationBuilder {
DistributedOperator<CoefficientPrecision> distributed_operator;
const HMatrix<CoefficientPrecision, CoordinatePrecision> *block_diagonal_hmatrix{nullptr};

DefaultApproximationBuilder(const VirtualGenerator<CoefficientPrecision> &generator, const Cluster<CoordinatePrecision> &target_cluster, const Cluster<CoordinatePrecision> &source_cluster, htool::underlying_type<CoefficientPrecision> epsilon, htool::underlying_type<CoefficientPrecision> eta, char symmetry, char UPLO, MPI_Comm communicator) : target_partition(target_cluster), source_partition(source_cluster), hmatrix(HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision>(target_cluster, source_cluster, epsilon, eta, symmetry, UPLO, -1, get_rankWorld(communicator)).build(generator)), local_hmatrix(hmatrix, target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster, symmetry, UPLO, false, false), distributed_operator(target_partition, source_partition, symmetry, UPLO, communicator) {
DefaultApproximationBuilder(const VirtualGenerator<CoefficientPrecision> &generator, const Cluster<CoordinatePrecision> &target_cluster, const Cluster<CoordinatePrecision> &source_cluster, htool::underlying_type<CoefficientPrecision> epsilon, htool::underlying_type<CoefficientPrecision> eta, char symmetry, char UPLO, MPI_Comm communicator) : target_partition(target_cluster), source_partition(source_cluster), hmatrix(HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision>(target_cluster, source_cluster, epsilon, eta, symmetry, UPLO, -1, get_rankWorld(communicator), get_rankWorld(communicator)).build(generator)), local_hmatrix(hmatrix, target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster, symmetry, UPLO, false, false), distributed_operator(target_partition, source_partition, symmetry, UPLO, communicator) {
distributed_operator.add_local_operator(&local_hmatrix);
block_diagonal_hmatrix = hmatrix.get_sub_hmatrix(target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster.get_cluster_on_partition(get_rankWorld(communicator)));
}
Expand All @@ -52,7 +52,7 @@ class DefaultLocalApproximationBuilder {
const HMatrix<CoefficientPrecision, CoordinatePrecision> *block_diagonal_hmatrix{nullptr};

public:
DefaultLocalApproximationBuilder(const VirtualGenerator<CoefficientPrecision> &generator, const Cluster<CoordinatePrecision> &target_cluster, const Cluster<CoordinatePrecision> &source_cluster, htool::underlying_type<CoefficientPrecision> epsilon, htool::underlying_type<CoefficientPrecision> eta, char symmetry, char UPLO, MPI_Comm communicator) : target_partition(target_cluster), source_partition(source_cluster), hmatrix(HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision>(target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster.get_cluster_on_partition(get_rankWorld(communicator)), epsilon, eta, symmetry, UPLO, -1, -1).build(generator)), local_hmatrix(hmatrix, target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster.get_cluster_on_partition(get_rankWorld(communicator)), symmetry, UPLO, false, false), distributed_operator(target_partition, source_partition, symmetry, UPLO, communicator) {
DefaultLocalApproximationBuilder(const VirtualGenerator<CoefficientPrecision> &generator, const Cluster<CoordinatePrecision> &target_cluster, const Cluster<CoordinatePrecision> &source_cluster, htool::underlying_type<CoefficientPrecision> epsilon, htool::underlying_type<CoefficientPrecision> eta, char symmetry, char UPLO, MPI_Comm communicator) : target_partition(target_cluster), source_partition(source_cluster), hmatrix(HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision>(target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster.get_cluster_on_partition(get_rankWorld(communicator)), epsilon, eta, symmetry, UPLO, -1, -1, -1).build(generator)), local_hmatrix(hmatrix, target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster.get_cluster_on_partition(get_rankWorld(communicator)), symmetry, UPLO, false, false), distributed_operator(target_partition, source_partition, symmetry, UPLO, communicator) {
distributed_operator.add_local_operator(&local_hmatrix);
block_diagonal_hmatrix = hmatrix.get_sub_hmatrix(target_cluster.get_cluster_on_partition(get_rankWorld(communicator)), source_cluster.get_cluster_on_partition(get_rankWorld(communicator)));
}
Expand Down
118 changes: 110 additions & 8 deletions include/htool/hmatrix/hmatrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ namespace htool {
// Class
template <typename CoefficientPrecision, typename CoordinatePrecision = underlying_type<CoefficientPrecision>>
class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecision>, HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>> {
public:
enum class StorageType {
Dense,
LowRank,
Hierarchical
};

private:
// Data members
Expand All @@ -42,11 +48,6 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
mutable char m_symmetry_type_for_leaves{'N'};
// std::vector<HMatrix *> m_leaves_in_diagonal_block{};

enum class StorageType {
Dense,
LowRank,
Hierarchical
};
StorageType m_storage_type{StorageType::Hierarchical};

void set_leaves_in_cache() const {
Expand Down Expand Up @@ -91,16 +92,85 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
// Child constructor
HMatrix(const HMatrix &parent, const Cluster<CoordinatePrecision> *target_cluster, const Cluster<CoordinatePrecision> *source_cluster) : TreeNode<HMatrix, HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(parent), m_target_cluster(target_cluster), m_source_cluster(source_cluster) {}

// no copy
HMatrix(const HMatrix &) = delete;
HMatrix &operator=(const HMatrix &) = delete;
HMatrix(const HMatrix &rhs) : TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecision>, HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(rhs), m_target_cluster(rhs.m_target_cluster), m_source_cluster(rhs.m_source_cluster), m_symmetry(rhs.m_symmetry), m_UPLO(rhs.m_UPLO), m_leaves(), m_leaves_for_symmetry(), m_symmetry_type_for_leaves(), m_storage_type(rhs.m_storage_type) {
Logger::get_instance().log(LogLevel::INFO, "Deep copy of HMatrix");
this->m_depth = rhs.m_depth;
this->m_is_root = rhs.m_is_root;
this->m_tree_data = std::make_shared<HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(*rhs.m_tree_data);
this->m_children.clear();
for (auto &child : rhs.m_children) {
this->m_children.emplace_back(std::make_unique<HMatrix<CoefficientPrecision, CoordinatePrecision>>(*child));
}
if (rhs.m_dense_data) {
m_dense_data = std::make_unique<Matrix<CoefficientPrecision>>(*rhs.m_dense_data);
}
if (rhs.m_low_rank_data) {
m_low_rank_data = std::make_unique<LowRankMatrix<CoefficientPrecision, CoordinatePrecision>>(*rhs.m_low_rank_data);
}
}
HMatrix &operator=(const HMatrix &rhs) {
Logger::get_instance().log(LogLevel::INFO, "Deep copy of HMatrix");
if (&rhs == this) {
return *this;
}
this->m_depth = rhs.m_depth;
this->m_is_root = rhs.m_is_root;
this->m_tree_data = std::make_shared<HMatrixTreeData<CoefficientPrecision, CoordinatePrecision>>(*rhs.m_tree_data);
this->m_children.clear();
for (auto &child : rhs.m_children) {
this->m_children.emplace_back(std::make_unique<HMatrix<CoefficientPrecision, CoordinatePrecision>>(*child));
}
m_target_cluster = rhs.m_target_cluster;
m_source_cluster = rhs.m_source_cluster;
m_symmetry = rhs.m_symmetry;
m_UPLO = rhs.m_UPLO;
m_storage_type = rhs.m_storage_type;

if (rhs.m_dense_data) {
m_dense_data = std::make_unique<Matrix<CoefficientPrecision>>(*rhs.m_dense_data);
}
if (rhs.m_low_rank_data) {
m_low_rank_data = std::make_unique<LowRankMatrix<CoefficientPrecision, CoordinatePrecision>>(*rhs.m_low_rank_data);
}
m_leaves.clear();
m_leaves_for_symmetry.clear();
return *this;
}

HMatrix(HMatrix &&) noexcept = default;
HMatrix &operator=(HMatrix &&) noexcept = default;
virtual ~HMatrix() = default;

// HMatrix getters
const Cluster<CoordinatePrecision> &get_target_cluster() const { return *m_target_cluster; }
const Cluster<CoordinatePrecision> &get_source_cluster() const { return *m_source_cluster; }
int nb_cols() const { return m_source_cluster->get_size(); }
int nb_rows() const { return m_target_cluster->get_size(); }

HMatrix<CoefficientPrecision, CoordinatePrecision> *get_child_or_this(const Cluster<CoordinatePrecision> &required_target_cluster, const Cluster<CoordinatePrecision> &required_source_cluster) {
if (*m_target_cluster == required_target_cluster and *m_source_cluster == required_source_cluster) {
return this;
}
for (auto &child : this->m_children) {
if (child->get_target_cluster() == required_target_cluster and child->get_source_cluster() == required_source_cluster) {
return child.get();
}
}
return nullptr;
}

const HMatrix<CoefficientPrecision, CoordinatePrecision> *get_child_or_this(const Cluster<CoordinatePrecision> &required_target_cluster, const Cluster<CoordinatePrecision> &required_source_cluster) const {
if (*m_target_cluster == required_target_cluster and *m_source_cluster == required_source_cluster) {
return this;
}
for (auto &child : this->m_children) {
if (child->get_target_cluster() == required_target_cluster and child->get_source_cluster() == required_source_cluster) {
return child.get();
}
}
return nullptr;
}

int get_rank() const {
return m_storage_type == StorageType::LowRank ? m_low_rank_data->rank_of() : -1;
}
Expand All @@ -113,7 +183,9 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
return m_leaves_for_symmetry;
}
const Matrix<CoefficientPrecision> *get_dense_data() const { return m_dense_data.get(); }
Matrix<CoefficientPrecision> *get_dense_data() { return m_dense_data.get(); }
const LowRankMatrix<CoefficientPrecision, CoordinatePrecision> *get_low_rank_data() const { return m_low_rank_data.get(); }
LowRankMatrix<CoefficientPrecision, CoordinatePrecision> *get_low_rank_data() { return m_low_rank_data.get(); }
char get_symmetry() const { return m_symmetry; }
char get_UPLO() const { return m_UPLO; }
const HMatrixTreeData<CoefficientPrecision, CoordinatePrecision> *get_hmatrix_tree_data() const { return this->m_tree_data.get(); }
Expand All @@ -136,6 +208,26 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
}
return nullptr;
}
HMatrix<CoefficientPrecision> *get_sub_hmatrix(const Cluster<CoordinatePrecision> &target_cluster, const Cluster<CoordinatePrecision> &source_cluster) {
std::queue<HMatrix<CoefficientPrecision> *> hmatrix_queue;
hmatrix_queue.push(this);

while (!hmatrix_queue.empty()) {
HMatrix<CoefficientPrecision> *current_hmatrix = hmatrix_queue.front();
hmatrix_queue.pop();

if (target_cluster == current_hmatrix->get_target_cluster() && source_cluster == current_hmatrix->get_source_cluster()) {
return current_hmatrix;
}

auto &children = current_hmatrix->get_children();
for (auto &child : children) {
hmatrix_queue.push(child.get());
}
}
return nullptr;
}
StorageType get_storage_type() const { return m_storage_type; }

// HMatrix node setters
void set_symmetry(char symmetry) { m_symmetry = symmetry; }
Expand All @@ -145,6 +237,7 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
// Test properties
bool is_dense() const { return m_storage_type == StorageType::Dense; }
bool is_low_rank() const { return m_storage_type == StorageType::LowRank; }
bool is_hierarchical() const { return m_storage_type == StorageType::Hierarchical; }

// HMatrix Tree setters
void set_eta(CoordinatePrecision eta) { this->m_tree_data->m_eta = eta; }
Expand Down Expand Up @@ -186,6 +279,15 @@ class HMatrix : public TreeNode<HMatrix<CoefficientPrecision, CoordinatePrecisio
}
void clear_low_rank_data() { m_low_rank_data.reset(); }

void set_dense_data(Matrix<CoefficientPrecision> &dense_matrix) {
this->delete_children();
m_leaves.clear();
m_leaves_for_symmetry.clear();
m_dense_data = std::make_unique<Matrix<CoefficientPrecision>>();
m_dense_data->assign(dense_matrix.nb_rows(), dense_matrix.nb_cols(), dense_matrix.release(), true);
m_storage_type = StorageType::Dense;
}

// Linear algebra
void add_vector_product(char trans, CoefficientPrecision alpha, const CoefficientPrecision *in, CoefficientPrecision beta, CoefficientPrecision *out) const;
void add_matrix_product_row_major(char trans, CoefficientPrecision alpha, const CoefficientPrecision *in, CoefficientPrecision beta, CoefficientPrecision *out, int mu) const;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef HTOOL_VIRTUAL_LRMAT_GENERATOR_HPP
#define HTOOL_VIRTUAL_LRMAT_GENERATOR_HPP

#include "../../basic_types/matrix.hpp"
#include "../../matrix/matrix.hpp"
#include "../../misc/misc.hpp"
#include "virtual_generator.hpp"
#include <cassert>
Expand Down
Loading

0 comments on commit d614322

Please sign in to comment.