Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,27 @@ jobs:
run: |
./build/test/gtest/spblas-tests

aocl:
runs-on: 'cpu_amd'
steps:
- uses: actions/checkout@v4
- name: Add AOCL-Sparse to Environment
run: |
source /apps/spacks/current/share/spack/setup-env.sh
echo "AOCLSPARSE_DIR=$(spack location -i aocl-sparse)" >> $GITHUB_ENV
echo "AOCLUTILS_DIR=$(spack location -i aocl-utils)" >> $GITHUB_ENV
- name: CMake
run: |
source /apps/spacks/current/share/spack/setup-env.sh
spack load /ia2365b
cmake -B build -DENABLE_AOCLSPARSE=ON
- name: Build
run: |
make -C build -j `nproc`
- name: Test
run: |
./build/test/gtest/spblas-tests

rocsparse:
runs-on: 'gpu_amd'
steps:
Expand Down
19 changes: 18 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,24 @@ if (ENABLE_AOCLSPARSE)
message(FATAL_ERROR "Environment variable AOCLUTILS_DIR must be set when the AOCLSPARSE is enabled.")
endif()
target_include_directories(spblas INTERFACE $ENV{AOCLSPARSE_DIR}/include $ENV{AOCLUTILS_DIR}/include)
target_link_libraries(spblas INTERFACE $ENV{AOCLSPARSE_DIR}/lib/libaoclsparse.a $ENV{AOCLUTILS_DIR}/lib/libaoclutils.a)

find_library(AOCLSPARSE_LIBRARY NAMES aoclsparse libaoclsparse
PATHS $ENV{AOCLSPARSE_DIR}/lib
NO_DEFAULT_PATH)

find_library(AOCLUTILS_LIBRARY NAMES aoclutils libaoclutils
PATHS $ENV{AOCLUTILS_DIR}/lib
NO_DEFAULT_PATH)

if (NOT AOCLSPARSE_LIBRARY)
message(FATAL_ERROR "Could not find AOCL-Sparse library in $ENV{AOCLSPARSE_DIR}/lib")
endif()
if (NOT AOCLUTILS_LIBRARY)
message(FATAL_ERROR "Could not find AOCL-Utils library in $ENV{AOCLUTILS_DIR}/lib")
endif()

target_link_libraries(spblas INTERFACE ${AOCLSPARSE_LIBRARY} ${AOCLUTILS_LIBRARY})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPBLAS_ENABLE_AOCLSPARSE")
endif()

Expand Down
26 changes: 26 additions & 0 deletions include/spblas/vendor/aoclsparse/aocl_wrappers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,32 @@ inline aoclsparse_status aoclsparse_create_csr<double>(
return aoclsparse_create_dcsr(mat, base, M, N, nnz, row_ptr, col_idx, val);
}

template <class T>
inline aoclsparse_status
aoclsparse_create_csc(aoclsparse_matrix* mat, aoclsparse_index_base base,
aoclsparse_int M, aoclsparse_int N, aoclsparse_int nnz,
aoclsparse_int* col_ptr, aoclsparse_int* row_idx,
T* val) {
log_warning("matrix creating with this data type is currently not supported");
return aoclsparse_status_not_implemented;
}

template <>
inline aoclsparse_status
aoclsparse_create_csc<float>(aoclsparse_matrix* mat, aoclsparse_index_base base,
aoclsparse_int M, aoclsparse_int N,
aoclsparse_int nnz, aoclsparse_int* col_ptr,
aoclsparse_int* row_idx, float* val) {
return aoclsparse_create_scsc(mat, base, M, N, nnz, col_ptr, row_idx, val);
}
template <>
inline aoclsparse_status aoclsparse_create_csc<double>(
aoclsparse_matrix* mat, aoclsparse_index_base base, aoclsparse_int M,
aoclsparse_int N, aoclsparse_int nnz, aoclsparse_int* col_ptr,
aoclsparse_int* row_idx, double* val) {
return aoclsparse_create_dcsc(mat, base, M, N, nnz, col_ptr, row_idx, val);
}

