Classes | |
| struct | ArrayHandlerError |
| class | BufferManager |
| BufferManager provides single-buffered or asynchronous double-buffered read access to the data in a collection of DistrArray objects. At construction, an amount of memory is allocated as a buffer, and the buffer is divided into one or more chunks that are independent windows on the data. Sequential access to the data is provided through iterators. More... | |
| struct | CompareAbs |
| class | DistrArrayIteratorImpl |
| struct | DistrChunks |
| The pointers to, and on completion the write-back of, chunks of distributed arrays yy for gemm_buffered() More... | |
| class | DistrFlags |
| Distributed array of integer flags with one flag per process and a locking mechanism to ensure atomic access. More... | |
| class | Distribution |
| Specifies distribution of a contiguous array into non-overlapping chunks. More... | |
| struct | is_allocatable |
| struct | is_allocatable< T, std::enable_if_t< std::is_constructible_v< T, std::size_t > > > |
| struct | is_std_array |
| struct | is_std_array< std::array< T, N > > |
| class | LockMPI3 |
| Atomic lock allowing only one process to acquire it. Implemented using MPI3 RMA. More... | |
| struct | OperationRegister |
| struct | RefEqual |
| When called returns true if addresses of two references are the same. More... | |
| class | ScopeLock |
| Utility object that locks on creation and unlocks on destruction. More... | |
| class | Task |
| struct | TempHandle |
| Static registrar of temporary handles. More... | |
| class | ValueProxy |
Enumerations | |
| enum | gemm_type { inner , outer } |
Functions | |
| template<typename X , typename Y , typename Z , class EqualX , class EqualY , class EqualZ > | |
| std::tuple< std::vector< std::tuple< size_t, size_t, size_t > >, std::vector< X >, std::vector< Y >, std::vector< Z > > | remove_duplicates (const std::list< std::tuple< X, Y, Z > > ®, EqualX equal_x, EqualY equal_y, EqualZ equal_z) |
| Find duplicates references to x and y arrays and store unique elements in a separate vector. | |
| template<class Compare > | |
| std::list< std::pair< DistrArray::index_type, DistrArray::value_type > > | extrema (const DistrArray &x, int n) |
| std::map< size_t, double > | select_max_dot_broadcast (size_t n, std::map< size_t, double > &local_selection, MPI_Comm communicator) |
| template<typename T > | |
| T | allocate_like (std::size_t size) |
| Creates an array of type T able to hold size elements. | |
| template<class R > | |
| auto | contiguous_span (R &r) |
| A view of all the elements of a contiguous array. | |
| template<typename Ind > | |
| Distribution< Ind > | make_distribution_spread_remainder (size_t dimension, int n_chunks) |
| Creates a distribution with first (dimension % n_chunks) chunks larger by 1 element. | |
| template<class X , typename value_type , typename std::enable_if< std::is_compound< value_type >::value, value_type >::type * = nullptr> | |
| std::map< size_t, value_type > | select (size_t n, const X &x, bool max=false, bool ignore_sign=false) |
| Select n indices with largest (or smallest) actual (or absolute) value. | |
| template<class X , typename value_type , typename std::enable_if<!std::is_compound< value_type >::value, value_type >::type * = nullptr> | |
| auto | select (size_t n, const X &x, bool max=false, bool ignore_sign=false) |
| template<class X , typename value_type , typename std::enable_if< std::is_compound< value_type >::value, value_type >::type * = nullptr> | |
| std::map< size_t, value_type > | select_sparse (size_t n, const X &x, bool max=false, bool ignore_sign=false) |
| Select n indices with largest (or smallest) actual (or absolute) value. | |
| template<class X , typename value_type , typename std::enable_if<!std::is_compound< value_type >::value, value_type >::type * = nullptr> | |
| auto | select_sparse (size_t n, const X &x, bool max=false, bool ignore_sign=false) |
| template<class X , class Y , typename value_type , typename value_type_abs > | |
| auto | select_max_dot (size_t n, const X &x, const Y &y) |
| Select n indices with largest by absolute value contributions to the dot product. | |
| template<class X , class Y , typename value_type , typename value_type_abs > | |
| auto | select_max_dot_iter_sparse (size_t n, const X &x, const Y &y) |
| Select n indices with largest by absolute value contributions to the dot product. | |
| template<class X , class Y , typename value_type , typename value_type_abs > | |
| auto | select_max_dot_sparse (size_t n, const X &x, const Y &y) |
| Select n indices with largest by absolute value contributions to the dot product. | |
| fs::path | temp_file_name (const fs::path &base_name, const std::string &suffix) |
| Returns random file name for a temporary file. | |
| template<class A > | |
| auto | local_range (const A &a) |
| The section [lo, hi) of a distributed array held by this process. | |
| template<class T > | |
| size_t | constant_stride (const std::vector< T * > &p, size_t n) |
| template<class T > | |
| std::vector< T * > | offset_pointers (const std::vector< T * > &bases, size_t lo, size_t g) |
| Pointers to elements [g, ...) of arrays whose local sections, starting at global index lo, are at bases. | |
| template<class T , class A > | |
| std::vector< T * > | local_buffer_pointers (const std::vector< std::reference_wrapper< A > > &aa) |
| Pointers to the start of the local sections of distributed arrays held in memory. | |
| template<class A , class Range > | |
| void | check_local_ranges (const std::vector< std::reference_wrapper< A > > &aa, const Range &range, const std::string &name) |
| Checks that the distributed arrays aa all have the local section range, so that they can be processed together. | |
| template<class T , class R , class A > | |
| std::vector< T * > | contiguous_pointers (const std::vector< std::reference_wrapper< R > > &rr, const A &q, const std::string &name) |
| Pointers to the elements of contiguous arrays rr, offset to the start of the local section of the distributed array q. | |
| template<class T > | |
| void | gemm_chunk (gemm_type type, size_t n, const T *x, size_t ldx, size_t nx, T *alphadata, const std::vector< T * > &y) |
| One chunk of n elements of a gemm between the arrays xx, which are the nx columns of x with leading dimension ldx, and the arrays yy at pointers y. | |
| template<class AD , class T = typename AD::value_type> | |
| void | gemm_buffered (T *alphadata, const CVecRef< AD > &xx, const std::type_identity_t< std::function< std::vector< T * >(size_t g, size_t n)> > &y_pointers, const std::function< void(size_t g, size_t n)> &y_done, gemm_type type) |
| gemm between distributed arrays xx, read through a BufferManager, and arrays yy, which can be held anywhere. | |
| template<class AD , class T = typename AD::value_type> | |
| Matrix< T > | gemm_inner_buffered (size_t ny, const CVecRef< AD > &xx, const std::type_identity_t< std::function< std::vector< T * >(size_t g, size_t n)> > &y_pointers, const std::function< void(size_t g, size_t n)> &y_done={}) |
| The overlap matrix between arrays yy, accessed as described in gemm_buffered(), and distributed arrays xx, which are read through a BufferManager. Collective. | |
| template<class T > | |
| void | check_gemm_outer_dimensions (const Matrix< T > &alphas, size_t nx, size_t ny, const std::string &name) |
| Checks the dimensions of the coefficient matrix of gemm_outer. | |
| template<class T > | |
| Matrix< T > | conjugate_transpose (const Matrix< T > &m) |
| The transpose of an overlap matrix, which for the hermitian inner product is its conjugate transpose. | |
| template<class AD , class T = typename AD::value_type> | |
| void | gemm_outer_to_distr (const Matrix< T > &alphas, const std::vector< T * > &x_bases, const VecRef< AD > &yy) |
| yy += alphas^T xx, for arrays xx held in memory and distributed arrays yy held anywhere. | |
| template<class AL , class AD , std::enable_if_t< is_disk_array_v< AD >, int > = 0> | |
| Matrix< typename array::mapped_or_value_type_t< AL > > | gemm_inner_distr_distr (const CVecRef< AL > &yy, const CVecRef< AD > &xx) |
| template<class AD , class AL , std::enable_if_t< is_disk_array_v< AD > and not is_disk_array_v< AL >, int > = 0> | |
| Matrix< typename array::mapped_or_value_type_t< AL > > | gemm_inner_distr_distr (const CVecRef< AD > &xx, const CVecRef< AL > &yy) |
| template<class AL , class AD , std::enable_if_t< is_disk_array_v< AD >, int > = 0> | |
| void | gemm_outer_distr_distr (const Matrix< typename array::mapped_or_value_type_t< AL > > alphas, const CVecRef< AD > &xx, const VecRef< AL > &yy) |
| template<class R , class AD > | |
| Matrix< typename AD::value_type > | gemm_inner_contiguous_distr (const CVecRef< R > &rr, const CVecRef< AD > &qq) |
| The overlap matrix (rr.size(), qq.size()) between contiguous arrays rr and distributed arrays qq. Collective. | |
| template<class AD , class R > | |
| Matrix< typename AD::value_type > | gemm_inner_distr_contiguous (const CVecRef< AD > &qq, const CVecRef< R > &rr) |
| The overlap matrix (qq.size(), rr.size()) between distributed arrays qq and contiguous arrays rr. Collective. | |
| template<class AD , class R > | |
| void | gemm_outer_distr_contiguous (const Matrix< typename AD::value_type > &alphas, const CVecRef< AD > &qq, const VecRef< R > &rr) |
| rr += alphas^T qq for contiguous arrays rr and distributed arrays qq. Collective. | |
| template<class R , class AD > | |
| void | gemm_outer_contiguous_distr (const Matrix< typename AD::value_type > &alphas, const CVecRef< R > &rr, const VecRef< AD > &qq) |
| qq += alphas^T rr for contiguous arrays rr and distributed arrays qq. Local. | |
| template<class AL , class AR = AL, std::enable_if_t< not is_disk_array_v< AL > and not is_disk_array_v< AR >, int > = 0> | |
| Matrix< typename array::mapped_or_value_type_t< AL > > | gemm_inner_distr_distr (const CVecRef< AL > &xx, const CVecRef< AR > &yy) |
| template<class AL , class AR = AL, std::enable_if_t< not is_disk_array_v< AR >, int > = 0> | |
| void | gemm_outer_distr_distr (const Matrix< typename array::mapped_or_value_type_t< AL > > alphas, const CVecRef< AR > &xx, const VecRef< AL > &yy) |
| template<class AL , class AR = AL> | |
| void | gemm_outer_distr_sparse (const Matrix< typename array::mapped_or_value_type_t< AL > > alphas, const CVecRef< AR > &xx, const VecRef< AL > &yy) |
| template<class AL , class AR = AL> | |
| Matrix< typename array::mapped_or_value_type_t< AL > > | gemm_inner_distr_sparse (const CVecRef< AL > &xx, const CVecRef< AR > &yy) |
| template<class Handler , class AL , class AR = AL> | |
| void | gemm_outer_default (Handler &handler, const Matrix< typename Handler::value_type > alphas, const CVecRef< AR > &xx, const VecRef< AL > &yy) |
| template<class Handler , class AL , class AR = AL> | |
| Matrix< typename Handler::value_type > | gemm_inner_default (Handler &handler, const CVecRef< AL > &xx, const CVecRef< AR > &yy) |
| void | gather_all (const Distribution< size_t > &distr, MPI_Comm commun, double *first_elem) |
| Replicate data of a full container on all the processes based on distributed pieces. | |
| void | swap (DistrFlags &x, DistrFlags &y) |
Variables | |
| template<typename T > | |
| constexpr bool | is_std_array_v = is_std_array<T>::value |
| template<typename T > | |
| constexpr bool | is_array_v = std::is_array<T>::value || is_std_array_v<T> |
| template<typename T > | |
| constexpr bool | is_allocatable_v = is_allocatable<T>::value |
| template<class A > | |
| constexpr bool | is_disk_array_v = std::is_base_of_v<DistrArrayDisk, std::decay_t<A>> |
| Whether arrays of type A are held on disk, and so must be read through buffers rather than local_buffer() | |
| T molpro::linalg::array::util::allocate_like | ( | std::size_t | size | ) |
Creates an array of type T able to hold size elements.
Fixed-size arrays are default constructed, types constructible from a size are constructed from it, and any other type is created by the customization point allocate_array().
| void molpro::linalg::array::util::check_gemm_outer_dimensions | ( | const Matrix< T > & | alphas, |
| size_t | nx, | ||
| size_t | ny, | ||
| const std::string & | name | ||
| ) |
Checks the dimensions of the coefficient matrix of gemm_outer.
| void molpro::linalg::array::util::check_local_ranges | ( | const std::vector< std::reference_wrapper< A > > & | aa, |
| const Range & | range, | ||
| const std::string & | name | ||
| ) |
Checks that the distributed arrays aa all have the local section range, so that they can be processed together.
| Matrix< T > molpro::linalg::array::util::conjugate_transpose | ( | const Matrix< T > & | m | ) |
The transpose of an overlap matrix, which for the hermitian inner product is its conjugate transpose.
| size_t molpro::linalg::array::util::constant_stride | ( | const std::vector< T * > & | p, |
| size_t | n | ||
| ) |
Returns the constant distance between consecutive arrays at pointers p, if they are the columns of a matrix with n rows, or 0 if they are not. A single array is given the stride n.
| std::vector< T * > molpro::linalg::array::util::contiguous_pointers | ( | const std::vector< std::reference_wrapper< R > > & | rr, |
| const A & | q, | ||
| const std::string & | name | ||
| ) |
Pointers to the elements of contiguous arrays rr, offset to the start of the local section of the distributed array q.
| std::out_of_range | if any of rr differs from q in size |
| auto molpro::linalg::array::util::contiguous_span | ( | R & | r | ) |
A view of all the elements of a contiguous array.
|
protected |
|
inline |
Replicate data of a full container on all the processes based on distributed pieces.
| distr | distribution of the container, which local data chuncks are to be replicated |
| commun | MPI communicator |
| first_elem | pointer to the beginning of the container, which data to be replicated |
Does nothing without MPI, or on a single process, when the container already holds all the data.
| void molpro::linalg::array::util::gemm_buffered | ( | T * | alphadata, |
| const CVecRef< AD > & | xx, | ||
| const std::type_identity_t< std::function< std::vector< T * >(size_t g, size_t n)> > & | y_pointers, | ||
| const std::function< void(size_t g, size_t n)> & | y_done, | ||
| gemm_type | type | ||
| ) |
gemm between distributed arrays xx, read through a BufferManager, and arrays yy, which can be held anywhere.
Only the local section of xx is processed, chunk by chunk. For each chunk of global indices [g, g+n), y_pointers(g, n) returns pointers to the same elements of each of yy, and y_done(g, n) is called once the chunk is complete, e.g. to write back yy updated by gemm_type::outer.
| alphadata | see gemm_chunk(), with nx = xx.size() and ny the number of yy |
| void molpro::linalg::array::util::gemm_chunk | ( | gemm_type | type, |
| size_t | n, | ||
| const T * | x, | ||
| size_t | ldx, | ||
| size_t | nx, | ||
| T * | alphadata, | ||
| const std::vector< T * > & | y | ||
| ) |
One chunk of n elements of a gemm between the arrays xx, which are the nx columns of x with leading dimension ldx, and the arrays yy at pointers y.
inner: alphadata[i + k * nx] += x_i . y_k outer: y_k += sum_i alphadata[i * ny + k] * x_i
This is a single dgemm. If yy are not evenly spaced, they are first packed into one matrix, which an outer product then updates before it is copied back.
| Matrix< T > molpro::linalg::array::util::gemm_inner_buffered | ( | size_t | ny, |
| const CVecRef< AD > & | xx, | ||
| const std::type_identity_t< std::function< std::vector< T * >(size_t g, size_t n)> > & | y_pointers, | ||
| const std::function< void(size_t g, size_t n)> & | y_done = {} |
||
| ) |
The overlap matrix between arrays yy, accessed as described in gemm_buffered(), and distributed arrays xx, which are read through a BufferManager. Collective.
| Matrix< typename AD::value_type > molpro::linalg::array::util::gemm_inner_contiguous_distr | ( | const CVecRef< R > & | rr, |
| const CVecRef< AD > & | |||
| ) |
The overlap matrix (rr.size(), qq.size()) between contiguous arrays rr and distributed arrays qq. Collective.
| Matrix< typename Handler::value_type > molpro::linalg::array::util::gemm_inner_default | ( | Handler & | handler, |
| const CVecRef< AL > & | xx, | ||
| const CVecRef< AR > & | yy | ||
| ) |
| Matrix< typename AD::value_type > molpro::linalg::array::util::gemm_inner_distr_contiguous | ( | const CVecRef< AD > & | qq, |
| const CVecRef< R > & | rr | ||
| ) |
The overlap matrix (qq.size(), rr.size()) between distributed arrays qq and contiguous arrays rr. Collective.
| Matrix< typename array::mapped_or_value_type_t< AL > > molpro::linalg::array::util::gemm_inner_distr_distr | ( | const CVecRef< AD > & | xx, |
| const CVecRef< AL > & | yy | ||
| ) |
| Matrix< typename array::mapped_or_value_type_t< AL > > molpro::linalg::array::util::gemm_inner_distr_distr | ( | const CVecRef< AL > & | xx, |
| const CVecRef< AR > & | yy | ||
| ) |
| Matrix< typename array::mapped_or_value_type_t< AL > > molpro::linalg::array::util::gemm_inner_distr_distr | ( | const CVecRef< AL > & | yy, |
| const CVecRef< AD > & | xx | ||
| ) |
| Matrix< typename array::mapped_or_value_type_t< AL > > molpro::linalg::array::util::gemm_inner_distr_sparse | ( | const CVecRef< AL > & | xx, |
| const CVecRef< AR > & | yy | ||
| ) |
| void molpro::linalg::array::util::gemm_outer_contiguous_distr | ( | const Matrix< typename AD::value_type > & | alphas, |
| const CVecRef< R > & | rr, | ||
| const VecRef< AD > & | |||
| ) |
qq += alphas^T rr for contiguous arrays rr and distributed arrays qq. Local.
| void molpro::linalg::array::util::gemm_outer_default | ( | Handler & | handler, |
| const Matrix< typename Handler::value_type > | alphas, | ||
| const CVecRef< AR > & | xx, | ||
| const VecRef< AL > & | yy | ||
| ) |
| void molpro::linalg::array::util::gemm_outer_distr_contiguous | ( | const Matrix< typename AD::value_type > & | alphas, |
| const CVecRef< AD > & | qq, | ||
| const VecRef< R > & | rr | ||
| ) |
rr += alphas^T qq for contiguous arrays rr and distributed arrays qq. Collective.
| void molpro::linalg::array::util::gemm_outer_distr_distr | ( | const Matrix< typename array::mapped_or_value_type_t< AL > > | alphas, |
| const CVecRef< AD > & | xx, | ||
| const VecRef< AL > & | yy | ||
| ) |
| void molpro::linalg::array::util::gemm_outer_distr_distr | ( | const Matrix< typename array::mapped_or_value_type_t< AL > > | alphas, |
| const CVecRef< AR > & | xx, | ||
| const VecRef< AL > & | yy | ||
| ) |
| void molpro::linalg::array::util::gemm_outer_distr_sparse | ( | const Matrix< typename array::mapped_or_value_type_t< AL > > | alphas, |
| const CVecRef< AR > & | xx, | ||
| const VecRef< AL > & | yy | ||
| ) |
| void molpro::linalg::array::util::gemm_outer_to_distr | ( | const Matrix< T > & | alphas, |
| const std::vector< T * > & | x_bases, | ||
| const VecRef< AD > & | yy | ||
| ) |
yy += alphas^T xx, for arrays xx held in memory and distributed arrays yy held anywhere.
Only the local section of yy is processed, in pages. Pages of yy without a local buffer are read with get() and written back with put(), so that each element is read and written once. x_bases are pointers to the starts of the local sections of xx; unless they are evenly spaced, each page of them is first packed into one matrix, so that the update is always a single dgemm.
| std::vector< T * > molpro::linalg::array::util::local_buffer_pointers | ( | const std::vector< std::reference_wrapper< A > > & | aa | ) |
Pointers to the start of the local sections of distributed arrays held in memory.
| auto molpro::linalg::array::util::local_range | ( | const A & | a | ) |
The section [lo, hi) of a distributed array held by this process.
| Distribution< Ind > molpro::linalg::array::util::make_distribution_spread_remainder | ( | size_t | dimension, |
| int | n_chunks | ||
| ) |
Creates a distribution with first (dimension % n_chunks) chunks larger by 1 element.
| Ind | integer type for indexing the array |
| dimension | number of elements in array |
| n_chunks | number of chunks to subdivide the array into |
| std::vector< T * > molpro::linalg::array::util::offset_pointers | ( | const std::vector< T * > & | bases, |
| size_t | lo, | ||
| size_t | g | ||
| ) |
Pointers to elements [g, ...) of arrays whose local sections, starting at global index lo, are at bases.
| std::tuple< std::vector< std::tuple< size_t, size_t, size_t > >, std::vector< X >, std::vector< Y >, std::vector< Z > > molpro::linalg::array::util::remove_duplicates | ( | const std::list< std::tuple< X, Y, Z > > & | reg, |
| EqualX | equal_x, | ||
| EqualY | equal_y, | ||
| EqualZ | equal_z | ||
| ) |
Find duplicates references to x and y arrays and store unique elements in a separate vector.
Vector of scalars is returned complete without truncation. The register becomes a vector of pairs, first element of a pair containing index of x array in the vector of unique x arrays, the second is for y arrays.
| std::map< size_t, value_type > molpro::linalg::array::util::select | ( | size_t | n, |
| const X & | x, | ||
| bool | max = false, |
||
| bool | ignore_sign = false |
||
| ) |
Select n indices with largest (or smallest) actual (or absolute) value.
| X | type of array, must be iterable complete array |
| value_type | type for X elements |
| value_type_abs | type for absolute value of value_type |
| n | number of indices to select |
| x | array to examine |
| max | If true, select largest values, otherwise smallest |
| ignore_sign | If true, consider std::abs() of elements |
| auto molpro::linalg::array::util::select | ( | size_t | n, |
| const X & | x, | ||
| bool | max = false, |
||
| bool | ignore_sign = false |
||
| ) |
| auto molpro::linalg::array::util::select_max_dot | ( | size_t | n, |
| const X & | x, | ||
| const Y & | y | ||
| ) |
Select n indices with largest by absolute value contributions to the dot product.
| X | type of left array, must be iterable complete array |
| Y | type of right array, must be iterable complete array |
| value_type | type for product of X and Y elements |
| value_type_abs | type for absolute value of value_type |
| n | number of indices to select |
| x | left array |
| y | right array |
|
protected |
| auto molpro::linalg::array::util::select_max_dot_iter_sparse | ( | size_t | n, |
| const X & | x, | ||
| const Y & | y | ||
| ) |
Select n indices with largest by absolute value contributions to the dot product.
| X | type of left array, must be random access container |
| Y | type of right array, must be a sparse array |
| value_type | type for product of X and Y elements |
| value_type_abs | type for absolute value of value_type |
| n | number of indices to select |
| x | left array |
| y | right array |
| auto molpro::linalg::array::util::select_max_dot_sparse | ( | size_t | n, |
| const X & | x, | ||
| const Y & | y | ||
| ) |
Select n indices with largest by absolute value contributions to the dot product.
| X | type of left array, must be a sparse array |
| Y | type of right array, must be a sparse array |
| value_type | type for product of X and Y elements |
| value_type_abs | type for absolute value of value_type |
| n | number of indices to select |
| x | left array |
| y | right array |
| std::map< size_t, value_type > molpro::linalg::array::util::select_sparse | ( | size_t | n, |
| const X & | x, | ||
| bool | max = false, |
||
| bool | ignore_sign = false |
||
| ) |
Select n indices with largest (or smallest) actual (or absolute) value.
| X | type of array, must be iterable complete array |
| value_type | type for X elements |
| n | number of indices to select |
| x | array to examine |
| max | If true, select largest values, otherwise smallest |
| ignore_sign | If true, consider std::abs() of elements |
Select n indices with largest (or smallest) actual (or absolute) value
| X | type of array, must be iterable complete array |
| value_type | type for X elements |
| value_type_abs | type for absolute value of value_type |
| n | number of indices to select |
| x | array to examine |
| max | If true, select largest values, otherwise smallest |
| ignore_sign | If true, consider std::abs() of elements |
| auto molpro::linalg::array::util::select_sparse | ( | size_t | n, |
| const X & | x, | ||
| bool | max = false, |
||
| bool | ignore_sign = false |
||
| ) |
| void molpro::linalg::array::util::swap | ( | DistrFlags & | x, |
| DistrFlags & | y | ||
| ) |
| fs::path molpro::linalg::array::util::temp_file_name | ( | const fs::path & | base_name, |
| const std::string & | suffix | ||
| ) |
Returns random file name for a temporary file.
| base_name | base name for the file, after which a random character string will follow |
| suffix | suffix to add to the file name e.g. ".hdf5" |
|
constexpr |
|
constexpr |
|
inlineconstexpr |
Whether arrays of type A are held on disk, and so must be read through buffers rather than local_buffer()
|
constexpr |