Skip to content
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

Sparsity format Reference and OpenMP kernels #350

Merged
merged 8 commits into from
Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add OpenMP kernels and tests.
  • Loading branch information
pratikvn committed Sep 30, 2019
commit 9275cd7c22067501f09631b9145aaac19c681331
136 changes: 124 additions & 12 deletions omp/matrix/sparsity_kernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ namespace gko {
namespace kernels {
namespace omp {
/**
* @brief The Compressed sparse row matrix format namespace.
* @brief The Sparsity pattern format namespace.
*
* @ingroup sparsity
*/
Expand All @@ -64,8 +64,26 @@ namespace sparsity {
template <typename ValueType, typename IndexType>
void spmv(std::shared_ptr<const OmpExecutor> exec,
const matrix::Sparsity<ValueType, IndexType> *a,
const matrix::Dense<ValueType> *b,
matrix::Dense<ValueType> *c) GKO_NOT_IMPLEMENTED;
const matrix::Dense<ValueType> *b, matrix::Dense<ValueType> *c)
{
auto row_ptrs = a->get_const_row_ptrs();
auto col_idxs = a->get_const_col_idxs();

#pragma omp parallel for
for (size_type row = 0; row < a->get_size()[0]; ++row) {
for (size_type j = 0; j < c->get_size()[1]; ++j) {
c->at(row, j) = zero<ValueType>();
}
for (size_type k = row_ptrs[row];
k < static_cast<size_type>(row_ptrs[row + 1]); ++k) {
auto val = one<ValueType>();
auto col = col_idxs[k];
for (size_type j = 0; j < c->get_size()[1]; ++j) {
c->at(row, j) += val * b->at(col, j);
}
}
}
}

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_SPARSITY_SPMV_KERNEL);

Expand All @@ -76,7 +94,28 @@ void advanced_spmv(std::shared_ptr<const OmpExecutor> exec,
const matrix::Sparsity<ValueType, IndexType> *a,
const matrix::Dense<ValueType> *b,
const matrix::Dense<ValueType> *beta,
matrix::Dense<ValueType> *c) GKO_NOT_IMPLEMENTED;
matrix::Dense<ValueType> *c)
{
auto row_ptrs = a->get_const_row_ptrs();
auto col_idxs = a->get_const_col_idxs();
auto valpha = alpha->at(0, 0);
auto vbeta = beta->at(0, 0);

#pragma omp parallel for
for (size_type row = 0; row < a->get_size()[0]; ++row) {
for (size_type j = 0; j < c->get_size()[1]; ++j) {
c->at(row, j) *= vbeta;
}
for (size_type k = row_ptrs[row];
k < static_cast<size_type>(row_ptrs[row + 1]); ++k) {
auto val = one<ValueType>();
auto col = col_idxs[k];
for (size_type j = 0; j < c->get_size()[1]; ++j) {
c->at(row, j) += valpha * val * b->at(col, j);
}
}
}
}

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
GKO_DECLARE_SPARSITY_ADVANCED_SPMV_KERNEL);
Expand All @@ -96,7 +135,26 @@ template <typename ValueType, typename IndexType>
void remove_diagonal_elements(std::shared_ptr<const OmpExecutor> exec,
matrix::Sparsity<ValueType, IndexType> *matrix,
const IndexType *row_ptrs,
const IndexType *col_idxs) GKO_NOT_IMPLEMENTED;
const IndexType *col_idxs)
{
auto num_rows = matrix->get_size()[0];
auto adj_ptrs = matrix->get_row_ptrs();
auto adj_idxs = matrix->get_col_idxs();
for (auto i = 0; i <= num_rows; ++i) {
adj_ptrs[i] = row_ptrs[i] - i;
}
pratikvn marked this conversation as resolved.
Show resolved Hide resolved
std::vector<IndexType> temp_idxs;
for (auto i = 0; i < num_rows; ++i) {
for (auto j = row_ptrs[i]; j < row_ptrs[i + 1]; ++j) {
if (col_idxs[j] != i) {
temp_idxs.push_back(col_idxs[j]);
}
}
}
for (auto i = 0; i < temp_idxs.size(); ++i) {
adj_idxs[i] = temp_idxs[i];
}
}

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
GKO_DECLARE_SPARSITY_REMOVE_DIAGONAL_ELEMENTS_KERNEL);
Expand All @@ -106,22 +164,47 @@ template <typename IndexType>
inline void convert_sparsity_to_csc(size_type num_rows,
const IndexType *row_ptrs,
const IndexType *col_idxs,
IndexType *row_idxs,
IndexType *col_ptrs) GKO_NOT_IMPLEMENTED;
IndexType *row_idxs, IndexType *col_ptrs)
{
for (size_type row = 0; row < num_rows; ++row) {
for (auto i = row_ptrs[row]; i < row_ptrs[row + 1]; ++i) {
const auto dest_idx = col_ptrs[col_idxs[i]]++;
row_idxs[dest_idx] = row;
}
}
}


