35#ifndef OPM_SPARSETABLE_HEADER
36#define OPM_SPARSETABLE_HEADER
38#include <opm/grid/utility/ErrorMacros.hpp>
39#include <opm/grid/utility/IteratorRange.hpp>
42#include <opm/common/utility/gpuistl_if_available.hpp>
57inline constexpr bool always_false_v =
false;
63struct PoisonIterator {
65 using iterator_category = std::input_iterator_tag;
67 using difference_type = std::ptrdiff_t;
71 PoisonIterator() =
default;
74 reference operator*()
const {
75 static_assert(always_false_v<T>,
"PoisonIterator: operator*() is not allowed.");
79 pointer operator->()
const {
80 static_assert(always_false_v<T>,
"PoisonIterator: operator->() is not allowed.");
85 PoisonIterator& operator++() {
86 static_assert(always_false_v<T>,
"PoisonIterator: operator++() is not allowed.");
91 PoisonIterator operator++(
int) {
92 static_assert(always_false_v<T>,
"PoisonIterator: operator++(int) is not allowed.");
97 friend bool operator==(
const PoisonIterator&,
const PoisonIterator&) {
98 static_assert(always_false_v<T>,
"PoisonIterator: operator== is not allowed.");
102 friend bool operator!=(
const PoisonIterator&,
const PoisonIterator&) {
103 static_assert(always_false_v<T>,
"PoisonIterator: operator!= is not allowed.");
115 template <
typename T,
template <
typename,
typename...>
class Storage = std::vector>
130 template <
typename DataIter,
typename IntegerIter>
132 IntegerIter rowsize_beg, IntegerIter rowsize_end)
133 : data_(data_beg, data_end)
135 setRowStartsFromSizes(rowsize_beg, rowsize_end);
138 SparseTable (Storage<T>&& data, Storage<int>&& row_starts)
139 : data_(std::move(data))
140 , row_start_(std::move(row_starts))
144 if constexpr (std::is_same_v<Storage<T>, std::vector<T>>) {
145 OPM_ERROR_IF(row_start_.size() == 0 || row_start_[0] != 0,
146 "Invalid row_start array");
157 template <
typename DataIter,
typename IntegerIter>
158 void assign(DataIter data_beg, DataIter data_end,
159 IntegerIter rowsize_beg, IntegerIter rowsize_end)
161 data_.assign(data_beg, data_end);
162 setRowStartsFromSizes(rowsize_beg, rowsize_end);
169 template <
typename IntegerIter>
170 void allocate(IntegerIter rowsize_beg, IntegerIter rowsize_end)
172 typedef typename Storage<T>::size_type sz_t;
174 sz_t ndata = std::accumulate(rowsize_beg, rowsize_end, sz_t(0));
176 setRowStartsFromSizes(rowsize_beg, rowsize_end);
181 template <
typename DataIter>
184 data_.insert(data_.end(), row_beg, row_end);
185 row_start_.push_back(data_.size());
191 return row_start_.size()==1;
195 OPM_HOST_DEVICE
int size()
const
197 return row_start_.size() - 1;
201 void reserve(
int exptd_nrows,
int exptd_ndata)
203 row_start_.reserve(exptd_nrows + 1);
204 data_.reserve(exptd_ndata);
210 row_start_.swap(other.row_start_);
211 data_.swap(other.data_);
224 OPM_ERROR_IF(row < 0 || row >=
size(),
225 "Row index " + std::to_string(row) +
" is out of range");
227 return row_start_[row + 1] - row_start_[row];
234 row_start_.resize(1);
239 template<
class U,
class =
void>
254 template<
typename TT>
261 template<
typename TT>
262 struct row_type_helper<gpuistl::GpuBuffer<TT>> {
268 using row_type =
typename row_type_helper<Storage<T>>::const_type;
269 using mutable_row_type =
typename row_type_helper<Storage<T>>::mutable_type;
274 assert(row >= 0 && row <
size());
275 return row_type{data_.begin()+ row_start_[row],
276 data_.begin() + row_start_[row + 1]};
282 assert(row >= 0 && row <
size());
283 return mutable_row_type{data_.begin() + row_start_[row],
284 data_.begin() + row_start_[row + 1]};
292 OPM_HOST_DEVICE Iterator(
const SparseTable& table,
const int begin_row_index)
294 , row_index_(begin_row_index)
297 OPM_HOST_DEVICE Iterator& operator++()
302 OPM_HOST_DEVICE row_type operator*()
const
304 return table_[row_index_];
306 OPM_HOST_DEVICE
bool operator==(
const Iterator& other)
308 assert(&table_ == &other.table_);
309 return row_index_ == other.row_index_;
311 OPM_HOST_DEVICE
bool operator!=(
const Iterator& other)
313 return !(*
this == other);
321 OPM_HOST_DEVICE Iterator
begin()
const
323 return Iterator(*
this, 0);
325 OPM_HOST_DEVICE Iterator end()
const
327 return Iterator(*
this,
size());
333 return data_ == other.data_ && row_start_ == other.row_start_;
336 template<
class charT,
class traits>
337 void print(std::basic_ostream<charT, traits>& os)
const
339 os <<
"Number of rows: " <<
size() <<
'\n';
341 os <<
"Row starts = [";
342 std::ranges::copy(row_start_, std::ostream_iterator<int>(os,
" "));
345 os <<
"Data values = [";
346 std::ranges::copy(data_, std::ostream_iterator<T>(os,
" "));
349 const T data(
int i)
const {
355 const T* dataPtr()
const
361 const Storage<T>& dataStorage()
const
367 const Storage<int>& rowStarts()
const
375 Storage<int> row_start_;
377 template <
class IntegerIter>
378 void setRowStartsFromSizes(IntegerIter rowsize_beg, IntegerIter rowsize_end)
382 for (
auto it = rowsize_beg; it != rowsize_end; ++it) {
384 OPM_THROW(std::runtime_error,
"Negative row size given.");
390 int num_rows = rowsize_end - rowsize_beg;
391 row_start_.resize(num_rows + 1);
393 std::partial_sum(rowsize_beg, rowsize_end, row_start_.begin() + 1);
395 if (
int(data_.size()) != row_start_.back()) {
396 OPM_THROW(std::runtime_error,
"End of row start indices different from data size.");
405namespace Opm::gpuistl {
408auto copy_to_gpu(
const SparseTable<T>& cpu_table)
410 return SparseTable<T, GpuBuffer>(
411 GpuBuffer<T>(cpu_table.dataStorage()),
412 GpuBuffer<int>(cpu_table.rowStarts())
417auto make_view(SparseTable<T, GpuBuffer>& buffer_table)
419 return SparseTable<T, GpuView>(
420 GpuView<T>(
const_cast<T*
>(buffer_table.dataStorage().data()),
421 buffer_table.dataStorage().size()),
422 GpuView<int>(
const_cast<int*
>(buffer_table.rowStarts().data()),
423 buffer_table.rowStarts().size())
OPM_HOST_DEVICE bool operator==(const SparseTable &other) const
Equality.
Definition SparseTable.hpp:331
void swap(SparseTable< T > &other)
Swap contents for other SparseTable<T>.
Definition SparseTable.hpp:208
void reserve(int exptd_nrows, int exptd_ndata)
Allocate storage for table of expected size.
Definition SparseTable.hpp:201
void allocate(IntegerIter rowsize_beg, IntegerIter rowsize_end)
Request storage for table of given size.
Definition SparseTable.hpp:170
OPM_HOST_DEVICE int dataSize() const
Returns the number of data elements.
Definition SparseTable.hpp:215
void clear()
Makes the table empty().
Definition SparseTable.hpp:231
void appendRow(DataIter row_beg, DataIter row_end)
Appends a row to the table.
Definition SparseTable.hpp:182
OPM_HOST_DEVICE bool empty() const
True if the table contains no rows.
Definition SparseTable.hpp:189
OPM_HOST_DEVICE int size() const
Returns the number of rows in the table.
Definition SparseTable.hpp:195
SparseTable()
Default constructor. Yields an empty SparseTable.
Definition SparseTable.hpp:120
OPM_HOST_DEVICE row_type operator[](int row) const
Returns a row of the table.
Definition SparseTable.hpp:272
void assign(DataIter data_beg, DataIter data_end, IntegerIter rowsize_beg, IntegerIter rowsize_end)
Sets the table to contain the given data, organized into rows as indicated by the given row sizes.
Definition SparseTable.hpp:158
SparseTable(DataIter data_beg, DataIter data_end, IntegerIter rowsize_beg, IntegerIter rowsize_end)
A constructor taking all the data for the table and row sizes.
Definition SparseTable.hpp:131
OPM_HOST_DEVICE Iterator begin() const
Iterator access.
Definition SparseTable.hpp:321
OPM_HOST_DEVICE int rowSize(int row) const
Returns the size of a table row.
Definition SparseTable.hpp:221
OPM_HOST_DEVICE mutable_row_type operator[](int row)
Returns a mutable row of the table.
Definition SparseTable.hpp:280
Holds the implementation of the CpGrid as a pimple.
Definition CellQuadrature.cpp:71
Definition SparseTable.hpp:240
Definition IteratorRange.hpp:56
Definition IteratorRange.hpp:76