├── web ├── HPCG_Logo.jpg ├── common │ ├── bg_box.png │ ├── bg_nav.png │ ├── bg_footer.png │ ├── bg_logo.png │ ├── bg_subnav.png │ ├── favicon.ico │ ├── bg_content.png │ ├── nav_events.html │ ├── nav_packages.html │ ├── nav_home.html │ ├── nav_download.html │ ├── nav_about.html │ ├── nav_resources.html │ ├── page.php │ ├── html.css │ ├── header.html │ └── footer.html ├── doc │ ├── HPCG-Logo.jpg │ ├── HPCG-Logo.pptx │ ├── HPCG-Logo.tiff │ ├── HPCG-Benchmark.pdf │ ├── HPCG-workflow.pptx │ ├── HPCG-workflow.tiff │ ├── HPCG-Benchmark.docx │ ├── HPCG-Specification.docx │ └── HPCG-Specification.pdf ├── 2014-06-hpcg-list.pdf ├── research.php ├── HPCG_BOF.php ├── resources.php ├── software_design.php ├── license.php ├── results.php ├── applications.php ├── index.html ├── documentation.php ├── team.php ├── contact.php ├── publications.php ├── events.php ├── developer_tools.php ├── default.php ├── packages.php ├── mail_lists.php ├── download.php ├── about.php ├── news.php ├── release_notes.php └── faq.php ├── src ├── ComputeOptimalShapeXYZ.hpp ├── mytimer.hpp ├── MixedBaseCounter.hpp ├── SetupHalo.hpp ├── SetupHalo_ref.hpp ├── ReadHpcgDat.hpp ├── ExchangeHalo.hpp ├── CheckAspectRatio.hpp ├── GenerateCoarseProblem.hpp ├── ComputeMG.hpp ├── ComputeResidual.hpp ├── ComputeSPMV.hpp ├── CheckProblem.hpp ├── ComputeSYMGS.hpp ├── ComputeMG_ref.hpp ├── ComputeSPMV_ref.hpp ├── GenerateProblem.hpp ├── ComputeSYMGS_ref.hpp ├── ComputeProlongation_ref.hpp ├── ComputeRestriction_ref.hpp ├── GenerateProblem_ref.hpp ├── ComputeWAXPBY.hpp ├── ComputeWAXPBY_ref.hpp ├── WriteProblem.hpp ├── ComputeDotProduct.hpp ├── ComputeDotProduct_ref.hpp ├── GenerateGeometry.hpp ├── finalize.cpp ├── .project ├── ReportResults.hpp ├── TestNorms.hpp ├── ComputeMG.cpp ├── OptimizeProblem.hpp ├── TestSymmetry.hpp ├── SetupHalo.cpp ├── CG.hpp ├── CG_ref.hpp ├── ComputeSPMV.cpp ├── CheckAspectRatio.cpp ├── MixedBaseCounter.cpp ├── TestNorms.cpp ├── TestCG.hpp ├── mytimer.cpp ├── ComputeRestriction_ref.cpp ├── ComputeWAXPBY.cpp ├── ComputeProlongation_ref.cpp ├── ComputeDotProduct.cpp ├── GenerateProblem.cpp ├── CGData.hpp ├── hpcg.hpp ├── ComputeSPMV_ref.cpp ├── ComputeWAXPBY_ref.cpp ├── ComputeSYMGS.cpp ├── ReadHpcgDat.cpp ├── ComputeMG_ref.cpp ├── MGData.hpp ├── ComputeDotProduct_ref.cpp ├── ComputeResidual.cpp ├── YAML_Doc.cpp ├── WriteProblem.cpp ├── YAML_Element.hpp ├── Vector.hpp ├── ExchangeHalo.cpp ├── OutputFile.cpp ├── ComputeSYMGS_ref.cpp ├── OptimizeProblem.cpp ├── .cproject ├── GenerateCoarseProblem.cpp ├── YAML_Doc.hpp └── ComputeOptimalShapeXYZ.cpp ├── .gitignore ├── unittesting ├── hpcg_dat │ ├── Makefile │ └── main.cpp ├── Geometry │ ├── build │ └── main.cpp └── yaml_output │ ├── Makefile │ ├── readhpcgyaml.py │ └── main.cpp ├── AUTHORS ├── bin └── hpcg.dat ├── tools ├── symgs.m ├── hpcg.astyle ├── main.m ├── updateTarfile ├── hpcg.m ├── updateDoxWeb ├── makefile.py ├── Makefile.mtxdmp ├── replace_header.py └── mtxdmp.cc ├── README ├── TODO ├── NEWS ├── BUGS ├── ChangeLog ├── setup └── Make.UNKNOWN ├── .project ├── configure ├── Makefile ├── LICENSE ├── index.doc ├── Makefile.am ├── TUNING ├── COPYING ├── COPYRIGHT ├── QUICKSTART ├── CMakeLists.txt ├── README.md ├── configure.ac └── .cproject /web/HPCG_Logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/HPCG_Logo.jpg -------------------------------------------------------------------------------- /web/common/bg_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/common/bg_box.png -------------------------------------------------------------------------------- /web/common/bg_nav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/common/bg_nav.png -------------------------------------------------------------------------------- /web/doc/HPCG-Logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-Logo.jpg -------------------------------------------------------------------------------- /web/common/bg_footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/common/bg_footer.png -------------------------------------------------------------------------------- /web/common/bg_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/common/bg_logo.png -------------------------------------------------------------------------------- /web/common/bg_subnav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/common/bg_subnav.png -------------------------------------------------------------------------------- /web/common/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/common/favicon.ico -------------------------------------------------------------------------------- /web/doc/HPCG-Logo.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-Logo.pptx -------------------------------------------------------------------------------- /web/doc/HPCG-Logo.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-Logo.tiff -------------------------------------------------------------------------------- /src/ComputeOptimalShapeXYZ.hpp: -------------------------------------------------------------------------------- 1 | 2 | void ComputeOptimalShapeXYZ(int xyz, int & x, int & y, int & z); 3 | -------------------------------------------------------------------------------- /web/2014-06-hpcg-list.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/2014-06-hpcg-list.pdf -------------------------------------------------------------------------------- /web/common/bg_content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/common/bg_content.png -------------------------------------------------------------------------------- /web/doc/HPCG-Benchmark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-Benchmark.pdf -------------------------------------------------------------------------------- /web/doc/HPCG-workflow.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-workflow.pptx -------------------------------------------------------------------------------- /web/doc/HPCG-workflow.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-workflow.tiff -------------------------------------------------------------------------------- /web/doc/HPCG-Benchmark.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-Benchmark.docx -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | *.swp 3 | src/*.o 4 | bin/HPCG-Benchmark_3*.txt 5 | bin/xhpcg 6 | bin/hpcg20*.txt 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /unittesting/hpcg_dat/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CXXFLAGS = -I../../src -pipe -g 3 | 4 | main: main.o ../../src/ReadHpcgDat.o 5 | -------------------------------------------------------------------------------- /web/doc/HPCG-Specification.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-Specification.docx -------------------------------------------------------------------------------- /web/doc/HPCG-Specification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpcg-benchmark/hpcg/HEAD/web/doc/HPCG-Specification.pdf -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Jack Dongarra dongarra@icl.utk.edu 2 | Michael Heroux maherou@sandia.gov 3 | Piotr Luszczek luszczek@icl.utk.edu 4 | -------------------------------------------------------------------------------- /bin/hpcg.dat: -------------------------------------------------------------------------------- 1 | HPCG benchmark input file 2 | Sandia National Laboratories; University of Tennessee, Knoxville 3 | 104 104 104 4 | 60 5 | -------------------------------------------------------------------------------- /web/common/nav_events.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /web/common/nav_packages.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /tools/symgs.m: -------------------------------------------------------------------------------- 1 | function [x] = symgs(A,y) 2 | LA = tril(A); 3 | UA = triu(A); 4 | DA = diag(diag(A)); 5 | x = LA\y; 6 | x1 = y - LA*x + DA*x; 7 | x = UA\x1; 8 | end 9 | -------------------------------------------------------------------------------- /unittesting/Geometry/build: -------------------------------------------------------------------------------- 1 | g++ -c -I../../src ../../src/GenerateGeometry.cpp -o GenerateGeometry.o 2 | g++ -I../../src main.cpp GenerateGeometry.o -o xTestGeometry 3 | -------------------------------------------------------------------------------- /web/common/nav_home.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /web/common/nav_download.html: -------------------------------------------------------------------------------- 1 |
5 | -------------------------------------------------------------------------------- /tools/hpcg.astyle: -------------------------------------------------------------------------------- 1 | --brackets=attach 2 | --indent=spaces=2 3 | --convert-tabs 4 | --max-instatement-indent=2 5 | --pad-header 6 | --keep-one-line-blocks 7 | --keep-one-line-statements 8 | --align-pointer=middle 9 | --align-reference=middle 10 | --preserve-date 11 | --verbose 12 | --lineend=linux 13 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | #################################################### 2 | High Performance Conjugate Gradient Benchmark (HPCG) 3 | #################################################### 4 | 5 | :Author: Jack Dongarra and Michael Heroux and Piotr Luszczek 6 | :Revision: 3.1 7 | :Date: March 28, 2019 8 | 9 | For overview of HPCG please see README.md file. 10 | -------------------------------------------------------------------------------- /tools/main.m: -------------------------------------------------------------------------------- 1 | load A.dat 2 | A=spconvert(A); 3 | load x.dat 4 | load xexact.dat 5 | load b.dat 6 | normr = norm(b-A*xexact); 7 | os = sprintf('Residual of b - A*xexact (should be zero) %10.4e',normr); 8 | disp(os); 9 | normr = norm(b-A*x); 10 | os = sprintf('Residual of b - A*x (initial guess) %10.4e\n\n',normr); 11 | disp(os); 12 | xcomputed = hpcg(A,b,x); -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | ============================================================== 2 | High Performance Conjugate Gradients (HPCG) Benchmark 3 | HPCG - 3.1 - March 28, 2019 4 | ============================================================== 5 | 6 | - Add support for derived MPI Communicators (other than MPI_COMM_WORLD) 7 | 8 | ============================================================== 9 | -------------------------------------------------------------------------------- /unittesting/yaml_output/Makefile: -------------------------------------------------------------------------------- 1 | 2 | SRCD = ../../src 3 | 4 | OBJS = $(SRCD)/ComputeOptimalShapeXYZ.o $(SRCD)/GenerateGeometry.o $(SRCD)/MixedBaseCounter.o $(SRCD)/ReportResults.o $(SRCD)/YAML_Doc.o $(SRCD)/YAML_Element.o 5 | 6 | CXXFLAGS = -I../../src -pipe -g -DHPCG_NO_MPI 7 | LDFLAGS = -g 8 | 9 | main: main.o $(OBJS) 10 | $(CXX) $(LDFLAGS) -o main main.o $(OBJS) $(LDLIBS) 11 | -------------------------------------------------------------------------------- /web/common/nav_about.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | #################################################### 2 | High Performance Conjugate Gradient Benchmark (HPCG) 3 | #################################################### 4 | 5 | :Author: Jack Dongarra and Michael Heroux and Piotr Luszczek 6 | :Revision: 3.1 7 | :Date: March 28, 2019 8 | 9 | =============== 10 | History of HPCG 11 | =============== 12 | 13 | For release history please see HISTORY file. 14 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | ============================================================== 2 | List of the known problems with the HPCG software 3 | 4 | Current as of release HPCG - 3.1 - March 28, 2019 5 | ============================================================== 6 | - No known bugs 7 | 8 | ============================================================== 9 | 10 | ============================================================== 11 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | #################################################### 2 | High Performance Conjugate Gradient Benchmark (HPCG) 3 | #################################################### 4 | 5 | :Author: Jack Dongarra and Michael Heroux and Piotr Luszczek 6 | :Revision: 3.1 7 | :Date: March 28, 2019 8 | 9 | =============== 10 | History of HPCG 11 | =============== 12 | 13 | For release history please see HISTORY file. 14 | -------------------------------------------------------------------------------- /tools/updateTarfile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run this script from the main hpcg directory: 3 | # hpcg> tools/updateTarfile [version_number] 4 | make VERSION=$1 dist 5 | scp hpcg-$1.tar.gz mheroux@unix.csbsju.edu: 6 | 7 | echo #### Log into software.sandia.gov and execute the following commands 8 | echo cd /var/www/html/hpcg/downloads 9 | echo scp mheroux@unix.csbsju.edu:hpcg-$1.tar.gz . 10 | echo chmod a+r hpcg-$1.tar.gz 11 | -------------------------------------------------------------------------------- /web/research.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Research'); 6 | $page->setNavIdentifier('about'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 |

Research results will be posted here as available.

14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /web/HPCG_BOF.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('SC14 BOF'); 6 | $page->setNavIdentifier('events'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 |

SC'14 New Orleans, LA, USA, Location and Time TBD

14 | 15 | 16 | -------------------------------------------------------------------------------- /web/resources.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Resources'); 6 | $page->setNavIdentifier('resources'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Please follow the links to the left to find more in-depth information about 15 | the HPCG project.

16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /web/common/nav_resources.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/mytimer.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef MYTIMER_HPP 16 | #define MYTIMER_HPP 17 | double mytimer(void); 18 | #endif // MYTIMER_HPP 19 | -------------------------------------------------------------------------------- /unittesting/yaml_output/readhpcgyaml.py: -------------------------------------------------------------------------------- 1 | 2 | import dircache 3 | import sys 4 | 5 | import yaml 6 | 7 | def read_yaml_files(filenames): 8 | for filename in filenames: 9 | if filename[-4:] == "yaml": 10 | yaml.load(open(filename).read()) 11 | 12 | def main(argv): 13 | if len(argv) > 1: 14 | read_yaml_files(argv[1:]) 15 | else: 16 | read_yaml_files(dircache.listdir(".")) 17 | 18 | return 0 19 | 20 | if "__main__" == __name__: 21 | sys.exit(main(sys.argv)) 22 | -------------------------------------------------------------------------------- /web/software_design.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Software Design'); 6 | $page->setNavIdentifier('about'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 |

HPCG is a self-contained C++ program with MPI and OpenMP support.

14 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /web/license.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - License'); 6 | $page->setNavIdentifier('download'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 | 14 |

HPCG is available for download under a New BSD License.

15 | 16 | 17 | -------------------------------------------------------------------------------- /src/MixedBaseCounter.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | class MixedBaseCounter { 4 | private: 5 | int length; //!< number of prime factor counts (cannot exceed 32 for a 32-bit integer) 6 | int max_counts[32+1]; //!< maximum value for prime factor counts 7 | int cur_counts[32+1]; //!< current prime factor counts 8 | 9 | public: 10 | MixedBaseCounter(int *counts, int length); 11 | MixedBaseCounter(MixedBaseCounter & left, MixedBaseCounter & right); 12 | void next(); 13 | int is_zero(); 14 | int product(int * multipliers); 15 | }; 16 | -------------------------------------------------------------------------------- /web/results.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Results'); 6 | $page->setNavIdentifier('results'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 |

HPCG Benchmark Results

14 | 15 | 16 |

HPCG Performance Rankings, ISC'14, Leipzig, Germany, 26 June 2014

17 | 18 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/SetupHalo.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef SETUPHALO_HPP 16 | #define SETUPHALO_HPP 17 | #include "SparseMatrix.hpp" 18 | 19 | void SetupHalo(SparseMatrix & A); 20 | 21 | #endif // SETUPHALO_HPP 22 | -------------------------------------------------------------------------------- /src/SetupHalo_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef SETUPHALO_REF_HPP 16 | #define SETUPHALO_REF_HPP 17 | #include "SparseMatrix.hpp" 18 | 19 | void SetupHalo_ref(SparseMatrix & A); 20 | 21 | #endif // SETUPHALO_REF_HPP 22 | -------------------------------------------------------------------------------- /src/ReadHpcgDat.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef READHPCGDAT_HPP 16 | #define READHPCGDAT_HPP 17 | 18 | int ReadHpcgDat(int *localDimensions, int *secondsPerRun, int *localProcDimensions); 19 | 20 | #endif // READHPCGDAT_HPP 21 | -------------------------------------------------------------------------------- /src/ExchangeHalo.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef EXCHANGEHALO_HPP 16 | #define EXCHANGEHALO_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | void ExchangeHalo(const SparseMatrix & A, Vector & x); 20 | #endif // EXCHANGEHALO_HPP 21 | -------------------------------------------------------------------------------- /src/CheckAspectRatio.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef CHECKASPECTRATIO_HPP 16 | #define CHECKASPECTRATIO_HPP 17 | extern int CheckAspectRatio(double smallest_ratio, int x, int y, int z, const char *what, bool DoIo); 18 | #endif // CHECKASPECTRATIO_HPP 19 | 20 | -------------------------------------------------------------------------------- /src/GenerateCoarseProblem.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef GENERATECOARSEPROBLEM_HPP 16 | #define GENERATECOARSEPROBLEM_HPP 17 | #include "SparseMatrix.hpp" 18 | 19 | void GenerateCoarseProblem(const SparseMatrix & A); 20 | #endif // GENERATECOARSEPROBLEM_HPP 21 | -------------------------------------------------------------------------------- /src/ComputeMG.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTEMG_HPP 16 | #define COMPUTEMG_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | 20 | int ComputeMG(const SparseMatrix & A, const Vector & r, Vector & x); 21 | 22 | #endif // COMPUTEMG_HPP 23 | -------------------------------------------------------------------------------- /src/ComputeResidual.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTERESIDUAL_HPP 16 | #define COMPUTERESIDUAL_HPP 17 | #include "Vector.hpp" 18 | int ComputeResidual(const local_int_t n, const Vector & v1, const Vector & v2, double & residual); 19 | #endif // COMPUTERESIDUAL_HPP 20 | -------------------------------------------------------------------------------- /src/ComputeSPMV.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTESPMV_HPP 16 | #define COMPUTESPMV_HPP 17 | #include "Vector.hpp" 18 | #include "SparseMatrix.hpp" 19 | 20 | int ComputeSPMV( const SparseMatrix & A, Vector & x, Vector & y); 21 | 22 | #endif // COMPUTESPMV_HPP 23 | -------------------------------------------------------------------------------- /src/CheckProblem.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef CHECKPROBLEM_HPP 16 | #define CHECKPROBLEM_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | 20 | void CheckProblem(SparseMatrix & A, Vector * b, Vector * x, Vector * xexact); 21 | #endif // CHECKPROBLEM_HPP 22 | -------------------------------------------------------------------------------- /src/ComputeSYMGS.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTESYMGS_HPP 16 | #define COMPUTESYMGS_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | 20 | int ComputeSYMGS( const SparseMatrix & A, const Vector & r, Vector & x); 21 | 22 | #endif // COMPUTESYMGS_HPP 23 | -------------------------------------------------------------------------------- /src/ComputeMG_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTEMG_REF_HPP 16 | #define COMPUTEMG_REF_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | 20 | int ComputeMG_ref(const SparseMatrix & A, const Vector & r, Vector & x); 21 | 22 | #endif // COMPUTEMG_REF_HPP 23 | -------------------------------------------------------------------------------- /src/ComputeSPMV_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTESPMV_REF_HPP 16 | #define COMPUTESPMV_REF_HPP 17 | #include "Vector.hpp" 18 | #include "SparseMatrix.hpp" 19 | 20 | int ComputeSPMV_ref( const SparseMatrix & A, Vector & x, Vector & y); 21 | 22 | #endif // COMPUTESPMV_REF_HPP 23 | -------------------------------------------------------------------------------- /src/GenerateProblem.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef GENERATEPROBLEM_HPP 16 | #define GENERATEPROBLEM_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | 20 | void GenerateProblem(SparseMatrix & A, Vector * b, Vector * x, Vector * xexact); 21 | #endif // GENERATEPROBLEM_HPP 22 | -------------------------------------------------------------------------------- /src/ComputeSYMGS_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTESYMGS_REF_HPP 16 | #define COMPUTESYMGS_REF_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | 20 | int ComputeSYMGS_ref( const SparseMatrix & A, const Vector & r, Vector & x); 21 | 22 | #endif // COMPUTESYMGS_REF_HPP 23 | -------------------------------------------------------------------------------- /src/ComputeProlongation_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTEPROLONGATION_REF_HPP 16 | #define COMPUTEPROLONGATION_REF_HPP 17 | #include "Vector.hpp" 18 | #include "SparseMatrix.hpp" 19 | int ComputeProlongation_ref(const SparseMatrix & Af, Vector & xf); 20 | #endif // COMPUTEPROLONGATION_REF_HPP 21 | -------------------------------------------------------------------------------- /src/ComputeRestriction_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTERESTRICTION_REF_HPP 16 | #define COMPUTERESTRICTION_REF_HPP 17 | #include "Vector.hpp" 18 | #include "SparseMatrix.hpp" 19 | int ComputeRestriction_ref(const SparseMatrix & A, const Vector & rf); 20 | #endif // COMPUTERESTRICTION_REF_HPP 21 | -------------------------------------------------------------------------------- /src/GenerateProblem_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef GENERATEPROBLEM_REF_HPP 16 | #define GENERATEPROBLEM_REF_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "Vector.hpp" 19 | 20 | void GenerateProblem_ref(SparseMatrix & A, Vector * b, Vector * x, Vector * xexact); 21 | #endif // GENERATEPROBLEM_REF_HPP 22 | -------------------------------------------------------------------------------- /tools/hpcg.m: -------------------------------------------------------------------------------- 1 | function [x]=hpcg(A, b, x) 2 | iter =0; 3 | maxiters = 100; 4 | p = x; 5 | Ap = A*p; 6 | r = b - Ap; 7 | normr = sqrt(r'*r); 8 | os = sprintf('\n\nInitial residual = %10.4e',normr); 9 | disp(os); 10 | while norm(r) > 1e-16 && iter < maxiters 11 | iter=iter+1; 12 | z = symgs(A,r); 13 | if iter==1 14 | p = z; 15 | rtz = r'*z; 16 | else 17 | oldrtz = rtz; 18 | rtz = r'*z; 19 | beta = rtz/oldrtz; 20 | p = beta*p + z; 21 | end 22 | Ap = A*p; 23 | pAp = p'*Ap; 24 | alpha = rtz/pAp; 25 | x = x + alpha*p; 26 | r = r - alpha*Ap; 27 | normr = sqrt(r'*r); 28 | os = sprintf('Residual at iteration %3d = %10.4e',iter,normr); 29 | disp(os); 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /src/ComputeWAXPBY.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTEWAXPBY_HPP 16 | #define COMPUTEWAXPBY_HPP 17 | #include "Vector.hpp" 18 | int ComputeWAXPBY(const local_int_t n, const double alpha, const Vector & x, 19 | const double beta, const Vector & y, Vector & w, bool & isOptimized); 20 | #endif // COMPUTEWAXPBY_HPP 21 | -------------------------------------------------------------------------------- /src/ComputeWAXPBY_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTEWAXPBY_REF_HPP 16 | #define COMPUTEWAXPBY_REF_HPP 17 | #include "Vector.hpp" 18 | int ComputeWAXPBY_ref(const local_int_t n, const double alpha, const Vector & x, 19 | const double beta, const Vector & y, Vector & w); 20 | #endif // COMPUTEWAXPBY_REF_HPP 21 | -------------------------------------------------------------------------------- /src/WriteProblem.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef WRITEPROBLEM_HPP 16 | #define WRITEPROBLEM_HPP 17 | #include "Geometry.hpp" 18 | #include "SparseMatrix.hpp" 19 | 20 | int WriteProblem( const Geometry & geom, const SparseMatrix & A, const Vector b, const Vector x, const Vector xexact); 21 | #endif // WRITEPROBLEM_HPP 22 | -------------------------------------------------------------------------------- /src/ComputeDotProduct.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTEDOTPRODUCT_HPP 16 | #define COMPUTEDOTPRODUCT_HPP 17 | #include "Vector.hpp" 18 | int ComputeDotProduct(const local_int_t n, const Vector & x, const Vector & y, 19 | double & result, double & time_allreduce, bool & isOptimized); 20 | 21 | #endif // COMPUTEDOTPRODUCT_HPP 22 | -------------------------------------------------------------------------------- /src/ComputeDotProduct_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef COMPUTEDOTPRODUCT_REF_HPP 16 | #define COMPUTEDOTPRODUCT_REF_HPP 17 | #include "Vector.hpp" 18 | int ComputeDotProduct_ref(const local_int_t n, const Vector & x, const Vector & y, 19 | double & result, double & time_allreduce); 20 | 21 | #endif // COMPUTEDOTPRODUCT_REF_HPP 22 | -------------------------------------------------------------------------------- /web/applications.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Applications'); 6 | $page->setNavIdentifier('about'); 7 | 8 | $x = <<< END 9 | img.app { float: right; padding: 10px 10px 20px 20px; } 10 | END; 11 | $page->setInlineStyles($x); 12 | 13 | ?> 14 | 15 | 16 | 17 | 18 | 19 |

Applications

20 | 21 |

Current activities: 22 | 23 | We have released HPCG Version 2.4 for general availability. 24 | 25 |



26 | 27 | 28 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Home'); 6 | $page->setNavIdentifier('home'); 7 | $page->setPageIdentifier('home'); 8 | ?> 9 | 10 | 11 | 12 |

Welcome to the HPCG Project Home Page

13 | 14 | HPCG is presently in BETA Testing Mode. The website and other content is under development. 15 | 16 | Here is a quick link to the source code documentation: 17 |

Reference Documentation for HPCG sourc files is here.

18 | 19 | 20 |

21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /web/documentation.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Documentation'); 6 | $page->setNavIdentifier('resources'); 7 | 8 | $x = <<< END 9 | table.docs td { padding: .5em 2em .5em 0; border-bottom: 1px solid #999; } 10 | ul.docs li { padding-bottom: 1em; } 11 | END; 12 | $page->setInlineStyles($x); 13 | 14 | ?> 15 | 16 | 17 | 18 | 19 | 20 |

Reference Documentation for HPCG source files is here.

21 | 22 | 23 | -------------------------------------------------------------------------------- /src/GenerateGeometry.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef GENERATEGEOMETRY_HPP 16 | #define GENERATEGEOMETRY_HPP 17 | #include "Geometry.hpp" 18 | void GenerateGeometry(int size, int rank, int numThreads, int pz, local_int_t zl, local_int_t zu, local_int_t nx, local_int_t ny, local_int_t nz, int npx, int npy, int npz, Geometry * geom); 19 | #endif // GENERATEGEOMETRY_HPP 20 | -------------------------------------------------------------------------------- /src/finalize.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #include 16 | 17 | #include "hpcg.hpp" 18 | 19 | /*! 20 | Closes the I/O stream used for logging information throughout the HPCG run. 21 | 22 | @return returns 0 upon success and non-zero otherwise 23 | 24 | @see HPCG_Init 25 | */ 26 | int 27 | HPCG_Finalize(void) { 28 | HPCG_fout.close(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /tools/updateDoxWeb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # First edit tools/hpcg.dox and update version number of release. Then 3 | # Run this script from the main hpcg directory: 4 | # hpcg> tools/updateDoxWeb 5 | doxygen tools/hpcg.dox 6 | cd out 7 | rm -f html.tar.gz 8 | tar cvzf html.tar.gz html 9 | scp html.tar.gz mheroux@unix.csbsju.edu: 10 | echo #### Log into software.sandia.gov and execute the following: 11 | echo cd /var/www/html/hpcg 12 | echo rm -f html 13 | echo scp mheroux@unix.csbsju.edu:html.tar.gz . 14 | echo tar xvzf html.tar.gz 15 | echo chmod a+rx html 16 | echo chmod a+r html/\* 17 | #scp -r html maherou@software.sandia.gov:/var/www/html/hpcg/ 18 | #ssh maherou@software.sandia.gov chmod a+rx /var/www/html/hpcg/html 19 | #ssh maherou@software.sandia.gov chmod a+r /var/www/html/hpcg/html/* 20 | -------------------------------------------------------------------------------- /web/team.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Team'); 6 | $page->setNavIdentifier('about'); 7 | 8 | $y = <<< END 9 | th { text-align: left; padding-right: 1em; } 10 | END; 11 | $page->setInlineStyles($y); 12 | 13 | ?> 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 |
Leaders:       Mike Heroux, 23 | Jack Dongarra, 24 | Piotr Luszczek
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /setup/Make.UNKNOWN: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | 3 | arch=UNKNOWN 4 | 5 | VERSION = 3.1 6 | 7 | UNKNOWN: 8 | @echo 9 | @echo Please specify "'"arch"'" variable, for example: 10 | @echo 1. Create file "'"Make.Unix"'" in the "'"setup"'" directory 11 | @echo 2. Type: "'"make arch=Unix"'" 12 | @echo 13 | 14 | #GNUTAR = gnutar # or "gtar" on Linux 15 | GNUTAR = gtar 16 | 17 | dist: 18 | @echo Packaging for version $(VERSION) 19 | ln -s -f . hpcg-$(VERSION) 20 | grep :0: /etc/group | sed -e 's/:.*//' | xargs -I '{}' $(GNUTAR) --owner=root --group='{}' -cvhof hpcg-$(VERSION).tar hpcg-$(VERSION)/src/*.[ch]pp hpcg-$(VERSION)/[BCHIQRTV]* hpcg-$(VERSION)/bin/hpcg.dat hpcg-$(VERSION)/setup/Make.* hpcg-$(VERSION)/configure hpcg-$(VERSION)/Makefile hpcg-$(VERSION)/Makefile.ext hpcg-$(VERSION)/tools/hpcg.dox 21 | gzip -v --best hpcg-$(VERSION).tar 22 | rm -f hpcg-$(VERSION) 23 | 24 | .PHONY: UNKNOWN dist 25 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | HPCG 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | HPCG 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/ReportResults.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef REPORTRESULTS_HPP 16 | #define REPORTRESULTS_HPP 17 | #include "SparseMatrix.hpp" 18 | #include "TestCG.hpp" 19 | #include "TestSymmetry.hpp" 20 | #include "TestNorms.hpp" 21 | 22 | void ReportResults(const SparseMatrix & A, int numberOfMgLevels, int numberOfCgSets, int refMaxIters, int optMaxIters, double times[], 23 | const TestCGData & testcg_data, const TestSymmetryData & testsymmetry_data, const TestNormsData & testnorms_data, int global_failure, bool quickPath); 24 | 25 | #endif // REPORTRESULTS_HPP 26 | -------------------------------------------------------------------------------- /web/contact.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Contact'); 6 | $page->setNavIdentifier('home'); 7 | 8 | $y = <<< END 9 | th { text-align: left; padding-right: 1em; vertical-align: top; 10 | padding-bottom: 1em; } 11 | td { vertical-align: top; padding-bottom: 1em; } 12 | END; 13 | $page->setInlineStyles($y); 14 | 15 | ?> 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Primary Contacts:Jack Dongarra
Michael Heroux,Piotr Luszczek
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/TestNorms.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file TestNorms.hpp 17 | 18 | HPCG data structure 19 | */ 20 | 21 | #ifndef TESTNORMS_HPP 22 | #define TESTNORMS_HPP 23 | 24 | 25 | struct TestNormsData_STRUCT { 26 | double * values; //!< sample values 27 | double mean; //!< mean of all sampes 28 | double variance; //!< variance of mean 29 | int samples; //!< number of samples 30 | bool pass; //!< pass/fail indicator 31 | }; 32 | typedef struct TestNormsData_STRUCT TestNormsData; 33 | 34 | extern int TestNorms(TestNormsData & testnorms_data); 35 | 36 | #endif // TESTNORMS_HPP 37 | -------------------------------------------------------------------------------- /web/publications.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Publications/Presentations'); 6 | $page->setNavIdentifier('resources'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tools/makefile.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import os 4 | import re 5 | 6 | def generate_rule(fname): 7 | if fname[-4:] != ".cpp": 8 | return 9 | 10 | base = fname[:-4] 11 | 12 | regex = re.compile(r'#\s*include\s*"([\w/.]+)"') 13 | 14 | deps = list() 15 | 16 | for fline in open(fname): 17 | mtch = regex.search(fline) 18 | #print mtch, fline 19 | if mtch: 20 | deps.append(mtch.group(1)) 21 | 22 | print "%s.o:" % base, fname, 23 | for d in deps: 24 | print d, 25 | print "\n" 26 | 27 | def usage(argv0): 28 | print "Usage:\n", argv0, "[--prefix=path]" 29 | 30 | def main(argv): 31 | 32 | prefix = "" 33 | for a in argv[1:]: 34 | if a.startswith("--help") or a == "-h": 35 | usage(argv[0]) 36 | break 37 | 38 | elif a.startswith("--prefix="): 39 | prefix = a[a.find("=")+1:] 40 | 41 | else: 42 | generate_rule(a) 43 | 44 | return 0 45 | 46 | if "__main__" == __name__: 47 | import sys 48 | sys.exit(main(sys.argv)) 49 | -------------------------------------------------------------------------------- /web/events.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Events'); 6 | $page->setNavIdentifier('events'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Past HPCG-related events.

15 | 20 | 21 |

Upcoming HPCG-related events.

22 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /web/developer_tools.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Developer Tools'); 6 | $page->setNavIdentifier('resources'); 7 | 8 | $x = <<< END 9 | table.lists th { text-align: left; padding: .5em 2em .5em 0; 10 | border-bottom: 1px solid #999; } 11 | table.lists td { padding: .5em 2em .5em 0; border-bottom: 1px solid #999; } 12 | END; 13 | $page->setInlineStyles($x); 14 | 15 | ?> 16 | 17 | 18 | 19 | 20 | 21 |

Please contact the project leader for access to HPCG developer tools.

22 |

Once you have an account on software.sandia.gov and are a member of the Unix groups HPCGDevelopers and HPCGUsers, you can obtain a working copy of the archive using the following command (note this is a single command, even if it appears to be two):

23 |

svn checkout svn+ssh://username@software.sandia.gov/space/sandiasvn/private/hpcg/trunk HPCG

24 | 25 | 26 | -------------------------------------------------------------------------------- /src/ComputeMG.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeMG.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include "ComputeMG.hpp" 22 | #include "ComputeMG_ref.hpp" 23 | 24 | /*! 25 | @param[in] A the known system matrix 26 | @param[in] r the input vector 27 | @param[inout] x On exit contains the result of the multigrid V-cycle with r as the RHS, x is the approximation to Ax = r. 28 | 29 | @return returns 0 upon success and non-zero otherwise 30 | 31 | @see ComputeMG_ref 32 | */ 33 | int ComputeMG(const SparseMatrix & A, const Vector & r, Vector & x) { 34 | 35 | // This line and the next two lines should be removed and your version of ComputeSYMGS should be used. 36 | A.isMgOptimized = false; 37 | return ComputeMG_ref(A, r, x); 38 | } 39 | -------------------------------------------------------------------------------- /src/OptimizeProblem.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef OPTIMIZEPROBLEM_HPP 16 | #define OPTIMIZEPROBLEM_HPP 17 | 18 | #include "SparseMatrix.hpp" 19 | #include "Vector.hpp" 20 | #include "CGData.hpp" 21 | 22 | int OptimizeProblem(SparseMatrix & A, CGData & data, Vector & b, Vector & x, Vector & xexact); 23 | 24 | // This helper function should be implemented in a non-trivial way if OptimizeProblem is non-trivial 25 | // It should return as type double, the total number of bytes allocated and retained after calling OptimizeProblem. 26 | // This value will be used to report Gbytes used in ReportResults (the value returned will be divided by 1000000000.0). 27 | 28 | double OptimizeProblemMemoryUse(const SparseMatrix & A); 29 | 30 | #endif // OPTIMIZEPROBLEM_HPP 31 | -------------------------------------------------------------------------------- /src/TestSymmetry.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file TestSymmetry.hpp 17 | 18 | HPCG data structures for symmetry testing 19 | */ 20 | 21 | #ifndef TESTSYMMETRY_HPP 22 | #define TESTSYMMETRY_HPP 23 | 24 | #include "hpcg.hpp" 25 | #include "SparseMatrix.hpp" 26 | #include "CGData.hpp" 27 | 28 | struct TestSymmetryData_STRUCT { 29 | double depsym_spmv; //!< departure from symmetry for the SPMV kernel 30 | double depsym_mg; //!< departure from symmetry for the MG kernel 31 | int count_fail; //!< number of failures in the symmetry tests 32 | }; 33 | typedef struct TestSymmetryData_STRUCT TestSymmetryData; 34 | 35 | extern int TestSymmetry(SparseMatrix & A, Vector & b, Vector & xexact, TestSymmetryData & testsymmetry_data); 36 | 37 | #endif // TESTSYMMETRY_HPP 38 | -------------------------------------------------------------------------------- /web/default.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Home'); 6 | $page->setNavIdentifier('home'); 7 | $page->setPageIdentifier('home'); 8 | ?> 9 | 10 | 11 | 12 | 13 | 26 | 27 | 37 | 38 |

Welcome to the HPCG Project Home Page

39 | 40 | 41 | -------------------------------------------------------------------------------- /unittesting/yaml_output/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | int 6 | main() { 7 | int comm_size = 1, comm_rank = 0, numThreads = 1; 8 | int nx = 13, ny = 17, nz = 19; 9 | Geometry geom; 10 | SparseMatrix A, *Af; 11 | int numberOfMgLevels = 4; 12 | int numberOfCgSets = 97; 13 | int refMaxIters = 53; 14 | int optMaxIters = 57; 15 | double times[8] = {1000.5, 1001.5, 1002.5, 1003.5, 1004.5, 1005.5, 1006.5, 1007.5}; 16 | TestCGData testcg_data; 17 | TestSymmetryData testsymmetry_data; 18 | TestNormsData testnorms_data; 19 | int global_failure; 20 | 21 | GenerateGeometry( comm_size, comm_rank, numThreads, nx, ny, nz, &geom); 22 | 23 | Af = &A; 24 | for (int i=1; igeom = &geom; 26 | 27 | MGData *mgData = new MGData(); 28 | mgData->numberOfPresmootherSteps = 1; 29 | mgData->numberOfPostsmootherSteps = 1; 30 | Af->mgData = mgData; 31 | 32 | Af->Ac = new SparseMatrix(); 33 | Af = Af->Ac; 34 | } 35 | 36 | ReportResults( A, numberOfMgLevels, numberOfCgSets, refMaxIters, optMaxIters, times, 37 | testcg_data, testsymmetry_data, testnorms_data, global_failure ); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | src_path=`echo $0 | sed -e s:/configure$::` 4 | bld_path=`pwd` 5 | 6 | #FIXME: need to check whether src and bld are the same (test f1 -ef f2) 7 | 8 | if test x"$#" != x"1" -o x"$1" = "x" ; then 9 | echo 10 | echo Please specify '"'arch'"' argument, for example: 11 | echo 12 | echo $0 Unix 13 | echo 14 | exit 127 15 | fi 16 | 17 | arg_arch="$1" 18 | 19 | setup_file=${src_path}/setup/Make.${arg_arch} 20 | 21 | if test ! -f $setup_file ; then 22 | echo 23 | echo Please create the configuration file $setup_file 24 | echo 25 | exit 127 26 | fi 27 | 28 | mkfile=${bld_path}/Makefile 29 | 30 | if test -d $mkfile -o -f $mkfile ; then 31 | rm -rf $mkfile 32 | fi 33 | 34 | sed -e "s:HPCG_ROOT_PATH:${bld_path}:g" ${src_path}/Makefile.ext | sed -e "s:HPCG_SRC_PATH:${src_path}:g" | sed -e "s:UNKNOWN:${arg_arch}:" > $mkfile 35 | 36 | # creating missing directories 37 | for path in src testing bin setup 38 | do 39 | if test ! -d $path ; then 40 | mkdir $path 41 | fi 42 | done 43 | 44 | # copy hpcg.dat if it doesn't exist 45 | if test ! -f bin/hpcg.dat ; then 46 | cp ${src_path}/bin/hpcg.dat bin/hpcg.dat 47 | fi 48 | 49 | # copy the architecture setup file 50 | cp -f $setup_file setup 51 | -------------------------------------------------------------------------------- /tools/Makefile.mtxdmp: -------------------------------------------------------------------------------- 1 | 2 | CXXFLAGS = -I../src -DHPCG_NO_MPI=1 -DHPCG_NO_OPENMP=1 3 | 4 | LINK.o := $(LINK.cc) 5 | 6 | mtxdmp: \ 7 | ../src/CG.o \ 8 | ../src/CG_ref.o \ 9 | ../src/CheckAspectRatio.o \ 10 | ../src/CheckProblem.o \ 11 | ../src/ComputeDotProduct.o \ 12 | ../src/ComputeDotProduct_ref.o \ 13 | ../src/ComputeMG.o \ 14 | ../src/ComputeMG_ref.o \ 15 | ../src/ComputeOptimalShapeXYZ.o \ 16 | ../src/ComputeProlongation_ref.o \ 17 | ../src/ComputeResidual.o \ 18 | ../src/ComputeRestriction_ref.o \ 19 | ../src/ComputeSPMV.o \ 20 | ../src/ComputeSPMV_ref.o \ 21 | ../src/ComputeSYMGS.o \ 22 | ../src/ComputeSYMGS_ref.o \ 23 | ../src/ComputeWAXPBY.o \ 24 | ../src/ComputeWAXPBY_ref.o \ 25 | ../src/ExchangeHalo.o \ 26 | ../src/finalize.o \ 27 | ../src/GenerateCoarseProblem.o \ 28 | ../src/GenerateGeometry.o \ 29 | ../src/GenerateProblem.o \ 30 | ../src/GenerateProblem_ref.o \ 31 | ../src/init.o \ 32 | ../src/main.o \ 33 | ../src/MixedBaseCounter.o \ 34 | ../src/mytimer.o \ 35 | ../src/OptimizeProblem.o \ 36 | ../src/OutputFile.o \ 37 | ../src/ReadHpcgDat.o \ 38 | ../src/ReportResults.o \ 39 | ../src/TestCG.o \ 40 | ../src/TestNorms.o \ 41 | ../src/TestSymmetry.o \ 42 | ../src/WriteProblem.o \ 43 | ../src/YAML_Doc.o \ 44 | ../src/YAML_Element.o \ 45 | mtxdmp.o 46 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | 3 | # by default, "arch" is unknown, should be specified in the command line 4 | arch = UNKNOWN 5 | 6 | setup_file = setup/Make.$(arch) 7 | include $(setup_file) 8 | 9 | HPCG_DEPS = src/CG.o src/CG_ref.o src/TestCG.o src/ComputeResidual.o \ 10 | src/ExchangeHalo.o src/GenerateGeometry.o src/GenerateProblem.o \ 11 | src/GenerateProblem_ref.o src/CheckProblem.o \ 12 | src/OptimizeProblem.o src/ReadHpcgDat.o src/ReportResults.o \ 13 | src/SetupHalo.o src/SetupHalo_ref.o src/TestSymmetry.o src/TestNorms.o src/WriteProblem.o \ 14 | src/YAML_Doc.o src/YAML_Element.o src/ComputeDotProduct.o \ 15 | src/ComputeDotProduct_ref.o src/finalize.o src/init.o src/mytimer.o src/ComputeSPMV.o \ 16 | src/ComputeSPMV_ref.o src/ComputeSYMGS.o src/ComputeSYMGS_ref.o src/ComputeWAXPBY.o src/ComputeWAXPBY_ref.o \ 17 | src/ComputeMG_ref.o src/ComputeMG.o src/ComputeProlongation_ref.o src/ComputeRestriction_ref.o src/GenerateCoarseProblem.o \ 18 | src/ComputeOptimalShapeXYZ.o src/MixedBaseCounter.o src/CheckAspectRatio.o src/OutputFile.o 19 | 20 | bin/xhpcg: src/main.o $(HPCG_DEPS) 21 | $(LINKER) $(LINKFLAGS) src/main.o $(HPCG_DEPS) -o bin/xhpcg $(HPCG_LIBS) 22 | 23 | clean: 24 | rm -f $(HPCG_DEPS) bin/xhpcg src/main.o 25 | 26 | .PHONY: clean 27 | 28 | -------------------------------------------------------------------------------- /src/SetupHalo.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file SetupHalo.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #ifndef HPCG_NO_MPI 22 | #include 23 | #include 24 | #include 25 | #endif 26 | 27 | #ifndef HPCG_NO_OPENMP 28 | #include 29 | #endif 30 | 31 | #include "SetupHalo.hpp" 32 | #include "SetupHalo_ref.hpp" 33 | 34 | /*! 35 | Prepares system matrix data structure and creates data necessary necessary 36 | for communication of boundary values of this process. 37 | 38 | @param[inout] A The known system matrix 39 | 40 | @see ExchangeHalo 41 | */ 42 | void SetupHalo(SparseMatrix & A) { 43 | 44 | // The call to this reference version of SetupHalo can be replaced with custom code. 45 | // However, any code must work for general unstructured sparse matrices. Special knowledge about the 46 | // specific nature of the sparsity pattern may not be explicitly used. 47 | 48 | return(SetupHalo_ref(A)); 49 | } 50 | -------------------------------------------------------------------------------- /src/CG.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef CG_HPP 16 | #define CG_HPP 17 | 18 | #include "SparseMatrix.hpp" 19 | #include "Vector.hpp" 20 | #include "CGData.hpp" 21 | 22 | int CG(const SparseMatrix & A, CGData & data, const Vector & b, Vector & x, 23 | const int max_iter, const double tolerance, int & niters, double & normr, double & normr0, 24 | double * times, bool doPreconditioning); 25 | 26 | // this function will compute the Conjugate Gradient iterations. 27 | // geom - Domain and processor topology information 28 | // A - Matrix 29 | // b - constant 30 | // x - used for return value 31 | // max_iter - how many times we iterate 32 | // tolerance - Stopping tolerance for preconditioned iterations. 33 | // niters - number of iterations performed 34 | // normr - computed residual norm 35 | // normr0 - Original residual 36 | // times - array of timing information 37 | // doPreconditioning - bool to specify whether or not symmetric GS will be applied. 38 | 39 | #endif // CG_HPP 40 | -------------------------------------------------------------------------------- /src/CG_ref.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #ifndef CG_REF_HPP 16 | #define CG_REF_HPP 17 | 18 | #include "SparseMatrix.hpp" 19 | #include "Vector.hpp" 20 | #include "CGData.hpp" 21 | 22 | int CG_ref(const SparseMatrix & A, CGData & data, const Vector & b, Vector & x, 23 | const int max_iter, const double tolerance, int & niters, double & normr, double & normr0, 24 | double * times, bool doPreconditioning); 25 | 26 | // this function will compute the Conjugate Gradient iterations. 27 | // geom - Domain and processor topology information 28 | // A - Matrix 29 | // b - constant 30 | // x - used for return value 31 | // max_iter - how many times we iterate 32 | // tolerance - Stopping tolerance for preconditioned iterations. 33 | // niters - number of iterations performed 34 | // normr - computed residual norm 35 | // normr0 - Original residual 36 | // times - array of timing information 37 | // doPreconditioning - bool to specify whether or not symmetric GS will be applied. 38 | 39 | #endif // CG_REF_HPP 40 | -------------------------------------------------------------------------------- /src/ComputeSPMV.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeSPMV.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include "ComputeSPMV.hpp" 22 | #include "ComputeSPMV_ref.hpp" 23 | 24 | /*! 25 | Routine to compute sparse matrix vector product y = Ax where: 26 | Precondition: First call exchange_externals to get off-processor values of x 27 | 28 | This routine calls the reference SpMV implementation by default, but 29 | can be replaced by a custom, optimized routine suited for 30 | the target system. 31 | 32 | @param[in] A the known system matrix 33 | @param[in] x the known vector 34 | @param[out] y the On exit contains the result: Ax. 35 | 36 | @return returns 0 upon success and non-zero otherwise 37 | 38 | @see ComputeSPMV_ref 39 | */ 40 | int ComputeSPMV( const SparseMatrix & A, Vector & x, Vector & y) { 41 | 42 | // This line and the next two lines should be removed and your version of ComputeSPMV should be used. 43 | A.isSpmvOptimized = false; 44 | return ComputeSPMV_ref(A, x, y); 45 | } 46 | -------------------------------------------------------------------------------- /tools/replace_header.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | """ 4 | Script to test and replace header in all source and header files. 5 | 6 | Typical invocation: 7 | 8 | python tools/replace_header.py src/*.[hc]pp testing/*.cpp 9 | """ 10 | 11 | import sha 12 | 13 | HEADER = """//@HEADER 14 | // *************************************************** 15 | // 16 | // HPCG: High Performance Conjugate Gradient Benchmark 17 | // 18 | // Contact: 19 | // Michael A. Heroux ( maherou@sandia.gov) 20 | // Jack Dongarra (dongarra@eecs.utk.edu) 21 | // Piotr Luszczek (luszczek@eecs.utk.edu) 22 | // 23 | // *************************************************** 24 | //@HEADER""" 25 | 26 | def replace_header(filename): 27 | global HEADER 28 | 29 | comment = "//@HEADER" 30 | 31 | fobj = open(filename) 32 | data = fobj.read() 33 | fobj.close() 34 | 35 | begin_idx = data.find(comment) 36 | end_idx = data.find(comment, begin_idx+1) + len(comment) 37 | print begin_idx, end_idx-begin_idx, sha.sha(data[begin_idx:end_idx]).hexdigest(), filename 38 | 39 | if data[begin_idx:end_idx] != HEADER: 40 | fobj = open(filename, "w") 41 | fobj.write(data[:begin_idx] + HEADER + data[end_idx:]) 42 | fobj.close() 43 | 44 | def main(argv): 45 | for filename in argv[1:]: 46 | replace_header(filename) 47 | return 0 48 | 49 | if "__main__" == __name__: 50 | import sys 51 | sys.exit(main(sys.argv)) 52 | -------------------------------------------------------------------------------- /src/CheckAspectRatio.cpp: -------------------------------------------------------------------------------- 1 | //@HEADER 2 | // *************************************************** 3 | // 4 | // HPCG: High Performance Conjugate Gradient Benchmark 5 | // 6 | // Contact: 7 | // Michael A. Heroux ( maherou@sandia.gov) 8 | // Jack Dongarra (dongarra@eecs.utk.edu) 9 | // Piotr Luszczek (luszczek@eecs.utk.edu) 10 | // 11 | // *************************************************** 12 | //@HEADER 13 | 14 | /*! 15 | @file CheckAspectRatio.cpp 16 | 17 | HPCG routine 18 | */ 19 | 20 | #include 21 | 22 | #ifndef HPCG_NO_MPI 23 | #include 24 | #endif 25 | 26 | #include "hpcg.hpp" 27 | 28 | #include "CheckAspectRatio.hpp" 29 | 30 | int 31 | CheckAspectRatio(double smallest_ratio, int x, int y, int z, const char *what, bool DoIo) { 32 | double current_ratio = std::min(std::min(x, y), z) / double(std::max(std::max(x, y), z)); 33 | 34 | if (current_ratio < smallest_ratio) { // ratio of the smallest to the largest 35 | if (DoIo) { 36 | HPCG_fout << "The " << what << " sizes (" << x << "," << y << "," << z << 37 | ") are invalid because the ratio min(x,y,z)/max(x,y,z)=" << current_ratio << 38 | " is too small (at least " << smallest_ratio << " is required)." << std::endl; 39 | HPCG_fout << "The shape should resemble a 3D cube. Please adjust and try again." << std::endl; 40 | HPCG_fout.flush(); 41 | } 42 | 43 | #ifndef HPCG_NO_MPI 44 | MPI_Abort(MPI_COMM_WORLD, 127); 45 | #endif 46 | 47 | return 127; 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /src/MixedBaseCounter.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "MixedBaseCounter.hpp" 5 | 6 | MixedBaseCounter::MixedBaseCounter(int *counts, int length) { 7 | this->length = length; 8 | 9 | int i; 10 | 11 | for (i = 0; i < 32; ++i) { 12 | this->max_counts[i] = counts[i]; 13 | this->cur_counts[i] = 0; 14 | } 15 | // terminate with 0's 16 | this->max_counts[i] = this->cur_counts[i] = 0; 17 | this->max_counts[length] = this->cur_counts[length] = 0; 18 | } 19 | 20 | MixedBaseCounter::MixedBaseCounter(MixedBaseCounter & left, MixedBaseCounter & right) { 21 | this->length = left.length; 22 | for (int i = 0; i < left.length; ++i) { 23 | this->max_counts[i] = left.max_counts[i] - right.cur_counts[i]; 24 | this->cur_counts[i] = 0; 25 | } 26 | } 27 | 28 | void 29 | MixedBaseCounter::next() { 30 | for (int i = 0; i < this->length; ++i) { 31 | this->cur_counts[i]++; 32 | if (this->cur_counts[i] > this->max_counts[i]) { 33 | this->cur_counts[i] = 0; 34 | continue; 35 | } 36 | break; 37 | } 38 | } 39 | 40 | int 41 | MixedBaseCounter::is_zero() { 42 | for (int i = 0; i < this->length; ++i) 43 | if (this->cur_counts[i]) 44 | return 0; 45 | return 1; 46 | } 47 | 48 | int 49 | MixedBaseCounter::product(int * multipliers) { 50 | int k=0, x=1; 51 | 52 | for (int i = 0; i < this->length; ++i) 53 | for (int j = 0; j < this->cur_counts[i]; ++j) { 54 | k = 1; 55 | x *= multipliers[i]; 56 | } 57 | 58 | return x * k; 59 | } 60 | -------------------------------------------------------------------------------- /src/TestNorms.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file TestNorms.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include 22 | #include "TestNorms.hpp" 23 | 24 | /*! 25 | Computes the mean and standard deviation of the array of norm results. 26 | 27 | @param[in] testnorms_data data structure with the results of norm test 28 | 29 | @return Returns 0 upon success or non-zero otherwise 30 | */ 31 | int TestNorms(TestNormsData & testnorms_data) { 32 | double mean_delta = 0.0; 33 | for (int i= 0; i 25 | 26 | double mytimer(void) { 27 | return MPI_Wtime(); 28 | } 29 | 30 | #elif !defined(HPCG_NO_OPENMP) 31 | 32 | // If this routine is compiled with HPCG_NO_MPI defined and not compiled with HPCG_NO_OPENMP then use the OpenMP timer 33 | #include 34 | double mytimer(void) { 35 | return omp_get_wtime(); 36 | } 37 | #else 38 | 39 | #include 40 | #include 41 | #include 42 | double mytimer(void) { 43 | struct timeval tp; 44 | static long start=0, startu; 45 | if (!start) { 46 | gettimeofday(&tp, NULL); 47 | start = tp.tv_sec; 48 | startu = tp.tv_usec; 49 | return 0.0; 50 | } 51 | gettimeofday(&tp, NULL); 52 | return ((double) (tp.tv_sec - start)) + (tp.tv_usec-startu)/1000000.0 ; 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /web/packages.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Packages'); 6 | $page->setNavIdentifier('packages'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2019, hpcg-benchmark 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of hpcg nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /unittesting/Geometry/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // ************************************************************************ 4 | // 5 | // HPCG: Simple Conjugate Gradient Benchmark Code 6 | // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 7 | // 8 | // ************************************************************************ 9 | //@HEADER 10 | 11 | /*! 12 | @file main.cpp 13 | 14 | */ 15 | 16 | #include 17 | #include "GenerateGeometry.hpp" 18 | //#include "hpcg.hpp" 19 | int main(int argc, char * argv[]) { 20 | /* 21 | HPCG_Params params; 22 | 23 | HPCG_Init(&argc, &argv, params); 24 | 25 | int size = params.comm_size, rank = params.comm_rank; // Number of MPI processes, My process ID 26 | 27 | 28 | local_int_t nx,ny,nz; 29 | nx = (local_int_t)params.nx; 30 | ny = (local_int_t)params.ny; 31 | nz = (local_int_t)params.nz; 32 | int ierr = 0; // Used to check return codes on function calls 33 | */ 34 | 35 | // Construct the geometry and linear system 36 | Geometry geom; 37 | int size = 2048; 38 | int rank = 2047; 39 | int numThreads = 1; 40 | int nx, ny, nz; 41 | nx = ny = nz = 200; 42 | GenerateGeometry(size, rank, numThreads, nx, ny, nz, geom); 43 | 44 | global_int_t index = ((global_int_t) (nx * ny * nz)) * size - 1; 45 | std::cout << "Global Index = " << index << std::endl; 46 | int owningRank = ComputeRankOfMatrixRow(geom, index); 47 | std::cout << "Owning rank should be " << size - 1 << ". Computed to be " << owningRank << "." << std::endl; 48 | 49 | 50 | //HPCG_Finalize(); 51 | 52 | return 0 ; 53 | } 54 | -------------------------------------------------------------------------------- /index.doc: -------------------------------------------------------------------------------- 1 | /*! \mainpage HPCG: High Performance Conjugate Gradients Benchmark 2 | 3 | \section HPCG_outline Outline 4 | 5 |
    6 |
  • \ref HPCG_intro 7 |
  • \ref HPCG_startup 8 |
      9 |
    • \ref HPCG_quickstart 10 |
    • \ref HPCG_readme 11 |
    • \ref HPCG_installation 12 |
    • \ref HPCG_tuning 13 |
    14 |
  • \ref HPCG_details 15 |
      16 |
    • \ref HPCG_history 17 |
    • \ref HPCG_bugs 18 |
    • \ref HPCG_todo 19 |
    • \ref HPCG_copyright 20 |
    21 |
22 | 23 | \section HPCG_intro Introduction 24 | HPCG is a self-contained benchmark that generates and solves a synthetic 3D sparse linear system 25 | using a multigrid preconditioned (with local symmetric Gauss-Seidel smoother) conjugate gradients method. 26 | 27 | \section HPCG_startup Getting started 28 | 29 | This content is found in the main directory of the HPCG distribution tar file. 30 | 31 | \subsection HPCG_quickstart Quick Start 32 | 33 | \verbinclude QUICKSTART 34 | 35 | \subsection HPCG_readme README file 36 | 37 | \verbinclude README 38 | 39 | \subsection HPCG_installation Installation Instructions 40 | 41 | \verbinclude INSTALL 42 | 43 | \subsection HPCG_tuning Tuning HPCG 44 | 45 | \verbinclude TUNING 46 | 47 | \section HPCG_details Details about HPCG 48 | 49 | \subsection HPCG_history Code History 50 | 51 | \verbinclude HISTORY 52 | 53 | \subsection HPCG_bugs Known Bugs 54 | 55 | \verbinclude BUGS 56 | 57 | \subsection HPCG_todo Next Project Efforts 58 | 59 | \verbinclude TODO 60 | 61 | \subsection HPCG_copyright Copyright Statement 62 | 63 | \verbinclude COPYRIGHT 64 | 65 | */ 66 | -------------------------------------------------------------------------------- /web/mail_lists.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Mail Lists'); 6 | $page->setNavIdentifier('resources'); 7 | 8 | $x = <<< END 9 | table.lists th { text-align: left; padding: .5em 2em .5em 0; 10 | border-bottom: 1px solid #999; } 11 | table.lists td { padding: .5em 2em .5em 0; border-bottom: 1px solid #999; } 12 | END; 13 | $page->setInlineStyles($x); 14 | 15 | ?> 16 | 17 | 18 | 19 | 20 | 21 |

HPCG maintains two main lists that are open to the public. The 22 | hpcg-announce list provides a convenient mechanism for distributing 23 | announcements from the development team to the user community. The hpcg-users 24 | list provides a discussion forum for users. 25 | 27 |

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
Announce list:subscribe
Users list:subscribe
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/ComputeRestriction_ref.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeRestriction_ref.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | 22 | #ifndef HPCG_NO_OPENMP 23 | #include 24 | #endif 25 | 26 | #include "ComputeRestriction_ref.hpp" 27 | 28 | /*! 29 | Routine to compute the coarse residual vector. 30 | 31 | @param[inout] A - Sparse matrix object containing pointers to mgData->Axf, the fine grid matrix-vector product and mgData->rc the coarse residual vector. 32 | @param[in] rf - Fine grid RHS. 33 | 34 | 35 | Note that the fine grid residual is never explicitly constructed. 36 | We only compute it for the fine grid points that will be injected into corresponding coarse grid points. 37 | 38 | @return Returns zero on success and a non-zero value otherwise. 39 | */ 40 | int ComputeRestriction_ref(const SparseMatrix & A, const Vector & rf) { 41 | 42 | double * Axfv = A.mgData->Axf->values; 43 | double * rfv = rf.values; 44 | double * rcv = A.mgData->rc->values; 45 | local_int_t * f2c = A.mgData->f2cOperator; 46 | local_int_t nc = A.mgData->rc->localLength; 47 | 48 | #ifndef HPCG_NO_OPENMP 49 | #pragma omp parallel for 50 | #endif 51 | for (local_int_t i=0; i 23 | #endif 24 | 25 | #include "ComputeProlongation_ref.hpp" 26 | 27 | /*! 28 | Routine to compute the coarse residual vector. 29 | 30 | @param[in] Af - Fine grid sparse matrix object containing pointers to current coarse grid correction and the f2c operator. 31 | @param[inout] xf - Fine grid solution vector, update with coarse grid correction. 32 | 33 | Note that the fine grid residual is never explicitly constructed. 34 | We only compute it for the fine grid points that will be injected into corresponding coarse grid points. 35 | 36 | @return Returns zero on success and a non-zero value otherwise. 37 | */ 38 | int ComputeProlongation_ref(const SparseMatrix & Af, Vector & xf) { 39 | 40 | double * xfv = xf.values; 41 | double * xcv = Af.mgData->xc->values; 42 | local_int_t * f2c = Af.mgData->f2cOperator; 43 | local_int_t nc = Af.mgData->rc->localLength; 44 | 45 | #ifndef HPCG_NO_OPENMP 46 | #pragma omp parallel for 47 | #endif 48 | // TODO: Somehow note that this loop can be safely vectorized since f2c has no repeated indices 49 | for (local_int_t i=0; i 23 | #endif 24 | 25 | #ifndef HPCG_NO_OPENMP 26 | #include 27 | #endif 28 | 29 | #include "GenerateProblem.hpp" 30 | #include "GenerateProblem_ref.hpp" 31 | 32 | 33 | /*! 34 | Routine to generate a sparse matrix, right hand side, initial guess, and exact solution. 35 | 36 | @param[in] A The generated system matrix 37 | @param[inout] b The newly allocated and generated right hand side vector (if b!=0 on entry) 38 | @param[inout] x The newly allocated solution vector with entries set to 0.0 (if x!=0 on entry) 39 | @param[inout] xexact The newly allocated solution vector with entries set to the exact solution (if the xexact!=0 non-zero on entry) 40 | 41 | @see GenerateGeometry 42 | */ 43 | 44 | void GenerateProblem(SparseMatrix & A, Vector * b, Vector * x, Vector * xexact) { 45 | 46 | // The call to this reference version of GenerateProblem can be replaced with custom code. 47 | // However, the data structures must remain unchanged such that the CheckProblem function is satisfied. 48 | // Furthermore, any code must work for general unstructured sparse matrices. Special knowledge about the 49 | // specific nature of the sparsity pattern may not be explicitly used. 50 | 51 | return(GenerateProblem_ref(A, b, x, xexact)); 52 | } 53 | -------------------------------------------------------------------------------- /src/CGData.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file CGData.hpp 17 | 18 | HPCG data structure 19 | */ 20 | 21 | #ifndef CGDATA_HPP 22 | #define CGDATA_HPP 23 | 24 | #include "SparseMatrix.hpp" 25 | #include "Vector.hpp" 26 | 27 | struct CGData_STRUCT { 28 | Vector r; //!< pointer to residual vector 29 | Vector z; //!< pointer to preconditioned residual vector 30 | Vector p; //!< pointer to direction vector 31 | Vector Ap; //!< pointer to Krylov vector 32 | }; 33 | typedef struct CGData_STRUCT CGData; 34 | 35 | /*! 36 | Constructor for the data structure of CG vectors. 37 | 38 | @param[in] A the data structure that describes the problem matrix and its structure 39 | @param[out] data the data structure for CG vectors that will be allocated to get it ready for use in CG iterations 40 | */ 41 | inline void InitializeSparseCGData(SparseMatrix & A, CGData & data) { 42 | local_int_t nrow = A.localNumberOfRows; 43 | local_int_t ncol = A.localNumberOfColumns; 44 | InitializeVector(data.r, nrow); 45 | InitializeVector(data.z, ncol); 46 | InitializeVector(data.p, ncol); 47 | InitializeVector(data.Ap, nrow); 48 | return; 49 | } 50 | 51 | /*! 52 | Destructor for the CG vectors data. 53 | 54 | @param[inout] data the CG vectors data structure whose storage is deallocated 55 | */ 56 | inline void DeleteCGData(CGData & data) { 57 | 58 | DeleteVector (data.r); 59 | DeleteVector (data.z); 60 | DeleteVector (data.p); 61 | DeleteVector (data.Ap); 62 | return; 63 | } 64 | 65 | #endif // CGDATA_HPP 66 | 67 | -------------------------------------------------------------------------------- /web/download.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Download'); 6 | $page->setNavIdentifier('download'); 7 | 8 | $y = <<< END 9 | th { text-align: left; padding-right: 1em; vertical-align: top; 10 | padding-bottom: 1em; } 11 | td { vertical-align: top; padding-bottom: 1em; } 12 | END; 13 | $page->setInlineStyles($y); 14 | 15 | ?> 16 | 17 | 18 | 19 | 20 | 21 |

HPCG Benchmark Release Version 2.4

22 | 23 |

The current HPCG Suite Release version is 2.4.

24 | 25 | 26 | HPCG: Reference Version 2.4 (3-Jun-2014) 27 | 28 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/hpcg.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file hpcg.hpp 17 | 18 | HPCG data structures and functions 19 | */ 20 | 21 | #ifndef HPCG_HPP 22 | #define HPCG_HPP 23 | 24 | #include 25 | #include "Geometry.hpp" 26 | 27 | extern std::ofstream HPCG_fout; 28 | 29 | struct HPCG_Params_STRUCT { 30 | int comm_size; //!< Number of MPI processes in MPI_COMM_WORLD 31 | int comm_rank; //!< This process' MPI rank in the range [0 to comm_size - 1] 32 | int numThreads; //!< This process' number of threads 33 | local_int_t nx; //!< Number of processes in x-direction of 3D process grid 34 | local_int_t ny; //!< Number of processes in y-direction of 3D process grid 35 | local_int_t nz; //!< Number of processes in z-direction of 3D process grid 36 | int runningTime; //!< Number of seconds to run the timed portion of the benchmark 37 | int npx; //!< Number of x-direction grid points for each local subdomain 38 | int npy; //!< Number of y-direction grid points for each local subdomain 39 | int npz; //!< Number of z-direction grid points for each local subdomain 40 | int pz; //!< Partition in the z processor dimension, default is npz 41 | local_int_t zl; //!< nz for processors in the z dimension with value less than pz 42 | local_int_t zu; //!< nz for processors in the z dimension with value greater than pz 43 | }; 44 | /*! 45 | HPCG_Params is a shorthand for HPCG_Params_STRUCT 46 | */ 47 | typedef HPCG_Params_STRUCT HPCG_Params; 48 | 49 | extern int HPCG_Init(int * argc_p, char ** *argv_p, HPCG_Params & params); 50 | extern int HPCG_Finalize(void); 51 | 52 | #endif // HPCG_HPP 53 | -------------------------------------------------------------------------------- /web/about.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - About'); 6 | $page->setNavIdentifier('about'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 |

About the HPCG Benchmark Project

14 | 15 |

The HPCG Benchmark project is an effort to create a more relevant metric for ranking HPC systems than the 16 | High Performance LINPACK (HPL) benchmark, that is currently used by the TOP500 benchmark. The computational and data 17 | access patterns of HPL are no longer driving computer system designs in directions that are beneficial 18 | to many important scalable applications. HPCG is designed to exercise computational and data access patterns that more 19 | closely match a broad set of important applications, and to give incentive to computer system designers to invest in 20 | capabilities that will have impact on the collective performance of these applications. 21 |

22 | 23 |

HPCG is a complete, stand-alone code that measures the performance of basic operations in a unified code: 24 | 25 |

    26 |
  • Sparse matrix-vector multiplication.
  • 27 |
  • Sparse triangular solve.
  • 28 |
  • Vector updates.
  • 29 |
  • Global dot products.
  • 30 |
  • Local symmetric Gauss-Seidel smoother.
  • 31 |
  • Driven by multigrid preconditioned conjugate gradient algorithm that exercises the key kernels on a nested set of coarse grids.
  • 32 |
  • Reference implementation is written in C++ with MPI and OpenMP support.
  • 33 |
34 |

35 | 36 |

HPCG Overview Papers

37 | 38 |

Toward a New Metric for Ranking High Performance Computing Systems

39 |

HPCG Technical Specification

40 | 41 | 42 |
43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | EXTRA_DIST = bin m4 setup tools unittesting web 3 | 4 | bin_PROGRAMS = xhpcg 5 | 6 | xhpcg_SOURCES = \ 7 | src/CG.cpp src/CGData.hpp src/CG.hpp src/CG_ref.cpp src/CG_ref.hpp \ 8 | src/CheckAspectRatio.cpp src/CheckAspectRatio.hpp src/CheckProblem.cpp \ 9 | src/CheckProblem.hpp src/ComputeDotProduct.cpp src/ComputeDotProduct.hpp \ 10 | src/ComputeDotProduct_ref.cpp src/ComputeDotProduct_ref.hpp src/ComputeMG.cpp \ 11 | src/ComputeMG.hpp src/ComputeMG_ref.cpp src/ComputeMG_ref.hpp \ 12 | src/ComputeOptimalShapeXYZ.cpp src/ComputeOptimalShapeXYZ.hpp \ 13 | src/ComputeProlongation_ref.cpp src/ComputeProlongation_ref.hpp \ 14 | src/ComputeResidual.cpp src/ComputeResidual.hpp src/ComputeRestriction_ref.cpp \ 15 | src/ComputeRestriction_ref.hpp src/ComputeSPMV.cpp src/ComputeSPMV.hpp \ 16 | src/ComputeSPMV_ref.cpp src/ComputeSPMV_ref.hpp src/ComputeSYMGS.cpp \ 17 | src/ComputeSYMGS.hpp src/ComputeSYMGS_ref.cpp src/ComputeSYMGS_ref.hpp \ 18 | src/ComputeWAXPBY.cpp src/ComputeWAXPBY.hpp src/ComputeWAXPBY_ref.cpp \ 19 | src/ComputeWAXPBY_ref.hpp src/ExchangeHalo.cpp src/ExchangeHalo.hpp \ 20 | src/finalize.cpp src/GenerateCoarseProblem.cpp src/GenerateCoarseProblem.hpp \ 21 | src/GenerateGeometry.cpp src/GenerateGeometry.hpp src/GenerateProblem.cpp \ 22 | src/GenerateProblem.hpp src/GenerateProblem_ref.cpp src/GenerateProblem_ref.hpp \ 23 | src/Geometry.hpp src/hpcgconfig.hpp.in src/hpcg.hpp src/init.cpp src/main.cpp \ 24 | src/MGData.hpp src/MixedBaseCounter.cpp src/MixedBaseCounter.hpp \ 25 | src/mytimer.cpp src/mytimer.hpp src/OptimizeProblem.cpp src/OptimizeProblem.hpp \ 26 | src/OutputFile.cpp src/OutputFile.hpp src/ReadHpcgDat.cpp src/ReadHpcgDat.hpp \ 27 | src/ReportResults.cpp src/ReportResults.hpp src/SetupHalo.cpp src/SetupHalo.hpp \ 28 | src/SetupHalo_ref.cpp src/SetupHalo_ref.hpp src/SparseMatrix.hpp src/TestCG.cpp \ 29 | src/TestCG.hpp src/TestNorms.cpp src/TestNorms.hpp src/TestSymmetry.cpp \ 30 | src/TestSymmetry.hpp src/Vector.hpp src/WriteProblem.cpp src/WriteProblem.hpp \ 31 | src/YAML_Doc.cpp src/YAML_Doc.hpp src/YAML_Element.cpp src/YAML_Element.hpp 32 | -------------------------------------------------------------------------------- /src/ComputeSPMV_ref.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeSPMV_ref.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include "ComputeSPMV_ref.hpp" 22 | 23 | #ifndef HPCG_NO_MPI 24 | #include "ExchangeHalo.hpp" 25 | #endif 26 | 27 | #ifndef HPCG_NO_OPENMP 28 | #include 29 | #endif 30 | #include 31 | 32 | /*! 33 | Routine to compute matrix vector product y = Ax where: 34 | Precondition: First call exchange_externals to get off-processor values of x 35 | 36 | This is the reference SPMV implementation. It CANNOT be modified for the 37 | purposes of this benchmark. 38 | 39 | @param[in] A the known system matrix 40 | @param[in] x the known vector 41 | @param[out] y the On exit contains the result: Ax. 42 | 43 | @return returns 0 upon success and non-zero otherwise 44 | 45 | @see ComputeSPMV 46 | */ 47 | int ComputeSPMV_ref( const SparseMatrix & A, Vector & x, Vector & y) { 48 | 49 | assert(x.localLength>=A.localNumberOfColumns); // Test vector lengths 50 | assert(y.localLength>=A.localNumberOfRows); 51 | 52 | #ifndef HPCG_NO_MPI 53 | ExchangeHalo(A,x); 54 | #endif 55 | const double * const xv = x.values; 56 | double * const yv = y.values; 57 | const local_int_t nrow = A.localNumberOfRows; 58 | #ifndef HPCG_NO_OPENMP 59 | #pragma omp parallel for 60 | #endif 61 | for (local_int_t i=0; i< nrow; i++) { 62 | double sum = 0.0; 63 | const double * const cur_vals = A.matrixValues[i]; 64 | const local_int_t * const cur_inds = A.mtxIndL[i]; 65 | const int cur_nnz = A.nonzerosInRow[i]; 66 | 67 | for (int j=0; j< cur_nnz; j++) 68 | sum += cur_vals[j]*xv[cur_inds[j]]; 69 | yv[i] = sum; 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /TUNING: -------------------------------------------------------------------------------- 1 | ============================================================== 2 | Performance tuning and setting up the input data file hpcg.dat 3 | ============================================================== 4 | 5 | Current as of release HPCG - 3.1 - March 11, 2019 6 | 7 | Check the website http://hpcg-benchmark.org/ for the latest 8 | information. 9 | 10 | After building the executable hpcg_build/bin/xhpcg, (where hpcg_build is your 11 | build directory for HPCG) one may want to modify the 12 | input data file hpcg.dat. This file should reside in the same directory 13 | as the executable hpcg_build/bin/xhpcg. An example hpcg.dat file is provided 14 | by default. This file contains information about the problem sizes, 15 | machine configuration, and algorithm features to be used by the executable. 16 | It is 4 lines long. All the selected parameters will be printed in the 17 | output generated by the executable. 18 | 19 | ================================ 20 | Description of the hpcg.dat file 21 | ================================ 22 | 23 | * Line 1: (unused) Typically one would use this line for its own good. For 24 | example, it could be used to summarize the con- tent of the input file. By 25 | default this line reads: 26 | 27 | HPCG benchmark input file 28 | 29 | * Line 2: (unused) same as Line 1. By default, this line reads: 30 | 31 | Sandia National Laboratories; University of Tennessee, Knoxville 32 | 33 | * Line 3: This line specifies the local (to an MPI process) dimensions of the 34 | problem. By default, this line reads: 35 | 36 | 104 104 104 37 | 38 | which means that each MPI process will be computing a solution for a cube of 39 | size 104 points. 40 | 41 | * Line 4: This line specifies the number of seconds of how long the timed 42 | portion of the benchmark should run. By default, this line reads: 43 | 44 | 60 45 | 46 | which means that the timed portion of the benchmark will run 1 minute. 47 | This length of time is not sufficient for submitting an official run 48 | but does give sufficient data for tuning the benchmark in most cases. 49 | -------------------------------------------------------------------------------- /web/common/page.php: -------------------------------------------------------------------------------- 1 | pathToWebRoot = $pathToWebRoot; } 18 | 19 | function setPageTitle($pageTitle) { 20 | $this->pageTitle = $pageTitle; } 21 | 22 | function setPageIdentifier($pageIdentifier) { 23 | $this->pageIdentifier = $pageIdentifier; } 24 | 25 | function setNavIdentifier($navIdentifier) { 26 | $this->navIdentifier = $navIdentifier; } 27 | 28 | function setStyleSheet($styleSheet) { 29 | $this->styleSheet= $styleSheet; } 30 | 31 | function setInlineStyles($inlineStyles) { 32 | $this->inlineStyles = $inlineStyles; } 33 | 34 | function setInlineScripts($inlineScripts) { 35 | $this->inlineScripts = $inlineScripts; } 36 | 37 | function setBodyAttributes($bodyAttributes) { 38 | $this->bodyAttributes = $bodyAttributes; } 39 | 40 | # get functions 41 | function getPathToWebRoot() { 42 | return $this->pathToWebRoot; } 43 | 44 | function getPageTitle() { 45 | return $this->pageTitle; } 46 | 47 | function getPageIdentifier() { 48 | return $this->pageIdentifier; 49 | } 50 | 51 | function getNavIdentifier() { 52 | return $this->navIdentifier; 53 | } 54 | 55 | function getNav() { 56 | $navString = $this->getPathToWebRoot(); 57 | $navString .= 'common/nav_'; 58 | $navString .= $this->navIdentifier; 59 | $navString .= '.html'; 60 | return $navString; 61 | } 62 | 63 | function getStyleSheet() { 64 | return $this->styleSheet; } 65 | 66 | function getInlineStyles() { 67 | return $this->inlineStyles; } 68 | 69 | function getInlineScripts() { 70 | return $this->inlineScripts; } 71 | 72 | function getBodyAttributes() { 73 | return $this->bodyAttributes; } 74 | 75 | } # Page 76 | 77 | ?> 78 | 79 | -------------------------------------------------------------------------------- /src/ComputeWAXPBY_ref.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeWAXPBY_ref.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include "ComputeWAXPBY_ref.hpp" 22 | #ifndef HPCG_NO_OPENMP 23 | #include 24 | #endif 25 | #include 26 | /*! 27 | Routine to compute the update of a vector with the sum of two 28 | scaled vectors where: w = alpha*x + beta*y 29 | 30 | This is the reference WAXPBY impmentation. It CANNOT be modified for the 31 | purposes of this benchmark. 32 | 33 | @param[in] n the number of vector elements (on this processor) 34 | @param[in] alpha, beta the scalars applied to x and y respectively. 35 | @param[in] x, y the input vectors 36 | @param[out] w the output vector. 37 | 38 | @return returns 0 upon success and non-zero otherwise 39 | 40 | @see ComputeWAXPBY 41 | */ 42 | int ComputeWAXPBY_ref(const local_int_t n, const double alpha, const Vector & x, 43 | const double beta, const Vector & y, Vector & w) { 44 | 45 | assert(x.localLength>=n); // Test vector lengths 46 | assert(y.localLength>=n); 47 | 48 | const double * const xv = x.values; 49 | const double * const yv = y.values; 50 | double * const wv = w.values; 51 | 52 | if (alpha==1.0) { 53 | #ifndef HPCG_NO_OPENMP 54 | #pragma omp parallel for 55 | #endif 56 | for (local_int_t i=0; i 16 | 17 | #include "ReadHpcgDat.hpp" 18 | 19 | static int 20 | SkipUntilEol(FILE *stream) { 21 | int chOrEof; 22 | bool finished; 23 | 24 | do { 25 | chOrEof = fgetc( stream ); 26 | finished = (chOrEof == EOF) || (chOrEof == '\n') || (chOrEof == '\r'); 27 | } while (! finished); 28 | 29 | if ('\r' == chOrEof) { // on Windows, \r might be followed by \n 30 | int chOrEofExtra = fgetc( stream ); 31 | 32 | if ('\n' == chOrEofExtra || EOF == chOrEofExtra) 33 | chOrEof = chOrEofExtra; 34 | else 35 | ungetc(chOrEofExtra, stream); 36 | } 37 | 38 | return chOrEof; 39 | } 40 | 41 | int 42 | ReadHpcgDat(int *localDimensions, int *secondsPerRun, int *localProcDimensions) { 43 | FILE * hpcgStream = fopen("hpcg.dat", "r"); 44 | 45 | if (! hpcgStream) 46 | return -1; 47 | 48 | SkipUntilEol(hpcgStream); // skip the first line 49 | 50 | SkipUntilEol(hpcgStream); // skip the second line 51 | 52 | for (int i = 0; i < 3; ++i) 53 | if (fscanf(hpcgStream, "%d", localDimensions+i) != 1 || localDimensions[i] < 16) 54 | localDimensions[i] = 16; 55 | 56 | SkipUntilEol( hpcgStream ); // skip the rest of the second line 57 | 58 | if (secondsPerRun!=0) { // Only read number of seconds if the pointer is non-zero 59 | if (fscanf(hpcgStream, "%d", secondsPerRun) != 1 || secondsPerRun[0] < 0) 60 | secondsPerRun[0] = 30 * 60; // 30 minutes 61 | } 62 | 63 | SkipUntilEol( hpcgStream ); // skip the rest of the third line 64 | 65 | for (int i = 0; i < 3; ++i) 66 | // the user didn't specify (or values are invalid) process dimensions 67 | if (fscanf(hpcgStream, "%d", localProcDimensions+i) != 1 || localProcDimensions[i] < 1) 68 | localProcDimensions[i] = 0; // value 0 means: "not specified" and it will be fixed later 69 | 70 | fclose(hpcgStream); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /src/ComputeMG_ref.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeSYMGS_ref.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include "ComputeMG_ref.hpp" 22 | #include "ComputeSYMGS_ref.hpp" 23 | #include "ComputeSPMV_ref.hpp" 24 | #include "ComputeRestriction_ref.hpp" 25 | #include "ComputeProlongation_ref.hpp" 26 | #include 27 | #include 28 | 29 | /*! 30 | 31 | @param[in] A the known system matrix 32 | @param[in] r the input vector 33 | @param[inout] x On exit contains the result of the multigrid V-cycle with r as the RHS, x is the approximation to Ax = r. 34 | 35 | @return returns 0 upon success and non-zero otherwise 36 | 37 | @see ComputeMG 38 | */ 39 | int ComputeMG_ref(const SparseMatrix & A, const Vector & r, Vector & x) { 40 | assert(x.localLength==A.localNumberOfColumns); // Make sure x contain space for halo values 41 | 42 | ZeroVector(x); // initialize x to zero 43 | 44 | int ierr = 0; 45 | if (A.mgData!=0) { // Go to next coarse level if defined 46 | int numberOfPresmootherSteps = A.mgData->numberOfPresmootherSteps; 47 | for (int i=0; i< numberOfPresmootherSteps; ++i) ierr += ComputeSYMGS_ref(A, r, x); 48 | if (ierr!=0) return ierr; 49 | ierr = ComputeSPMV_ref(A, x, *A.mgData->Axf); if (ierr!=0) return ierr; 50 | // Perform restriction operation using simple injection 51 | ierr = ComputeRestriction_ref(A, r); if (ierr!=0) return ierr; 52 | ierr = ComputeMG_ref(*A.Ac,*A.mgData->rc, *A.mgData->xc); if (ierr!=0) return ierr; 53 | ierr = ComputeProlongation_ref(A, x); if (ierr!=0) return ierr; 54 | int numberOfPostsmootherSteps = A.mgData->numberOfPostsmootherSteps; 55 | for (int i=0; i< numberOfPostsmootherSteps; ++i) ierr += ComputeSYMGS_ref(A, r, x); 56 | if (ierr!=0) return ierr; 57 | } 58 | else { 59 | ierr = ComputeSYMGS_ref(A, r, x); 60 | if (ierr!=0) return ierr; 61 | } 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /web/news.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - News'); 6 | $page->setNavIdentifier('home'); 7 | 8 | $y = <<< END 9 | div#contentMain li { padding-bottom: 1em; } 10 | END; 11 | $page->setInlineStyles($y); 12 | 13 | ?> 14 | 15 | 16 | 17 | 18 | 19 | Thursday, June 26th, 2014 - First list of HPCG ranking results released. 20 |

21 | 22 | Monday, June 3nd, 2014 - HPCG Benchmark Release 2.4 fixes a floating point operation count issue that persisted from Release 2.2. 23 | Release 2.3 is available for download. See the release notes for more information.

24 | 25 | Monday, June 2nd, 2014 - HPCG Benchmark Release 2.3 fixes a floating point operation count issue in Release 2.2. 26 | Release 2.3 is available for download. See the release notes for more information.

27 | 28 | Wednesday, May 27th, 2014 - HPCG Benchmark Release 2.2, with 29 | reduced penalty for optimization overhead cost, is now available for download. See the release notes for more information.

30 | 31 | Friday, January 31st, 2014 - HPCG Benchmark Release 2.1, the 32 | first Multigrid preconditioned version of HPCG , is now available for download. See the release notes for more information.

33 | 34 | Tuesday, November 26th, 2013 - HPCG Benchmark Release 1.1, the 35 | first update release of the HPCG Suite, is now available for download. See the release notes for more information.

36 | 37 | Monday, November 19th, 2013 - HPCG Benchmark Release 1.0, the 38 | first release of the HPCG Suite, is now available for download. See the release notes for more information.

39 | 40 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /src/MGData.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file MGData.hpp 17 | 18 | HPCG data structure 19 | */ 20 | 21 | #ifndef MGDATA_HPP 22 | #define MGDATA_HPP 23 | 24 | #include 25 | #include "SparseMatrix.hpp" 26 | #include "Vector.hpp" 27 | 28 | struct MGData_STRUCT { 29 | int numberOfPresmootherSteps; // Call ComputeSYMGS this many times prior to coarsening 30 | int numberOfPostsmootherSteps; // Call ComputeSYMGS this many times after coarsening 31 | local_int_t * f2cOperator; //!< 1D array containing the fine operator local IDs that will be injected into coarse space. 32 | Vector * rc; // coarse grid residual vector 33 | Vector * xc; // coarse grid solution vector 34 | Vector * Axf; // fine grid residual vector 35 | /*! 36 | This is for storing optimized data structres created in OptimizeProblem and 37 | used inside optimized ComputeSPMV(). 38 | */ 39 | void * optimizationData; 40 | }; 41 | typedef struct MGData_STRUCT MGData; 42 | 43 | /*! 44 | Constructor for the data structure of CG vectors. 45 | 46 | @param[in] Ac - Fully-formed coarse matrix 47 | @param[in] f2cOperator - 48 | @param[out] data the data structure for CG vectors that will be allocated to get it ready for use in CG iterations 49 | */ 50 | inline void InitializeMGData(local_int_t * f2cOperator, Vector * rc, Vector * xc, Vector * Axf, MGData & data) { 51 | data.numberOfPresmootherSteps = 1; 52 | data.numberOfPostsmootherSteps = 1; 53 | data.f2cOperator = f2cOperator; // Space for injection operator 54 | data.rc = rc; 55 | data.xc = xc; 56 | data.Axf = Axf; 57 | return; 58 | } 59 | 60 | /*! 61 | Destructor for the CG vectors data. 62 | 63 | @param[inout] data the MG data structure whose storage is deallocated 64 | */ 65 | inline void DeleteMGData(MGData & data) { 66 | 67 | delete [] data.f2cOperator; 68 | DeleteVector(*data.Axf); 69 | DeleteVector(*data.rc); 70 | DeleteVector(*data.xc); 71 | delete data.Axf; 72 | delete data.rc; 73 | delete data.xc; 74 | return; 75 | } 76 | 77 | #endif // MGDATA_HPP 78 | 79 | -------------------------------------------------------------------------------- /src/ComputeDotProduct_ref.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeDotProduct_ref.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #ifndef HPCG_NO_MPI 22 | #include 23 | #include "mytimer.hpp" 24 | #endif 25 | #ifndef HPCG_NO_OPENMP 26 | #include 27 | #endif 28 | #include 29 | #include "ComputeDotProduct_ref.hpp" 30 | 31 | /*! 32 | Routine to compute the dot product of two vectors where: 33 | 34 | This is the reference dot-product implementation. It _CANNOT_ be modified for the 35 | purposes of this benchmark. 36 | 37 | @param[in] n the number of vector elements (on this processor) 38 | @param[in] x, y the input vectors 39 | @param[in] result a pointer to scalar value, on exit will contain result. 40 | @param[out] time_allreduce the time it took to perform the communication between processes 41 | 42 | @return returns 0 upon success and non-zero otherwise 43 | 44 | @see ComputeDotProduct 45 | */ 46 | int ComputeDotProduct_ref(const local_int_t n, const Vector & x, const Vector & y, 47 | double & result, double & time_allreduce) { 48 | assert(x.localLength>=n); // Test vector lengths 49 | assert(y.localLength>=n); 50 | 51 | double local_result = 0.0; 52 | double * xv = x.values; 53 | double * yv = y.values; 54 | if (yv==xv) { 55 | #ifndef HPCG_NO_OPENMP 56 | #pragma omp parallel for reduction (+:local_result) 57 | #endif 58 | for (local_int_t i=0; isetPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - Release Notes'); 6 | $page->setNavIdentifier('download'); 7 | 8 | $y = <<< END 9 | h2 { padding-top: 2em; } 10 | END; 11 | $page->setInlineStyles($y); 12 | 13 | ?> 14 | 15 | 16 | 17 | 18 | 19 |

HPCG Benchmark Release 2.4

20 | 21 |

Release 2.4 fixes a flop count error introduced in Release 2.2 and not completely resolved in Release 2.3.

22 | 23 |

HPCG Benchmark Release 2.3

24 | 25 |

Release 2.3 fixes a flop count error introduced in Release 2.2.

26 | 27 |

HPCG Benchmark Release 2.2

28 | 29 |

Release 2.2 reduces the penalty for optimization overhead costs by a factor of 10. It also contain several minor bugfixes.

30 | 31 |

HPCG Benchmark Release 2.1

32 | 33 |

HPCG 2.0/2.1 provides the first implementation of a multigrid preconditioner for the conjugate gradient method. 34 |

    35 |
  • HPCG 2.0/2.1replaces the additive Schwarz preconditioner with a synthetic multigrid approach.
  • 36 |
  • The number of coarse grid levels is parametrized but fixed for production benchmark runs (presently set to 3 levels of coarsening).
  • 37 |
  • We use injection as the grid transfer operator and symmetric Gauss-Seidel as the pre and post smoother.
  • 38 |
  • All kernels from HPCG 1.1 remain important and no new kernels were added. 39 |
  • The biggest impact of the multigrid preconditioner is that all computation and communication kernels will execute on 40 | a nested sequence of coarse grids where each grid level is 8 times smaller than the previous level.
  • 41 |
  • Every attempt was made to assure that the kernels are not unnecessarily different between HPCG 1.1 and HPCG 2.0.
  • 42 |
  • Even so, some changes were necessary to supported the nested hierarchy.
  • 43 |
  • We did not implement a true multigrid preconditioner. In particular, we do not have a "bottom" solver for the coarsest grid.
  • 44 |
  • We also added a Vector struct to facility easier implementation of kernels on discrete devices such as GPUs.
  • 45 |

    46 | 47 |

    HPCG Benchmark Release 1.1

    48 | 49 |

    This is the first update release of HPCG. See HISTORY file for more detailed list of changes.

    50 | 51 |

    HPCG Benchmark Release 1.0

    52 | 53 |

    This is the first official release of HPCG for general public access.

    54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /tools/mtxdmp.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "CheckAspectRatio.hpp" 3 | #include "GenerateGeometry.hpp" 4 | #include "GenerateProblem.hpp" 5 | #include "GenerateCoarseProblem.hpp" 6 | #include "SetupHalo.hpp" 7 | #include "CheckProblem.hpp" 8 | #include "ExchangeHalo.hpp" 9 | #include "OptimizeProblem.hpp" 10 | #include "WriteProblem.hpp" 11 | #include "ReportResults.hpp" 12 | #include "mytimer.hpp" 13 | #include "ComputeSPMV_ref.hpp" 14 | #include "ComputeMG_ref.hpp" 15 | #include "ComputeResidual.hpp" 16 | #include "CG.hpp" 17 | #include "CG_ref.hpp" 18 | #include "Geometry.hpp" 19 | #include "SparseMatrix.hpp" 20 | #include "Vector.hpp" 21 | #include "CGData.hpp" 22 | #include "TestCG.hpp" 23 | #include "TestSymmetry.hpp" 24 | #include "TestNorms.hpp" 25 | 26 | #if 0 27 | int main(int argc, char * argv[]) { 28 | int size =1, rank=0; 29 | HPCG_Params params; 30 | Geometry * geom = new Geometry; 31 | GenerateGeometry(size, rank, params.numThreads, params.pz, params.zl, params.zu, nx, ny, nz, params.npx, params.npy, params.npz, geom); 32 | SparseMatrix A; 33 | InitializeSparseMatrix(A, geom); 34 | GenerateProblem(A, &b, &x, &xexact); 35 | return 0; 36 | } 37 | #endif 38 | 39 | void SetupHalo(SparseMatrix & A) { 40 | printf("nx=%ld;\n",(long)A.geom->nx); 41 | printf("ny=%ld;\n",(long)A.geom->ny); 42 | printf("nz=%ld;\n",(long)A.geom->nz); 43 | printf("gnx=%ld;\n",(long)A.geom->gnx); 44 | printf("gny=%ld;\n",(long)A.geom->gny); 45 | printf("gnz=%ld;\n",(long)A.geom->gnz); 46 | 47 | printf("totalNumberOfRows=%ld;\n",(long)A.totalNumberOfRows); 48 | printf("totalNumberOfNonzeros=%ld;\n",(long)A.totalNumberOfNonzeros); 49 | printf("localNumberOfRows=%ld;\n",(long)A.localNumberOfRows); 50 | printf("localNumberOfColumns=%ld;\n",(long)A.localNumberOfColumns); 51 | printf("localNumberOfNonzeros=%ld;\n",(long)A.localNumberOfNonzeros); 52 | printf("nonzerosInRow=%ld;\n",(long)A.nonzerosInRow[0]); 53 | 54 | local_int_t numberOfNonzerosPerRow = 27; // We are approximating a 27-point finite element/volume/difference 3D stencil 55 | printf("a=zeros(%ld,%ld);\n", (long)A.localNumberOfRows, (long)A.localNumberOfRows); 56 | for (local_int_t j=0; j< A.localNumberOfRows; ++j) { 57 | printf("idx=["); 58 | char ch=' '; 59 | for (local_int_t i=0; i< numberOfNonzerosPerRow; ++i) 60 | if (A.mtxIndG[j][i]) { 61 | printf("%c%ld", ch, (long)(A.mtxIndG[j][i]+1) ); 62 | ch = ';'; 63 | } 64 | printf("];\nfor i = 1:size(idx,1)\na(%ld,idx(i))=-1;\nend\n", (long)(j+1)); 65 | } 66 | printf("for i=1:%ld\na(i,i)=26;\nend\n", (long)A.localNumberOfRows); 67 | printf("spy(sparse(a));\n"); 68 | 69 | exit(0); 70 | } 71 | -------------------------------------------------------------------------------- /src/ComputeResidual.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeResidual.cpp 17 | 18 | HPCG routine 19 | */ 20 | #ifndef HPCG_NO_MPI 21 | #include 22 | #endif 23 | #ifndef HPCG_NO_OPENMP 24 | #include 25 | #endif 26 | 27 | #include "Vector.hpp" 28 | 29 | #ifdef HPCG_DETAILED_DEBUG 30 | #include 31 | #include "hpcg.hpp" 32 | #endif 33 | 34 | #include // needed for fabs 35 | #include "ComputeResidual.hpp" 36 | #ifdef HPCG_DETAILED_DEBUG 37 | #include 38 | #endif 39 | 40 | /*! 41 | Routine to compute the inf-norm difference between two vectors where: 42 | 43 | @param[in] n number of vector elements (local to this processor) 44 | @param[in] v1, v2 input vectors 45 | @param[out] residual pointer to scalar value; on exit, will contain result: inf-norm difference 46 | 47 | @return Returns zero on success and a non-zero value otherwise. 48 | */ 49 | int ComputeResidual(const local_int_t n, const Vector & v1, const Vector & v2, double & residual) { 50 | 51 | double * v1v = v1.values; 52 | double * v2v = v2.values; 53 | double local_residual = 0.0; 54 | 55 | #ifndef HPCG_NO_OPENMP 56 | #pragma omp parallel shared(local_residual, v1v, v2v, n) 57 | { 58 | double threadlocal_residual = 0.0; 59 | #pragma omp for 60 | for (local_int_t i=0; i threadlocal_residual) threadlocal_residual = diff; 63 | } 64 | #pragma omp critical 65 | { 66 | if (threadlocal_residual>local_residual) local_residual = threadlocal_residual; 67 | } 68 | } 69 | #else // No threading 70 | for (local_int_t i=0; i local_residual) local_residual = diff; 73 | #ifdef HPCG_DETAILED_DEBUG 74 | HPCG_fout << " Computed, exact, diff = " << v1v[i] << " " << v2v[i] << " " << diff << std::endl; 75 | #endif 76 | } 77 | #endif 78 | 79 | #ifndef HPCG_NO_MPI 80 | // Use MPI's reduce function to collect all partial sums 81 | double global_residual = 0; 82 | MPI_Allreduce(&local_residual, &global_residual, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); 83 | residual = global_residual; 84 | #else 85 | residual = local_residual; 86 | #endif 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /src/YAML_Doc.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "YAML_Doc.hpp" 21 | using namespace std; 22 | 23 | /*! 24 | Sets the application name and version which will become part of the YAML doc. 25 | 26 | @param[in] miniApp_Name application name 27 | @param[in] miniApp_Version application name 28 | @param[in] destination_Directory destination directory for the YAML document 29 | @param[in] destination_FileName file name for the YAML document 30 | */ 31 | YAML_Doc::YAML_Doc(const std::string & miniApp_Name, const std::string & miniApp_Version, const std::string & destination_Directory, const std::string & destination_FileName) { 32 | miniAppName = miniApp_Name; 33 | miniAppVersion = miniApp_Version; 34 | destinationDirectory = destination_Directory; 35 | destinationFileName = destination_FileName; 36 | } 37 | 38 | //inherits the destructor from YAML_Element 39 | YAML_Doc::~YAML_Doc(void) { 40 | } 41 | 42 | /*! 43 | Generates YAML from the elements of the document and saves it to a file. 44 | 45 | @return returns the complete YAML document as a string 46 | */ 47 | string YAML_Doc::generateYAML() { 48 | string yaml; 49 | 50 | yaml = yaml + miniAppName + " version: " + miniAppVersion + "\n"; 51 | 52 | for (size_t i=0; iprintYAML(""); 54 | } 55 | 56 | time_t rawtime; 57 | tm * ptm; 58 | time ( &rawtime ); 59 | ptm = localtime(&rawtime); 60 | char sdate[25]; 61 | //use tm_mon+1 because tm_mon is 0 .. 11 instead of 1 .. 12 62 | sprintf (sdate,"%04d.%02d.%02d.%02d.%02d.%02d",ptm->tm_year + 1900, ptm->tm_mon+1, 63 | ptm->tm_mday, ptm->tm_hour, ptm->tm_min,ptm->tm_sec); 64 | 65 | string filename; 66 | if (destinationFileName=="") 67 | filename = miniAppName + "-" + miniAppVersion + "_"; 68 | else 69 | filename = destinationFileName; 70 | filename = filename + string(sdate) + ".yaml"; 71 | if (destinationDirectory!="" && destinationDirectory!=".") { 72 | string mkdir_cmd = "mkdir " + destinationDirectory; 73 | system(mkdir_cmd.c_str()); 74 | filename = destinationDirectory + "/" + destinationFileName; 75 | } else 76 | filename = "./" + filename; 77 | 78 | ofstream myfile; 79 | myfile.open(filename.c_str()); 80 | myfile << yaml; 81 | myfile.close(); 82 | return yaml; 83 | } 84 | -------------------------------------------------------------------------------- /src/WriteProblem.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file WriteProblem.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include 22 | #include "WriteProblem.hpp" 23 | 24 | 25 | /*! 26 | Routine to dump: 27 | - matrix in row, col, val format for analysis with MATLAB 28 | - x, xexact, b as simple arrays of numbers. 29 | 30 | Writes to A.dat, x.dat, xexact.dat and b.dat, respectivly. 31 | 32 | NOTE: THIS CODE ONLY WORKS ON SINGLE PROCESSOR RUNS 33 | 34 | Read into MATLAB using: 35 | 36 | load A.dat 37 | A=spconvert(A); 38 | load x.dat 39 | load xexact.dat 40 | load b.dat 41 | 42 | @param[in] geom The description of the problem's geometry. 43 | @param[in] A The known system matrix 44 | @param[in] b The known right hand side vector 45 | @param[in] x The solution vector computed by CG iteration 46 | @param[in] xexact Generated exact solution 47 | 48 | @return Returns with -1 if used with more than one MPI process. Returns with 0 otherwise. 49 | 50 | @see GenerateProblem 51 | */ 52 | int WriteProblem( const Geometry & geom, const SparseMatrix & A, 53 | const Vector b, const Vector x, const Vector xexact) { 54 | 55 | if (geom.size!=1) return -1; //TODO Only works on one processor. Need better error handler 56 | const global_int_t nrow = A.totalNumberOfRows; 57 | 58 | FILE * fA = 0, * fx = 0, * fxexact = 0, * fb = 0; 59 | fA = fopen("A.dat", "w"); 60 | fx = fopen("x.dat", "w"); 61 | fxexact = fopen("xexact.dat", "w"); 62 | fb = fopen("b.dat", "w"); 63 | 64 | if (! fA || ! fx || ! fxexact || ! fb) { 65 | if (fb) fclose(fb); 66 | if (fxexact) fclose(fxexact); 67 | if (fx) fclose(fx); 68 | if (fA) fclose(fA); 69 | return -1; 70 | } 71 | 72 | for (global_int_t i=0; i< nrow; i++) { 73 | const double * const currentRowValues = A.matrixValues[i]; 74 | const global_int_t * const currentRowIndices = A.mtxIndG[i]; 75 | const int currentNumberOfNonzeros = A.nonzerosInRow[i]; 76 | for (int j=0; j< currentNumberOfNonzeros; j++) 77 | #ifdef HPCG_NO_LONG_LONG 78 | fprintf(fA, " %d %d %22.16e\n",i+1,(global_int_t)(currentRowIndices[j]+1),currentRowValues[j]); 79 | #else 80 | fprintf(fA, " %lld %lld %22.16e\n",i+1,(global_int_t)(currentRowIndices[j]+1),currentRowValues[j]); 81 | #endif 82 | fprintf(fx, "%22.16e\n",x.values[i]); 83 | fprintf(fxexact, "%22.16e\n",xexact.values[i]); 84 | fprintf(fb, "%22.16e\n",b.values[i]); 85 | } 86 | 87 | fclose(fA); 88 | fclose(fx); 89 | fclose(fxexact); 90 | fclose(fb); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # HPCG Benchmark CMake configuration 3 | # 4 | cmake_minimum_required( VERSION 3.0 FATAL_ERROR ) 5 | 6 | project( hpcg 7 | VERSION 3.1 8 | LANGUAGES CXX 9 | DESCRIPTION "High Performance Conjugate Gradient Benchmark (HPCG) " ) 10 | 11 | # 12 | # Options 13 | # 14 | option(HPCG_ENABLE_CONTIGUOUS_ARRAYS "Enable contiguous arrays for better cache pre-fetch" OFF) 15 | option(HPCG_ENABLE_CUBIC_RADICAL_SEARCH "Enable faster search for optimal 3D process grid" OFF) 16 | option(HPCG_ENABLE_DEBUG "Enable debug build" OFF) 17 | option(HPCG_ENABLE_DETAILED_DEBUG "Enable detailed debug build" OFF) 18 | option(HPCG_ENABLE_MPI "Enable MPI support" OFF) 19 | option(HPCG_ENABLE_LONG_LONG "Enable use of 'long long' type for global indices" ON) 20 | option(HPCG_ENABLE_OPENMP "Enable OpenMP support" OFF) 21 | 22 | add_executable( xhpcg src/main.cpp src/CG.cpp src/CG_ref.cpp src/TestCG.cpp 23 | src/ComputeResidual.cpp src/ExchangeHalo.cpp src/GenerateGeometry.cpp 24 | src/GenerateProblem.cpp src/GenerateProblem_ref.cpp src/CheckProblem.cpp 25 | src/OptimizeProblem.cpp src/ReadHpcgDat.cpp src/ReportResults.cpp 26 | src/SetupHalo.cpp src/SetupHalo_ref.cpp src/TestSymmetry.cpp 27 | src/TestNorms.cpp src/WriteProblem.cpp src/YAML_Doc.cpp 28 | src/YAML_Element.cpp src/ComputeDotProduct.cpp 29 | src/ComputeDotProduct_ref.cpp src/finalize.cpp src/init.cpp src/mytimer.cpp 30 | src/ComputeSPMV.cpp src/ComputeSPMV_ref.cpp src/ComputeSYMGS.cpp 31 | src/ComputeSYMGS_ref.cpp src/ComputeWAXPBY.cpp src/ComputeWAXPBY_ref.cpp 32 | src/ComputeMG_ref.cpp src/ComputeMG.cpp src/ComputeProlongation_ref.cpp 33 | src/ComputeRestriction_ref.cpp src/GenerateCoarseProblem.cpp 34 | src/ComputeOptimalShapeXYZ.cpp src/MixedBaseCounter.cpp 35 | src/CheckAspectRatio.cpp src/OutputFile.cpp) 36 | 37 | if (HPCG_ENABLE_CONTIGUOUS_ARRAYS) 38 | target_compile_definitions(xhpcg PRIVATE HPCG_CONTIGUOUS_ARRAYS) 39 | endif () 40 | 41 | if (HPCG_ENABLE_CUBIC_RADICAL_SEARCH) 42 | target_compile_definitions(xhpcg PRIVATE HPCG_CUBIC_RADICAL_SEARCH) 43 | endif () 44 | 45 | if (HPCG_ENABLE_DEBUG) 46 | target_compile_definitions(xhpcg PRIVATE HPCG_DEBUG) 47 | endif () 48 | 49 | if (HPCG_ENABLE_DETAILED_DEBUG) 50 | target_compile_definitions(xhpcg PRIVATE HPCG_DETAILED_DEBUG) 51 | endif () 52 | 53 | if (HPCG_ENABLE_MPI) 54 | set(MPI_CXX_SKIP_MPICXX ON) 55 | find_package(MPI REQUIRED) 56 | target_link_libraries(xhpcg ${MPI_CXX_LIBRARIES}) 57 | else () 58 | target_compile_definitions(xhpcg PRIVATE HPCG_NO_MPI) 59 | endif () 60 | 61 | if (NOT HPCG_ENABLE_LONG_LONG) 62 | target_compile_definitions(xhpcg PRIVATE HPCG_NO_LONG_LONG) 63 | endif () 64 | 65 | if (HPCG_ENABLE_OPENMP) 66 | find_package(OpenMP REQUIRED) 67 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 68 | target_link_libraries(xhpcg ${OpenMP_CXX_LIBRARIES}) 69 | else () 70 | target_compile_definitions(xhpcg PRIVATE HPCG_NO_OPENMP) 71 | endif () 72 | -------------------------------------------------------------------------------- /src/YAML_Element.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file YAML_Element.hpp 17 | 18 | HPCG data structures for YAML output 19 | */ 20 | 21 | // Changelog 22 | // 23 | // Version 0.1 24 | // - Initial version. 25 | // 26 | ///////////////////////////////////////////////////////////////////////// 27 | 28 | #ifndef YAML_ELEMENT_HPP 29 | #define YAML_ELEMENT_HPP 30 | #include 31 | #include 32 | #include "Geometry.hpp" 33 | //! HPCG YAML_Element class, from the HPCG YAML_Element class for registering key-value pairs of performance data 34 | 35 | /*! 36 | HPCG generates a collection of performance data for each run of the executable. YAML_Element, and 37 | the related YAML_Doc class, provide a uniform facility for gathering and reporting this data using the YAML text format. 38 | */ 39 | class YAML_Element { 40 | public: 41 | 42 | //! Default constructor. 43 | YAML_Element () {key=""; value="";} 44 | //! Construct with known key-value pair 45 | YAML_Element (const std::string & key_arg, const std::string & value_arg); 46 | //! Destructor 47 | ~YAML_Element (); 48 | //! Key accessor method 49 | std::string getKey() {return key;} 50 | //! Add a child element to an element list associated with this element, value of type double 51 | YAML_Element * add(const std::string & key_arg, double value_arg); 52 | //! Add a child element to an element list associated with this element, value of type int 53 | YAML_Element * add(const std::string & key_arg, int value_arg); 54 | #ifndef HPCG_NO_LONG_LONG 55 | //! Add a child element to an element list associated with this element, value of type long long 56 | YAML_Element * add(const std::string & key_arg, long long value_arg); 57 | #endif 58 | //! Add a child element to an element list associated with this element, value of type size_t 59 | YAML_Element * add(const std::string & key_arg, size_t value_arg); 60 | //! Add a child element to an element list associated with this element, value of type string 61 | YAML_Element * add(const std::string & key_arg, const std::string & value_arg); 62 | //! get the element in the list with the given key 63 | YAML_Element * get(const std::string & key_arg); 64 | std::string printYAML(std::string space); 65 | 66 | protected: 67 | std::string key; //!< the key under which the element is stored 68 | std::string value; //!< the value of the stored element 69 | std::vector children; //!< children elements of this element 70 | 71 | private: 72 | std::string convert_double_to_string(double value_arg); 73 | std::string convert_int_to_string(int value_arg); 74 | #ifndef HPCG_NO_LONG_LONG 75 | std::string convert_long_long_to_string(long long value_arg); 76 | #endif 77 | std::string convert_size_t_to_string(size_t value_arg); 78 | }; 79 | #endif // YAML_ELEMENT_HPP 80 | -------------------------------------------------------------------------------- /web/faq.php: -------------------------------------------------------------------------------- 1 | setPathToWebRoot(''); 5 | $page->setPageTitle('HPCG - FAQ'); 6 | $page->setNavIdentifier('faq'); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 |
      14 |
    1. Will HPCG replace High Performance Linpack (HPL)? 15 |

      16 | We do not intend to eliminate HPL. HPCG will provide 17 | an alternative ranking of the TOP500 machines. We 18 | expect that HPCG will take several years to both mature 19 | and emerge as a widely-visible metric. 20 |

      21 | 22 |
    2. Isn't HPCG just another version of the STREAM benchmark? 23 |

      24 | If the reference version of HPCG is used for performance 25 | analysis, the fraction of time spent in the (unoptimized) 26 | sparse kernels (in particular ComputeSPMV and ComputeSYMGS) 27 | will be very high, and HPCG performance will be dominated by 28 | memory system performance. In this case, for computer systems 29 | with a good reduction networks, or HPCG runs using few MPI processes, 30 | the benchmark will 31 | give rankings that are very similar to STREAM. 32 |

      33 |

      34 | However, this is true for many benchmarks. If HPL were executed 35 | with reference Fortran computational kernels (Basic Linear Algebra 36 | Subprograms), HPL would also look like a STREAM benchmark. 37 |

      38 |

      39 | Warnings have been added to HPCG reports to let the benchmarker 40 | know that performance will be suboptimal when using reference 41 | kernels. 42 |

      43 | 44 |
    3. Is it permitted to use a custom ordering for the matrix? 45 |

      46 | Yes, it is permitted to use a custom ordering of the grid points. This is 47 | facilitated with the function OptimizeProblem() and the 48 | optimizationData members of various data structures. 49 |

      50 |
    4. 51 | 52 |
    5. Why doesn't HPCG include variant X of the CG algorithm? 53 |

      54 | We are aware of many variants of the CG algorithm and their benefits for 55 | particular matrices. At the same time, we strive for simplicity of the 56 | reference implementation and permit only selected optimizations that allow 57 | the results to remain representative of a wide range of CG variants. 58 |

      59 |
    6. 60 | 61 |
    7. Can I change the Gauss-Seidel preconditioner to make it parallel? 62 |

      63 | It is not permitted to change the preconditioner but it is allowed to change 64 | the ordering of the matrix to facilitate parallel preconditioning. 65 |

      66 |
    8. 67 | 68 |
    9. How is HPCG different from NAS PB CG (NAS Parallel Benchmarks, CG component)? 69 |

      70 | NAS PB CG uses random sparsity pattern which naturally leads to 71 | two-dimensional distribution of the matrix for optimality. This results in 72 | computation and communication patterns that are non-physical. Another 73 | difference is the lack of preconditioning, does not allow to show the effects 74 | of local triangular solve. The options for introducing such a preconditioning 75 | component are limited due to the non-physical sparsity pattern. 76 |

      77 |
    10. 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Vector.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file Vector.hpp 17 | 18 | HPCG data structures for dense vectors 19 | */ 20 | 21 | #ifndef VECTOR_HPP 22 | #define VECTOR_HPP 23 | #include 24 | #include 25 | #include "Geometry.hpp" 26 | 27 | struct Vector_STRUCT { 28 | local_int_t localLength; //!< length of local portion of the vector 29 | double * values; //!< array of values 30 | /*! 31 | This is for storing optimized data structures created in OptimizeProblem and 32 | used inside optimized ComputeSPMV(). 33 | */ 34 | void * optimizationData; 35 | 36 | }; 37 | typedef struct Vector_STRUCT Vector; 38 | 39 | /*! 40 | Initializes input vector. 41 | 42 | @param[in] v 43 | @param[in] localLength Length of local portion of input vector 44 | */ 45 | inline void InitializeVector(Vector & v, local_int_t localLength) { 46 | v.localLength = localLength; 47 | v.values = new double[localLength]; 48 | v.optimizationData = 0; 49 | return; 50 | } 51 | 52 | /*! 53 | Fill the input vector with zero values. 54 | 55 | @param[inout] v - On entrance v is initialized, on exit all its values are zero. 56 | */ 57 | inline void ZeroVector(Vector & v) { 58 | local_int_t localLength = v.localLength; 59 | double * vv = v.values; 60 | for (int i=0; i=0 && index < v.localLength); 72 | double * vv = v.values; 73 | vv[index] *= value; 74 | return; 75 | } 76 | /*! 77 | Fill the input vector with pseudo-random values. 78 | 79 | @param[in] v 80 | */ 81 | inline void FillRandomVector(Vector & v) { 82 | local_int_t localLength = v.localLength; 83 | double * vv = v.values; 84 | for (int i=0; i= localLength); 96 | double * vv = v.values; 97 | double * wv = w.values; 98 | for (int i=0; i 24 | #include "Geometry.hpp" 25 | #include "ExchangeHalo.hpp" 26 | #include 27 | 28 | /*! 29 | Communicates data that is at the border of the part of the domain assigned to this processor. 30 | 31 | @param[in] A The known system matrix 32 | @param[inout] x On entry: the local vector entries followed by entries to be communicated; on exit: the vector with non-local entries updated by other processors 33 | */ 34 | void ExchangeHalo(const SparseMatrix & A, Vector & x) { 35 | 36 | // Extract Matrix pieces 37 | 38 | local_int_t localNumberOfRows = A.localNumberOfRows; 39 | int num_neighbors = A.numberOfSendNeighbors; 40 | local_int_t * receiveLength = A.receiveLength; 41 | local_int_t * sendLength = A.sendLength; 42 | int * neighbors = A.neighbors; 43 | double * sendBuffer = A.sendBuffer; 44 | local_int_t totalToBeSent = A.totalToBeSent; 45 | local_int_t * elementsToSend = A.elementsToSend; 46 | 47 | double * const xv = x.values; 48 | 49 | int size, rank; // Number of MPI processes, My process ID 50 | MPI_Comm_size(MPI_COMM_WORLD, &size); 51 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); 52 | 53 | // 54 | // first post receives, these are immediate receives 55 | // Do not wait for result to come, will do that at the 56 | // wait call below. 57 | // 58 | 59 | int MPI_MY_TAG = 99; 60 | 61 | MPI_Request * request = new MPI_Request[num_neighbors]; 62 | 63 | // 64 | // Externals are at end of locals 65 | // 66 | double * x_external = (double *) xv + localNumberOfRows; 67 | 68 | // Post receives first 69 | // TODO: Thread this loop 70 | for (int i = 0; i < num_neighbors; i++) { 71 | local_int_t n_recv = receiveLength[i]; 72 | MPI_Irecv(x_external, n_recv, MPI_DOUBLE, neighbors[i], MPI_MY_TAG, MPI_COMM_WORLD, request+i); 73 | x_external += n_recv; 74 | } 75 | 76 | 77 | // 78 | // Fill up send buffer 79 | // 80 | 81 | // TODO: Thread this loop 82 | for (local_int_t i=0; i'; ?> 2 | 4 | 5 | 6 | 7 | 8 | <?php echo $page->getPageTitle(); ?> 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 24 | 26 | 29 | 35 | 36 | 37 | 38 | 39 | getBodyAttributes(); ?>> 42 | 43 | 44 |
      50 | 51 | 52 |
      53 | 54 | 55 | 66 | 67 |
      68 | 69 |
      70 | 71 | -------------------------------------------------------------------------------- /src/OutputFile.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "OutputFile.hpp" 22 | 23 | using std::string; 24 | using std::stringstream; 25 | using std::list; 26 | using std::ofstream; 27 | 28 | OutputFile::OutputFile(const string & name_arg, const string & version_arg) 29 | : name(name_arg), version(version_arg), eol("\n"), keySeparator("::") {} 30 | 31 | OutputFile::OutputFile(void) : eol("\n"), keySeparator("::") {} 32 | 33 | OutputFile::~OutputFile() { 34 | for (list::iterator it = descendants.begin(); it != descendants.end(); ++it) { 35 | delete *it; 36 | } 37 | } 38 | 39 | void 40 | OutputFile::add(const string & key_arg, const string & value_arg) { 41 | descendants.push_back(allocKeyVal(key_arg, value_arg)); 42 | } 43 | 44 | void 45 | OutputFile::add(const string & key_arg, double value_arg) { 46 | stringstream ss; 47 | ss << value_arg; 48 | descendants.push_back(allocKeyVal(key_arg, ss.str())); 49 | } 50 | 51 | void 52 | OutputFile::add(const string & key_arg, int value_arg) { 53 | stringstream ss; 54 | ss << value_arg; 55 | descendants.push_back(allocKeyVal(key_arg, ss.str())); 56 | } 57 | 58 | #ifndef HPCG_NO_LONG_LONG 59 | 60 | void 61 | OutputFile::add(const string & key_arg, long long value_arg) { 62 | stringstream ss; 63 | ss << value_arg; 64 | descendants.push_back(allocKeyVal(key_arg, ss.str())); 65 | } 66 | 67 | #endif 68 | 69 | void 70 | OutputFile::add(const string & key_arg, size_t value_arg) { 71 | stringstream ss; 72 | ss << value_arg; 73 | descendants.push_back(allocKeyVal(key_arg, ss.str())); 74 | } 75 | 76 | void 77 | OutputFile::setKeyValue(const string & key_arg, const string & value_arg) { 78 | key = key_arg; 79 | value = value_arg; 80 | } 81 | 82 | OutputFile * 83 | OutputFile::get(const string & key_arg) { 84 | for (list::iterator it = descendants.begin(); it != descendants.end(); ++it) { 85 | if ((*it)->key == key_arg) 86 | return *it; 87 | } 88 | 89 | return 0; 90 | } 91 | 92 | string 93 | OutputFile::generateRecursive(string prefix) { 94 | string result = ""; 95 | 96 | result += prefix + key + "=" + value + eol; 97 | 98 | for (list::iterator it = descendants.begin(); it != descendants.end(); ++it) { 99 | result += (*it)->generateRecursive(prefix + key + keySeparator); 100 | } 101 | 102 | return result; 103 | } 104 | 105 | string 106 | OutputFile::generate(void) { 107 | string result = name + "\nversion=" + version + eol; 108 | 109 | for (list::iterator it = descendants.begin(); it != descendants.end(); ++it) { 110 | result += (*it)->generateRecursive(""); 111 | } 112 | 113 | time_t rawtime; 114 | time(&rawtime); 115 | tm * ptm = localtime(&rawtime); 116 | char sdate[25]; 117 | //use tm_mon+1 because tm_mon is 0 .. 11 instead of 1 .. 12 118 | sprintf (sdate,"%04d-%02d-%02d_%02d-%02d-%02d",ptm->tm_year + 1900, ptm->tm_mon+1, 119 | ptm->tm_mday, ptm->tm_hour, ptm->tm_min,ptm->tm_sec); 120 | 121 | string filename = name + "_" + version + "_"; 122 | filename += string(sdate) + ".txt"; 123 | 124 | ofstream myfile(filename.c_str()); 125 | myfile << result; 126 | myfile.close(); 127 | 128 | return result; 129 | } 130 | 131 | OutputFile * OutputFile::allocKeyVal(const std::string & key_arg, const std::string & value_arg) { 132 | OutputFile * of = new OutputFile(); 133 | of->setKeyValue(key_arg, value_arg); 134 | return of; 135 | } 136 | -------------------------------------------------------------------------------- /src/ComputeSYMGS_ref.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file ComputeSYMGS_ref.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #ifndef HPCG_NO_MPI 22 | #include "ExchangeHalo.hpp" 23 | #endif 24 | #include "ComputeSYMGS_ref.hpp" 25 | #include 26 | 27 | /*! 28 | Computes one step of symmetric Gauss-Seidel: 29 | 30 | Assumption about the structure of matrix A: 31 | - Each row 'i' of the matrix has nonzero diagonal value whose address is matrixDiagonal[i] 32 | - Entries in row 'i' are ordered such that: 33 | - lower triangular terms are stored before the diagonal element. 34 | - upper triangular terms are stored after the diagonal element. 35 | - No other assumptions are made about entry ordering. 36 | 37 | Symmetric Gauss-Seidel notes: 38 | - We use the input vector x as the RHS and start with an initial guess for y of all zeros. 39 | - We perform one forward sweep. x should be initially zero on the first GS sweep, but we do not attempt to exploit this fact. 40 | - We then perform one back sweep. 41 | - For simplicity we include the diagonal contribution in the for-j loop, then correct the sum after 42 | 43 | @param[in] A the known system matrix 44 | @param[in] r the input vector 45 | @param[inout] x On entry, x should contain relevant values, on exit x contains the result of one symmetric GS sweep with r as the RHS. 46 | 47 | 48 | @warning Early versions of this kernel (Version 1.1 and earlier) had the r and x arguments in reverse order, and out of sync with other kernels. 49 | 50 | @return returns 0 upon success and non-zero otherwise 51 | 52 | @see ComputeSYMGS 53 | */ 54 | int ComputeSYMGS_ref( const SparseMatrix & A, const Vector & r, Vector & x) { 55 | 56 | assert(x.localLength==A.localNumberOfColumns); // Make sure x contain space for halo values 57 | 58 | #ifndef HPCG_NO_MPI 59 | ExchangeHalo(A,x); 60 | #endif 61 | 62 | const local_int_t nrow = A.localNumberOfRows; 63 | double ** matrixDiagonal = A.matrixDiagonal; // An array of pointers to the diagonal entries A.matrixValues 64 | const double * const rv = r.values; 65 | double * const xv = x.values; 66 | 67 | for (local_int_t i=0; i< nrow; i++) { 68 | const double * const currentValues = A.matrixValues[i]; 69 | const local_int_t * const currentColIndices = A.mtxIndL[i]; 70 | const int currentNumberOfNonzeros = A.nonzerosInRow[i]; 71 | const double currentDiagonal = matrixDiagonal[i][0]; // Current diagonal value 72 | double sum = rv[i]; // RHS value 73 | 74 | for (int j=0; j< currentNumberOfNonzeros; j++) { 75 | local_int_t curCol = currentColIndices[j]; 76 | sum -= currentValues[j] * xv[curCol]; 77 | } 78 | sum += xv[i]*currentDiagonal; // Remove diagonal contribution from previous loop 79 | 80 | xv[i] = sum/currentDiagonal; 81 | 82 | } 83 | 84 | // Now the back sweep. 85 | 86 | for (local_int_t i=nrow-1; i>=0; i--) { 87 | const double * const currentValues = A.matrixValues[i]; 88 | const local_int_t * const currentColIndices = A.mtxIndL[i]; 89 | const int currentNumberOfNonzeros = A.nonzerosInRow[i]; 90 | const double currentDiagonal = matrixDiagonal[i][0]; // Current diagonal value 91 | double sum = rv[i]; // RHS value 92 | 93 | for (int j = 0; j< currentNumberOfNonzeros; j++) { 94 | local_int_t curCol = currentColIndices[j]; 95 | sum -= currentValues[j]*xv[curCol]; 96 | } 97 | sum += xv[i]*currentDiagonal; // Remove diagonal contribution from previous loop 98 | 99 | xv[i] = sum/currentDiagonal; 100 | } 101 | 102 | return 0; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/OptimizeProblem.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file OptimizeProblem.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #include "OptimizeProblem.hpp" 22 | /*! 23 | Optimizes the data structures used for CG iteration to increase the 24 | performance of the benchmark version of the preconditioned CG algorithm. 25 | 26 | @param[inout] A The known system matrix, also contains the MG hierarchy in attributes Ac and mgData. 27 | @param[inout] data The data structure with all necessary CG vectors preallocated 28 | @param[inout] b The known right hand side vector 29 | @param[inout] x The solution vector to be computed in future CG iteration 30 | @param[inout] xexact The exact solution vector 31 | 32 | @return returns 0 upon success and non-zero otherwise 33 | 34 | @see GenerateGeometry 35 | @see GenerateProblem 36 | */ 37 | int OptimizeProblem(SparseMatrix & A, CGData & data, Vector & b, Vector & x, Vector & xexact) { 38 | 39 | // This function can be used to completely transform any part of the data structures. 40 | // Right now it does nothing, so compiling with a check for unused variables results in complaints 41 | 42 | #if defined(HPCG_USE_MULTICOLORING) 43 | const local_int_t nrow = A.localNumberOfRows; 44 | std::vector colors(nrow, nrow); // value `nrow' means `uninitialized'; initialized colors go from 0 to nrow-1 45 | int totalColors = 1; 46 | colors[0] = 0; // first point gets color 0 47 | 48 | // Finds colors in a greedy (a likely non-optimal) fashion. 49 | 50 | for (local_int_t i=1; i < nrow; ++i) { 51 | if (colors[i] == nrow) { // if color not assigned 52 | std::vector assigned(totalColors, 0); 53 | int currentlyAssigned = 0; 54 | const local_int_t * const currentColIndices = A.mtxIndL[i]; 55 | const int currentNumberOfNonzeros = A.nonzerosInRow[i]; 56 | 57 | for (int j=0; j< currentNumberOfNonzeros; j++) { // scan neighbors 58 | local_int_t curCol = currentColIndices[j]; 59 | if (curCol < i) { // if this point has an assigned color (points beyond `i' are unassigned) 60 | if (assigned[colors[curCol]] == 0) 61 | currentlyAssigned += 1; 62 | assigned[colors[curCol]] = 1; // this color has been used before by `curCol' point 63 | } // else // could take advantage of indices being sorted 64 | } 65 | 66 | if (currentlyAssigned < totalColors) { // if there is at least one color left to use 67 | for (int j=0; j < totalColors; ++j) // try all current colors 68 | if (assigned[j] == 0) { // if no neighbor with this color 69 | colors[i] = j; 70 | break; 71 | } 72 | } else { 73 | if (colors[i] == nrow) { 74 | colors[i] = totalColors; 75 | totalColors += 1; 76 | } 77 | } 78 | } 79 | } 80 | 81 | std::vector counters(totalColors); 82 | for (local_int_t i=0; i 3 | #include 4 | #include 5 | 6 | #include "ReadHpcgDat.hpp" 7 | 8 | const char *HPCG_DAT = "hpcg.dat"; 9 | 10 | static int 11 | WriteHpcgDat(const char *s, size_t length) { 12 | FILE *stream = fopen(HPCG_DAT, "wb"); 13 | 14 | if (! stream) { 15 | fprintf(stderr, "Cannot write %s\n", HPCG_DAT); 16 | exit(127); 17 | return -1; 18 | } 19 | 20 | fwrite(s, 1, length, stream); 21 | 22 | fclose(stream); 23 | 24 | return 0; 25 | } 26 | 27 | static void 28 | RemoveHpcgDat(void) { 29 | remove(HPCG_DAT); 30 | } 31 | 32 | // Test for empty hpcg.dat 33 | int 34 | TestCase1(void) { 35 | const char *s = ""; 36 | WriteHpcgDat(s, strlen(s)); 37 | int localDims[3] = {-23, -29, -31}, seconds = -7; 38 | 39 | ReadHpcgDat(localDims, &seconds); 40 | printf( "%d %d %d %d\n", localDims[0], localDims[1], localDims[2], seconds ); fflush(stdout); 41 | 42 | int retVal = 0, idx = 0; 43 | if (localDims[0] < 1) retVal |= 1 << (idx++); 44 | if (localDims[1] < 1) retVal |= 1 << (idx++); 45 | if (localDims[2] < 1) retVal |= 1 << (idx++); 46 | if (seconds < 1) retVal |= 1 << (idx++); 47 | RemoveHpcgDat(); 48 | 49 | return retVal; 50 | } 51 | 52 | // Test for simple hpcg.dat with Unix line endings: \n 53 | int 54 | TestCase2(void) { 55 | const char *s = "First\nSecond\n13 17 19\n3613\n"; 56 | WriteHpcgDat(s, strlen(s)); 57 | 58 | int localDims[3] = {23, 29, 31}, seconds = 7; 59 | int retVal = 0, idx = 0; 60 | 61 | ReadHpcgDat(localDims, &seconds); 62 | printf( "%d %d %d %d\n", localDims[0], localDims[1], localDims[2], seconds ); fflush(stdout); 63 | 64 | if (localDims[0] != 13) retVal |= 1 << (idx++); 65 | 66 | if (localDims[1] != 17) retVal |= 1 << (idx++); 67 | 68 | if (localDims[2] != 19) retVal |= 1 << (idx++); 69 | 70 | if (seconds != 3613) retVal |= 1 << (idx++); 71 | 72 | RemoveHpcgDat(); 73 | 74 | return retVal; 75 | } 76 | 77 | // Test for simple hpcg.dat with Windows line endings: \r\n 78 | int 79 | TestCase3(void) { 80 | const char *s = "First\r\nSecond\r\n13 17 19\r\n3613\r\n"; 81 | WriteHpcgDat(s, strlen(s)); 82 | 83 | int localDims[3] = {23, 29, 31}, seconds = 7; 84 | int retVal = 0, idx = 0; 85 | 86 | ReadHpcgDat(localDims, &seconds); 87 | printf( "%d %d %d %d\n", localDims[0], localDims[1], localDims[2], seconds ); fflush(stdout); 88 | 89 | if (localDims[0] != 13) retVal |= 1 << (idx++); 90 | 91 | if (localDims[1] != 17) retVal |= 1 << (idx++); 92 | 93 | if (localDims[2] != 19) retVal |= 1 << (idx++); 94 | 95 | if (seconds != 3613) retVal |= 1 << (idx++); 96 | 97 | RemoveHpcgDat(); 98 | 99 | return retVal; 100 | } 101 | 102 | // Test for simple hpcg.dat with old Mac OS line endings: \r 103 | int 104 | TestCase4(void) { 105 | const char *s = "First\rSecond\r13 17 19\r3613\r"; 106 | WriteHpcgDat(s, strlen(s)); 107 | 108 | int localDims[3] = {23, 29, 31}, seconds = 7; 109 | int retVal = 0, idx = 0; 110 | 111 | ReadHpcgDat(localDims, &seconds); 112 | printf( "%d %d %d %d\n", localDims[0], localDims[1], localDims[2], seconds ); fflush(stdout); 113 | 114 | if (localDims[0] != 13) retVal |= 1 << (idx++); 115 | 116 | if (localDims[1] != 17) retVal |= 1 << (idx++); 117 | 118 | if (localDims[2] != 19) retVal |= 1 << (idx++); 119 | 120 | if (seconds != 3613) retVal |= 1 << (idx++); 121 | 122 | RemoveHpcgDat(); 123 | 124 | return retVal; 125 | } 126 | 127 | int main(void) { 128 | int mainReturnValue = 0; 129 | 130 | int (*testCases[])(void) = { 131 | TestCase1, 132 | TestCase2, 133 | TestCase3, 134 | TestCase4, 135 | 0 136 | }; 137 | 138 | for (int i=0; testCases[i]; ++i) { 139 | int retVal = testCases[i](); 140 | if (retVal) { 141 | fprintf(stderr, "Test case %d returned %d\n", i+1, retVal); 142 | mainReturnValue = 129; 143 | } else 144 | fprintf(stderr, "Test case %d succeeded\n", i+1); 145 | fflush(stderr); 146 | } 147 | 148 | return mainReturnValue; 149 | } 150 | -------------------------------------------------------------------------------- /src/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /web/common/footer.html: -------------------------------------------------------------------------------- 1 |
      2 | 3 | 4 | 18 | 19 |
      20 |

      21 | 22 | 23 |
      90 | 91 | 92 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /src/GenerateCoarseProblem.cpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file GenerateProblem.cpp 17 | 18 | HPCG routine 19 | */ 20 | 21 | #ifndef HPCG_NO_OPENMP 22 | #include 23 | #endif 24 | 25 | #include 26 | #include "GenerateCoarseProblem.hpp" 27 | #include "GenerateGeometry.hpp" 28 | #include "GenerateProblem.hpp" 29 | #include "SetupHalo.hpp" 30 | 31 | /*! 32 | Routine to construct a prolongation/restriction operator for a given fine grid matrix 33 | solution (as computed by a direct solver). 34 | 35 | @param[inout] Af - The known system matrix, on output its coarse operator, fine-to-coarse operator and auxiliary vectors will be defined. 36 | 37 | Note that the matrix Af is considered const because the attributes we are modifying are declared as mutable. 38 | 39 | */ 40 | 41 | void GenerateCoarseProblem(const SparseMatrix & Af) { 42 | 43 | // Make local copies of geometry information. Use global_int_t since the RHS products in the calculations 44 | // below may result in global range values. 45 | global_int_t nxf = Af.geom->nx; 46 | global_int_t nyf = Af.geom->ny; 47 | global_int_t nzf = Af.geom->nz; 48 | 49 | local_int_t nxc, nyc, nzc; //Coarse nx, ny, nz 50 | assert(nxf%2==0); assert(nyf%2==0); assert(nzf%2==0); // Need fine grid dimensions to be divisible by 2 51 | nxc = nxf/2; nyc = nyf/2; nzc = nzf/2; 52 | local_int_t * f2cOperator = new local_int_t[Af.localNumberOfRows]; 53 | local_int_t localNumberOfRows = nxc*nyc*nzc; // This is the size of our subblock 54 | // If this assert fails, it most likely means that the local_int_t is set to int and should be set to long long 55 | assert(localNumberOfRows>0); // Throw an exception of the number of rows is less than zero (can happen if "int" overflows) 56 | 57 | // Use a parallel loop to do initial assignment: 58 | // distributes the physical placement of arrays of pointers across the memory system 59 | #ifndef HPCG_NO_OPENMP 60 | #pragma omp parallel for 61 | #endif 62 | for (local_int_t i=0; i< localNumberOfRows; ++i) { 63 | f2cOperator[i] = 0; 64 | } 65 | 66 | 67 | // TODO: This triply nested loop could be flattened or use nested parallelism 68 | #ifndef HPCG_NO_OPENMP 69 | #pragma omp parallel for 70 | #endif 71 | for (local_int_t izc=0; izcpz; 89 | if (pz>0) { 90 | zlc = Af.geom->partz_nz[0]/2; // Coarsen nz for the lower block in the z processor dimension 91 | zuc = Af.geom->partz_nz[1]/2; // Coarsen nz for the upper block in the z processor dimension 92 | } 93 | GenerateGeometry(Af.geom->size, Af.geom->rank, Af.geom->numThreads, Af.geom->pz, zlc, zuc, nxc, nyc, nzc, Af.geom->npx, Af.geom->npy, Af.geom->npz, geomc); 94 | 95 | SparseMatrix * Ac = new SparseMatrix; 96 | InitializeSparseMatrix(*Ac, geomc); 97 | GenerateProblem(*Ac, 0, 0, 0); 98 | SetupHalo(*Ac); 99 | Vector *rc = new Vector; 100 | Vector *xc = new Vector; 101 | Vector * Axf = new Vector; 102 | InitializeVector(*rc, Ac->localNumberOfRows); 103 | InitializeVector(*xc, Ac->localNumberOfColumns); 104 | InitializeVector(*Axf, Af.localNumberOfColumns); 105 | Af.Ac = Ac; 106 | MGData * mgData = new MGData; 107 | InitializeMGData(f2cOperator, rc, xc, Axf, *mgData); 108 | Af.mgData = mgData; 109 | 110 | return; 111 | } 112 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.69]) 2 | 3 | AC_INIT(hpcg, 3.1, info@hpcg-benchmark.org) 4 | AC_CONFIG_SRCDIR([src/main.cpp]) 5 | dnl HPCG requires command line configuration 6 | dnl AC_CONFIG_HEADERS([src/hpcgconfig.hpp]) 7 | 8 | AC_CONFIG_MACRO_DIR([m4]) 9 | 10 | m4_define(hpcg_contiguous_arrays_help,[enable contiguous arrays storage for better cache pre-fetch]) 11 | AC_ARG_ENABLE(contiguous_arrays, 12 | [AS_HELP_STRING([--enable-contiguous-arrays], hpcg_contiguous_arrays_help [@<:@default=no@:>@])], 13 | AS_IF([test "x${enable_contiguous_arrays}" = xyes], AC_DEFINE([HPCG_CONTIGUOUS_ARRAYS], [1], hpcg_contiguous_arrays_help))) 14 | 15 | AC_ARG_WITH(debug, 16 | [AS_HELP_STRING([--with-debug=none,basic,detailed], [enable debugging output @<:@default=none@:>@])], 17 | AS_IF([test xnone != x$with_debug], AC_DEFINE([HPCG_DEBUG], [1], [Define to enable basic debugging output])) 18 | AS_IF([test xdetailed = x$with_debug], 19 | AC_DEFINE([HPCG_DETAILED_DEBUG], [1], [Define to enable detailed debugging output]))) 20 | 21 | AC_ARG_ENABLE(mpi, 22 | [AS_HELP_STRING([--enable-mpi],[enable MPI support @<:@default=no@:>@])], 23 | dnl detect MPI later due to Autoconf syntax error in `configure' 24 | AS_IF([test "x${enable_mpi}" = xno], AC_DEFINE([HPCG_NO_MPI], [1], [Define if MPI support is disabled])), 25 | AC_DEFINE([HPCG_NO_MPI], [1], [Define if MPI support is disabled])) 26 | 27 | m4_define(hpcg_cubic_radical_search_help, [enable cubic radical search for 3D process grid]) 28 | AC_ARG_ENABLE(cubic_radical_search, 29 | [AS_HELP_STRING([--enable-cubic-radical-search], hpcg_cubic_radical_search_help [@<:@default=no@:>@])], 30 | AS_IF([test "x${enable_cubic_radical_search}" = xyes], AC_DEFINE([HPCG_CONTIGUOUS_ARRAYS], [1], hpcg_cubic_radical_search_help))) 31 | 32 | m4_define(hpcg_longlong_help, [enable use of long long type for global indices]) 33 | AC_ARG_ENABLE(longlong, 34 | [AS_HELP_STRING([--enable-longlong], hpcg_longlong_help [@<:@default=yes@:>@])], 35 | AS_IF([test "x${enable_longlong}" = xno], AC_DEFINE([HPCG_NO_LONG_LONG], [1], hpcg_longlong_help))) 36 | 37 | AC_ARG_ENABLE(openmp, 38 | [AS_HELP_STRING([--enable-openmp], [enable OpenMP support [@<:@default=no@:>@]])], 39 | AS_IF([test "x${enable_openmp}" = xno], AC_DEFINE([HPCG_NO_OPENMP], [1], [disable OpenMP support])), 40 | AC_DEFINE([HPCG_NO_OPENMP], [1], [disable OpenMP support])) 41 | 42 | AC_PROG_RANLIB 43 | 44 | AC_PROG_INSTALL 45 | 46 | AM_INIT_AUTOMAKE([subdir-objects]) 47 | 48 | dnl select programming language as OpenMP tests require it 49 | AC_LANG(C++) 50 | 51 | AS_IF([test "x${enable_mpi}" != xyes], AC_MSG_NOTICE([MPI not enabled and it is OK for the following tests to fail.])) 52 | 53 | AX_PROG_CXX_MPI([test x"$enable_mpi" != xno],[],[ 54 | if test x"$with_mpi" = xyes; then 55 | AC_MSG_FAILURE([MPI compiler requested, but MPI unusable.]) 56 | else 57 | AC_MSG_WARN([No MPI compiler found and MPI is diabled.]) 58 | fi]) 59 | 60 | dnl AX_PROG_CC_MPI and AX_PROG_CXX_MPI must not be inside raw shell "if" 61 | dnl construct because Autoconf macros create 'configure' with syntax errors. 62 | dnl For example, this will cause syntax error when running "configure": 63 | dnl AS_IF([test "x${enable_mpi}" = yes], AX_PROG_CXX_MPI, AC_PROG_CXX) 64 | 65 | dnl Cannot use AS_IF() because of syntax errors. 66 | dnl AS_IF([test "x${enable_mpi}" = xyes], AC_CHECK_HEADER([mpi.h], [], AC_MSG_ERROR([MPI not found]))) 67 | if test "x${enable_mpi}" = xyes ; then : 68 | AC_CHECK_HEADER([mpi.h], [], AC_MSG_ERROR([MPI not found])) 69 | fi 70 | 71 | dnl 72 | dnl AC_PROG_CC and AC_PROG_CXX have to be after AX_PROG_CXX_MPI to properly pickup 73 | dnl mpic++ and link C++ bindings (if present or if they get added to the object 74 | dnl files by sloppy compiler/linker). In other words, the order matters. 75 | dnl 76 | 77 | dnl AC_PROG_CXX has to be outside of conditionals not to cause Automake variable AMDEP error. 78 | dnl The first AC_PROG_CXX will be used to set AMDEP variables and if they happen 79 | dnl to execute conditionally then "configure" invocation fails. 80 | AC_PROG_CXX 81 | dnl AC_PROG_CXX_C_O 82 | 83 | dnl Configuring C compiler is required for am__fastdepCC or Automake errors out (unless the C++ langauge is enforced). 84 | dnl AC_PROG_CC 85 | dnl AC_PROG_CC_C_O 86 | 87 | if test "x${enable_openmp}" = xyes ; then : 88 | AX_OPENMP 89 | CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" 90 | else 91 | AC_DEFINE([HPCG_NO_OPENMP], [1], [disable OpenMP support]) 92 | fi 93 | 94 | AC_CONFIG_FILES([Makefile]) 95 | 96 | AC_OUTPUT 97 | -------------------------------------------------------------------------------- /.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/YAML_Doc.hpp: -------------------------------------------------------------------------------- 1 | 2 | //@HEADER 3 | // *************************************************** 4 | // 5 | // HPCG: High Performance Conjugate Gradient Benchmark 6 | // 7 | // Contact: 8 | // Michael A. Heroux ( maherou@sandia.gov) 9 | // Jack Dongarra (dongarra@eecs.utk.edu) 10 | // Piotr Luszczek (luszczek@eecs.utk.edu) 11 | // 12 | // *************************************************** 13 | //@HEADER 14 | 15 | /*! 16 | @file YAML_Doc.hpp 17 | 18 | HPCG YAML classes 19 | */ 20 | 21 | // Changelog 22 | // 23 | // Version 0.1 24 | // - Initial version. 25 | // 26 | ///////////////////////////////////////////////////////////////////////// 27 | 28 | #ifndef YAML_DOC_HPP 29 | #define YAML_DOC_HPP 30 | #include 31 | #include "YAML_Element.hpp" 32 | 33 | //! The YAML_Doc class for the uniform collecting and reporting of performance data for HPCG 34 | 35 | /*! 36 | 37 | The YAML_Doc class works in conjunction with the YAML_Element class to facilitate easy collecting and reporting of YAML-formatted 38 | data that can be then registered with the HPCG results collection website. 39 | 40 | \code 41 | 42 | //EXAMPLE CODE FOR GENERATING YAML 43 | 44 | YAML_Doc doc("hpcg","0.1"); 45 | doc.add("final_residual",1.4523e-13); 46 | doc.add("time","4.893"); 47 | 48 | //note: the following line will remove the data (4.890) associated with "time" 49 | doc.get("time")->add("total",4.243); 50 | 51 | //note: the following line will likewise remove the data (1.243) associated with "time" 52 | doc.get("time")->get("total")->add("time",2.457); 53 | doc.get("time")->get("total")->add("flops",4.88e5); 54 | doc.get("time")->add("ddot",1.243); 55 | doc.get("time")->add("sparsemv",""); 56 | doc.get("time")->get("sparsemv")->add("time",0.3445); 57 | doc.get("time")->get("sparsemv")->add("overhead",""); 58 | doc.get("time")->get("sparsemv")->get("overhead")->add("time",0.0123); 59 | doc.get("time")->get("sparsemv")->get("overhead")->add("percentage",0.034); 60 | cout << doc.generateYAML() << endl; 61 | return 0; 62 | 63 | \endcode 64 | 65 | Below is the output generated by the above code: 66 | 67 | \verbatim 68 | 69 | final_residual: 1.4523e-13 70 | time: 71 | total: 72 | time: 2.457 73 | flops: 4.88e5 74 | ddot: 1.243 75 | sparsemv: 76 | time: 0.3445 77 | overhead: 78 | time: 0.0123 79 | percentage: 0.034 80 | 81 | \endverbatim 82 | 83 | \note {No value is allowed to be attached to a key that has children. If children are added to a key, the value is simply set to "".} 84 | 85 | */ 86 | class YAML_Doc: public YAML_Element { 87 | public: 88 | //! Constructor: accepts mini-application name and version as strings, optionally accepts directory and file name for printing results. 89 | /*! 90 | The sole constructor for this class accepts and name and version number for the mini-application as well as optional directory 91 | and file name information for results that are generated by the generateYAML() method. 92 | \param miniApp_Name (in) string containing name of the mini-application 93 | \param miniApp_Version (in) string containing the version of the mini-application 94 | \param destination_Directory (in, optional) path of directory where results file will be stored, relative to current working directory. 95 | If this value is not supplied, the results file will be stored in the current working directory. If the directory does not exist 96 | it will be created. 97 | \param destination_FileName (in, optional) root name of the results file. A suffix of ".yaml" will be automatically appended. If no 98 | file name is specified the filename will be constructed by concatenating the miniAppName + miniAppVersion + ".yaml" strings. 99 | */ 100 | YAML_Doc(const std::string & miniApp_Name, const std::string & miniApp_Version, const std::string & destination_Directory = "", const std::string & destination_FileName = ""); 101 | //! Destructor 102 | ~YAML_Doc(); 103 | //! Generate YAML results to standard out and to a file using specified directory and filename, using current directory and miniAppName + miniAppVersion + ".yaml" by default 104 | std::string generateYAML(); 105 | 106 | protected: 107 | std::string miniAppName; //!< the name of the application that generated the YAML output 108 | std::string miniAppVersion; //!< the version of the application that generated the YAML output 109 | std::string destinationDirectory; //!< the destination directory for the generated the YAML output 110 | std::string destinationFileName; //!< the filename for the generated the YAML output 111 | }; 112 | #endif // YAML_DOC_HPP 113 | -------------------------------------------------------------------------------- /src/ComputeOptimalShapeXYZ.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef HPCG_CUBIC_RADICAL_SEARCH 6 | #include 7 | #endif 8 | #include 9 | 10 | #include "ComputeOptimalShapeXYZ.hpp" 11 | #include "MixedBaseCounter.hpp" 12 | 13 | #ifdef HPCG_CUBIC_RADICAL_SEARCH 14 | static int 15 | min3(int a, int b, int c) { 16 | return std::min(a, std::min(b, c)); 17 | } 18 | 19 | static int 20 | max3(int a, int b, int c) { 21 | return std::max(a, std::max(b, c)); 22 | } 23 | 24 | static void 25 | cubic_radical_search(int n, int & x, int & y, int & z) { 26 | double best = 0.0; 27 | 28 | for (int f1 = (int)(pow(n,1.0/3.0)+0.5); f1 > 0; --f1) 29 | if (n % f1 == 0) { 30 | int n1 = n/f1; 31 | for (int f2 = (int)(pow(n1,0.5)+0.5); f2 > 0; --f2) 32 | if (n1 % f2 == 0) { 33 | int f3 = n1 / f2; 34 | double current = (double)min3(f1, f2, f3)/max3(f1, f2, f3); 35 | if (current > best) { 36 | best = current; 37 | x = f1; 38 | y = f2; 39 | z = f3; 40 | } 41 | } 42 | } 43 | } 44 | 45 | #else 46 | 47 | static void 48 | ComputePrimeFactors(int n, std::map & factors) { 49 | int d, sq = int((sqrt(double(n)))+1L); 50 | div_t r; 51 | 52 | // remove 2 as a factor with shifts instead "/" and "%" 53 | for (; n > 1 && (n & 1) == 0; n >>= 1) { 54 | factors[2]++; 55 | } 56 | 57 | // keep removing subsequent odd numbers 58 | for (d = 3; d <= sq; d += 2) { 59 | while (1) { 60 | r = div(n, d); 61 | if (r.rem == 0) { 62 | factors[d]++; 63 | n = r.quot; 64 | continue; 65 | } 66 | break; 67 | } 68 | } 69 | if (n > 1 || factors.size() == 0) // left with a prime or x==1 70 | factors[n]++; 71 | } 72 | 73 | static int 74 | pow_i(int x, int p) { 75 | int v; 76 | 77 | if (0 == x || 1 == x) return x; 78 | 79 | if (p < 0) 80 | return 0; 81 | 82 | for (v = 1; p; p >>= 1) { 83 | if (1 & p) 84 | v *= x; 85 | x *= x; 86 | } 87 | 88 | return v; 89 | } 90 | 91 | #endif 92 | 93 | void 94 | ComputeOptimalShapeXYZ(int xyz, int & x, int & y, int & z) { 95 | #ifdef HPCG_CUBIC_RADICAL_SEARCH 96 | cubic_radical_search( xyz, x, y, z); 97 | #else 98 | std::map factors; 99 | 100 | ComputePrimeFactors( xyz, factors ); // factors are sorted: ascending order 101 | 102 | std::map::iterator iter = factors.begin(); 103 | 104 | // there is at least one prime factor 105 | x = (iter++)->first; // cache the first factor, move to the next one 106 | 107 | y = iter != factors.end() ? (iter++)->first : y; // try to cache the second factor in "y" 108 | 109 | if (factors.size() == 1) { // only a single factor 110 | z = pow_i(x, factors[x] / 3); 111 | y = pow_i(x, factors[x] / 3 + ((factors[x] % 3) >= 2 ? 1 : 0)); 112 | x = pow_i(x, factors[x] / 3 + ((factors[x] % 3) >= 1 ? 1 : 0)); 113 | 114 | } else if (factors.size() == 2 && factors[x] == 1 && factors[y] == 1) { // two distinct prime factors 115 | z = 1; 116 | 117 | } else if (factors.size() == 2 && factors[x] + factors[y] == 3) { // three prime factors, one repeated 118 | z = factors[x] == 2 ? x : y; // test which factor is repeated 119 | 120 | } else if (factors.size() == 3 && factors[x] == 1 && factors[y] == 1 && iter->second == 1) { // three distinct and single prime factors 121 | z = iter->first; 122 | 123 | } else { // 3 or more prime factors so try all possible 3-subsets 124 | 125 | int i, distinct_factors[32+1], count_factors[32+1]; 126 | 127 | i = 0; 128 | for (std::map::iterator iter = factors.begin(); iter != factors.end(); ++iter, ++i) { 129 | distinct_factors[i] = iter->first; 130 | count_factors[i] = iter->second; 131 | } 132 | 133 | // count total number of prime factors in "c_main" and distribute some factors into "c1" 134 | MixedBaseCounter c_main(count_factors, factors.size()), c1(count_factors, factors.size()); 135 | 136 | // at the beginning, minimum area is the maximum area 137 | double area, min_area = 2.0 * xyz + 1.0; 138 | 139 | for (c1.next(); ! c1.is_zero(); c1.next()) { 140 | MixedBaseCounter c2(c_main, c1); // "c2" gets the factors remaining in "c_main" that "c1" doesn't have 141 | for (c2.next(); ! c2.is_zero(); c2.next()) { 142 | int tf1 = c1.product(distinct_factors); 143 | int tf2 = c2.product(distinct_factors); 144 | int tf3 = xyz / tf1/ tf2; // we derive the third dimension, we don't keep track of the factors it has 145 | 146 | area = tf1 * double(tf2) + tf2 * double(tf3) + tf1 * double(tf3); 147 | if (area < min_area) { 148 | min_area = area; 149 | x = tf1; 150 | y = tf2; 151 | z = tf3; 152 | } 153 | } 154 | } 155 | } 156 | #endif 157 | } 158 | --------------------------------------------------------------------------------