Skip to content

Commit 3ed8696

Browse files
improve coverage ?
1 parent 9a6d825 commit 3ed8696

File tree

5 files changed

+98
-72
lines changed

5 files changed

+98
-72
lines changed

src/htool/clustering/cluster_tree_builder.hpp

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,39 +32,23 @@ void declare_cluster_builder(py::module &m, const std::string &className) {
3232
py::arg("weights") // make them optional with C++17 and None
3333
);
3434
py_class.def(
35-
"create_cluster_tree", [](Class &self, py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, int number_of_children, int size_of_partition, py::array_t<int, py::array::f_style | py::array::forcecast> partition, py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> radii) {
36-
if (partition.ndim() != 2 && partition.shape()[0] != 2) {
37-
throw std::runtime_error("Wrong format for partition"); // LCOV_EXCL_LINE
38-
}
39-
return self.create_cluster_tree(coordinates.shape()[1], coordinates.shape()[0], coordinates.data(), radii.data(), nullptr, number_of_children, size_of_partition, partition.data());
40-
},
41-
py::arg("coordinates"),
42-
py::arg("number_of_children"),
43-
py::arg("size_of_partition"),
44-
py::kw_only(),
45-
py::arg("partition"), // make them optional with C++17 and None
46-
py::arg("radii") // make them optional with C++17 and None
47-
);
48-
py_class.def(
49-
"create_cluster_tree", [](Class &self, py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, int number_of_children, int size_of_partition, py::array_t<int, py::array::f_style | py::array::forcecast> partition) {
50-
if (partition.ndim() != 2 && partition.shape()[0] != 2) {
35+
"create_cluster_tree", [](Class &self, py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, int number_of_children, int size_of_partition, std::optional<py::array_t<int, py::array::f_style | py::array::forcecast>> partition, std::optional<py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast>> radii, std::optional<py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast>> weights) {
36+
if (partition.has_value() && partition->ndim() != 2 && partition->shape()[0] != 2) {
5137
throw std::runtime_error("Wrong format for partition"); // LCOV_EXCL_LINE
5238
}
53-
return self.create_cluster_tree(coordinates.shape()[1], coordinates.shape()[0], coordinates.data(), number_of_children, size_of_partition, partition.data());
39+
auto partition_ptr = partition.has_value() ? partition.value().data() : nullptr;
40+
auto radii_ptr = radii.has_value() ? radii.value().data() : nullptr;
41+
auto weights_ptr = weights.has_value() ? weights.value().data() : nullptr;
42+
return self.create_cluster_tree(coordinates.shape()[1], coordinates.shape()[0], coordinates.data(), radii_ptr, weights_ptr, number_of_children, size_of_partition, partition_ptr);
5443
},
5544
py::arg("coordinates"),
5645
py::arg("number_of_children"),
5746
py::arg("size_of_partition"),
5847
py::kw_only(),
59-
py::arg("partition"));
48+
py::arg("partition") = py::none(),
49+
py::arg("radii") = py::none(),
50+
py::arg("weights") = py::none());
6051

61-
py_class.def(
62-
"create_cluster_tree", [](Class &self, py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, int number_of_children, int size_of_partition) {
63-
return self.create_cluster_tree(coordinates.shape()[1], coordinates.shape()[0], coordinates.data(), number_of_children, size_of_partition);
64-
},
65-
py::arg("coordinates"),
66-
py::arg("number_of_children"),
67-
py::arg("size_of_partition"));
6852
py_class.def("set_maximal_leaf_size", &Class::set_maximal_leaf_size);
6953
py_class.def("set_partitioning_strategy", &Class::set_partitioning_strategy);
7054
}

src/htool/solver/solver.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ void declare_DDM(py::module &m, const std::string &className) {
3030
mu = 1;
3131
} else if ((b.ndim() == 2 && x.ndim() == 2) && b.shape()[1] == x.shape()[1]) {
3232
mu = b.shape()[1];
33-
} else {
34-
std::string rhs = "("; // LCOV_EXCL_START
33+
} else { // LCOV_EXCL_START
34+
std::string rhs = "(";
3535
std::string sol = "(";
3636
for (int p = 0; p < b.ndim(); p++) {
3737
rhs += htool::NbrToStr(b.shape()[p]);
@@ -48,8 +48,8 @@ void declare_DDM(py::module &m, const std::string &className) {
4848
}
4949
sol += ")";
5050
throw std::invalid_argument("Wrong dimension for right-hand side or solution\nright-hand side: " + rhs + "\n" + "solution: " + sol + "\n");
51-
// LCOV_EXCL_STOP
52-
}
51+
52+
} // LCOV_EXCL_STOP
5353

