├── 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 | Events - SC14 Birds-of-a-Feather
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 | Resources
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 | Results
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 |
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 |
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 | Events
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 | Packages
12 |
13 |
14 | Versions of HPCG:
15 |
16 | Reference: HPCG 2.4 Reference code (June 3, 2014)
17 | Reference: HPCG 2.3 Reference code (June 2, 2014)
18 | Reference: HPCG 2.2 Reference code (May 27, 2014)
19 | Reference: HPCG 2.1 Reference code (January 31, 2014)
20 | Reference: HPCG 2.0 Reference code (January 28, 2014)
21 | Reference: HPCG 1.1 Reference code (November 26, 2013)
22 | Reference: HPCG 1.0 Reference code (November 19, 2013)
23 | Reference: HPCG 0.5 Reference code (October 25, 2013)
24 | Reference: HPCG 0.4 Reference code (October 21, 2013)
25 | Reference: HPCG 0.3 Reference code (September 25, 2013)
26 |
27 |
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 | Announce list:
31 | subscribe
32 |
33 |
34 |
35 | Users list:
36 | subscribe
37 |
38 |
39 |
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 | Download
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 |
29 | Previous versions of HPCG:
30 |
41 |
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 | About
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 | FAQ
12 |
13 |
14 | 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 | 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 | 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 |
51 |
52 | 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 |
60 |
61 | 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 |
67 |
68 | 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 |
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 | 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 |
56 |
57 | Home
58 | Results
59 | About
60 | Resources
61 | Events
62 | FAQ
63 | Download
64 |
65 |
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 |
5 | getNav()); ?>
6 |
7 | getPageIdentifier() == "home") { ?>
8 |
9 |
14 |
15 |
16 |
17 |
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 |
--------------------------------------------------------------------------------