Skip to content

Commit

Permalink
Revved to version 14. This rev includes the new nuclide grid mode, wh…
Browse files Browse the repository at this point in the history
…ich allows for lookups to be performed without using the unionized energy grid. This uses much less memory but is also a lot slower. This alternative mode was added as there was some interest in doing performance analysis on it. The new mode can be used with the new -G flag.
  • Loading branch information
jtramm committed Aug 21, 2017
1 parent 2689578 commit bccbb1d
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 86 deletions.
17 changes: 17 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
=====================================================================
NEW IN VERSION 14
=====================================================================
- (Feature) Added in the ability to only use a nuclide grid via the
"-G nuclide" command line argument. This stops the code from
allocating and initializing the unionized energy grid, which
significantly reduces the amount of memory required. However,
lookups are much slower in this mode as now a binary search must
be performed for all nuclides for each macroscopic XS lookup
(instead of only once per macro XS lookup). This feature was added
as there was some interest in performance testing for this type
of lookup method.
- Slight refactoring of arguments for the lookup functions to
specify the new grid type option.
- Documentation was added for the new -G grid type command line
argument.

=====================================================================
NEW IN VERSION 13
=====================================================================
Expand Down
51 changes: 27 additions & 24 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/ /^\ \/\__/ / |_/ / __/ | | | (__| | | |
\/ \/\____/\____/ \___|_| |_|\___|_| |_|

Version 13
Version 14

==============================================================================
Contact Information
Expand Down Expand Up @@ -38,8 +38,7 @@ Download----------------------------------------------------------------------
For the most up-to-date version of XSBench, we recommend that you
download from our git repository. This can be accomplished via
cloning the repository from the command line, or by downloading a zip
from our github page. Alternatively, you can download a tar file from
the CESAR website directly.
from our github page.

Git Repository Clone:

Expand All @@ -57,26 +56,6 @@ Download----------------------------------------------------------------------
Simply use the "zip download" option on our webpage at:

https://github.com/jtramm/XSBench

CESAR Tar Download:

A tar of the XSBench source code is available
on the CESAR website at the following URL:

https://cesar.mcs.anl.gov/content/software/neutronics

Once downloaded, you can decompress XSBench using the following
command on a linux or Mac OSX system:

>$ tar -xvf XSBench-11.tar

This will decompress the tar file into a directory called
XSBench-11.

To begin use of the XSBench code, you will have to navigate to
the src directory:

>$ cd XSBench-11/src

Compilation-------------------------------------------------------------------

Expand All @@ -99,8 +78,9 @@ Running XSBench---------------------------------------------------------------
-t <threads> Number of OpenMP threads to run
-s <size> Size of H-M Benchmark to run (small, large, XL, XXL)
-g <gridpoints> Number of gridpoints per nuclide
-G <grid type> Grid search type (unionized, nuclide). Defaults to unionized.
-l <lookups> Number of Cross-section (XS) lookups
Default (no arguments given) is equivalent to: -s large -l 15000000
Default (no arguments given) is equivalent to: -s large -l 15000000 -G unionized

-t <threads>

Expand Down Expand Up @@ -143,6 +123,18 @@ Running XSBench---------------------------------------------------------------

Note that this option will override the number of default grid
-points as set by the '-s' option.

-G <grid type>

Sets the grid search type (unionized, nuclide). Defaults to unionized.
The unionized grid is what is typically used in Monte Carlo codes, as
it offers the fastest speed. However, the increase in speed comes in
a significant increase in memory usage as a union of all the separate
nuclide grids must be formed and stored in memory. The "nuclide" mode
uses only the basic nuclide grid data, with no unionization. This is
slower as a binary search must be performed on every nuclide for each
macroscopic XS lookup, rather than only once when using the unionized
grid.

-l <lookups>

Expand Down Expand Up @@ -197,6 +189,11 @@ BINARY_READ = no
-> Binary dump mode writes a binary file containing a randomized data set
of cross sections. This can be used in tandem with the binary read mode
to skip generation of cross section data every time the program is run.
Note that if you create the grid when specifying the -G flag as
"nuclide", data for the unionized energy grid will not be written, and
therefore any subsequent runs using that file in binary read mode must
also use the -G nuclide option. Files generated for the unionized grid
can also be used when running in the nuclide grid mode.

-> Binary read mode reads the binary file created by the binary dump mode
as a (usually) much faster substitution for randomly generating XS
Expand Down Expand Up @@ -302,6 +299,12 @@ when reading and writing a binary file. No runtime checks are made
to validate that the file correctly corresponds to the selected input
parameters.

Also note that if you create the grid when specifying the -G flag as
"nuclide", data for the unionized energy grid will not be written, and
therefore any subsequent runs using that file in binary read mode must
also use the "-G nuclide" option. Files generated for the full unionized grid
can also be used when running in the nuclide grid mode.

==============================================================================
Running on ANL BlueGene/Q (Vesta & Mira)
==============================================================================
Expand Down
61 changes: 50 additions & 11 deletions src/CalculateXS.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,33 @@ 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 idx, double * restrict xs_vector, int grid_type ){

// 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];
if( grid_type == NUCLIDE )
{
// Perform binary search on the Nuclide Grid to find the index
idx = grid_search_nuclide( n_gridpoints, p_energy, nuclide_grids[nuc]);

// pull ptr from nuclide grid and check to ensure that
// we're not reading off the end of the nuclide's grid
if( idx == n_gridpoints - 1 )
low = &nuclide_grids[nuc][idx - 1];
else
low = &nuclide_grids[nuc][idx];
}
else
low = &nuclide_grids[nuc][energy_grid[idx].xs_ptrs[nuc]];
{
// 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;

Expand Down Expand Up @@ -58,19 +73,20 @@ void calculate_macro_xs( double p_energy, int mat, long n_isotopes,
GridPoint * restrict energy_grid,
NuclideGridPoint ** restrict nuclide_grids,
int ** restrict mats,
double * restrict macro_xs_vector ){
double * restrict macro_xs_vector, int grid_type ){
double xs_vector[5];
int p_nuc; // the nuclide we are looking up
long idx = 0;
long idx = -1;
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);
if( grid_type == UNIONIZED )
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
Expand All @@ -85,7 +101,7 @@ void calculate_macro_xs( double p_energy, int mat, long n_isotopes,
conc = concs[mat][j];
calculate_micro_xs( p_energy, p_nuc, n_isotopes,
n_gridpoints, energy_grid,
nuclide_grids, idx, xs_vector );
nuclide_grids, idx, xs_vector, grid_type );
for( int k = 0; k < 5; k++ )
macro_xs_vector[k] += xs_vector[k] * conc;
}
Expand Down Expand Up @@ -122,3 +138,26 @@ long grid_search( long n, double quarry, GridPoint * A)

return lowerLimit;
}

// binary search for energy on nuclide energy grid
long grid_search_nuclide( long n, double quarry, NuclideGridPoint * 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;
}
54 changes: 31 additions & 23 deletions src/Main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ int main( int argc, char* argv[] )
// =====================================================================
// Initialization & Command Line Read-In
// =====================================================================
int version = 13;
int version = 14;
int mype = 0;
int max_procs = omp_get_num_procs();
int i, thread, mat;
Expand Down Expand Up @@ -66,28 +66,36 @@ int main( int argc, char* argv[] )
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
// If using a unionized grid search, initialize the energy grid
// Otherwise, leave these as null
GridPoint * energy_grid = NULL;
int * index_data = NULL;

// 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
if( in.grid_type == UNIONIZED )
{
// Prepare Unionized Energy Grid Framework
#ifndef BINARY_READ
energy_grid = generate_energy_grid( in.n_isotopes,
in.n_gridpoints, nuclide_grids );
#else
energy_grid = (GridPoint *)malloc( in.n_isotopes *
in.n_gridpoints * sizeof( GridPoint ) );
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);
binary_read(in.n_isotopes, in.n_gridpoints, nuclide_grids, energy_grid, in.grid_type);
#endif

// Get material data
Expand All @@ -104,7 +112,7 @@ int main( int argc, char* argv[] )

#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);
binary_dump(in.n_isotopes, in.n_gridpoints, nuclide_grids, energy_grid, in.grid_type);
if( mype == 0 ) printf("Binary file \"XS_data.dat\" written! Exiting...\n");
return 0;
#endif
Expand Down Expand Up @@ -191,9 +199,9 @@ int main( int argc, char* argv[] )
// 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 );
in.n_gridpoints, num_nucs, concs,
energy_grid, nuclide_grids, mats,
macro_xs_vector, in.grid_type );

// Copy results from above function call onto heap
// so that compiler cannot optimize function out
Expand Down
6 changes: 3 additions & 3 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ LDFLAGS = -lm
# Regular gcc Compiler
ifeq ($(COMPILER),gnu)
CC = gcc
CFLAGS += -fopenmp
CFLAGS += -fopenmp -flto
endif

# Intel Compiler
Expand Down Expand Up @@ -121,10 +121,10 @@ endif
# Targets to Build
#===============================================================================

$(program): $(obj) XSbench_header.h
$(program): $(obj) XSbench_header.h Makefile
$(CC) $(CFLAGS) $(obj) -o $@ $(LDFLAGS)

%.o: %.c
%.o: %.c Makefile
$(CC) $(CFLAGS) -c $< -o $@

clean:
Expand Down
17 changes: 12 additions & 5 deletions src/XSbench_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ typedef struct{
long n_gridpoints;
int lookups;
char * HM;
int grid_type; // 0: Unionized Grid (default) 1: Nuclide Grid
} Inputs;

#define UNIONIZED 0
#define NUCLIDE 1

// Function Prototypes
void logo(int version);
void center_print(const char *s, int width);
Expand Down Expand Up @@ -78,15 +82,16 @@ void calculate_macro_xs( double p_energy, int mat, long n_isotopes,
GridPoint * restrict energy_grid,
NuclideGridPoint ** restrict nuclide_grids,
int ** restrict mats,
double * restrict macro_xs_vector );
double * restrict macro_xs_vector, int grid_type );

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 );
NuclideGridPoint ** restrict nuclide_grids, long idx,
double * restrict xs_vector, int grid_type );

long grid_search( long n, double quarry, GridPoint * A);
long grid_search_nuclide( long n, double quarry, NuclideGridPoint * A);

int * load_num_nucs(long n_isotopes);
int ** load_mats( int * num_nucs, long n_isotopes );
Expand All @@ -109,7 +114,9 @@ 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);
void binary_dump(long n_isotopes, long n_gridpoints, NuclideGridPoint ** nuclide_grids, GridPoint * energy_grid, int grid_type);
void binary_read(long n_isotopes, long n_gridpoints, NuclideGridPoint ** nuclide_grids, GridPoint * energy_grid, int grid_type);



#endif
Loading

0 comments on commit bccbb1d

Please sign in to comment.