5454
{
5555
py::scoped_ostream_redirect stream(std::cout, py::module_::import("sys").attr("stdout"));

src/htool/solver/utility.hpp

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ void declare_solver_utility(py::module &m, std::string prefix = "") {
1515

1616
ddm_solver_class.def(py::init<DistributedOperator<CoefficientPrecision> &, HMatrix<CoefficientPrecision, CoordinatePrecision> &, const VirtualGenerator<CoefficientPrecision> &, const std::vector<int> &, const std::vector<int> &, const std::vector<int> &, const std::vector<std::vector<int>> &>(), py::keep_alive<1, 2>(), py::keep_alive<1, 3>());
1717

18-
ddm_solver_class.def(py::init([](DistributedOperator<CoefficientPrecision> &distributed_operator, const std::vector<int> &ovr_subdomain_to_global, const std::vector<int> &cluster_to_ovr_subdomain, const std::vector<int> &neighbors, const std::vector<std::vector<int>> &intersections, const VirtualGenerator<CoefficientPrecision> &generator, const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, const ClusterTreeBuilder<CoordinatePrecision> &cluster_tree_builder, HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision> &local_hmatrix_builder, const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> radii, const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> weights) {
19-
return new DDMSolverBuilder(distributed_operator, ovr_subdomain_to_global, cluster_to_ovr_subdomain, neighbors, intersections, generator, coordinates.shape()[0], coordinates.data(), radii.data(), weights.data(), cluster_tree_builder, local_hmatrix_builder);
18+
ddm_solver_class.def(py::init([](DistributedOperator<CoefficientPrecision> &distributed_operator, const std::vector<int> &ovr_subdomain_to_global, const std::vector<int> &cluster_to_ovr_subdomain, const std::vector<int> &neighbors, const std::vector<std::vector<int>> &intersections, const VirtualGenerator<CoefficientPrecision> &generator, const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, const ClusterTreeBuilder<CoordinatePrecision> &cluster_tree_builder, HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision> &local_hmatrix_builder, std::optional<const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast>> radii, std::optional<const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast>> weights) {
19+
auto radii_ptr = radii.has_value() ? radii.value().data() : nullptr;
20+
auto weights_ptr = weights.has_value() ? weights.value().data() : nullptr;
21+
return new DDMSolverBuilder(distributed_operator, ovr_subdomain_to_global, cluster_to_ovr_subdomain, neighbors, intersections, generator, coordinates.shape()[0], coordinates.data(), radii_ptr, weights_ptr, cluster_tree_builder, local_hmatrix_builder);
2022
}),
2123
py::keep_alive<1, 2>(),
2224
py::arg("distributed_operator"),
@@ -29,31 +31,8 @@ void declare_solver_utility(py::module &m, std::string prefix = "") {
2931
py::arg("cluster_tree_builder"),
3032
py::arg("local_hmatrix_builder"),
3133
py::kw_only(),
32-
py::arg("radii"), // make them optional with C++17 and None
33-
py::arg("weights") // make them optional with C++17 and None
34-
);
35-
36-
ddm_solver_class.def(py::init([](DistributedOperator<CoefficientPrecision> &distributed_operator, const std::vector<int> &ovr_subdomain_to_global, const std::vector<int> &cluster_to_ovr_subdomain, const std::vector<int> &neighbors, const std::vector<std::vector<int>> &intersections, const VirtualGenerator<CoefficientPrecision> &generator, const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, const ClusterTreeBuilder<CoordinatePrecision> &cluster_tree_builder, HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision> &local_hmatrix_builder, const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> radii) {
37-
return new DDMSolverBuilder(distributed_operator, ovr_subdomain_to_global, cluster_to_ovr_subdomain, neighbors, intersections, generator, coordinates.shape()[0], coordinates.data(), radii.data(), nullptr, cluster_tree_builder, local_hmatrix_builder);
38-
}),
39-
py::keep_alive<1, 2>(),
40-
py::arg("distributed_operator"),
41-
py::arg("ovr_subdomain_to_global"),
42-
py::arg("cluster_to_ovr_subdomain"),
43-
py::arg("neighbors"),
44-
py::arg("intersections"),
45-
py::arg("generator"),
46-
py::arg("coordinates"),
47-
py::arg("cluster_tree_builder"),
48-
py::arg("local_hmatrix_builder"),
49-
py::kw_only(),
50-
py::arg("radii") // make them optional with C++17 and None
51-
);
52-
53-
ddm_solver_class.def(py::init([](DistributedOperator<CoefficientPrecision> &distributed_operator, const std::vector<int> &ovr_subdomain_to_global, const std::vector<int> &cluster_to_ovr_subdomain, const std::vector<int> &neighbors, const std::vector<std::vector<int>> &intersections, const VirtualGenerator<CoefficientPrecision> &generator, const py::array_t<CoordinatePrecision, py::array::f_style | py::array::forcecast> coordinates, const ClusterTreeBuilder<CoordinatePrecision> &cluster_tree_builder, HMatrixTreeBuilder<CoefficientPrecision, CoordinatePrecision> &local_hmatrix_builder) {
54-
return new DDMSolverBuilder(distributed_operator, ovr_subdomain_to_global, cluster_to_ovr_subdomain, neighbors, intersections, generator, coordinates.shape()[0], coordinates.data(), cluster_tree_builder, local_hmatrix_builder);
55-
}),
56-
py::keep_alive<1, 2>());
34+
py::arg("radii") = py::none(),
35+
py::arg("weights") = py::none());
5736

5837
ddm_solver_class.def_property_readonly(
5938
"solver", [](const DDMSolverBuilder &self) { return &self.solver; }, py::return_value_policy::reference_internal);

tests/conftest.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,12 @@ def cluster(geometry, symmetry):
146146
source_cluster = None
147147
if symmetry == "N":
148148
source_cluster: Htool.Cluster = cluster_builder.create_cluster_tree(
149-
source_points, number_of_children, mpi4py.MPI.COMM_WORLD.size
149+
source_points,
150+
number_of_children,
151+
mpi4py.MPI.COMM_WORLD.size,
152+
partition=None,
153+
radii=None,
154+
weights=None
150155
)
151156

152157
if target_partition is not None:
@@ -155,10 +160,17 @@ def cluster(geometry, symmetry):
155160
number_of_children,
156161
mpi4py.MPI.COMM_WORLD.size,
157162
partition=target_partition,
163+
radii=None,
164+
weights=None
158165
)
159166
else:
160167
target_cluster: Htool.Cluster = cluster_builder.create_cluster_tree(
161-
target_points, number_of_children, mpi4py.MPI.COMM_WORLD.size
168+
target_points,
169+
number_of_children,
170+
mpi4py.MPI.COMM_WORLD.size,
171+
partition=None,
172+
radii=None,
173+
weights=None
162174
)
163175

164176
if symmetry == "S" or symmetry == "H":

tests/test_ddm_solver.py

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,39 @@ def compute_coarse_space(self, Ai, Bi):
3636
@pytest.mark.parametrize(
3737
"mu,symmetry,ddm_builder,hpddm_schwarz_method,hpddm_schwarz_coarse_correction,geneo_type",
3838
[
39-
# (1, "N", "BlockJacobi", "none", "none", "none"),
40-
# (1, "N", "BlockJacobi", "asm", "none", "none"),
41-
# (1, "N", "BlockJacobi", "ras", "none", "none"),
42-
# (1, "N", "DDMWithHMatrixPlusOverlap", "asm", "none", "none"),
43-
# (1, "N", "DDMWithHMatrixPlusOverlap", "ras", "none", "none"),
44-
# (1, "N", "DDMWithHMatrix", "asm", "none", "none"),
45-
# (1, "N", "DDMWithHMatrix", "ras", "none", "none"),
46-
# (10, "N", "BlockJacobi", "none", "none", "none"),
47-
# (10, "N", "BlockJacobi", "asm", "none", "none"),
48-
# (10, "N", "BlockJacobi", "ras", "none", "none"),
49-
# (10, "N", "DDMWithHMatrixPlusOverlap", "asm", "none", "none"),
50-
# (10, "N", "DDMWithHMatrixPlusOverlap", "ras", "none", "none"),
51-
# (10, "N", "DDMWithHMatrix", "asm", "none", "none"),
52-
# (10, "N", "DDMWithHMatrix", "ras", "none", "none"),
39+
(1, "N", "BlockJacobi", "none", "none", "none"),
40+
(1, "N", "BlockJacobi", "asm", "none", "none"),
41+
(1, "N", "BlockJacobi", "ras", "none", "none"),
42+
(1, "N", "BlockJacobiDense", "none", "none", "none"),
43+
(1, "N", "BlockJacobiDense", "asm", "none", "none"),
44+
(1, "N", "BlockJacobiDense", "ras", "none", "none"),
45+
(1, "N", "DDMWithHMatrixPlusOverlap", "asm", "none", "none"),
46+
(1, "N", "DDMWithHMatrixPlusOverlap", "ras", "none", "none"),
47+
(1, "N", "DDMWithHMatrix", "asm", "none", "none"),
48+
(1, "N", "DDMWithHMatrix", "ras", "none", "none"),
49+
(1, "N", "DDMWithHMatrixDense", "asm", "none", "none"),
50+
(1, "N", "DDMWithHMatrixDense", "ras", "none", "none"),
51+
(10, "N", "BlockJacobi", "none", "none", "none"),
52+
(10, "N", "BlockJacobi", "asm", "none", "none"),
53+
(10, "N", "BlockJacobi", "ras", "none", "none"),
54+
(10, "N", "BlockJacobiDense", "none", "none", "none"),
55+
(10, "N", "BlockJacobiDense", "asm", "none", "none"),
56+
(10, "N", "BlockJacobiDense", "ras", "none", "none"),
57+
(10, "N", "DDMWithHMatrixPlusOverlap", "asm", "none", "none"),
58+
(10, "N", "DDMWithHMatrixPlusOverlap", "ras", "none", "none"),
59+
(10, "N", "DDMWithHMatrix", "asm", "none", "none"),
60+
(10, "N", "DDMWithHMatrix", "ras", "none", "none"),
61+
(10, "N", "DDMWithHMatrixDense", "asm", "none", "none"),
62+
(10, "N", "DDMWithHMatrixDense", "ras", "none", "none"),
5363
(1, "S", "BlockJacobi", "none", "none", "none"),
5464
(1, "S", "BlockJacobi", "asm", "none", "none"),
5565
(1, "S", "BlockJacobi", "ras", "none", "none"),
5666
(1, "S", "DDMWithHMatrixPlusOverlap", "asm", "none", "none"),
5767
(1, "S", "DDMWithHMatrixPlusOverlap", "ras", "none", "none"),
5868
(1, "S", "DDMWithHMatrix", "asm", "none", "none"),
5969
(1, "S", "DDMWithHMatrix", "ras", "none", "none"),
70+
(1, "S", "DDMWithHMatrixDense", "asm", "none", "none"),
71+
(1, "S", "DDMWithHMatrixDense", "ras", "none", "none"),
6072
(10, "S", "BlockJacobi", "none", "none", "none"),
6173
(10, "S", "BlockJacobi", "asm", "none", "none"),
6274
(10, "S", "BlockJacobi", "ras", "none", "none"),
@@ -228,6 +240,18 @@ def test_ddm_solver(
228240
default_approximation.distributed_operator,
229241
block_diagonal_hmatrix,
230242
)
243+
elif ddm_builder == "BlockJacobiDense":
244+
if symmetry == "S":
245+
default_solver_builder = Htool.DDMSolverWithDenseLocalSolver(
246+
default_approximation.distributed_operator,
247+
default_approximation.block_diagonal_hmatrix,
248+
)
249+
else:
250+
default_solver_builder = Htool.ComplexDDMSolverWithDenseLocalSolver(
251+
default_approximation.distributed_operator,
252+
default_approximation.block_diagonal_hmatrix,
253+
)
254+
local_hmatrix = default_solver_builder.get_local_hmatrix()
231255

232256
elif ddm_builder == "DDMWithHMatrixPlusOverlap":
233257
block_diagonal_hmatrix = copy.deepcopy(
@@ -266,6 +290,8 @@ def test_ddm_solver(
266290
geometry,
267291
Htool.ClusterTreeBuilder(),
268292
Htool.HMatrixTreeBuilder(epsilon, eta * 1.0, symmetry, UPLO),
293+
radii=None,
294+
weights=None,
269295
)
270296
else:
271297
default_solver_builder = Htool.ComplexDDMSolverBuilder(
@@ -278,10 +304,35 @@ def test_ddm_solver(
278304
geometry,
279305
Htool.ClusterTreeBuilder(),
280306
Htool.ComplexHMatrixTreeBuilder(epsilon, eta * 1.0, symmetry, UPLO),
307+
radii=None,
308+
weights=None,
281309
)
282310
local_hmatrix = default_solver_builder.get_local_hmatrix()
283311
Htool.recompression(local_hmatrix)
284312

313+
elif ddm_builder == "DDMWithHMatrixDense":
314+
if symmetry == "S":
315+
default_solver_builder = Htool.DDMSolverWithDenseLocalSolver(
316+
default_approximation.distributed_operator,
317+
default_approximation.block_diagonal_hmatrix,
318+
generator,
319+
ovr_subdomain_to_global,
320+
cluster_to_ovr_subdomain,
321+
neighbors,
322+
intersections,
323+
)
324+
else:
325+
default_solver_builder = Htool.ComplexDDMSolverWithDenseLocalSolver(
326+
default_approximation.distributed_operator,
327+
default_approximation.block_diagonal_hmatrix,
328+
generator,
329+
ovr_subdomain_to_global,
330+
cluster_to_ovr_subdomain,
331+
neighbors,
332+
intersections,
333+
)
334+
local_hmatrix = default_solver_builder.get_local_hmatrix()
335+
285336
solver = default_solver_builder.solver
286337
distributed_operator = default_approximation.distributed_operator
287338
local_size_wo_overlap = len(cluster_to_ovr_subdomain)

0 commit comments

Comments
 (0)