Skip to content
Snippets Groups Projects
Commit 28e5f448 authored by Peter W. Draper's avatar Peter W. Draper
Browse files

Add new repartition methods based on different weight strategies.

Move more code into partition.c and remove param.h.
parent 6f84a700
No related branches found
No related tags found
2 merge requests!136Master,!76Add new initial partition schemes and extend repartition ones.
...@@ -84,14 +84,20 @@ int main(int argc, char *argv[]) { ...@@ -84,14 +84,20 @@ int main(int argc, char *argv[]) {
int nr_nodes = 1, myrank = 0; int nr_nodes = 1, myrank = 0;
FILE *file_thread; FILE *file_thread;
int with_outputs = 1; int with_outputs = 1;
struct pgrid pgrid; struct initpart ipart;
#if defined(WITH_MPI) && defined(HAVE_METIS)
/* Default parition type is grid. */ enum repart_type reparttype = REPART_METIS_BOTH;
pgrid.type = GRID_GRID; #endif
pgrid.grid[0] = 1;
pgrid.grid[1] = 1;
pgrid.grid[2] = 1;
/* Default initial partition type is grid for shared memory and when
* METIS is not available. */
ipart.type = INITPART_GRID;
ipart.grid[0] = 1;
ipart.grid[1] = 1;
ipart.grid[2] = 1;
#if defined(WITH_MPI) && defined(HAVE_METIS)
ipart.type = INITPART_METIS_NOWEIGHT;
#endif
/* Choke on FP-exceptions. */ /* Choke on FP-exceptions. */
// feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); // feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
...@@ -115,9 +121,9 @@ int main(int argc, char *argv[]) { ...@@ -115,9 +121,9 @@ int main(int argc, char *argv[]) {
fflush(stdout); fflush(stdout);
/* Set a default grid so that grid[0]*grid[1]*grid[2] == nr_nodes. */ /* Set a default grid so that grid[0]*grid[1]*grid[2] == nr_nodes. */
factor(nr_nodes, &pgrid.grid[0], &pgrid.grid[1]); factor(nr_nodes, &ipart.grid[0], &ipart.grid[1]);
factor(nr_nodes / pgrid.grid[1], &pgrid.grid[0], &pgrid.grid[2]); factor(nr_nodes / ipart.grid[1], &ipart.grid[0], &ipart.grid[2]);
factor(pgrid.grid[0] * pgrid.grid[1], &pgrid.grid[1], &pgrid.grid[0]); factor(ipart.grid[0] * ipart.grid[1], &ipart.grid[1], &ipart.grid[0]);
#endif #endif
/* Greeting message */ /* Greeting message */
...@@ -127,7 +133,7 @@ int main(int argc, char *argv[]) { ...@@ -127,7 +133,7 @@ int main(int argc, char *argv[]) {
bzero(&s, sizeof(struct space)); bzero(&s, sizeof(struct space));
/* Parse the options */ /* Parse the options */
while ((c = getopt(argc, argv, "a:c:d:f:g:m:q:r:s:t:w:yz:")) != -1) while ((c = getopt(argc, argv, "a:c:d:e:f:m:p:q:r:s:t:w:yz:")) != -1)
switch (c) { switch (c) {
case 'a': case 'a':
if (sscanf(optarg, "%lf", &scaling) != 1) if (sscanf(optarg, "%lf", &scaling) != 1)
...@@ -146,32 +152,48 @@ int main(int argc, char *argv[]) { ...@@ -146,32 +152,48 @@ int main(int argc, char *argv[]) {
if (myrank == 0) message("dt set to %e.", dt_max); if (myrank == 0) message("dt set to %e.", dt_max);
fflush(stdout); fflush(stdout);
break; break;
case 'e':
/* REpartition type "b", "v", "e". */
#if defined(WITH_MPI) && defined(HAVE_METIS)
switch (optarg[0]) {
case 'b':
reparttype = REPART_METIS_BOTH;
break;
case 'v':
reparttype = REPART_METIS_VERTEX;
break;
case 'e':
reparttype = REPART_METIS_EDGE;
break;
}
#endif
break;
case 'f': case 'f':
if (!strcpy(ICfileName, optarg)) error("Error parsing IC file name."); if (!strcpy(ICfileName, optarg)) error("Error parsing IC file name.");
break; break;
case 'g': case 'p':
/* Grid is one of "g", "r", "m", "w", or "v". g can be followed by three /* Parition type is one of "g", "r", "m", "w", or "v"; "g" can be
* numbers. */ * followed by three numbers defining the grid. */
switch (optarg[0]) { switch (optarg[0]) {
case 'g': case 'g':
pgrid.type = GRID_GRID; ipart.type = INITPART_GRID;
if (strlen(optarg) > 2) { if (strlen(optarg) > 2) {
if (sscanf(optarg, "g %i %i %i", &pgrid.grid[0], &pgrid.grid[1], if (sscanf(optarg, "g %i %i %i", &ipart.grid[0], &ipart.grid[1],
&pgrid.grid[2]) != 3) &ipart.grid[2]) != 3)
error("Error parsing grid."); error("Error parsing grid.");
} }
break; break;
case 'r': case 'r':
pgrid.type = GRID_RANDOM; ipart.type = INITPART_RANDOM;
break; break;
case 'm': case 'm':
pgrid.type = GRID_METIS_NOWEIGHT; ipart.type = INITPART_METIS_NOWEIGHT;
break; break;
case 'w': case 'w':
pgrid.type = GRID_METIS_WEIGHT; ipart.type = INITPART_METIS_WEIGHT;
break; break;
case 'v': case 'v':
pgrid.type = GRID_VECTORIZE; ipart.type = INITPART_VECTORIZE;
break; break;
} }
break; break;
...@@ -223,7 +245,8 @@ int main(int argc, char *argv[]) { ...@@ -223,7 +245,8 @@ int main(int argc, char *argv[]) {
#if defined(WITH_MPI) #if defined(WITH_MPI)
if (myrank == 0) { if (myrank == 0) {
message("Running with %i thread(s) per node.", nr_threads); message("Running with %i thread(s) per node.", nr_threads);
message("grid set to [ %i %i %i ].", pgrid.grid[0], pgrid.grid[1], pgrid.grid[2]);
message("grid set to [ %i %i %i ].", ipart.grid[0], ipart.grid[1], ipart.grid[2]);
if (nr_nodes == 1) { if (nr_nodes == 1) {
message("WARNING: you are running with one MPI rank."); message("WARNING: you are running with one MPI rank.");
...@@ -356,7 +379,7 @@ int main(int argc, char *argv[]) { ...@@ -356,7 +379,7 @@ int main(int argc, char *argv[]) {
#ifdef WITH_MPI #ifdef WITH_MPI
/* Split the space. */ /* Split the space. */
engine_split(&e, &pgrid); engine_split(&e, &ipart);
engine_redistribute(&e); engine_redistribute(&e);
#endif #endif
...@@ -410,8 +433,8 @@ int main(int argc, char *argv[]) { ...@@ -410,8 +433,8 @@ int main(int argc, char *argv[]) {
/* Repartition the space amongst the nodes? */ /* Repartition the space amongst the nodes? */
#if defined(WITH_MPI) && defined(HAVE_METIS) #if defined(WITH_MPI) && defined(HAVE_METIS)
//if (j % 100 == 2) e.forcerepart = 1; //if (j % 100 == 2) e.forcerepart = reparttype;
if (j % 10 == 9) e.forcerepart = 1; if (j % 10 == 9) e.forcerepart = reparttype;
#endif #endif
timers_reset(timers_mask_all); timers_reset(timers_mask_all);
......
This diff is collapsed.
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "scheduler.h" #include "scheduler.h"
#include "space.h" #include "space.h"
#include "task.h" #include "task.h"
#include "param.h" #include "partition.h"
/* Some constants. */ /* Some constants. */
#define engine_policy_none 0 #define engine_policy_none 0
...@@ -118,7 +118,8 @@ struct engine { ...@@ -118,7 +118,8 @@ struct engine {
ticks tic_step; ticks tic_step;
/* Force the engine to rebuild? */ /* Force the engine to rebuild? */
int forcerebuild, forcerepart; int forcerebuild;
enum repart_type forcerepart;
/* How many steps have we done with the same set of tasks? */ /* How many steps have we done with the same set of tasks? */
int tasks_age; int tasks_age;
...@@ -136,7 +137,7 @@ void engine_launch(struct engine *e, int nr_runners, unsigned int mask); ...@@ -136,7 +137,7 @@ void engine_launch(struct engine *e, int nr_runners, unsigned int mask);
void engine_prepare(struct engine *e); void engine_prepare(struct engine *e);
void engine_step(struct engine *e); void engine_step(struct engine *e);
void engine_maketasks(struct engine *e); void engine_maketasks(struct engine *e);
void engine_split(struct engine *e, struct pgrid *grid); void engine_split(struct engine *e, struct initpart *ipart);
int engine_exchange_strays(struct engine *e, int offset, int *ind, int N); int engine_exchange_strays(struct engine *e, int offset, int *ind, int N);
void engine_rebuild(struct engine *e); void engine_rebuild(struct engine *e);
void engine_repartition(struct engine *e); void engine_repartition(struct engine *e);
......
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (C) 2015 Peter W. Draper (p.w.draper@durham.ac.uk)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#ifndef SWIFT_PARAM_H
#define SWIFT_PARAM_H
/* Initial partition grid struct. Defines type of partitioning to use and any
* related parameters. */
enum grid_types {
GRID_GRID = 0,
GRID_RANDOM,
GRID_VECTORIZE,
GRID_METIS_WEIGHT,
GRID_METIS_NOWEIGHT
};
struct pgrid {
enum grid_types type;
int grid[3];
};
#endif /* SWIFT_PARAM_H */
...@@ -47,15 +47,29 @@ ...@@ -47,15 +47,29 @@
#include "partition.h" #include "partition.h"
#include "const.h" #include "const.h"
#include "error.h" #include "error.h"
#include "param.h"
#include "debug.h" #include "debug.h"
/* Useful defines. */ /* Useful defines. */
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) > (b) ? (b) : (a)) #define MIN(a, b) ((a) > (b) ? (b) : (a))
#define CHUNK 512 #define CHUNK 512
/* Simple descriptions of initial partition types for reports. */
const char *initpart_name[] = {
"gridded cells",
"random point associated cells",
"vectorized point associated cells",
"METIS particle weighted cells",
"METIS unweighted cells"
};
/* Simple descriptions of repartition types for reports. */
const char *repart_name[] = {
"METIS edge and vertex weighted cells",
"METIS vertex weighted cells",
"METIS edge weights"
};
/* Vectorisation support */ /* Vectorisation support */
/* ===================== */ /* ===================== */
...@@ -744,12 +758,16 @@ int main(int argc, char *argv[]) { ...@@ -744,12 +758,16 @@ int main(int argc, char *argv[]) {
* *
* @param s the space of cells to partition. * @param s the space of cells to partition.
* @param nregions the number of regions required in the partition. * @param nregions the number of regions required in the partition.
* @param weights for the cells, sizeof number of cells if used, NULL * @param vertexw weights for the cells, sizeof number of cells if used,
* for unit weights. * NULL for unit weights.
* @param celllist on exit this contains the ids of the select region, * @param edgew weights for the graph edges between all cells, sizeof number
* of cells * 26 if used, NULL for unit weights. Need to be packed
* in CSR format, so same as adjcny array.
* @param celllist on exit this contains the ids of the selected regions,
* sizeof number of cells. * sizeof number of cells.
*/ */
void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist) { void part_pick_metis(struct space *s, int nregions, int *vertexw,
int *edgew, int *celllist) {
#if defined(HAVE_METIS) #if defined(HAVE_METIS)
...@@ -770,9 +788,14 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist) ...@@ -770,9 +788,14 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist)
idx_t *adjncy; idx_t *adjncy;
if ((adjncy = (idx_t *)malloc(sizeof(idx_t) * 26 * ncells)) == NULL) if ((adjncy = (idx_t *)malloc(sizeof(idx_t) * 26 * ncells)) == NULL)
error("Failed to allocate adjncy array."); error("Failed to allocate adjncy array.");
idx_t *weights_v; idx_t *weights_v = NULL;
if ((weights_v = (idx_t *)malloc(sizeof(idx_t) * ncells)) == NULL) if (vertexw != NULL)
error("Failed to allocate weights array"); if ((weights_v = (idx_t *)malloc(sizeof(idx_t) * ncells)) == NULL)
error("Failed to allocate vertex weights array");
idx_t *weights_e = NULL;
if (edgew != NULL)
if ((weights_e = (idx_t *)malloc( 26 *sizeof(idx_t) * ncells)) == NULL)
error("Failed to allocate edge weights array");
idx_t *regionid; idx_t *regionid;
if ((regionid = (idx_t *)malloc(sizeof(idx_t) * ncells)) == NULL) if ((regionid = (idx_t *)malloc(sizeof(idx_t) * ncells)) == NULL)
error("Failed to allocate regionid array"); error("Failed to allocate regionid array");
...@@ -823,17 +846,25 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist) ...@@ -823,17 +846,25 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist)
for (int k = 0; k < ncells; k++) xadj[k + 1] = xadj[k] + 26; for (int k = 0; k < ncells; k++) xadj[k + 1] = xadj[k] + 26;
/* Init the vertex weights array. */ /* Init the vertex weights array. */
if ( weights != NULL) { if (vertexw != NULL) {
for (int k = 0; k < ncells; k++) { for (int k = 0; k < ncells; k++) {
if ( weights[k] > 0 ) { if ( vertexw[k] > 0 ) {
weights_v[k] = weights[k]; weights_v[k] = vertexw[k];
} else { } else {
weights_v[k] = 1; weights_v[k] = 1;
} }
} }
} else { }
for (int k = 0; k < ncells; k++)
weights_v[k] = 1; /* Init the edges weights array. */
if (edgew != NULL) {
for (int k = 0; k < 26 * ncells; k++) {
if (edgew[k] > 0 ) {
weights_e[k] = edgew[k];
} else {
weights_e[k] = 1;
}
}
} }
/* Set the METIS options. */ /* Set the METIS options. */
...@@ -853,10 +884,10 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist) ...@@ -853,10 +884,10 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist)
/* Dump graph in METIS format */ /* Dump graph in METIS format */
dumpMETISGraph("metis_graph", idx_ncells, one, xadj, adjncy, dumpMETISGraph("metis_graph", idx_ncells, one, xadj, adjncy,
weights_v, NULL, NULL); weights_v, weights_e, NULL);
if (METIS_PartGraphKway(&idx_ncells, &one, xadj, adjncy, weights_v, if (METIS_PartGraphKway(&idx_ncells, &one, xadj, adjncy, weights_v,
NULL, NULL, &idx_nregions, NULL, NULL, weights_e, NULL, &idx_nregions, NULL, NULL,
options, &objval, regionid) != METIS_OK) options, &objval, regionid) != METIS_OK)
error("Call to METIS_PartGraphKway failed."); error("Call to METIS_PartGraphKway failed.");
...@@ -894,7 +925,7 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist) ...@@ -894,7 +925,7 @@ void part_pick_metis(struct space *s, int nregions, int *weights, int *celllist)
for (int l = 0, k = 0; l < s->cdim[0]; l++) { for (int l = 0, k = 0; l < s->cdim[0]; l++) {
for (int m = 0; m < s->cdim[1]; m++) { for (int m = 0; m < s->cdim[1]; m++) {
for (int n = 0; n < s->cdim[2]; n++) { for (int n = 0; n < s->cdim[2]; n++) {
message("node %d %d %d -> %d %d", l, m, n, regionid[k], weights_v[k]); message("node %d %d %d -> %d", l, m, n, regionid[k]);
k++; k++;
} }
} }
......
...@@ -22,13 +22,43 @@ ...@@ -22,13 +22,43 @@
#include "space.h" #include "space.h"
#include "cell.h" #include "cell.h"
/* Initial partitioning types. */
enum initpart_type {
INITPART_GRID = 0,
INITPART_RANDOM,
INITPART_VECTORIZE,
INITPART_METIS_WEIGHT,
INITPART_METIS_NOWEIGHT
};
/* Simple descriptions of types for reports. */
extern const char *initpart_name[];
/* The selected initial partition type and any related metadata. */
struct initpart {
enum initpart_type type;
int grid[3];
};
/* Repartition type to use. */
enum repart_type {
REPART_NONE = 0,
REPART_METIS_BOTH,
REPART_METIS_VERTEX,
REPART_METIS_EDGE
};
/* Simple descriptions of types for reports. */
extern const char *repart_name[];
int part_pick_random(struct space *s, int nregions, float *samplelist); int part_pick_random(struct space *s, int nregions, float *samplelist);
void part_split_random(struct space *s, int nregions, float *samplelist); void part_split_random(struct space *s, int nregions, float *samplelist);
void part_pick_vector(struct space *s, int nregions, int *samplecells); void part_pick_vector(struct space *s, int nregions, int *samplecells);
void part_split_vector(struct space *s, int nregions, int *samplecells); void part_split_vector(struct space *s, int nregions, int *samplecells);
void part_pick_metis(struct space *s, int nregions, int *weight, int *celllist); void part_pick_metis(struct space *s, int nregions, int *vertexw,
int *edgew, int *celllist);
void part_split_metis(struct space *s, int nregions, int *celllist); void part_split_metis(struct space *s, int nregions, int *celllist);
#endif /* SWIFT_POISSON_DISC_H */ #endif /* SWIFT_PARTITION_H */
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include "timers.h" #include "timers.h"
#include "units.h" #include "units.h"
#include "tools.h" #include "tools.h"
#include "param.h"
#include "partition.h" #include "partition.h"
#include "version.h" #include "version.h"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment