[test-suite] r289666 - Add XSBench

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 14 09:43:40 PST 2016


----- Original Message -----
> From: "Hal Finkel" <hfinkel at anl.gov>
> To: "Kristof Beyls" <Kristof.Beyls at arm.com>
> Cc: llvm-commits at lists.llvm.org, "nd" <nd at arm.com>
> Sent: Wednesday, December 14, 2016 11:40:36 AM
> Subject: Re: [test-suite] r289666 - Add XSBench
> 
> ----- Original Message -----
> > From: "Kristof Beyls" <Kristof.Beyls at arm.com>
> > To: "Hal Finkel" <hfinkel at anl.gov>
> > Cc: llvm-commits at lists.llvm.org, "nd" <nd at arm.com>
> > Sent: Wednesday, December 14, 2016 11:34:30 AM
> > Subject: Re: [test-suite] r289666 - Add XSBench
> > 
> > Hi Hal,
> > 
> > Given XSBench comes with its own LICENSE file, should
> > MultiSource/Benchmarks/DOE-ProxyApps-C/ or
> > MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench
> > be pointed to by the top-level test-suite LICENSE.TXT file in the
> > section starting with "The following pieces of software have
> > additional or alternate copyrights,
> > licenses, and/or restrictions:"?
> 
> I didn't even think about it (because it is an MIT license), but that
> is probably a good idea regardless. I'll add it.

r289677

Thanks again,
Hal

> 
>  -Hal
> 
> > 
> > Thanks,
> > 
> > Kristof
> > 
> > > On 14 Dec 2016, at 16:42, Hal Finkel via llvm-commits
> > > <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
> > > 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). 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
> > > 
> > > 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
> > > ==============================================================================
> > > --- 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > ---
> > > 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
> > > ==============================================================================
> > > --- 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
> > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> > 
> > 
> 
> --
> Hal Finkel
> Lead, Compiler Technology and Programming Languages
> Leadership Computing Facility
> Argonne National Laboratory
> 

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


More information about the llvm-commits mailing list