TiledArray includes a set of functions that allows you to convert DistArray
objects to and from 2D block-cyclic distributions, such as those used by the ScaLAPACK library. These conversions and subsequent linear algebra bindings are facilitated through the [blacspp]() and [scalapackpp]() libraries with provide modern C++ wrappers around the BLACS and ScaLAPACK libraries.
As the target of the 2D block-cyclic conversions is for compatibility with ScaLAPACK, the conversion utilities are only to be used with rank 2 Tensor
s. Further, the internal value_type
of the DistArray
must be ScaLAPACK compatible, i.e. float
, double
, std::complex<float>
, std::complex<double>
. If either of these conditions are not met, the conversion utilities will throw an error.
The ScaLAPACKMatrix class
TiledArray provides a helper class which enables the conversion of DistArray
objects to 2D block-cyclic distribution formats. It extends the concept of a madness::WorldObject
.
Public Class API
template <typename T,
typename = scalapackpp::detail::enable_if_scalapack_supported_t<T>>
class ScaLAPACKMatrix {
ScaLAPACKMatrix(madness::World& world, const blacspp::Grid& grid, size_t M,
size_t N, size_t MB, size_t NB);
ScaLAPACKMatrix(const TArray<T>& array, const blacspp::Grid& grid, size_t MB,
size_t NB);
};
Converting between DistArray<T>
Object and ScaLAPACKMatrix<T>
TArray<T> tensor(...);
auto& tensor_world = tensor.world();
MPI_Comm tensor_comm = tensor_world.mpi.comm().Get_mpi_comm();
blacspp::Grid grid = blacspp::Grid::square_grid(tensor_comm);
size_t MB = 128;
size_t NB = 128;
ScaLAPACKMatrix<T> matrix( tensor, grid, MB, NB );
auto [M, N] = matrix.dims();
auto [Mloc, Nloc] = matrix.dist().get_local_dims();
auto desc = matrix.dist().descinit_noerror(M, N, Mloc);
tensor_world.gop().fence();
assert( M == N );
assert( MB == NB );
ScaLAPACKMatrix<T> evec( tensor_world, grid, M, M, MB, MB );
std::vector<scalapackpp::detail::real_t<T>> eval( M );
auto info = scalapackpp::hereig(
scalapackpp::VectorFlag::Vectors,
blacspp::Triangle::Lower,
M, matrix.local_mat().data(), 1, 1, desc, eval.data(),
evec.local_mat().data(), 1, 1, desc
);
assert( info == 0 );
tensor_world.gop().fence();
auto evec_tensor = evec.tensor_from_matrix( tensor.trange() );