template <typename T>
inline aoclsparse_status
aoclsparse_export_csr(const aoclsparse_matrix mat, aoclsparse_index_base* base,
Expand Down
57 changes: 57 additions & 0 deletions include/spblas/vendor/aoclsparse/detail/create_matrix_handle.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include <spblas/vendor/aoclsparse/aocl_wrappers.hpp>

#include <spblas/detail/view_inspectors.hpp>

namespace spblas {

namespace __aoclsparse {

template <matrix M>
requires __detail::is_csr_view_v<M>
aoclsparse_matrix create_matrix_handle(M&& m) {
aoclsparse_matrix handle = nullptr;
aoclsparse_status status = __aoclsparse::aoclsparse_create_csr(
&handle, aoclsparse_index_base_zero, m.shape()[0], m.shape()[1], m.size(),
m.rowptr().data(), m.colind().data(), m.values().data());

if (status != aoclsparse_status_success) {
throw std::runtime_error("create_matrix_handle: AOCL-Sparse failed while "
"creating matrix handle.");
}

return handle;
}

template <matrix M>
requires __detail::is_csc_view_v<M>
aoclsparse_matrix create_matrix_handle(M&& m) {
aoclsparse_matrix handle = nullptr;
aoclsparse_status status = __aoclsparse::aoclsparse_create_csr(
&handle, aoclsparse_index_base_zero, m.shape()[1], m.shape()[0], m.size(),
m.colptr().data(), m.rowind().data(), m.values().data());

if (status != aoclsparse_status_success) {
throw std::runtime_error("create_matrix_handle: AOCL-Sparse failed while "
"creating matrix handle.");
}

return handle;
}

template <matrix M>
aoclsparse_operation get_transpose(M&& m) {
static_assert(__detail::has_csr_base<M> || __detail::has_csc_base<M>);
if constexpr (__detail::has_base<M>) {
return get_transpose(m.base());
} else if constexpr (__detail::is_csr_view_v<M>) {
return aoclsparse_operation_none;
} else if constexpr (__detail::is_csc_view_v<M>) {
return aoclsparse_operation_transpose;
}
}

} // namespace __aoclsparse

} // namespace spblas
3 changes: 3 additions & 0 deletions include/spblas/vendor/aoclsparse/detail/detail.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

#include "create_matrix_handle.hpp"
91 changes: 44 additions & 47 deletions include/spblas/vendor/aoclsparse/spgemm_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

#pragma once

#include "aoclsparse.h"
#include <aoclsparse.h>
#include <cstdint>

#include "aocl_wrappers.hpp"
#include "detail/detail.hpp"
#include <fmt/core.h>
#include <spblas/algorithms/transposed.hpp>
#include <spblas/detail/log.hpp>
#include <spblas/detail/operation_info_t.hpp>
#include <spblas/detail/ranges.hpp>
Expand All @@ -30,8 +32,9 @@
namespace spblas {

template <matrix A, matrix B, matrix C>
requires(__detail::has_csr_base<A>) &&
(__detail::has_csr_base<B>) && __detail::is_csr_view_v<C>
requires(__detail::has_csr_base<A> || __detail::has_csc_base<A>) &&
(__detail::has_csr_base<B> || __detail::has_csc_base<B>) &&
__detail::is_csr_view_v<C>
operation_info_t multiply_compute(A&& a, B&& b, C&& c) {
log_trace("");
auto a_base = __detail::get_ultimate_base(a);
Expand All @@ -41,32 +44,27 @@ operation_info_t multiply_compute(A&& a, B&& b, C&& c) {
using I = tensor_index_t<C>;
using O = tensor_offset_t<C>;

aoclsparse_matrix csrA = nullptr;
aoclsparse_mat_descr descrA;
aoclsparse_matrix csrA = __aoclsparse::create_matrix_handle(a_base);
aoclsparse_matrix csrB = __aoclsparse::create_matrix_handle(b_base);

aoclsparse_operation opA = __aoclsparse::get_transpose(a);
aoclsparse_operation opB = __aoclsparse::get_transpose(b);

aoclsparse_mat_descr descrA = NULL;
aoclsparse_status status = aoclsparse_create_mat_descr(&descrA);
if (status != aoclsparse_status_success) {
fmt::print("\t descr creation failed\n");
}
aoclsparse_set_mat_type(descrA, aoclsparse_matrix_type_general);
aoclsparse_index_base indexingA = aoclsparse_index_base_zero;
aoclsparse_operation opA = aoclsparse_operation_none;

const index_t a_nrows = __backend::shape(a_base)[0];
const index_t a_ncols = __backend::shape(a_base)[1];

aoclsparse_matrix csrB = nullptr;
aoclsparse_mat_descr descrB;
aoclsparse_mat_descr descrB = NULL;
status = aoclsparse_create_mat_descr(&descrB);
if (status != aoclsparse_status_success) {
fmt::print("\t descr creation failed\n");
}

aoclsparse_set_mat_type(descrB, aoclsparse_matrix_type_general);
aoclsparse_index_base indexingB = aoclsparse_index_base_zero;
aoclsparse_operation opB = aoclsparse_operation_none;

const index_t b_nrows = __backend::shape(b_base)[0];
const index_t b_ncols = __backend::shape(b_base)[1];

aoclsparse_matrix csrC = nullptr;
aoclsparse_index_base indexingC = aoclsparse_index_base_zero;
Expand All @@ -76,22 +74,6 @@ operation_info_t multiply_compute(A&& a, B&& b, C&& c) {
index_t* c_colind = nullptr;
T* c_values = nullptr;

const aoclsparse_int nnzA = a_base.rowptr().data()[a_nrows] - indexingA;
const aoclsparse_int nnzB = b_base.rowptr().data()[b_nrows] - indexingB;

status = __aoclsparse::aoclsparse_create_csr(
&csrA, indexingA, a_nrows, a_ncols, nnzA, a_base.rowptr().data(),
a_base.colind().data(), a_base.values().data());
if (status != aoclsparse_status_success) {
fmt::print("\t csr matrix A creation failed\n");
}
status = __aoclsparse::aoclsparse_create_csr(
&csrB, indexingB, b_nrows, b_ncols, nnzB, b_base.rowptr().data(),
b_base.colind().data(), b_base.values().data());
if (status != aoclsparse_status_success) {
fmt::print("\t csr matrix B creation failed\n");
}

aoclsparse_request request = aoclsparse_stage_nnz_count;
status =
aoclsparse_sp2m(opA, descrA, csrA, opB, descrB, csrB, request, &csrC);
Expand All @@ -108,20 +90,22 @@ operation_info_t multiply_compute(A&& a, B&& b, C&& c) {
// Check: csrA and csrB destroyed when the operation_info destructor is
// called?

aoclsparse_destroy_mat_descr(descrA);
aoclsparse_destroy_mat_descr(descrB);
return operation_info_t{
index<>{__backend::shape(c)[0], __backend::shape(c)[1]}, c_nnz,
__aoclsparse::operation_state_t{csrA, csrB, csrC}};
}

template <matrix A, matrix B, matrix C>
requires(__detail::has_csr_base<A>) &&
(__detail::has_csr_base<B>) && __detail::is_csr_view_v<C>
requires(__detail::has_csr_base<A> || __detail::has_csc_base<A>) &&
(__detail::has_csr_base<B> || __detail::has_csc_base<B>) &&
__detail::is_csr_view_v<C>
void multiply_fill(operation_info_t& info, A&& a, B&& b, C&& c) {
log_trace("");

auto a_base = __detail::get_ultimate_base(a);
auto b_base = __detail::get_ultimate_base(b);
auto c_base = __detail::get_ultimate_base(c);

using T = tensor_scalar_t<C>;
using I = tensor_index_t<C>;
Expand All @@ -135,35 +119,30 @@ void multiply_fill(operation_info_t& info, A&& a, B&& b, C&& c) {
aoclsparse_matrix csrC = info.state_.c_handle;
offset_t c_nnz = info.result_nnz();

aoclsparse_mat_descr descrA;
aoclsparse_operation opA = __aoclsparse::get_transpose(a);
aoclsparse_operation opB = __aoclsparse::get_transpose(b);

aoclsparse_mat_descr descrA = NULL;
aoclsparse_status status = aoclsparse_create_mat_descr(&descrA);
if (status != aoclsparse_status_success) {
fmt::print("\t descr creation failed\n");
}

aoclsparse_set_mat_type(descrA, aoclsparse_matrix_type_general);
aoclsparse_index_base indexingA = aoclsparse_index_base_zero;
aoclsparse_operation opA = aoclsparse_operation_none;

const index_t a_nrows = __backend::shape(a_base)[0];
const index_t a_ncols = __backend::shape(a_base)[1];

aoclsparse_mat_descr descrB;
aoclsparse_mat_descr descrB = NULL;
status = aoclsparse_create_mat_descr(&descrB);
if (status != aoclsparse_status_success) {
fmt::print("\t descr creation failed\n");
}

aoclsparse_set_mat_type(descrB, aoclsparse_matrix_type_general);
aoclsparse_index_base indexingB = aoclsparse_index_base_zero;
aoclsparse_operation opB = aoclsparse_operation_none;

const index_t b_nrows = __backend::shape(b_base)[0];
const index_t b_ncols = __backend::shape(b_base)[1];

aoclsparse_index_base indexingC = aoclsparse_index_base_zero;
index_t c_nrows = __backend::shape(c_base)[0];
index_t c_ncols = __backend::shape(c_base)[1];
index_t c_nrows = __backend::shape(c)[0];
index_t c_ncols = __backend::shape(c)[1];
offset_t* c_rowptr = nullptr;
index_t* c_colind = nullptr;
T* c_values = nullptr;
Expand Down Expand Up @@ -194,6 +173,24 @@ void multiply_fill(operation_info_t& info, A&& a, B&& b, C&& c) {
if (alpha_optional.has_value()) {
scale(alpha, c);
}
aoclsparse_destroy_mat_descr(descrA);
aoclsparse_destroy_mat_descr(descrB);
}

template <matrix A, matrix B, matrix C>
requires(__detail::has_csr_base<A> || __detail::has_csc_base<A>) &&
(__detail::has_csr_base<B> || __detail::has_csc_base<B>) &&
__detail::is_csc_view_v<C>
operation_info_t multiply_compute(A&& a, B&& b, C&& c) {
return multiply_compute(transposed(b), transposed(a), transposed(c));
}

template <matrix A, matrix B, matrix C>
requires((__detail::has_csr_base<A> || __detail::has_csc_base<A>) &&
(__detail::has_csr_base<B> || __detail::has_csc_base<B>) &&
__detail::is_csc_view_v<C>)
void multiply_fill(operation_info_t& info, A&& a, B&& b, C&& c) {
multiply_fill(info, transposed(b), transposed(a), transposed(c));
}

} // namespace spblas
Loading