Commit 115564ca authored by Berrill, Mark's avatar Berrill, Mark
Browse files

Syncing with master RayTrace

parent c06a49dc
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -38,12 +38,6 @@ double bcast( double x, int root )
    MPI_Bcast( &y, 1, MPI_DOUBLE, root, MPI_COMM_WORLD );
    return y;
}
std::vector<double> gatherAll( const std::vector<double>& x )
{
    std::vector<double> y( x.size() * getSize(), 0 );
    MPI_Allgather( x.data(), x.size(), MPI_DOUBLE, y.data(), x.size(), MPI_DOUBLE, MPI_COMM_WORLD );
    return y;
}


#else
@@ -57,6 +51,5 @@ int getRank() { return 0; }
int getSize() { return 1; }
int sumReduce( const int val ) { return val; }
double bcast( double x, int ) { return x; }
std::vector<double> gatherAll( const std::vector<double>& x ) { return x; }

#endif
+0 −1
Original line number Diff line number Diff line
@@ -10,4 +10,3 @@ int getRank();
int getSize();
int sumReduce( const int val );
double bcast( double x, int root = 0 );
std::vector<double> gatherAll( const std::vector<double>& x );
+129 −4
Original line number Diff line number Diff line
@@ -25,8 +25,11 @@ std::ostream &perr = AtomicModel::perr;
std::ostream &plog = AtomicModel::plog;


