p4est  2.8.7
p4est is a software library for parallel adaptive mesh refinement.
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
timings/timings2.c

This 2D example program (3D counterpart: timings/timings3.c) calls p4est's core routines.The example's purpose is to measure the runtime of p4est's core routines.

Usage:

p4est_timings <configuration> <level>

possible configurations:

/*
This file is part of p4est.
p4est is a C library to manage a collection (a forest) of multiple
connected adaptive quadtrees or octrees in parallel.
Copyright (C) 2010 The University of Texas System
Additional copyright (C) 2011 individual authors
Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac
p4est is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
p4est 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 General Public License
along with p4est; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* Usage: p4est_timings <configuration> <level>
* possible configurations:
* o unit Refinement on the unit square.
* o periodic Refinement on the unit square with periodic b.c.
* o three Refinement on a forest with three trees.
* o moebius Refinement on a 5-tree Moebius band.
* o star Refinement on a 6-tree star shaped domain.
*
* Usage: p8est_timings <configuration> <level>
* possible configurations:
* o unit Refinement on the unit cube.
* o periodic Refinement on the unit cube with all-periodic b.c.
* o rotwrap Refinement on the unit cube with weird periodic b.c.
* o twocubes Refinement on a forest with two trees.
* o rotcubes Refinement on a forest with six rotated trees.
* o shell Refinement on a 24-tree spherical shell.
*/
#ifndef P4_TO_P8
#include <p4est_bits.h>
#include <p4est_extended.h>
#include <p4est_ghost.h>
#include <p4est_nodes.h>
#include <p4est_vtk.h>
#include <p4est_lnodes.h>
#else
#include <p8est_bits.h>
#include <p8est_extended.h>
#include <p8est_ghost.h>
#include <p8est_nodes.h>
#include <p8est_vtk.h>
#include <p8est_lnodes.h>
#endif
#include <sc_flops.h>
#include <sc_statistics.h>
#include <sc_options.h>
/* #define P4EST_TIMINGS_VTK */
typedef enum
{
P4EST_CONFIG_NULL,
P4EST_CONFIG_UNIT,
P4EST_CONFIG_PERIODIC,
#ifndef P4_TO_P8
P4EST_CONFIG_THREE,
P4EST_CONFIG_MOEBIUS,
P4EST_CONFIG_STAR
#else
P4EST_CONFIG_ROTWRAP,
P4EST_CONFIG_TWOCUBES,
P4EST_CONFIG_ROTCUBES,
P4EST_CONFIG_SHELL
#endif
}
timings_config_t;
enum
{
TIMINGS_REFINE,
TIMINGS_BALANCE,
TIMINGS_BALANCE_A,
TIMINGS_BALANCE_COMM,
TIMINGS_BALANCE_B,
TIMINGS_BALANCE_A_COUNT_IN,
TIMINGS_BALANCE_A_COUNT_OUT,
TIMINGS_BALANCE_COMM_SENT,
TIMINGS_BALANCE_COMM_NZPEERS,
TIMINGS_BALANCE_B_COUNT_IN,
TIMINGS_BALANCE_B_COUNT_OUT,
TIMINGS_BALANCE_RANGES,
TIMINGS_BALANCE_NOTIFY,
TIMINGS_BALANCE_NOTIFY_ALLGATHER,
TIMINGS_BALANCE_A_ZERO_SENDS,
TIMINGS_BALANCE_A_ZERO_RECEIVES,
TIMINGS_BALANCE_B_ZERO_SENDS,
TIMINGS_BALANCE_B_ZERO_RECEIVES,
TIMINGS_REBALANCE,
TIMINGS_REBALANCE_A,
TIMINGS_REBALANCE_COMM,
TIMINGS_REBALANCE_B,
TIMINGS_REBALANCE_A_COUNT_IN,
TIMINGS_REBALANCE_A_COUNT_OUT,
TIMINGS_REBALANCE_COMM_SENT,
TIMINGS_REBALANCE_COMM_NZPEERS,
TIMINGS_REBALANCE_B_COUNT_IN,
TIMINGS_REBALANCE_B_COUNT_OUT,
TIMINGS_PARTITION,
TIMINGS_GHOSTS,
TIMINGS_NODES,
TIMINGS_TRILINEAR_OBSOLETE,
TIMINGS_REPARTITION,
TIMINGS_LNODES,
TIMINGS_LNODES3,
TIMINGS_LNODES7,
TIMINGS_NUM_STATS
};
typedef struct
{
timings_config_t config;
int mpisize;
int level;
unsigned checksum;
}
timings_regression_t;
typedef struct
{
sc_MPI_Comm mpicomm;
int mpisize;
int mpirank;
}
mpi_context_t;
static int refine_level = 0;
static int level_shift = 0;
/* *INDENT-OFF* */
static const timings_regression_t regression_oldschool[] =
{
#ifndef P4_TO_P8
{ P4EST_CONFIG_UNIT, 1, 10, 0x6e3e83c4U },
{ P4EST_CONFIG_UNIT, 1, 11, 0x334bc3deU },
{ P4EST_CONFIG_UNIT, 64, 14, 0xad908ce4U },
{ P4EST_CONFIG_UNIT, 256, 15, 0x9e7da646U },
{ P4EST_CONFIG_STAR, 1, 6, 0x14107b57U },
{ P4EST_CONFIG_STAR, 4, 6, 0x14107b57U },
{ P4EST_CONFIG_STAR, 52, 13, 0xc86c74d9U },
{ P4EST_CONFIG_STAR, 64, 13, 0xc86c74d9U },
#else
{ P4EST_CONFIG_UNIT, 1, 5, 0xe1ffa67bU },
{ P4EST_CONFIG_UNIT, 1, 6, 0x2cad814dU },
{ P4EST_CONFIG_UNIT, 3, 8, 0xeb252238U },
{ P4EST_CONFIG_PERIODIC, 1, 5, 0x99874fedU },
{ P4EST_CONFIG_PERIODIC, 2, 5, 0x575af6d5U },
{ P4EST_CONFIG_PERIODIC, 7, 6, 0xbc35524aU },
{ P4EST_CONFIG_ROTWRAP, 2, 6, 0x372f7402U },
{ P4EST_CONFIG_ROTWRAP, 7, 6, 0xa2f1ee48U },
{ P4EST_CONFIG_TWOCUBES, 5, 6, 0xa8b1f54eU },
{ P4EST_CONFIG_TWOCUBES, 8, 5, 0x98d3579dU },
{ P4EST_CONFIG_ROTCUBES, 1, 5, 0x404e4aa8U },
{ P4EST_CONFIG_ROTCUBES, 7, 6, 0x4c381706U },
{ P4EST_CONFIG_SHELL, 1, 4, 0x8c56f159U },
{ P4EST_CONFIG_SHELL, 3, 5, 0xafbc4f8cU },
{ P4EST_CONFIG_SHELL, 5, 6, 0xf6d9efb8U },
#endif
{ P4EST_CONFIG_NULL, 0, 0, 0 }
};
static const timings_regression_t regression_latest[] =
{
#ifndef P4_TO_P8
{ P4EST_CONFIG_UNIT, 1, 10, 0x6e3e83c4U },
{ P4EST_CONFIG_UNIT, 1, 11, 0x334bc3deU },
{ P4EST_CONFIG_UNIT, 64, 14, 0xad908ce4U },
{ P4EST_CONFIG_UNIT, 256, 15, 0x9e7da646U },
{ P4EST_CONFIG_STAR, 1, 6, 0x14107b57U },
{ P4EST_CONFIG_STAR, 4, 6, 0x14107b57U },
{ P4EST_CONFIG_STAR, 52, 13, 0xc86c74d9U },
{ P4EST_CONFIG_STAR, 64, 13, 0xc86c74d9U },
#else
{ P4EST_CONFIG_UNIT, 1, 5, 0xc2012e84U },
{ P4EST_CONFIG_UNIT, 1, 6, 0x2cad814dU },
{ P4EST_CONFIG_UNIT, 3, 8, 0xeb252238U },
{ P4EST_CONFIG_PERIODIC, 1, 5, 0x2776c9b7U },
{ P4EST_CONFIG_PERIODIC, 2, 5, 0x2776c9b7U },
{ P4EST_CONFIG_PERIODIC, 7, 6, 0x4f281079U },
{ P4EST_CONFIG_ROTWRAP, 2, 6, 0x372f7402U },
{ P4EST_CONFIG_ROTWRAP, 7, 6, 0x372f7402U },
{ P4EST_CONFIG_TWOCUBES, 5, 6, 0xa8b1f54eU },
{ P4EST_CONFIG_TWOCUBES, 8, 5, 0x0aad11d0U },
{ P4EST_CONFIG_ROTCUBES, 1, 5, 0x404e4aa8U },
{ P4EST_CONFIG_ROTCUBES, 7, 6, 0x4c381706U },
{ P4EST_CONFIG_SHELL, 1, 4, 0x8c56f159U },
{ P4EST_CONFIG_SHELL, 3, 5, 0xafbc4f8cU },
{ P4EST_CONFIG_SHELL, 5, 6, 0xf6d9efb8U },
#endif
{ P4EST_CONFIG_NULL, 0, 0, 0 }
};
/* *INDENT-ON* */
static int
refine_fractal (p4est_t * p4est, p4est_topidx_t which_tree,
{
int qid;
if ((int) q->level >= refine_level) {
return 0;
}
if ((int) q->level < refine_level - level_shift) {
return 1;
}
return (qid == 0 || qid == 3
#ifdef P4_TO_P8
|| qid == 5 || qid == 6
#endif
);
}
int
main (int argc, char **argv)
{
int i;
int mpiret;
int wrongusage;
unsigned crc, gcrc;
const char *config_name;
const char *load_name;
p4est_locidx_t *quadrant_counts;
p4est_gloidx_t count_refined, count_balanced;
p4est_gloidx_t prev_quadrant, next_quadrant;
p4est_gloidx_t global_shipped;
p4est_connectivity_t *connectivity;
p4est_nodes_t *nodes = NULL;
p4est_ghost_t *ghost;
p4est_lnodes_t *lnodes;
const timings_regression_t *r, *regression;
timings_config_t config;
sc_statinfo_t stats[TIMINGS_NUM_STATS];
sc_flopinfo_t fi, snapshot;
mpi_context_t mpi_context, *mpi = &mpi_context;
sc_options_t *opt;
int overlap;
int subtree;
int borders;
int max_ranges;
int use_ranges, use_ranges_notify, use_balance_verify;
int oldschool, generate;
int first_argc;
int test_multiple_orders;
int skip_nodes, skip_lnodes;
int repartition_lnodes;
/* initialize MPI and p4est internals */
mpiret = sc_MPI_Init (&argc, &argv);
SC_CHECK_MPI (mpiret);
mpi->mpicomm = sc_MPI_COMM_WORLD;
mpiret = sc_MPI_Comm_size (mpi->mpicomm, &mpi->mpisize);
SC_CHECK_MPI (mpiret);
mpiret = sc_MPI_Comm_rank (mpi->mpicomm, &mpi->mpirank);
SC_CHECK_MPI (mpiret);
sc_init (mpi->mpicomm, 1, 1, NULL, SC_LP_DEFAULT);
#ifndef P4EST_ENABLE_DEBUG
sc_set_log_defaults (NULL, NULL, SC_LP_STATISTICS);
#endif
p4est_init (NULL, SC_LP_DEFAULT);
/* process command line arguments */
P4EST_GLOBAL_PRODUCTIONF ("Size of %dtant: %lld bytes\n", P4EST_DIM,
(long long) sizeof (p4est_quadrant_t));
opt = sc_options_new (argv[0]);
sc_options_add_switch (opt, 'o', "new-balance-overlap", &overlap,
"use the new balance overlap algorithm");
sc_options_add_switch (opt, 's', "new-balance-subtree", &subtree,
"use the new balance subtree algorithm");
sc_options_add_switch (opt, 'b', "new-balance-borders", &borders,
"use borders in balance");
sc_options_add_int (opt, 'm', "max-ranges", &max_ranges, -1,
"override p4est_num_ranges");
sc_options_add_switch (opt, 'r', "ranges", &use_ranges,
"use ranges in balance");
sc_options_add_switch (opt, 't', "ranges-notify", &use_ranges_notify,
"use both ranges and notify");
sc_options_add_switch (opt, 'y', "balance-verify", &use_balance_verify,
"use verifications in balance");
sc_options_add_int (opt, 'l', "level", &refine_level, 0,
"initial refine level");
#ifndef P4_TO_P8
sc_options_add_string (opt, 'c', "configuration", &config_name, "unit",
"configuration: unit|periodic|three|moebius|star");
#else
sc_options_add_string (opt, 'c', "configuration", &config_name, "unit",
"configuration: unit|periodic|rotwrap|twocubes|rotcubes|shell");
#endif
sc_options_add_bool (opt, 0, "oldschool", &oldschool, 0,
"Use original p4est_new call");
sc_options_add_switch (opt, 0, "generate", &generate,
"Generate regression commands");
sc_options_add_string (opt, 'f', "load-forest", &load_name, NULL,
"load saved " P4EST_STRING);
sc_options_add_switch (opt, 0, "multiple-lnodes",
&test_multiple_orders,
"Also time lnodes for orders 2, 4, and 8");
sc_options_add_switch (opt, 0, "skip-nodes", &skip_nodes, "Skip nodes");
sc_options_add_switch (opt, 0, "skip-lnodes", &skip_lnodes, "Skip lnodes");
sc_options_add_switch (opt, 0, "repartition-lnodes",
&repartition_lnodes,
"Repartition to load-balance lnodes");
first_argc = sc_options_parse (p4est_package_id, SC_LP_DEFAULT,
opt, argc, argv);
if (first_argc < 0 || first_argc != argc) {
sc_options_print_usage (p4est_package_id, SC_LP_ERROR, opt, NULL);
return 1;
}
if (max_ranges < -1 || max_ranges == 0) {
P4EST_GLOBAL_LERROR ("The -m / --max-ranges option must be positive\n");
return 1;
}
sc_options_print_summary (p4est_package_id, SC_LP_PRODUCTION, opt);
if (skip_lnodes) {
if (test_multiple_orders) {
SC_GLOBAL_PRODUCTION
("Warning: cannot test multiple lnode orders if --skip-lnodes is given.\n");
test_multiple_orders = 0;
}
}
wrongusage = 0;
config = P4EST_CONFIG_NULL;
if (!strcmp (config_name, "unit")) {
config = P4EST_CONFIG_UNIT;
}
else if (!strcmp (config_name, "periodic")) {
config = P4EST_CONFIG_PERIODIC;
}
#ifndef P4_TO_P8
else if (!strcmp (config_name, "three")) {
config = P4EST_CONFIG_THREE;
}
else if (!strcmp (config_name, "moebius")) {
config = P4EST_CONFIG_MOEBIUS;
}
else if (!strcmp (config_name, "star")) {
config = P4EST_CONFIG_STAR;
}
#else
else if (!strcmp (config_name, "rotwrap")) {
config = P4EST_CONFIG_ROTWRAP;
}
else if (!strcmp (config_name, "twocubes")) {
config = P4EST_CONFIG_TWOCUBES;
}
else if (!strcmp (config_name, "rotcubes")) {
config = P4EST_CONFIG_ROTCUBES;
}
else if (!strcmp (config_name, "shell")) {
config = P4EST_CONFIG_SHELL;
}
#endif
else if (load_name != NULL) {
config_name = load_name;
}
else {
wrongusage = 1;
}
if (wrongusage) {
P4EST_GLOBAL_LERRORF ("Wrong configuration name given: %s\n",
config_name);
sc_options_print_usage (p4est_package_id, SC_LP_ERROR, opt, NULL);
sc_abort_collective ("Usage error");
}
/* get command line argument: maximum refinement level */
level_shift = 4;
/* print general setup information */
P4EST_GLOBAL_STATISTICSF
("Processors %d configuration %s level %d shift %d\n", mpi->mpisize,
config_name, refine_level, level_shift);
/* start overall timing */
mpiret = sc_MPI_Barrier (mpi->mpicomm);
SC_CHECK_MPI (mpiret);
sc_flops_start (&fi);
/* create connectivity and forest structures */
regression = NULL;
if (load_name == NULL) {
#ifndef P4_TO_P8
if (config == P4EST_CONFIG_PERIODIC) {
}
else if (config == P4EST_CONFIG_THREE) {
connectivity = p4est_connectivity_new_corner ();
}
else if (config == P4EST_CONFIG_MOEBIUS) {
connectivity = p4est_connectivity_new_moebius ();
}
else if (config == P4EST_CONFIG_STAR) {
connectivity = p4est_connectivity_new_star ();
}
else {
}
#else
if (config == P4EST_CONFIG_PERIODIC) {
}
else if (config == P4EST_CONFIG_ROTWRAP) {
connectivity = p8est_connectivity_new_rotwrap ();
}
else if (config == P4EST_CONFIG_TWOCUBES) {
}
else if (config == P4EST_CONFIG_ROTCUBES) {
}
else if (config == P4EST_CONFIG_SHELL) {
connectivity = p8est_connectivity_new_shell ();
}
else {
}
#endif
/* create new p4est from scratch */
if (oldschool) {
regression = regression_oldschool;
p4est = p4est_new_ext (mpi->mpicomm, connectivity,
15, 0, 0, 0, NULL, NULL);
}
else {
regression = regression_latest;
p4est = p4est_new_ext (mpi->mpicomm, connectivity,
0, refine_level - level_shift, 1, 0, NULL, NULL);
}
/* print all available regression tests */
if (generate) {
const char *config_gname = NULL;
P4EST_GLOBAL_PRODUCTION ("Checksum regression tests available:\n");
for (r = regression; r->config != P4EST_CONFIG_NULL; ++r) {
switch (r->config) {
case P4EST_CONFIG_PERIODIC:
config_gname = "periodic";
break;
#ifndef P4_TO_P8
case P4EST_CONFIG_THREE:
config_gname = "three";
break;
case P4EST_CONFIG_MOEBIUS:
config_gname = "moebius";
break;
case P4EST_CONFIG_STAR:
config_gname = "star";
break;
#else
case P4EST_CONFIG_ROTWRAP:
config_gname = "rotwrap";
break;
case P4EST_CONFIG_TWOCUBES:
config_gname = "twocubes";
break;
case P4EST_CONFIG_ROTCUBES:
config_gname = "rotcubes";
break;
case P4EST_CONFIG_SHELL:
config_gname = "shell";
break;
#endif
default:
config_gname = "unit";
break;
}
P4EST_GLOBAL_PRODUCTIONF ("mpirun -np %3d %s%s -c %10s -l %2d\n",
r->mpisize, P4EST_STRING "_timings",
oldschool ? " --oldschool" : "",
config_gname, r->level);
}
}
}
else {
p4est = p4est_load (load_name, mpi->mpicomm, 0, 0, NULL, &connectivity);
}
p4est->inspect->use_balance_ranges_notify = use_ranges_notify;
p4est->inspect->use_balance_verify = use_balance_verify;
P4EST_GLOBAL_STATISTICSF
("Balance: new overlap %d new subtree %d borders %d\n", overlap,
(overlap && subtree), (overlap && borders));
quadrant_counts = P4EST_ALLOC (p4est_locidx_t, p4est->mpisize);
/* time refine */
sc_flops_snap (&fi, &snapshot);
p4est_refine (p4est, 1, refine_fractal, NULL);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_REFINE], snapshot.iwtime, "Refine");
#ifdef P4EST_TIMINGS_VTK
p4est_vtk_write_file (p4est, "timings_refined");
#endif
count_refined = p4est->global_num_quadrants;
/* time balance */
sc_flops_snap (&fi, &snapshot);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_BALANCE], snapshot.iwtime, "Balance");
sc_stats_set1 (&stats[TIMINGS_BALANCE_A],
p4est->inspect->balance_A, "Balance A time");
sc_stats_set1 (&stats[TIMINGS_BALANCE_COMM],
p4est->inspect->balance_comm, "Balance comm time");
sc_stats_set1 (&stats[TIMINGS_BALANCE_B],
p4est->inspect->balance_B, "Balance B time");
sc_stats_set1 (&stats[TIMINGS_BALANCE_A_COUNT_IN],
(double) p4est->inspect->balance_A_count_in,
"Balance A count inlist");
sc_stats_set1 (&stats[TIMINGS_BALANCE_A_COUNT_OUT],
(double) p4est->inspect->balance_A_count_out,
"Balance A count outlist");
sc_stats_set1 (&stats[TIMINGS_BALANCE_COMM_SENT],
(double) p4est->inspect->balance_comm_sent,
"Balance sent second round");
sc_stats_set1 (&stats[TIMINGS_BALANCE_COMM_NZPEERS],
(double) p4est->inspect->balance_comm_nzpeers,
"Balance nonzero peers second round");
sc_stats_set1 (&stats[TIMINGS_BALANCE_B_COUNT_IN],
(double) p4est->inspect->balance_B_count_in,
"Balance B count inlist");
sc_stats_set1 (&stats[TIMINGS_BALANCE_B_COUNT_OUT],
(double) p4est->inspect->balance_B_count_out,
"Balance B count outlist");
sc_stats_set1 (&stats[TIMINGS_BALANCE_RANGES],
p4est->inspect->balance_ranges, "Balance time for ranges");
sc_stats_set1 (&stats[TIMINGS_BALANCE_NOTIFY],
p4est->inspect->balance_notify, "Balance time for notify");
sc_stats_set1 (&stats[TIMINGS_BALANCE_NOTIFY_ALLGATHER],
"Balance time for notify_allgather");
sc_stats_set1 (&stats[TIMINGS_BALANCE_A_ZERO_RECEIVES],
p4est->inspect->balance_zero_receives[0],
"Balance A zero receives");
sc_stats_set1 (&stats[TIMINGS_BALANCE_A_ZERO_SENDS],
p4est->inspect->balance_zero_sends[0],
"Balance A zero sends");
sc_stats_set1 (&stats[TIMINGS_BALANCE_B_ZERO_RECEIVES],
p4est->inspect->balance_zero_receives[1],
"Balance B zero receives");
sc_stats_set1 (&stats[TIMINGS_BALANCE_B_ZERO_SENDS],
p4est->inspect->balance_zero_sends[1],
"Balance B zero sends");
#ifdef P4EST_TIMINGS_VTK
p4est_vtk_write_file (p4est, "timings_balanced");
#endif
count_balanced = p4est->global_num_quadrants;
/* time rebalance - is a noop on the tree */
sc_flops_snap (&fi, &snapshot);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_REBALANCE], snapshot.iwtime, "Rebalance");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_A],
p4est->inspect->balance_A, "Rebalance A time");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_COMM],
p4est->inspect->balance_comm, "Rebalance comm time");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_B],
p4est->inspect->balance_B, "Rebalance B time");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_A_COUNT_IN],
(double) p4est->inspect->balance_A_count_in,
"Rebalance A count inlist");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_A_COUNT_OUT],
(double) p4est->inspect->balance_A_count_out,
"Rebalance A count outlist");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_COMM_SENT],
(double) p4est->inspect->balance_comm_sent,
"Rebalance sent second round");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_COMM_NZPEERS],
(double) p4est->inspect->balance_comm_nzpeers,
"Rebalance nonzero peers second round");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_B_COUNT_IN],
(double) p4est->inspect->balance_B_count_in,
"Rebalance B count inlist");
sc_stats_set1 (&stats[TIMINGS_REBALANCE_B_COUNT_OUT],
(double) p4est->inspect->balance_B_count_out,
"Rebalance B count outlist");
P4EST_ASSERT (count_balanced == p4est->global_num_quadrants);
P4EST_ASSERT (crc == p4est_checksum (p4est));
/* time a uniform partition */
sc_flops_snap (&fi, &snapshot);
p4est_partition (p4est, 0, NULL);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_PARTITION], snapshot.iwtime, "Partition");
#ifdef P4EST_TIMINGS_VTK
p4est_vtk_write_file (p4est, "timings_partitioned");
#endif
P4EST_ASSERT (crc == p4est_checksum (p4est));
/* time building the ghost layer */
sc_flops_snap (&fi, &snapshot);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_GHOSTS], snapshot.iwtime, "Ghost layer");
gcrc = p4est_ghost_checksum (p4est, ghost);
/* time the node numbering */
if (!skip_nodes) {
sc_flops_snap (&fi, &snapshot);
nodes = p4est_nodes_new (p4est, ghost);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_NODES], snapshot.iwtime, "Nodes");
}
else {
sc_stats_set1 (&stats[TIMINGS_NODES], 0., "Nodes");
}
/* set this anyway so the output format is dimension independent */
sc_stats_set1 (&stats[TIMINGS_TRILINEAR_OBSOLETE], 0., "Unused");
if (!skip_nodes) {
p4est_nodes_destroy (nodes);
}
if (!skip_lnodes && repartition_lnodes) {
p4est_partition_lnodes (p4est, ghost, 1, 0);
}
/* time the lnode numbering */
if (!skip_lnodes) {
sc_flops_snap (&fi, &snapshot);
lnodes = p4est_lnodes_new (p4est, ghost, 1);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_LNODES], snapshot.iwtime, "L-Nodes");
}
else {
sc_stats_set1 (&stats[TIMINGS_LNODES], 0., "L-Nodes");
}
if (test_multiple_orders) {
if (repartition_lnodes) {
p4est_partition_lnodes (p4est, ghost, 3, 0);
}
sc_flops_snap (&fi, &snapshot);
lnodes = p4est_lnodes_new (p4est, ghost, 3);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_LNODES3], snapshot.iwtime, "L-Nodes 3");
if (repartition_lnodes) {
p4est_partition_lnodes (p4est, ghost, 7, 0);
}
sc_flops_snap (&fi, &snapshot);
lnodes = p4est_lnodes_new (p4est, ghost, 7);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_LNODES7], snapshot.iwtime, "L-Nodes 7");
}
else {
sc_stats_set1 (&stats[TIMINGS_LNODES3], 0., "L-Nodes 3");
sc_stats_set1 (&stats[TIMINGS_LNODES7], 0., "L-Nodes 7");
}
/* time a partition with a shift of all elements by one processor */
for (i = 0, next_quadrant = 0; i < p4est->mpisize; ++i) {
prev_quadrant = next_quadrant;
next_quadrant = (p4est->global_num_quadrants * (i + 1)) / p4est->mpisize;
quadrant_counts[i] = (p4est_locidx_t) (next_quadrant - prev_quadrant);
}
if (p4est->mpisize > 1) {
quadrant_counts[0] += quadrant_counts[p4est->mpisize - 1]; /* same type */
quadrant_counts[p4est->mpisize - 1] = 0;
}
sc_flops_snap (&fi, &snapshot);
global_shipped = p4est_partition_given (p4est, quadrant_counts);
sc_flops_shot (&fi, &snapshot);
sc_stats_set1 (&stats[TIMINGS_REPARTITION], snapshot.iwtime, "Repartition");
P4EST_GLOBAL_PRODUCTIONF
("Done " P4EST_STRING "_partition_given shipped %lld quadrants %.3g%%\n",
(long long) global_shipped,
global_shipped * 100. / p4est->global_num_quadrants);
P4EST_ASSERT (crc == p4est_checksum (p4est));
/* verify forest checksum */
if (regression != NULL && mpi->mpirank == 0) {
for (r = regression; r->config != P4EST_CONFIG_NULL; ++r) {
if (r->config != config || r->mpisize != mpi->mpisize
|| r->level != refine_level)
continue;
SC_CHECK_ABORT (crc == r->checksum, "Checksum mismatch");
P4EST_GLOBAL_INFO ("Checksum regression OK\n");
break;
}
}
/* print status and checksum */
P4EST_GLOBAL_STATISTICSF ("Processors %d level %d shift %d"
" checksums 0x%08x 0x%08x\n",
mpi->mpisize, refine_level, level_shift,
crc, gcrc);
P4EST_GLOBAL_STATISTICSF ("Level %d refined to %lld balanced to %lld\n",
refine_level, (long long) count_refined,
(long long) count_balanced);
/* calculate and print timings */
sc_stats_compute (mpi->mpicomm, TIMINGS_NUM_STATS, stats);
sc_stats_print (p4est_package_id, SC_LP_ESSENTIAL,
TIMINGS_NUM_STATS, stats, 1, 1);
/* destroy the p4est and its connectivity structure */
P4EST_FREE (quadrant_counts);
sc_options_destroy (opt);
/* clean up and exit */
sc_finalize ();
mpiret = sc_MPI_Finalize ();
SC_CHECK_MPI (mpiret);
return 0;
}
void p4est_refine(p4est_t *p4est, int refine_recursive, p4est_refine_t refine_fn, p4est_init_t init_fn)
Refine a forest.
void p4est_destroy(p4est_t *p4est)
Destroy a p4est.
void p4est_partition(p4est_t *p4est, int allow_for_coarsening, p4est_weight_t weight_fn)
Equally partition the forest.
void p4est_balance(p4est_t *p4est, p4est_connect_type_t btype, p4est_init_t init_fn)
2:1 balance the size differences of neighboring elements in a forest.
p4est_t * p4est_load(const char *filename, sc_MPI_Comm mpicomm, size_t data_size, int load_data, void *user_pointer, p4est_connectivity_t **connectivity)
Load the complete connectivity/p4est structure from disk.
unsigned p4est_checksum(p4est_t *p4est)
Compute the checksum for a forest.
Routines for managing quadrants as elements of trees and subtrees.
p4est_gloidx_t p4est_partition_given(p4est_t *p4est, const p4est_locidx_t *num_quadrants_in_proc)
Partition p4est given the number of quadrants per proc.
#define P4EST_FREE(p)
free an allocated array
Definition: p4est_base.h:210
#define P4EST_ALLOC(t, n)
allocate a t-array with n elements
Definition: p4est_base.h:199
SC_DLL_PUBLIC int p4est_package_id
The package id for p4est within libsc.
int32_t p4est_topidx_t
Typedef for counting topological entities (trees, tree vertices).
Definition: p4est_base.h:93
int32_t p4est_locidx_t
Typedef for processor-local indexing of quadrants and nodes.
Definition: p4est_base.h:106
void p4est_init(sc_log_handler_t log_handler, int log_threshold)
Registers p4est with the SC Library and sets the logging behavior.
#define P4EST_ALLOC_ZERO(t, n)
allocate a t-array with n elements and zero
Definition: p4est_base.h:202
int64_t p4est_gloidx_t
Typedef for globally unique indexing of quadrants.
Definition: p4est_base.h:118
Routines for manipulating quadrants (neighbors, parents, children, etc.)
int p4est_quadrant_child_id(const p4est_quadrant_t *q)
Compute the position of this child within its siblings.
p4est_connectivity_t * p4est_connectivity_new_moebius(void)
Create a connectivity structure for a five-tree moebius band.
void p4est_connectivity_destroy(p4est_connectivity_t *connectivity)
Destroy a connectivity structure.
p4est_connectivity_t * p4est_connectivity_new_star(void)
Create a connectivity structure for a six-tree star.
#define P4EST_DIM
The spatial dimension.
Definition: p4est_connectivity.h:71
p4est_connectivity_t * p4est_connectivity_new_unitsquare(void)
Create a connectivity structure for the unit square.
#define P4EST_STRING
p4est identification string
Definition: p4est_connectivity.h:94
p4est_connectivity_t * p4est_connectivity_new_corner(void)
Create a connectivity structure for a three-tree mesh around a corner.
@ P4EST_CONNECT_FULL
= CORNER.
Definition: p4est_connectivity.h:119
p4est_connectivity_t * p4est_connectivity_new_periodic(void)
Create a connectivity structure for an all-periodic unit square.
Interface routines with extended capabilities.
p4est_t * p4est_new_ext(sc_MPI_Comm mpicomm, p4est_connectivity_t *connectivity, p4est_locidx_t min_quadrants, int min_level, int fill_uniform, size_t data_size, p4est_init_t init_fn, void *user_pointer)
Create a new forest.
Passing quadrants and data to neighboring processes.
p4est_ghost_t * p4est_ghost_new(p4est_t *p4est, p4est_connect_type_t btype)
Builds the ghost layer.
void p4est_ghost_destroy(p4est_ghost_t *ghost)
Frees all memory used for the ghost layer.
unsigned p4est_ghost_checksum(p4est_t *p4est, p4est_ghost_t *ghost)
Compute the parallel checksum of a ghost layer.
Generate Lobatto node numbers for any degree.
void p4est_partition_lnodes(p4est_t *p4est, p4est_ghost_t *ghost, int degree, int partition_for_coarsening)
Partition using weights based on the number of nodes assigned to each element in lnodes.
void p4est_lnodes_destroy(p4est_lnodes_t *lnodes)
Free all memory in a previously constructed lnodes structure.
p4est_lnodes_t * p4est_lnodes_new(p4est_t *p4est, p4est_ghost_t *ghost_layer, int degree)
Create a tensor-product Lobatto node structure for a given degree.
Routines for printing a forest and associated fields to VTK format.
void p4est_vtk_write_file(p4est_t *p4est, p4est_geometry_t *geom, const char *filename)
Write the p4est in VTK format.
Routines for managing quadrants as elements of trees and subtrees.
Routines for manipulating quadrants (neighbors, parents, children, etc.)
p8est_connectivity_t * p8est_connectivity_new_periodic(void)
Create a connectivity structure for an all-periodic unit cube.
p8est_connectivity_t * p8est_connectivity_new_unitcube(void)
Create a connectivity structure for the unit cube.
p8est_connectivity_t * p8est_connectivity_new_twocubes(void)
Create a connectivity structure that contains two cubes.
p8est_connectivity_t * p8est_connectivity_new_shell(void)
Create a connectivity structure that builds a spherical shell.
p8est_connectivity_t * p8est_connectivity_new_rotwrap(void)
Create a connectivity structure for a mostly periodic unit cube.
p8est_connectivity_t * p8est_connectivity_new_rotcubes(void)
Create a connectivity structure that contains a few cubes.
Interface routines with extended capabilities.
Passing quadrants and data to neighboring processes.
Generate Lobatto node numbers for any degree.
Routines for printing a forest and associated fields to VTK format.
This structure holds the 2D inter-tree connectivity information.
Definition: p4est_connectivity.h:190
Quadrants that neighbor the local domain.
Definition: p4est_ghost.h:46
Data pertaining to selecting, inspecting, and profiling algorithms.
Definition: p4est_extended.h:62
double balance_notify
time spent in sc_notify
Definition: p4est_extended.h:84
double balance_notify_allgather
time spent in sc_notify_allgather
Definition: p4est_extended.h:86
int balance_max_ranges
If positive and smaller than p4est_num ranges, overrides it.
Definition: p4est_extended.h:72
int use_balance_ranges_notify
If true, call both sc_ranges and sc_notify and verify consistency.
Definition: p4est_extended.h:68
double balance_ranges
time spent in sc_ranges
Definition: p4est_extended.h:83
int use_balance_ranges
Use sc_ranges to determine the asymmetric communication pattern.
Definition: p4est_extended.h:65
int use_balance_verify
Verify sc_ranges and/or sc_notify as applicable.
Definition: p4est_extended.h:70
Store a parallel numbering of Lobatto points of a given degree > 0.
Definition: p4est_lnodes.h:145
This structure holds complete parallel node information.
Definition: p4est_nodes.h:141
The 2D quadrant datatype.
Definition: p4est.h:76
int8_t level
level of refinement
Definition: p4est.h:80
The p4est forest datatype.
Definition: p4est.h:150
int mpisize
number of MPI processes
Definition: p4est.h:152
p4est_inspect_t * inspect
algorithmic switches
Definition: p4est.h:185
p4est_gloidx_t global_num_quadrants
number of quadrants on all trees on all processors
Definition: p4est.h:169