blob: 40078028914d2152e1c8889f8a2729bf62d722c7 [file] [log] [blame]
//
// See README-LCALS_license.txt for access and distribution restrictions
//
//
// Header file with enums, macros, routines and structures used to
// compile and run loops in LCALS suite and to generate execution
// statistics.
//
#ifndef LCALSSuite_HXX
#define LCALSSuite_HXX
#include "LCALSParams.hxx"
#include "LCALSStats.hxx"
#include <vector>
#include <string>
//
// Enumeration defining unique id for each loop KERNEL in suite.
//
// IMPORTANT: Generally, this should not need modification unless
// new loops (i.e., kernels) are added to the suite.
//
// Note: To keep output understandable, keep this consistent with
// routine defineLoopSuiteRunInfo().
//
enum LoopKernelID {
// Keep this one first and don't comment out (!!)
// This insures loop ids start at zero so all array indexing
// or data structures is correct. Also, this loop is not
// executed the same way the others are.
REF_LOOP = 0,
//
// Loop Subset A: Loops extracted from LLNL app codes.
// They are implemented in runA<variant>Loops.cxx files.
//
PRESSURE_CALC,
PRESSURE_CALC_ALT,
ENERGY_CALC,
ENERGY_CALC_ALT,
VOL3D_CALC,
DEL_DOT_VEC_2D,
COUPLE,
FIR,
//
// Loop Subset B: "Basic" Loops.
// They are implemented in runB<variant>Loops.cxx files.
//
INIT3,
MULADDSUB,
IF_QUAD,
TRAP_INT,
//
// Loop Subset C: Loops from older Livermore Loops in "C" suite.
// They are implemented in runC<variant>Loops.cxx files.
//
HYDRO_1D,
ICCG,
INNER_PROD,
BAND_LIN_EQ,
TRIDIAG_ELIM,
EOS,
ADI,
INT_PREDICT,
DIFF_PREDICT,
FIRST_SUM,
FIRST_DIFF,
PIC_2D,
PIC_1D,
HYDRO_2D,
GEN_LIN_RECUR,
DISC_ORD,
MAT_X_MAT,
PLANCKIAN,
IMP_HYDRO_2D,
FIND_FIRST_MIN,
NUM_LOOP_KERNELS // Keep this one last and NEVER comment out (!!)
};
//
// Enumeration defining unique id for each loop VARIANT in suite.
//
// IMPORTANT: Generally, this should not need modification unless
// new loop variants are added to the suite.
//
enum LoopVariantID {
//
// These variants define LCALS benchmark
//
RAW,
RAW_OMP,
FORALL_LAMBDA,
FORALL_LAMBDA_OMP,
#if defined(LCALS_DO_MISC)
//
// These variants are used in miscellaneous LCALS studies
//
FORALL_HYBRID_LAMBDA,
#if 0 // THESE ARE NOT AVAILABLE YET!!!
FORALL_HYBRID_LAMBDA_OMP,
#endif
FORALL_FUNCTOR,
FORALL_FUNCTOR_OMP,
#if 0 // THESE ARE NOT AVAILABLE YET!!!
FORALL_HYBRID_FUNCTOR,
FORALL_HYBRID_FUNCTOR_OMP,
#endif
RAW_FUNC,
FORALL_LAMBDA_TYPEFIX,
FORALL_LAMBDA_OMP_TYPEFIX,
FORALL_HYBRID_LAMBDA_TYPEFIX,
#endif // if LCALS_DO_MISC
};
//
// Enumeration defining possible loop lengths to run.
//
enum LoopLength {
LONG = 0,
MEDIUM,
SHORT,
NUM_LENGTHS // Keep this one last (!!)
};
////////////////////////////////////////////////////////////////////////////////
//
// The following macro constants define which loop VARIANTS can be compiled
// (and potentially) run for a given compiler.
//
// NOTE: The Makefile sets the LCALS_COMPILER_* macro constant.
//
// --> IMPORTANT: Actual selection of which loop variants are run is done
// in main.cxx via the vector 'run_variants'.
//
////////////////////////////////////////////////////////////////////////////////
#if defined(LCALS_COMPILER_ICC)
//
// Configuration options for Intel compilers
//
#define COMPILE_RAW_VARIANTS
#define COMPILE_LAMBDA_VARIANTS
#define COMPILE_FUNCTOR_VARIANTS
#define COMPILE_OMP_VARIANTS
#elif defined(LCALS_COMPILER_GNU)
//
// Configuration options for GNU compilers
//
#define COMPILE_RAW_VARIANTS
#define COMPILE_LAMBDA_VARIANTS
#define COMPILE_FUNCTOR_VARIANTS
#define COMPILE_OMP_VARIANTS
#elif defined(LCALS_COMPILER_XLC12)
//
// Configuration options for IBM xlC compilers
//
//
// xlC compilers DO NOT support lambda functions currently!!
//
#define COMPILE_RAW_VARIANTS
#undef COMPILE_LAMBDA_VARIANTS
#define COMPILE_FUNCTOR_VARIANTS
#define COMPILE_OMP_VARIANTS
#elif defined(LCALS_COMPILER_CLANG)
//
// Configuration options for clang compilers
//
//
// Clang compilers DO NOT support OpenMP currently!!
//
#define COMPILE_RAW_VARIANTS
#define COMPILE_LAMBDA_VARIANTS
#define COMPILE_FUNCTOR_VARIANTS
#undef COMPILE_OMP_VARIANTS
#else
#error LCALS compiler is undefined!
#endif
//
// The following macro constants are used to turn on/off compilation of
// individual loop KERNELS in suite. Names are consistent with LoopID
// enum above.
//
#if defined (LCALS_DO_OMP_ONLY)
//
// Only these loops have OpenMP implementations. The imlementations are
// found in runOMP<variant>Loops.cxx files.
//
// Loop Subset A: Loops extracted from LLNL app codes.
#define COMPILE_PRESSURE_CALC
#define COMPILE_PRESSURE_CALC_ALT
#define COMPILE_ENERGY_CALC
#define COMPILE_ENERGY_CALC_ALT
#define COMPILE_VOL3D_CALC
#define COMPILE_DEL_DOT_VEC_2D
#define COMPILE_COUPLE
#define COMPILE_FIR
// Loop Subset B: "Basic" Loops.
#define COMPILE_INIT3
#define COMPILE_MULADDSUB
#define COMPILE_IF_QUAD
#define COMPILE_TRAP_INT
// Loop Subset C: Loops from older Livermore Loops in "C" suite.
#define COMPILE_PIC_2D
#else // compile all loop kernels
//
// Loop Subset A: Loops extracted from LLNL app codes.
// They are implemented in runA<variant>Loops.cxx files.
//
#define COMPILE_PRESSURE_CALC
#define COMPILE_PRESSURE_CALC_ALT
#define COMPILE_ENERGY_CALC
#define COMPILE_ENERGY_CALC_ALT
#define COMPILE_VOL3D_CALC
#define COMPILE_DEL_DOT_VEC_2D
#define COMPILE_COUPLE
#define COMPILE_FIR
//
// Loop Subset B: "Basic" Loops.
// They are implemented in runB<variant>Loops.cxx files.
//
#define COMPILE_INIT3
#define COMPILE_MULADDSUB
#define COMPILE_IF_QUAD
#define COMPILE_TRAP_INT
//
// Loop Subset C: Loops from older Livermore Loops in "C" suite.
// They are implemented in runLCK<variant>Loops.cxx files.
//
#define COMPILE_HYDRO_1D
#define COMPILE_ICCG
#define COMPILE_INNER_PROD
#define COMPILE_BAND_LIN_EQ
#define COMPILE_TRIDIAG_ELIM
#define COMPILE_EOS
#define COMPILE_ADI
#define COMPILE_INT_PREDICT
#define COMPILE_DIFF_PREDICT
#define COMPILE_FIRST_SUM
#define COMPILE_FIRST_DIFF
#define COMPILE_PIC_2D
#define COMPILE_PIC_1D
#define COMPILE_HYDRO_2D
#define COMPILE_GEN_LIN_RECUR
#define COMPILE_DISC_ORD
#define COMPILE_MAT_X_MAT
#define COMPILE_PLANCKIAN
#define COMPILE_IMP_HYDRO_2D
#define COMPILE_FIND_FIRST_MIN
#endif
//////////////////////////////////////////////////////////////////
//
// Structure holding double arrays and scalars used in loops.
//
// Note: These are initialized in allocateLoopData().
//
///////////////////////////////////////////////////////////////////
struct LoopData
{
//
// Structures to hold data for easy reinitialization
// (useful for verifying result checksums, etc.)
//
struct RealArray
{
int id;
Real_ptr data;
Index_type len;
};
struct IndxArray
{
int id;
Index_type* data;
Index_type len;
};
struct ComplexArray
{
int id;
Complex_ptr data;
Index_type len;
};
Index_type max_loop_length;
//
// Static values indicating number of data arrays
// of various forms used in loop suite.
//
// NOTE: These number may need to change to accomodate new loops.
// Also, other arrays may need to be added.
//
static const unsigned s_num_1D_Real_arrays = 16;
static const unsigned s_num_1D_Nx4_Real_arrays = 2;
static const unsigned s_num_1D_Indx_arrays = 5;
static const unsigned s_num_1D_Complex_arrays = 5;
static const unsigned s_num_2D_Nx25_Real_arrays = 4;
static const unsigned s_num_2D_7xN_Real_arrays = 11;
static const unsigned s_num_2D_64x64_Real_arrays = 1;
static const unsigned s_num_3D_2xNx4_Real_arrays = 3;
static const unsigned s_num_Real_scalars = 10;
//
// NOTE: To see how the following data structures are related,
// please see the routine allocateLoopData() in the
// file LCALSSuite.cxx.
//
// The reason that we hold on to the same data in two
// different ways is two-fold:
// 1) The first set of arrays below makes it easy to
// access pointers to data based on what is used in
// each loop kernel; e.g., arrays of variaous dimensions.
// 2) The second set of arrays makes it easy to process
// arrays for (re)initialization and checksum
// computation to verify results; e.g., we simply
// iterate through 1-dim arrays without having to
// know their lengths, if they are really being used
// as 2- or 3-dimensional arrays, for example.
//
//
// Data arrays and scalars used in loop execution.
//
Real_ptr array_1D_Real[s_num_1D_Real_arrays];
Real_ptr array_1D_Nx4_Real[s_num_1D_Nx4_Real_arrays];
Index_type* array_1D_Indx[s_num_1D_Indx_arrays];
Complex_ptr array_1D_Complex[s_num_1D_Complex_arrays];
Real_ptr* array_2D_Nx25_Real[s_num_2D_Nx25_Real_arrays];
Real_ptr* array_2D_7xN_Real[s_num_2D_7xN_Real_arrays];
Real_ptr* array_2D_64x64_Real[s_num_2D_64x64_Real_arrays];
Real_ptr** array_3D_2xNx4_Real[s_num_3D_2xNx4_Real_arrays];
Real_type scalar_Real[s_num_Real_scalars];
//
// Arrays of structs holding data arrays used for data initialization
// and checksum verification.
//
RealArray RealArray_1D[s_num_1D_Real_arrays];
RealArray RealArray_1D_Nx4[s_num_1D_Nx4_Real_arrays];
IndxArray IndxArray_1D[s_num_1D_Indx_arrays];
ComplexArray ComplexArray_1D[s_num_1D_Complex_arrays];
RealArray RealArray_2D_Nx25[s_num_2D_Nx25_Real_arrays];
RealArray RealArray_2D_7xN[s_num_2D_7xN_Real_arrays];
RealArray RealArray_2D_64x64[s_num_2D_64x64_Real_arrays];
RealArray RealArray_3D_2xNx4[s_num_3D_2xNx4_Real_arrays];
RealArray RealArray_scalars;
};
//
// Routine to access data structure that holds data needed to execute loops.
//
LoopData& getLoopData();
//
// Routine that generates vector of loop variant names string
// from vector of LoopVariantID enum values.
//
std::vector<std::string> getVariantNames(
const std::vector<LoopVariantID>& lvids);
//
// Routine that maps LoopVariantID enum value (used in main to help
// insure correctness) to string (used in loop framework for flexibility).
//
std::string getVariantName(LoopVariantID lvid);
//////////////////////////////////////////////////////////////////
//
// Routines to define how loop suite will be run and
// to set up data for loop suite.
//
//////////////////////////////////////////////////////////////////
//
// Routines to define specific details about how to run loop suite.
//
// Note: Individual loop lengths and sampling parameters
// are defined in this routine.
//
void defineLoopSuiteRunInfo(const std::vector<LoopVariantID>& run_variants,
bool run_loop[],
double sample_frac,
double loop_length_factor );
//
// Routines to allocate and initialize arrays (and scalars) for
// loops in suite and to free those arrays when done.
//
void allocateLoopData();
void freeLoopData();
//
// Routines to initialize and finalize loop data, statistics, timers, etc.
//
// Each of these routines must be called before and after the execution
// of each loop.
//
void loopInit(unsigned iloop, LoopStat& stat);
void loopInit(unsigned iloop); //, LoopStat& stat);
//
void loopFinalize(unsigned iloop, LoopStat& stat, LoopLength ilength);
//
// Routines to run reference loops for figure of merit (FOM) calculations.
//
void defineReferenceLoopRunInfo();
void computeReferenceLoopTimes();
//
// Routine called in main to execute loops corresponding to given
// variant ID and length. The run_loop boolean array indicates which
// loop kernels in suite to execute
//
void runLoopVariant( LoopVariantID lvid,
bool run_loop[],
LoopLength ilength );
//
// Routines to run specific loop variants for suite.
//
// THESE SHOULD NOT BE CALLED BY ROUTINE ABOVE, NOT DIRECTLY!!!
//
// loop_stats is vector of LoopStat objects corresponding to loop variant.
// run_loop boolean array indicates which loop kernels in suite to execute.
// ilength indicates which loop length to run (see LoopLength enum).
//
void runARawLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runBRawLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runCRawLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runARawFuncLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runBRawFuncLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runCRawFuncLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runOMPRawLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runAForallLambdaLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runBForallLambdaLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runCForallLambdaLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runOMPForallLambdaLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runAForallLambdaLoops_TYPEFIX( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runBForallLambdaLoops_TYPEFIX( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runCForallLambdaLoops_TYPEFIX( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runOMPForallLambdaLoops_TYPEFIX( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runAForallFunctorLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runBForallFunctorLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runCForallFunctorLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runOMPForallFunctorLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runAForallHybridLambdaLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runBForallHybridLambdaLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runCForallHybridLambdaLoops( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runAForallHybridLambdaLoops_TYPEFIX( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runBForallHybridLambdaLoops_TYPEFIX( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
void runCForallHybridLambdaLoops_TYPEFIX( std::vector<LoopStat>& loop_stats,
bool run_loop[],
LoopLength ilength );
//
// Recursively construct directories based on a relative or
// absolute path name. Return true if directory created
// successfully, else false.
//
bool recursiveMkdir(const std::string& path);
#endif // closing endif for header file include guard