Commit 1301293a authored by Berrill, Mark's avatar Berrill, Mark
Browse files

Removing unnecessary structures

parent 6909efa7
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

#include "CompilerFeatures.h"
#ifdef ENABLE_STD_FUNCTION
@@ -259,6 +260,15 @@ template <class type>
void quicksort( size_t n, type *X );


/*!
 * @brief    Subroutine to sort the elements in X
 * @details  This function sorts the values in X using quicksort
 * @param X         Input/Output: Points to sort
 */
template <class type>
inline void quicksort( std::vector<type>& X );


/*!
 * @brief    Subroutine to sort the elements in X
 * @details  This function sorts the values in X
@@ -270,6 +280,17 @@ template <class type1, class type2>
void quicksort( size_t n, type1 *X, type2 *Y );


/*!
 * @brief    Subroutine to sort the elements in X
 * @details  This function sorts the values in X
 * @param n         The number of values in X
 * @param X         Input/Output: Points to sort
 * @param Y         Input/Output: Extra values to be sorted with X
 */
template <class type1, class type2>
inline void quicksort( std::vector<type1>& X, std::vector<type2>& Y );


/*!
 * @brief    Subroutine to sort the elements in X
 * @details  This function sorts the values in X, storing them in Y
+16 −1
Original line number Diff line number Diff line
#ifndef included_interp_hpp
#define included_interp_hpp

#include "AtomicModel/interp.h"
#include <iostream>
#include <limits>
#include <stdexcept>
@@ -343,6 +342,22 @@ void interp::quicksort( size_t size, T1 *arr, T2 *brr )
}


template <class type>
inline void quicksort( std::vector<type>& X )
{
    quicksort(X.size(),X.data());
}


template <class type1, class type2>
inline void quicksort( std::vector<type1>& X, std::vector<type2>& Y )
{
    if ( X.size() != Y.size() )
        throw std::logic_error( "Error: X.size() != Y>size()" );
    quicksort(X.size(),X.data(),Y.data());
}


inline void interp::sort( size_t n, const double *X, double *Y )
{
    // Copy the values of X
+16 −1
Original line number Diff line number Diff line
@@ -36,6 +36,21 @@ INCLUDE( "${RAYTRACE_SOURCE_DIR}/macros.cmake" )
SET_COMPILER_FLAGS()


# Check if we are using an MPI compiler
SET( CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS} )
CHECK_CXX_SOURCE_COMPILES(
    "#include <mpi.h>
     int main(int, char**) {
        MPI_Init(NULL, NULL);
        MPI_Finalize();
     }"
    USE_MPI )
IF ( USE_MPI )
    ADD_DEFINITIONS( -DUSE_MPI )
    MESSAGE( "Using MPI" )
ENDIF()


# Enable OpenMP
IF ( USE_OPENMP )
    ADD_DEFINITIONS( -DUSE_OPENMP )
@@ -156,7 +171,7 @@ ADD_DISTCLEAN( libRayTrace.* null_timer CreateImage* )
# Create the library
INCLUDE_DIRECTORIES( ${RAYTRACE_SOURCE_DIR} )
ADD_DEFINITIONS( -DDISABLE_WRITE_FAILED_RAYS )
SET( SOURCES RayTrace RayTraceImage.cpp RayTraceStructures.cpp utilities/RayUtilities.cpp AtomicModel/interp.cpp RayTraceImageCPU.cpp )
SET( SOURCES RayTrace RayTraceImage.cpp RayTraceStructures.cpp utilities/RayUtilities.cpp AtomicModel/interp.cpp RayTraceImageCPU.cpp CreateImageHelpers.cpp )
IF ( USE_OPENACC )
    SET( SOURCES ${SOURCES} RayTraceImageOpenACC.cpp )
ENDIF()
+37 −187
Original line number Diff line number Diff line
@@ -2,6 +2,9 @@
// This miniapp mimics the behavior of create_image

#include "RayTrace.h"
#include "MPI_helpers.h"
#include "CreateImageHelpers.h"

#include <cstring>
#include <iostream>
#include <math.h>
@@ -10,191 +13,18 @@
#include <string>


#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 )
#include <windows.h>
#define get_time( x ) QueryPerformanceCounter( x )
#define get_frequency( f ) QueryPerformanceFrequency( f )
#define TIME_TYPE LARGE_INTEGER
#define sleep_ms Sleep
inline double get_diff( TIME_TYPE start, TIME_TYPE end, TIME_TYPE f )
{
    return ( ( (double) ( end.QuadPart - start.QuadPart ) ) / ( (double) f.QuadPart ) );
}
#else
#include <sys/time.h>
#define get_time( x ) gettimeofday( x, NULL );
#define get_frequency( f ) ( *f = timeval() )
#define TIME_TYPE timeval
#define sleep_ms( X )                        \
    do {                                     \
        struct timespec ts;                  \
        ts.tv_sec  = X / 1000;               \
        ts.tv_nsec = ( X % 1000 ) * 1000000; \
        nanosleep( &ts, NULL );              \
    } while ( 0 )
inline double get_diff( TIME_TYPE start, TIME_TYPE end, TIME_TYPE )
{
    return ( (double) end.tv_sec - start.tv_sec ) + 1e-6 * ( (double) end.tv_usec - start.tv_usec );
}
#endif

#ifdef USE_KOKKOS
#include <Kokkos_Core.hpp>
#endif


inline void fread2( void *ptr, size_t size, size_t count, FILE *fid )
{
    size_t N = fread( ptr, size, count, fid );
    if ( N != count ) {
        std::cerr << "Failed to read desired count\n";
        exit( -1 );
    }
}


// Check the answer
inline bool check_ans(
    const double *image0, const double *I_ang0, const RayTrace::create_image_struct &data )
{
    size_t N_image  = data.euv_beam->nx * data.euv_beam->ny * data.euv_beam->nv;
    size_t N_ang    = data.euv_beam->na * data.euv_beam->nb;
    double error[2] = { 0, 0 };
    double norm0[2] = { 0, 0 };
    double norm1[2] = { 0, 0 };
    for ( size_t i = 0; i < N_image; i++ ) {
        error[0] += ( image0[i] - data.image[i] ) * ( image0[i] - data.image[i] );
        norm0[0] += image0[i] * image0[i];
        norm1[0] += data.image[i] * data.image[i];
    }
    for ( size_t i = 0; i < N_ang; i++ ) {
        error[1] += ( I_ang0[i] - data.I_ang[i] ) * ( I_ang0[i] - data.I_ang[i] );
        norm0[1] += I_ang0[i] * I_ang0[i];
        norm1[1] += data.I_ang[i] * data.I_ang[i];
    }
    norm0[0] = sqrt( norm0[0] );
    norm0[1] = sqrt( norm0[1] );
    norm1[0] = sqrt( norm1[0] );
    norm1[1] = sqrt( norm1[1] );
    error[0] = sqrt( error[0] ) / norm0[0];
    error[1] = sqrt( error[1] ) / norm0[1];
    const double tol =
        5e-6; // RayTrace uses single precision for some calculations (may need to adjust to 1e-5)
    // bool pass = error[0]<=tol && error[1]<=tol;
    bool pass =
        ( norm0[0] - norm1[0] ) / norm0[0] <= tol && ( norm0[1] - norm1[1] ) / norm0[1] <= tol;
    if ( !pass ) {
        std::cerr << "  Answers do not match:" << std::endl;
        std::cerr << "    image: " << error[0] << " " << norm0[0] << " " << norm1[0] << std::endl;
        std::cerr << "    I_ang: " << error[1] << " " << norm0[1] << " " << norm1[1] << std::endl;
    }
    return pass;
}


// Scale the input problem
template <class TYPE>
void scale_beam( TYPE &beam, double scale )
{
    const double x[2] = { beam.x[0] - 0.5 * beam.dx, beam.x[beam.nx - 1] + 0.5 * beam.dx };
    const double y[2] = { beam.y[0] - 0.5 * beam.dy, beam.y[beam.ny - 1] + 0.5 * beam.dy };
    const double a[2] = { beam.a[0] - 0.5 * beam.da, beam.a[beam.na - 1] + 0.5 * beam.da };
    const double b[2] = { beam.b[0] - 0.5 * beam.db, beam.b[beam.nb - 1] + 0.5 * beam.db };
    int nx            = static_cast<int>( beam.nx * scale );
    int ny            = static_cast<int>( beam.ny * scale );
    int na            = static_cast<int>( beam.na * scale );
    int nb            = static_cast<int>( beam.nb * scale );
    delete[] beam.x;
    beam.x = new double[nx];
    delete[] beam.y;
    beam.y = new double[ny];
    delete[] beam.a;
    beam.a = new double[na];
    delete[] beam.b;
    beam.b  = new double[nb];
    beam.nx = nx;
    beam.dx = ( x[1] - x[0] ) / nx;
    beam.ny = ny;
    beam.dy = ( y[1] - y[0] ) / ny;
    beam.na = na;
    beam.da = ( a[1] - a[0] ) / na;
    beam.nb = nb;
    beam.db = ( b[1] - b[0] ) / nb;
    for ( int i = 0; i < nx; i++ ) {
        beam.x[i] = x[0] + ( 0.5 + i ) * beam.dx;
    }
    for ( int i = 0; i < ny; i++ ) {
        beam.y[i] = y[0] + ( 0.5 + i ) * beam.dy;
    }
    for ( int i = 0; i < na; i++ ) {
        beam.a[i] = a[0] + ( 0.5 + i ) * beam.da;
    }
    for ( int i = 0; i < nb; i++ ) {
        beam.b[i] = b[0] + ( 0.5 + i ) * beam.db;
    }
}
void scale_problem( RayTrace::create_image_struct &info, double scale )
{
    scale_beam( *const_cast<RayTrace::EUV_beam_struct *>( info.euv_beam ), pow( scale, 0.25 ) );
    if ( info.seed_beam != NULL )
        scale_beam(
            *const_cast<RayTrace::seed_beam_struct *>( info.seed_beam ), pow( scale, 0.25 ) );
}


// Clas to hold options
class Options {
public:
    Options() {};
    int iterations = 1;
    double scale   = 1.0;
    std::vector<std::string> methods;
    std::vector<std::string> read_cmd( int argc, char *argv[] )
    {
        const char *err_msg = "CreateImage called with the wrong number of arguments:\n"
            "  CreateImage <args> file.dat\n"
            "Optional arguments:\n"
            "  -methods=METHODS  Comma seperated list of methods to test.  Default is all availible methods\n"
            "                    cpu, threads, OpenMP, Cuda, OpenAcc, Kokkos-Serial, "
            "Kokkos-Thread, Kokkos-OpenMP, Kokkos-Cuda\n"
            "  -iterations=N     Number of iterations to run.  Time returned will be "
            "the average time/iteration.\n"
            "  -scale=factor     Increate the size of the problem by ~ this factor. "
            "(2.0 - twice as expensive)\n"
            "                    Note: this will disable checking the answer.\n"
            "                    Note: the scale factor is only approximate.\n";
        std::vector<std::string> filenames;
        for ( int i = 1; i < argc; i++ ) {
            if ( argv[i][0] == '-' ) {
                // Processing an argument
                if ( strncmp( argv[i], "-methods=", 9 ) == 0 ) {
                    std::stringstream ss( &argv[i][9] );
                    std::string token;
                    while ( std::getline( ss, token, ',' ) )
                        methods.push_back( token );
                } else if ( strncmp( argv[i], "-iterations=", 12 ) == 0 ) {
                    iterations = atoi( &argv[i][12] );
                } else if ( strncmp( argv[i], "-scale=", 7 ) == 0 ) {
                    scale = atof( &argv[i][7] );
                } else {
                    std::cerr << "Unknown option: " << argv[i] << std::endl;
                    return std::vector<std::string>();
                }
            } else {
                // Processing a filename
                filenames.push_back( argv[i] );
            }
        }
        if ( filenames.empty() )
            std::cerr << err_msg;
        return filenames;
    }
};


// Run the tests for a single file
int run_tests( const std::string& filename, const Options& options )
{
    if ( rank() == 0 )
        printf( "\nRunning tests for %s\n\n", filename.c_str() );
    // load the input file
    FILE *fid = fopen( filename.c_str(), "rb" );
@@ -259,16 +89,18 @@ int run_tests( const std::string& filename, const Options& options )
    // Call create_image for each method
    int N_errors = 0;
    sleep_ms( 50 );
    std::vector<double> time( methods.size() );
    std::vector<std::vector<double>> time( methods.size() );
    for ( size_t i = 0; i < methods.size(); i++ ) {
        if ( rank() == 0 )
            printf( "Running %s\n", methods[i].c_str() );
        TIME_TYPE start, stop, f;
        get_frequency( &f );
        get_time( &start );
        for ( int it = 0; it < options.iterations; it++ )
        double start = getTime();
        for ( int it = 0; it < options.iterations; it++ ) {
            RayTrace::create_image( &info, methods[i] );
        get_time( &stop );
        time[i] = get_diff( start, stop, f );
            double stop = getTime();
            time[i].push_back( stop - start );
            start = stop;
        }
        time[i] = gatherAll( time[i] );
        // Check the results
        if ( scale == 1.0 ) {
            bool pass = check_ans( image0, I_ang0, info );
@@ -280,9 +112,24 @@ int run_tests( const std::string& filename, const Options& options )
        info.image = NULL;
        info.I_ang = NULL;
    }
    printf( "\n      METHOD     TIME\n" );
    for ( size_t i = 0; i < methods.size(); i++ )
        printf( "%14s   %0.3f\n", methods[i].c_str(), time[i] );
    if ( rank() == 0 ) {
        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] );
            printf( "%14s %7.3f %7.3f %7.3f %7.3f\n", methods[i].c_str(), avg, min, max, dev );
            if ( dev/avg > 0.10 ) {
                printf( "   Standard deviation exceeded tolerance (10%%)\n");
                N_errors++;
            }
            if ( (max-avg)/avg > 0.15 ) {
                printf( "   Maximum runtime exceeded average by more than 15%%\n");
                N_errors++;
            }
        }
    }

    // Free memory and return
    free( (void *) image0 );
@@ -291,7 +138,7 @@ int run_tests( const std::string& filename, const Options& options )
    delete info.seed_beam;
    delete[] info.gain;
    delete info.seed;
    return N_errors;
    return sumReduce(N_errors);
}


@@ -300,6 +147,8 @@ int run_tests( const std::string& filename, const Options& options )
******************************************************************/
int main( int argc, char *argv[] )
{
    // Start MPI (if used)
    startup( argc, argv );

// Initialize kokkos
#ifdef USE_KOKKOS
@@ -335,5 +184,6 @@ int main( int argc, char *argv[] )
#ifdef USE_KOKKOS
    Kokkos::finalize();
#endif
    shutdown();
    return N_errors;
}

src/CreateImage.h

0 → 100644
+0 −0

Empty file added.

Loading