From 23df217034c7d8150704dd625d2ed063f49f3344 Mon Sep 17 00:00:00 2001 From: cstyl Date: Sun, 16 Apr 2023 19:26:14 +0000 Subject: [PATCH] Added workspaces for COO and CSR SpMV to be used with ArmPL --- core/src/CMakeLists.txt | 11 ++- .../Arm/Morpheus_Multiply_ArmPL_Impl.hpp | 12 +-- .../Coo/Serial/Arm/Morpheus_Workspace.cpp | 39 +++++++++ .../Coo/Serial/Arm/Morpheus_Workspace.hpp | 83 +++++++++++++++++++ .../Arm/Morpheus_Multiply_ArmPL_Impl.hpp | 12 +-- .../Csr/Serial/Arm/Morpheus_Workspace.cpp | 39 +++++++++ .../Csr/Serial/Arm/Morpheus_Workspace.hpp | 82 ++++++++++++++++++ 7 files changed, 261 insertions(+), 17 deletions(-) create mode 100644 core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.cpp create mode 100644 core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.hpp create mode 100644 core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.cpp create mode 100644 core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.hpp diff --git a/core/src/CMakeLists.txt b/core/src/CMakeLists.txt index fe2c0fde..f075a6ba 100644 --- a/core/src/CMakeLists.txt +++ b/core/src/CMakeLists.txt @@ -50,7 +50,7 @@ if(Morpheus_ENABLE_CUDA OR MORPHEUS_ENABLE_HIP) ${CMAKE_CURRENT_SOURCE_DIR}/impl/DenseVector/Kernels/*.hpp) endif() -foreach(Fmt Coo;Csr;Dia) +foreach(Fmt Coo;Csr;Dia;Ell;Hdc;Hyb) append_glob(MORPHEUS_CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/impl/${Fmt}/*.cpp) append_glob(MORPHEUS_CORE_HEADERS @@ -92,6 +92,15 @@ foreach(Fmt Coo;Csr;Dia) endif() endforeach() +if(Morpheus_ENABLE_SERIAL AND Morpheus_ENABLE_TPL_ARMPL) + foreach(Fmt Coo;Csr) + append_glob(MORPHEUS_CORE_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/impl/${Fmt}/Serial/Arm/*.cpp) + append_glob(MORPHEUS_CORE_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/impl/${Fmt}/Serial/Arm/*.hpp) + endforeach() +endif() + append_glob(MORPHEUS_CORE_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/MorpheusCore_config.hpp) diff --git a/core/src/impl/Coo/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp b/core/src/impl/Coo/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp index 18ee4ea8..0f2161b6 100644 --- a/core/src/impl/Coo/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp +++ b/core/src/impl/Coo/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp @@ -30,6 +30,7 @@ #include #include +#include namespace Morpheus { namespace Impl { @@ -41,16 +42,11 @@ void multiply_armpl_coo_serial( ValueType* y, bool init, typename std::enable_if_t && std::is_same_v>* = nullptr) { - armpl_spmat_t armpl_mat; - ValueType beta = init ? 0.0 : 1.0; - - CHECK_ARMPL_ERROR(armpl_spmat_create_coo( - &armpl_mat, M, N, nnnz, rind, cind, vals, ARMPL_SPARSE_CREATE_NOCOPY)); - + double beta = init ? 0.0 : 1.0; + armpl_spmat_t armpl_mat = armplcoospace_serial.handle( + M, N, nnnz, rind, cind, vals, ARMPL_SPARSE_CREATE_NOCOPY); CHECK_ARMPL_ERROR(armpl_spmv_exec(ARMPL_SPARSE_OPERATION_NOTRANS, 1.0, armpl_mat, x, beta, y)); - - CHECK_ARMPL_ERROR(armpl_spmat_destroy(armpl_mat)); } } // namespace Impl diff --git a/core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.cpp b/core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.cpp new file mode 100644 index 00000000..f4ea312e --- /dev/null +++ b/core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.cpp @@ -0,0 +1,39 @@ +/** + * Morpheus_Workspace.cpp + * + * EPCC, The University of Edinburgh + * + * (c) 2021 - 2023 The University of Edinburgh + * + * Contributing Authors: + * Christodoulos Stylianou (c.stylianou@ed.ac.uk) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#if defined(MORPHEUS_ENABLE_SERIAL) +#if defined(MORPHEUS_ENABLE_TPL_ARMPL) + +namespace Morpheus { +namespace Impl { + +ArmPLCooWorkspace_Serial armplcoospace_serial; + +} // namespace Impl +} // namespace Morpheus + +#endif // MORPHEUS_ENABLE_TPL_ARMPL +#endif // MORPHEUS_ENABLE_SERIAL \ No newline at end of file diff --git a/core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.hpp b/core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.hpp new file mode 100644 index 00000000..ab2d6ae0 --- /dev/null +++ b/core/src/impl/Coo/Serial/Arm/Morpheus_Workspace.hpp @@ -0,0 +1,83 @@ +/** + * Morpheus_Workspace.hpp + * + * EPCC, The University of Edinburgh + * + * (c) 2021 - 2023 The University of Edinburgh + * + * Contributing Authors: + * Christodoulos Stylianou (c.stylianou@ed.ac.uk) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MORPHEUS_COO_ARM_WORKSPACE_HPP +#define MORPHEUS_COO_ARM_WORKSPACE_HPP + +#include +#if defined(MORPHEUS_ENABLE_SERIAL) +#if defined(MORPHEUS_ENABLE_TPL_ARMPL) + +#include +#include +#include + +namespace Morpheus { +namespace Impl { + +class ArmPLCooWorkspace_Serial { + public: + ArmPLCooWorkspace_Serial() : _handles_map(), _init(false) {} + + ~ArmPLCooWorkspace_Serial() { + for (auto p = _handles_map.begin(); p != _handles_map.end(); p++) + CHECK_ARMPL_ERROR(armpl_spmat_destroy(p->second)); + } + + template + armpl_spmat_t handle(armpl_int_t m, armpl_int_t n, armpl_int_t nnz, + const armpl_int_t *row_indx, const armpl_int_t *col_indx, + const ValueType *vals, armpl_int_t flags) { + armpl_int_t *key = (armpl_int_t *)row_indx; + if (_handles_map.find(key) == _handles_map.end()) { + armpl_spmat_t armpl_mat; + armpl_spmat_create_coo(&armpl_mat, m, n, nnz, row_indx, + col_indx, vals, flags); + // Give hints and optimize spmv algorithm + CHECK_ARMPL_ERROR(armpl_spmat_hint(armpl_mat, + ARMPL_SPARSE_HINT_SPMV_OPERATION, + ARMPL_SPARSE_OPERATION_NOTRANS)); + + CHECK_ARMPL_ERROR(armpl_spmat_hint(armpl_mat, + ARMPL_SPARSE_HINT_SPMV_INVOCATIONS, + ARMPL_SPARSE_INVOCATIONS_MANY)); + CHECK_ARMPL_ERROR(armpl_spmv_optimize(armpl_mat)); + + _handles_map[key] = armpl_mat; + } + return _handles_map[key]; + } + + private: + std::unordered_map _handles_map; + bool _init; +}; + +extern ArmPLCooWorkspace_Serial armplcoospace_serial; + +} // namespace Impl +} // namespace Morpheus + +#endif // MORPHEUS_ENABLE_TPL_ARMPL +#endif // MORPHEUS_ENABLE_SERIAL +#endif // MORPHEUS_COO_ARM_WORKSPACE_HPP \ No newline at end of file diff --git a/core/src/impl/Csr/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp b/core/src/impl/Csr/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp index 831677f9..bb47e2ea 100644 --- a/core/src/impl/Csr/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp +++ b/core/src/impl/Csr/Serial/Arm/Morpheus_Multiply_ArmPL_Impl.hpp @@ -30,6 +30,7 @@ #include #include +#include namespace Morpheus { namespace Impl { @@ -41,16 +42,11 @@ void multiply_armpl_csr_serial( ValueType* y, bool init, typename std::enable_if_t && std::is_same_v>* = nullptr) { - armpl_spmat_t armpl_mat; - double beta = init ? 0.0 : 1.0; - - CHECK_ARMPL_ERROR(armpl_spmat_create_csr( - &armpl_mat, M, N, roff, cind, vals, ARMPL_SPARSE_CREATE_NOCOPY)); - + double beta = init ? 0.0 : 1.0; + armpl_spmat_t armpl_mat = armplcsrspace_serial.handle( + M, N, roff, cind, vals, ARMPL_SPARSE_CREATE_NOCOPY); CHECK_ARMPL_ERROR(armpl_spmv_exec(ARMPL_SPARSE_OPERATION_NOTRANS, 1.0, armpl_mat, x, beta, y)); - - CHECK_ARMPL_ERROR(armpl_spmat_destroy(armpl_mat)); } } // namespace Impl diff --git a/core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.cpp b/core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.cpp new file mode 100644 index 00000000..5b64e607 --- /dev/null +++ b/core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.cpp @@ -0,0 +1,39 @@ +/** + * Morpheus_Workspace.cpp + * + * EPCC, The University of Edinburgh + * + * (c) 2021 - 2023 The University of Edinburgh + * + * Contributing Authors: + * Christodoulos Stylianou (c.stylianou@ed.ac.uk) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#if defined(MORPHEUS_ENABLE_SERIAL) +#if defined(MORPHEUS_ENABLE_TPL_ARMPL) + +namespace Morpheus { +namespace Impl { + +ArmPLCsrWorkspace_Serial armplcsrspace_serial; + +} // namespace Impl +} // namespace Morpheus + +#endif // MORPHEUS_ENABLE_TPL_ARMPL +#endif // MORPHEUS_ENABLE_SERIAL \ No newline at end of file diff --git a/core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.hpp b/core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.hpp new file mode 100644 index 00000000..bf25fb98 --- /dev/null +++ b/core/src/impl/Csr/Serial/Arm/Morpheus_Workspace.hpp @@ -0,0 +1,82 @@ +/** + * Morpheus_Workspace.hpp + * + * EPCC, The University of Edinburgh + * + * (c) 2021 - 2023 The University of Edinburgh + * + * Contributing Authors: + * Christodoulos Stylianou (c.stylianou@ed.ac.uk) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MORPHEUS_CSR_ARM_WORKSPACE_HPP +#define MORPHEUS_CSR_ARM_WORKSPACE_HPP + +#include +#if defined(MORPHEUS_ENABLE_SERIAL) +#if defined(MORPHEUS_ENABLE_TPL_ARMPL) + +#include +#include +#include + +namespace Morpheus { +namespace Impl { + +class ArmPLCsrWorkspace_Serial { + public: + ArmPLCsrWorkspace_Serial() : _handles_map(), _init(false) {} + + ~ArmPLCsrWorkspace_Serial() { + for (auto p = _handles_map.begin(); p != _handles_map.end(); p++) + CHECK_ARMPL_ERROR(armpl_spmat_destroy(p->second)); + } + + template + armpl_spmat_t handle(armpl_int_t m, armpl_int_t n, const armpl_int_t *row_ptr, + const armpl_int_t *col_indx, const ValueType *vals, + armpl_int_t flags) { + armpl_int_t *key = (armpl_int_t *)row_ptr; + if (_handles_map.find(key) == _handles_map.end()) { + armpl_spmat_t armpl_mat; + armpl_spmat_create_csr(&armpl_mat, m, n, row_ptr, col_indx, + vals, flags); + // Give hints and optimize spmv algorithm + CHECK_ARMPL_ERROR(armpl_spmat_hint(armpl_mat, + ARMPL_SPARSE_HINT_SPMV_OPERATION, + ARMPL_SPARSE_OPERATION_NOTRANS)); + CHECK_ARMPL_ERROR(armpl_spmat_hint(armpl_mat, + ARMPL_SPARSE_HINT_SPMV_INVOCATIONS, + ARMPL_SPARSE_INVOCATIONS_MANY)); + CHECK_ARMPL_ERROR(armpl_spmv_optimize(armpl_mat)); + + _handles_map[key] = armpl_mat; + } + return _handles_map[key]; + } + + private: + std::unordered_map _handles_map; + bool _init; +}; + +extern ArmPLCsrWorkspace_Serial armplcsrspace_serial; + +} // namespace Impl +} // namespace Morpheus + +#endif // MORPHEUS_ENABLE_TPL_ARMPL +#endif // MORPHEUS_ENABLE_SERIAL +#endif // MORPHEUS_CSR_ARM_WORKSPACE_HPP \ No newline at end of file