Redesign_mapping_1d - t-sakashita/rokko GitHub Wiki
local_offset_の廃止
void eigenvector(int k, distributed_vector<double>& vec) const {
vec.initialize(dimension_, offset_local_, offset_local_ + num_local_rows_);
eigenvector(k, vec.get_storage());
}
rokko::distributed_vectorでは、rokko::skel::mapping_1dを継承するか、メンバとするか?
以下のみが未定義のdistributed_mfree_defaultを用いることを推奨する。
virtual void multiply(const double *const x, double *const y) const = 0;
純粋仮想関数のmultiply
が呼び出されてしまう?
py::class_<rokko::heisenberg_mfree, rokko::distributed_mfree>(m, "mfree")
.def(py::init<int, const std::vector<std::pair<int, int>>&>())
.def_property_readonly("dim", &rokko::distributed_mfree_default::get_dim)
.def_property_readonly("num_local_rows", &rokko::distributed_mfree_default::get_num_local_rows)
heisenberg_mfreeクラスのmultiply関数は、Python側に晒されてはいない。 よって、C++内部の問題である。
以下は不要 pyrokko_distributed_mfree.cpp
/*wrap_parameters diagonalize(distributed_mfree_default& mat, wrap_parameters const& params) {
return parallel_sparse_ev::diagonalize(mat, parameters(params));
}*/
pyrokko.cpp
//.def("diagonalize", py::overload_cast<distributed_mfree_default&, wrap_parameters const&>(&wrap_parallel_sparse_ev::diagonalize),
// py::arg("mat"), py::arg("params") = wrap_parameters())
以下のtrampoline classも不要
class wrap_distributed_mfree_default : public distributed_mfree_default {
using distributed_mfree_default::distributed_mfree_default;
};
同じ基底クラスを継承することで共通化する。 すると、diagonalize関数にmapping_1dを誤って与えたときに、mfreeと解釈されてしまう。
以下を共通化できないか?
- rokko/distributed_mfree_c.cpp
- rokko/distributed_mfree_f.cpp
Pythonバインディングにおいても、op.dim, op.num_local_rows
を渡さなくて良いようにした。
mat = distributed_mfree(op.multiply, op.dim, op.num_local_rows)
PythonでC++で書いたクラスを継承した。 dimやnum_local_rowsを親クラスのプロパティとして読み出せるようにできた。
C/Fortranバインディングにおいて、commを渡すか?
call rokko_distributed_mfree_construct(mat, multiply, dim)
Cではオーバーロードやデフォルト引数が使用できないので、MPI_COMM_WORLDを渡すことにする。
コミュニケータは、vars->commにより渡される。 だが、varsはvoid*であり、distributed_mfree_cの初期化関数では型がわかないためキャストできないので、commを取り出せない。
引数として、dimとcommを含むmapping_1dを渡すことにするか?
- CやFortranでは、mapping_1dの継承ができない。
- mapping_1dをユーザプログラムの中でも使う。
Fortran/Cラッパーは、共通化しない方が良い。 それぞれの言語仕様に対して自然(かつ効率的?)になるように、引数の型としたいため。
Cラッパーでは、値渡し
int rokko_distributed_mfree_num_local_rows(struct rokko_distributed_mfree matrix) {
Fortranラッパーでは、ポインタ渡し
int rokko_distributed_mfree_f_num_local_rows(struct rokko_distributed_mfree* matrix) {
--- a/rokko/distributed_crs_matrix.hpp
+++ b/rokko/distributed_crs_matrix.hpp
@@ -43,6 +43,7 @@ public:
template<typename CRS>
class ps_crs_wrapper : public ps_crs_base {
using crs_type = CRS;
+ using map_type = typename CRS::map_type;
public:
ps_crs_wrapper() : crs_impl_() {}
virtual ~ps_crs_wrapper() = default;
--- a/rokko/slepc/distributed_crs_matrix.hpp
+++ b/rokko/slepc/distributed_crs_matrix.hpp
@@ -26,6 +26,8 @@ namespace slepc {
class distributed_crs_matrix : public rokko::detail::ps_crs_base {
public:
+ using map_type = rokko::slepc::mapping_1d;
+
distributed_crs_matrix() = default;
~distributed_crs_matrix() = default;
@@ -166,7 +168,7 @@ public:
}
}
- const rokko::slepc::mapping_1d* get_map() const { return map_; }
+ const map_type* get_map() const { return map_; }
上記のように、AnasaziとSLEPcのそれぞれの型をmapping_1dを返すようにしても、rokko::distributed_crs_matrixでのget_mapの戻り値は基底型であるため、AnasaziとSLEPc向けに継承したメンバは失われてしまう。
const ps_mapping_1d_base* get_map() const { return crs_impl_.get_map(); }