blob: a73def9692b00e93279a8fa1b7e796d8a1e2ba34 [file] [log] [blame]
/*
* Copyright (c) 2011-2012, Los Alamos National Security, LLC.
* All rights Reserved.
*
* Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
* under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
* Laboratory (LANL), which is operated by Los Alamos National Security, LLC
* for the U.S. Department of Energy. The U.S. Government has rights to use,
* reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
* ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Los Alamos National Security, LLC, Los Alamos
* National Laboratory, LANL, the U.S. Government, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
* SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* CLAMR -- LA-CC-11-094
* This research code is being developed as part of the
* 2011 X Division Summer Workshop for the express purpose
* of a collaborative code for development of ideas in
* the implementation of AMR codes for Exascale platforms
*
* AMR implementation of the Wave code previously developed
* as a demonstration code for regular grids on Exascale platforms
* as part of the Supercomputing Challenge and Los Alamos
* National Laboratory
*
* Authors: Bob Robey XCP-2 brobey@lanl.gov
* Neal Davis davis68@lanl.gov, davis68@illinois.edu
* David Nicholaeff dnic@lanl.gov, mtrxknight@aol.com
* Dennis Trujillo dptrujillo@lanl.gov, dptru10@gmail.com
*
*
* This file and the associated header is based on a file from the capablanca
* project available under the MIT open-source license. As author of that code,
* I, Neal Davis, permit repurposing and redistribution for CLAMR under the New
* BSD License used above.
* http://code.google.com/p/capablanca/
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "state.h"
#include "partition.h"
#include "mesh.h"
#include "hash.h"
#include "crux.h"
//#include "graphics/display.h"
#include "graphics.h"
#include <fstream>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/stat.h>
#include <limits.h>
#define OUTPUT_INTERVAL 100
#define COARSE_GRID_RES 128
#define MAX_TIME_STEP 3000
using namespace std;
// Global variables.
char progName[12]; // Program name.
char progVers[8]; // Program version.
// External global variables.
extern bool verbose,
localStencil,
outline,
face_based,
dynamic_load_balance_on,
h5_spoutput,
neighbor_remap,
restart;
extern int outputInterval,
crux_type,
enhanced_precision_sum,
tmax,
levmx,
nx,
ny,
niter,
measure_type,
lttrace_on,
do_quo_setup,
calc_neighbor_type,
choose_hash_method,
initial_order,
graphic_outputInterval,
graphics_type,
checkpoint_outputInterval,
num_of_rollback_states,
cycle_reorder;
extern float
mem_opt_factor;
extern double
upper_mass_diff_percentage;
extern char* restart_file;
void outputHelp()
{ cout << "CLAMR is an experimental adaptive mesh refinement code for the GPU." << endl
#ifdef PACKAGE_VERSION
<< "Version is " << PACKAGE_VERSION << endl << endl
#endif
<< "Usage: " << progName << " [options]..." << endl
<< " -b <B> Number of rollback images, disk or in memory (default 2);" << endl
<< " -c <C> Checkpoint to disk at interval specified;" << endl
<< " -C <C> Checkpoint to memory at interval specified;" << endl
<< " -d turn on LTTRACE;" << endl
<< " -D turn on dynamic load balancing using LTTRACE;" << endl
<< " -e <E> force hash_method, ie linear, quadratic..." <<endl
<< " \"perfect\"" << endl
<< " \"linear\"" << endl
<< " \"quadratic\"" << endl
<< " \"prime_jump\"" << endl
<< " -f face-based finite difference;" << endl
<< " -g <g> specify I step between saving graphics information for post processing;" << endl
<< " -G <G> specify graphics file type for post processing;" << endl
<< " \"bmp\"" << endl
<< " \"gif\"" << endl
<< " \"jpeg\"" << endl
<< " \"mpeg\"" << endl
<< " \"pdf\"" << endl
<< " \"png\"" << endl
<< " \"svg\"" << endl
<< " \"data\"" << endl
<< " -h display this help message;" << endl
<< " -i <I> specify I steps between output files;" << endl
<< " -l <l> max number of levels;" << endl
<< " -M <M> memory optimization factor 1.0 <= M <=100.0 (default 1.0 -- represents 1/20 perfect hash);" << endl
<< " -m <m> specify partition measure type;" << endl
<< " \"with_duplicates\"" << endl
<< " \"without_duplicates\"" << endl
<< " -N <n> specify calc neighbor type;" << endl
<< " \"hash_table\"" << endl
<< " \"kdtree\"" << endl
<< " -n <N> specify coarse grid resolution of NxN;" << endl
<< " -o turn off outlines;" << endl
<< " -P <P> specify initial order P;" << endl
<< " \"original_order\"" << endl
<< " \"hilbert_sort\"" << endl
<< " \"hilbert_partition\"" << endl
<< " \"z_order\"" << endl
<< " -p <p> specify ordering P every cycle;" << endl
<< " \"original_order\"" << endl
<< " \"hilbert_sort\"" << endl
<< " \"hilbert_partition\"" << endl
<< " \"local_hilbert\"" << endl
<< " \"local_fixed\"" << endl
<< " \"z_order\"" << endl
<< " -q turn on quo;" << endl
<< " -r regular sum instead of enhanced precision sum (Kahan sum);" << endl
<< " -R restart simulation from the backup file specified;" << endl
<< " -s <s> specify space-filling curve method S;" << endl
<< " -S write out double precision data as single precision;" << endl
<< " -T execute with TVD;" << endl
<< " -t <t> specify T time steps to run;" << endl
<< " -u allowed percentage of difference between total mass between iterations." << endl
<< " the default value for this parameter is 2.6e-13;" << endl
<< " -V use verbose output;" << endl
<< " -v display version information." << endl
<< " -z force recalculation of neighbors." << endl; }
void outputVersion()
{ cout << progName << " " << progVers << endl; }
/* parseInput(const int argc, char** argv)
*
* Interpret the command line input.
*/
void parseInput(const int argc, char** argv)
{ strcpy(progName, "clamr");
#ifdef PACKAGE_VERSION
strcpy(progVers, PACKAGE_VERSION);
#endif
// Reconstruct command line argument as a string.
char progCL[256]; // Complete program command line.
strcpy(progCL, argv[0]);
for (int i = 1; i < argc; i++)
{ strcat(progCL, " ");
strcat(progCL, argv[i]); }
// Set variables to defaults, which may be overridden by CLI.
verbose = false;
localStencil = true;
outline = true;
#ifdef HAVE_LTTRACE
lttrace_on = 0;
#endif
#ifdef HAVE_QUO
do_quo_setup = 0;
#endif
dynamic_load_balance_on = false;
crux_type = CRUX_NONE;
face_based = false;
restart = false;
restart_file = NULL;
outputInterval = OUTPUT_INTERVAL;
nx = COARSE_GRID_RES;
ny = COARSE_GRID_RES;
niter = MAX_TIME_STEP;
neighbor_remap = true;
//measure_type = CSTARVALUE;
measure_type = NO_PARTITION_MEASURE;
calc_neighbor_type = HASH_TABLE;
choose_hash_method = METHOD_UNSET;
initial_order = HILBERT_SORT;
cycle_reorder = ORIGINAL_ORDER;
graphic_outputInterval = INT_MAX;
graphics_type = GRAPHICS_NONE;
checkpoint_outputInterval = INT_MAX;
num_of_rollback_states = 2;
levmx = 1;
mem_opt_factor = 1.0;
upper_mass_diff_percentage = -1.0;
enhanced_precision_sum = SUM_KAHAN;
char *val;
if (argc > 1)
{ int i = 1;
val = strtok(argv[i++], " ,.-");
while (val != NULL){
switch (val[0]){
case 'b': // Number of rollback images, disk or in memory (default 2)
sprintf(val,"0");
if (i < argc) val = strtok(argv[i++], " ,");
if(atoi(val) < 1){
printf("backup number must be at least 1, setting to default value 2\n");
}
else{
num_of_rollback_states = atoi(val);
}
break;
case 'c': // Checkpoint to disk at interval specified
val = strtok(argv[i++], " ,.-");
checkpoint_outputInterval = atoi(val);
crux_type = CRUX_DISK;
break;
case 'C': // Checkpoint to memory at interval specified
val = strtok(argv[i++], " ,.-");
checkpoint_outputInterval = atoi(val);
crux_type = CRUX_IN_MEMORY;
break;
case 'd': // Turn on lttrace.
// This is provided as a separate option to measure
// the overhead of having lttrace on.
#ifdef HAVE_LTTRACE
lttrace_on = 1;
#endif
break;
case 'D': // Turn on dynamic load balancing.
// This forces on lttrace.
#ifdef HAVE_LTTRACE
lttrace_on = true;
dynamic_load_balance_on = true;
#endif
break;
case 'e': // hash method specified.
val = strtok(argv[i++], " ,");
if (! strcmp(val,"perfect") ) {
choose_hash_method = PERFECT_HASH;
} else if (! strcmp(val,"linear") ) {
choose_hash_method = LINEAR;
} else if (! strcmp(val,"quadratic") ) {
choose_hash_method = QUADRATIC;
} else if (! strcmp(val,"prime_jump") ) {
choose_hash_method = PRIME_JUMP;
}
break;
case 'f': // Use face-based finite difference
face_based = true;
break;
case 'g': // Save graphics data to files during simulation.
val = strtok(argv[i++], " ,.-");
graphic_outputInterval = atoi(val);
if (graphics_type == GRAPHICS_NONE) graphics_type = GRAPHICS_DATA;
break;
case 'G': // Graphics data file type.
val = strtok(argv[i++], " ,.-");
if (! strcmp(val,"none") ) {
graphics_type = GRAPHICS_NONE;
graphic_outputInterval = INT_MAX;
} else if (! strcmp(val,"data") ) {
graphics_type = GRAPHICS_DATA;
#ifdef HAVE_MAGICKWAND
} else if (! strcmp(val,"bmp") ) {
graphics_type = GRAPHICS_BMP;
} else if (! strcmp(val,"gif") ) {
graphics_type = GRAPHICS_GIF;
} else if (! strcmp(val,"jpeg") ) {
graphics_type = GRAPHICS_JPEG;
} else if (! strcmp(val,"mpeg") ) {
graphics_type = GRAPHICS_MPEG;
} else if (! strcmp(val,"pdf") ) {
graphics_type = GRAPHICS_PDF;
} else if (! strcmp(val,"png") ) {
graphics_type = GRAPHICS_PNG;
} else if (! strcmp(val,"svg") ) {
graphics_type = GRAPHICS_SVG;
#endif
} else {
printf("Unrecognized option for graphics file type %s\n",val);
exit(-1);
}
break;
case 'h': // Output help.
outputHelp();
cout.flush();
exit(EXIT_SUCCESS);
break;
case 'i': // Output interval specified.
val = strtok(argv[i++], " ,.-");
outputInterval = atoi(val);
break;
case 'l': // max level specified.
val = strtok(argv[i++], " ,");
levmx = atoi(val);
break;
case 'M': // memory optimization factor
val = strtok(argv[i++], " ,");
mem_opt_factor = atof(val);
break;
case 'm': // partition measure specified.
val = strtok(argv[i++], " ,");
if (! strcmp(val,"no_partition_measure") ) {
measure_type = NO_PARTITION_MEASURE;
} else if (! strcmp(val,"with_duplicates") ) {
measure_type = WITH_DUPLICATES;
} else if (! strcmp(val,"without_duplicates") ) {
measure_type = WITHOUT_DUPLICATES;
} else if (! strcmp(val,"cvalue") ) {
measure_type = CVALUE;
} else if (! strcmp(val,"cstarvalue") ) {
measure_type = CSTARVALUE;
}
break;
case 'N': // calc neighbor type specified.
val = strtok(argv[i++], " ,");
if (! strcmp(val,"hash_table") ) {
calc_neighbor_type = HASH_TABLE;
} else if (! strcmp(val,"kdtree") ) {
calc_neighbor_type = KDTREE;
}
break;
case 'n': // Domain grid resolution specified.
val = strtok(argv[i++], " ,");
nx = atoi(val);
ny = nx;
break;
case 'o': // Turn off outlines on mesh drawing.
outline = false;
break;
case 'P': // Initial order specified.
val = strtok(argv[i++], " ,");
if (! strcmp(val,"original_order") ) {
initial_order = ORIGINAL_ORDER;
} else if (! strcmp(val,"hilbert_sort") ) {
initial_order = HILBERT_SORT;
} else if (! strcmp(val,"hilbert_partition") ) {
initial_order = HILBERT_PARTITION;
} else if (! strcmp(val,"z_order") ) {
initial_order = ZORDER;
}
break;
case 'p': // Initial order specified.
val = strtok(argv[i++], " ,");
if (! strcmp(val,"original_order") ) {
cycle_reorder = ORIGINAL_ORDER;
localStencil = false;
} else if (! strcmp(val,"hilbert_sort") ) {
cycle_reorder = HILBERT_SORT;
localStencil = false;
} else if (! strcmp(val,"hilbert_partition") ) {
cycle_reorder = HILBERT_PARTITION;
localStencil = false;
} else if (! strcmp(val,"local_hilbert") ) {
cycle_reorder = ORIGINAL_ORDER;
localStencil = true;
} else if (! strcmp(val,"local_fixed") ) {
cycle_reorder = ORIGINAL_ORDER;
localStencil = false;
} else if (! strcmp(val,"z_order") ) {
cycle_reorder = ZORDER;
localStencil = false;
}
break;
case 'q': // turn on quo package.
#ifdef HAVE_QUO
do_quo_setup = 1;
#endif
break;
case 'r': // Regular sum instead of enhanced precision sum.
val = strtok(argv[i++], " ,");
if (! strcmp(val,"regular_sum") ) {
enhanced_precision_sum = SUM_REGULAR;
} else if (! strcmp(val,"kahan_sum") ) {
enhanced_precision_sum = SUM_KAHAN;
} else {
printf("Error with sum argument %s\n",val);
exit(0);
}
break;
case 'R': // Restart application from last checkpoint
restart = true;
restart_file = strtok(argv[i++], " ,");
#ifndef HDF5_FF
struct stat stat_descriptor;
if (stat(restart_file,&stat_descriptor) == -1){
printf("Error -- restart file %s does not exist\n",restart_file);
exit(0);
}
#endif
break;
case 's': // Space-filling curve method specified (default HILBERT_SORT).
// Add different problem setups such as sloped wave in x, y and diagonal directions to help check algorithm
// HILBERT_SORT
break;
case 'T': // TVD inclusion specified.
break;
case 't': // Number of time steps specified.
val = strtok(argv[i++], " ,.-");
niter = atoi(val);
break;
case 'u': // Allowed percentage of difference in mass per iteration
val = strtok(argv[i++], " ,");
upper_mass_diff_percentage = atof(val);
break;
case 'V': // Verbose output desired.
verbose = true;
break;
case 'v': // Version.
outputVersion();
cout.flush();
exit(EXIT_SUCCESS);
break;
case 'z': // Neighbor remap -- default is true, -z sets to false
neighbor_remap = false;
break;
default: // Unknown parameter encountered.
cout << "⚠ Unknown input parameter " << val << endl;
outputHelp();
cout.flush();
exit(EXIT_FAILURE);
break; }
val = strtok(argv[i++], " ,.-");
}
}
/*
if(upper_mass_diff_percentage < 0){
upper_mass_diff_percentage = 1.0e-12;
}
*/
}