namespace Utilities {


// Functions to get the path to a file
std::string Utilities::path( const std::string &filename )
std::string path( const std::string &filename )
{
    size_t index = 0;
    for ( size_t i = 0; i < filename.size(); i++ ) {
@@ -40,8 +43,7 @@ std::string Utilities::path( const std::string &filename )

// Functions to compress a bool array
template<>
size_t Utilities::compress_array<bool>(
    size_t N, const bool data[], int method, unsigned char *cdata[] )
size_t compress_array<bool>( size_t N, const bool data[], int method, unsigned char *cdata[] )
{
    size_t N_bytes = 0;
    if ( method == 0 ) {
@@ -63,7 +65,7 @@ size_t Utilities::compress_array<bool>(
    return N_bytes;
}
template<>
void Utilities::decompress_array<bool>(
void decompress_array<bool>(
    size_t N, size_t N_bytes, const unsigned char cdata[], int method, bool *data[] )
{
    *data = new bool[N];
@@ -79,3 +81,126 @@ void Utilities::decompress_array<bool>(
        }
    }
}


/****************************************************************************
 * Functions to compress/decompres an array without the zero-valued entries  *
 ****************************************************************************/
template<class TYPE>
size_t compress_array( size_t N, const TYPE data[], int method, unsigned char *cdata[] )
{
    size_t N_bytes = 0;
    if ( method == 0 ) {
        N_bytes = N * sizeof( TYPE );
        *cdata  = new unsigned char[N_bytes];
        memcpy( *cdata, data, N_bytes );
    } else if ( method == 1 ) {
        size_t N_zeros = 0;
        for ( size_t i = 0; i < N; i++ ) {
            if ( data[i] == 0 )
                N_zeros++;
        }
        // Determine the optimum storage type:
        if ( N_zeros == N ) {
            // Special case where everything is zero
            *cdata    = new unsigned char[1];
            *cdata[0] = 7;
            N_bytes   = 1;
        } else if ( ( N - N_zeros ) * sizeof( TYPE ) + ( N + 7 ) / 8 >= N * sizeof( TYPE ) ) {
            // We are better off storing the data as a dense array
            N_bytes = N * sizeof( TYPE );
            *cdata  = new unsigned char[N_bytes];
            memcpy( *cdata, data, N_bytes );
        } else {
            // Store the data as a bit array indicating if each value is non-zero, and then a dense
            // array of non-zeroed values
            N_bytes = ( N + 7 ) / 8 + ( N - N_zeros ) * sizeof( TYPE );
            *cdata  = new unsigned char[N_bytes];
            memset( *cdata, 0, N_bytes );
            // Create a byte array to store which values are zero
            for ( size_t i = 0; i < N; i++ ) {
                if ( data[i] == 0 )
                    continue;
                unsigned char mask = 1 << ( i % 8 );
                ( *cdata )[i / 8]  = ( *cdata )[i / 8] | mask;
            }
            // Store the non-zero values
            auto data2 = &( *cdata )[( N + 7 ) / 8];
            for ( size_t i = 0; i < N; i++ ) {
                if ( data[i] != 0 ) {
                    memcpy( data2, &data[i], sizeof( TYPE ) );
                    data2 += sizeof( TYPE );
                }
            }
        }
    } else if ( method == 2 ) {
        // Convert to single precision then compress array to remove zeros
        float *tmp = new float[N];
        for ( size_t i = 0; i < N; i++ )
            tmp[i] = static_cast<float>( data[i] );
        N_bytes = Utilities::compress_array<float>( N, tmp, 1, cdata );
        delete[] tmp;
    } else {
        RAY_ERROR( "Unknown compression method" );
    }
    return N_bytes;
}
template<class TYPE>
void decompress_array(
    size_t N, size_t N_bytes_in, const unsigned char cdata[], int method, TYPE *data[] )
{
    *data = new TYPE[N];
    memset( *data, 0, N * sizeof( TYPE ) );
    if ( method == 0 ) {
        size_t N_bytes = N * sizeof( TYPE );
        RAY_ASSERT( N_bytes == N_bytes_in );
        memcpy( *data, cdata, N_bytes );
    } else if ( method == 1 ) {
        for ( size_t i = 0; i < N; i++ )
            ( *data )[i] = 0;
        if ( N_bytes_in == 0 ) {
            // NULL array
            return;
        } else if ( N_bytes_in == 1 ) {
            // Empty array
            return;
        } else if ( N_bytes_in == N * sizeof( TYPE ) ) {
            // We are storing the dense array
            memcpy( *data, cdata, N * sizeof( TYPE ) );
        } else {
            // We are storing a bit array indicating the non-zeroed entries, and the non-zero values
            // as a dense array
            auto data2 = &cdata[( N + 7 ) / 8];
            memset( *data, 0, N * sizeof( TYPE ) );
            for ( unsigned long int i = 0; i < N; i++ ) {
                unsigned char mask = 1 << ( i % 8 );
                unsigned char test = mask & cdata[i / 8];
                if ( test != 0 ) {
                    memcpy( &( *data )[i], data2, sizeof( TYPE ) );
                    data2 += sizeof( TYPE );
                }
            }
        }
    } else if ( method == 2 ) {
        // Convert to single precision then compress array to remove zeros
        float *tmp = nullptr;
        Utilities::decompress_array<float>( N, N_bytes_in, cdata, 1, &tmp );
        for ( size_t i = 0; i < N; i++ )
            ( *data )[i] = tmp[i];
        delete[] tmp;
    } else {
        RAY_ERROR( "Unknown compression method" );
    }
}


/********************************************************
 *  Explicit instantiations of Array<std::string>        *
 ********************************************************/
template size_t compress_array<float>( size_t, const float[], int, unsigned char *[] );
template void decompress_array<float>( size_t, size_t, const unsigned char[], int, float *[] );
template size_t compress_array<double>( size_t, const double[], int, unsigned char *[] );
template void decompress_array<double>( size_t, size_t, const unsigned char[], int, double *[] );


} // namespace Utilities
+3 −114
Original line number Diff line number Diff line
@@ -10,6 +10,9 @@
#include <vector>


#include "RayTrace/utilities/RayUtilityMacros.h"


namespace Utilities {


@@ -91,118 +94,4 @@ inline std::string Utilities::stringf( const char *format, ... )
}


#include "RayTrace/utilities/RayUtilityMacros.h"


/****************************************************************************
 * Functions to compress/decompres an array without the zero-valued entries  *
 ****************************************************************************/
template<class TYPE>
size_t Utilities::compress_array( size_t N, const TYPE data[], int method, unsigned char *cdata[] )
{
    size_t N_bytes = 0;
    if ( method == 0 ) {
        N_bytes = N * sizeof( TYPE );
        *cdata  = new unsigned char[N_bytes];
        memcpy( *cdata, data, N_bytes );
    } else if ( method == 1 ) {
        size_t N_zeros = 0;
        for ( size_t i = 0; i < N; i++ ) {
            if ( data[i] == 0 )
                N_zeros++;
        }
        // Determine the optimum storage type:
        if ( N_zeros == N ) {
            // Special case where everything is zero
            *cdata    = new unsigned char[1];
            *cdata[0] = 7;
            N_bytes   = 1;
        } else if ( ( N - N_zeros ) * sizeof( TYPE ) + ( N + 7 ) / 8 >= N * sizeof( TYPE ) ) {
            // We are better off storing the data as a dense array
            N_bytes = N * sizeof( TYPE );
            *cdata  = new unsigned char[N_bytes];
            memcpy( *cdata, data, N_bytes );
        } else {
            // Store the data as a bit array indicating if each value is non-zero, and then a dense
            // array of non-zeroed values
            N_bytes = ( N + 7 ) / 8 + ( N - N_zeros ) * sizeof( TYPE );
            *cdata  = new unsigned char[N_bytes];
            memset( *cdata, 0, N_bytes );
            // Create a byte array to store which values are zero
            for ( size_t i = 0; i < N; i++ ) {
                if ( data[i] == 0 )
                    continue;
                unsigned char mask = 1 << ( i % 8 );
                ( *cdata )[i / 8]  = ( *cdata )[i / 8] | mask;
            }
            // Store the non-zero values
            auto data2 = &( *cdata )[( N + 7 ) / 8];
            for ( size_t i = 0; i < N; i++ ) {
                if ( data[i] != 0 ) {
                    memcpy( data2, &data[i], sizeof( TYPE ) );
                    data2 += sizeof( TYPE );
                }
            }
        }
    } else if ( method == 2 ) {
        // Convert to single precision then compress array to remove zeros
        float *tmp = new float[N];
        for ( size_t i = 0; i < N; i++ )
            tmp[i] = static_cast<float>( data[i] );
        N_bytes = Utilities::compress_array<float>( N, tmp, 1, cdata );
        delete[] tmp;
    } else {
        RAY_ERROR( "Unknown compression method" );
    }
    return N_bytes;
}
template<class TYPE>
void Utilities::decompress_array(
    size_t N, size_t N_bytes_in, const unsigned char cdata[], int method, TYPE *data[] )
{
    *data = new TYPE[N];
    memset( *data, 0, N * sizeof( TYPE ) );
    if ( method == 0 ) {
        size_t N_bytes = N * sizeof( TYPE );
        RAY_ASSERT( N_bytes == N_bytes_in );
        memcpy( *data, cdata, N_bytes );
    } else if ( method == 1 ) {
        for ( size_t i = 0; i < N; i++ )
            ( *data )[i] = 0;
        if ( N_bytes_in == 0 ) {
            // NULL array
            return;
        } else if ( N_bytes_in == 1 ) {
            // Empty array
            return;
        } else if ( N_bytes_in == N * sizeof( TYPE ) ) {
            // We are storing the dense array
            memcpy( *data, cdata, N * sizeof( TYPE ) );
        } else {
            // We are storing a bit array indicating the non-zeroed entries, and the non-zero values
            // as a dense array
            auto data2 = &cdata[( N + 7 ) / 8];
            memset( *data, 0, N * sizeof( TYPE ) );
            for ( unsigned long int i = 0; i < N; i++ ) {
                unsigned char mask = 1 << ( i % 8 );
                unsigned char test = mask & cdata[i / 8];
                if ( test != 0 ) {
                    memcpy( &( *data )[i], data2, sizeof( TYPE ) );
                    data2 += sizeof( TYPE );
                }
            }
        }
    } else if ( method == 2 ) {
        // Convert to single precision then compress array to remove zeros
        float *tmp = nullptr;
        Utilities::decompress_array<float>( N, N_bytes_in, cdata, 1, &tmp );
        for ( size_t i = 0; i < N; i++ )
            ( *data )[i] = tmp[i];
        delete[] tmp;
    } else {
        RAY_ERROR( "Unknown compression method" );
    }
}


#endif