[test-suite] r289666 - Add XSBench

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 3 06:15:28 PST 2017


On 12/18/2016 02:02 AM, Sean Silva wrote:
> Do you have contact with the folks that develop these proxy apps?

Yes. The XSBench author helped me construct the "runs for a few seconds" 
input configuration.

>
> It seems like RSBench includes its own RNG. It seems like it would be 
> beneficial overall to the benchmarks for them to not rely on details 
> of the system rand(). Maybe it's as easy as copypasting it into the 
> other proxy apps?
> https://github.com/ANL-CESAR/RSBench/blob/master/src/utils.c

So, as it turns out, I screwed this up. XSBench also contains its own 
RNG that is used in verification mode. As a result, the glibc rand 
emulation code is not necessary. The problem on ARM (and also on any 
other 32-bit architecture) was that this rn_v routine used 'unsigned 
long' instead of uint64_t, and so produced different numbers on 64-bit 
and 32-bit architectures (thus causing the output to fail to match the 
reference output). This is easy to fix and I'll remove the unnecessary 
glibc-rand-emulation code I added before recommiting.

Thanks again,
Hal

>
>
> -- Sean Silva
>
> On Wed, Dec 14, 2016 at 8:42 AM, Hal Finkel via llvm-commits 
> <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>> wrote:
>
>     Author: hfinkel
>     Date: Wed Dec 14 10:42:31 2016
>     New Revision: 289666
>
>     URL: http://llvm.org/viewvc/llvm-project?rev=289666&view=rev
>     <http://llvm.org/viewvc/llvm-project?rev=289666&view=rev>
>     Log:
>     Add XSBench
>
>     The US Department of Energy (DOE) has open-sourced a significant
>     number of
>     so-called proxy applications (i.e. small applications,
>     representative of our
>     larger workloads in some respects, intended for use as benchmarks
>     and test beds
>     for various kind of porting exercises). Many of these are useful
>     as compiler
>     tests, and I'd like to add these to our test suite. Doing so will
>     increase the
>     representation within our test suite of HPC/scientific
>     applications and allow
>     us to better track how Clang/LLVM is doing in this area. Scientific
>     applications are certainly a diverse group in themselves, and so
>     my long term
>     goal is to add a significant number of these proxies to ensure
>     good coverage.
>
>     Some months ago, I compiled a list of our open-source proxy
>     applications
>     released by the various DOE laboratories
>     (https://gitlab.com/llvm-doe/public/wikis/DOEProxyApps
>     <https://gitlab.com/llvm-doe/public/wikis/DOEProxyApps>). By my
>     estimate, of the
>     approximately 40 proxy applications on that list, around half could be
>     reasonably added to our test suite. We're continuing to develop
>     new proxies,
>     and so the number of suitable applications should grow somewhat in
>     the future.
>
>     In any case, here's the first one: XSBench. This is a C
>     application with a
>     straightforward reference output. It is designed to represent a key
>     computational kernel of the Monte-Carlo neutronics application
>     OpenMC. The
>     builtin "small" test configuration is mostly suitable for our test
>     suite - the
>     parameters have been adjusted slightly so that the test uses only
>     ~27MB of
>     memory and runs in a few seconds. The only complication in adding this
>     application is its dependence on rand(). The developer's provided
>     known-good
>     output will work only for glibc's implementation of rand (other rand
>     implementation obviously may produce a different series of random
>     numbers given
>     the same initial seed). Luckily, the algorithm that glibc uses for
>     rand() is
>     reasonably well described by various web pages, and so I
>     constructed a small
>     independent implementation. This is in the glibc_compat_rand.{c,h}
>     files.
>
>     As a reflection of my desire to add more of these applications,
>     I've place this
>     in a subdirectory named DOE-ProxyApps-C (the idea being that the
>     C++ proxy
>     applications will get a DOE-ProxyApps-C++ directory or similar).
>
>     Differential Revision: https://reviews.llvm.org/D27311
>     <https://reviews.llvm.org/D27311>
>
>     Added:
>         test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/CMakeLists.txt
>         test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/Makefile
>         test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CMakeLists.txt
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CalculateXS.c
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/GridInit.c
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/LICENSE
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Main.c
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Makefile
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Materials.c
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSBench.reference_output
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSbench_header.h
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSutils.c
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.c
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.h
>        
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/io.c
>     Modified:
>         test-suite/trunk/MultiSource/Benchmarks/CMakeLists.txt
>         test-suite/trunk/MultiSource/Benchmarks/Makefile
>
>     Modified: test-suite/trunk/MultiSource/Benchmarks/CMakeLists.txt
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/CMakeLists.txt?rev=289666&r1=289665&r2=289666&view=diff
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/CMakeLists.txt?rev=289666&r1=289665&r2=289666&view=diff>
>     ==============================================================================
>     --- test-suite/trunk/MultiSource/Benchmarks/CMakeLists.txt (original)
>     +++ test-suite/trunk/MultiSource/Benchmarks/CMakeLists.txt Wed Dec
>     14 10:42:31 2016
>     @@ -18,6 +18,7 @@ add_subdirectory(llubenchmark)
>      add_subdirectory(mediabench)
>      add_subdirectory(nbench)
>      add_subdirectory(sim)
>     +add_subdirectory(DOE-ProxyApps-C)
>
>      if((NOT "${TARGET_OS}" STREQUAL "Darwin") OR (NOT "${ARCH}"
>     STREQUAL "ARM"))
>        add_subdirectory(TSVC)
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/CMakeLists.txt
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/CMakeLists.txt?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/CMakeLists.txt?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/CMakeLists.txt
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/CMakeLists.txt
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,2 @@
>     +add_subdirectory(XSBench)
>     +
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/Makefile
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/Makefile?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/Makefile?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/Makefile
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/Makefile
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,7 @@
>     +# MultiSource/DOE-ProxyApps-C Makefile:  Build all subdirectories
>     automatically
>     +
>     +LEVEL = ../../..
>     +PARALLEL_DIRS = XSBench
>     +
>     +
>     +include $(LEVEL)/Makefile.programs
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CMakeLists.txt
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CMakeLists.txt?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CMakeLists.txt?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CMakeLists.txt
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CMakeLists.txt
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,5 @@
>     +set(PROG XSBench)
>     +set(CPPFLAGS -DVERIFICATION)
>     +set(LDFLAGS -lm)
>     +set(RUN_OPTIONS -s small -g 1250 -l 1000000)
>     +llvm_multisource()
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CalculateXS.c
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CalculateXS.c?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CalculateXS.c?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CalculateXS.c
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/CalculateXS.c
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,124 @@
>     +#include "XSbench_header.h"
>     +
>     +// Calculates the microscopic cross section for a given nuclide &
>     energy
>     +void calculate_micro_xs(   double p_energy, int nuc, long n_isotopes,
>     +                           long n_gridpoints,
>     +                           GridPoint * restrict energy_grid,
>     +                           NuclideGridPoint ** restrict
>     nuclide_grids,
>     +                           int idx, double * restrict xs_vector ){
>     +
>     +       // Variables
>     +       double f;
>     +       NuclideGridPoint * low, * high;
>     +
>     +       // pull ptr from energy grid and check to ensure that
>     +       // we're not reading off the end of the nuclide's grid
>     +       if( energy_grid[idx].xs_ptrs[nuc] == n_gridpoints - 1 )
>     +               low =
>     &nuclide_grids[nuc][energy_grid[idx].xs_ptrs[nuc] - 1];
>     +       else
>     +               low =
>     &nuclide_grids[nuc][energy_grid[idx].xs_ptrs[nuc]];
>     +
>     +       high = low + 1;
>     +
>     +       // calculate the re-useable interpolation factor
>     +       f = (high->energy - p_energy) / (high->energy - low->energy);
>     +
>     +       // Total XS
>     +       xs_vector[0] = high->total_xs - f * (high->total_xs -
>     low->total_xs);
>     +
>     +       // Elastic XS
>     +       xs_vector[1] = high->elastic_xs - f * (high->elastic_xs -
>     low->elastic_xs);
>     +
>     +       // Absorbtion XS
>     +       xs_vector[2] = high->absorbtion_xs - f *
>     (high->absorbtion_xs - low->absorbtion_xs);
>     +
>     +       // Fission XS
>     +       xs_vector[3] = high->fission_xs - f * (high->fission_xs -
>     low->fission_xs);
>     +
>     +       // Nu Fission XS
>     +       xs_vector[4] = high->nu_fission_xs - f *
>     (high->nu_fission_xs - low->nu_fission_xs);
>     +
>     +       //test
>     +       /*
>     +       if( omp_get_thread_num() == 0 )
>     +       {
>     +               printf("Lookup: Energy = %lf, nuc = %d\n",
>     p_energy, nuc);
>     +               printf("e_h = %lf e_l = %lf\n", high->energy ,
>     low->energy);
>     +               printf("xs_h = %lf xs_l = %lf\n",
>     high->elastic_xs, low->elastic_xs);
>     +               printf("total_xs = %lf\n\n", xs_vector[1]);
>     +       }
>     +       */
>     +
>     +}
>     +
>     +// Calculates macroscopic cross section based on a given material
>     & energy
>     +void calculate_macro_xs( double p_energy, int mat, long n_isotopes,
>     +                         long n_gridpoints, int * restrict num_nucs,
>     +                         double ** restrict concs,
>     +                         GridPoint * restrict energy_grid,
>     +                         NuclideGridPoint ** restrict nuclide_grids,
>     +                         int ** restrict mats,
>     +                         double * restrict macro_xs_vector ){
>     +       double xs_vector[5];
>     +       int p_nuc; // the nuclide we are looking up
>     +       long idx = 0;
>     +       double conc; // the concentration of the nuclide in the
>     material
>     +
>     +       // cleans out macro_xs_vector
>     +       for( int k = 0; k < 5; k++ )
>     +               macro_xs_vector[k] = 0;
>     +
>     +       // binary search for energy on unionized energy grid (UEG)
>     +       idx = grid_search( n_isotopes * n_gridpoints, p_energy,
>     +                          energy_grid);
>     +
>     +       // Once we find the pointer array on the UEG, we can pull
>     the data
>     +       // from the respective nuclide grids, as well as the nuclide
>     +       // concentration data for the material
>     +       // Each nuclide from the material needs to have its
>     micro-XS array
>     +       // looked up & interpolatied (via calculate_micro_xs).
>     Then, the
>     +       // micro XS is multiplied by the concentration of that nuclide
>     +       // in the material, and added to the total macro XS array.
>     +       for( int j = 0; j < num_nucs[mat]; j++ )
>     +       {
>     +               p_nuc = mats[mat][j];
>     +               conc = concs[mat][j];
>     +               calculate_micro_xs( p_energy, p_nuc, n_isotopes,
>     +                                   n_gridpoints, energy_grid,
>     +                                   nuclide_grids, idx, xs_vector );
>     +               for( int k = 0; k < 5; k++ )
>     +                       macro_xs_vector[k] += xs_vector[k] * conc;
>     +       }
>     +
>     +       //test
>     +       /*
>     +       for( int k = 0; k < 5; k++ )
>     +               printf("Energy: %lf, Material: %d, XSVector[%d]:
>     %lf\n",
>     +                      p_energy, mat, k, macro_xs_vector[k]);
>     +       */
>     +}
>     +
>     +
>     +// (fixed) binary search for energy on unionized energy grid
>     +// returns lower index
>     +long grid_search( long n, double quarry, GridPoint * A)
>     +{
>     +       long lowerLimit = 0;
>     +       long upperLimit = n-1;
>     +       long examinationPoint;
>     +       long length = upperLimit - lowerLimit;
>     +
>     +       while( length > 1 )
>     +       {
>     +               examinationPoint = lowerLimit + ( length / 2 );
>     +
>     +               if( A[examinationPoint].energy > quarry )
>     +                       upperLimit = examinationPoint;
>     +               else
>     +                       lowerLimit = examinationPoint;
>     +
>     +               length = upperLimit - lowerLimit;
>     +       }
>     +
>     +       return lowerLimit;
>     +}
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/GridInit.c
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/GridInit.c?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/GridInit.c?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/GridInit.c
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/GridInit.c
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,171 @@
>     +#include "XSbench_header.h"
>     +
>     +#ifdef MPI
>     +#include<mpi.h>
>     +#endif
>     +
>     +// Generates randomized energy grid for each nuclide
>     +// Note that this is done as part of initialization (serial), so
>     +// rand() is used.
>     +void generate_grids( NuclideGridPoint ** nuclide_grids,
>     +                     long n_isotopes, long n_gridpoints ) {
>     +       for( long i = 0; i < n_isotopes; i++ )
>     +               for( long j = 0; j < n_gridpoints; j++ )
>     +               {
>     +                       nuclide_grids[i][j].energy
>      =((double)rand()/(double)RAND_MAX);
>     +                       nuclide_grids[i][j].total_xs
>      =((double)rand()/(double)RAND_MAX);
>     +                       nuclide_grids[i][j].elastic_xs
>      =((double)rand()/(double)RAND_MAX);
>     +                     
>      nuclide_grids[i][j].absorbtion_xs=((double)rand()/(double)RAND_MAX);
>     +                       nuclide_grids[i][j].fission_xs
>      =((double)rand()/(double)RAND_MAX);
>     +                     
>      nuclide_grids[i][j].nu_fission_xs=((double)rand()/(double)RAND_MAX);
>     +               }
>     +}
>     +
>     +// Verification version of this function (tighter control over RNG)
>     +void generate_grids_v( NuclideGridPoint ** nuclide_grids,
>     +                     long n_isotopes, long n_gridpoints ) {
>     +       for( long i = 0; i < n_isotopes; i++ )
>     +               for( long j = 0; j < n_gridpoints; j++ )
>     +               {
>     +                       nuclide_grids[i][j].energy       = rn_v();
>     +                       nuclide_grids[i][j].total_xs     = rn_v();
>     +                       nuclide_grids[i][j].elastic_xs   = rn_v();
>     +                       nuclide_grids[i][j].absorbtion_xs= rn_v();
>     +                       nuclide_grids[i][j].fission_xs   = rn_v();
>     +                       nuclide_grids[i][j].nu_fission_xs= rn_v();
>     +               }
>     +}
>     +
>     +// Sorts the nuclide grids by energy (lowest -> highest)
>     +void sort_nuclide_grids( NuclideGridPoint ** nuclide_grids, long
>     n_isotopes,
>     +                         long n_gridpoints )
>     +{
>     +       int (*cmp) (const void *, const void *);
>     +       cmp = NGP_compare;
>     +
>     +       for( long i = 0; i < n_isotopes; i++ )
>     +               qsort( nuclide_grids[i], n_gridpoints,
>     sizeof(NuclideGridPoint),
>     +                      cmp );
>     +
>     +       // error debug check
>     +       /*
>     +       for( int i = 0; i < n_isotopes; i++ )
>     +       {
>     +               printf("NUCLIDE %d
>     ==============================\n", i);
>     +               for( int j = 0; j < n_gridpoints; j++ )
>     +                       printf("E%d = %lf\n", j,
>     nuclide_grids[i][j].energy);
>     +       }
>     +       */
>     +}
>     +
>     +// Allocates unionized energy grid, and assigns union of energy
>     levels
>     +// from nuclide grids to it.
>     +GridPoint * generate_energy_grid( long n_isotopes, long n_gridpoints,
>     +                                  NuclideGridPoint **
>     nuclide_grids) {
>     +       int mype = 0;
>     +
>     +       #ifdef MPI
>     +       MPI_Comm_rank(MPI_COMM_WORLD, &mype);
>     +       #endif
>     +
>     +       if( mype == 0 ) printf("Generating Unionized Energy
>     Grid...\n");
>     +
>     +       long n_unionized_grid_points = n_isotopes*n_gridpoints;
>     +       int (*cmp) (const void *, const void *);
>     +       cmp = NGP_compare;
>     +
>     +       GridPoint * energy_grid = (GridPoint *)malloc(
>     n_unionized_grid_points
>     +                                                      * sizeof(
>     GridPoint ) );
>     +       if( mype == 0 ) printf("Copying and Sorting all nuclide
>     grids...\n");
>     +
>     +       NuclideGridPoint ** n_grid_sorted = gpmatrix( n_isotopes,
>     n_gridpoints );
>     +
>     +
>     +       memcpy( n_grid_sorted[0], nuclide_grids[0],
>     n_isotopes*n_gridpoints*
>     +                                             sizeof(
>     NuclideGridPoint ) );
>     +
>     +       qsort( &n_grid_sorted[0][0], n_unionized_grid_points,
>     +              sizeof(NuclideGridPoint), cmp);
>     +
>     +       if( mype == 0 ) printf("Assigning energies to unionized
>     grid...\n");
>     +
>     +       for( long i = 0; i < n_unionized_grid_points; i++ )
>     +               energy_grid[i].energy = n_grid_sorted[0][i].energy;
>     +
>     +
>     +       gpmatrix_free(n_grid_sorted);
>     +
>     +       int * full = (int *) malloc( n_isotopes *
>     n_unionized_grid_points
>     +                                    * sizeof(int) );
>     +       if( full == NULL )
>     +       {
>     +               fprintf(stderr,"ERROR - Out Of Memory!\n");
>     +               exit(1);
>     +       }
>     +
>     +       for( long i = 0; i < n_unionized_grid_points; i++ )
>     +               energy_grid[i].xs_ptrs = &full[n_isotopes * i];
>     +
>     +       // debug error checking
>     +       /*
>     +       for( int i = 0; i < n_unionized_grid_points; i++ )
>     +               printf("E%d = %lf\n", i, energy_grid[i].energy);
>     +       */
>     +
>     +       return energy_grid;
>     +}
>     +
>     +// Searches each nuclide grid for the closest energy level and
>     assigns
>     +// pointer from unionized grid to the correct spot in the nuclide
>     grid.
>     +// This process is time consuming, as the number of binary searches
>     +// required is:  binary searches = n_gridpoints * n_isotopes^2
>     +void set_grid_ptrs( GridPoint * energy_grid, NuclideGridPoint **
>     nuclide_grids,
>     +                    long n_isotopes, long n_gridpoints )
>     +{
>     +       int mype = 0;
>     +
>     +       #ifdef MPI
>     +       MPI_Comm_rank(MPI_COMM_WORLD, &mype);
>     +       #endif
>     +
>     +       if( mype == 0 ) printf("Assigning pointers to Unionized
>     Energy Grid...\n");
>     +       #ifdef OPENMP
>     +       #pragma omp parallel for default(none) \
>     +       shared( energy_grid, nuclide_grids, n_isotopes,
>     n_gridpoints, mype )
>     +       #endif
>     +       for( long i = 0; i < n_isotopes * n_gridpoints ; i++ )
>     +       {
>     +               int nthreads = 1, tid = 0;
>     +               double quarry = energy_grid[i].energy;
>     +
>     +               #ifdef OPENMP
>     +               nthreads = omp_get_num_threads();
>     +               tid = omp_get_thread_num();
>     +               #endif
>     +
>     +               if( INFO && mype == 0 && tid == 0 && i % 200 == 0 )
>     +                       printf("\rAligning Unionized
>     Grid...(%.0lf%% complete)",
>     +                              100.0 * (double) i /
>     (n_isotopes*n_gridpoints /
>     + nthreads)     );
>     +               for( long j = 0; j < n_isotopes; j++ )
>     +               {
>     +                       // j is the nuclide i.d.
>     +                       // log n binary search
>     +                       energy_grid[i].xs_ptrs[j] =
>     +                               binary_search( nuclide_grids[j],
>     quarry, n_gridpoints);
>     +               }
>     +       }
>     +       if( mype == 0 ) printf("\n");
>     +
>     +       //test
>     +       /*
>     +       for( int i=0; i < n_isotopes * n_gridpoints; i++ )
>     +               for( int j = 0; j < n_isotopes; j++ )
>     +                       printf("E = %.4lf\tNuclide %d->%p->%.4lf\n",
>     +                              energy_grid[i].energy,
>     +                   j,
>     + energy_grid[i].xs_ptrs[j],
>     + (energy_grid[i].xs_ptrs[j])->energy
>     +                                  );
>     +       */
>     +}
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/LICENSE
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/LICENSE?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/LICENSE?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/LICENSE
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/LICENSE
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,18 @@
>     +Copyright (c) 2012-2013 Argonne National Laboratory
>     +
>     +Permission is hereby granted, free of charge, to any person
>     obtaining a copy of
>     +this software and associated documentation files (the
>     "Software"), to deal in
>     +the Software without restriction, including without limitation
>     the rights to
>     +use, copy, modify, merge, publish, distribute, sublicense, and/or
>     sell copies of
>     +the Software, and to permit persons to whom the Software is
>     furnished to do so,
>     +subject to the following conditions:
>     +
>     +The above copyright notice and this permission notice shall be
>     included in all
>     +copies or substantial portions of the Software.
>     +
>     +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>     EXPRESS OR
>     +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>     MERCHANTABILITY, FITNESS
>     +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
>     THE AUTHORS OR
>     +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>     LIABILITY, WHETHER
>     +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
>     OR IN
>     +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
>     SOFTWARE.
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Main.c
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Main.c?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Main.c?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Main.c
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Main.c
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,285 @@
>     +#include "XSbench_header.h"
>     +
>     +#ifdef MPI
>     +#include<mpi.h>
>     +#endif
>     +
>     +int main( int argc, char* argv[] )
>     +{
>     +       //
>     =====================================================================
>     +       // Initialization & Command Line Read-In
>     +       //
>     =====================================================================
>     +       int version = 13;
>     +       int mype = 0;
>     +       #ifdef OPENMP
>     +       int max_procs = omp_get_num_procs();
>     +       #else
>     +       int max_procs = 1;
>     +       #endif
>     +       int i, thread = 0, mat;
>     +       unsigned long seed;
>     +       double omp_start = 0.0, omp_end = 0.0, p_energy;
>     +       unsigned long long vhash = 0;
>     +       int nprocs;
>     +
>     +       #ifdef MPI
>     +       MPI_Status stat;
>     +       MPI_Init(&argc, &argv);
>     +       MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
>     +       MPI_Comm_rank(MPI_COMM_WORLD, &mype);
>     +       #endif
>     +
>     +       // rand() is only used in the serial initialization stages.
>     +       // A custom RNG is used in parallel portions.
>     +       #ifdef VERIFICATION
>     +       srand(26);
>     +       #else
>     +       srand(time(NULL));
>     +       #endif
>     +
>     +       // Process CLI Fields -- store in "Inputs" structure
>     +       Inputs in = read_CLI( argc, argv );
>     +
>     +       #ifdef OPENMP
>     +       // Set number of OpenMP Threads
>     +       omp_set_num_threads(in.nthreads);
>     +       #endif
>     +
>     +       // Print-out of Input Summary
>     +       if( mype == 0 )
>     +               print_inputs( in, nprocs, version );
>     +
>     +       //
>     =====================================================================
>     +       // Prepare Nuclide Energy Grids, Unionized Energy Grid, &
>     Material Data
>     +       //
>     =====================================================================
>     +
>     +       // Allocate & fill energy grids
>     +       #ifndef BINARY_READ
>     +       if( mype == 0) printf("Generating Nuclide Energy Grids...\n");
>     +       #endif
>     +
>     +       NuclideGridPoint ** nuclide_grids =
>     gpmatrix(in.n_isotopes,in.n_gridpoints);
>     +
>     +       #ifdef VERIFICATION
>     +       generate_grids_v( nuclide_grids, in.n_isotopes,
>     in.n_gridpoints );
>     +       #else
>     +       generate_grids( nuclide_grids, in.n_isotopes,
>     in.n_gridpoints );
>     +       #endif
>     +
>     +       // Sort grids by energy
>     +       #ifndef BINARY_READ
>     +       if( mype == 0) printf("Sorting Nuclide Energy Grids...\n");
>     +       sort_nuclide_grids( nuclide_grids, in.n_isotopes,
>     in.n_gridpoints );
>     +       #endif
>     +
>     +       // Prepare Unionized Energy Grid Framework
>     +       #ifndef BINARY_READ
>     +       GridPoint * energy_grid = generate_energy_grid( in.n_isotopes,
>     +                                 in.n_gridpoints, nuclide_grids );
>     +       #else
>     +       GridPoint * energy_grid = (GridPoint *)malloc( in.n_isotopes *
>     +                                  in.n_gridpoints * sizeof(
>     GridPoint ) );
>     +       int * index_data = (int *) malloc( in.n_isotopes *
>     in.n_gridpoints
>     +                          * in.n_isotopes * sizeof(int));
>     +       for( i = 0; i < in.n_isotopes*in.n_gridpoints; i++ )
>     +               energy_grid[i].xs_ptrs = &index_data[i*in.n_isotopes];
>     +       #endif
>     +
>     +       // Double Indexing. Filling in energy_grid with pointers
>     to the
>     +       // nuclide_energy_grids.
>     +       #ifndef BINARY_READ
>     +       set_grid_ptrs( energy_grid, nuclide_grids, in.n_isotopes,
>     in.n_gridpoints );
>     +       #endif
>     +
>     +       #ifdef BINARY_READ
>     +       if( mype == 0 ) printf("Reading data from \"XS_data.dat\"
>     file...\n");
>     +       binary_read(in.n_isotopes, in.n_gridpoints, nuclide_grids,
>     energy_grid);
>     +       #endif
>     +
>     +       // Get material data
>     +       if( mype == 0 )
>     +               printf("Loading Mats...\n");
>     +       int *num_nucs  = load_num_nucs(in.n_isotopes);
>     +       int **mats     = load_mats(num_nucs, in.n_isotopes);
>     +
>     +       #ifdef VERIFICATION
>     +       double **concs = load_concs_v(num_nucs);
>     +       #else
>     +       double **concs = load_concs(num_nucs);
>     +       #endif
>     +
>     +       #ifdef BINARY_DUMP
>     +       if( mype == 0 ) printf("Dumping data to binary file...\n");
>     +       binary_dump(in.n_isotopes, in.n_gridpoints, nuclide_grids,
>     energy_grid);
>     +       if( mype == 0 ) printf("Binary file \"XS_data.dat\"
>     written! Exiting...\n");
>     +       return 0;
>     +       #endif
>     +
>     +       //
>     =====================================================================
>     +       // Cross Section (XS) Parallel Lookup Simulation Begins
>     +       //
>     =====================================================================
>     +
>     +       // Outer benchmark loop can loop through all possible # of
>     threads
>     +       #if defined(BENCHMARK) && defined(OPENMP)
>     +       for( int bench_n = 1; bench_n <=omp_get_num_procs();
>     bench_n++ )
>     +       {
>     +               in.nthreads = bench_n;
>     +               omp_set_num_threads(in.nthreads);
>     +       #endif
>     +
>     +       if( mype == 0 )
>     +       {
>     +               printf("\n");
>     +               border_print();
>     +               center_print("SIMULATION", 79);
>     +               border_print();
>     +       }
>     +
>     +       #if defined(TIMING) && defined(OPENMP)
>     +       omp_start = omp_get_wtime();
>     +       #endif
>     +
>     +       //initialize papi with one thread (master) here
>     +       #ifdef PAPI
>     +       if ( PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT){
>     +               fprintf(stderr, "PAPI library init error!\n");
>     +               exit(1);
>     +       }
>     +       #endif
>     +
>     +       // OpenMP compiler directives - declaring variables as
>     shared or private
>     +       #ifdef OPENMP
>     +       #pragma omp parallel default(none) \
>     +       private(i, thread, p_energy, mat, seed) \
>     +       shared( max_procs, in, energy_grid, nuclide_grids, \
>     +               mats, concs, num_nucs, mype, vhash)
>     +       #endif
>     +       {
>     +               // Initialize parallel PAPI counters
>     +               #ifdef PAPI
>     +               int eventset = PAPI_NULL;
>     +               int num_papi_events;
>     +               #ifdef OPENMP
>     +               #pragma omp critical
>     +               #endif
>     +               {
>     +                       counter_init(&eventset, &num_papi_events);
>     +               }
>     +               #endif
>     +
>     +               double macro_xs_vector[5];
>     +               double * xs = (double *) calloc(5, sizeof(double));
>     +
>     +               // Initialize RNG seeds for threads
>     +               #ifdef OPENMP
>     +               thread = omp_get_thread_num();
>     +               #endif
>     +               seed   = (thread+1)*19+17;
>     +
>     +               // XS Lookup Loop
>     +               #ifdef OPENMP
>     +               #pragma omp for schedule(dynamic)
>     +               #endif
>     +               for( i = 0; i < in.lookups; i++ )
>     +               {
>     +                       // Status text
>     +                       if( INFO && mype == 0 && thread == 0 && i
>     % 1000 == 0 )
>     +                               printf("\rCalculating XS's...
>     (%.0lf%% completed)",
>     +                                               (i / (
>     (double)in.lookups / (double) in.nthreads ))
>     +                                               / (double)
>     in.nthreads * 100.0);
>     +
>     +                       // Randomly pick an energy and material
>     for the particle
>     +                       #ifdef VERIFICATION
>     +                       #ifdef OPENMP
>     +                       #pragma omp critical
>     +                       #endif
>     +                       {
>     +                               p_energy = rn_v();
>     +                               mat      = pick_mat(&seed);
>     +                       }
>     +                       #else
>     +                       p_energy = rn(&seed);
>     +                       mat      = pick_mat(&seed);
>     +                       #endif
>     +
>     +                       // debugging
>     +                       //printf("E = %lf mat = %d\n", p_energy, mat);
>     +
>     +                       // This returns the macro_xs_vector, but
>     we're not going
>     +                       // to do anything with it in this program,
>     so return value
>     +                       // is written over.
>     +                       calculate_macro_xs( p_energy, mat,
>     in.n_isotopes,
>     +                                           in.n_gridpoints,
>     num_nucs, concs,
>     +                                           energy_grid,
>     nuclide_grids, mats,
>     +                                macro_xs_vector );
>     +
>     +                       // Copy results from above function call
>     onto heap
>     +                       // so that compiler cannot optimize
>     function out
>     +                       // (only occurs if -flto flag is used)
>     +                       memcpy(xs, macro_xs_vector, 5*sizeof(double));
>     +
>     +                       // Verification hash calculation
>     +                       // This method provides a consistent hash
>     accross
>     +                       // architectures and compilers.
>     +                       #ifdef VERIFICATION
>     +                       char line[256];
>     +                       sprintf(line, "%.5lf %d %.5lf %.5lf %.5lf
>     %.5lf %.5lf",
>     +                              p_energy, mat,
>     +                                  macro_xs_vector[0],
>     +                                  macro_xs_vector[1],
>     +                                  macro_xs_vector[2],
>     +                                  macro_xs_vector[3],
>     +                                  macro_xs_vector[4]);
>     +                       unsigned long long vhash_local =
>     hash(line, 10000);
>     +                       #ifdef OPENMP
>     +                       #pragma omp atomic
>     +                       #endif
>     +                       vhash += vhash_local;
>     +                       #endif
>     +               }
>     +
>     +               // Prints out thread local PAPI counters
>     +               #ifdef PAPI
>     +               if( mype == 0 && thread == 0 )
>     +               {
>     +                       printf("\n");
>     +                       border_print();
>     +                       center_print("PAPI COUNTER RESULTS", 79);
>     +                       border_print();
>     +                       printf("Count          \tSmybol
>     \tDescription\n");
>     +               }
>     +               {
>     +               #ifdef OPENMP
>     +               #pragma omp barrier
>     +               #endif
>     +               }
>     +               counter_stop(&eventset, num_papi_events);
>     +               #endif
>     +
>     +       }
>     +
>     +       #ifndef PAPI
>     +       if( mype == 0)
>     +       {
>     +               printf("\n" );
>     +               printf("Simulation complete.\n" );
>     +       }
>     +       #endif
>     +
>     +       #if defined(TIMING) && defined(OPENMP)
>     +       omp_end = omp_get_wtime();
>     +       #endif
>     +
>     +       // Print / Save Results and Exit
>     +       print_results( in, mype, omp_end-omp_start, nprocs, vhash );
>     +
>     +       #ifdef BENCHMARK
>     +       }
>     +       #endif
>     +
>     +       #ifdef MPI
>     +       MPI_Finalize();
>     +       #endif
>     +
>     +       return 0;
>     +}
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Makefile
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Makefile?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Makefile?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Makefile
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Makefile
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,8 @@
>     +LEVEL = ../../../..
>     +
>     +PROG     = XSBench
>     +CPPFLAGS = -DVERIFICATION
>     +LDFLAGS  = -lm
>     +RUN_OPTIONS = -s small -g 1250 -l 1000000
>     +include $(LEVEL)/MultiSource/Makefile.multisrc
>     +
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Materials.c
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Materials.c?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Materials.c?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Materials.c
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/Materials.c
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,188 @@
>     +// Material data is hard coded into the functions in this file.
>     +// Note that there are 12 materials present in H-M (large or small)
>     +
>     +#include "XSbench_header.h"
>     +
>     +// num_nucs represents the number of nuclides that each material
>     contains
>     +int * load_num_nucs(long n_isotopes)
>     +{
>     +       int * num_nucs = (int*)malloc(12*sizeof(int));
>     +
>     +       // Material 0 is a special case (fuel). The H-M small
>     reactor uses
>     +       // 34 nuclides, while H-M larges uses 300.
>     +       if( n_isotopes == 68 )
>     +               num_nucs[0]  = 34; // HM Small is 34, H-M Large is 321
>     +       else
>     +               num_nucs[0]  = 321; // HM Small is 34, H-M Large
>     is 321
>     +
>     +       num_nucs[1]  = 5;
>     +       num_nucs[2]  = 4;
>     +       num_nucs[3]  = 4;
>     +       num_nucs[4]  = 27;
>     +       num_nucs[5]  = 21;
>     +       num_nucs[6]  = 21;
>     +       num_nucs[7]  = 21;
>     +       num_nucs[8]  = 21;
>     +       num_nucs[9]  = 21;
>     +       num_nucs[10] = 9;
>     +       num_nucs[11] = 9;
>     +
>     +       return num_nucs;
>     +}
>     +
>     +// Assigns an array of nuclide ID's to each material
>     +int ** load_mats( int * num_nucs, long n_isotopes )
>     +{
>     +       int ** mats = (int **) malloc( 12 * sizeof(int *) );
>     +       for( int i = 0; i < 12; i++ )
>     +               mats[i] = (int *) malloc(num_nucs[i] * sizeof(int) );
>     +
>     +       // Small H-M has 34 fuel nuclides
>     +       int mats0_Sml[] =  { 58, 59, 60, 61, 40, 42, 43, 44, 45,
>     46, 1, 2, 3, 7,
>     +                        8, 9, 10, 29, 57, 47, 48, 0, 62, 15, 33,
>     34, 52, 53,
>     +                        54, 55, 56, 18, 23, 41 }; //fuel
>     +       // Large H-M has 300 fuel nuclides
>     +       int mats0_Lrg[321] =  { 58, 59, 60, 61, 40, 42, 43, 44,
>     45, 46, 1, 2, 3, 7,
>     +                        8, 9, 10, 29, 57, 47, 48, 0, 62, 15, 33,
>     34, 52, 53,
>     +                        54, 55, 56, 18, 23, 41 }; //fuel
>     +       for( int i = 0; i < 321-34; i++ )
>     +               mats0_Lrg[34+i] = 68 + i; // H-M large adds
>     nuclides to fuel only
>     +
>     +       // These are the non-fuel materials
>     +       int mats1[] =  { 63, 64, 65, 66, 67 }; // cladding
>     +       int mats2[] =  { 24, 41, 4, 5 }; // cold borated water
>     +       int mats3[] =  { 24, 41, 4, 5 }; // hot borated water
>     +       int mats4[] =  { 19, 20, 21, 22, 35, 36, 37, 38, 39, 25,
>     27, 28, 29,
>     +                        30, 31, 32, 26, 49, 50, 51, 11, 12, 13,
>     14, 6, 16,
>     +                        17 }; // RPV
>     +       int mats5[] =  { 24, 41, 4, 5, 19, 20, 21, 22, 35, 36, 37,
>     38, 39, 25,
>     +                        49, 50, 51, 11, 12, 13, 14 }; // lower
>     radial reflector
>     +       int mats6[] =  { 24, 41, 4, 5, 19, 20, 21, 22, 35, 36, 37,
>     38, 39, 25,
>     +                        49, 50, 51, 11, 12, 13, 14 }; // top
>     reflector / plate
>     +       int mats7[] =  { 24, 41, 4, 5, 19, 20, 21, 22, 35, 36, 37,
>     38, 39, 25,
>     +                        49, 50, 51, 11, 12, 13, 14 }; // bottom plate
>     +       int mats8[] =  { 24, 41, 4, 5, 19, 20, 21, 22, 35, 36, 37,
>     38, 39, 25,
>     +                        49, 50, 51, 11, 12, 13, 14 }; // bottom
>     nozzle
>     +       int mats9[] =  { 24, 41, 4, 5, 19, 20, 21, 22, 35, 36, 37,
>     38, 39, 25,
>     +                        49, 50, 51, 11, 12, 13, 14 }; // top nozzle
>     +       int mats10[] = { 24, 41, 4, 5, 63, 64, 65, 66, 67 }; //
>     top of FA's
>     +       int mats11[] = { 24, 41, 4, 5, 63, 64, 65, 66, 67 }; //
>     bottom FA's
>     +
>     +       // H-M large v small dependency
>     +       if( n_isotopes == 68 )
>     +               memcpy( mats[0],  mats0_Sml,  num_nucs[0]  *
>     sizeof(int) );
>     +       else
>     +               memcpy( mats[0],  mats0_Lrg,  num_nucs[0]  *
>     sizeof(int) );
>     +
>     +       // Copy other materials
>     +       memcpy( mats[1],  mats1,  num_nucs[1]  * sizeof(int) );
>     +       memcpy( mats[2],  mats2,  num_nucs[2]  * sizeof(int) );
>     +       memcpy( mats[3],  mats3,  num_nucs[3]  * sizeof(int) );
>     +       memcpy( mats[4],  mats4,  num_nucs[4]  * sizeof(int) );
>     +       memcpy( mats[5],  mats5,  num_nucs[5]  * sizeof(int) );
>     +       memcpy( mats[6],  mats6,  num_nucs[6]  * sizeof(int) );
>     +       memcpy( mats[7],  mats7,  num_nucs[7]  * sizeof(int) );
>     +       memcpy( mats[8],  mats8,  num_nucs[8]  * sizeof(int) );
>     +       memcpy( mats[9],  mats9,  num_nucs[9]  * sizeof(int) );
>     +       memcpy( mats[10], mats10, num_nucs[10] * sizeof(int) );
>     +       memcpy( mats[11], mats11, num_nucs[11] * sizeof(int) );
>     +
>     +       // test
>     +       /*
>     +       for( int i = 0; i < 12; i++ )
>     +               for( int j = 0; j < num_nucs[i]; j++ )
>     +                       printf("material %d - Nuclide %d: %d\n",
>     +                              i, j, mats[i][j]);
>     +       */
>     +
>     +       return mats;
>     +}
>     +
>     +// Creates a randomized array of 'concentrations' of nuclides in
>     each mat
>     +double ** load_concs( int * num_nucs )
>     +{
>     +       double ** concs = (double **)malloc( 12 * sizeof( double *) );
>     +
>     +       for( int i = 0; i < 12; i++ )
>     +               concs[i] = (double *)malloc( num_nucs[i] *
>     sizeof(double) );
>     +
>     +       for( int i = 0; i < 12; i++ )
>     +               for( int j = 0; j < num_nucs[i]; j++ )
>     +                       concs[i][j] = (double) rand() / (double)
>     RAND_MAX;
>     +
>     +       // test
>     +       /*
>     +       for( int i = 0; i < 12; i++ )
>     +               for( int j = 0; j < num_nucs[i]; j++ )
>     +                       printf("concs[%d][%d] = %lf\n", i, j,
>     concs[i][j] );
>     +       */
>     +
>     +       return concs;
>     +}
>     +
>     +// Verification version of this function (tighter control over RNG)
>     +double ** load_concs_v( int * num_nucs )
>     +{
>     +       double ** concs = (double **)malloc( 12 * sizeof( double *) );
>     +
>     +       for( int i = 0; i < 12; i++ )
>     +               concs[i] = (double *)malloc( num_nucs[i] *
>     sizeof(double) );
>     +
>     +       for( int i = 0; i < 12; i++ )
>     +               for( int j = 0; j < num_nucs[i]; j++ )
>     +                       concs[i][j] = rn_v();
>     +
>     +       // test
>     +       /*
>     +       for( int i = 0; i < 12; i++ )
>     +               for( int j = 0; j < num_nucs[i]; j++ )
>     +                       printf("concs[%d][%d] = %lf\n", i, j,
>     concs[i][j] );
>     +       */
>     +
>     +       return concs;
>     +}
>     +
>     +// picks a material based on a probabilistic distribution
>     +int pick_mat( unsigned long * seed )
>     +{
>     +       // I have a nice spreadsheet supporting these numbers.
>     They are
>     +       // the fractions (by volume) of material in the core. Not a
>     +       // *perfect* approximation of where XS lookups are going
>     to occur,
>     +       // but this will do a good job of biasing the system
>     nonetheless.
>     +
>     +       // Also could be argued that doing fractions by weight
>     would be
>     +       // a better approximation, but volume does a good enough
>     job for now.
>     +
>     +       double dist[12];
>     +       dist[0]  = 0.140;       // fuel
>     +       dist[1]  = 0.052;       // cladding
>     +       dist[2]  = 0.275;       // cold, borated water
>     +       dist[3]  = 0.134;       // hot, borated water
>     +       dist[4]  = 0.154;       // RPV
>     +       dist[5]  = 0.064;       // Lower, radial reflector
>     +       dist[6]  = 0.066;       // Upper reflector / top plate
>     +       dist[7]  = 0.055;       // bottom plate
>     +       dist[8]  = 0.008;       // bottom nozzle
>     +       dist[9]  = 0.015;       // top nozzle
>     +       dist[10] = 0.025;       // top of fuel assemblies
>     +       dist[11] = 0.013;       // bottom of fuel assemblies
>     +
>     +       //double roll = (double) rand() / (double) RAND_MAX;
>     +       #ifdef VERIFICATION
>     +       double roll = rn_v();
>     +       #else
>     +       double roll = rn(seed);
>     +       #endif
>     +
>     +       // makes a pick based on the distro
>     +       for( int i = 0; i < 12; i++ )
>     +       {
>     +               double running = 0;
>     +               for( int j = i; j > 0; j-- )
>     +                       running += dist[j];
>     +               if( roll < running )
>     +                       return i;
>     +       }
>     +
>     +       return 0;
>     +}
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSBench.reference_output
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSBench.reference_output?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSBench.reference_output?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSBench.reference_output
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSBench.reference_output
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,47 @@
>     +================================================================================
>     +                   __   __ ___________                 _
>     +                   \ \ / //  ___| ___ \               | |
>     +                    \ V / \ `--.| |_/ / ___ _ __   ___| |__
>     +                    /   \  `--. \ ___ \/ _ \ '_ \ / __| '_ \
>     +                   / /^\ \/\__/ / |_/ /  __/ | | | (__| | | |
>     +                   \/   \/\____/\____/ \___|_| |_|\___|_| |_|
>     +
>     +================================================================================
>     +                    Developed at Argonne National Laboratory
>     +                                   Version: 13
>     +================================================================================
>     +                                  INPUT SUMMARY
>     +================================================================================
>     +Verification Mode:            on
>     +Materials:                    12
>     +H-M Benchmark Size:           small
>     +Total Nuclides:               68
>     +Gridpoints (per Nuclide):     1,250
>     +Unionized Energy Gridpoints:  85,000
>     +XS Lookups:                   1,000,000
>     +Threads:                      1
>     +Est. Memory Usage (MB):       27
>     +================================================================================
>     +                                 INITIALIZATION
>     +================================================================================
>     +Generating Nuclide Energy Grids...
>     +Sorting Nuclide Energy Grids...
>     +Generating Unionized Energy Grid...
>     +Copying and Sorting all nuclide grids...
>     +Assigning energies to unionized grid...
>     +Assigning pointers to Unionized Energy Grid...
>     +
>     +Loading Mats...
>     +
>     +================================================================================
>     +                                   SIMULATION
>     +================================================================================
>     +
>     +Simulation complete.
>     +================================================================================
>     +                                     RESULTS
>     +================================================================================
>     +Threads:     1
>     +Verification checksum: 5000647235
>     +================================================================================
>     +exit 0
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSbench_header.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSbench_header.h?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSbench_header.h?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSbench_header.h
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSbench_header.h
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,124 @@
>     +#ifndef __XSBENCH_HEADER_H__
>     +#define __XSBENCH_HEADER_H__
>     +
>     +#include<stdio.h>
>     +#include<stdlib.h>
>     +#include<time.h>
>     +#include<string.h>
>     +#include<strings.h>
>     +#include<math.h>
>     +#ifdef OPENMP
>     +#include<omp.h>
>     +#endif
>     +#include<unistd.h>
>     +#include<sys/time.h>
>     +
>     +// The verification depends on the rand algorithm.
>     +#include "glibc_compat_rand.h"
>     +#ifndef NO_GLIBC_COMPAT_RAND
>     +#define rand glibc_compat_rand
>     +#define srand glibc_compat_srand
>     +#endif
>     +
>     +// Papi Header
>     +#ifdef PAPI
>     +#include "papi.h"
>     +#endif
>     +
>     +// I/O Specifiers
>     +#define INFO 0
>     +#define DEBUG 0
>     +#define SAVE 0
>     +
>     +// Structures
>     +typedef struct{
>     +       double energy;
>     +       double total_xs;
>     +       double elastic_xs;
>     +       double absorbtion_xs;
>     +       double fission_xs;
>     +       double nu_fission_xs;
>     +} NuclideGridPoint;
>     +
>     +typedef struct{
>     +       double energy;
>     +       int * xs_ptrs;
>     +} GridPoint;
>     +
>     +typedef struct{
>     +       int nthreads;
>     +       long n_isotopes;
>     +       long n_gridpoints;
>     +       int lookups;
>     +       char * HM;
>     +} Inputs;
>     +
>     +// Function Prototypes
>     +void logo(int version);
>     +void center_print(const char *s, int width);
>     +void border_print(void);
>     +void fancy_int(long a);
>     +
>     +NuclideGridPoint ** gpmatrix(size_t m, size_t n);
>     +
>     +void gpmatrix_free( NuclideGridPoint ** M );
>     +
>     +int NGP_compare( const void * a, const void * b );
>     +
>     +void generate_grids( NuclideGridPoint ** nuclide_grids,
>     +                     long n_isotopes, long n_gridpoints );
>     +void generate_grids_v( NuclideGridPoint ** nuclide_grids,
>     +                     long n_isotopes, long n_gridpoints );
>     +
>     +void sort_nuclide_grids( NuclideGridPoint ** nuclide_grids, long
>     n_isotopes,
>     +                         long n_gridpoints );
>     +
>     +GridPoint * generate_energy_grid( long n_isotopes, long n_gridpoints,
>     +                                  NuclideGridPoint ** nuclide_grids);
>     +
>     +void set_grid_ptrs( GridPoint * energy_grid, NuclideGridPoint **
>     nuclide_grids,
>     +                    long n_isotopes, long n_gridpoints );
>     +
>     +int binary_search( NuclideGridPoint * A, double quarry, int n );
>     +
>     +void calculate_macro_xs(   double p_energy, int mat, long n_isotopes,
>     +                           long n_gridpoints, int * restrict
>     num_nucs,
>     +                           double ** restrict concs,
>     +                                                  GridPoint *
>     restrict energy_grid,
>     +                           NuclideGridPoint ** restrict
>     nuclide_grids,
>     +                                                  int ** restrict
>     mats,
>     +                           double * restrict macro_xs_vector );
>     +
>     +void calculate_micro_xs(   double p_energy, int nuc, long n_isotopes,
>     +                           long n_gridpoints,
>     +                           GridPoint * restrict energy_grid,
>     +                           NuclideGridPoint ** restrict
>     nuclide_grids, int idx,
>     +                           double * restrict xs_vector );
>     +
>     +long grid_search( long n, double quarry, GridPoint * A);
>     +
>     +int * load_num_nucs(long n_isotopes);
>     +int ** load_mats( int * num_nucs, long n_isotopes );
>     +double ** load_concs( int * num_nucs );
>     +double ** load_concs_v( int * num_nucs );
>     +int pick_mat(unsigned long * seed);
>     +double rn(unsigned long * seed);
>     +int rn_int(unsigned long * seed);
>     +void counter_stop( int * eventset, int num_papi_events );
>     +void counter_init( int * eventset, int * num_papi_events );
>     +void do_flops(void);
>     +void do_loads( int nuc,
>     +               NuclideGridPoint ** restrict nuclide_grids,
>     +                      long n_gridpoints );
>     +Inputs read_CLI( int argc, char * argv[] );
>     +void print_CLI_error(void);
>     +double rn_v(void);
>     +double round_double( double input );
>     +unsigned int hash(unsigned char *str, int nbins);
>     +size_t estimate_mem_usage( Inputs in );
>     +void print_inputs(Inputs in, int nprocs, int version);
>     +void print_results( Inputs in, int mype, double runtime, int
>     nprocs, unsigned long long vhash );
>     +void binary_dump(long n_isotopes, long n_gridpoints,
>     NuclideGridPoint ** nuclide_grids, GridPoint * energy_grid);
>     +void binary_read(long n_isotopes, long n_gridpoints,
>     NuclideGridPoint ** nuclide_grids, GridPoint * energy_grid);
>     +
>     +#endif
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSutils.c
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSutils.c?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSutils.c?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSutils.c
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/XSutils.c
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,169 @@
>     +#include "XSbench_header.h"
>     +
>     +// Allocates nuclide matrix
>     +NuclideGridPoint ** gpmatrix(size_t m, size_t n)
>     +{
>     +       int i,j;
>     +       NuclideGridPoint * full = (NuclideGridPoint *) malloc( m * n *
>     +                                 sizeof( NuclideGridPoint ) );
>     +       NuclideGridPoint ** M = (NuclideGridPoint **) malloc( m *
>     +                                 sizeof(NuclideGridPoint *) );
>     +
>     +       for( i = 0, j=0; i < m*n; i++ )
>     +               if( i % n == 0 )
>     +                       M[j++] = &full[i];
>     +
>     +       return M;
>     +}
>     +
>     +// Frees nuclide matrix
>     +void gpmatrix_free( NuclideGridPoint ** M )
>     +{
>     +       free( *M );
>     +       free( M );
>     +}
>     +
>     +// Compare function for two grid points. Used for sorting during init
>     +int NGP_compare( const void * a, const void * b )
>     +{
>     +       NuclideGridPoint *i, *j;
>     +
>     +       i = (NuclideGridPoint *) a;
>     +       j = (NuclideGridPoint *) b;
>     +
>     +       if( i->energy > j->energy )
>     +               return 1;
>     +       else if ( i->energy < j->energy)
>     +               return -1;
>     +       else
>     +               return 0;
>     +}
>     +
>     +
>     +
>     +// Binary Search function for nuclide grid
>     +// Returns ptr to energy less than the quarry that is closest to
>     the quarry
>     +int binary_search( NuclideGridPoint * A, double quarry, int n )
>     +{
>     +       int min = 0;
>     +       int max = n-1;
>     +       int mid;
>     +
>     +       // checks to ensure we're not reading off the end of the grid
>     +       if( A[0].energy > quarry )
>     +               return 0;
>     +       else if( A[n-1].energy < quarry )
>     +               return n-2;
>     +
>     +       // Begins binary search
>     +       while( max >= min )
>     +       {
>     +               mid = min + floor( (max-min) / 2.0);
>     +               if( A[mid].energy < quarry )
>     +                       min = mid+1;
>     +               else if( A[mid].energy > quarry )
>     +                       max = mid-1;
>     +               else
>     +                       return mid;
>     +       }
>     +       return max;
>     +}
>     +
>     +// Park & Miller Multiplicative Conguential Algorithm
>     +// From "Numerical Recipes" Second Edition
>     +double rn(unsigned long * seed)
>     +{
>     +       double ret;
>     +       unsigned long n1;
>     +       unsigned long a = 16807;
>     +       unsigned long m = 2147483647;
>     +       n1 = ( a * (*seed) ) % m;
>     +       *seed = n1;
>     +       ret = (double) n1 / m;
>     +       return ret;
>     +}
>     +
>     +
>     +
>     +// RNG Used for Verification Option.
>     +// This one has a static seed (must be set manually in source).
>     +// Park & Miller Multiplicative Conguential Algorithm
>     +// From "Numerical Recipes" Second Edition
>     +double rn_v(void)
>     +{
>     +       static unsigned long seed = 1337;
>     +       double ret;
>     +       unsigned long n1;
>     +       unsigned long a = 16807;
>     +       unsigned long m = 2147483647;
>     +       n1 = ( a * (seed) ) % m;
>     +       seed = n1;
>     +       ret = (double) n1 / m;
>     +       return ret;
>     +}
>     +
>     +unsigned int hash(unsigned char *str, int nbins)
>     +{
>     +       unsigned int hash = 5381;
>     +       int c;
>     +
>     +       while (c = *str++)
>     +               hash = ((hash << 5) + hash) + c;
>     +
>     +       return hash % nbins;
>     +}
>     +
>     +size_t estimate_mem_usage( Inputs in )
>     +{
>     +       size_t single_nuclide_grid = in.n_gridpoints * sizeof(
>     NuclideGridPoint );
>     +       size_t all_nuclide_grids   = in.n_isotopes *
>     single_nuclide_grid;
>     +       size_t size_GridPoint      = sizeof(GridPoint) +
>     in.n_isotopes*sizeof(int);
>     +       size_t size_UEG            = in.n_isotopes*in.n_gridpoints
>     * size_GridPoint;
>     +       size_t memtotal;
>     +
>     +       memtotal          = all_nuclide_grids + size_UEG;
>     +       all_nuclide_grids = all_nuclide_grids / 1048576;
>     +       size_UEG          = size_UEG / 1048576;
>     +       memtotal          = memtotal / 1048576;
>     +       return memtotal;
>     +}
>     +
>     +void binary_dump(long n_isotopes, long n_gridpoints,
>     NuclideGridPoint ** nuclide_grids, GridPoint * energy_grid)
>     +{
>     +       FILE * fp = fopen("XS_data.dat", "wb");
>     +       // Dump Nuclide Grid Data
>     +       for( long i = 0; i < n_isotopes; i++ )
>     +               fwrite(nuclide_grids[i], sizeof(NuclideGridPoint),
>     n_gridpoints, fp);
>     +       // Dump UEG Data
>     +       for( long i = 0; i < n_isotopes * n_gridpoints; i++ )
>     +       {
>     +               // Write energy level
>     +               fwrite(&energy_grid[i].energy, sizeof(double), 1, fp);
>     +
>     +               // Write index data array (xs_ptrs array)
>     +               fwrite(energy_grid[i].xs_ptrs, sizeof(int),
>     n_isotopes, fp);
>     +       }
>     +
>     +       fclose(fp);
>     +}
>     +
>     +void binary_read(long n_isotopes, long n_gridpoints,
>     NuclideGridPoint ** nuclide_grids, GridPoint * energy_grid)
>     +{
>     +       int stat;
>     +       FILE * fp = fopen("XS_data.dat", "rb");
>     +       // Read Nuclide Grid Data
>     +       for( long i = 0; i < n_isotopes; i++ )
>     +               stat = fread(nuclide_grids[i],
>     sizeof(NuclideGridPoint), n_gridpoints, fp);
>     +       // Dump UEG Data
>     +       for( long i = 0; i < n_isotopes * n_gridpoints; i++ )
>     +       {
>     +               // Write energy level
>     +               stat = fread(&energy_grid[i].energy,
>     sizeof(double), 1, fp);
>     +
>     +               // Write index data array (xs_ptrs array)
>     +               stat = fread(energy_grid[i].xs_ptrs, sizeof(int),
>     n_isotopes, fp);
>     +       }
>     +
>     +       fclose(fp);
>     +
>     +}
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.c
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.c?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.c?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.c
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.c
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,57 @@
>     +/*===------------- glibc_compat_rand.h- glibc rand emulation
>     --------------===*\
>     +|*
>     +|*                     The LLVM Compiler Infrastructure
>     +|*
>     +|* This file is distributed under the University of Illinois Open
>     Source
>     +|* License. See LICENSE.TXT for details.
>     +|*
>     +\*===----------------------------------------------------------------------===*/
>     +
>     +#include "glibc_compat_rand.h"
>     +
>     +/**
>     + * This rand implementation is designed to emulate the
>     implementation of
>     + * rand/srand in recent versions of glibc. This is used for
>     programs which
>     + * require this specific rand implementation in order to pass
>     verification
>     + * tests.
>     + */
>     +
>     +#define TABLE_SIZE 34
>     +#define NUM_DISCARDED 344
>     +static unsigned int table[TABLE_SIZE];
>     +static int next;
>     +
>     +int glibc_compat_rand(void) {
>     +  /* Calculate the indices i-3 and i-31 in the circular vector. */
>     +  int i3 = (next < 3) ? (TABLE_SIZE + next - 3) : (next - 3);
>     +  int i31 = (next < 31) ? (TABLE_SIZE + next - 31) : (next - 31);
>     +
>     +  table[next] = table[i3] + table[i31];
>     +  unsigned int r = table[next] >> 1;
>     +
>     +  ++next;
>     +  if (next > TABLE_SIZE)
>     +    next = 0;
>     +
>     +  return r;
>     +}
>     +
>     +void glibc_compat_srand(unsigned int seed) {
>     +  table[0] = seed;
>     +  for (int i = 1; i < TABLE_SIZE - 3; ++i) {
>     +    int r = 16807ll * ((long long) table[i - 1]) % 2147483647;
>     +    if (r < 0)
>     +      r += 2147483647;
>     +
>     +    table[i] = r;
>     +  }
>     +
>     +  for (int i = TABLE_SIZE - 3; i < TABLE_SIZE; ++i)
>     +    table[i] = table[i - 31];
>     +
>     +  next = 0;
>     +
>     +  for (int i = 0; i < NUM_DISCARDED; ++i)
>     +    (void)glibc_compat_rand();
>     +}
>     +
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.h?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.h?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.h
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/glibc_compat_rand.h
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,17 @@
>     +/*===------------- glibc_compat_rand.h- glibc rand emulation
>     --------------===*\
>     +|*
>     +|*                     The LLVM Compiler Infrastructure
>     +|*
>     +|* This file is distributed under the University of Illinois Open
>     Source
>     +|* License. See LICENSE.TXT for details.
>     +|*
>     +\*===----------------------------------------------------------------------===*/
>     +
>     +#ifndef GLIBC_COMPAT_RAND_H
>     +#define GLIBC_COMPAT_RAND_H
>     +
>     +int glibc_compat_rand(void);
>     +void glibc_compat_srand(unsigned int seed);
>     +
>     +#endif /* GLIBC_COMPAT_RAND_H */
>     +
>
>     Added:
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/io.c
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/io.c?rev=289666&view=auto
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/io.c?rev=289666&view=auto>
>     ==============================================================================
>     ---
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/io.c
>     (added)
>     +++
>     test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench/io.c
>     Wed Dec 14 10:42:31 2016
>     @@ -0,0 +1,278 @@
>     +#include "XSbench_header.h"
>     +
>     +#ifdef MPI
>     +#include<mpi.h>
>     +#endif
>     +
>     +// Prints program logo
>     +void logo(int version)
>     +{
>     +       border_print();
>     +       printf(
>     +       "                   __   __ ___________    _             
>               \n"
>     +       "                   \\ \\ / //  ___| ___ \\      | |     
>                      \n"
>     +       "                    \\ V / \\ `--.| |_/ / ___ _ __  ___|
>     |__                     \n"
>     +       "                    /   \\  `--. \\ ___ \\/ _ \\ '_ \\ /
>     __| '_ \\                    \n"
>     +       "                   / /^\\ \\/\\__/ / |_/ /  __/ | | |
>     (__| | | |                   \n"
>     +       "                   \\/   \\/\\____/\\____/ \\___|_|
>     |_|\\___|_| |_|                   \n\n"
>     +    );
>     +       border_print();
>     +       center_print("Developed at Argonne National Laboratory", 79);
>     +       char v[100];
>     +       sprintf(v, "Version: %d", version);
>     +       center_print(v, 79);
>     +       border_print();
>     +}
>     +
>     +// Prints Section titles in center of 80 char terminal
>     +void center_print(const char *s, int width)
>     +{
>     +       int length = strlen(s);
>     +       int i;
>     +       for (i=0; i<=(width-length)/2; i++) {
>     +               fputs(" ", stdout);
>     +       }
>     +       fputs(s, stdout);
>     +       fputs("\n", stdout);
>     +}
>     +
>     +void print_results( Inputs in, int mype, double runtime, int nprocs,
>     +       unsigned long long vhash )
>     +{
>     +       // Calculate Lookups per sec
>     +       int lookups_per_sec = (int) ((double) in.lookups / runtime);
>     +
>     +       // If running in MPI, reduce timing statistics and
>     calculate average
>     +       #ifdef MPI
>     +       int total_lookups = 0;
>     +       MPI_Barrier(MPI_COMM_WORLD);
>     +       MPI_Reduce(&lookups_per_sec, &total_lookups, 1, MPI_INT,
>     +                  MPI_SUM, 0, MPI_COMM_WORLD);
>     +       #endif
>     +
>     +       // Print output
>     +       if( mype == 0 )
>     +       {
>     +               border_print();
>     +               center_print("RESULTS", 79);
>     +               border_print();
>     +
>     +               // Print the results
>     +               printf("Threads:     %d\n", in.nthreads);
>     +               #ifdef MPI
>     +               printf("MPI ranks:   %d\n", nprocs);
>     +               #endif
>     +               #ifdef TIMING
>     +               #ifdef MPI
>     +               printf("Total Lookups/s:            ");
>     +               fancy_int(total_lookups);
>     +               printf("Avg Lookups/s per MPI rank: ");
>     +               fancy_int(total_lookups / nprocs);
>     +               #else
>     +               printf("Runtime:     %.3lf seconds\n", runtime);
>     +               printf("Lookups:     "); fancy_int(in.lookups);
>     +               printf("Lookups/s:   ");
>     +               fancy_int(lookups_per_sec);
>     +               #endif
>     +               #endif
>     +               #ifdef VERIFICATION
>     +               printf("Verification checksum: %llu\n", vhash);
>     +               #endif
>     +               border_print();
>     +
>     +               // For bechmarking, output lookup/s data to file
>     +               if( SAVE )
>     +               {
>     +                       FILE * out = fopen( "results.txt", "a" );
>     +                       fprintf(out, "%d\t%d\n", in.nthreads,
>     lookups_per_sec);
>     +                       fclose(out);
>     +               }
>     +       }
>     +}
>     +
>     +void print_inputs(Inputs in, int nprocs, int version )
>     +{
>     +       // Calculate Estimate of Memory Usage
>     +       int mem_tot = estimate_mem_usage( in );
>     +       logo(version);
>     +       center_print("INPUT SUMMARY", 79);
>     +       border_print();
>     +       #ifdef VERIFICATION
>     +       printf("Verification Mode:            on\n");
>     +       #endif
>     +       printf("Materials:                    %d\n", 12);
>     +       printf("H-M Benchmark Size:           %s\n", in.HM);
>     +       printf("Total Nuclides:               %ld\n", in.n_isotopes);
>     +       printf("Gridpoints (per Nuclide):     ");
>     +       fancy_int(in.n_gridpoints);
>     +       printf("Unionized Energy Gridpoints:  ");
>     +       fancy_int(in.n_isotopes*in.n_gridpoints);
>     +       printf("XS Lookups:                   ");
>     fancy_int(in.lookups);
>     +       #ifdef MPI
>     +       printf("MPI Ranks:                    %d\n", nprocs);
>     +       printf("OMP Threads per MPI Rank:     %d\n", in.nthreads);
>     +       printf("Mem Usage per MPI Rank (MB):  "); fancy_int(mem_tot);
>     +       #else
>     +       printf("Threads:                      %d\n", in.nthreads);
>     +       printf("Est. Memory Usage (MB):       "); fancy_int(mem_tot);
>     +       #endif
>     +       border_print();
>     +       center_print("INITIALIZATION", 79);
>     +       border_print();
>     +}
>     +
>     +void border_print(void)
>     +{
>     +       printf(
>     +     
>      "==================================================================="
>     +       "=============\n");
>     +}
>     +
>     +// Prints comma separated integers - for ease of reading
>     +void fancy_int( long a )
>     +{
>     +    if( a < 1000 )
>     +        printf("%ld\n",a);
>     +
>     +    else if( a >= 1000 && a < 1000000 )
>     +        printf("%ld,%03ld\n", a / 1000, a % 1000);
>     +
>     +    else if( a >= 1000000 && a < 1000000000 )
>     +        printf("%ld,%03ld,%03ld\n",a / 1000000,(a % 1000000) /
>     1000,a % 1000 );
>     +
>     +    else if( a >= 1000000000 )
>     +        printf("%ld,%03ld,%03ld,%03ld\n",
>     +               a / 1000000000,
>     +               (a % 1000000000) / 1000000,
>     +               (a % 1000000) / 1000,
>     +               a % 1000 );
>     +    else
>     +        printf("%ld\n",a);
>     +}
>     +
>     +void print_CLI_error(void)
>     +{
>     +       printf("Usage: ./XSBench <options>\n");
>     +       printf("Options include:\n");
>     +       printf("  -t <threads>     Number of OpenMP threads to
>     run\n");
>     +       printf("  -s <size>        Size of H-M Benchmark to run
>     (small, large, XL, XXL)\n");
>     +       printf("  -g <gridpoints>  Number of gridpoints per
>     nuclide (overrides -s defaults)\n");
>     +       printf("  -l <lookups>     Number of Cross-section (XS)
>     lookups\n");
>     +       printf("Default is equivalent to: -s large -l 15000000\n");
>     +       printf("See readme for full description of default run
>     values\n");
>     +       exit(4);
>     +}
>     +
>     +Inputs read_CLI( int argc, char * argv[] )
>     +{
>     +       Inputs input;
>     +
>     +       // defaults to max threads on the system
>     +       #ifdef OPENMP
>     +       input.nthreads = omp_get_num_procs();
>     +       #else
>     +       input.nthreads = 1;
>     +       #endif
>     +
>     +       // defaults to 355 (corresponding to H-M Large benchmark)
>     +       input.n_isotopes = 355;
>     +
>     +       // defaults to 11303 (corresponding to H-M Large benchmark)
>     +       input.n_gridpoints = 11303;
>     +
>     +       // defaults to 15,000,000
>     +       input.lookups = 15000000;
>     +
>     +       // defaults to H-M Large benchmark
>     +       input.HM = (char *) malloc( 6 * sizeof(char) );
>     +       input.HM[0] = 'l' ;
>     +       input.HM[1] = 'a' ;
>     +       input.HM[2] = 'r' ;
>     +       input.HM[3] = 'g' ;
>     +       input.HM[4] = 'e' ;
>     +       input.HM[5] = '\0';
>     +
>     +       // Check if user sets these
>     +       int user_g = 0;
>     +
>     +       // Collect Raw Input
>     +       for( int i = 1; i < argc; i++ )
>     +       {
>     +               char * arg = argv[i];
>     +
>     +               // nthreads (-t)
>     +               if( strcmp(arg, "-t") == 0 )
>     +               {
>     +                       if( ++i < argc )
>     +                               input.nthreads = atoi(argv[i]);
>     +                       else
>     +                               print_CLI_error();
>     +               }
>     +               // n_gridpoints (-g)
>     +               else if( strcmp(arg, "-g") == 0 )
>     +               {
>     +                       if( ++i < argc )
>     +                       {
>     +                               user_g = 1;
>     +                               input.n_gridpoints = atol(argv[i]);
>     +                       }
>     +                       else
>     +                               print_CLI_error();
>     +               }
>     +               // lookups (-l)
>     +               else if( strcmp(arg, "-l") == 0 )
>     +               {
>     +                       if( ++i < argc )
>     +                               input.lookups = atoi(argv[i]);
>     +                       else
>     +                               print_CLI_error();
>     +               }
>     +               // HM (-s)
>     +               else if( strcmp(arg, "-s") == 0 )
>     +               {
>     +                       if( ++i < argc )
>     +                               input.HM = argv[i];
>     +                       else
>     +                               print_CLI_error();
>     +               }
>     +               else
>     +                       print_CLI_error();
>     +       }
>     +
>     +       // Validate Input
>     +
>     +       // Validate nthreads
>     +       if( input.nthreads < 1 )
>     +               print_CLI_error();
>     +
>     +       // Validate n_isotopes
>     +       if( input.n_isotopes < 1 )
>     +               print_CLI_error();
>     +
>     +       // Validate n_gridpoints
>     +       if( input.n_gridpoints < 1 )
>     +               print_CLI_error();
>     +
>     +       // Validate lookups
>     +       if( input.lookups < 1 )
>     +               print_CLI_error();
>     +
>     +       // Validate HM size
>     +       if( strcasecmp(input.HM, "small") != 0 &&
>     +               strcasecmp(input.HM, "large") != 0 &&
>     +               strcasecmp(input.HM, "XL") != 0 &&
>     +               strcasecmp(input.HM, "XXL") != 0 )
>     +               print_CLI_error();
>     +
>     +       // Set HM size specific parameters
>     +       // (defaults to large)
>     +       if( strcasecmp(input.HM, "small") == 0 )
>     +               input.n_isotopes = 68;
>     +       else if( strcasecmp(input.HM, "XL") == 0 && user_g == 0 )
>     +               input.n_gridpoints = 238847; // sized to make 120
>     GB XS data
>     +       else if( strcasecmp(input.HM, "XXL") == 0 && user_g == 0 )
>     +               input.n_gridpoints = 238847 * 2.1; // 252 GB XS data
>     +
>     +       // Return input struct
>     +       return input;
>     +}
>
>     Modified: test-suite/trunk/MultiSource/Benchmarks/Makefile
>     URL:
>     http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/Makefile?rev=289666&r1=289665&r2=289666&view=diff
>     <http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/Makefile?rev=289666&r1=289665&r2=289666&view=diff>
>     ==============================================================================
>     --- test-suite/trunk/MultiSource/Benchmarks/Makefile (original)
>     +++ test-suite/trunk/MultiSource/Benchmarks/Makefile Wed Dec 14
>     10:42:31 2016
>     @@ -9,7 +9,7 @@ PARALLEL_DIRS := Fhourstones Fhourstones
>                       McCat Olden Ptrdist llubenchmark \
>                       sim FreeBench MallocBench Prolangs-C SciMark2-C
>     mediabench\
>                       nbench ASCI_Purple MiBench Trimaran VersaBench
>     NPB-serial\
>     -                 BitBench ASC_Sequoia TSVC
>     +                 BitBench ASC_Sequoia TSVC DOE-ProxyApps-C
>
>      # Disable TSVC on Darwin until the tests support
>     SMALL_PROBLEM_SIZE=1.
>      ifeq ($(TARGET_OS),Darwin)
>
>
>     _______________________________________________
>     llvm-commits mailing list
>     llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits>
>
>

-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170103/b5ed9dc3/attachment.html>


More information about the llvm-commits mailing list