-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1947 from vqd8a/get-diagonal-blocks-crsmatrix
Extract diagonal blocks from a CRS matrix into separate CRS matrices
- Loading branch information
Showing
3 changed files
with
366 additions
and
0 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
154 changes: 154 additions & 0 deletions
154
sparse/unit_test/Test_Sparse_extractCrsDiagonalBlocks.hpp
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,154 @@ | ||
//@HEADER | ||
// ************************************************************************ | ||
// | ||
// Kokkos v. 4.0 | ||
// Copyright (2022) National Technology & Engineering | ||
// Solutions of Sandia, LLC (NTESS). | ||
// | ||
// Under the terms of Contract DE-NA0003525 with NTESS, | ||
// the U.S. Government retains certain rights in this software. | ||
// | ||
// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://kokkos.org/LICENSE for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//@HEADER | ||
|
||
#include "KokkosSparse_Utils.hpp" | ||
#include "KokkosKernels_TestUtils.hpp" | ||
|
||
namespace Test { | ||
template <typename scalar_t, typename lno_t, typename size_type, | ||
typename device> | ||
void run_test_extract_diagonal_blocks(int nrows, int nblocks) { | ||
using RowMapType = Kokkos::View<size_type *, device>; | ||
using EntriesType = Kokkos::View<lno_t *, device>; | ||
using ValuesType = Kokkos::View<scalar_t *, device>; | ||
using RowMapType_hm = typename RowMapType::HostMirror; | ||
using EntriesType_hm = typename EntriesType::HostMirror; | ||
using ValuesType_hm = typename ValuesType::HostMirror; | ||
using crsMat_t = CrsMatrix<scalar_t, lno_t, device, void, size_type>; | ||
|
||
crsMat_t A; | ||
std::vector<crsMat_t> DiagBlks(nblocks); | ||
|
||
if (nrows != 0) { | ||
// Generate test matrix | ||
const size_type nnz = 2 + (nrows - 2) * 3 + 2; | ||
RowMapType_hm hrow_map("hrow_map", nrows + 1); | ||
EntriesType_hm hentries("hentries", nnz); | ||
ValuesType_hm hvalues("hvalues", nnz); | ||
|
||
// first row | ||
hrow_map(0) = 0; | ||
hentries(0) = 0; | ||
hentries(1) = 1; | ||
hvalues(0) = 0; | ||
hvalues(1) = 1; | ||
// rows in between | ||
int cnt = 2; | ||
for (int i = 1; i <= (nrows - 2); i++) { | ||
hrow_map(i) = cnt; | ||
hentries(cnt) = -1 + i; | ||
hentries(cnt + 1) = 0 + i; | ||
hentries(cnt + 2) = 1 + i; | ||
hvalues(cnt) = -1 + i; | ||
hvalues(cnt + 1) = 0 + i; | ||
hvalues(cnt + 2) = 1 + i; | ||
cnt += 3; | ||
} | ||
// last row | ||
hrow_map(nrows - 1) = cnt; | ||
hentries(nnz - 2) = nrows - 2; | ||
hentries(nnz - 1) = nrows - 1; | ||
hvalues(nnz - 2) = nrows - 2; | ||
hvalues(nnz - 1) = nrows - 1; | ||
// last element of row_map | ||
hrow_map(nrows) = nnz; | ||
|
||
// Allocate A on device memory | ||
RowMapType row_map("row_map", nrows + 1); | ||
EntriesType entries("entries", nnz); | ||
ValuesType values("values", nnz); | ||
|
||
// Copy from host to device | ||
Kokkos::deep_copy(row_map, hrow_map); | ||
Kokkos::deep_copy(entries, hentries); | ||
Kokkos::deep_copy(values, hvalues); | ||
|
||
// Construct a CRS matrix | ||
A = crsMat_t("CrsMatrix", nrows, nrows, nnz, values, row_map, entries); | ||
} | ||
|
||
// Extract | ||
KokkosSparse::Impl::kk_extract_diagonal_blocks_crsmatrix_sequential(A, | ||
DiagBlks); | ||
|
||
// Checking | ||
lno_t numRows = 0; | ||
lno_t numCols = 0; | ||
for (int i = 0; i < nblocks; i++) { | ||
numRows += DiagBlks[i].numRows(); | ||
numCols += DiagBlks[i].numCols(); | ||
} | ||
|
||
EXPECT_TRUE(numRows == static_cast<lno_t>(nrows)); | ||
EXPECT_TRUE(numCols == static_cast<lno_t>(nrows)); | ||
|
||
if (nrows > 0) { | ||
bool flag = true; | ||
lno_t col_start = 0; | ||
for (int i = 0; i < nblocks; i++) { | ||
RowMapType_hm hrow_map_diagblk("hrow_map_diagblk", | ||
DiagBlks[i].numRows() + 1); | ||
EntriesType_hm hentries_diagblk("hentries_diagblk", DiagBlks[i].nnz()); | ||
ValuesType_hm hvalues_diagblk("hvalues_diagblk", DiagBlks[i].nnz()); | ||
|
||
Kokkos::deep_copy(hrow_map_diagblk, DiagBlks[i].graph.row_map); | ||
Kokkos::deep_copy(hentries_diagblk, DiagBlks[i].graph.entries); | ||
Kokkos::deep_copy(hvalues_diagblk, DiagBlks[i].values); | ||
|
||
for (int j = 0; j < static_cast<int>(DiagBlks[i].numRows()); j++) { | ||
size_type k1 = hrow_map_diagblk(j); | ||
size_type k2 = hrow_map_diagblk(j + 1); | ||
for (size_type k = k1; k < k2; k++) { | ||
scalar_t col = static_cast<scalar_t>(hentries_diagblk(k) + col_start); | ||
scalar_t val = hvalues_diagblk(k); | ||
if (Kokkos::abs(col - val) != 0) { | ||
flag = false; | ||
break; | ||
} | ||
} | ||
if (flag == false) break; | ||
} | ||
if (flag == false) break; | ||
col_start += DiagBlks[i].numCols(); | ||
} | ||
EXPECT_TRUE(flag); | ||
} | ||
} | ||
} // namespace Test | ||
|
||
template <typename scalar_t, typename lno_t, typename size_type, | ||
typename device> | ||
void test_extract_diagonal_blocks() { | ||
for (int s = 1; s <= 8; s++) { | ||
Test::run_test_extract_diagonal_blocks<scalar_t, lno_t, size_type, device>( | ||
0, s); | ||
Test::run_test_extract_diagonal_blocks<scalar_t, lno_t, size_type, device>( | ||
12, s); | ||
Test::run_test_extract_diagonal_blocks<scalar_t, lno_t, size_type, device>( | ||
123, s); | ||
} | ||
} | ||
|
||
#define KOKKOSKERNELS_EXECUTE_TEST(SCALAR, ORDINAL, OFFSET, DEVICE) \ | ||
TEST_F( \ | ||
TestCategory, \ | ||
sparse##_##extract_diagonal_blocks##_##SCALAR##_##ORDINAL##_##OFFSET##_##DEVICE) { \ | ||
test_extract_diagonal_blocks<SCALAR, ORDINAL, OFFSET, DEVICE>(); \ | ||
} | ||
|
||
#include <Test_Common_Test_All_Type_Combos.hpp> | ||
|
||
#undef KOKKOSKERNELS_EXECUTE_TEST |