-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c1f738
commit 88badf1
Showing
13 changed files
with
460 additions
and
379 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* (C) Copyright 2024- ECMWF. | ||
* | ||
* This software is licensed under the terms of the Apache Licence Version 2.0 | ||
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. | ||
* In applying this licence, ECMWF does not waive the privileges and immunities | ||
* granted to it by virtue of its status as an intergovernmental organisation | ||
* nor does it submit to any jurisdiction. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <any> | ||
#include <memory> | ||
#include <algorithm> | ||
#include <type_traits> | ||
|
||
#include "eckit/linalg/SparseMatrix.h" | ||
|
||
#include "atlas/array.h" | ||
#include "atlas/linalg/sparse/SparseMatrixStorage.h" | ||
|
||
namespace atlas { | ||
namespace linalg { | ||
|
||
//---------------------------------------------------------------------------------------------------------------------- | ||
|
||
template<typename OutputT, typename InputT> | ||
void host_copy_eckit (const InputT* input_data, array::Array& output) { | ||
auto size = output.size(); | ||
OutputT* output_data = output.host_data<OutputT>(); | ||
std::copy( input_data, input_data + size, output_data ); | ||
} | ||
|
||
inline SparseMatrixStorage make_sparse_matrix_storage(eckit::linalg::SparseMatrix&& m) { | ||
using Index = eckit::linalg::Index; | ||
using Value = eckit::linalg::Scalar; | ||
std::cout << "make_sparse_matrix_storage move" << std::endl; | ||
|
||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = array::Array::wrap(const_cast<Index*>(m.outer()), array::make_shape(rows+1)); | ||
auto* inner = array::Array::wrap(const_cast<Index*>(m.inner()), array::make_shape(nnz)); | ||
auto* value = array::Array::wrap(const_cast<Value*>(m.data()), array::make_shape(nnz)); | ||
|
||
// We now move the eckit::linalg::SparseMatrix into a generic storage so | ||
// the wrapped array data does not go out of scope | ||
auto storage = std::make_any<eckit::linalg::SparseMatrix>(std::move(m)); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<array::Array>(value), | ||
std::unique_ptr<array::Array>(inner), | ||
std::unique_ptr<array::Array>(outer), | ||
std::move(storage) | ||
); | ||
} | ||
|
||
template< typename value_type, typename index_type = eckit::linalg::Index> | ||
SparseMatrixStorage make_sparse_matrix_storage(eckit::linalg::SparseMatrix&& m) { | ||
std::cout << "make_sparse_matrix_storage move or convert" << std::endl; | ||
|
||
if (std::is_same_v<eckit::linalg::Scalar, value_type> && std::is_same_v<eckit::linalg::Index, index_type>) { | ||
return make_sparse_matrix_storage(std::move(m)); | ||
} | ||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = array::Array::create<index_type>(rows+1); | ||
auto* inner = array::Array::create<index_type>(nnz); | ||
auto* value = array::Array::create<value_type>(nnz); | ||
|
||
host_copy_eckit<index_type>(m.outer(), *outer); | ||
host_copy_eckit<index_type>(m.inner(), *inner); | ||
host_copy_eckit<value_type>(m.data(), *value); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<array::Array>(value), | ||
std::unique_ptr<array::Array>(inner), | ||
std::unique_ptr<array::Array>(outer), | ||
std::any() | ||
); | ||
} | ||
|
||
|
||
inline SparseMatrixStorage make_sparse_matrix_storage(const eckit::linalg::SparseMatrix& m) { | ||
using Index = eckit::linalg::Index; | ||
using Value = eckit::linalg::Scalar; | ||
|
||
std::cout << "make_sparse_matrix_storage copy" << std::endl; | ||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = array::Array::create<Index>(rows+1); | ||
auto* inner = array::Array::create<Index>(nnz); | ||
auto* value = array::Array::create<Value>(nnz); | ||
|
||
host_copy_eckit<Index>(m.outer(), *outer); | ||
host_copy_eckit<Index>(m.inner(), *inner); | ||
host_copy_eckit<Value>(m.data(), *value); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<array::Array>(value), | ||
std::unique_ptr<array::Array>(inner), | ||
std::unique_ptr<array::Array>(outer), | ||
std::any() | ||
); | ||
} | ||
|
||
template< typename value_type, typename index_type = eckit::linalg::Index> | ||
SparseMatrixStorage make_sparse_matrix_storage(const eckit::linalg::SparseMatrix& m) { | ||
std::cout << "make_sparse_matrix_storage copy and convert" << std::endl; | ||
|
||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = array::Array::create<index_type>(rows+1); | ||
auto* inner = array::Array::create<index_type>(nnz); | ||
auto* value = array::Array::create<value_type>(nnz); | ||
host_copy_eckit<index_type>(m.outer(), *outer); | ||
host_copy_eckit<index_type>(m.inner(), *inner); | ||
host_copy_eckit<value_type>(m.data(), *value); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<array::Array>(value), | ||
std::unique_ptr<array::Array>(inner), | ||
std::unique_ptr<array::Array>(outer), | ||
std::any() | ||
); | ||
} | ||
|
||
//---------------------------------------------------------------------------------------------------------------------- | ||
|
||
} // namespace linalg | ||
} // namespace atlas |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* (C) Copyright 2024- ECMWF. | ||
* | ||
* This software is licensed under the terms of the Apache Licence Version 2.0 | ||
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. | ||
* In applying this licence, ECMWF does not waive the privileges and immunities | ||
* granted to it by virtue of its status as an intergovernmental organisation | ||
* nor does it submit to any jurisdiction. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <any> | ||
#include <memory> | ||
#include <algorithm> | ||
#include <type_traits> | ||
|
||
#include "atlas/library/defines.h" | ||
#if ATLAS_HAVE_EIGEN | ||
#include <Eigen/Sparse> | ||
#endif | ||
|
||
#include "atlas/array.h" | ||
#include "atlas/linalg/sparse/SparseMatrixStorage.h" | ||
|
||
namespace atlas { | ||
namespace linalg { | ||
|
||
//---------------------------------------------------------------------------------------------------------------------- | ||
|
||
#if ATLAS_HAVE_EIGEN | ||
|
||
template<typename OutputT, typename InputT> | ||
void host_copy_eigen (const InputT* input_data, atlas::array::Array& output) { | ||
auto size = output.size(); | ||
OutputT* output_data = output.host_data<OutputT>(); | ||
std::copy( input_data, input_data + size, output_data ); | ||
} | ||
|
||
template <typename Value, typename Index> | ||
SparseMatrixStorage make_sparse_matrix_storage(Eigen::SparseMatrix<Value, Eigen::RowMajor, Index>&& m) { | ||
std::cout << "make_sparse_matrix_storage move" << std::endl; | ||
|
||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = atlas::array::Array::wrap(const_cast<Index*>(m.outerIndexPtr()), atlas::array::make_shape(rows+1)); | ||
auto* inner = atlas::array::Array::wrap(const_cast<Index*>(m.innerIndexPtr()), atlas::array::make_shape(nnz)); | ||
auto* value = atlas::array::Array::wrap(const_cast<Value*>(m.valuePtr()), atlas::array::make_shape(nnz)); | ||
|
||
using EigenMatrix = Eigen::SparseMatrix<Value, Eigen::RowMajor, Index>; | ||
auto m_ptr = std::make_shared<EigenMatrix>(); | ||
m_ptr->swap(m); | ||
auto storage = std::make_any<std::shared_ptr<EigenMatrix>>(std::move(m_ptr)); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<atlas::array::Array>(value), | ||
std::unique_ptr<atlas::array::Array>(inner), | ||
std::unique_ptr<atlas::array::Array>(outer), | ||
std::move(storage) | ||
); | ||
} | ||
|
||
template< typename value_type, typename index_type = eckit::linalg::Index, typename Value, typename Index, | ||
typename = std::enable_if_t < !std::is_same_v<value_type,Value>>> | ||
SparseMatrixStorage make_sparse_matrix_storage(Eigen::SparseMatrix<Value, Eigen::RowMajor, Index>&& m) { | ||
std::cout << "make_sparse_matrix_storage move or convert" << std::endl; | ||
|
||
if (std::is_same_v<Value, value_type> && std::is_same_v<Index, index_type>) { | ||
return make_sparse_matrix_storage(std::move(m)); | ||
} | ||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = atlas::array::Array::create<index_type>(rows+1); | ||
auto* inner = atlas::array::Array::create<index_type>(nnz); | ||
auto* value = atlas::array::Array::create<value_type>(nnz); | ||
|
||
host_copy_eigen<index_type>(m.outerIndexPtr(), *outer); | ||
host_copy_eigen<index_type>(m.innerIndexPtr(), *inner); | ||
host_copy_eigen<value_type>(m.valuePtr(), *value); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<atlas::array::Array>(value), | ||
std::unique_ptr<atlas::array::Array>(inner), | ||
std::unique_ptr<atlas::array::Array>(outer), | ||
std::any() | ||
); | ||
} | ||
|
||
|
||
template <typename Value, typename Index> | ||
SparseMatrixStorage make_sparse_matrix_storage(const Eigen::SparseMatrix<Value, Eigen::RowMajor, Index>& m) { | ||
std::cout << "make_sparse_matrix_storage copy" << std::endl; | ||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = atlas::array::Array::create<Index>(rows+1); | ||
auto* inner = atlas::array::Array::create<Index>(nnz); | ||
auto* value = atlas::array::Array::create<Value>(nnz); | ||
|
||
host_copy_eigen<Index>(m.outerIndexPtr(), *outer); | ||
host_copy_eigen<Index>(m.innerIndexPtr(), *inner); | ||
host_copy_eigen<Value>(m.valuePtr(), *value); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<atlas::array::Array>(value), | ||
std::unique_ptr<atlas::array::Array>(inner), | ||
std::unique_ptr<atlas::array::Array>(outer), | ||
std::any() | ||
); | ||
} | ||
|
||
template< typename value_type, typename index_type = eckit::linalg::Index, typename Value, typename Index, | ||
typename = std::enable_if_t < !std::is_same_v<value_type,Value>>> | ||
SparseMatrixStorage make_sparse_matrix_storage(const Eigen::SparseMatrix<Value, Eigen::RowMajor, Index>& m) { | ||
std::cout << "make_sparse_matrix_storage copy and convert" << std::endl; | ||
|
||
std::size_t rows = m.rows(); | ||
std::size_t cols = m.cols(); | ||
std::size_t nnz = m.nonZeros(); | ||
auto* outer = atlas::array::Array::create<index_type>(rows+1); | ||
auto* inner = atlas::array::Array::create<index_type>(nnz); | ||
auto* value = atlas::array::Array::create<value_type>(nnz); | ||
host_copy_eigen<index_type>(m.outerIndexPtr(), *outer); | ||
host_copy_eigen<index_type>(m.innerIndexPtr(), *inner); | ||
host_copy_eigen<value_type>(m.valuePtr(), *value); | ||
|
||
return SparseMatrixStorage::make( rows, cols, nnz, | ||
std::unique_ptr<atlas::array::Array>(value), | ||
std::unique_ptr<atlas::array::Array>(inner), | ||
std::unique_ptr<atlas::array::Array>(outer), | ||
std::any() | ||
); | ||
} | ||
|
||
#endif | ||
|
||
//---------------------------------------------------------------------------------------------------------------------- | ||
|
||
} // namespace linalg | ||
} // namespace atlas |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.