template <typename ValueType, typename IndexType>
void transpose_and_transform(std::shared_ptr<const OmpExecutor> exec,
matrix::Sparsity<ValueType, IndexType> *trans,
const matrix::Sparsity<ValueType, IndexType> *orig)
GKO_NOT_IMPLEMENTED;
{
auto trans_row_ptrs = trans->get_row_ptrs();
auto orig_row_ptrs = orig->get_const_row_ptrs();
auto trans_col_idxs = trans->get_col_idxs();
auto orig_col_idxs = orig->get_const_col_idxs();

auto orig_num_cols = orig->get_size()[1];
auto orig_num_rows = orig->get_size()[0];
auto orig_nnz = orig_row_ptrs[orig_num_rows];

trans_row_ptrs[0] = 0;
convert_unsorted_idxs_to_ptrs(orig_col_idxs, orig_nnz, trans_row_ptrs + 1,
orig_num_cols);

convert_sparsity_to_csc(orig_num_rows, orig_row_ptrs, orig_col_idxs,
trans_col_idxs, trans_row_ptrs + 1);
}


template <typename ValueType, typename IndexType>
void transpose(std::shared_ptr<const OmpExecutor> exec,
matrix::Sparsity<ValueType, IndexType> *trans,
const matrix::Sparsity<ValueType, IndexType> *orig)
GKO_NOT_IMPLEMENTED;
{
transpose_and_transform(exec, trans, orig);
}

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
GKO_DECLARE_SPARSITY_TRANSPOSE_KERNEL);
Expand All @@ -130,7 +213,17 @@ GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
template <typename ValueType, typename IndexType>
void sort_by_column_index(std::shared_ptr<const OmpExecutor> exec,
matrix::Sparsity<ValueType, IndexType> *to_sort)
GKO_NOT_IMPLEMENTED;
{
auto row_ptrs = to_sort->get_row_ptrs();
auto col_idxs = to_sort->get_col_idxs();
const auto number_rows = to_sort->get_size()[0];
#pragma omp parallel for
for (size_type i = 0; i < number_rows; ++i) {
auto start_row_idx = row_ptrs[i];
auto row_nnz = row_ptrs[i + 1] - start_row_idx;
std::sort(col_idxs + start_row_idx, col_idxs + start_row_idx + row_nnz);
}
}

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
GKO_DECLARE_SPARSITY_SORT_BY_COLUMN_INDEX);
Expand All @@ -139,8 +232,27 @@ GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
template <typename ValueType, typename IndexType>
void is_sorted_by_column_index(
std::shared_ptr<const OmpExecutor> exec,
const matrix::Sparsity<ValueType, IndexType> *to_check,
bool *is_sorted) GKO_NOT_IMPLEMENTED;
const matrix::Sparsity<ValueType, IndexType> *to_check, bool *is_sorted)
{
const auto row_ptrs = to_check->get_const_row_ptrs();
const auto col_idxs = to_check->get_const_col_idxs();
const auto size = to_check->get_size();
bool local_is_sorted = true;
#pragma omp parallel for shared(local_is_sorted)
for (size_type i = 0; i < size[0]; ++i) {
#pragma omp flush(local_is_sorted)
// Skip comparison if any thread detects that it is not sorted
if (local_is_sorted) {
for (auto idx = row_ptrs[i] + 1; idx < row_ptrs[i + 1]; ++idx) {
if (col_idxs[idx - 1] > col_idxs[idx]) {
local_is_sorted = false;
break;
}
}
}
}
*is_sorted = local_is_sorted;
}

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
GKO_DECLARE_SPARSITY_IS_SORTED_BY_COLUMN_INDEX);
Expand Down
1 change: 1 addition & 0 deletions omp/test/matrix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ ginkgo_create_test(dense_kernels)
ginkgo_create_test(ell_kernels)
ginkgo_create_test(hybrid_kernels)
ginkgo_create_test(sellp_kernels)
ginkgo_create_test(sparsity_kernels)
Loading