From 97171156929d74fdb55eecc9db41ccb4233a8aa4 Mon Sep 17 00:00:00 2001 From: Timo Heister Date: Tue, 26 Jan 2016 10:51:38 +0100 Subject: [PATCH] fix metis partitioning with too many processors If you have more processors than cells to partition, METIS will behave in a weird and undesired way: - at some point all subdomains land on a single processor - METIS produces an error message "***Cannot bisect a graph with 0 vertices!" --- source/lac/sparsity_tools.cc | 29 +++++++++++++++-------------- tests/metis/metis_04.output | 24 ++++++++++++------------ 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/source/lac/sparsity_tools.cc b/source/lac/sparsity_tools.cc index a3837ac34b..813c4edd33 100644 --- a/source/lac/sparsity_tools.cc +++ b/source/lac/sparsity_tools.cc @@ -82,13 +82,19 @@ namespace SparsityTools dummy; // the numbers of edges cut by the // resulting partition + // We can not partition n items into more than n parts. METIS will + // generate non-sensical output (everything is owned by a single process) + // and complain with a message (but won't return an error code!): + // ***Cannot bisect a graph with 0 vertices! + // ***You are trying to partition a graph into too many parts! + nparts = std::min(n, nparts); + // use default options for METIS idx_t options[METIS_NOPTIONS]; METIS_SetDefaultOptions (options); - // one more nuisance: we have to copy our - // own data to arrays that store signed - // integers :-( + // one more nuisance: we have to copy our own data to arrays that store + // signed integers :-( std::vector int_rowstart(1); int_rowstart.reserve(sparsity_pattern.n_rows()+1); std::vector int_colnums; @@ -106,12 +112,10 @@ namespace SparsityTools // Make use of METIS' error code. int ierr; - // Select which type of partitioning to - // create + // Select which type of partitioning to create - // Use recursive if the number of - // partitions is less than or equal to 8 - if (n_partitions <= 8) + // Use recursive if the number of partitions is less than or equal to 8 + if (nparts <= 8) ierr = METIS_PartGraphRecursive(&n, &ncon, &int_rowstart[0], &int_colnums[0], NULL, NULL, NULL, &nparts,NULL,NULL,&options[0], @@ -124,14 +128,11 @@ namespace SparsityTools &nparts,NULL,NULL,&options[0], &dummy,&int_partition_indices[0]); - // If metis returns normally, an - // error code METIS_OK=1 is - // returned from the above - // functions (see metish.h) + // If metis returns normally, an error code METIS_OK=1 is returned from + // the above functions (see metish.h) AssertThrow (ierr == 1, ExcMETISError (ierr)); - // now copy back generated indices into the - // output array + // now copy back generated indices into the output array std::copy (int_partition_indices.begin(), int_partition_indices.end(), partition_indices.begin()); diff --git a/tests/metis/metis_04.output b/tests/metis/metis_04.output index 753e2b4819..b9c688d08c 100644 --- a/tests/metis/metis_04.output +++ b/tests/metis/metis_04.output @@ -14,27 +14,27 @@ DEAL::1 3 0 5 1 5 2 DEAL:: procs = 7 DEAL::2 3 0 6 2 5 4 DEAL:: procs = 8 -DEAL::1 5 0 7 3 4 2 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 9 -DEAL::3 3 3 3 3 3 3 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 10 -DEAL::4 4 4 4 4 4 4 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 11 -DEAL::10 10 10 10 10 10 10 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 12 -DEAL::11 11 11 11 11 11 11 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 13 -DEAL::2 2 2 2 2 2 2 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 14 -DEAL::9 9 9 9 9 9 9 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 15 -DEAL::6 6 6 6 6 6 6 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 16 -DEAL::7 7 7 7 7 7 7 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 17 -DEAL::7 7 7 7 7 7 7 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 18 -DEAL::8 8 8 8 8 8 8 +DEAL::2 3 0 6 2 5 4 DEAL:: procs = 19 -DEAL::8 8 8 8 8 8 8 +DEAL::2 3 0 6 2 5 4 DEAL::OK -- 2.39.5