test_partitioners/
test_partitioners.rs1use mpi::{
2 collective::SystemOperation, environment::Universe, topology::Communicator,
3 traits::CommunicatorCollectives,
4};
5use ndelement::types::ReferenceCellType;
6use ndgrid::{
7 grid::local_grid::SingleElementGridBuilder,
8 traits::{Builder, Entity, Grid, ParallelBuilder, ParallelGrid},
9 types::{GraphPartitioner, Ownership},
10};
11
12fn run_test<C: Communicator>(comm: &C, partitioner: GraphPartitioner) {
14 let n = 10;
15
16 let mut b = SingleElementGridBuilder::<f64>::new(2, (ReferenceCellType::Quadrilateral, 1));
17
18 let rank = comm.rank();
19 let grid = if rank == 0 {
20 let mut i = 0;
21 for y in 0..n {
22 for x in 0..n {
23 b.add_point(i, &[x as f64 / (n - 1) as f64, y as f64 / (n - 1) as f64]);
24 i += 1;
25 }
26 }
27
28 let mut i = 0;
29 for y in 0..n - 1 {
30 for x in 0..n - 1 {
31 let sw = n * y + x;
32 b.add_cell(i, &[sw, sw + 1, sw + n, sw + n + 1]);
33 i += 1;
34 }
35 }
36
37 b.create_parallel_grid_root(comm, partitioner)
38 } else {
39 b.create_parallel_grid(comm, 0)
40 };
41
42 let cell_count_owned = grid
45 .local_grid()
46 .entity_iter(ReferenceCellType::Quadrilateral)
47 .filter(|entity| entity.is_owned())
48 .count();
49
50 for cell in grid
52 .local_grid()
53 .entity_iter(ReferenceCellType::Quadrilateral)
54 .take(cell_count_owned)
55 {
56 assert!(cell.is_owned())
57 }
58
59 let mut cell_global_count = grid.cell_layout().local_range().0;
62
63 for cell in grid
64 .local_grid()
65 .entity_iter(ReferenceCellType::Quadrilateral)
66 .take(cell_count_owned)
67 {
68 assert_eq!(cell.global_index(), cell_global_count);
69 cell_global_count += 1;
70 }
71
72 let global_vertices = grid
75 .local_grid()
76 .entity_iter(ReferenceCellType::Point)
77 .filter(|e| matches!(e.ownership(), Ownership::Owned))
78 .map(|e| e.global_index())
79 .collect::<Vec<_>>();
80
81 let nvertices = global_vertices.len();
82
83 let global_cells = grid
84 .local_grid()
85 .entity_iter(ReferenceCellType::Quadrilateral)
86 .filter(|e| matches!(e.ownership(), Ownership::Owned))
87 .map(|e| e.global_index())
88 .collect::<Vec<_>>();
89
90 let ncells = global_cells.len();
91
92 let mut total_cells: usize = 0;
93 let mut total_vertices: usize = 0;
94
95 comm.all_reduce_into(&ncells, &mut total_cells, SystemOperation::sum());
96 comm.all_reduce_into(&nvertices, &mut total_vertices, SystemOperation::sum());
97
98 assert_eq!(total_cells, (n - 1) * (n - 1));
99 assert_eq!(total_vertices, n * n);
100}
101
102fn main() {
104 let universe: Universe = mpi::initialize().unwrap();
105 let comm = universe.world();
106
107 if comm.rank() == 0 {
108 println!("Testing GraphPartitioner::None");
109 }
110 run_test(&comm, GraphPartitioner::None);
111
112 let mut p = vec![];
113 for i in 0..81 {
114 p.push(i % comm.size() as usize);
115 }
116 if comm.rank() == 0 {
117 println!("Testing GraphPartitioner::Manual");
118 }
119 run_test(&comm, GraphPartitioner::Manual(p));
120
121 if comm.rank() == 0 {
122 println!("Testing GraphPartitioner::Coupe");
123 }
124 run_test(&comm, GraphPartitioner::Coupe);
125
126 if comm.rank() == 0 {
127 println!("Testing GraphPartitioner::Scotch");
128 }
129 run_test(&comm, GraphPartitioner::Scotch);
130}