#include <ScalapackState.h>
class ScalapackState {
public:
// structs
struct DescCacheEntry;
// methods
static ScalapackState& instance();
static int recommended_block_size(int requested_block, int nprocs);
static int recommended_nprow(int nprocs, int block_size);
void initialize(int block_size = 0);
void make_desc(int m, int n, int* desc) const;
int local_rows(int m) const;
int local_cols(int n) const;
int local_index_for_global(int global_index, int block_size, int proc_coord, int nprocs_dim) const;
int global_index_for_local(int local_index, int block_size, int proc_coord, int nprocs_dim) const;
std::vector<double> scatter(const EigenMatrix& global, int m, int n, int* desc) const;
std::vector<double> scatter_root_bcast(const EigenMatrix& global, int m, int n, int* desc) const;
std::vector<double> scatter_colvector_root(const Eigen::VectorXd& global, int m, int* desc) const;
EigenMatrix gather(const double* local, const int* desc, int m, int n, bool broadcast_result = true) const;
Eigen::VectorXd gather_colvector_root(const double* local, const int* desc, int m, bool broadcast_result = true) const;
void cache_L(std::vector<double> L_dist, const int* desc, int n);
bool has_cached_L() const;
const double* cached_L() const;
double* cached_L_mut();
const int* cached_L_desc() const;
int cached_n() const;
void invalidate_L();
void cache_inv(std::vector<double> inv_dist, const int* desc, int n);
bool has_cached_inv() const;
const double* cached_inv() const;
const int* cached_inv_desc() const;
int cached_inv_n() const;
void invalidate_inv();
bool owns_global_entry(int global_row, int global_col) const;
double cached_inv_local_entry(int global_row, int global_col) const;
int context() const;
int nprocs() const;
int myrank() const;
int myrow() const;
int mycol() const;
int nprow() const;
int npcol() const;
int block_size() const;
bool is_root() const;
private:
// construction
~ScalapackState();
};