Loading build/configure +2 −2 Original line number Diff line number Diff line Loading @@ -6,8 +6,8 @@ rm -rf CMake* cmake \ -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_CXX_COMPILER=g++ \ -D CXX_STD=11 \ -D CMAKE_CXX_COMPILER=mpic++ \ -D CMAKE_CXX_STANDARD=11 \ -D USE_OPENACC=0 \ -D USE_OPENMP=1 \ -D USE_KOKKOS=0 \ Loading src/CreateImage.cpp +21 −12 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ int run_tests( const std::string &filename, const Options &options ) // Call create_image for each method int N_errors = 0; std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) ); std::vector<std::vector<double>> time( methods.size() ); std::vector<Times> perf1( methods.size() ); std::vector<Times> perf2( methods.size() ); for ( size_t i = 0; i < methods.size(); i++ ) { if ( rank() == 0 ) std::cout << " Running " << methods[i] << std::endl; Loading @@ -117,16 +118,19 @@ int run_tests( const std::string &filename, const Options &options ) RayTrace::create_image( info2, methods[i] ); // Run the timing tests auto t0 = std::chrono::steady_clock::now(); std::vector<double> tmp1; std::vector<double> tmp2; while ( true ) { for ( int it = 0; it < iterations; it++ ) { auto t1 = std::chrono::steady_clock::now(); // Run the calculation RayTrace::create_image( info, methods[i] ); if ( options.benchmark ) { auto t2 = std::chrono::steady_clock::now(); // Mimic communication in full application communicate( *info ); } auto t2 = std::chrono::steady_clock::now(); time[i].push_back( 1e-9 * diff_ns( t2, t1 ) ); auto t3 = std::chrono::steady_clock::now(); tmp1.push_back( 1e-9 * diff_ns( t2, t1 ) ); tmp2.push_back( 1e-9 * diff_ns( t3, t1 ) ); t1 = t2; } double time = 1e-9 * diff_ns( std::chrono::steady_clock::now(), t0 ); Loading @@ -134,13 +138,18 @@ int run_tests( const std::string &filename, const Options &options ) if ( time > options.time ) break; } time[i] = gatherAll( time[i] ); perf1[i] = Times( tmp2 ); perf2[i] = Times( tmp2 ); // Check the results if ( options.scale == 1.0 ) { bool pass = check_ans( image0, I_ang0, *info ); if ( !pass ) N_errors++; } if ( perf1[i].avg[0] < 0.5 * perf1[i].avg[1] ) { std::cout << "Slow rank detected: " << rank() << std::endl; N_errors++; } free( (void *) info->image ); free( (void *) info->I_ang ); info->image = nullptr; Loading @@ -148,7 +157,7 @@ int run_tests( const std::string &filename, const Options &options ) } if ( rank() == 0 ) { if ( options.benchmark ) { double t = getAvg( time[0] ); double t = perf2[0].avg[1]; double N = 0; if ( info->seed_beam == nullptr ) { auto &beam = *( info->euv_beam ); Loading @@ -162,10 +171,10 @@ int run_tests( const std::string &filename, const Options &options ) } else { printf( "\n METHOD Avg Min Max Std Dev\n" ); for ( size_t i = 0; i < methods.size(); i++ ) { double min = getMin( time[i] ); double max = getMax( time[i] ); double avg = getAvg( time[i] ); double dev = getDev( time[i] ); double min = perf1[i].min[1]; double max = perf1[i].max[1]; double avg = perf1[i].avg[1]; double dev = perf1[i].std[1]; printf( "%14s %7.3f %7.3f %7.3f %7.3f\n", methods[i].c_str(), avg, min, max, dev ); if ( dev / avg > 0.25 ) { printf( " Standard deviation exceeded tolerance (25%%)\n" ); Loading src/CreateImageHelpers.cpp +50 −27 Original line number Diff line number Diff line Loading @@ -205,37 +205,60 @@ void scale_problem( RayTrace::create_image_struct &info, double scale ) /********************************************************************** * Basic math operations * * Compute the statistics for the times * **********************************************************************/ double getMin( const std::vector<double> &x ) Times::Times() { double y = x[0]; for ( size_t i = 1; i < x.size(); i++ ) y = std::min( y, x[i] ); return y; } double getMax( const std::vector<double> &x ) { double y = x[0]; for ( size_t i = 1; i < x.size(); i++ ) y = std::max( y, x[i] ); return y; } double getAvg( const std::vector<double> &x ) N[0] = 0; N[1] = 0; min[0] = 0; min[1] = 0; max[0] = 0; max[1] = 0; avg[0] = 0; avg[1] = 0; std[0] = 0; std[1] = 0; } Times::Times( const std::vector<double> &x ) { double y = 0; for ( size_t i = 0; i < x.size(); i++ ) y += x[i]; return y / x.size(); } double getDev( const std::vector<double> &x ) { double avg = getAvg( x ); double y = 0; for ( size_t i = 0; i < x.size(); i++ ) y += ( x[i] - avg ) * ( x[i] - avg ); y = sqrt( y / x.size() ); return y; // Compute local properties N[0] = x.size(); min[0] = 1e100; max[0] = 0; avg[0] = 0; for ( size_t i = 0; i < x.size(); i++ ) { min[0] = std::min( min[0], x[i] ); max[0] = std::max( max[0], x[i] ); avg[0] += x[i]; } // Compute global properties N[1] = N[0]; min[1] = min[0]; max[1] = max[0]; avg[1] = avg[0]; #ifdef USE_MPI static_assert( sizeof( unsigned long long ) == sizeof( size_t ), "Unexpected size" ); MPI_Allreduce( &N[0], &N[1], 1, MPI_UNSIGNED_LONG_LONG, MPI_SUM, MPI_COMM_WORLD ); MPI_Allreduce( &min[0], &min[1], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD ); MPI_Allreduce( &max[0], &max[1], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD ); MPI_Allreduce( &avg[0], &avg[1], 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD ); #endif // Finish computing the average and the standard deviation avg[0] /= N[0]; avg[1] /= N[1]; std[0] = 0; std[1] = 0; for ( size_t i = 0; i < x.size(); i++ ) { std[0] += ( x[i] - avg[0] ) * ( x[i] - avg[0] ); std[1] += ( x[i] - avg[1] ) * ( x[i] - avg[1] ); } #ifdef USE_MPI double tmp = std[1]; MPI_Allreduce( &tmp, &std[1], 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD ); #endif std[0] = sqrt( std[0] / ( N[0] - 1 ) ); std[1] = sqrt( std[1] / ( N[1] - 1 ) ); } Loading src/CreateImageHelpers.h +29 −33 Original line number Diff line number Diff line Loading @@ -10,6 +10,35 @@ #include "RayTrace/RayTrace.h" // Clas to hold options class Options { public: Options(); Options( int argc, char *argv[] ); public: bool benchmark = false; int iterations = 1; double scale = 1.0; double time = 0; std::vector<std::string> methods; std::vector<std::string> filenames; }; // Class to store statistical information about the times struct Times { size_t N[2]; double min[2]; double max[2]; double avg[2]; double std[2]; Times(); Times( const std::vector<double> × ); }; // Function to print info about the hardware that we will use void printHardware(); Loading @@ -31,37 +60,4 @@ bool check_ans( const double *image0, const double *I_ang0, const RayTrace::create_image_struct &data ); // Get the minimum value double getMin( const std::vector<double> &x ); // Get the maximum value double getMax( const std::vector<double> &x ); // Get the average value double getAvg( const std::vector<double> &x ); // Get the standard deviation double getDev( const std::vector<double> &x ); // Clas to hold options class Options { public: Options(); Options( int argc, char *argv[] ); public: bool benchmark = false; int iterations = 1; double scale = 1.0; double time = 0; std::vector<std::string> methods; std::vector<std::string> filenames; }; #endif src/WriteCompilerFeatures.cmakedeleted 100644 → 0 +0 −107 Original line number Diff line number Diff line INCLUDE(CheckCXXCompilerFlag) INCLUDE(CheckCXXSourceCompiles) # CMake is adding extra options for extensions that we don't want SET( CMAKE_CXX11_COMPILE_FEATURES -DDUMMY ) SET( CMAKE_CXX11_EXTENSION_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX11_STANDARD_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX14_COMPILE_FEATURES -DDUMMY ) SET( CMAKE_CXX14_EXTENSION_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX14_STANDARD_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX98_COMPILE_FEATURES -DDUMMY ) SET( CMAKE_CXX98_EXTENSION_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX98_STANDARD_COMPILE_OPTION -DDUMMY ) # This function writes a list of the supported C++ compiler features FUNCTION( WRITE_COMPILE_FEATURES FILENAME ${ARGN} ) SET( PREFIX ${ARGN} ) IF ( NOT PREFIX ) SET( PREFIX " " ) ELSE() SET( PREFIX "${PREFIX}_" ) ENDIF() FILE(WRITE ${FILENAME} "// This is a automatically generated file to set define variables for supported C++ features\n" ) TEST_FEATURE( SHARED_PTR ${FILENAME} ${PREFIX} "#include <memory> int main() { std::shared_ptr<int> ptr; return 0; }" ) TEST_FEATURE( STD_FUNCTION ${FILENAME} ${PREFIX} "#include <functional> void myfun(int) { } int main() { std::function<void(int)> f_display = myfun; return 0; }" ) TEST_FEATURE( STD_TUPLE ${FILENAME} ${PREFIX} "#include <tuple> int main() { std::tuple<double,int> x(1,2); return 0; }" ) TEST_FEATURE( VARIADIC_TEMPLATE ${FILENAME} ${PREFIX} "#include <iostream> template<class... Ts> void test(Ts... ts) {} int main() { test<int,double>(1,3); return 0; }" ) IF ( USE_MATLAB ) # Thread local storage and matlab do not agree FILE(APPEND ${FILENAME} "#define ${PREFIX}DISABLE_THREAD_LOCAL\n" ) ELSE() TEST_FEATURE( THREAD_LOCAL ${FILENAME} ${PREFIX} "#include <iostream> template<class... Ts> void test(Ts... ts) {} int main() { thread_local static int id = 0; return 0; }" ) ENDIF() TEST_FEATURE( MOVE_CONSTRUCTOR ${FILENAME} ${PREFIX} "#include <iostream> struct st { int i; st(){} st(st&&){} private: st(st&); }; st fun() { return st(); } int main() { st tmp = fun(); return 0; }" ) TEST_FEATURE( STATIC_ASSERT ${FILENAME} ${PREFIX} "#include <iostream> int main() { static_assert(true,\"test\"); return 0; }" ) ENDFUNCTION() # This function trys to compile and then sets the appropriate macro FUNCTION( TEST_FEATURE FEATURE_NAME FILENAME PREFIX CODE ) IF ( ${CXX_STD} STREQUAL "98" ) # Disable all features for 98 SET( ${FEATURE_NAME} OFF ) ELSEIF ( DISABLE_${FEATURE_NAME} ) # Disable feature SET( ${FEATURE_NAME} OFF ) ELSE() # Check if compiler allows feature SET( CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS} ) CHECK_CXX_SOURCE_COMPILES( "${CODE}" ${FEATURE_NAME} ) ENDIF() IF ( ${FEATURE_NAME} ) FILE(APPEND ${FILENAME} "#define ${PREFIX}ENABLE_${FEATURE_NAME}\n" ) ELSE() FILE(APPEND ${FILENAME} "#define ${PREFIX}DISABLE_${FEATURE_NAME}\n" ) ENDIF() ENDFUNCTION() Loading
build/configure +2 −2 Original line number Diff line number Diff line Loading @@ -6,8 +6,8 @@ rm -rf CMake* cmake \ -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_CXX_COMPILER=g++ \ -D CXX_STD=11 \ -D CMAKE_CXX_COMPILER=mpic++ \ -D CMAKE_CXX_STANDARD=11 \ -D USE_OPENACC=0 \ -D USE_OPENMP=1 \ -D USE_KOKKOS=0 \ Loading
src/CreateImage.cpp +21 −12 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ int run_tests( const std::string &filename, const Options &options ) // Call create_image for each method int N_errors = 0; std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) ); std::vector<std::vector<double>> time( methods.size() ); std::vector<Times> perf1( methods.size() ); std::vector<Times> perf2( methods.size() ); for ( size_t i = 0; i < methods.size(); i++ ) { if ( rank() == 0 ) std::cout << " Running " << methods[i] << std::endl; Loading @@ -117,16 +118,19 @@ int run_tests( const std::string &filename, const Options &options ) RayTrace::create_image( info2, methods[i] ); // Run the timing tests auto t0 = std::chrono::steady_clock::now(); std::vector<double> tmp1; std::vector<double> tmp2; while ( true ) { for ( int it = 0; it < iterations; it++ ) { auto t1 = std::chrono::steady_clock::now(); // Run the calculation RayTrace::create_image( info, methods[i] ); if ( options.benchmark ) { auto t2 = std::chrono::steady_clock::now(); // Mimic communication in full application communicate( *info ); } auto t2 = std::chrono::steady_clock::now(); time[i].push_back( 1e-9 * diff_ns( t2, t1 ) ); auto t3 = std::chrono::steady_clock::now(); tmp1.push_back( 1e-9 * diff_ns( t2, t1 ) ); tmp2.push_back( 1e-9 * diff_ns( t3, t1 ) ); t1 = t2; } double time = 1e-9 * diff_ns( std::chrono::steady_clock::now(), t0 ); Loading @@ -134,13 +138,18 @@ int run_tests( const std::string &filename, const Options &options ) if ( time > options.time ) break; } time[i] = gatherAll( time[i] ); perf1[i] = Times( tmp2 ); perf2[i] = Times( tmp2 ); // Check the results if ( options.scale == 1.0 ) { bool pass = check_ans( image0, I_ang0, *info ); if ( !pass ) N_errors++; } if ( perf1[i].avg[0] < 0.5 * perf1[i].avg[1] ) { std::cout << "Slow rank detected: " << rank() << std::endl; N_errors++; } free( (void *) info->image ); free( (void *) info->I_ang ); info->image = nullptr; Loading @@ -148,7 +157,7 @@ int run_tests( const std::string &filename, const Options &options ) } if ( rank() == 0 ) { if ( options.benchmark ) { double t = getAvg( time[0] ); double t = perf2[0].avg[1]; double N = 0; if ( info->seed_beam == nullptr ) { auto &beam = *( info->euv_beam ); Loading @@ -162,10 +171,10 @@ int run_tests( const std::string &filename, const Options &options ) } else { printf( "\n METHOD Avg Min Max Std Dev\n" ); for ( size_t i = 0; i < methods.size(); i++ ) { double min = getMin( time[i] ); double max = getMax( time[i] ); double avg = getAvg( time[i] ); double dev = getDev( time[i] ); double min = perf1[i].min[1]; double max = perf1[i].max[1]; double avg = perf1[i].avg[1]; double dev = perf1[i].std[1]; printf( "%14s %7.3f %7.3f %7.3f %7.3f\n", methods[i].c_str(), avg, min, max, dev ); if ( dev / avg > 0.25 ) { printf( " Standard deviation exceeded tolerance (25%%)\n" ); Loading
src/CreateImageHelpers.cpp +50 −27 Original line number Diff line number Diff line Loading @@ -205,37 +205,60 @@ void scale_problem( RayTrace::create_image_struct &info, double scale ) /********************************************************************** * Basic math operations * * Compute the statistics for the times * **********************************************************************/ double getMin( const std::vector<double> &x ) Times::Times() { double y = x[0]; for ( size_t i = 1; i < x.size(); i++ ) y = std::min( y, x[i] ); return y; } double getMax( const std::vector<double> &x ) { double y = x[0]; for ( size_t i = 1; i < x.size(); i++ ) y = std::max( y, x[i] ); return y; } double getAvg( const std::vector<double> &x ) N[0] = 0; N[1] = 0; min[0] = 0; min[1] = 0; max[0] = 0; max[1] = 0; avg[0] = 0; avg[1] = 0; std[0] = 0; std[1] = 0; } Times::Times( const std::vector<double> &x ) { double y = 0; for ( size_t i = 0; i < x.size(); i++ ) y += x[i]; return y / x.size(); } double getDev( const std::vector<double> &x ) { double avg = getAvg( x ); double y = 0; for ( size_t i = 0; i < x.size(); i++ ) y += ( x[i] - avg ) * ( x[i] - avg ); y = sqrt( y / x.size() ); return y; // Compute local properties N[0] = x.size(); min[0] = 1e100; max[0] = 0; avg[0] = 0; for ( size_t i = 0; i < x.size(); i++ ) { min[0] = std::min( min[0], x[i] ); max[0] = std::max( max[0], x[i] ); avg[0] += x[i]; } // Compute global properties N[1] = N[0]; min[1] = min[0]; max[1] = max[0]; avg[1] = avg[0]; #ifdef USE_MPI static_assert( sizeof( unsigned long long ) == sizeof( size_t ), "Unexpected size" ); MPI_Allreduce( &N[0], &N[1], 1, MPI_UNSIGNED_LONG_LONG, MPI_SUM, MPI_COMM_WORLD ); MPI_Allreduce( &min[0], &min[1], 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD ); MPI_Allreduce( &max[0], &max[1], 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD ); MPI_Allreduce( &avg[0], &avg[1], 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD ); #endif // Finish computing the average and the standard deviation avg[0] /= N[0]; avg[1] /= N[1]; std[0] = 0; std[1] = 0; for ( size_t i = 0; i < x.size(); i++ ) { std[0] += ( x[i] - avg[0] ) * ( x[i] - avg[0] ); std[1] += ( x[i] - avg[1] ) * ( x[i] - avg[1] ); } #ifdef USE_MPI double tmp = std[1]; MPI_Allreduce( &tmp, &std[1], 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD ); #endif std[0] = sqrt( std[0] / ( N[0] - 1 ) ); std[1] = sqrt( std[1] / ( N[1] - 1 ) ); } Loading
src/CreateImageHelpers.h +29 −33 Original line number Diff line number Diff line Loading @@ -10,6 +10,35 @@ #include "RayTrace/RayTrace.h" // Clas to hold options class Options { public: Options(); Options( int argc, char *argv[] ); public: bool benchmark = false; int iterations = 1; double scale = 1.0; double time = 0; std::vector<std::string> methods; std::vector<std::string> filenames; }; // Class to store statistical information about the times struct Times { size_t N[2]; double min[2]; double max[2]; double avg[2]; double std[2]; Times(); Times( const std::vector<double> × ); }; // Function to print info about the hardware that we will use void printHardware(); Loading @@ -31,37 +60,4 @@ bool check_ans( const double *image0, const double *I_ang0, const RayTrace::create_image_struct &data ); // Get the minimum value double getMin( const std::vector<double> &x ); // Get the maximum value double getMax( const std::vector<double> &x ); // Get the average value double getAvg( const std::vector<double> &x ); // Get the standard deviation double getDev( const std::vector<double> &x ); // Clas to hold options class Options { public: Options(); Options( int argc, char *argv[] ); public: bool benchmark = false; int iterations = 1; double scale = 1.0; double time = 0; std::vector<std::string> methods; std::vector<std::string> filenames; }; #endif
src/WriteCompilerFeatures.cmakedeleted 100644 → 0 +0 −107 Original line number Diff line number Diff line INCLUDE(CheckCXXCompilerFlag) INCLUDE(CheckCXXSourceCompiles) # CMake is adding extra options for extensions that we don't want SET( CMAKE_CXX11_COMPILE_FEATURES -DDUMMY ) SET( CMAKE_CXX11_EXTENSION_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX11_STANDARD_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX14_COMPILE_FEATURES -DDUMMY ) SET( CMAKE_CXX14_EXTENSION_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX14_STANDARD_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX98_COMPILE_FEATURES -DDUMMY ) SET( CMAKE_CXX98_EXTENSION_COMPILE_OPTION -DDUMMY ) SET( CMAKE_CXX98_STANDARD_COMPILE_OPTION -DDUMMY ) # This function writes a list of the supported C++ compiler features FUNCTION( WRITE_COMPILE_FEATURES FILENAME ${ARGN} ) SET( PREFIX ${ARGN} ) IF ( NOT PREFIX ) SET( PREFIX " " ) ELSE() SET( PREFIX "${PREFIX}_" ) ENDIF() FILE(WRITE ${FILENAME} "// This is a automatically generated file to set define variables for supported C++ features\n" ) TEST_FEATURE( SHARED_PTR ${FILENAME} ${PREFIX} "#include <memory> int main() { std::shared_ptr<int> ptr; return 0; }" ) TEST_FEATURE( STD_FUNCTION ${FILENAME} ${PREFIX} "#include <functional> void myfun(int) { } int main() { std::function<void(int)> f_display = myfun; return 0; }" ) TEST_FEATURE( STD_TUPLE ${FILENAME} ${PREFIX} "#include <tuple> int main() { std::tuple<double,int> x(1,2); return 0; }" ) TEST_FEATURE( VARIADIC_TEMPLATE ${FILENAME} ${PREFIX} "#include <iostream> template<class... Ts> void test(Ts... ts) {} int main() { test<int,double>(1,3); return 0; }" ) IF ( USE_MATLAB ) # Thread local storage and matlab do not agree FILE(APPEND ${FILENAME} "#define ${PREFIX}DISABLE_THREAD_LOCAL\n" ) ELSE() TEST_FEATURE( THREAD_LOCAL ${FILENAME} ${PREFIX} "#include <iostream> template<class... Ts> void test(Ts... ts) {} int main() { thread_local static int id = 0; return 0; }" ) ENDIF() TEST_FEATURE( MOVE_CONSTRUCTOR ${FILENAME} ${PREFIX} "#include <iostream> struct st { int i; st(){} st(st&&){} private: st(st&); }; st fun() { return st(); } int main() { st tmp = fun(); return 0; }" ) TEST_FEATURE( STATIC_ASSERT ${FILENAME} ${PREFIX} "#include <iostream> int main() { static_assert(true,\"test\"); return 0; }" ) ENDFUNCTION() # This function trys to compile and then sets the appropriate macro FUNCTION( TEST_FEATURE FEATURE_NAME FILENAME PREFIX CODE ) IF ( ${CXX_STD} STREQUAL "98" ) # Disable all features for 98 SET( ${FEATURE_NAME} OFF ) ELSEIF ( DISABLE_${FEATURE_NAME} ) # Disable feature SET( ${FEATURE_NAME} OFF ) ELSE() # Check if compiler allows feature SET( CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS} ) CHECK_CXX_SOURCE_COMPILES( "${CODE}" ${FEATURE_NAME} ) ENDIF() IF ( ${FEATURE_NAME} ) FILE(APPEND ${FILENAME} "#define ${PREFIX}ENABLE_${FEATURE_NAME}\n" ) ELSE() FILE(APPEND ${FILENAME} "#define ${PREFIX}DISABLE_${FEATURE_NAME}\n" ) ENDIF() ENDFUNCTION()