diff --git a/src/sparse/KokkosSparse_CrsMatrix.hpp b/src/sparse/KokkosSparse_CrsMatrix.hpp index d734d9ac3a..3ce574602c 100644 --- a/src/sparse/KokkosSparse_CrsMatrix.hpp +++ b/src/sparse/KokkosSparse_CrsMatrix.hpp @@ -554,7 +554,37 @@ class CrsMatrix { OrdinalType* rowmap, OrdinalType* cols) { - ctor_impl (label, nrows, ncols, annz, val, rowmap, cols); + using Kokkos::Unmanaged; + using HostRowmap = Kokkos::View; + using UnmanagedRowmap = Kokkos::View>; + using UnmanagedEntries = Kokkos::View>; + using UnmanagedValues = Kokkos::View>; + //Allocate device rowmap, entries, values views + typename row_map_type::non_const_type rowmapDevice(Kokkos::ViewAllocateWithoutInitializing("rowmap"), nrows + 1); + index_type entriesDevice(Kokkos::ViewAllocateWithoutInitializing("entries"), annz); + //given rowmap in ordinal_type, so may need to convert to size_type explicitly + HostRowmap rowmapConverted; + UnmanagedRowmap rowmapRaw; + if(!std::is_same::value) + { + rowmapConverted = HostRowmap(Kokkos::ViewAllocateWithoutInitializing("rowmap raw"), nrows + 1); + for(OrdinalType i = 0; i <= nrows; i++) + rowmapConverted(i) = rowmap[i]; + rowmapRaw = rowmapConverted; + } + else + { + rowmapRaw = UnmanagedRowmap((const SizeType*) rowmap, nrows + 1); + } + Kokkos::deep_copy(rowmapDevice, rowmapRaw); + UnmanagedEntries entriesRaw(cols, annz); + Kokkos::deep_copy(entriesDevice, entriesRaw); + //Construct graph and populate all members + this->numCols_ = ncols; + this->graph = StaticCrsGraphType(entriesDevice, rowmapDevice); + this->values = values_type(Kokkos::ViewAllocateWithoutInitializing("values"), annz); + UnmanagedValues valuesRaw(val, annz); + Kokkos::deep_copy(this->values, valuesRaw); // FIXME (mfh 09 Aug 2013) Specialize this on the Device type. // Only use cuSPARSE for the Cuda Device. @@ -646,15 +676,6 @@ class CrsMatrix { #endif // KOKKOS_USE_CUSPARSE } - void - ctor_impl (const std::string &label, - const OrdinalType nrows, - const OrdinalType ncols, - const size_type annz, - ScalarType* val, - OrdinalType* rows, - OrdinalType* cols); - KOKKOS_INLINE_FUNCTION OrdinalType sumIntoValues (const OrdinalType rowi, @@ -883,50 +904,5 @@ class CrsMatrix { ordinal_type numCols_; }; -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- - -template< typename ScalarType , typename OrdinalType, class Device, class MemoryTraits, typename SizeType > -void -CrsMatrix:: -ctor_impl (const std::string &label, - const OrdinalType nrows, - const OrdinalType ncols, - const size_type annz, - ScalarType* val, - OrdinalType* rows, - OrdinalType* cols) -{ - std::string str = label; - values = values_type (str.append (".values"), annz); - - numCols_ = ncols; - - // FIXME (09 Aug 2013) CrsArray only takes std::vector for now. - // We'll need to fix that. - std::vector row_lengths (nrows, 0); - - // FIXME (mfh 21 Jun 2013) This calls for a parallel_for kernel. - for (OrdinalType i = 0; i < nrows; ++i) { - row_lengths[i] = rows[i + 1] - rows[i]; - } - - graph = Kokkos::create_staticcrsgraph (str.append (".graph"), row_lengths); - typename values_type::HostMirror h_values = Kokkos::create_mirror_view (values); - typename index_type::HostMirror h_entries = Kokkos::create_mirror_view (graph.entries); - - // FIXME (mfh 21 Jun 2013) This needs to be a parallel copy. - // Furthermore, why are the arrays copied twice? -- once here, to a - // host view, and once below, in the deep copy? - for (size_type i = 0; i < annz; ++i) { - if (val) { - h_values(i) = val[i]; - } - h_entries(i) = cols[i]; - } - - Kokkos::deep_copy (values, h_values); - Kokkos::deep_copy (graph.entries, h_entries); -} } #endif diff --git a/unit_test/sparse/Test_Sparse_CrsMatrix.hpp b/unit_test/sparse/Test_Sparse_CrsMatrix.hpp index 792bb56466..facdafa28a 100644 --- a/unit_test/sparse/Test_Sparse_CrsMatrix.hpp +++ b/unit_test/sparse/Test_Sparse_CrsMatrix.hpp @@ -192,6 +192,26 @@ testCrsMatrix () //printf ("A is %d by %d\n", A.numRows (), A.numCols ()); } +template +void +testCrsMatrixRawConstructor() +{ + int nrows = 5; + //note: last 2 columns will be empty. + //This makes sure the ncols provided to constructor is preserved. + int ncols = 7; + int nnz = 9; + //NOTE: this is not a mistake, the raw ptr constructor takes rowmap as ordinal. + std::vector rowmap = {0, 0, 2, 5, 6, 9}; + std::vector entries = {3, 4, 0, 1, 2, 2, 0, 3, 4}; + std::vector values(nnz, Kokkos::ArithTraits::one()); + KokkosSparse::CrsMatrix A( + "A", nrows, ncols, nnz, values.data(), rowmap.data(), entries.data()); + EXPECT_EQ(A.numRows(), nrows); + EXPECT_EQ(A.numCols(), ncols); + EXPECT_EQ(A.nnz(), nnz); +} + template void testCrsMatrixHostMirror () @@ -229,6 +249,7 @@ testCrsMatrixHostMirror () #define EXECUTE_TEST(SCALAR, ORDINAL, OFFSET, DEVICE) \ TEST_F( TestCategory, sparse ## _ ## crsmatrix ## _ ## SCALAR ## _ ## ORDINAL ## _ ## OFFSET ## _ ## DEVICE ) { \ testCrsMatrix (); \ + testCrsMatrixRawConstructor (); \ } \ TEST_F( TestCategory, sparse ## _ ## crsmatrix_host_mirror ## _ ## SCALAR ## _ ## ORDINAL ## _ ## OFFSET ## _ ## DEVICE ) { \ testCrsMatrixHostMirror (); \