From 290fb275faf4dd504d661e3fb441d13deec50f9a Mon Sep 17 00:00:00 2001 From: Verinder Rana Date: Fri, 15 May 2020 15:57:37 -0700 Subject: [PATCH 01/12] Initial vec feature added in add --- scripts/lc-builds/toss3_clang8.0.1.sh | 1 + src/common/KernelBase.cpp | 1 + src/common/RAJAPerfSuite.cpp | 1 + src/common/RAJAPerfSuite.hpp | 1 + src/polybench/POLYBENCH_2MM-OMP.cpp | 37 +++++++------- src/polybench/POLYBENCH_2MM-Seq.cpp | 47 +++++++++--------- src/polybench/POLYBENCH_3MM-OMP.cpp | 52 ++++++++++---------- src/polybench/POLYBENCH_3MM-Seq.cpp | 64 ++++++++++++------------- src/polybench/POLYBENCH_ADI-OMP.cpp | 24 +++++----- src/polybench/POLYBENCH_ADI-Seq.cpp | 24 +++++----- src/polybench/POLYBENCH_ATAX-OMP.cpp | 32 ++++++------- src/polybench/POLYBENCH_ATAX-Seq.cpp | 32 ++++++------- src/polybench/POLYBENCH_GEMM-OMP.cpp | 24 +++++----- src/polybench/POLYBENCH_GEMM-Seq.cpp | 25 +++++----- src/polybench/POLYBENCH_GEMVER-OMP.cpp | 46 +++++++++++------- src/polybench/POLYBENCH_GEMVER-Seq.cpp | 51 +++++++++++--------- src/polybench/POLYBENCH_GESUMMV-OMP.cpp | 12 ++--- src/polybench/POLYBENCH_GESUMMV-Seq.cpp | 11 ++--- src/polybench/POLYBENCH_MVT-OMP.cpp | 28 +++++------ src/polybench/POLYBENCH_MVT-Seq.cpp | 28 +++++------ src/stream/ADD-Seq.cpp | 21 +++++++- src/stream/ADD.hpp | 9 +++- tpl/RAJA | 2 +- 23 files changed, 299 insertions(+), 274 deletions(-) diff --git a/scripts/lc-builds/toss3_clang8.0.1.sh b/scripts/lc-builds/toss3_clang8.0.1.sh index b265c0486..00676c40f 100755 --- a/scripts/lc-builds/toss3_clang8.0.1.sh +++ b/scripts/lc-builds/toss3_clang8.0.1.sh @@ -19,6 +19,7 @@ module load cmake/3.14.5 cmake \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_CXX_COMPILER=/usr/tce/packages/clang/clang-8.0.1/bin/clang++ \ + -DCMAKE_CXX_FLAGS="-mavx2" \ -C ${RAJA_HOSTCONFIG} \ -DENABLE_OPENMP=On \ -DCMAKE_INSTALL_PREFIX=../install_${BUILD_SUFFIX} \ diff --git a/src/common/KernelBase.cpp b/src/common/KernelBase.cpp index 938abb501..3ae3edf84 100644 --- a/src/common/KernelBase.cpp +++ b/src/common/KernelBase.cpp @@ -88,6 +88,7 @@ void KernelBase::runKernel(VariantID vid) #if defined(RUN_RAJA_SEQ) case Lambda_Seq : case RAJA_Seq : + case RAJA_Vec: #endif { runSeqVariant(vid); diff --git a/src/common/RAJAPerfSuite.cpp b/src/common/RAJAPerfSuite.cpp index 13649f5de..3e2704aaf 100644 --- a/src/common/RAJAPerfSuite.cpp +++ b/src/common/RAJAPerfSuite.cpp @@ -214,6 +214,7 @@ static const std::string VariantNames [] = #if defined(RUN_RAJA_SEQ) std::string("Lambda_Seq"), std::string("RAJA_Seq"), + std::string("RAJA_Vec"), #endif #if defined(RAJA_ENABLE_OPENMP) && defined(RUN_OPENMP) diff --git a/src/common/RAJAPerfSuite.hpp b/src/common/RAJAPerfSuite.hpp index 848c7dc68..a56269dd8 100644 --- a/src/common/RAJAPerfSuite.hpp +++ b/src/common/RAJAPerfSuite.hpp @@ -185,6 +185,7 @@ enum VariantID { #if defined(RUN_RAJA_SEQ) Lambda_Seq, RAJA_Seq, + RAJA_Vec, #endif #if defined(RAJA_ENABLE_OPENMP) && defined(RUN_OPENMP) diff --git a/src/polybench/POLYBENCH_2MM-OMP.cpp b/src/polybench/POLYBENCH_2MM-OMP.cpp index b9e9a3b7c..ca66bbdfa 100644 --- a/src/polybench/POLYBENCH_2MM-OMP.cpp +++ b/src/polybench/POLYBENCH_2MM-OMP.cpp @@ -53,26 +53,25 @@ void POLYBENCH_2MM::runOpenMPVariant(VariantID vid) POLYBENCH_2MM_VIEWS_RAJA; - auto poly_2mm_lam1 = [=](Index_type /*i*/, Index_type /*j*/, Index_type /*k*/, Real_type &dot) { + auto poly_2mm_lam1 = [=](Real_type &dot) { POLYBENCH_2MM_BODY1_RAJA; }; auto poly_2mm_lam2 = [=](Index_type i, Index_type j, Index_type k, Real_type &dot) { POLYBENCH_2MM_BODY2_RAJA; }; - auto poly_2mm_lam3 = [=](Index_type i, Index_type j, Index_type /*k*/, + auto poly_2mm_lam3 = [=](Index_type i, Index_type j, Real_type &dot) { POLYBENCH_2MM_BODY3_RAJA; }; - auto poly_2mm_lam4 = [=](Index_type /*i*/, Index_type /*l*/, Index_type /*j*/, - Real_type &dot) { + auto poly_2mm_lam4 = [=](Real_type &dot) { POLYBENCH_2MM_BODY4_RAJA; }; auto poly_2mm_lam5 = [=](Index_type i, Index_type l, Index_type j, Real_type &dot) { POLYBENCH_2MM_BODY5_RAJA; }; - auto poly_2mm_lam6 = [=](Index_type i, Index_type l, Index_type /*j*/, + auto poly_2mm_lam6 = [=](Index_type i, Index_type l, Real_type &dot) { POLYBENCH_2MM_BODY6_RAJA; }; @@ -168,11 +167,11 @@ void POLYBENCH_2MM::runOpenMPVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::Collapse, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1,2>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0,1>, RAJA::Params<0>> > >; #else // without collapse... @@ -180,11 +179,11 @@ void POLYBENCH_2MM::runOpenMPVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_parallel_for_exec, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1,2>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0,1>, RAJA::Params<0>> > > >; @@ -194,10 +193,10 @@ void POLYBENCH_2MM::runOpenMPVariant(VariantID vid) for (RepIndex_type irep = 0; irep < run_reps; ++irep) { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nk}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nk)), + RAJA::tuple {0.0}, poly_2mm_lam1, poly_2mm_lam2, @@ -205,10 +204,10 @@ void POLYBENCH_2MM::runOpenMPVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nl}, - RAJA::RangeSegment{0, nj}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nl), + RAJA::RangeSegment(0, nj)), + RAJA::tuple {0.0}, poly_2mm_lam4, poly_2mm_lam5, diff --git a/src/polybench/POLYBENCH_2MM-Seq.cpp b/src/polybench/POLYBENCH_2MM-Seq.cpp index 46393963c..260129f89 100644 --- a/src/polybench/POLYBENCH_2MM-Seq.cpp +++ b/src/polybench/POLYBENCH_2MM-Seq.cpp @@ -43,27 +43,24 @@ void POLYBENCH_2MM::runSeqVariant(VariantID vid) POLYBENCH_2MM_VIEWS_RAJA; - auto poly_2mm_lam1 = [=](Index_type /*i*/, Index_type /*j*/, Index_type /*k*/, Real_type &dot) { + auto poly_2mm_lam1 = [=](Real_type &dot) { POLYBENCH_2MM_BODY1_RAJA; }; auto poly_2mm_lam2 = [=](Index_type i, Index_type j, Index_type k, Real_type &dot) { POLYBENCH_2MM_BODY2_RAJA; }; - auto poly_2mm_lam3 = [=](Index_type i, Index_type j, Index_type /*k*/, - Real_type &dot) { + auto poly_2mm_lam3 = [=](Index_type i, Index_type j, Real_type &dot) { POLYBENCH_2MM_BODY3_RAJA; }; - auto poly_2mm_lam4 = [=](Index_type /*i*/, Index_type /*l*/, Index_type /*j*/, - Real_type &dot) { + auto poly_2mm_lam4 = [=](Real_type &dot) { POLYBENCH_2MM_BODY4_RAJA; }; auto poly_2mm_lam5 = [=](Index_type i, Index_type l, Index_type j, Real_type &dot) { POLYBENCH_2MM_BODY5_RAJA; }; - auto poly_2mm_lam6 = [=](Index_type i, Index_type l, Index_type /*j*/, - Real_type &dot) { + auto poly_2mm_lam6 = [=](Index_type i, Index_type l, Real_type &dot) { POLYBENCH_2MM_BODY6_RAJA; }; @@ -137,36 +134,36 @@ void POLYBENCH_2MM::runSeqVariant(VariantID vid) using EXEC_POL = RAJA::KernelPolicy< - RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0>, - RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<1> - >, - RAJA::statement::Lambda<2> + RAJA::statement::For<0, RAJA::loop_exec, + RAJA::statement::For<1, RAJA::loop_exec, + RAJA::statement::Lambda<0, RAJA::Params<0>>, + RAJA::statement::For<2, RAJA::loop_exec, + RAJA::statement::Lambda<1, RAJA::Segs<0,1,2>, RAJA::Params<0>>, + RAJA::statement::Lambda<2, RAJA::Segs<0,1>, RAJA::Params<0>> > > + > >; startTimer(); for (RepIndex_type irep = 0; irep < run_reps; ++irep) { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nk}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nk)), + RAJA::tuple {0.0}, - poly_2mm_lam1, - poly_2mm_lam2, + poly_2mm_lam1, + poly_2mm_lam2, poly_2mm_lam3 - ); + ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nl}, - RAJA::RangeSegment{0, nj}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nl), + RAJA::RangeSegment(0, nj)), + RAJA::tuple {0.0}, poly_2mm_lam4, poly_2mm_lam5, diff --git a/src/polybench/POLYBENCH_3MM-OMP.cpp b/src/polybench/POLYBENCH_3MM-OMP.cpp index 175516c5e..faddcde5b 100644 --- a/src/polybench/POLYBENCH_3MM-OMP.cpp +++ b/src/polybench/POLYBENCH_3MM-OMP.cpp @@ -62,41 +62,37 @@ void POLYBENCH_3MM::runOpenMPVariant(VariantID vid) POLYBENCH_3MM_VIEWS_RAJA; - auto poly_3mm_lam1 = [=] (Index_type /*i*/, Index_type /*j*/, Index_type /*k*/, - Real_type &dot) { + auto poly_3mm_lam1 = [=] ( Real_type &dot) { POLYBENCH_3MM_BODY1_RAJA; }; auto poly_3mm_lam2 = [=] (Index_type i, Index_type j, Index_type k, Real_type &dot) { POLYBENCH_3MM_BODY2_RAJA; }; - auto poly_3mm_lam3 = [=] (Index_type i, Index_type j, Index_type /*k*/, + auto poly_3mm_lam3 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_3MM_BODY3_RAJA; }; - auto poly_3mm_lam4 = [=] (Index_type /*j*/, Index_type /*l*/, Index_type /*m*/, - Real_type &dot) { + auto poly_3mm_lam4 = [=] (Real_type &dot) { POLYBENCH_3MM_BODY4_RAJA; }; auto poly_3mm_lam5 = [=] (Index_type j, Index_type l, Index_type m, Real_type &dot) { POLYBENCH_3MM_BODY5_RAJA; }; - auto poly_3mm_lam6 = [=] (Index_type j, Index_type l, Index_type /*m*/, + auto poly_3mm_lam6 = [=] (Index_type j, Index_type l, Real_type &dot) { POLYBENCH_3MM_BODY6_RAJA; }; - auto poly_3mm_lam7 = [=] (Index_type /*i*/, Index_type /*l*/, Index_type /*j*/, - Real_type &dot) { + auto poly_3mm_lam7 = [=] (Real_type &dot) { POLYBENCH_3MM_BODY7_RAJA; }; auto poly_3mm_lam8 = [=] (Index_type i, Index_type l, Index_type j, Real_type &dot) { POLYBENCH_3MM_BODY8_RAJA; }; - auto poly_3mm_lam9 = [=] (Index_type i, Index_type l, Index_type /*j*/, - Real_type &dot) { + auto poly_3mm_lam9 = [=] (Index_type i, Index_type l, Real_type &dot) { POLYBENCH_3MM_BODY9_RAJA; }; @@ -221,11 +217,11 @@ void POLYBENCH_3MM::runOpenMPVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::Collapse, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1,2>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0,1>, RAJA::Params<0>> > >; #else @@ -233,11 +229,11 @@ void POLYBENCH_3MM::runOpenMPVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_parallel_for_exec, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1,2>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0,1>, RAJA::Params<0>> > > >; @@ -247,10 +243,10 @@ void POLYBENCH_3MM::runOpenMPVariant(VariantID vid) for (RepIndex_type irep = 0; irep < run_reps; ++irep) { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nk}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nk)), + RAJA::tuple {0.0}, poly_3mm_lam1, poly_3mm_lam2, @@ -259,10 +255,10 @@ void POLYBENCH_3MM::runOpenMPVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nl}, - RAJA::RangeSegment{0, nm}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nl), + RAJA::RangeSegment(0, nm)), + RAJA::tuple {0.0}, poly_3mm_lam4, poly_3mm_lam5, @@ -271,10 +267,10 @@ void POLYBENCH_3MM::runOpenMPVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nl}, - RAJA::RangeSegment{0, nj}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nl), + RAJA::RangeSegment(0, nj)), + RAJA::tuple{0.0}, poly_3mm_lam7, poly_3mm_lam8, diff --git a/src/polybench/POLYBENCH_3MM-Seq.cpp b/src/polybench/POLYBENCH_3MM-Seq.cpp index 95e753e12..9d1dd8424 100644 --- a/src/polybench/POLYBENCH_3MM-Seq.cpp +++ b/src/polybench/POLYBENCH_3MM-Seq.cpp @@ -53,41 +53,39 @@ void POLYBENCH_3MM::runSeqVariant(VariantID vid) POLYBENCH_3MM_VIEWS_RAJA; - auto poly_3mm_lam1 = [=] (Index_type /*i*/, Index_type /*j*/, Index_type /*k*/, - Real_type &dot) { + auto poly_3mm_lam1 = [=] (Real_type &dot) { POLYBENCH_3MM_BODY1_RAJA; }; - auto poly_3mm_lam2 = [=] (Index_type i, Index_type j, Index_type k, - Real_type &dot) { + + auto poly_3mm_lam2 = [=] (Index_type i, Index_type j, Index_type k, Real_type &dot) { POLYBENCH_3MM_BODY2_RAJA; }; - auto poly_3mm_lam3 = [=] (Index_type i, Index_type j, Index_type /*k*/, - Real_type &dot) { + + auto poly_3mm_lam3 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_3MM_BODY3_RAJA; }; - auto poly_3mm_lam4 = [=] (Index_type /*j*/, Index_type /*l*/, Index_type /*m*/, - Real_type &dot) { + auto poly_3mm_lam4 = [=] (Real_type &dot) { POLYBENCH_3MM_BODY4_RAJA; }; - auto poly_3mm_lam5 = [=] (Index_type j, Index_type l, Index_type m, - Real_type &dot) { + + auto poly_3mm_lam5 = [=] (Index_type j, Index_type l, Index_type m, Real_type &dot) { POLYBENCH_3MM_BODY5_RAJA; }; - auto poly_3mm_lam6 = [=] (Index_type j, Index_type l, Index_type /*m*/, - Real_type &dot) { + + auto poly_3mm_lam6 = [=] (Index_type j, Index_type l, Real_type &dot) { POLYBENCH_3MM_BODY6_RAJA; }; - auto poly_3mm_lam7 = [=] (Index_type /*i*/, Index_type /*l*/, Index_type /*j*/, - Real_type &dot) { + + auto poly_3mm_lam7 = [=] (Real_type &dot) { POLYBENCH_3MM_BODY7_RAJA; }; - auto poly_3mm_lam8 = [=] (Index_type i, Index_type l, Index_type j, - Real_type &dot) { + + auto poly_3mm_lam8 = [=] (Index_type i, Index_type l, Index_type j, Real_type &dot) { POLYBENCH_3MM_BODY8_RAJA; }; - auto poly_3mm_lam9 = [=] (Index_type i, Index_type l, Index_type /*j*/, - Real_type &dot) { + + auto poly_3mm_lam9 = [=] (Index_type i, Index_type l, Real_type &dot) { POLYBENCH_3MM_BODY9_RAJA; }; @@ -182,11 +180,11 @@ void POLYBENCH_3MM::runSeqVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1,2>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0,1>, RAJA::Params<0>> > > >; @@ -195,10 +193,10 @@ void POLYBENCH_3MM::runSeqVariant(VariantID vid) for (RepIndex_type irep = 0; irep < run_reps; ++irep) { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nk}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nk)), + RAJA::tuple{0.0}, poly_3mm_lam1, poly_3mm_lam2, @@ -207,10 +205,10 @@ void POLYBENCH_3MM::runSeqVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nl}, - RAJA::RangeSegment{0, nm}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nl), + RAJA::RangeSegment(0, nm)), + RAJA::tuple{0.0}, poly_3mm_lam4, poly_3mm_lam5, @@ -219,10 +217,10 @@ void POLYBENCH_3MM::runSeqVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nl}, - RAJA::RangeSegment{0, nj}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nl), + RAJA::RangeSegment(0, nj)), + RAJA::tuple{0.0}, poly_3mm_lam7, poly_3mm_lam8, diff --git a/src/polybench/POLYBENCH_ADI-OMP.cpp b/src/polybench/POLYBENCH_ADI-OMP.cpp index fa715da4f..a7818126b 100644 --- a/src/polybench/POLYBENCH_ADI-OMP.cpp +++ b/src/polybench/POLYBENCH_ADI-OMP.cpp @@ -54,28 +54,28 @@ void POLYBENCH_ADI::runOpenMPVariant(VariantID vid) POLYBENCH_ADI_VIEWS_RAJA; - auto poly_adi_lam2 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam2 = [=](Index_type i) { POLYBENCH_ADI_BODY2_RAJA; }; - auto poly_adi_lam3 = [=](Index_type i, Index_type j, Index_type /*k*/) { + auto poly_adi_lam3 = [=](Index_type i, Index_type j) { POLYBENCH_ADI_BODY3_RAJA; }; - auto poly_adi_lam4 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam4 = [=](Index_type i) { POLYBENCH_ADI_BODY4_RAJA; }; - auto poly_adi_lam5 = [=](Index_type i, Index_type /*j*/, Index_type k) { + auto poly_adi_lam5 = [=](Index_type i, Index_type k) { POLYBENCH_ADI_BODY5_RAJA; }; - auto poly_adi_lam6 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam6 = [=](Index_type i) { POLYBENCH_ADI_BODY6_RAJA; }; - auto poly_adi_lam7 = [=](Index_type i, Index_type j, Index_type /*k*/) { + auto poly_adi_lam7 = [=](Index_type i, Index_type j) { POLYBENCH_ADI_BODY7_RAJA; }; - auto poly_adi_lam8 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam8 = [=](Index_type i) { POLYBENCH_ADI_BODY8_RAJA; }; - auto poly_adi_lam9 = [=](Index_type i, Index_type /*j*/, Index_type k) { + auto poly_adi_lam9 = [=](Index_type i, Index_type k) { POLYBENCH_ADI_BODY9_RAJA; }; @@ -164,13 +164,13 @@ void POLYBENCH_ADI::runOpenMPVariant(VariantID vid) using EXEC_POL = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_parallel_for_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Segs<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>> >, - RAJA::statement::Lambda<2>, + RAJA::statement::Lambda<2, RAJA::Segs<0>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<3> + RAJA::statement::Lambda<3, RAJA::Segs<0,2>> > > >; diff --git a/src/polybench/POLYBENCH_ADI-Seq.cpp b/src/polybench/POLYBENCH_ADI-Seq.cpp index 0333f0b72..f19e3f81f 100644 --- a/src/polybench/POLYBENCH_ADI-Seq.cpp +++ b/src/polybench/POLYBENCH_ADI-Seq.cpp @@ -51,28 +51,28 @@ void POLYBENCH_ADI::runSeqVariant(VariantID vid) POLYBENCH_ADI_VIEWS_RAJA; - auto poly_adi_lam2 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam2 = [=](Index_type i) { POLYBENCH_ADI_BODY2_RAJA; }; - auto poly_adi_lam3 = [=](Index_type i, Index_type j, Index_type /*k*/) { + auto poly_adi_lam3 = [=](Index_type i, Index_type j) { POLYBENCH_ADI_BODY3_RAJA; }; - auto poly_adi_lam4 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam4 = [=](Index_type i) { POLYBENCH_ADI_BODY4_RAJA; }; - auto poly_adi_lam5 = [=](Index_type i, Index_type /*j*/, Index_type k) { + auto poly_adi_lam5 = [=](Index_type i, Index_type k) { POLYBENCH_ADI_BODY5_RAJA; }; - auto poly_adi_lam6 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam6 = [=](Index_type i) { POLYBENCH_ADI_BODY6_RAJA; }; - auto poly_adi_lam7 = [=](Index_type i, Index_type j, Index_type /*k*/) { + auto poly_adi_lam7 = [=](Index_type i, Index_type j) { POLYBENCH_ADI_BODY7_RAJA; }; - auto poly_adi_lam8 = [=](Index_type i, Index_type /*j*/, Index_type /*k*/) { + auto poly_adi_lam8 = [=](Index_type i) { POLYBENCH_ADI_BODY8_RAJA; }; - auto poly_adi_lam9 = [=](Index_type i, Index_type /*j*/, Index_type k) { + auto poly_adi_lam9 = [=](Index_type i, Index_type k) { POLYBENCH_ADI_BODY9_RAJA; }; @@ -158,13 +158,13 @@ void POLYBENCH_ADI::runSeqVariant(VariantID vid) using EXEC_POL = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Segs<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>> >, - RAJA::statement::Lambda<2>, + RAJA::statement::Lambda<2, RAJA::Segs<0>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<3> + RAJA::statement::Lambda<3, RAJA::Segs<0,2>> > > >; diff --git a/src/polybench/POLYBENCH_ATAX-OMP.cpp b/src/polybench/POLYBENCH_ATAX-OMP.cpp index 6580b4f70..9ae619b1b 100644 --- a/src/polybench/POLYBENCH_ATAX-OMP.cpp +++ b/src/polybench/POLYBENCH_ATAX-OMP.cpp @@ -42,22 +42,22 @@ void POLYBENCH_ATAX::runOpenMPVariant(VariantID vid) POLYBENCH_ATAX_VIEWS_RAJA; - auto poly_atax_lam1 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_atax_lam1 = [=] (Index_type i, Real_type &dot) { POLYBENCH_ATAX_BODY1_RAJA; }; auto poly_atax_lam2 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_ATAX_BODY2_RAJA; }; - auto poly_atax_lam3 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_atax_lam3 = [=] (Index_type i, Real_type &dot) { POLYBENCH_ATAX_BODY3_RAJA; }; - auto poly_atax_lam4 = [=] (Index_type /* i */, Index_type j, Real_type &dot) { + auto poly_atax_lam4 = [=] (Index_type j, Real_type &dot) { POLYBENCH_ATAX_BODY4_RAJA; }; auto poly_atax_lam5 = [=] (Index_type i, Index_type j , Real_type &dot) { POLYBENCH_ATAX_BODY5_RAJA; }; - auto poly_atax_lam6 = [=] (Index_type /* i */, Index_type j, Real_type &dot) { + auto poly_atax_lam6 = [=] (Index_type j, Real_type &dot) { POLYBENCH_ATAX_BODY6_RAJA; }; @@ -126,22 +126,22 @@ void POLYBENCH_ATAX::runOpenMPVariant(VariantID vid) using EXEC_POL1 = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_parallel_for_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Segs<0>, RAJA::Params<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> > >; using EXEC_POL2 = RAJA::KernelPolicy< RAJA::statement::For<1, RAJA::omp_parallel_for_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Segs<1>, RAJA::Params<0>>, RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<1>, RAJA::Params<0>> > >; @@ -150,9 +150,9 @@ void POLYBENCH_ATAX::runOpenMPVariant(VariantID vid) for (RepIndex_type irep = 0; irep < run_reps; ++irep) { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple{0.0}, poly_atax_lam1, poly_atax_lam2, @@ -161,9 +161,9 @@ void POLYBENCH_ATAX::runOpenMPVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple{0.0}, poly_atax_lam4, poly_atax_lam5, diff --git a/src/polybench/POLYBENCH_ATAX-Seq.cpp b/src/polybench/POLYBENCH_ATAX-Seq.cpp index 11366e9a6..7fa840339 100644 --- a/src/polybench/POLYBENCH_ATAX-Seq.cpp +++ b/src/polybench/POLYBENCH_ATAX-Seq.cpp @@ -39,22 +39,22 @@ void POLYBENCH_ATAX::runSeqVariant(VariantID vid) POLYBENCH_ATAX_VIEWS_RAJA; - auto poly_atax_lam1 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_atax_lam1 = [=] (Index_type i, Real_type &dot) { POLYBENCH_ATAX_BODY1_RAJA; }; auto poly_atax_lam2 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_ATAX_BODY2_RAJA; }; - auto poly_atax_lam3 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_atax_lam3 = [=] (Index_type i, Real_type &dot) { POLYBENCH_ATAX_BODY3_RAJA; }; - auto poly_atax_lam4 = [=] (Index_type /* i */, Index_type j, Real_type &dot) { + auto poly_atax_lam4 = [=] (Index_type j, Real_type &dot) { POLYBENCH_ATAX_BODY4_RAJA; }; auto poly_atax_lam5 = [=] (Index_type i, Index_type j , Real_type &dot) { POLYBENCH_ATAX_BODY5_RAJA; }; - auto poly_atax_lam6 = [=] (Index_type /* i */, Index_type j, Real_type &dot) { + auto poly_atax_lam6 = [=] (Index_type j, Real_type &dot) { POLYBENCH_ATAX_BODY6_RAJA; }; @@ -121,22 +121,22 @@ void POLYBENCH_ATAX::runSeqVariant(VariantID vid) using EXEC_POL1 = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Segs<0>, RAJA::Params<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> > >; using EXEC_POL2 = RAJA::KernelPolicy< RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Segs<1>, RAJA::Params<0>>, RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<1>, RAJA::Params<0>> > >; @@ -145,9 +145,9 @@ void POLYBENCH_ATAX::runSeqVariant(VariantID vid) for (RepIndex_type irep = 0; irep < run_reps; ++irep) { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple{0.0}, poly_atax_lam1, poly_atax_lam2, @@ -156,9 +156,9 @@ void POLYBENCH_ATAX::runSeqVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple{0.0}, poly_atax_lam4, poly_atax_lam5, diff --git a/src/polybench/POLYBENCH_GEMM-OMP.cpp b/src/polybench/POLYBENCH_GEMM-OMP.cpp index ce7dd4f21..fe2df03b0 100644 --- a/src/polybench/POLYBENCH_GEMM-OMP.cpp +++ b/src/polybench/POLYBENCH_GEMM-OMP.cpp @@ -41,19 +41,17 @@ void POLYBENCH_GEMM::runOpenMPVariant(VariantID vid) POLYBENCH_GEMM_VIEWS_RAJA; - auto poly_gemm_lam1 = [=](Index_type /*i*/, Index_type /*j*/, Index_type /*k*/, - Real_type& dot) { + auto poly_gemm_lam1 = [=](Real_type& dot) { POLYBENCH_GEMM_BODY1_RAJA; }; - auto poly_gemm_lam2 = [=](Index_type i, Index_type j, Index_type /*k*/, - Real_type& /*dot*/) { + auto poly_gemm_lam2 = [=](Index_type i, Index_type j) { POLYBENCH_GEMM_BODY2_RAJA; }; auto poly_gemm_lam3 = [=](Index_type i, Index_type j, Index_type k, Real_type& dot) { POLYBENCH_GEMM_BODY3_RAJA; }; - auto poly_gemm_lam4 = [=](Index_type i, Index_type j, Index_type /*k*/, + auto poly_gemm_lam4 = [=](Index_type i, Index_type j, Real_type& dot) { POLYBENCH_GEMM_BODY4_RAJA; }; @@ -112,12 +110,12 @@ void POLYBENCH_GEMM::runOpenMPVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::Collapse, - RAJA::statement::Lambda<0>, - RAJA::statement::Lambda<1>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, + RAJA::statement::Lambda<1, RAJA::Segs<0,1>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0,1,2>, RAJA::Params<0>> >, - RAJA::statement::Lambda<3> + RAJA::statement::Lambda<3, RAJA::Segs<0,1>, RAJA::Params<0>> > >; @@ -126,10 +124,10 @@ void POLYBENCH_GEMM::runOpenMPVariant(VariantID vid) RAJA::kernel_param( - RAJA::make_tuple( RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nk} ), - RAJA::make_tuple(static_cast(0.0)), // variable for dot + RAJA::make_tuple( RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nk) ), + RAJA::tuple {0.0}, // variable for dot poly_gemm_lam1, poly_gemm_lam2, diff --git a/src/polybench/POLYBENCH_GEMM-Seq.cpp b/src/polybench/POLYBENCH_GEMM-Seq.cpp index ef5f2c997..e754fa453 100644 --- a/src/polybench/POLYBENCH_GEMM-Seq.cpp +++ b/src/polybench/POLYBENCH_GEMM-Seq.cpp @@ -39,20 +39,17 @@ void POLYBENCH_GEMM::runSeqVariant(VariantID vid) POLYBENCH_GEMM_VIEWS_RAJA; - auto poly_gemm_lam1 = [=](Index_type /*i*/, Index_type /*j*/, Index_type /*k*/, - Real_type& dot) { + auto poly_gemm_lam1 = [=]( Real_type& dot) { POLYBENCH_GEMM_BODY1_RAJA; }; - auto poly_gemm_lam2 = [=](Index_type i, Index_type j, Index_type /*k*/, - Real_type& /*dot*/) { + auto poly_gemm_lam2 = [=](Index_type i, Index_type j) { POLYBENCH_GEMM_BODY2_RAJA; }; auto poly_gemm_lam3 = [=](Index_type i, Index_type j, Index_type k, Real_type& dot) { POLYBENCH_GEMM_BODY3_RAJA; }; - auto poly_gemm_lam4 = [=](Index_type i, Index_type j, Index_type /*k*/, - Real_type& dot) { + auto poly_gemm_lam4 = [=](Index_type i, Index_type j,Real_type& dot) { POLYBENCH_GEMM_BODY4_RAJA; }; @@ -109,12 +106,12 @@ void POLYBENCH_GEMM::runSeqVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0>, - RAJA::statement::Lambda<1>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, + RAJA::statement::Lambda<1, RAJA::Segs<0,1>>, RAJA::statement::For<2, RAJA::loop_exec, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0,1,2>, RAJA::Params<0>> >, - RAJA::statement::Lambda<3> + RAJA::statement::Lambda<3, RAJA::Segs<0,1>, RAJA::Params<0>> > > >; @@ -124,10 +121,10 @@ void POLYBENCH_GEMM::runSeqVariant(VariantID vid) RAJA::kernel_param( - RAJA::make_tuple( RAJA::RangeSegment{0, ni}, - RAJA::RangeSegment{0, nj}, - RAJA::RangeSegment{0, nk} ), - RAJA::make_tuple(static_cast(0.0)), // variable for dot + RAJA::make_tuple( RAJA::RangeSegment(0, ni), + RAJA::RangeSegment(0, nj), + RAJA::RangeSegment(0, nk) ), + RAJA::tuple {0.0}, // variable for dot poly_gemm_lam1, poly_gemm_lam2, diff --git a/src/polybench/POLYBENCH_GEMVER-OMP.cpp b/src/polybench/POLYBENCH_GEMVER-OMP.cpp index ba101bbfd..26d9a6335 100644 --- a/src/polybench/POLYBENCH_GEMVER-OMP.cpp +++ b/src/polybench/POLYBENCH_GEMVER-OMP.cpp @@ -52,28 +52,27 @@ void POLYBENCH_GEMVER::runOpenMPVariant(VariantID vid) auto poly_gemver_lam1 = [=] (Index_type i, Index_type j) { POLYBENCH_GEMVER_BODY1_RAJA; }; - auto poly_gemver_lam2 = [=] (Index_type /* i */, Index_type /* j */, - Real_type &dot) { + auto poly_gemver_lam2 = [=] (Real_type &dot) { POLYBENCH_GEMVER_BODY2_RAJA; }; auto poly_gemver_lam3 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_GEMVER_BODY3_RAJA; }; - auto poly_gemver_lam4 = [=] (Index_type i, Index_type /* j */, + auto poly_gemver_lam4 = [=] (Index_type i, Real_type &dot) { POLYBENCH_GEMVER_BODY4_RAJA; }; auto poly_gemver_lam5 = [=] (Index_type i) { POLYBENCH_GEMVER_BODY5_RAJA; }; - auto poly_gemver_lam6 = [=] (Index_type i, Index_type /* j */, + auto poly_gemver_lam6 = [=] (Index_type i, Real_type &dot) { POLYBENCH_GEMVER_BODY6_RAJA; }; auto poly_gemver_lam7 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_GEMVER_BODY7_RAJA; }; - auto poly_gemver_lam8 = [=] (Index_type i, Index_type /* j */, + auto poly_gemver_lam8 = [=] (Index_type i, Real_type &dot) { POLYBENCH_GEMVER_BODY8_RAJA; }; @@ -168,7 +167,7 @@ void POLYBENCH_GEMVER::runOpenMPVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_parallel_for_exec, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0> + RAJA::statement::Lambda<0, RAJA::Segs<0,1>> > > >; @@ -176,28 +175,39 @@ void POLYBENCH_GEMVER::runOpenMPVariant(VariantID vid) using EXEC_POL24 = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_parallel_for_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> > >; using EXEC_POL3 = RAJA::loop_exec; + using EXEC_POL5 = + RAJA::KernelPolicy< + RAJA::statement::For<0, RAJA::omp_parallel_for_exec, + RAJA::statement::Lambda<0, RAJA::Segs<0>, RAJA::Params<0>>, + RAJA::statement::For<1, RAJA::loop_exec, + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> + >, + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> + > + >; + startTimer(); for (RepIndex_type irep = 0; irep < run_reps; ++irep) { - RAJA::kernel( RAJA::make_tuple(RAJA::RangeSegment{0, n}, - RAJA::RangeSegment{0, n}), + RAJA::kernel( RAJA::make_tuple(RAJA::RangeSegment(0, n), + RAJA::RangeSegment(0, n)), poly_gemver_lam1 ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, n}, - RAJA::RangeSegment{0, n}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, n), + RAJA::RangeSegment(0, n)), + RAJA::tuple {0.0}, poly_gemver_lam2, poly_gemver_lam3, @@ -208,10 +218,10 @@ void POLYBENCH_GEMVER::runOpenMPVariant(VariantID vid) poly_gemver_lam5 ); - RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, n}, - RAJA::RangeSegment{0, n}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::kernel_param( + RAJA::make_tuple(RAJA::RangeSegment(0, n), + RAJA::RangeSegment(0, n)), + RAJA::tuple {0.0}, poly_gemver_lam6, poly_gemver_lam7, diff --git a/src/polybench/POLYBENCH_GEMVER-Seq.cpp b/src/polybench/POLYBENCH_GEMVER-Seq.cpp index 41a010b9a..e14558b2a 100644 --- a/src/polybench/POLYBENCH_GEMVER-Seq.cpp +++ b/src/polybench/POLYBENCH_GEMVER-Seq.cpp @@ -50,29 +50,25 @@ void POLYBENCH_GEMVER::runSeqVariant(VariantID vid) auto poly_gemver_lam1 = [=] (Index_type i, Index_type j) { POLYBENCH_GEMVER_BODY1_RAJA; }; - auto poly_gemver_lam2 = [=] (Index_type /* i */, Index_type /* j */, - Real_type &dot) { + auto poly_gemver_lam2 = [=] ( Real_type &dot) { POLYBENCH_GEMVER_BODY2_RAJA; }; auto poly_gemver_lam3 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_GEMVER_BODY3_RAJA; }; - auto poly_gemver_lam4 = [=] (Index_type i, Index_type /* j */, - Real_type &dot) { + auto poly_gemver_lam4 = [=] (Index_type i, Real_type &dot) { POLYBENCH_GEMVER_BODY4_RAJA; }; auto poly_gemver_lam5 = [=] (Index_type i) { POLYBENCH_GEMVER_BODY5_RAJA; }; - auto poly_gemver_lam6 = [=] (Index_type i, Index_type /* j */, - Real_type &dot) { + auto poly_gemver_lam6 = [=] (Index_type i, Real_type &dot) { POLYBENCH_GEMVER_BODY6_RAJA; }; auto poly_gemver_lam7 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_GEMVER_BODY7_RAJA; }; - auto poly_gemver_lam8 = [=] (Index_type i, Index_type /* j */, - Real_type &dot) { + auto poly_gemver_lam8 = [=] (Index_type i, Real_type &dot) { POLYBENCH_GEMVER_BODY8_RAJA; }; @@ -159,7 +155,7 @@ void POLYBENCH_GEMVER::runSeqVariant(VariantID vid) RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<0> + RAJA::statement::Lambda<0, RAJA::Segs<0,1>> > > >; @@ -167,42 +163,53 @@ void POLYBENCH_GEMVER::runSeqVariant(VariantID vid) using EXEC_POL24 = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> > >; using EXEC_POL3 = RAJA::loop_exec; + using EXEC_POL5 = + RAJA::KernelPolicy< + RAJA::statement::For<0, RAJA::loop_exec, + RAJA::statement::Lambda<0, RAJA::Segs<0>, RAJA::Params<0>>, + RAJA::statement::For<1, RAJA::loop_exec, + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> + >, + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> + > + >; + startTimer(); for (RepIndex_type irep = 0; irep < run_reps; ++irep) { - RAJA::kernel( RAJA::make_tuple(RAJA::RangeSegment{0, n}, - RAJA::RangeSegment{0, n}), + RAJA::kernel( RAJA::make_tuple(RAJA::RangeSegment(0, n), + RAJA::RangeSegment(0, n)), poly_gemver_lam1 ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, n}, - RAJA::RangeSegment{0, n}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, n), + RAJA::RangeSegment(0, n)), + RAJA::tuple {0.0}, poly_gemver_lam2, poly_gemver_lam3, poly_gemver_lam4 ); - RAJA::forall (RAJA::RangeSegment{0, n}, + RAJA::forall (RAJA::RangeSegment(0, n), poly_gemver_lam5 ); - RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, n}, - RAJA::RangeSegment{0, n}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::kernel_param( + RAJA::make_tuple(RAJA::RangeSegment(0, n), + RAJA::RangeSegment(0, n)), + RAJA::tuple {0.0}, poly_gemver_lam6, poly_gemver_lam7, diff --git a/src/polybench/POLYBENCH_GESUMMV-OMP.cpp b/src/polybench/POLYBENCH_GESUMMV-OMP.cpp index 83ab4b4b8..d78705e5e 100644 --- a/src/polybench/POLYBENCH_GESUMMV-OMP.cpp +++ b/src/polybench/POLYBENCH_GESUMMV-OMP.cpp @@ -38,16 +38,14 @@ void POLYBENCH_GESUMMV::runOpenMPVariant(VariantID vid) POLYBENCH_GESUMMV_VIEWS_RAJA; - auto poly_gesummv_lam1 = [=](Index_type /*i*/, Index_type /*j*/, - Real_type& tmpdot, Real_type& ydot) { + auto poly_gesummv_lam1 = [=](Real_type& tmpdot, Real_type& ydot) { POLYBENCH_GESUMMV_BODY1_RAJA; }; auto poly_gesummv_lam2 = [=](Index_type i, Index_type j, Real_type& tmpdot, Real_type& ydot) { POLYBENCH_GESUMMV_BODY2_RAJA; }; - auto poly_gesummv_lam3 = [=](Index_type i, Index_type /*j*/, - Real_type& tmpdot, Real_type& ydot) { + auto poly_gesummv_lam3 = [=](Index_type i, Real_type& tmpdot, Real_type& ydot) { POLYBENCH_GESUMMV_BODY3_RAJA; }; @@ -98,11 +96,11 @@ void POLYBENCH_GESUMMV::runOpenMPVariant(VariantID vid) using EXEC_POL = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_parallel_for_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0,1>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0,1>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0,1>> > >; diff --git a/src/polybench/POLYBENCH_GESUMMV-Seq.cpp b/src/polybench/POLYBENCH_GESUMMV-Seq.cpp index d78de0459..5a254f7ed 100644 --- a/src/polybench/POLYBENCH_GESUMMV-Seq.cpp +++ b/src/polybench/POLYBENCH_GESUMMV-Seq.cpp @@ -35,15 +35,14 @@ void POLYBENCH_GESUMMV::runSeqVariant(VariantID vid) POLYBENCH_GESUMMV_VIEWS_RAJA; - auto poly_gesummv_lam1 = [=](Index_type /*i*/, Index_type /*j*/, - Real_type& tmpdot, Real_type& ydot) { + auto poly_gesummv_lam1 = [=]( Real_type& tmpdot, Real_type& ydot) { POLYBENCH_GESUMMV_BODY1_RAJA; }; auto poly_gesummv_lam2 = [=](Index_type i, Index_type j, Real_type& tmpdot, Real_type& ydot) { POLYBENCH_GESUMMV_BODY2_RAJA; }; - auto poly_gesummv_lam3 = [=](Index_type i, Index_type /*j*/, + auto poly_gesummv_lam3 = [=](Index_type i, Real_type& tmpdot, Real_type& ydot) { POLYBENCH_GESUMMV_BODY3_RAJA; }; @@ -95,11 +94,11 @@ void POLYBENCH_GESUMMV::runSeqVariant(VariantID vid) using EXEC_POL = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0,1>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0,1>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0,1>> > >; diff --git a/src/polybench/POLYBENCH_MVT-OMP.cpp b/src/polybench/POLYBENCH_MVT-OMP.cpp index cf55fda68..9c02ce940 100644 --- a/src/polybench/POLYBENCH_MVT-OMP.cpp +++ b/src/polybench/POLYBENCH_MVT-OMP.cpp @@ -42,24 +42,22 @@ void POLYBENCH_MVT::runOpenMPVariant(VariantID vid) POLYBENCH_MVT_VIEWS_RAJA; - auto poly_mvt_lam1 = [=] (Index_type /* i */, Index_type /* j */, - Real_type &dot) { + auto poly_mvt_lam1 = [=] (Real_type &dot) { POLYBENCH_MVT_BODY1_RAJA; }; auto poly_mvt_lam2 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_MVT_BODY2_RAJA; }; - auto poly_mvt_lam3 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_mvt_lam3 = [=] (Index_type i,Real_type &dot) { POLYBENCH_MVT_BODY3_RAJA; }; - auto poly_mvt_lam4 = [=] (Index_type /* i */, Index_type /* j */, - Real_type &dot) { + auto poly_mvt_lam4 = [=] (Real_type &dot) { POLYBENCH_MVT_BODY4_RAJA; }; auto poly_mvt_lam5 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_MVT_BODY5_RAJA; }; - auto poly_mvt_lam6 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_mvt_lam6 = [=] (Index_type i, Real_type &dot) { POLYBENCH_MVT_BODY6_RAJA; }; @@ -138,11 +136,11 @@ void POLYBENCH_MVT::runOpenMPVariant(VariantID vid) using EXEC_POL = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::omp_for_nowait_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> > >; @@ -152,9 +150,9 @@ void POLYBENCH_MVT::runOpenMPVariant(VariantID vid) RAJA::region( [=]() { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple{0.0}, poly_mvt_lam1, poly_mvt_lam2, @@ -163,9 +161,9 @@ void POLYBENCH_MVT::runOpenMPVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple{0.0}, poly_mvt_lam4, poly_mvt_lam5, diff --git a/src/polybench/POLYBENCH_MVT-Seq.cpp b/src/polybench/POLYBENCH_MVT-Seq.cpp index 8efba1fd5..96b6db4f8 100644 --- a/src/polybench/POLYBENCH_MVT-Seq.cpp +++ b/src/polybench/POLYBENCH_MVT-Seq.cpp @@ -40,24 +40,22 @@ void POLYBENCH_MVT::runSeqVariant(VariantID vid) POLYBENCH_MVT_VIEWS_RAJA; - auto poly_mvt_lam1 = [=] (Index_type /* i */, Index_type /* j */, - Real_type &dot) { + auto poly_mvt_lam1 = [=] (Real_type &dot) { POLYBENCH_MVT_BODY1_RAJA; }; auto poly_mvt_lam2 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_MVT_BODY2_RAJA; }; - auto poly_mvt_lam3 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_mvt_lam3 = [=] (Index_type i,Real_type &dot) { POLYBENCH_MVT_BODY3_RAJA; }; - auto poly_mvt_lam4 = [=] (Index_type /* i */, Index_type /* j */, - Real_type &dot) { + auto poly_mvt_lam4 = [=] (Real_type &dot) { POLYBENCH_MVT_BODY4_RAJA; }; auto poly_mvt_lam5 = [=] (Index_type i, Index_type j, Real_type &dot) { POLYBENCH_MVT_BODY5_RAJA; }; - auto poly_mvt_lam6 = [=] (Index_type i, Index_type /* j */, Real_type &dot) { + auto poly_mvt_lam6 = [=] (Index_type i, Real_type &dot) { POLYBENCH_MVT_BODY6_RAJA; }; @@ -124,11 +122,11 @@ void POLYBENCH_MVT::runSeqVariant(VariantID vid) using EXEC_POL = RAJA::KernelPolicy< RAJA::statement::For<0, RAJA::loop_exec, - RAJA::statement::Lambda<0>, + RAJA::statement::Lambda<0, RAJA::Params<0>>, RAJA::statement::For<1, RAJA::loop_exec, - RAJA::statement::Lambda<1> + RAJA::statement::Lambda<1, RAJA::Segs<0,1>, RAJA::Params<0>> >, - RAJA::statement::Lambda<2> + RAJA::statement::Lambda<2, RAJA::Segs<0>, RAJA::Params<0>> > >; @@ -138,9 +136,9 @@ void POLYBENCH_MVT::runSeqVariant(VariantID vid) RAJA::region( [=]() { RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple {0.0}, poly_mvt_lam1, poly_mvt_lam2, @@ -149,9 +147,9 @@ void POLYBENCH_MVT::runSeqVariant(VariantID vid) ); RAJA::kernel_param( - RAJA::make_tuple(RAJA::RangeSegment{0, N}, - RAJA::RangeSegment{0, N}), - RAJA::make_tuple(static_cast(0.0)), + RAJA::make_tuple(RAJA::RangeSegment(0, N), + RAJA::RangeSegment(0, N)), + RAJA::tuple {0.0}, poly_mvt_lam4, poly_mvt_lam5, diff --git a/src/stream/ADD-Seq.cpp b/src/stream/ADD-Seq.cpp index 3ef8b81c9..d7915bd6a 100644 --- a/src/stream/ADD-Seq.cpp +++ b/src/stream/ADD-Seq.cpp @@ -76,12 +76,31 @@ void ADD::runSeqVariant(VariantID vid) break; } -#endif // RUN_RAJA_SEQ + + case RAJA_Vec : { + + startTimer(); + + for (RepIndex_type irep = 0; irep < run_reps; ++irep) { + + RAJA::forall>(RAJA::TypedRangeSegment(ibegin, iend), + [=](VecI i) + { + C[i] = A[i] + B[i]; + }); + + } + stopTimer(); + + break; + } + default : { std::cout << "\n ADD : Unknown variant id = " << vid << std::endl; } +#endif } } diff --git a/src/stream/ADD.hpp b/src/stream/ADD.hpp index 17dcefae7..3e0c02641 100644 --- a/src/stream/ADD.hpp +++ b/src/stream/ADD.hpp @@ -20,7 +20,14 @@ #define ADD_DATA_SETUP \ Real_ptr a = m_a; \ Real_ptr b = m_b; \ - Real_ptr c = m_c; + Real_ptr c = m_c; \ + RAJA_INDEX_VALUE_T(I, int, "I");\ + using vector_t = RAJA::StreamVector;\ + using VecI = RAJA::VectorIndex;\ + RAJA::TypedView, I> A(a, getRunSize()); \ + RAJA::TypedView, I> B(b, getRunSize()); \ + RAJA::TypedView, I> C(c, getRunSize()); + #define ADD_BODY \ c[i] = a[i] + b[i]; diff --git a/tpl/RAJA b/tpl/RAJA index 0502b9b69..7b7aaf651 160000 --- a/tpl/RAJA +++ b/tpl/RAJA @@ -1 +1 @@ -Subproject commit 0502b9b69c4cb60aa0afbdf699b555c76cb18f22 +Subproject commit 7b7aaf651c57eb2981747edd2465a1c812321c1f From ef92cd453dc6d8d10db55aa164aab3e67f1bcbe3 Mon Sep 17 00:00:00 2001 From: Verinder Rana Date: Fri, 15 May 2020 16:09:02 -0700 Subject: [PATCH 02/12] temp remove RAJA submodule --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index e6a012fbe..04f0dfcd9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "blt"] path = blt url = https://github.com/LLNL/blt.git -[submodule "tpl/RAJA"] - path = tpl/RAJA - url = https://github.com/LLNL/RAJA.git From ab57da5d56998ada2c08df7f7f12eddecbc51937 Mon Sep 17 00:00:00 2001 From: Verinder Rana Date: Fri, 15 May 2020 16:25:46 -0700 Subject: [PATCH 03/12] Attemtp to add RAJAvec lib --- tpl/RAJA | 1 - tpl/RAJA/.clang-format | 27 + tpl/RAJA/.github/PULL_REQUEST_TEMPLATE.md | 21 + tpl/RAJA/.gitignore | 8 + tpl/RAJA/.gitmodules | 12 + tpl/RAJA/.travis.yml | 110 + tpl/RAJA/CMakeLists.txt | 309 + tpl/RAJA/CODE_OF_CONDUCT.md | 74 + tpl/RAJA/CONTRIBUTING.md | 91 + tpl/RAJA/Dockerfile | 23 + tpl/RAJA/LICENSE | 27 + tpl/RAJA/NOTICE | 20 + tpl/RAJA/README.md | 177 + tpl/RAJA/RELEASE | 29 + tpl/RAJA/RELEASE_NOTES.md | 565 ++ tpl/RAJA/appveyor.yml | 18 + tpl/RAJA/benchmark/CMakeLists.txt | 12 + .../host-device-lambda-benchmark.cpp | 72 + tpl/RAJA/blt/.mailmap | 10 + tpl/RAJA/blt/.travis.yml | 225 + tpl/RAJA/blt/CODE-OF-CONDUCT.md | 77 + tpl/RAJA/blt/CONTRIBUTING.md | 38 + tpl/RAJA/blt/LICENSE | 27 + tpl/RAJA/blt/NOTICE | 20 + tpl/RAJA/blt/README.md | 134 + tpl/RAJA/blt/RELEASE-NOTES.md | 107 + tpl/RAJA/blt/SetupBLT.cmake | 206 + tpl/RAJA/blt/appveyor.yml | 156 + tpl/RAJA/blt/cmake/BLTGitMacros.cmake | 250 + tpl/RAJA/blt/cmake/BLTMacros.cmake | 1109 +++ tpl/RAJA/blt/cmake/BLTOptions.cmake | 138 + tpl/RAJA/blt/cmake/BLTPrivateMacros.cmake | 739 ++ tpl/RAJA/blt/cmake/SetupCodeChecks.cmake | 489 ++ .../blt/cmake/SetupCodeCoverageReports.cmake | 91 + tpl/RAJA/blt/cmake/SetupCodeMetrics.cmake | 45 + tpl/RAJA/blt/cmake/SetupCompilerOptions.cmake | 420 + tpl/RAJA/blt/cmake/SetupDocs.cmake | 107 + tpl/RAJA/blt/cmake/WrapAstyle.cmake.in | 61 + tpl/RAJA/blt/cmake/clang-query-wrapper.py | 84 + tpl/RAJA/blt/cmake/thirdparty/FindHIP.cmake | 582 ++ .../cmake/thirdparty/FindHIP/run_hipcc.cmake | 173 + .../thirdparty/FindHIP/run_make2cmake.cmake | 55 + tpl/RAJA/blt/cmake/thirdparty/FindROCm.cmake | 27 + tpl/RAJA/blt/cmake/thirdparty/SetupCUDA.cmake | 138 + tpl/RAJA/blt/cmake/thirdparty/SetupHCC.cmake | 39 + tpl/RAJA/blt/cmake/thirdparty/SetupHIP.cmake | 46 + tpl/RAJA/blt/cmake/thirdparty/SetupMPI.cmake | 161 + .../blt/cmake/thirdparty/SetupOpenMP.cmake | 57 + .../cmake/thirdparty/SetupThirdParty.cmake | 109 + tpl/RAJA/blt/docs/CMakeLists.txt | 22 + tpl/RAJA/blt/docs/api/code_check.rst | 254 + tpl/RAJA/blt/docs/api/documentation.rst | 42 + tpl/RAJA/blt/docs/api/git.rst | 183 + tpl/RAJA/blt/docs/api/index.rst | 17 + tpl/RAJA/blt/docs/api/target.rst | 283 + tpl/RAJA/blt/docs/api/target_properties.rst | 191 + tpl/RAJA/blt/docs/api/utility.rst | 124 + tpl/RAJA/blt/docs/conf.py | 224 + tpl/RAJA/blt/docs/index.rst | 69 + .../tutorial/blank_project/CMakeLists.txt | 32 + .../blt/docs/tutorial/calc_pi/CMakeLists.txt | 123 + .../blt/docs/tutorial/calc_pi/calc_pi.cpp | 29 + .../blt/docs/tutorial/calc_pi/calc_pi.hpp | 22 + .../docs/tutorial/calc_pi/calc_pi_cuda.cpp | 134 + .../docs/tutorial/calc_pi/calc_pi_cuda.hpp | 22 + .../tutorial/calc_pi/calc_pi_cuda_exports.h | 37 + .../docs/tutorial/calc_pi/calc_pi_exports.h | 37 + .../blt/docs/tutorial/calc_pi/calc_pi_mpi.cpp | 43 + .../blt/docs/tutorial/calc_pi/calc_pi_mpi.hpp | 22 + .../tutorial/calc_pi/calc_pi_mpi_exports.h | 37 + .../docs/tutorial/calc_pi/docs/CMakeLists.txt | 7 + .../calc_pi/docs/doxygen/CMakeLists.txt | 8 + .../tutorial/calc_pi/docs/doxygen/Doxyfile.in | 14 + .../calc_pi/docs/sphinx/CMakeLists.txt | 7 + .../docs/tutorial/calc_pi/docs/sphinx/conf.py | 356 + .../tutorial/calc_pi/docs/sphinx/index.rst | 25 + .../blt/docs/tutorial/calc_pi/example_1.cpp | 61 + .../blt/docs/tutorial/calc_pi/example_2.cpp | 43 + tpl/RAJA/blt/docs/tutorial/calc_pi/test_1.cpp | 21 + tpl/RAJA/blt/docs/tutorial/calc_pi/test_2.cpp | 55 + tpl/RAJA/blt/docs/tutorial/calc_pi/test_3.cpp | 36 + .../docs/tutorial/creating_documentation.rst | 140 + .../docs/tutorial/creating_execs_and_libs.rst | 124 + .../docs/tutorial/external_dependencies.rst | 319 + tpl/RAJA/blt/docs/tutorial/index.rst | 37 + .../blt/docs/tutorial/recommendations.rst | 104 + tpl/RAJA/blt/docs/tutorial/setup_blt.rst | 227 + tpl/RAJA/blt/docs/tutorial/unit_testing.rst | 251 + tpl/RAJA/blt/docs/tutorial/using_flags.rst | 69 + .../elcapitan-x86_64/naples-clang@7.3.0.cmake | 54 + .../llnl/bgqos_0/clang@4.0.0_xlf.cmake | 51 + .../clang@upstream_link_with_nvcc.cmake | 73 + .../clang@upstream_nvcc_xlf.cmake | 77 + .../toss_3_x86_64_ib/clang@4.0.0-libcxx.cmake | 51 + .../clang@6.0.0-static-analysis.cmake | 57 + .../llnl/toss_3_x86_64_ib/gcc@4.9.3.cmake | 46 + .../llnl/toss_3_x86_64_ib/pgi@18.5.cmake | 43 + .../llnl/windows/sqa-uno-msvc@15.cmake | 45 + tpl/RAJA/blt/host-configs/other/hcc.cmake | 66 + tpl/RAJA/blt/host-configs/other/hip.cmake | 32 + ...-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake | 50 + tpl/RAJA/blt/share/blt/logo/blt_logo.png | Bin 0 -> 22594 bytes tpl/RAJA/blt/tests/internal/CMakeLists.txt | 337 + tpl/RAJA/blt/tests/internal/astyle.cfg | 13 + tpl/RAJA/blt/tests/internal/src/Example.cpp | 25 + tpl/RAJA/blt/tests/internal/src/Example.hpp | 20 + .../blt/tests/internal/src/Example_Exports.h | 38 + .../blt/tests/internal/src/HeaderOnly.hpp | 19 + .../CMakeLists.txt | 55 + .../src/combine_static_library_test/Foo1.cpp | 28 + .../src/combine_static_library_test/Foo1.hpp | 25 + .../src/combine_static_library_test/Foo2.cpp | 27 + .../src/combine_static_library_test/Foo2.hpp | 26 + .../src/combine_static_library_test/Foo3.cpp | 26 + .../src/combine_static_library_test/Foo3.hpp | 26 + ..._combine_static_libraries_shared_smoke.cpp | 28 + ..._combine_static_libraries_static_smoke.cpp | 28 + .../src/combine_static_library_test/dummy.cpp | 1 + .../src/combine_static_library_test/main.cpp | 22 + .../src/object_library_test/CMakeLists.txt | 30 + .../src/object_library_test/base_object.cpp | 17 + .../src/object_library_test/base_object.hpp | 11 + .../inherited_base/CMakeLists.txt | 12 + .../inherited_base/inherited_base.cpp | 11 + .../inherited_base/inherited_base.hpp | 11 + .../internal/src/object_library_test/main.cpp | 56 + .../src/object_library_test/object.cpp | 12 + .../src/object_library_test/object.hpp | 11 + .../src/static_analysis/CMakeLists.txt | 20 + .../static_analysis_passes/if-stmt | 1 + .../static_analysis/well_analyzed_source.cpp | 37 + .../src/t_example_compile_definitions.cpp | 28 + .../tests/internal/src/t_example_smoke.cpp | 16 + .../internal/src/t_git_macros_smoke.cpp.in | 24 + .../internal/src/t_header_only_smoke.cpp | 12 + .../CMakeLists.txt | 33 + .../Child.cpp | 51 + .../Child.hpp | 30 + .../CudaTests.cpp | 38 + .../Parent.cpp | 16 + .../Parent.hpp | 23 + .../blt/tests/internal/src/test_cuda_mpi.cpp | 418 + tpl/RAJA/blt/tests/smoke/CMakeLists.txt | 196 + .../blt/tests/smoke/blt_cuda_mpi_smoke.cpp | 68 + .../blt/tests/smoke/blt_cuda_openmp_smoke.cpp | 54 + .../tests/smoke/blt_cuda_runtime_smoke.cpp | 43 + tpl/RAJA/blt/tests/smoke/blt_cuda_smoke.cpp | 38 + tpl/RAJA/blt/tests/smoke/blt_fruit_smoke.f90 | 48 + .../blt/tests/smoke/blt_gbenchmark_smoke.cpp | 55 + tpl/RAJA/blt/tests/smoke/blt_gmock_smoke.cpp | 79 + tpl/RAJA/blt/tests/smoke/blt_gtest_smoke.cpp | 35 + .../blt/tests/smoke/blt_hcc_runtime_smoke.cpp | 47 + tpl/RAJA/blt/tests/smoke/blt_hcc_smoke.cpp | 29 + .../blt/tests/smoke/blt_hip_runtime_smoke.cpp | 37 + tpl/RAJA/blt/tests/smoke/blt_hip_smoke.cpp | 34 + tpl/RAJA/blt/tests/smoke/blt_mpi_smoke.cpp | 48 + tpl/RAJA/blt/tests/smoke/blt_openmp_smoke.cpp | 30 + tpl/RAJA/blt/tests/smoke/fortran_driver.cpp | 17 + .../blt/thirdparty_builtin/CMakeLists.txt | 172 + .../benchmark-1.5.0/.clang-format | 5 + .../benchmark-1.5.0/.gitignore | 61 + .../benchmark-1.5.0/.travis-libcxx-setup.sh | 28 + .../benchmark-1.5.0/.travis.yml | 235 + .../benchmark-1.5.0/.ycm_extra_conf.py | 115 + .../benchmark-1.5.0/AUTHORS | 51 + .../benchmark-1.5.0/BUILD.bazel | 42 + .../benchmark-1.5.0/CMakeLists.txt | 274 + .../benchmark-1.5.0/CONTRIBUTING.md | 58 + .../benchmark-1.5.0/CONTRIBUTORS | 72 + .../benchmark-1.5.0/LICENSE | 202 + .../benchmark-1.5.0/README.md | 1179 +++ .../benchmark-1.5.0/WORKSPACE | 9 + .../benchmark-1.5.0/_config.yml | 1 + .../benchmark-1.5.0/appveyor.yml | 50 + .../cmake/AddCXXCompilerFlag.cmake | 74 + .../cmake/CXXFeatureCheck.cmake | 64 + .../benchmark-1.5.0/cmake/Config.cmake.in | 1 + .../benchmark-1.5.0/cmake/GetGitVersion.cmake | 54 + .../benchmark-1.5.0/cmake/GoogleTest.cmake | 41 + .../benchmark-1.5.0/cmake/GoogleTest.cmake.in | 58 + .../benchmark-1.5.0/cmake/benchmark.pc.in | 12 + .../benchmark-1.5.0/cmake/gnu_posix_regex.cpp | 12 + .../cmake/llvm-toolchain.cmake | 8 + .../benchmark-1.5.0/cmake/posix_regex.cpp | 14 + .../benchmark-1.5.0/cmake/split_list.cmake | 3 + .../benchmark-1.5.0/cmake/std_regex.cpp | 10 + .../benchmark-1.5.0/cmake/steady_clock.cpp | 7 + .../cmake/thread_safety_attributes.cpp | 4 + .../benchmark-1.5.0/conan/CMakeLists.txt | 7 + .../conan/test_package/CMakeLists.txt | 10 + .../conan/test_package/conanfile.py | 19 + .../conan/test_package/test_package.cpp | 18 + .../benchmark-1.5.0/conanfile.py | 79 + .../benchmark-1.5.0/dependencies.md | 18 + .../benchmark-1.5.0/docs/AssemblyTests.md | 147 + .../benchmark-1.5.0/docs/_config.yml | 1 + .../benchmark-1.5.0/docs/tools.md | 199 + .../include/benchmark/benchmark.h | 1583 ++++ .../benchmark-1.5.0/mingw.py | 320 + .../benchmark-1.5.0/releasing.md | 16 + .../benchmark-1.5.0/src/CMakeLists.txt | 112 + .../benchmark-1.5.0/src/arraysize.h | 33 + .../benchmark-1.5.0/src/benchmark.cc | 494 ++ .../src/benchmark_api_internal.cc | 15 + .../src/benchmark_api_internal.h | 53 + .../benchmark-1.5.0/src/benchmark_main.cc | 17 + .../benchmark-1.5.0/src/benchmark_name.cc | 58 + .../benchmark-1.5.0/src/benchmark_register.cc | 504 ++ .../benchmark-1.5.0/src/benchmark_register.h | 107 + .../benchmark-1.5.0/src/benchmark_runner.cc | 361 + .../benchmark-1.5.0/src/benchmark_runner.h | 51 + .../benchmark-1.5.0/src/check.h | 82 + .../benchmark-1.5.0/src/colorprint.cc | 188 + .../benchmark-1.5.0/src/colorprint.h | 33 + .../benchmark-1.5.0/src/commandlineflags.cc | 222 + .../benchmark-1.5.0/src/commandlineflags.h | 73 + .../benchmark-1.5.0/src/complexity.cc | 238 + .../benchmark-1.5.0/src/complexity.h | 55 + .../benchmark-1.5.0/src/console_reporter.cc | 179 + .../benchmark-1.5.0/src/counter.cc | 76 + .../benchmark-1.5.0/src/counter.h | 27 + .../benchmark-1.5.0/src/csv_reporter.cc | 154 + .../benchmark-1.5.0/src/cycleclock.h | 177 + .../benchmark-1.5.0/src/internal_macros.h | 94 + .../benchmark-1.5.0/src/json_reporter.cc | 253 + .../benchmark-1.5.0/src/log.h | 74 + .../benchmark-1.5.0/src/mutex.h | 155 + .../benchmark-1.5.0/src/re.h | 158 + .../benchmark-1.5.0/src/reporter.cc | 105 + .../benchmark-1.5.0/src/sleep.cc | 51 + .../benchmark-1.5.0/src/sleep.h | 15 + .../benchmark-1.5.0/src/statistics.cc | 193 + .../benchmark-1.5.0/src/statistics.h | 37 + .../benchmark-1.5.0/src/string_util.cc | 252 + .../benchmark-1.5.0/src/string_util.h | 59 + .../benchmark-1.5.0/src/sysinfo.cc | 699 ++ .../benchmark-1.5.0/src/thread_manager.h | 64 + .../benchmark-1.5.0/src/thread_timer.h | 86 + .../benchmark-1.5.0/src/timers.cc | 217 + .../benchmark-1.5.0/src/timers.h | 48 + .../benchmark-1.5.0/test/AssemblyTests.cmake | 46 + .../benchmark-1.5.0/test/BUILD | 65 + .../benchmark-1.5.0/test/CMakeLists.txt | 259 + .../benchmark-1.5.0/test/basic_test.cc | 136 + .../benchmark-1.5.0/test/benchmark_gtest.cc | 128 + .../test/benchmark_name_gtest.cc | 74 + .../benchmark-1.5.0/test/benchmark_test.cc | 245 + .../test/clobber_memory_assembly_test.cc | 64 + .../test/commandlineflags_gtest.cc | 78 + .../benchmark-1.5.0/test/complexity_test.cc | 211 + .../benchmark-1.5.0/test/cxx03_test.cc | 63 + .../benchmark-1.5.0/test/diagnostics_test.cc | 80 + .../test/display_aggregates_only_test.cc | 43 + .../test/donotoptimize_assembly_test.cc | 163 + .../test/donotoptimize_test.cc | 52 + .../benchmark-1.5.0/test/filter_test.cc | 104 + .../benchmark-1.5.0/test/fixture_test.cc | 49 + .../test/internal_threading_test.cc | 184 + .../benchmark-1.5.0/test/link_main_test.cc | 8 + .../benchmark-1.5.0/test/map_test.cc | 57 + .../test/memory_manager_test.cc | 44 + .../test/multiple_ranges_test.cc | 96 + .../benchmark-1.5.0/test/options_test.cc | 75 + .../benchmark-1.5.0/test/output_test.h | 213 + .../test/output_test_helper.cc | 505 ++ .../test/register_benchmark_test.cc | 184 + .../test/report_aggregates_only_test.cc | 39 + .../test/reporter_output_test.cc | 742 ++ .../test/skip_with_error_test.cc | 189 + .../test/state_assembly_test.cc | 68 + .../benchmark-1.5.0/test/statistics_gtest.cc | 28 + .../benchmark-1.5.0/test/string_util_gtest.cc | 146 + .../test/templated_fixture_test.cc | 28 + .../test/user_counters_tabular_test.cc | 283 + .../test/user_counters_test.cc | 438 + .../test/user_counters_thousands_test.cc | 173 + .../benchmark-1.5.0/tools/compare.py | 408 + .../tools/gbench/Inputs/test1_run1.json | 119 + .../tools/gbench/Inputs/test1_run2.json | 119 + .../tools/gbench/Inputs/test2_run.json | 81 + .../tools/gbench/Inputs/test3_run0.json | 65 + .../tools/gbench/Inputs/test3_run1.json | 65 + .../benchmark-1.5.0/tools/gbench/__init__.py | 8 + .../benchmark-1.5.0/tools/gbench/report.py | 541 ++ .../benchmark-1.5.0/tools/gbench/util.py | 164 + .../benchmark-1.5.0/tools/strip_asm.py | 151 + .../fruit-3.4.1/CHANGES.txt | 551 ++ .../fruit-3.4.1/CMakeLists.txt | 17 + .../fruit-3.4.1/LICENSE.txt | 43 + .../thirdparty_builtin/fruit-3.4.1/fruit.f90 | 2562 ++++++ .../googletest-master-2020-01-07/.gitignore | 2 + .../googletest-master-2020-01-07/.travis.yml | 46 + .../googletest-master-2020-01-07/BUILD.bazel | 179 + .../CMakeLists.txt | 24 + .../CONTRIBUTING.md | 142 + .../googletest-master-2020-01-07/LICENSE | 28 + .../googletest-master-2020-01-07/README.md | 136 + .../googletest-master-2020-01-07/WORKSPACE | 23 + .../googletest-master-2020-01-07/appveyor.yml | 156 + .../googlemock/CMakeLists.txt | 233 + .../googlemock/CONTRIBUTORS | 40 + .../googlemock/LICENSE | 28 + .../googlemock/README.md | 44 + .../googlemock/cmake/gmock.pc.in | 10 + .../googlemock/cmake/gmock_main.pc.in | 10 + .../googlemock/docs/cheat_sheet.md | 776 ++ .../googlemock/docs/cook_book.md | 4269 ++++++++++ .../googlemock/docs/for_dummies.md | 700 ++ .../googlemock/docs/gmock_faq.md | 396 + .../googlemock/docs/pump_manual.md | 187 + .../googlemock/include/gmock/gmock-actions.h | 1234 +++ .../include/gmock/gmock-cardinalities.h | 157 + .../include/gmock/gmock-function-mocker.h | 276 + .../include/gmock/gmock-generated-actions.h | 1757 ++++ .../gmock/gmock-generated-actions.h.pump | 579 ++ .../gmock/gmock-generated-function-mockers.h | 752 ++ .../gmock-generated-function-mockers.h.pump | 227 + .../include/gmock/gmock-generated-matchers.h | 1097 +++ .../gmock/gmock-generated-matchers.h.pump | 346 + .../googlemock/include/gmock/gmock-matchers.h | 4567 ++++++++++ .../include/gmock/gmock-more-actions.h | 162 + .../include/gmock/gmock-more-matchers.h | 92 + .../include/gmock/gmock-nice-strict.h | 215 + .../include/gmock/gmock-spec-builders.h | 1977 +++++ .../googlemock/include/gmock/gmock.h | 101 + .../include/gmock/internal/custom/README.md | 16 + .../internal/custom/gmock-generated-actions.h | 10 + .../custom/gmock-generated-actions.h.pump | 12 + .../gmock/internal/custom/gmock-matchers.h | 36 + .../gmock/internal/custom/gmock-port.h | 39 + .../gmock/internal/gmock-internal-utils.h | 470 ++ .../include/gmock/internal/gmock-port.h | 87 + .../include/gmock/internal/gmock-pp.h | 271 + .../googlemock/scripts/README.md | 5 + .../googlemock/scripts/fuse_gmock_files.py | 240 + .../googlemock/scripts/generator/LICENSE | 203 + .../googlemock/scripts/generator/README | 34 + .../scripts/generator/README.cppclean | 115 + .../scripts/generator/cpp/__init__.py | 0 .../googlemock/scripts/generator/cpp/ast.py | 1761 ++++ .../scripts/generator/cpp/gmock_class.py | 248 + .../scripts/generator/cpp/gmock_class_test.py | 540 ++ .../scripts/generator/cpp/keywords.py | 56 + .../scripts/generator/cpp/tokenize.py | 284 + .../googlemock/scripts/generator/cpp/utils.py | 37 + .../googlemock/scripts/generator/gmock_gen.py | 30 + .../googlemock/scripts/pump.py | 856 ++ .../googlemock/src/gmock-all.cc | 46 + .../googlemock/src/gmock-cardinalities.cc | 155 + .../googlemock/src/gmock-internal-utils.cc | 200 + .../googlemock/src/gmock-matchers.cc | 462 + .../googlemock/src/gmock-spec-builders.cc | 892 ++ .../googlemock/src/gmock.cc | 213 + .../googlemock/src/gmock_main.cc | 72 + .../googlemock/test/BUILD.bazel | 110 + .../googlemock/test/gmock-actions_test.cc | 1507 ++++ .../test/gmock-cardinalities_test.cc | 429 + .../test/gmock-function-mocker_nc.cc | 16 + .../test/gmock-function-mocker_nc_test.py | 43 + .../test/gmock-function-mocker_test.cc | 696 ++ .../test/gmock-generated-actions_test.cc | 1064 +++ .../gmock-generated-function-mockers_test.cc | 659 ++ .../test/gmock-generated-matchers_test.cc | 1314 +++ .../test/gmock-internal-utils_test.cc | 734 ++ .../googlemock/test/gmock-matchers_test.cc | 6909 +++++++++++++++ .../test/gmock-more-actions_test.cc | 698 ++ .../googlemock/test/gmock-nice-strict_test.cc | 500 ++ .../googlemock/test/gmock-port_test.cc | 42 + .../googlemock/test/gmock-pp-string_test.cc | 206 + .../googlemock/test/gmock-pp_test.cc | 83 + .../test/gmock-spec-builders_test.cc | 2775 ++++++ .../googlemock/test/gmock_all_test.cc | 49 + .../googlemock/test/gmock_ex_test.cc | 80 + .../googlemock/test/gmock_leak_test.py | 104 + .../googlemock/test/gmock_leak_test_.cc | 99 + .../googlemock/test/gmock_link2_test.cc | 39 + .../googlemock/test/gmock_link_test.cc | 39 + .../googlemock/test/gmock_link_test.h | 690 ++ .../googlemock/test/gmock_output_test.py | 183 + .../googlemock/test/gmock_output_test_.cc | 309 + .../test/gmock_output_test_golden.txt | 317 + .../googlemock/test/gmock_stress_test.cc | 240 + .../googlemock/test/gmock_test.cc | 181 + .../googlemock/test/gmock_test_utils.py | 108 + .../googlemock/test/pump_test.py | 182 + .../googletest/CMakeLists.txt | 329 + .../googletest/CONTRIBUTORS | 38 + .../googletest/LICENSE | 28 + .../googletest/README.md | 244 + .../googletest/cmake/Config.cmake.in | 9 + .../googletest/cmake/gtest.pc.in | 9 + .../googletest/cmake/gtest_main.pc.in | 10 + .../googletest/cmake/internal_utils.cmake | 358 + .../googletest/cmake/libgtest.la.in | 21 + .../googletest/docs/advanced.md | 2567 ++++++ .../googletest/docs/faq.md | 753 ++ .../googletest/docs/pkgconfig.md | 219 + .../googletest/docs/primer.md | 579 ++ .../googletest/docs/samples.md | 22 + .../include/gtest/gtest-death-test.h | 343 + .../googletest/include/gtest/gtest-matchers.h | 750 ++ .../googletest/include/gtest/gtest-message.h | 219 + .../include/gtest/gtest-param-test.h | 504 ++ .../googletest/include/gtest/gtest-printers.h | 926 ++ .../googletest/include/gtest/gtest-spi.h | 238 + .../include/gtest/gtest-test-part.h | 184 + .../include/gtest/gtest-typed-test.h | 337 + .../googletest/include/gtest/gtest.h | 2475 ++++++ .../include/gtest/gtest_pred_impl.h | 359 + .../googletest/include/gtest/gtest_prod.h | 61 + .../include/gtest/internal/custom/README.md | 56 + .../gtest/internal/custom/gtest-port.h | 37 + .../gtest/internal/custom/gtest-printers.h | 42 + .../include/gtest/internal/custom/gtest.h | 37 + .../internal/gtest-death-test-internal.h | 304 + .../include/gtest/internal/gtest-filepath.h | 211 + .../include/gtest/internal/gtest-internal.h | 1432 ++++ .../include/gtest/internal/gtest-param-util.h | 925 ++ .../include/gtest/internal/gtest-port-arch.h | 111 + .../include/gtest/internal/gtest-port.h | 2225 +++++ .../include/gtest/internal/gtest-string.h | 172 + .../include/gtest/internal/gtest-type-util.h | 183 + .../googletest/samples/prime_tables.h | 126 + .../googletest/samples/sample1.cc | 66 + .../googletest/samples/sample1.h | 41 + .../googletest/samples/sample10_unittest.cc | 139 + .../googletest/samples/sample1_unittest.cc | 151 + .../googletest/samples/sample2.cc | 54 + .../googletest/samples/sample2.h | 81 + .../googletest/samples/sample2_unittest.cc | 107 + .../googletest/samples/sample3-inl.h | 172 + .../googletest/samples/sample3_unittest.cc | 149 + .../googletest/samples/sample4.cc | 54 + .../googletest/samples/sample4.h | 53 + .../googletest/samples/sample4_unittest.cc | 53 + .../googletest/samples/sample5_unittest.cc | 196 + .../googletest/samples/sample6_unittest.cc | 224 + .../googletest/samples/sample7_unittest.cc | 117 + .../googletest/samples/sample8_unittest.cc | 154 + .../googletest/samples/sample9_unittest.cc | 156 + .../googletest/scripts/README.md | 5 + .../googletest/scripts/common.py | 83 + .../googletest/scripts/fuse_gtest_files.py | 253 + .../googletest/scripts/gen_gtest_pred_impl.py | 733 ++ .../googletest/scripts/gtest-config.in | 274 + .../googletest/scripts/release_docs.py | 158 + .../googletest/scripts/run_with_path.py | 32 + .../googletest/scripts/test/Makefile | 59 + .../googletest/scripts/upload.py | 1402 ++++ .../googletest/scripts/upload_gtest.py | 78 + .../googletest/src/gtest-all.cc | 48 + .../googletest/src/gtest-death-test.cc | 1653 ++++ .../googletest/src/gtest-filepath.cc | 382 + .../googletest/src/gtest-internal-inl.h | 1210 +++ .../googletest/src/gtest-matchers.cc | 97 + .../googletest/src/gtest-port.cc | 1403 ++++ .../googletest/src/gtest-printers.cc | 442 + .../googletest/src/gtest-test-part.cc | 108 + .../googletest/src/gtest-typed-test.cc | 121 + .../googletest/src/gtest.cc | 6317 ++++++++++++++ .../googletest/src/gtest_main.cc | 54 + .../googletest/test/BUILD.bazel | 545 ++ .../googletest-break-on-failure-unittest.py | 208 + .../googletest-break-on-failure-unittest_.cc | 86 + .../test/googletest-catch-exceptions-test.py | 236 + .../test/googletest-catch-exceptions-test_.cc | 293 + .../googletest/test/googletest-color-test.py | 127 + .../googletest/test/googletest-color-test_.cc | 62 + .../test/googletest-death-test-test.cc | 1516 ++++ .../test/googletest-death-test_ex_test.cc | 92 + .../test/googletest-env-var-test.py | 117 + .../test/googletest-env-var-test_.cc | 122 + .../test/googletest-filepath-test.cc | 649 ++ .../test/googletest-filter-unittest.py | 639 ++ .../test/googletest-filter-unittest_.cc | 137 + .../test/googletest-json-outfiles-test.py | 191 + .../test/googletest-json-output-unittest.py | 778 ++ .../test/googletest-list-tests-unittest.py | 205 + .../test/googletest-list-tests-unittest_.cc | 156 + .../test/googletest-listener-test.cc | 518 ++ .../test/googletest-message-test.cc | 158 + .../test/googletest-options-test.cc | 216 + .../googletest-output-test-golden-lin.txt | 1151 +++ .../googletest/test/googletest-output-test.py | 346 + .../test/googletest-output-test_.cc | 1179 +++ ...oogletest-param-test-invalid-name1-test.py | 63 + ...ogletest-param-test-invalid-name1-test_.cc | 50 + ...oogletest-param-test-invalid-name2-test.py | 62 + ...ogletest-param-test-invalid-name2-test_.cc | 55 + .../test/googletest-param-test-test.cc | 1097 +++ .../test/googletest-param-test-test.h | 51 + .../test/googletest-param-test2-test.cc | 61 + .../googletest/test/googletest-port-test.cc | 1272 +++ .../test/googletest-printers-test.cc | 1621 ++++ .../test/googletest-setuptestsuite-test.py | 54 + .../test/googletest-setuptestsuite-test_.cc | 49 + .../test/googletest-shuffle-test.py | 323 + .../test/googletest-shuffle-test_.cc | 101 + .../test/googletest-test-part-test.cc | 230 + .../googletest/test/googletest-test2_test.cc | 61 + .../test/googletest-throw-on-failure-test.py | 168 + .../test/googletest-throw-on-failure-test_.cc | 71 + .../test/googletest-uninitialized-test.py | 67 + .../test/googletest-uninitialized-test_.cc | 42 + .../googletest/test/gtest-typed-test2_test.cc | 44 + .../googletest/test/gtest-typed-test_test.cc | 462 + .../googletest/test/gtest-typed-test_test.h | 65 + .../test/gtest-unittest-api_test.cc | 341 + .../googletest/test/gtest_all_test.cc | 46 + .../test/gtest_assert_by_exception_test.cc | 116 + .../googletest/test/gtest_environment_test.cc | 188 + .../googletest/test/gtest_help_test.py | 170 + .../googletest/test/gtest_help_test_.cc | 45 + .../googletest/test/gtest_json_test_utils.py | 60 + .../test/gtest_list_output_unittest.py | 141 + .../test/gtest_list_output_unittest_.cc | 51 + .../googletest/test/gtest_main_unittest.cc | 44 + .../googletest/test/gtest_no_test_unittest.cc | 54 + .../test/gtest_pred_impl_unittest.cc | 2422 ++++++ .../test/gtest_premature_exit_test.cc | 126 + .../googletest/test/gtest_prod_test.cc | 56 + .../googletest/test/gtest_repeat_test.cc | 233 + .../test/gtest_skip_check_output_test.py | 59 + ...test_skip_environment_check_output_test.py | 54 + .../gtest_skip_in_environment_setup_test.cc | 49 + .../googletest/test/gtest_skip_test.cc | 55 + .../googletest/test/gtest_sole_header_test.cc | 56 + .../googletest/test/gtest_stress_test.cc | 248 + .../gtest_test_macro_stack_footprint_test.cc | 89 + .../googletest/test/gtest_test_utils.py | 314 + .../googletest/test/gtest_testbridge_test.py | 63 + .../googletest/test/gtest_testbridge_test_.cc | 43 + .../test/gtest_throw_on_failure_ex_test.cc | 90 + .../googletest/test/gtest_unittest.cc | 7462 +++++++++++++++++ .../test/gtest_xml_outfile1_test_.cc | 43 + .../test/gtest_xml_outfile2_test_.cc | 43 + .../test/gtest_xml_outfiles_test.py | 135 + .../test/gtest_xml_output_unittest.py | 389 + .../test/gtest_xml_output_unittest_.cc | 188 + .../googletest/test/gtest_xml_test_utils.py | 196 + .../googletest/test/production.cc | 35 + .../googletest/test/production.h | 54 + .../googletest-master-2020-01-07/library.json | 66 + .../platformio.ini | 47 + ...enchmark-2019-09-09-optional-install.patch | 58 + ...mark-2020-01-07-remove-minimum-cmake.patch | 10 + ...-01-07-override-GTEST_HAS_DEATH_TEST.patch | 20 + ...test-2020-01-07-remove-cxx-std-logic.patch | 29 + ...test-2020-01-07-remove-minimum-cmake.patch | 13 + tpl/RAJA/cmake/RAJAMacros.cmake | 108 + tpl/RAJA/cmake/SetupBasics.cmake | 11 + tpl/RAJA/cmake/SetupCompilers.cmake | 91 + tpl/RAJA/cmake/SetupPackages.cmake | 30 + tpl/RAJA/cmake/SetupRajaConfig.cmake | 100 + tpl/RAJA/cmake/thirdparty/FindCUB.cmake | 25 + tpl/RAJA/cmake/thirdparty/FindRocPRIM.cmake | 25 + tpl/RAJA/cmake/thirdparty/FindSphinx.cmake | 17 + tpl/RAJA/cmake/thirdparty/FindTBB.cmake | 303 + tpl/RAJA/codecov.yml | 18 + tpl/RAJA/docs/CMakeLists.txt | 21 + tpl/RAJA/docs/Licenses/libc++ License | 76 + tpl/RAJA/docs/Licenses/llvm-license.txt | 43 + tpl/RAJA/docs/doxygen/CMakeLists.txt | 25 + tpl/RAJA/docs/doxygen/Doxyfile.in | 2372 ++++++ tpl/RAJA/docs/sphinx/.gitignore | 3 + .../docs/sphinx/user_guide/CMakeLists.txt | 27 + .../sphinx/user_guide/app_considerations.rst | 15 + tpl/RAJA/docs/sphinx/user_guide/conf.py | 311 + .../docs/sphinx/user_guide/config_options.rst | 370 + .../docs/sphinx/user_guide/contributing.rst | 115 + .../docs/sphinx/user_guide/feature/atomic.rst | 155 + .../user_guide/feature/iteration_spaces.rst | 213 + .../sphinx/user_guide/feature/local_array.rst | 116 + .../sphinx/user_guide/feature/loop_basic.rst | 236 + .../sphinx/user_guide/feature/policies.rst | 588 ++ .../sphinx/user_guide/feature/reduction.rst | 105 + .../docs/sphinx/user_guide/feature/scan.rst | 142 + .../docs/sphinx/user_guide/feature/tiling.rst | 113 + .../docs/sphinx/user_guide/feature/view.rst | 336 + tpl/RAJA/docs/sphinx/user_guide/features.rst | 28 + .../sphinx/user_guide/figures/IndexSet.png | Bin 0 -> 6967 bytes .../sphinx/user_guide/figures/ListSegment.png | Bin 0 -> 1432 bytes .../user_guide/figures/RangeSegment.png | Bin 0 -> 3238 bytes .../user_guide/figures/RangeStrideSegment.png | Bin 0 -> 5837 bytes .../sphinx/user_guide/figures/gsboard.png | Bin 0 -> 94494 bytes .../user_guide/figures/index_set_fig.png | Bin 0 -> 54730 bytes .../docs/sphinx/user_guide/figures/jacobi.png | Bin 0 -> 165615 bytes .../sphinx/user_guide/figures/redblackGS.png | Bin 0 -> 174447 bytes .../sphinx/user_guide/figures/vertexsum.jpg | Bin 0 -> 8024 bytes .../sphinx/user_guide/getting_started.rst | 164 + tpl/RAJA/docs/sphinx/user_guide/index.rst | 119 + tpl/RAJA/docs/sphinx/user_guide/plugins.rst | 53 + .../docs/sphinx/user_guide/raja_license.rst | 75 + tpl/RAJA/docs/sphinx/user_guide/tutorial.rst | 288 + .../user_guide/tutorial/add_vectors.rst | 106 + .../user_guide/tutorial/atomic_histogram.rst | 86 + .../user_guide/tutorial/dot_product.rst | 96 + .../user_guide/tutorial/gaussSeidel.rst-KEEP | 82 + .../user_guide/tutorial/indexset_segments.rst | 198 + .../user_guide/tutorial/jacobi.rst-KEEP | 121 + .../user_guide/tutorial/matrix_multiply.rst | 321 + .../tutorial/matrix_transpose_local_array.rst | 203 + .../tutorial/nested_loop_reorder.rst | 172 + .../user_guide/tutorial/offset-layout.rst | 133 + .../user_guide/tutorial/permuted-layout.rst | 114 + .../sphinx/user_guide/tutorial/reductions.rst | 94 + .../docs/sphinx/user_guide/tutorial/scan.rst | 174 + .../tutorial/tiled_matrix_transpose.rst | 84 + .../tutorial/vertexsum_coloring.rst | 130 + .../sphinx/user_guide/tutorial/wave.rst-KEEP | 74 + .../docs/sphinx/user_guide/using_raja.rst | 44 + tpl/RAJA/docs/style_guide.md | 206 + tpl/RAJA/examples/CMakeLists.txt | 98 + tpl/RAJA/examples/jacobi.cpp | 507 ++ tpl/RAJA/examples/ltimes.cpp | 1813 ++++ tpl/RAJA/examples/memoryManager.hpp | 84 + tpl/RAJA/examples/omp-target-kernel.cpp | 44 + tpl/RAJA/examples/omp-target-ltimes.cpp | 191 + tpl/RAJA/examples/pi-reduce_vs_atomic.cpp | 245 + tpl/RAJA/examples/plugin/CMakeLists.txt | 10 + tpl/RAJA/examples/plugin/counter-plugin.cpp | 32 + tpl/RAJA/examples/plugin/test-plugin.cpp | 19 + tpl/RAJA/examples/red-black-gauss-seidel.cpp | 251 + tpl/RAJA/examples/test.cpp | 173 + tpl/RAJA/examples/tut_add-vectors.cpp | 232 + tpl/RAJA/examples/tut_atomic-histogram.cpp | 229 + .../examples/tut_batched-matrix-multiply.cpp | 689 ++ tpl/RAJA/examples/tut_daxpy.cpp | 243 + tpl/RAJA/examples/tut_dot-product.cpp | 198 + tpl/RAJA/examples/tut_indexset-segments.cpp | 426 + tpl/RAJA/examples/tut_matrix-multiply.cpp | 1170 +++ .../tut_matrix-transpose-local-array.cpp | 647 ++ tpl/RAJA/examples/tut_nested-loop-reorder.cpp | 141 + tpl/RAJA/examples/tut_offset-layout.cpp | 389 + tpl/RAJA/examples/tut_reductions.cpp | 256 + tpl/RAJA/examples/tut_scan.cpp | 335 + .../examples/tut_tiled-matrix-transpose.cpp | 381 + tpl/RAJA/examples/tut_vertexsum-coloring.cpp | 414 + tpl/RAJA/examples/wave-eqn.cpp | 269 + tpl/RAJA/exercises/CMakeLists.txt | 8 + .../exercises/tutorial_halfday/CMakeLists.txt | 78 + .../tutorial_halfday/ex1_vector-addition.cpp | 268 + .../ex1_vector-addition_solution.cpp | 252 + .../tutorial_halfday/ex2_approx-pi.cpp | 187 + .../ex2_approx-pi_solution.cpp | 171 + .../tutorial_halfday/ex3_colored-indexset.cpp | 342 + .../ex3_colored-indexset_solution.cpp | 331 + .../tutorial_halfday/ex4_atomic-histogram.cpp | 275 + .../ex4_atomic-histogram_solution.cpp | 263 + .../tutorial_halfday/ex5_line-of-sight.cpp | 275 + .../ex5_line-of-sight_solution.cpp | 279 + .../ex6_stencil-offset-layout.cpp | 364 + .../ex6_stencil-offset-layout_solution.cpp | 371 + .../ex7_nested-loop-reorder.cpp | 158 + .../ex7_nested-loop-reorder_solution.cpp | 148 + .../ex8_tiled-matrix-transpose.cpp | 362 + .../ex8_tiled-matrix-transpose_solution.cpp | 347 + .../ex9_matrix-transpose-local-array.cpp | 455 + ..._matrix-transpose-local-array_solution.cpp | 423 + .../tutorial_halfday/memoryManager.hpp | 84 + .../alcf-builds/cooley_clang5_0.cmake | 21 + .../alcf-builds/cooley_gcc7_1_0.cmake | 21 + .../alcf-builds/cooley_nvcc_clang4_0.cmake | 34 + .../alcf-builds/theta_intel18_0.cmake | 23 + .../lc-builds/bgqos/clang_4_0_0.cmake | 26 + .../lc-builds/blueos/clang_X.cmake | 18 + ...angcuda_upstream_2018_12_03_nvcc_9_2.cmake | 23 + .../host-configs/lc-builds/blueos/gcc_X.cmake | 18 + .../lc-builds/blueos/nvcc_clang_X.cmake | 24 + .../lc-builds/blueos/nvcc_gcc_X.cmake | 24 + .../lc-builds/blueos/nvcc_xl_2019_X.cmake | 31 + .../host-configs/lc-builds/blueos/pgi_X.cmake | 18 + .../lc-builds/blueos/xl_2019_X.cmake | 25 + .../lc-builds/toss3/clang_X.cmake | 18 + .../toss3/clangcuda_6_0_0_nvcc_8_0.cmake | 23 + .../host-configs/lc-builds/toss3/gcc_X.cmake | 18 + .../host-configs/lc-builds/toss3/hip.cmake | 44 + .../lc-builds/toss3/icpc_X_gcc7headers.cmake | 20 + .../lc-builds/toss3/icpc_X_gcc8headers.cmake | 20 + .../host-configs/lc-builds/toss3/pgi_X.cmake | 18 + tpl/RAJA/include/RAJA/RAJA.hpp | 164 + tpl/RAJA/include/RAJA/config.hpp.in | 426 + tpl/RAJA/include/RAJA/index/IndexSet.hpp | 768 ++ .../include/RAJA/index/IndexSetBuilders.hpp | 110 + tpl/RAJA/include/RAJA/index/IndexSetUtils.hpp | 114 + tpl/RAJA/include/RAJA/index/IndexValue.hpp | 409 + tpl/RAJA/include/RAJA/index/ListSegment.hpp | 332 + tpl/RAJA/include/RAJA/index/RangeSegment.hpp | 527 ++ .../include/RAJA/internal/DepGraphNode.hpp | 129 + tpl/RAJA/include/RAJA/internal/Iterators.hpp | 415 + .../include/RAJA/internal/MemUtils_CPU.hpp | 97 + tpl/RAJA/include/RAJA/internal/RAJAVec.hpp | 253 + .../include/RAJA/internal/ThreadUtils_CPU.hpp | 52 + .../include/RAJA/internal/fault_tolerance.hpp | 105 + tpl/RAJA/include/RAJA/internal/foldl.hpp | 138 + .../include/RAJA/internal/get_platform.hpp | 130 + tpl/RAJA/include/RAJA/module.modulemap | 6 + .../include/RAJA/module.private.modulemap | 10 + tpl/RAJA/include/RAJA/pattern/atomic.hpp | 507 ++ .../include/RAJA/pattern/detail/forall.hpp | 32 + .../RAJA/pattern/detail/privatizer.hpp | 103 + .../include/RAJA/pattern/detail/reduce.hpp | 455 + tpl/RAJA/include/RAJA/pattern/forall.hpp | 515 ++ tpl/RAJA/include/RAJA/pattern/kernel.hpp | 170 + .../include/RAJA/pattern/kernel/Collapse.hpp | 40 + .../RAJA/pattern/kernel/Conditional.hpp | 218 + tpl/RAJA/include/RAJA/pattern/kernel/For.hpp | 113 + .../include/RAJA/pattern/kernel/ForICount.hpp | 122 + .../RAJA/pattern/kernel/Hyperplane.hpp | 199 + .../RAJA/pattern/kernel/InitLocalMem.hpp | 115 + .../include/RAJA/pattern/kernel/Lambda.hpp | 354 + .../include/RAJA/pattern/kernel/Param.hpp | 66 + .../include/RAJA/pattern/kernel/Reduce.hpp | 61 + .../include/RAJA/pattern/kernel/Region.hpp | 68 + tpl/RAJA/include/RAJA/pattern/kernel/Tile.hpp | 240 + .../RAJA/pattern/kernel/TileTCount.hpp | 137 + .../include/RAJA/pattern/kernel/internal.hpp | 27 + .../RAJA/pattern/kernel/internal/LoopData.hpp | 236 + .../pattern/kernel/internal/LoopTypes.hpp | 96 + .../pattern/kernel/internal/Statement.hpp | 50 + .../pattern/kernel/internal/StatementList.hpp | 97 + .../RAJA/pattern/kernel/internal/Template.hpp | 86 + tpl/RAJA/include/RAJA/pattern/reduce.hpp | 185 + tpl/RAJA/include/RAJA/pattern/region.hpp | 44 + tpl/RAJA/include/RAJA/pattern/scan.hpp | 395 + tpl/RAJA/include/RAJA/pattern/synchronize.hpp | 48 + tpl/RAJA/include/RAJA/pattern/vector.hpp | 27 + .../include/RAJA/pattern/vector/Matrix.hpp | 114 + .../include/RAJA/pattern/vector/Register.hpp | 80 + .../RAJA/pattern/vector/TensorIndex.hpp | 332 + .../include/RAJA/pattern/vector/Vector.hpp | 118 + .../pattern/vector/internal/MatrixBase.hpp | 230 + .../pattern/vector/internal/MatrixImpl.hpp | 736 ++ .../vector/internal/MatrixProductRef.hpp | 255 + .../pattern/vector/internal/MatrixRef.hpp | 338 + .../pattern/vector/internal/RegisterBase.hpp | 284 + .../pattern/vector/internal/VectorImpl.hpp | 715 ++ .../vector/internal/VectorProductRef.hpp | 311 + .../pattern/vector/internal/VectorRef.hpp | 436 + tpl/RAJA/include/RAJA/policy/MultiPolicy.hpp | 190 + tpl/RAJA/include/RAJA/policy/PolicyBase.hpp | 188 + tpl/RAJA/include/RAJA/policy/atomic_auto.hpp | 154 + .../include/RAJA/policy/atomic_builtin.hpp | 363 + tpl/RAJA/include/RAJA/policy/cuda.hpp | 41 + .../RAJA/policy/cuda/MemUtils_CUDA.hpp | 277 + tpl/RAJA/include/RAJA/policy/cuda/atomic.hpp | 771 ++ tpl/RAJA/include/RAJA/policy/cuda/forall.hpp | 266 + tpl/RAJA/include/RAJA/policy/cuda/kernel.hpp | 35 + .../RAJA/policy/cuda/kernel/Conditional.hpp | 78 + .../RAJA/policy/cuda/kernel/CudaKernel.hpp | 595 ++ .../include/RAJA/policy/cuda/kernel/For.hpp | 855 ++ .../RAJA/policy/cuda/kernel/ForICount.hpp | 656 ++ .../RAJA/policy/cuda/kernel/Hyperplane.hpp | 112 + .../RAJA/policy/cuda/kernel/InitLocalMem.hpp | 229 + .../RAJA/policy/cuda/kernel/Lambda.hpp | 75 + .../RAJA/policy/cuda/kernel/Reduce.hpp | 155 + .../include/RAJA/policy/cuda/kernel/Sync.hpp | 104 + .../include/RAJA/policy/cuda/kernel/Tile.hpp | 483 ++ .../RAJA/policy/cuda/kernel/TileTCount.hpp | 316 + .../RAJA/policy/cuda/kernel/internal.hpp | 362 + tpl/RAJA/include/RAJA/policy/cuda/policy.hpp | 373 + .../RAJA/policy/cuda/raja_cudaerrchk.hpp | 67 + tpl/RAJA/include/RAJA/policy/cuda/reduce.hpp | 1208 +++ .../include/RAJA/policy/cuda/register.hpp | 38 + .../RAJA/policy/cuda/register/cuda_warp.hpp | 319 + tpl/RAJA/include/RAJA/policy/cuda/scan.hpp | 228 + .../include/RAJA/policy/cuda/synchronize.hpp | 52 + tpl/RAJA/include/RAJA/policy/hip.hpp | 39 + .../include/RAJA/policy/hip/MemUtils_HIP.hpp | 279 + tpl/RAJA/include/RAJA/policy/hip/atomic.hpp | 670 ++ tpl/RAJA/include/RAJA/policy/hip/forall.hpp | 268 + tpl/RAJA/include/RAJA/policy/hip/kernel.hpp | 36 + .../RAJA/policy/hip/kernel/Conditional.hpp | 78 + .../include/RAJA/policy/hip/kernel/For.hpp | 761 ++ .../RAJA/policy/hip/kernel/ForICount.hpp | 674 ++ .../RAJA/policy/hip/kernel/HipKernel.hpp | 576 ++ .../RAJA/policy/hip/kernel/Hyperplane.hpp | 112 + .../RAJA/policy/hip/kernel/InitLocalMem.hpp | 226 + .../include/RAJA/policy/hip/kernel/Lambda.hpp | 72 + .../include/RAJA/policy/hip/kernel/Reduce.hpp | 156 + .../include/RAJA/policy/hip/kernel/Sync.hpp | 100 + .../include/RAJA/policy/hip/kernel/Tile.hpp | 490 ++ .../RAJA/policy/hip/kernel/TileTCount.hpp | 320 + .../RAJA/policy/hip/kernel/internal.hpp | 420 + tpl/RAJA/include/RAJA/policy/hip/policy.hpp | 354 + .../RAJA/policy/hip/raja_hiperrchk.hpp | 66 + tpl/RAJA/include/RAJA/policy/hip/reduce.hpp | 1055 +++ tpl/RAJA/include/RAJA/policy/hip/scan.hpp | 308 + .../include/RAJA/policy/hip/synchronize.hpp | 52 + tpl/RAJA/include/RAJA/policy/loop.hpp | 29 + tpl/RAJA/include/RAJA/policy/loop/atomic.hpp | 34 + tpl/RAJA/include/RAJA/policy/loop/forall.hpp | 70 + tpl/RAJA/include/RAJA/policy/loop/kernel.hpp | 25 + .../RAJA/policy/loop/kernel/Collapse.hpp | 81 + tpl/RAJA/include/RAJA/policy/loop/policy.hpp | 74 + tpl/RAJA/include/RAJA/policy/loop/scan.hpp | 134 + tpl/RAJA/include/RAJA/policy/openmp.hpp | 43 + .../include/RAJA/policy/openmp/atomic.hpp | 217 + .../include/RAJA/policy/openmp/forall.hpp | 199 + .../include/RAJA/policy/openmp/kernel.hpp | 25 + .../RAJA/policy/openmp/kernel/Collapse.hpp | 149 + .../policy/openmp/kernel/OmpSyncThreads.hpp | 71 + .../include/RAJA/policy/openmp/policy.hpp | 163 + .../include/RAJA/policy/openmp/reduce.hpp | 131 + .../include/RAJA/policy/openmp/region.hpp | 55 + tpl/RAJA/include/RAJA/policy/openmp/scan.hpp | 159 + .../RAJA/policy/openmp/synchronize.hpp | 44 + .../include/RAJA/policy/openmp_target.hpp | 36 + .../RAJA/policy/openmp_target/forall.hpp | 100 + .../RAJA/policy/openmp_target/kernel.hpp | 14 + .../policy/openmp_target/kernel/Collapse.hpp | 109 + .../RAJA/policy/openmp_target/kernel/For.hpp | 65 + .../RAJA/policy/openmp_target/policy.hpp | 73 + .../RAJA/policy/openmp_target/reduce.hpp | 480 ++ tpl/RAJA/include/RAJA/policy/sequential.hpp | 31 + .../include/RAJA/policy/sequential/atomic.hpp | 169 + .../include/RAJA/policy/sequential/forall.hpp | 71 + .../include/RAJA/policy/sequential/kernel.hpp | 25 + .../policy/sequential/kernel/Collapse.hpp | 83 + .../RAJA/policy/sequential/kernel/Reduce.hpp | 55 + .../include/RAJA/policy/sequential/policy.hpp | 83 + .../include/RAJA/policy/sequential/reduce.hpp | 60 + .../include/RAJA/policy/sequential/region.hpp | 49 + .../include/RAJA/policy/sequential/scan.hpp | 131 + tpl/RAJA/include/RAJA/policy/simd.hpp | 28 + tpl/RAJA/include/RAJA/policy/simd/forall.hpp | 70 + .../include/RAJA/policy/simd/kernel/For.hpp | 138 + .../RAJA/policy/simd/kernel/ForICount.hpp | 88 + tpl/RAJA/include/RAJA/policy/simd/policy.hpp | 57 + tpl/RAJA/include/RAJA/policy/tbb.hpp | 32 + tpl/RAJA/include/RAJA/policy/tbb/forall.hpp | 138 + tpl/RAJA/include/RAJA/policy/tbb/policy.hpp | 93 + tpl/RAJA/include/RAJA/policy/tbb/reduce.hpp | 93 + tpl/RAJA/include/RAJA/policy/tbb/scan.hpp | 201 + tpl/RAJA/include/RAJA/policy/vector.hpp | 27 + .../include/RAJA/policy/vector/forall.hpp | 84 + .../include/RAJA/policy/vector/kernel/For.hpp | 102 + .../include/RAJA/policy/vector/policy.hpp | 76 + .../include/RAJA/policy/vector/register.hpp | 78 + .../RAJA/policy/vector/register/altivec.hpp | 37 + .../register/altivec/altivec_double.hpp | 308 + .../vector/register/altivec/altivec_float.hpp | 388 + .../vector/register/altivec/altivec_int32.hpp | 376 + .../vector/register/altivec/altivec_int64.hpp | 298 + .../RAJA/policy/vector/register/avx.hpp | 38 + .../policy/vector/register/avx/avx_double.hpp | 404 + .../policy/vector/register/avx/avx_float.hpp | 391 + .../policy/vector/register/avx/avx_int32.hpp | 615 ++ .../policy/vector/register/avx/avx_int64.hpp | 434 + .../RAJA/policy/vector/register/avx2.hpp | 37 + .../vector/register/avx2/avx2_double.hpp | 399 + .../vector/register/avx2/avx2_float.hpp | 428 + .../vector/register/avx2/avx2_int32.hpp | 477 ++ .../vector/register/avx2/avx2_int64.hpp | 408 + .../policy/vector/register/scalar/scalar.hpp | 287 + tpl/RAJA/include/RAJA/util/BitMask.hpp | 57 + tpl/RAJA/include/RAJA/util/Layout.hpp | 404 + tpl/RAJA/include/RAJA/util/LocalArray.hpp | 130 + tpl/RAJA/include/RAJA/util/OffsetLayout.hpp | 199 + tpl/RAJA/include/RAJA/util/Operators.hpp | 636 ++ tpl/RAJA/include/RAJA/util/Permutations.hpp | 244 + tpl/RAJA/include/RAJA/util/PermutedLayout.hpp | 102 + tpl/RAJA/include/RAJA/util/PluginContext.hpp | 34 + tpl/RAJA/include/RAJA/util/PluginStrategy.hpp | 36 + tpl/RAJA/include/RAJA/util/Registry.hpp | 135 + tpl/RAJA/include/RAJA/util/SoAArray.hpp | 81 + tpl/RAJA/include/RAJA/util/SoAPtr.hpp | 130 + tpl/RAJA/include/RAJA/util/Span.hpp | 160 + tpl/RAJA/include/RAJA/util/StaticLayout.hpp | 267 + tpl/RAJA/include/RAJA/util/Timer.hpp | 278 + tpl/RAJA/include/RAJA/util/TypeConvert.hpp | 57 + tpl/RAJA/include/RAJA/util/TypedViewBase.hpp | 552 ++ tpl/RAJA/include/RAJA/util/View.hpp | 121 + tpl/RAJA/include/RAJA/util/align.hpp | 59 + tpl/RAJA/include/RAJA/util/basic_mempool.hpp | 426 + tpl/RAJA/include/RAJA/util/camp_aliases.hpp | 50 + tpl/RAJA/include/RAJA/util/concepts.hpp | 43 + tpl/RAJA/include/RAJA/util/macros.hpp | 187 + tpl/RAJA/include/RAJA/util/mutex.hpp | 84 + tpl/RAJA/include/RAJA/util/plugins.hpp | 44 + tpl/RAJA/include/RAJA/util/types.hpp | 715 ++ tpl/RAJA/reproducers/CMakeLists.txt | 10 + tpl/RAJA/reproducers/clangcuda/CMakeLists.txt | 10 + .../clangcuda/reproducer-shuffle.cpp | 77 + .../scripts/alcf-builds/cooley_clang5.0.sh | 34 + .../scripts/alcf-builds/cooley_gcc7.1.0.sh | 34 + .../alcf-builds/cooley_nvcc9.1_clang4.0.sh | 37 + tpl/RAJA/scripts/alcf-builds/theta_intel18.sh | 37 + tpl/RAJA/scripts/install_llvm.sh | 15 + .../scripts/lc-builds/bgqos_clang4.0.0.sh | 22 + .../blueos_clang-coral-2018.08.08.sh | 24 + ...blueos_clang-coral-2018.08.08_omptarget.sh | 30 + .../blueos_clang-upstream-2019.08.15.sh | 24 + ...eos_clang-upstream-2019.08.15_omptarget.sh | 27 + .../scripts/lc-builds/blueos_clang6.0.0.sh | 24 + .../scripts/lc-builds/blueos_clang7.1.0.sh | 24 + .../scripts/lc-builds/blueos_clang8.0.1.sh | 24 + .../scripts/lc-builds/blueos_clang9.0.0.sh | 24 + ...s_clangcuda-upstream-2018.12.03_nvcc9.2.sh | 28 + tpl/RAJA/scripts/lc-builds/blueos_gcc4.9.3.sh | 24 + tpl/RAJA/scripts/lc-builds/blueos_gcc7.3.1.sh | 24 + tpl/RAJA/scripts/lc-builds/blueos_gcc8.3.1.sh | 24 + ...blueos_nvcc10_clang-upstream-2019.08.15.sh | 28 + .../lc-builds/blueos_nvcc10_clang6.0.0.sh | 28 + .../lc-builds/blueos_nvcc10_clang7.1.0.sh | 28 + .../lc-builds/blueos_nvcc10_clang8.0.1.sh | 28 + .../lc-builds/blueos_nvcc10_clang9.0.0.sh | 28 + .../lc-builds/blueos_nvcc10_gcc7.3.1.sh | 28 + .../lc-builds/blueos_nvcc10_gcc8.3.1.sh | 28 + .../lc-builds/blueos_nvcc10_xl-2019.04.19.sh | 28 + .../lc-builds/blueos_nvcc10_xl-2019.06.12.sh | 28 + .../lc-builds/blueos_nvcc10_xl-2019.08.20.sh | 28 + .../lc-builds/blueos_nvcc10_xl-2019.12.23.sh | 28 + .../blueos_nvcc9_clang-coral-2018.08.08.sh | 28 + .../lc-builds/blueos_nvcc9_gcc7.3.1.sh | 28 + .../lc-builds/blueos_nvcc9_xl-2019.04.19.sh | 28 + .../lc-builds/blueos_nvcc9_xl-2019.06.12.sh | 28 + tpl/RAJA/scripts/lc-builds/blueos_pgi19.10.sh | 25 + .../scripts/lc-builds/blueos_xl-2019.04.19.sh | 24 + .../blueos_xl-2019.04.19_omptarget.sh | 26 + .../scripts/lc-builds/blueos_xl-2019.06.12.sh | 24 + .../blueos_xl-2019.06.12_omptarget.sh | 26 + .../scripts/lc-builds/blueos_xl-2019.08.20.sh | 24 + .../blueos_xl-2019.08.20_omptarget.sh | 26 + .../scripts/lc-builds/blueos_xl-2019.12.23.sh | 24 + .../blueos_xl-2019.12.23_omptarget.sh | 26 + tpl/RAJA/scripts/lc-builds/corona_hipcc.sh | 29 + .../scripts/lc-builds/toss3_clang6.0.0.sh | 24 + .../scripts/lc-builds/toss3_clang7.1.0.sh | 24 + .../scripts/lc-builds/toss3_clang8.0.1.sh | 24 + .../scripts/lc-builds/toss3_clang9.0.0.sh | 24 + .../lc-builds/toss3_clangcuda6.0.0_nvcc8.0.sh | 28 + tpl/RAJA/scripts/lc-builds/toss3_gcc4.9.3.sh | 24 + tpl/RAJA/scripts/lc-builds/toss3_gcc6.1.0.sh | 24 + tpl/RAJA/scripts/lc-builds/toss3_gcc7.3.0.sh | 24 + tpl/RAJA/scripts/lc-builds/toss3_gcc8.1.0.sh | 24 + .../scripts/lc-builds/toss3_icpc17.0.2.sh | 24 + .../scripts/lc-builds/toss3_icpc18.0.2.sh | 24 + .../scripts/lc-builds/toss3_icpc19.1.0.sh | 24 + tpl/RAJA/scripts/lc-builds/toss3_pgi19.7.sh | 24 + tpl/RAJA/scripts/make_release_tarball.sh | 25 + tpl/RAJA/scripts/run_clang_format.sh | 12 + tpl/RAJA/scripts/travis_build_and_test.sh | 36 + tpl/RAJA/scripts/update_copyright.sh | 59 + .../share/raja/cmake/RAJA-config.cmake.in | 46 + tpl/RAJA/share/raja/logo/RAJA_LOGO_Color.png | Bin 0 -> 14209 bytes tpl/RAJA/share/raja/pkg-config/RAJA.pc.in | 8 + tpl/RAJA/src/AlignedRangeIndexSetBuilders.cpp | 188 + tpl/RAJA/src/DepGraphNode.cpp | 42 + tpl/RAJA/src/LockFreeIndexSetBuilders.cpp | 340 + tpl/RAJA/src/MemUtils_CUDA.cpp | 65 + tpl/RAJA/src/MemUtils_HIP.cpp | 65 + tpl/RAJA/src/PluginStrategy.cpp | 18 + tpl/RAJA/test/CMakeLists.txt | 17 + tpl/RAJA/test/functional/CMakeLists.txt | 9 + .../test/functional/atomic/CMakeLists.txt | 31 + .../atomic/test-atomic-forall-basic.cpp | 153 + .../atomic/test-atomic-forall-basic.hpp | 235 + .../atomic/test-atomic-forall-view.cpp | 69 + .../atomic/test-atomic-forall-view.hpp | 77 + .../test-atomic-ref-forall-math-auto.cpp | 60 + .../atomic/test-atomic-ref-forall-math.cpp | 70 + .../atomic/test-atomic-ref-forall-math.hpp | 313 + .../test-atomic-ref-forall-other-auto.cpp | 56 + .../atomic/test-atomic-ref-forall-other.cpp | 69 + .../atomic/test-atomic-ref-forall-other.hpp | 462 + tpl/RAJA/test/include/RAJA_gtest.hpp | 119 + tpl/RAJA/test/include/RAJA_unit_forone.hpp | 24 + tpl/RAJA/test/include/RAJA_value_params.hpp | 13 + tpl/RAJA/test/include/type_helper.hpp | 142 + tpl/RAJA/test/integration/CMakeLists.txt | 10 + tpl/RAJA/test/integration/counter.hpp | 13 + tpl/RAJA/test/integration/plugin_for_test.cpp | 27 + tpl/RAJA/test/integration/test_plugin.cpp | 33 + tpl/RAJA/test/old-tests/CMakeLists.txt | 17 + tpl/RAJA/test/old-tests/unit/CMakeLists.txt | 53 + .../test/old-tests/unit/cpu/CMakeLists.txt | 37 + .../test/old-tests/unit/cpu/buildIndexSet.cpp | 222 + .../test/old-tests/unit/cpu/buildIndexSet.hpp | 41 + .../old-tests/unit/cpu/test-forall-view.cpp | 95 + .../test/old-tests/unit/cpu/test-forall.cpp | 129 + .../test/old-tests/unit/cpu/test-reduce.cpp | 327 + .../old-tests/unit/cpu/test-reductions.cpp | 904 ++ .../test/old-tests/unit/cpu/test-scan.cpp | 216 + .../old-tests/unit/cpu/test-synchronize.cpp | 30 + .../test/old-tests/unit/cuda/CMakeLists.txt | 46 + .../old-tests/unit/cuda/test-forall-view.cpp | 127 + .../test/old-tests/unit/cuda/test-forall.cpp | 288 + .../old-tests/unit/cuda/test-reduce-loc.cpp | 337 + .../old-tests/unit/cuda/test-reduce-max.cpp | 229 + .../old-tests/unit/cuda/test-reduce-min.cpp | 227 + .../unit/cuda/test-reduce-randloc.cpp | 463 + .../old-tests/unit/cuda/test-reduce-sum.cpp | 277 + .../unit/cuda/test-reduce-tupleloc.cpp | 381 + .../test/old-tests/unit/cuda/test-scan.cpp | 218 + .../old-tests/unit/cuda/test-synchronize.cpp | 31 + .../old-tests/unit/omp-target/CMakeLists.txt | 24 + .../test/old-tests/unit/omp-target/kernel.cpp | 44 + .../unit/omp-target/test-nested-reduce.cpp | 63 + .../omp-target/test-reduce-tuplemaxloc.cpp | 185 + .../omp-target/test-reduce-tupleminloc.cpp | 190 + .../unit/omp-target/test-reductions.cpp | 327 + .../unit/test-kernel-lambda-args.cpp | 1410 ++++ tpl/RAJA/test/old-tests/unit/test-kernel.cpp | 4422 ++++++++++ tpl/RAJA/test/old-tests/unit/test-matrix.cpp | 459 + .../test/old-tests/unit/test-multipolicy.cpp | 103 + tpl/RAJA/test/old-tests/unit/test-region.cpp | 56 + .../test/old-tests/unit/test-register.cpp | 736 ++ .../test/old-tests/unit/test-sharedmem.cpp | 969 +++ tpl/RAJA/test/old-tests/unit/test-simd.cpp | 253 + tpl/RAJA/test/old-tests/unit/test-vector.cpp | 345 + tpl/RAJA/test/unit/CMakeLists.txt | 13 + tpl/RAJA/test/unit/atomic/CMakeLists.txt | 30 + .../unit/atomic/test-atomic-ref-accessors.cpp | 136 + .../unit/atomic/test-atomic-ref-addsub.cpp | 161 + .../unit/atomic/test-atomic-ref-bitwise.cpp | 182 + .../atomic/test-atomic-ref-constructor.cpp | 151 + .../unit/atomic/test-atomic-ref-exchanges.cpp | 200 + .../unit/atomic/test-atomic-ref-minmax.cpp | 130 + tpl/RAJA/test/unit/atomic/test-atomic-ref.hpp | 65 + tpl/RAJA/test/unit/hip/CMakeLists.txt | 46 + tpl/RAJA/test/unit/hip/test-forall-view.cpp | 133 + tpl/RAJA/test/unit/hip/test-forall.cpp | 300 + tpl/RAJA/test/unit/hip/test-reduce-loc.cpp | 352 + tpl/RAJA/test/unit/hip/test-reduce-max.cpp | 240 + tpl/RAJA/test/unit/hip/test-reduce-min.cpp | 240 + .../test/unit/hip/test-reduce-randloc.cpp | 465 + tpl/RAJA/test/unit/hip/test-reduce-sum.cpp | 294 + .../test/unit/hip/test-reduce-tupleloc.cpp | 394 + tpl/RAJA/test/unit/hip/test-scan.cpp | 273 + tpl/RAJA/test/unit/hip/test-synchronize.cpp | 36 + tpl/RAJA/test/unit/index/CMakeLists.txt | 27 + tpl/RAJA/test/unit/index/test-indexset.cpp | 219 + tpl/RAJA/test/unit/index/test-indexvalue.cpp | 289 + tpl/RAJA/test/unit/index/test-listsegment.cpp | 107 + .../test/unit/index/test-rangesegment.cpp | 140 + .../unit/index/test-rangestridesegment.cpp | 172 + tpl/RAJA/test/unit/internal/CMakeLists.txt | 15 + .../test/unit/internal/test-iterators.cpp | 167 + tpl/RAJA/test/unit/internal/test-rajavec.cpp | 66 + tpl/RAJA/test/unit/util/CMakeLists.txt | 26 + tpl/RAJA/test/unit/util/test-float-limits.cpp | 43 + .../test/unit/util/test-integral-limits.cpp | 51 + tpl/RAJA/test/unit/util/test-operators.cpp | 494 ++ tpl/RAJA/test/unit/util/test-span.cpp | 53 + tpl/RAJA/test/unit/util/test-span.hpp | 250 + tpl/RAJA/test/unit/util/test-timer.cpp | 95 + tpl/RAJA/test/unit/view-layout/CMakeLists.txt | 22 + .../test/unit/view-layout/test-makelayout.cpp | 245 + .../unit/view-layout/test-standard-layout.cpp | 178 + .../unit/view-layout/test-typedlayout.cpp | 226 + .../test/unit/view-layout/test-typedview.cpp | 325 + tpl/RAJA/tpl/camp/.clang-format | 28 + tpl/RAJA/tpl/camp/.gitignore | 9 + tpl/RAJA/tpl/camp/.gitmodules | 4 + tpl/RAJA/tpl/camp/.travis.yml | 80 + tpl/RAJA/tpl/camp/CMakeLists.txt | 87 + tpl/RAJA/tpl/camp/LICENSE | 32 + tpl/RAJA/tpl/camp/NOTICE | 22 + tpl/RAJA/tpl/camp/README.md | 5 + tpl/RAJA/tpl/camp/cmake/camp.pc.in | 8 + tpl/RAJA/tpl/camp/cmake/campConfig.cmake.in | 7 + tpl/RAJA/tpl/camp/docs/conf.py | 210 + tpl/RAJA/tpl/camp/docs/index.rst | 6 + tpl/RAJA/tpl/camp/docs/requirements.txt | 5 + tpl/RAJA/tpl/camp/include/camp/camp.hpp | 213 + tpl/RAJA/tpl/camp/include/camp/concepts.hpp | 388 + tpl/RAJA/tpl/camp/include/camp/defines.hpp | 105 + .../tpl/camp/include/camp/detail/sfinae.hpp | 54 + .../tpl/camp/include/camp/detail/test.hpp | 55 + tpl/RAJA/tpl/camp/include/camp/helpers.hpp | 199 + tpl/RAJA/tpl/camp/include/camp/lambda.hpp | 90 + tpl/RAJA/tpl/camp/include/camp/list.hpp | 18 + tpl/RAJA/tpl/camp/include/camp/list/at.hpp | 95 + .../tpl/camp/include/camp/list/find_if.hpp | 56 + tpl/RAJA/tpl/camp/include/camp/list/list.hpp | 55 + .../tpl/camp/include/camp/make_unique.hpp | 28 + tpl/RAJA/tpl/camp/include/camp/map.hpp | 57 + tpl/RAJA/tpl/camp/include/camp/number.hpp | 139 + tpl/RAJA/tpl/camp/include/camp/number/if.hpp | 57 + .../tpl/camp/include/camp/number/number.hpp | 44 + tpl/RAJA/tpl/camp/include/camp/resource.hpp | 143 + .../tpl/camp/include/camp/resource/cuda.hpp | 132 + .../tpl/camp/include/camp/resource/event.hpp | 78 + .../tpl/camp/include/camp/resource/hip.hpp | 131 + .../tpl/camp/include/camp/resource/host.hpp | 73 + .../camp/include/camp/resource/omp_target.hpp | 187 + .../camp/include/camp/resource/platform.hpp | 32 + tpl/RAJA/tpl/camp/include/camp/size.hpp | 22 + tpl/RAJA/tpl/camp/include/camp/tuple.hpp | 546 ++ .../tpl/camp/include/camp/type_traits.hpp | 16 + .../camp/include/camp/type_traits/is_same.hpp | 41 + tpl/RAJA/tpl/camp/include/camp/value.hpp | 54 + tpl/RAJA/tpl/camp/include/camp/value/eval.hpp | 23 + .../tpl/camp/scripts/travis_build_and_test.sh | 36 + tpl/RAJA/tpl/camp/test/CMakeLists.txt | 125 + tpl/RAJA/tpl/camp/test/accumulate.cpp | 34 + tpl/RAJA/tpl/camp/test/at_key.cpp | 7 + tpl/RAJA/tpl/camp/test/filter.cpp | 5 + tpl/RAJA/tpl/camp/test/find_if.cpp | 20 + tpl/RAJA/tpl/camp/test/flatten.cpp | 10 + tpl/RAJA/tpl/camp/test/index_of.cpp | 7 + tpl/RAJA/tpl/camp/test/lambda.cpp | 7 + tpl/RAJA/tpl/camp/test/number.cpp | 7 + tpl/RAJA/tpl/camp/test/resource.cpp | 182 + tpl/RAJA/tpl/camp/test/size.cpp | 11 + tpl/RAJA/tpl/camp/test/transform.cpp | 7 + tpl/RAJA/tpl/camp/test/tuple.cpp | 124 + tpl/RAJA/tpl/camp/test/tuple_out_of_range.cpp | 9 + tpl/RAJA/tpl/cub/.cproject | 1223 +++ tpl/RAJA/tpl/cub/.project | 27 + tpl/RAJA/tpl/cub/.settings/.gitignore | 1 + .../org.eclipse.cdt.codan.core.prefs | 72 + .../cub/.settings/org.eclipse.cdt.core.prefs | 177 + .../cub/.settings/org.eclipse.cdt.ui.prefs | 3 + .../.settings/org.eclipse.core.runtime.prefs | 4 + tpl/RAJA/tpl/cub/CHANGE_LOG.TXT | 403 + tpl/RAJA/tpl/cub/LICENSE.TXT | 24 + tpl/RAJA/tpl/cub/README.md | 128 + tpl/RAJA/tpl/cub/common.mk | 233 + .../tpl/cub/cub/agent/agent_histogram.cuh | 787 ++ .../cub/agent/agent_radix_sort_downsweep.cuh | 789 ++ .../cub/agent/agent_radix_sort_upsweep.cuh | 526 ++ tpl/RAJA/tpl/cub/cub/agent/agent_reduce.cuh | 385 + .../tpl/cub/cub/agent/agent_reduce_by_key.cuh | 547 ++ tpl/RAJA/tpl/cub/cub/agent/agent_rle.cuh | 837 ++ tpl/RAJA/tpl/cub/cub/agent/agent_scan.cuh | 471 ++ .../tpl/cub/cub/agent/agent_segment_fixup.cuh | 375 + .../tpl/cub/cub/agent/agent_select_if.cuh | 703 ++ .../tpl/cub/cub/agent/agent_spmv_orig.cuh | 670 ++ .../cub/agent/single_pass_scan_operators.cuh | 815 ++ .../cub/block/block_adjacent_difference.cuh | 596 ++ .../tpl/cub/cub/block/block_discontinuity.cuh | 1148 +++ tpl/RAJA/tpl/cub/cub/block/block_exchange.cuh | 1248 +++ .../tpl/cub/cub/block/block_histogram.cuh | 415 + tpl/RAJA/tpl/cub/cub/block/block_load.cuh | 1241 +++ .../tpl/cub/cub/block/block_radix_rank.cuh | 696 ++ .../tpl/cub/cub/block/block_radix_sort.cuh | 863 ++ .../tpl/cub/cub/block/block_raking_layout.cuh | 152 + tpl/RAJA/tpl/cub/cub/block/block_reduce.cuh | 607 ++ tpl/RAJA/tpl/cub/cub/block/block_scan.cuh | 2126 +++++ tpl/RAJA/tpl/cub/cub/block/block_shuffle.cuh | 305 + tpl/RAJA/tpl/cub/cub/block/block_store.cuh | 1000 +++ .../block_histogram_atomic.cuh | 82 + .../specializations/block_histogram_sort.cuh | 226 + .../specializations/block_reduce_raking.cuh | 226 + .../block_reduce_raking_commutative_only.cuh | 199 + .../block_reduce_warp_reductions.cuh | 218 + .../specializations/block_scan_raking.cuh | 666 ++ .../specializations/block_scan_warp_scans.cuh | 392 + .../block_scan_warp_scans2.cuh | 436 + .../block_scan_warp_scans3.cuh | 418 + tpl/RAJA/tpl/cub/cub/cub.cuh | 95 + .../tpl/cub/cub/device/device_histogram.cuh | 866 ++ .../tpl/cub/cub/device/device_partition.cuh | 273 + .../tpl/cub/cub/device/device_radix_sort.cuh | 797 ++ tpl/RAJA/tpl/cub/cub/device/device_reduce.cuh | 734 ++ .../cub/device/device_run_length_encode.cuh | 278 + tpl/RAJA/tpl/cub/cub/device/device_scan.cuh | 443 + .../device/device_segmented_radix_sort.cuh | 876 ++ .../cub/device/device_segmented_reduce.cuh | 619 ++ tpl/RAJA/tpl/cub/cub/device/device_select.cuh | 369 + tpl/RAJA/tpl/cub/cub/device/device_spmv.cuh | 174 + .../device/dispatch/dispatch_histogram.cuh | 1096 +++ .../device/dispatch/dispatch_radix_sort.cuh | 1619 ++++ .../cub/device/dispatch/dispatch_reduce.cuh | 882 ++ .../dispatch/dispatch_reduce_by_key.cuh | 554 ++ .../cub/cub/device/dispatch/dispatch_rle.cuh | 538 ++ .../cub/cub/device/dispatch/dispatch_scan.cuh | 563 ++ .../device/dispatch/dispatch_select_if.cuh | 542 ++ .../device/dispatch/dispatch_spmv_orig.cuh | 834 ++ tpl/RAJA/tpl/cub/cub/grid/grid_barrier.cuh | 211 + tpl/RAJA/tpl/cub/cub/grid/grid_even_share.cuh | 222 + tpl/RAJA/tpl/cub/cub/grid/grid_mapping.cuh | 113 + tpl/RAJA/tpl/cub/cub/grid/grid_queue.cuh | 220 + tpl/RAJA/tpl/cub/cub/host/mutex.cuh | 171 + .../cub/iterator/arg_index_input_iterator.cuh | 259 + .../cache_modified_input_iterator.cuh | 240 + .../cache_modified_output_iterator.cuh | 254 + .../cub/iterator/constant_input_iterator.cuh | 235 + .../cub/iterator/counting_input_iterator.cuh | 228 + .../cub/iterator/discard_output_iterator.cuh | 220 + .../cub/iterator/tex_obj_input_iterator.cuh | 310 + .../cub/iterator/tex_ref_input_iterator.cuh | 374 + .../cub/iterator/transform_input_iterator.cuh | 252 + tpl/RAJA/tpl/cub/cub/thread/thread_load.cuh | 438 + .../tpl/cub/cub/thread/thread_operators.cuh | 317 + tpl/RAJA/tpl/cub/cub/thread/thread_reduce.cuh | 152 + tpl/RAJA/tpl/cub/cub/thread/thread_scan.cuh | 268 + tpl/RAJA/tpl/cub/cub/thread/thread_search.cuh | 154 + tpl/RAJA/tpl/cub/cub/thread/thread_store.cuh | 422 + tpl/RAJA/tpl/cub/cub/util_allocator.cuh | 708 ++ tpl/RAJA/tpl/cub/cub/util_arch.cuh | 151 + tpl/RAJA/tpl/cub/cub/util_debug.cuh | 145 + tpl/RAJA/tpl/cub/cub/util_device.cuh | 347 + tpl/RAJA/tpl/cub/cub/util_macro.cuh | 103 + tpl/RAJA/tpl/cub/cub/util_namespace.cuh | 46 + tpl/RAJA/tpl/cub/cub/util_ptx.cuh | 758 ++ tpl/RAJA/tpl/cub/cub/util_type.cuh | 1167 +++ .../warp/specializations/warp_reduce_shfl.cuh | 541 ++ .../warp/specializations/warp_reduce_smem.cuh | 372 + .../warp/specializations/warp_scan_shfl.cuh | 632 ++ .../warp/specializations/warp_scan_smem.cuh | 397 + tpl/RAJA/tpl/cub/cub/warp/warp_reduce.cuh | 612 ++ tpl/RAJA/tpl/cub/cub/warp/warp_scan.cuh | 936 +++ .../tpl/cub/eclipse code style profile.xml | 155 + tpl/RAJA/tpl/cub/examples/block/.gitignore | 7 + tpl/RAJA/tpl/cub/examples/block/Makefile | 128 + .../block/example_block_radix_sort.cu | 323 + .../examples/block/example_block_reduce.cu | 290 + .../cub/examples/block/example_block_scan.cu | 334 + .../tpl/cub/examples/block/reduce_by_key.cu | 57 + tpl/RAJA/tpl/cub/examples/device/.gitignore | 8 + tpl/RAJA/tpl/cub/examples/device/Makefile | 197 + .../example_device_partition_flagged.cu | 233 + .../device/example_device_partition_if.cu | 244 + .../device/example_device_radix_sort.cu | 226 + .../examples/device/example_device_reduce.cu | 180 + .../examples/device/example_device_scan.cu | 186 + .../device/example_device_select_flagged.cu | 233 + .../device/example_device_select_if.cu | 242 + .../device/example_device_select_unique.cu | 221 + ...ample_device_sort_find_non_trivial_runs.cu | 384 + tpl/RAJA/tpl/cub/experimental/.gitignore | 1 + tpl/RAJA/tpl/cub/experimental/Makefile | 125 + .../experimental/defunct/example_coo_spmv.cu | 1070 +++ .../defunct/test_device_seg_reduce.cu | 2142 +++++ .../experimental/histogram/histogram_cub.h | 109 + .../histogram/histogram_gmem_atomics.h | 185 + .../histogram/histogram_smem_atomics.h | 195 + .../tpl/cub/experimental/histogram_compare.cu | 635 ++ tpl/RAJA/tpl/cub/experimental/sparse_matrix.h | 1244 +++ tpl/RAJA/tpl/cub/experimental/spmv_compare.cu | 917 ++ tpl/RAJA/tpl/cub/experimental/spmv_script.sh | 30 + tpl/RAJA/tpl/cub/test/.gitignore | 3 + tpl/RAJA/tpl/cub/test/Makefile | 468 ++ tpl/RAJA/tpl/cub/test/half.h | 298 + tpl/RAJA/tpl/cub/test/link_a.cu | 11 + tpl/RAJA/tpl/cub/test/link_b.cu | 11 + tpl/RAJA/tpl/cub/test/link_main.cpp | 10 + tpl/RAJA/tpl/cub/test/mersenne.h | 160 + tpl/RAJA/tpl/cub/test/test_allocator.cu | 459 + tpl/RAJA/tpl/cub/test/test_block_histogram.cu | 310 + .../tpl/cub/test/test_block_load_store.cu | 549 ++ .../tpl/cub/test/test_block_radix_sort.cu | 717 ++ tpl/RAJA/tpl/cub/test/test_block_reduce.cu | 822 ++ tpl/RAJA/tpl/cub/test/test_block_scan.cu | 929 ++ .../tpl/cub/test/test_device_histogram.cu | 1669 ++++ .../tpl/cub/test/test_device_radix_sort.cu | 1298 +++ tpl/RAJA/tpl/cub/test/test_device_reduce.cu | 1359 +++ .../tpl/cub/test/test_device_reduce_by_key.cu | 853 ++ .../cub/test/test_device_run_length_encode.cu | 890 ++ tpl/RAJA/tpl/cub/test/test_device_scan.cu | 1015 +++ .../tpl/cub/test/test_device_select_if.cu | 1039 +++ .../tpl/cub/test/test_device_select_unique.cu | 651 ++ tpl/RAJA/tpl/cub/test/test_grid_barrier.cu | 152 + tpl/RAJA/tpl/cub/test/test_iterator.cu | 805 ++ tpl/RAJA/tpl/cub/test/test_util.h | 1628 ++++ tpl/RAJA/tpl/cub/test/test_warp_reduce.cu | 840 ++ tpl/RAJA/tpl/cub/test/test_warp_scan.cu | 661 ++ tpl/RAJA/tpl/cub/tune/.gitignore | 1 + tpl/RAJA/tpl/cub/tune/Makefile | 192 + tpl/RAJA/tpl/cub/tune/tune_device_reduce.cu | 763 ++ tpl/RAJA/tpl/rocPRIM/.clang-format | 120 + tpl/RAJA/tpl/rocPRIM/.githooks/install | 8 + tpl/RAJA/tpl/rocPRIM/.githooks/pre-commit | 58 + tpl/RAJA/tpl/rocPRIM/.gitignore | 61 + tpl/RAJA/tpl/rocPRIM/.gitlab-ci.yml | 118 + tpl/RAJA/tpl/rocPRIM/CMakeLists.txt | 117 + tpl/RAJA/tpl/rocPRIM/Jenkinsfile | 105 + tpl/RAJA/tpl/rocPRIM/LICENSE.txt | 21 + tpl/RAJA/tpl/rocPRIM/NOTICES.txt | 67 + tpl/RAJA/tpl/rocPRIM/README.md | 150 + tpl/RAJA/tpl/rocPRIM/benchmark/CMakeLists.txt | 71 + .../benchmark_block_discontinuity.cpp | 337 + .../benchmark/benchmark_block_exchange.cpp | 381 + .../benchmark/benchmark_block_histogram.cpp | 256 + .../benchmark/benchmark_block_radix_sort.cpp | 300 + .../benchmark/benchmark_block_reduce.cpp | 266 + .../benchmark/benchmark_block_scan.cpp | 317 + .../benchmark/benchmark_block_sort.cpp | 283 + .../benchmark_device_binary_search.cpp | 231 + .../benchmark/benchmark_device_histogram.cpp | 535 ++ .../benchmark/benchmark_device_memory.cpp | 984 +++ .../benchmark/benchmark_device_merge.cpp | 344 + .../benchmark/benchmark_device_merge_sort.cpp | 356 + .../benchmark/benchmark_device_partition.cpp | 357 + .../benchmark/benchmark_device_radix_sort.cpp | 362 + .../benchmark/benchmark_device_reduce.cpp | 206 + .../benchmark_device_reduce_by_key.cpp | 267 + .../benchmark_device_run_length_encode.cpp | 374 + .../benchmark/benchmark_device_scan.cpp | 281 + .../benchmark_device_segmented_radix_sort.cpp | 444 + .../benchmark_device_segmented_reduce.cpp | 261 + .../benchmark/benchmark_device_select.cpp | 488 ++ .../benchmark/benchmark_device_transform.cpp | 198 + .../tpl/rocPRIM/benchmark/benchmark_utils.hpp | 207 + .../benchmark/benchmark_warp_reduce.cpp | 285 + .../rocPRIM/benchmark/benchmark_warp_scan.cpp | 238 + .../rocPRIM/benchmark/benchmark_warp_sort.cpp | 248 + tpl/RAJA/tpl/rocPRIM/benchmark/cmdparser.hpp | 508 ++ tpl/RAJA/tpl/rocPRIM/cmake/Dependencies.cmake | 126 + .../cmake/DownloadProject.CMakeLists.cmake.in | 27 + .../tpl/rocPRIM/cmake/DownloadProject.cmake | 170 + tpl/RAJA/tpl/rocPRIM/cmake/Summary.cmake | 39 + .../tpl/rocPRIM/cmake/VerifyCompiler.cmake | 62 + tpl/RAJA/tpl/rocPRIM/doc/Doxyfile | 2437 ++++++ tpl/RAJA/tpl/rocPRIM/doc/blockmodule.dox | 11 + tpl/RAJA/tpl/rocPRIM/doc/devicemodule.dox | 10 + tpl/RAJA/tpl/rocPRIM/doc/glossary.dox | 38 + tpl/RAJA/tpl/rocPRIM/doc/intrinsicsmodule.dox | 10 + tpl/RAJA/tpl/rocPRIM/doc/iteratormodule.dox | 10 + tpl/RAJA/tpl/rocPRIM/doc/mainpage.dox | 15 + tpl/RAJA/tpl/rocPRIM/doc/primitivesmodule.dox | 15 + tpl/RAJA/tpl/rocPRIM/doc/utilsmodule.dox | 29 + tpl/RAJA/tpl/rocPRIM/doc/warpmodule.dox | 11 + .../rocPRIM/docker/dockerfile-build-centos | 39 + .../tpl/rocPRIM/docker/dockerfile-build-sles | 37 + .../docker/dockerfile-build-ubuntu-rock | 39 + .../rocPRIM/docker/dockerfile-install-centos | 19 + .../rocPRIM/docker/dockerfile-install-sles | 6 + .../rocPRIM/docker/dockerfile-install-ubuntu | 19 + tpl/RAJA/tpl/rocPRIM/example/CMakeLists.txt | 46 + .../example/example_temporary_storage.cpp | 399 + .../tpl/rocPRIM/example/example_utils.hpp | 119 + tpl/RAJA/tpl/rocPRIM/install | 135 + tpl/RAJA/tpl/rocPRIM/rocprim/CMakeLists.txt | 78 + .../rocprim/block/block_discontinuity.hpp | 994 +++ .../include/rocprim/block/block_exchange.hpp | 729 ++ .../include/rocprim/block/block_histogram.hpp | 325 + .../include/rocprim/block/block_load.hpp | 756 ++ .../include/rocprim/block/block_load_func.hpp | 510 ++ .../rocprim/block/block_radix_sort.hpp | 980 +++ .../include/rocprim/block/block_reduce.hpp | 398 + .../include/rocprim/block/block_scan.hpp | 1318 +++ .../include/rocprim/block/block_sort.hpp | 327 + .../include/rocprim/block/block_store.hpp | 482 ++ .../rocprim/block/block_store_func.hpp | 393 + .../block/detail/block_histogram_atomic.hpp | 86 + .../block/detail/block_histogram_sort.hpp | 165 + .../detail/block_reduce_raking_reduce.hpp | 234 + .../block/detail/block_reduce_warp_reduce.hpp | 268 + .../detail/block_scan_reduce_then_scan.hpp | 628 ++ .../block/detail/block_scan_warp_scan.hpp | 746 ++ .../block/detail/block_sort_bitonic.hpp | 357 + .../rocprim/include/rocprim/config.hpp | 64 + .../include/rocprim/detail/all_true.hpp | 52 + .../rocprim/detail/binary_op_wrappers.hpp | 136 + .../rocprim/detail/match_result_type.hpp | 111 + .../include/rocprim/detail/radix_sort.hpp | 168 + .../include/rocprim/detail/various.hpp | 247 + .../include/rocprim/device/config_types.hpp | 161 + .../device/detail/device_binary_search.hpp | 126 + .../device/detail/device_histogram.hpp | 551 ++ .../rocprim/device/detail/device_merge.hpp | 455 + .../device/detail/device_merge_sort.hpp | 494 ++ .../device/detail/device_partition.hpp | 600 ++ .../device/detail/device_radix_sort.hpp | 590 ++ .../rocprim/device/detail/device_reduce.hpp | 184 + .../device/detail/device_reduce_by_key.hpp | 632 ++ .../device/detail/device_scan_lookback.hpp | 320 + .../detail/device_scan_reduce_then_scan.hpp | 442 + .../detail/device_segmented_radix_sort.hpp | 581 ++ .../device/detail/device_segmented_reduce.hpp | 166 + .../device/detail/device_segmented_scan.hpp | 236 + .../device/detail/device_transform.hpp | 154 + .../device/detail/lookback_scan_state.hpp | 381 + .../device/detail/ordered_block_id.hpp | 87 + .../rocprim/device/detail/uint_fast_div.hpp | 111 + .../rocprim/device/device_binary_search.hpp | 177 + .../rocprim/device/device_histogram.hpp | 1207 +++ .../device/device_histogram_config.hpp | 108 + .../include/rocprim/device/device_merge.hpp | 435 + .../rocprim/device/device_merge_config.hpp | 107 + .../rocprim/device/device_merge_sort.hpp | 441 + .../device/device_merge_sort_config.hpp | 85 + .../rocprim/device/device_partition.hpp | 447 + .../rocprim/device/device_radix_sort.hpp | 1397 +++ .../device/device_radix_sort_config.hpp | 174 + .../include/rocprim/device/device_reduce.hpp | 408 + .../rocprim/device/device_reduce_by_key.hpp | 412 + .../device/device_reduce_by_key_config.hpp | 105 + .../rocprim/device/device_reduce_config.hpp | 103 + .../device/device_run_length_encode.hpp | 409 + .../device_run_length_encode_config.hpp | 66 + .../include/rocprim/device/device_scan.hpp | 647 ++ .../rocprim/device/device_scan_by_key.hpp | 349 + .../rocprim/device/device_scan_config.hpp | 123 + .../device/device_segmented_radix_sort.hpp | 1261 +++ .../device_segmented_radix_sort_config.hpp | 154 + .../device/device_segmented_reduce.hpp | 270 + .../rocprim/device/device_segmented_scan.hpp | 647 ++ .../include/rocprim/device/device_select.hpp | 395 + .../rocprim/device/device_select_config.hpp | 116 + .../rocprim/device/device_transform.hpp | 276 + .../device/device_transform_config.hpp | 77 + .../rocprim/include/rocprim/functional.hpp | 193 + .../rocprim/include/rocprim/intrinsics.hpp | 33 + .../include/rocprim/intrinsics/atomic.hpp | 75 + .../include/rocprim/intrinsics/bit.hpp | 61 + .../include/rocprim/intrinsics/thread.hpp | 236 + .../include/rocprim/intrinsics/warp.hpp | 77 + .../rocprim/intrinsics/warp_shuffle.hpp | 195 + .../rocprim/include/rocprim/iterator.hpp | 35 + .../rocprim/iterator/arg_index_iterator.hpp | 264 + .../rocprim/iterator/constant_iterator.hpp | 257 + .../rocprim/iterator/counting_iterator.hpp | 267 + .../detail/replace_first_iterator.hpp | 133 + .../rocprim/iterator/discard_iterator.hpp | 236 + .../iterator/texture_cache_iterator.hpp | 346 + .../rocprim/iterator/transform_iterator.hpp | 260 + .../include/rocprim/iterator/zip_iterator.hpp | 339 + .../rocprim/include/rocprim/rocprim.hpp | 81 + .../include/rocprim/rocprim_version.hpp.in | 41 + .../rocprim/include/rocprim/type_traits.hpp | 107 + .../rocPRIM/rocprim/include/rocprim/types.hpp | 120 + .../include/rocprim/types/double_buffer.hpp | 80 + .../rocprim/types/integer_sequence.hpp | 94 + .../include/rocprim/types/key_value_pair.hpp | 81 + .../rocprim/include/rocprim/types/tuple.hpp | 1109 +++ .../warp/detail/warp_reduce_crosslane.hpp | 53 + .../rocprim/warp/detail/warp_reduce_dpp.hpp | 160 + .../warp/detail/warp_reduce_shared_mem.hpp | 167 + .../warp/detail/warp_reduce_shuffle.hpp | 165 + .../warp/detail/warp_scan_crosslane.hpp | 52 + .../rocprim/warp/detail/warp_scan_dpp.hpp | 262 + .../warp/detail/warp_scan_shared_mem.hpp | 191 + .../rocprim/warp/detail/warp_scan_shuffle.hpp | 237 + .../warp/detail/warp_segment_bounds.hpp | 63 + .../rocprim/warp/detail/warp_sort_shuffle.hpp | 178 + .../include/rocprim/warp/warp_reduce.hpp | 310 + .../include/rocprim/warp/warp_scan.hpp | 554 ++ .../include/rocprim/warp/warp_sort.hpp | 243 + tpl/RAJA/tpl/rocPRIM/test/CMakeLists.txt | 59 + .../tpl/rocPRIM/test/extra/CMakeLists.txt | 72 + .../test/extra/test_rocprim_package.cpp | 106 + .../tpl/rocPRIM/test/rocprim/CMakeLists.txt | 89 + .../test/rocprim/bounds_checking_iterator.hpp | 194 + .../rocprim/detail/get_rocprim_version.cpp | 58 + .../rocprim/detail/get_rocprim_version.hpp | 43 + .../test/rocprim/identity_iterator.hpp | 165 + .../test/rocprim/test_arg_index_iterator.cpp | 190 + .../tpl/rocPRIM/test/rocprim/test_basic.cpp | 47 + .../test/rocprim/test_block_discontinuity.cpp | 643 ++ .../test/rocprim/test_block_exchange.cpp | 843 ++ .../test/rocprim/test_block_histogram.cpp | 250 + .../test/rocprim/test_block_load_store.cpp | 557 ++ .../test/rocprim/test_block_radix_sort.cpp | 467 ++ .../test/rocprim/test_block_reduce.cpp | 509 ++ .../rocPRIM/test/rocprim/test_block_scan.cpp | 1487 ++++ .../rocPRIM/test/rocprim/test_block_sort.cpp | 382 + .../test/rocprim/test_constant_iterator.cpp | 133 + .../test/rocprim/test_counting_iterator.cpp | 130 + .../rocprim/test_device_binary_search.cpp | 401 + .../test/rocprim/test_device_histogram.cpp | 1034 +++ .../test/rocprim/test_device_merge.cpp | 407 + .../test/rocprim/test_device_merge_sort.cpp | 354 + .../test/rocprim/test_device_partition.cpp | 460 + .../test/rocprim/test_device_radix_sort.cpp | 697 ++ .../test/rocprim/test_device_reduce.cpp | 471 ++ .../rocprim/test_device_reduce_by_key.cpp | 317 + .../rocprim/test_device_run_length_encode.cpp | 413 + .../rocPRIM/test/rocprim/test_device_scan.cpp | 616 ++ .../test_device_segmented_radix_sort.cpp | 820 ++ .../rocprim/test_device_segmented_reduce.cpp | 235 + .../rocprim/test_device_segmented_scan.cpp | 642 ++ .../test/rocprim/test_device_select.cpp | 561 ++ .../test/rocprim/test_device_transform.cpp | 289 + .../test/rocprim/test_discard_iterator.cpp | 164 + .../rocPRIM/test/rocprim/test_intrinsics.cpp | 556 ++ .../rocprim/test_texture_cache_iterator.cpp | 149 + .../test/rocprim/test_transform_iterator.cpp | 192 + .../tpl/rocPRIM/test/rocprim/test_utils.hpp | 914 ++ .../rocPRIM/test/rocprim/test_utils_types.hpp | 101 + .../rocPRIM/test/rocprim/test_warp_reduce.cpp | 796 ++ .../rocPRIM/test/rocprim/test_warp_scan.cpp | 873 ++ .../rocPRIM/test/rocprim/test_warp_sort.cpp | 274 + .../test/rocprim/test_zip_iterator.cpp | 426 + tpl/RAJA/tpl/rocPRIM/test/test_hip_api.cpp | 100 + .../travis-data/docker/bionic-base/Dockerfile | 11 + .../docker/bionic-base/generic-setup-18.04.sh | 12 + tpl/RAJA/travis-data/docker/build-all.sh | 30 + tpl/RAJA/travis-data/docker/clang4/Dockerfile | 15 + tpl/RAJA/travis-data/docker/clang5/Dockerfile | 14 + tpl/RAJA/travis-data/docker/clang6/Dockerfile | 14 + tpl/RAJA/travis-data/docker/clang9/Dockerfile | 11 + tpl/RAJA/travis-data/docker/gcc49/Dockerfile | 14 + tpl/RAJA/travis-data/docker/gcc5/Dockerfile | 15 + tpl/RAJA/travis-data/docker/gcc6/Dockerfile | 15 + tpl/RAJA/travis-data/docker/gcc7/Dockerfile | 15 + tpl/RAJA/travis-data/docker/gcc8/Dockerfile | 16 + tpl/RAJA/travis-data/docker/generic-setup.sh | 26 + tpl/RAJA/travis-data/docker/hip/Dockerfile | 10 + .../travis-data/docker/hip/generic-setup.sh | 26 + tpl/RAJA/travis-data/docker/icc16/Dockerfile | 23 + .../travis-data/docker/icc16/generic-setup.sh | 26 + tpl/RAJA/travis-data/docker/icc18/Dockerfile | 23 + tpl/RAJA/travis-data/docker/nvcc10/Dockerfile | 12 + .../docker/nvcc10/generic-setup-18.04.sh | 21 + tpl/RAJA/travis-data/docker/nvcc8/Dockerfile | 12 + .../travis-data/docker/nvcc8/generic-setup.sh | 26 + tpl/RAJA/travis-data/docker/nvcc9/Dockerfile | 12 + .../travis-data/docker/nvcc9/generic-setup.sh | 26 + .../docker/ubuntu-clang-base/Dockerfile | 10 + .../docker/ubuntu-clang-base/generic-setup.sh | 26 + tpl/RAJA/travis-data/intel2016.lic.enc | Bin 0 -> 560 bytes 1506 files changed, 390658 insertions(+), 1 deletion(-) delete mode 160000 tpl/RAJA create mode 100644 tpl/RAJA/.clang-format create mode 100644 tpl/RAJA/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 tpl/RAJA/.gitignore create mode 100644 tpl/RAJA/.gitmodules create mode 100644 tpl/RAJA/.travis.yml create mode 100644 tpl/RAJA/CMakeLists.txt create mode 100644 tpl/RAJA/CODE_OF_CONDUCT.md create mode 100644 tpl/RAJA/CONTRIBUTING.md create mode 100644 tpl/RAJA/Dockerfile create mode 100644 tpl/RAJA/LICENSE create mode 100644 tpl/RAJA/NOTICE create mode 100644 tpl/RAJA/README.md create mode 100644 tpl/RAJA/RELEASE create mode 100644 tpl/RAJA/RELEASE_NOTES.md create mode 100644 tpl/RAJA/appveyor.yml create mode 100644 tpl/RAJA/benchmark/CMakeLists.txt create mode 100644 tpl/RAJA/benchmark/host-device-lambda-benchmark.cpp create mode 100644 tpl/RAJA/blt/.mailmap create mode 100644 tpl/RAJA/blt/.travis.yml create mode 100644 tpl/RAJA/blt/CODE-OF-CONDUCT.md create mode 100644 tpl/RAJA/blt/CONTRIBUTING.md create mode 100644 tpl/RAJA/blt/LICENSE create mode 100644 tpl/RAJA/blt/NOTICE create mode 100644 tpl/RAJA/blt/README.md create mode 100644 tpl/RAJA/blt/RELEASE-NOTES.md create mode 100644 tpl/RAJA/blt/SetupBLT.cmake create mode 100644 tpl/RAJA/blt/appveyor.yml create mode 100644 tpl/RAJA/blt/cmake/BLTGitMacros.cmake create mode 100644 tpl/RAJA/blt/cmake/BLTMacros.cmake create mode 100644 tpl/RAJA/blt/cmake/BLTOptions.cmake create mode 100644 tpl/RAJA/blt/cmake/BLTPrivateMacros.cmake create mode 100644 tpl/RAJA/blt/cmake/SetupCodeChecks.cmake create mode 100644 tpl/RAJA/blt/cmake/SetupCodeCoverageReports.cmake create mode 100644 tpl/RAJA/blt/cmake/SetupCodeMetrics.cmake create mode 100644 tpl/RAJA/blt/cmake/SetupCompilerOptions.cmake create mode 100644 tpl/RAJA/blt/cmake/SetupDocs.cmake create mode 100644 tpl/RAJA/blt/cmake/WrapAstyle.cmake.in create mode 100644 tpl/RAJA/blt/cmake/clang-query-wrapper.py create mode 100644 tpl/RAJA/blt/cmake/thirdparty/FindHIP.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_hipcc.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_make2cmake.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/FindROCm.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/SetupCUDA.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/SetupHCC.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/SetupHIP.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/SetupMPI.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/SetupOpenMP.cmake create mode 100644 tpl/RAJA/blt/cmake/thirdparty/SetupThirdParty.cmake create mode 100644 tpl/RAJA/blt/docs/CMakeLists.txt create mode 100644 tpl/RAJA/blt/docs/api/code_check.rst create mode 100644 tpl/RAJA/blt/docs/api/documentation.rst create mode 100644 tpl/RAJA/blt/docs/api/git.rst create mode 100644 tpl/RAJA/blt/docs/api/index.rst create mode 100644 tpl/RAJA/blt/docs/api/target.rst create mode 100644 tpl/RAJA/blt/docs/api/target_properties.rst create mode 100644 tpl/RAJA/blt/docs/api/utility.rst create mode 100644 tpl/RAJA/blt/docs/conf.py create mode 100644 tpl/RAJA/blt/docs/index.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/blank_project/CMakeLists.txt create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/CMakeLists.txt create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.hpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.hpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda_exports.h create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_exports.h create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.hpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi_exports.h create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/docs/CMakeLists.txt create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/CMakeLists.txt create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/Doxyfile.in create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/CMakeLists.txt create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/conf.py create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/index.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/example_1.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/example_2.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/test_1.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/test_2.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/calc_pi/test_3.cpp create mode 100644 tpl/RAJA/blt/docs/tutorial/creating_documentation.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/creating_execs_and_libs.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/external_dependencies.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/index.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/recommendations.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/setup_blt.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/unit_testing.rst create mode 100644 tpl/RAJA/blt/docs/tutorial/using_flags.rst create mode 100644 tpl/RAJA/blt/host-configs/darwin/elcapitan-x86_64/naples-clang@7.3.0.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/bgqos_0/clang@4.0.0_xlf.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_link_with_nvcc.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_nvcc_xlf.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@4.0.0-libcxx.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@6.0.0-static-analysis.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/gcc@4.9.3.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/pgi@18.5.cmake create mode 100644 tpl/RAJA/blt/host-configs/llnl/windows/sqa-uno-msvc@15.cmake create mode 100644 tpl/RAJA/blt/host-configs/other/hcc.cmake create mode 100644 tpl/RAJA/blt/host-configs/other/hip.cmake create mode 100644 tpl/RAJA/blt/host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake create mode 100644 tpl/RAJA/blt/share/blt/logo/blt_logo.png create mode 100644 tpl/RAJA/blt/tests/internal/CMakeLists.txt create mode 100644 tpl/RAJA/blt/tests/internal/astyle.cfg create mode 100644 tpl/RAJA/blt/tests/internal/src/Example.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/Example.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/Example_Exports.h create mode 100644 tpl/RAJA/blt/tests/internal/src/HeaderOnly.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/CMakeLists.txt create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_shared_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_static_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/dummy.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/combine_static_library_test/main.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/CMakeLists.txt create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/base_object.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/base_object.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/inherited_base/CMakeLists.txt create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/inherited_base/inherited_base.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/inherited_base/inherited_base.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/main.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/object.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/object_library_test/object.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/static_analysis/CMakeLists.txt create mode 100644 tpl/RAJA/blt/tests/internal/src/static_analysis/static_analysis_passes/if-stmt create mode 100644 tpl/RAJA/blt/tests/internal/src/static_analysis/well_analyzed_source.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/t_example_compile_definitions.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/t_example_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/t_git_macros_smoke.cpp.in create mode 100644 tpl/RAJA/blt/tests/internal/src/t_header_only_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CMakeLists.txt create mode 100644 tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CudaTests.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.cpp create mode 100644 tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.hpp create mode 100644 tpl/RAJA/blt/tests/internal/src/test_cuda_mpi.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/CMakeLists.txt create mode 100644 tpl/RAJA/blt/tests/smoke/blt_cuda_mpi_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_cuda_openmp_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_cuda_runtime_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_cuda_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_fruit_smoke.f90 create mode 100644 tpl/RAJA/blt/tests/smoke/blt_gbenchmark_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_gmock_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_gtest_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_hcc_runtime_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_hcc_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_hip_runtime_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_hip_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_mpi_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/blt_openmp_smoke.cpp create mode 100644 tpl/RAJA/blt/tests/smoke/fortran_driver.cpp create mode 100644 tpl/RAJA/blt/thirdparty_builtin/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.clang-format create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.gitignore create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis-libcxx-setup.sh create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis.yml create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.ycm_extra_conf.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/AUTHORS create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/BUILD.bazel create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTING.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTORS create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/LICENSE create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/README.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/WORKSPACE create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/_config.yml create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/appveyor.yml create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/AddCXXCompilerFlag.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/CXXFeatureCheck.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/Config.cmake.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GetGitVersion.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/benchmark.pc.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/gnu_posix_regex.cpp create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/llvm-toolchain.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/posix_regex.cpp create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/split_list.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/std_regex.cpp create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/steady_clock.cpp create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/thread_safety_attributes.cpp create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/conanfile.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/test_package.cpp create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conanfile.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/dependencies.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/AssemblyTests.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/_config.yml create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/tools.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/include/benchmark/benchmark.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/mingw.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/releasing.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/arraysize.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_main.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_name.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/check.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/console_reporter.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/csv_reporter.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/cycleclock.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/internal_macros.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/json_reporter.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/log.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/mutex.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/re.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/reporter.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sysinfo.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_manager.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_timer.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/AssemblyTests.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/BUILD create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/basic_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_gtest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_name_gtest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/clobber_memory_assembly_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/commandlineflags_gtest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/complexity_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/cxx03_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/diagnostics_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/display_aggregates_only_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_assembly_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/filter_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/fixture_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/internal_threading_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/link_main_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/map_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/memory_manager_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/multiple_ranges_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/options_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test_helper.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/register_benchmark_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/report_aggregates_only_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/reporter_output_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/skip_with_error_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/state_assembly_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/statistics_gtest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/string_util_gtest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/templated_fixture_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_tabular_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_thousands_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/compare.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run1.json create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run2.json create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test2_run.json create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run0.json create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run1.json create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/__init__.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/report.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/util.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/strip_asm.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CHANGES.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/LICENSE.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/fruit.f90 create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.gitignore create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.travis.yml create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/BUILD.bazel create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CONTRIBUTING.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/LICENSE create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/README.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/WORKSPACE create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/appveyor.yml create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CONTRIBUTORS create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/LICENSE create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/README.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock.pc.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock_main.pc.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cheat_sheet.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cook_book.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/for_dummies.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/gmock_faq.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/pump_manual.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-actions.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-cardinalities.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-function-mocker.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h.pump create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h.pump create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h.pump create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-matchers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-more-actions.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-more-matchers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-nice-strict.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-spec-builders.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/custom/README.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/custom/gmock-generated-actions.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/custom/gmock-matchers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/custom/gmock-port.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/gmock-internal-utils.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/gmock-port.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/internal/gmock-pp.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/README.md create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/fuse_gmock_files.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/LICENSE create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/README create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/README.cppclean create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/cpp/__init__.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/cpp/ast.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/cpp/gmock_class.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/cpp/gmock_class_test.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/cpp/keywords.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/cpp/tokenize.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/cpp/utils.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/generator/gmock_gen.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/scripts/pump.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/src/gmock-all.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/src/gmock-cardinalities.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/src/gmock-internal-utils.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/src/gmock-matchers.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/src/gmock-spec-builders.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/src/gmock.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/src/gmock_main.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/BUILD.bazel create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-actions_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-cardinalities_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-function-mocker_nc.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-function-mocker_nc_test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-function-mocker_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-generated-actions_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-generated-function-mockers_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-generated-matchers_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-internal-utils_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-matchers_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-more-actions_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-nice-strict_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-port_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-pp-string_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-pp_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock-spec-builders_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_all_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_ex_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_leak_test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_leak_test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_link2_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_link_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_link_test.h create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_output_test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_output_test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_output_test_golden.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_stress_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/gmock_test_utils.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/test/pump_test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/CMakeLists.txt create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/CONTRIBUTORS create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/LICENSE create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/README.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/cmake/Config.cmake.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/cmake/gtest.pc.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/cmake/gtest_main.pc.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/cmake/internal_utils.cmake create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/cmake/libgtest.la.in create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/docs/advanced.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/docs/faq.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/docs/pkgconfig.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/docs/primer.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/docs/samples.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-death-test.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-matchers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-message.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-param-test.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-printers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-spi.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-test-part.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest-typed-test.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest_pred_impl.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/gtest_prod.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/custom/README.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/custom/gtest-port.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/custom/gtest-printers.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/custom/gtest.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-death-test-internal.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-filepath.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-internal.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-param-util.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-port-arch.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-port.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-string.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/include/gtest/internal/gtest-type-util.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/prime_tables.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample1.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample1.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample10_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample1_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample2.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample2.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample2_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample3-inl.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample3_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample4.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample4.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample4_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample5_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample6_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample7_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample8_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/samples/sample9_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/README.md create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/common.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/fuse_gtest_files.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/gen_gtest_pred_impl.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/gtest-config.in create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/release_docs.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/run_with_path.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/test/Makefile create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/upload.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/scripts/upload_gtest.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-all.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-death-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-filepath.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-internal-inl.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-matchers.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-port.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-printers.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-test-part.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest-typed-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest_main.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/BUILD.bazel create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-break-on-failure-unittest.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-break-on-failure-unittest_.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-catch-exceptions-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-catch-exceptions-test_.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-color-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-color-test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-death-test-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-death-test_ex_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-env-var-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-env-var-test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-filepath-test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-filter-unittest.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-filter-unittest_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-json-outfiles-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-json-output-unittest.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-list-tests-unittest.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-list-tests-unittest_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-listener-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-message-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-options-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-output-test-golden-lin.txt create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-output-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-output-test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-param-test-invalid-name1-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-param-test-invalid-name1-test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-param-test-invalid-name2-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-param-test-invalid-name2-test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-param-test-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-param-test-test.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-param-test2-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-port-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-printers-test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-setuptestsuite-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-setuptestsuite-test_.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-shuffle-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-shuffle-test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-test-part-test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-test2_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-throw-on-failure-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-throw-on-failure-test_.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-uninitialized-test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/googletest-uninitialized-test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest-typed-test2_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest-typed-test_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest-typed-test_test.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest-unittest-api_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_all_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_assert_by_exception_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_environment_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_help_test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_help_test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_json_test_utils.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_list_output_unittest.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_list_output_unittest_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_main_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_no_test_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_pred_impl_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_premature_exit_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_prod_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_repeat_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_skip_check_output_test.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_skip_environment_check_output_test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_skip_in_environment_setup_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_skip_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_sole_header_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_stress_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_test_macro_stack_footprint_test.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_test_utils.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_testbridge_test.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_testbridge_test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_throw_on_failure_ex_test.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_unittest.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_xml_outfile1_test_.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_xml_outfile2_test_.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_xml_outfiles_test.py create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_xml_output_unittest.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_xml_output_unittest_.cc create mode 100755 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/gtest_xml_test_utils.py create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/production.cc create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/test/production.h create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/library.json create mode 100644 tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/platformio.ini create mode 100644 tpl/RAJA/blt/thirdparty_builtin/patches/gbenchmark-2019-09-09-optional-install.patch create mode 100644 tpl/RAJA/blt/thirdparty_builtin/patches/gbenchmark-2020-01-07-remove-minimum-cmake.patch create mode 100644 tpl/RAJA/blt/thirdparty_builtin/patches/gtest-2020-01-07-override-GTEST_HAS_DEATH_TEST.patch create mode 100644 tpl/RAJA/blt/thirdparty_builtin/patches/gtest-2020-01-07-remove-cxx-std-logic.patch create mode 100644 tpl/RAJA/blt/thirdparty_builtin/patches/gtest-2020-01-07-remove-minimum-cmake.patch create mode 100644 tpl/RAJA/cmake/RAJAMacros.cmake create mode 100644 tpl/RAJA/cmake/SetupBasics.cmake create mode 100644 tpl/RAJA/cmake/SetupCompilers.cmake create mode 100644 tpl/RAJA/cmake/SetupPackages.cmake create mode 100644 tpl/RAJA/cmake/SetupRajaConfig.cmake create mode 100644 tpl/RAJA/cmake/thirdparty/FindCUB.cmake create mode 100644 tpl/RAJA/cmake/thirdparty/FindRocPRIM.cmake create mode 100644 tpl/RAJA/cmake/thirdparty/FindSphinx.cmake create mode 100644 tpl/RAJA/cmake/thirdparty/FindTBB.cmake create mode 100644 tpl/RAJA/codecov.yml create mode 100644 tpl/RAJA/docs/CMakeLists.txt create mode 100644 tpl/RAJA/docs/Licenses/libc++ License create mode 100644 tpl/RAJA/docs/Licenses/llvm-license.txt create mode 100644 tpl/RAJA/docs/doxygen/CMakeLists.txt create mode 100644 tpl/RAJA/docs/doxygen/Doxyfile.in create mode 100644 tpl/RAJA/docs/sphinx/.gitignore create mode 100644 tpl/RAJA/docs/sphinx/user_guide/CMakeLists.txt create mode 100644 tpl/RAJA/docs/sphinx/user_guide/app_considerations.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/conf.py create mode 100644 tpl/RAJA/docs/sphinx/user_guide/config_options.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/contributing.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/atomic.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/iteration_spaces.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/local_array.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/loop_basic.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/policies.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/reduction.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/scan.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/tiling.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/feature/view.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/features.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/IndexSet.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/ListSegment.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/RangeSegment.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/RangeStrideSegment.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/gsboard.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/index_set_fig.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/jacobi.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/redblackGS.png create mode 100644 tpl/RAJA/docs/sphinx/user_guide/figures/vertexsum.jpg create mode 100644 tpl/RAJA/docs/sphinx/user_guide/getting_started.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/index.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/plugins.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/raja_license.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/add_vectors.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/atomic_histogram.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/dot_product.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/gaussSeidel.rst-KEEP create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/indexset_segments.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/jacobi.rst-KEEP create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/matrix_multiply.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/matrix_transpose_local_array.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/nested_loop_reorder.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/offset-layout.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/permuted-layout.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/reductions.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/scan.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/tiled_matrix_transpose.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/vertexsum_coloring.rst create mode 100644 tpl/RAJA/docs/sphinx/user_guide/tutorial/wave.rst-KEEP create mode 100644 tpl/RAJA/docs/sphinx/user_guide/using_raja.rst create mode 100644 tpl/RAJA/docs/style_guide.md create mode 100644 tpl/RAJA/examples/CMakeLists.txt create mode 100644 tpl/RAJA/examples/jacobi.cpp create mode 100644 tpl/RAJA/examples/ltimes.cpp create mode 100644 tpl/RAJA/examples/memoryManager.hpp create mode 100644 tpl/RAJA/examples/omp-target-kernel.cpp create mode 100644 tpl/RAJA/examples/omp-target-ltimes.cpp create mode 100644 tpl/RAJA/examples/pi-reduce_vs_atomic.cpp create mode 100644 tpl/RAJA/examples/plugin/CMakeLists.txt create mode 100644 tpl/RAJA/examples/plugin/counter-plugin.cpp create mode 100644 tpl/RAJA/examples/plugin/test-plugin.cpp create mode 100644 tpl/RAJA/examples/red-black-gauss-seidel.cpp create mode 100644 tpl/RAJA/examples/test.cpp create mode 100644 tpl/RAJA/examples/tut_add-vectors.cpp create mode 100644 tpl/RAJA/examples/tut_atomic-histogram.cpp create mode 100644 tpl/RAJA/examples/tut_batched-matrix-multiply.cpp create mode 100644 tpl/RAJA/examples/tut_daxpy.cpp create mode 100644 tpl/RAJA/examples/tut_dot-product.cpp create mode 100644 tpl/RAJA/examples/tut_indexset-segments.cpp create mode 100644 tpl/RAJA/examples/tut_matrix-multiply.cpp create mode 100644 tpl/RAJA/examples/tut_matrix-transpose-local-array.cpp create mode 100644 tpl/RAJA/examples/tut_nested-loop-reorder.cpp create mode 100644 tpl/RAJA/examples/tut_offset-layout.cpp create mode 100644 tpl/RAJA/examples/tut_reductions.cpp create mode 100644 tpl/RAJA/examples/tut_scan.cpp create mode 100644 tpl/RAJA/examples/tut_tiled-matrix-transpose.cpp create mode 100644 tpl/RAJA/examples/tut_vertexsum-coloring.cpp create mode 100644 tpl/RAJA/examples/wave-eqn.cpp create mode 100644 tpl/RAJA/exercises/CMakeLists.txt create mode 100644 tpl/RAJA/exercises/tutorial_halfday/CMakeLists.txt create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex1_vector-addition.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex1_vector-addition_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex2_approx-pi.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex2_approx-pi_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex3_colored-indexset.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex3_colored-indexset_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex4_atomic-histogram.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex4_atomic-histogram_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex5_line-of-sight.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex5_line-of-sight_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex6_stencil-offset-layout.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex6_stencil-offset-layout_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex7_nested-loop-reorder.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex7_nested-loop-reorder_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex8_tiled-matrix-transpose.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex8_tiled-matrix-transpose_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex9_matrix-transpose-local-array.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/ex9_matrix-transpose-local-array_solution.cpp create mode 100644 tpl/RAJA/exercises/tutorial_halfday/memoryManager.hpp create mode 100644 tpl/RAJA/host-configs/alcf-builds/cooley_clang5_0.cmake create mode 100644 tpl/RAJA/host-configs/alcf-builds/cooley_gcc7_1_0.cmake create mode 100644 tpl/RAJA/host-configs/alcf-builds/cooley_nvcc_clang4_0.cmake create mode 100755 tpl/RAJA/host-configs/alcf-builds/theta_intel18_0.cmake create mode 100644 tpl/RAJA/host-configs/lc-builds/bgqos/clang_4_0_0.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/blueos/clang_X.cmake create mode 100644 tpl/RAJA/host-configs/lc-builds/blueos/clangcuda_upstream_2018_12_03_nvcc_9_2.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/blueos/gcc_X.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/blueos/nvcc_clang_X.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/blueos/nvcc_gcc_X.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/blueos/nvcc_xl_2019_X.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/blueos/pgi_X.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/blueos/xl_2019_X.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/toss3/clang_X.cmake create mode 100644 tpl/RAJA/host-configs/lc-builds/toss3/clangcuda_6_0_0_nvcc_8_0.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/toss3/gcc_X.cmake create mode 100644 tpl/RAJA/host-configs/lc-builds/toss3/hip.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/toss3/icpc_X_gcc7headers.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/toss3/icpc_X_gcc8headers.cmake create mode 100755 tpl/RAJA/host-configs/lc-builds/toss3/pgi_X.cmake create mode 100644 tpl/RAJA/include/RAJA/RAJA.hpp create mode 100644 tpl/RAJA/include/RAJA/config.hpp.in create mode 100644 tpl/RAJA/include/RAJA/index/IndexSet.hpp create mode 100644 tpl/RAJA/include/RAJA/index/IndexSetBuilders.hpp create mode 100644 tpl/RAJA/include/RAJA/index/IndexSetUtils.hpp create mode 100644 tpl/RAJA/include/RAJA/index/IndexValue.hpp create mode 100644 tpl/RAJA/include/RAJA/index/ListSegment.hpp create mode 100644 tpl/RAJA/include/RAJA/index/RangeSegment.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/DepGraphNode.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/Iterators.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/MemUtils_CPU.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/RAJAVec.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/ThreadUtils_CPU.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/fault_tolerance.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/foldl.hpp create mode 100644 tpl/RAJA/include/RAJA/internal/get_platform.hpp create mode 100644 tpl/RAJA/include/RAJA/module.modulemap create mode 100644 tpl/RAJA/include/RAJA/module.private.modulemap create mode 100644 tpl/RAJA/include/RAJA/pattern/atomic.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/detail/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/detail/privatizer.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/detail/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Collapse.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Conditional.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/For.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/ForICount.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Hyperplane.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/InitLocalMem.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Lambda.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Param.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Region.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/Tile.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/TileTCount.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/internal.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/internal/LoopData.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/internal/LoopTypes.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/internal/Statement.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/internal/StatementList.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/kernel/internal/Template.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/region.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/scan.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/synchronize.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/Matrix.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/Register.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/TensorIndex.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/Vector.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/MatrixBase.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/MatrixImpl.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/MatrixProductRef.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/MatrixRef.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/RegisterBase.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/VectorImpl.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/VectorProductRef.hpp create mode 100644 tpl/RAJA/include/RAJA/pattern/vector/internal/VectorRef.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/MultiPolicy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/PolicyBase.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/atomic_auto.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/atomic_builtin.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/MemUtils_CUDA.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/atomic.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/Conditional.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/CudaKernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/For.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/ForICount.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/Hyperplane.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/InitLocalMem.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/Lambda.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/Reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/Sync.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/Tile.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/TileTCount.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/kernel/internal.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/raja_cudaerrchk.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/register.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/register/cuda_warp.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/scan.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/cuda/synchronize.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/MemUtils_HIP.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/atomic.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/Conditional.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/For.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/ForICount.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/HipKernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/Hyperplane.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/InitLocalMem.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/Lambda.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/Reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/Sync.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/Tile.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/TileTCount.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/kernel/internal.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/raja_hiperrchk.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/scan.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/hip/synchronize.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/loop.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/loop/atomic.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/loop/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/loop/kernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/loop/kernel/Collapse.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/loop/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/loop/scan.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/atomic.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/kernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/kernel/Collapse.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/kernel/OmpSyncThreads.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/region.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/scan.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp/synchronize.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp_target.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp_target/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp_target/kernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp_target/kernel/Collapse.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp_target/kernel/For.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp_target/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/openmp_target/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/atomic.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/kernel.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/kernel/Collapse.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/kernel/Reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/region.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/sequential/scan.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/simd.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/simd/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/simd/kernel/For.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/simd/kernel/ForICount.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/simd/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/tbb.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/tbb/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/tbb/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/tbb/reduce.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/tbb/scan.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/forall.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/kernel/For.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/policy.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/altivec.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/altivec/altivec_double.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/altivec/altivec_float.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/altivec/altivec_int32.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/altivec/altivec_int64.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx/avx_double.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx/avx_float.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx/avx_int32.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx/avx_int64.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx2.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx2/avx2_double.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx2/avx2_float.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx2/avx2_int32.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/avx2/avx2_int64.hpp create mode 100644 tpl/RAJA/include/RAJA/policy/vector/register/scalar/scalar.hpp create mode 100644 tpl/RAJA/include/RAJA/util/BitMask.hpp create mode 100644 tpl/RAJA/include/RAJA/util/Layout.hpp create mode 100644 tpl/RAJA/include/RAJA/util/LocalArray.hpp create mode 100644 tpl/RAJA/include/RAJA/util/OffsetLayout.hpp create mode 100644 tpl/RAJA/include/RAJA/util/Operators.hpp create mode 100644 tpl/RAJA/include/RAJA/util/Permutations.hpp create mode 100644 tpl/RAJA/include/RAJA/util/PermutedLayout.hpp create mode 100644 tpl/RAJA/include/RAJA/util/PluginContext.hpp create mode 100644 tpl/RAJA/include/RAJA/util/PluginStrategy.hpp create mode 100644 tpl/RAJA/include/RAJA/util/Registry.hpp create mode 100644 tpl/RAJA/include/RAJA/util/SoAArray.hpp create mode 100644 tpl/RAJA/include/RAJA/util/SoAPtr.hpp create mode 100644 tpl/RAJA/include/RAJA/util/Span.hpp create mode 100644 tpl/RAJA/include/RAJA/util/StaticLayout.hpp create mode 100644 tpl/RAJA/include/RAJA/util/Timer.hpp create mode 100644 tpl/RAJA/include/RAJA/util/TypeConvert.hpp create mode 100644 tpl/RAJA/include/RAJA/util/TypedViewBase.hpp create mode 100644 tpl/RAJA/include/RAJA/util/View.hpp create mode 100644 tpl/RAJA/include/RAJA/util/align.hpp create mode 100644 tpl/RAJA/include/RAJA/util/basic_mempool.hpp create mode 100644 tpl/RAJA/include/RAJA/util/camp_aliases.hpp create mode 100644 tpl/RAJA/include/RAJA/util/concepts.hpp create mode 100644 tpl/RAJA/include/RAJA/util/macros.hpp create mode 100644 tpl/RAJA/include/RAJA/util/mutex.hpp create mode 100644 tpl/RAJA/include/RAJA/util/plugins.hpp create mode 100644 tpl/RAJA/include/RAJA/util/types.hpp create mode 100644 tpl/RAJA/reproducers/CMakeLists.txt create mode 100644 tpl/RAJA/reproducers/clangcuda/CMakeLists.txt create mode 100644 tpl/RAJA/reproducers/clangcuda/reproducer-shuffle.cpp create mode 100755 tpl/RAJA/scripts/alcf-builds/cooley_clang5.0.sh create mode 100755 tpl/RAJA/scripts/alcf-builds/cooley_gcc7.1.0.sh create mode 100755 tpl/RAJA/scripts/alcf-builds/cooley_nvcc9.1_clang4.0.sh create mode 100755 tpl/RAJA/scripts/alcf-builds/theta_intel18.sh create mode 100755 tpl/RAJA/scripts/install_llvm.sh create mode 100755 tpl/RAJA/scripts/lc-builds/bgqos_clang4.0.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang-coral-2018.08.08.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang-coral-2018.08.08_omptarget.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang-upstream-2019.08.15.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang-upstream-2019.08.15_omptarget.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang6.0.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang7.1.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang8.0.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clang9.0.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_clangcuda-upstream-2018.12.03_nvcc9.2.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_gcc4.9.3.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_gcc7.3.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_gcc8.3.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_clang-upstream-2019.08.15.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_clang6.0.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_clang7.1.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_clang8.0.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_clang9.0.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_gcc7.3.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_gcc8.3.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_xl-2019.04.19.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_xl-2019.06.12.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_xl-2019.08.20.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc10_xl-2019.12.23.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc9_clang-coral-2018.08.08.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc9_gcc7.3.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc9_xl-2019.04.19.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_nvcc9_xl-2019.06.12.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_pgi19.10.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.04.19.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.04.19_omptarget.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.06.12.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.06.12_omptarget.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.08.20.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.08.20_omptarget.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.12.23.sh create mode 100755 tpl/RAJA/scripts/lc-builds/blueos_xl-2019.12.23_omptarget.sh create mode 100644 tpl/RAJA/scripts/lc-builds/corona_hipcc.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_clang6.0.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_clang7.1.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_clang8.0.1.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_clang9.0.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_clangcuda6.0.0_nvcc8.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_gcc4.9.3.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_gcc6.1.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_gcc7.3.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_gcc8.1.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_icpc17.0.2.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_icpc18.0.2.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_icpc19.1.0.sh create mode 100755 tpl/RAJA/scripts/lc-builds/toss3_pgi19.7.sh create mode 100755 tpl/RAJA/scripts/make_release_tarball.sh create mode 100755 tpl/RAJA/scripts/run_clang_format.sh create mode 100755 tpl/RAJA/scripts/travis_build_and_test.sh create mode 100755 tpl/RAJA/scripts/update_copyright.sh create mode 100644 tpl/RAJA/share/raja/cmake/RAJA-config.cmake.in create mode 100755 tpl/RAJA/share/raja/logo/RAJA_LOGO_Color.png create mode 100644 tpl/RAJA/share/raja/pkg-config/RAJA.pc.in create mode 100644 tpl/RAJA/src/AlignedRangeIndexSetBuilders.cpp create mode 100644 tpl/RAJA/src/DepGraphNode.cpp create mode 100644 tpl/RAJA/src/LockFreeIndexSetBuilders.cpp create mode 100644 tpl/RAJA/src/MemUtils_CUDA.cpp create mode 100644 tpl/RAJA/src/MemUtils_HIP.cpp create mode 100644 tpl/RAJA/src/PluginStrategy.cpp create mode 100644 tpl/RAJA/test/CMakeLists.txt create mode 100644 tpl/RAJA/test/functional/CMakeLists.txt create mode 100644 tpl/RAJA/test/functional/atomic/CMakeLists.txt create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-forall-basic.cpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-forall-basic.hpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-forall-view.cpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-forall-view.hpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-ref-forall-math-auto.cpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-ref-forall-math.cpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-ref-forall-math.hpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-ref-forall-other-auto.cpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-ref-forall-other.cpp create mode 100644 tpl/RAJA/test/functional/atomic/test-atomic-ref-forall-other.hpp create mode 100644 tpl/RAJA/test/include/RAJA_gtest.hpp create mode 100644 tpl/RAJA/test/include/RAJA_unit_forone.hpp create mode 100644 tpl/RAJA/test/include/RAJA_value_params.hpp create mode 100644 tpl/RAJA/test/include/type_helper.hpp create mode 100644 tpl/RAJA/test/integration/CMakeLists.txt create mode 100644 tpl/RAJA/test/integration/counter.hpp create mode 100644 tpl/RAJA/test/integration/plugin_for_test.cpp create mode 100644 tpl/RAJA/test/integration/test_plugin.cpp create mode 100644 tpl/RAJA/test/old-tests/CMakeLists.txt create mode 100644 tpl/RAJA/test/old-tests/unit/CMakeLists.txt create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/CMakeLists.txt create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/buildIndexSet.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/buildIndexSet.hpp create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/test-forall-view.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/test-forall.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/test-reduce.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/test-reductions.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/test-scan.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cpu/test-synchronize.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/CMakeLists.txt create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-forall-view.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-forall.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-reduce-loc.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-reduce-max.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-reduce-min.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-reduce-randloc.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-reduce-sum.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-reduce-tupleloc.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-scan.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/cuda/test-synchronize.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/omp-target/CMakeLists.txt create mode 100644 tpl/RAJA/test/old-tests/unit/omp-target/kernel.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/omp-target/test-nested-reduce.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/omp-target/test-reduce-tuplemaxloc.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/omp-target/test-reduce-tupleminloc.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/omp-target/test-reductions.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-kernel-lambda-args.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-kernel.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-matrix.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-multipolicy.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-region.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-register.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-sharedmem.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-simd.cpp create mode 100644 tpl/RAJA/test/old-tests/unit/test-vector.cpp create mode 100644 tpl/RAJA/test/unit/CMakeLists.txt create mode 100644 tpl/RAJA/test/unit/atomic/CMakeLists.txt create mode 100644 tpl/RAJA/test/unit/atomic/test-atomic-ref-accessors.cpp create mode 100644 tpl/RAJA/test/unit/atomic/test-atomic-ref-addsub.cpp create mode 100644 tpl/RAJA/test/unit/atomic/test-atomic-ref-bitwise.cpp create mode 100644 tpl/RAJA/test/unit/atomic/test-atomic-ref-constructor.cpp create mode 100644 tpl/RAJA/test/unit/atomic/test-atomic-ref-exchanges.cpp create mode 100644 tpl/RAJA/test/unit/atomic/test-atomic-ref-minmax.cpp create mode 100644 tpl/RAJA/test/unit/atomic/test-atomic-ref.hpp create mode 100644 tpl/RAJA/test/unit/hip/CMakeLists.txt create mode 100644 tpl/RAJA/test/unit/hip/test-forall-view.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-forall.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-reduce-loc.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-reduce-max.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-reduce-min.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-reduce-randloc.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-reduce-sum.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-reduce-tupleloc.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-scan.cpp create mode 100644 tpl/RAJA/test/unit/hip/test-synchronize.cpp create mode 100644 tpl/RAJA/test/unit/index/CMakeLists.txt create mode 100644 tpl/RAJA/test/unit/index/test-indexset.cpp create mode 100644 tpl/RAJA/test/unit/index/test-indexvalue.cpp create mode 100644 tpl/RAJA/test/unit/index/test-listsegment.cpp create mode 100644 tpl/RAJA/test/unit/index/test-rangesegment.cpp create mode 100644 tpl/RAJA/test/unit/index/test-rangestridesegment.cpp create mode 100644 tpl/RAJA/test/unit/internal/CMakeLists.txt create mode 100644 tpl/RAJA/test/unit/internal/test-iterators.cpp create mode 100644 tpl/RAJA/test/unit/internal/test-rajavec.cpp create mode 100644 tpl/RAJA/test/unit/util/CMakeLists.txt create mode 100644 tpl/RAJA/test/unit/util/test-float-limits.cpp create mode 100644 tpl/RAJA/test/unit/util/test-integral-limits.cpp create mode 100644 tpl/RAJA/test/unit/util/test-operators.cpp create mode 100644 tpl/RAJA/test/unit/util/test-span.cpp create mode 100644 tpl/RAJA/test/unit/util/test-span.hpp create mode 100644 tpl/RAJA/test/unit/util/test-timer.cpp create mode 100644 tpl/RAJA/test/unit/view-layout/CMakeLists.txt create mode 100644 tpl/RAJA/test/unit/view-layout/test-makelayout.cpp create mode 100644 tpl/RAJA/test/unit/view-layout/test-standard-layout.cpp create mode 100644 tpl/RAJA/test/unit/view-layout/test-typedlayout.cpp create mode 100644 tpl/RAJA/test/unit/view-layout/test-typedview.cpp create mode 100644 tpl/RAJA/tpl/camp/.clang-format create mode 100644 tpl/RAJA/tpl/camp/.gitignore create mode 100644 tpl/RAJA/tpl/camp/.gitmodules create mode 100644 tpl/RAJA/tpl/camp/.travis.yml create mode 100644 tpl/RAJA/tpl/camp/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/camp/LICENSE create mode 100644 tpl/RAJA/tpl/camp/NOTICE create mode 100644 tpl/RAJA/tpl/camp/README.md create mode 100644 tpl/RAJA/tpl/camp/cmake/camp.pc.in create mode 100644 tpl/RAJA/tpl/camp/cmake/campConfig.cmake.in create mode 100644 tpl/RAJA/tpl/camp/docs/conf.py create mode 100644 tpl/RAJA/tpl/camp/docs/index.rst create mode 100644 tpl/RAJA/tpl/camp/docs/requirements.txt create mode 100644 tpl/RAJA/tpl/camp/include/camp/camp.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/concepts.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/defines.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/detail/sfinae.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/detail/test.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/helpers.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/lambda.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/list.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/list/at.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/list/find_if.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/list/list.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/make_unique.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/map.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/number.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/number/if.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/number/number.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/resource.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/resource/cuda.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/resource/event.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/resource/hip.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/resource/host.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/resource/omp_target.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/resource/platform.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/size.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/tuple.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/type_traits.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/type_traits/is_same.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/value.hpp create mode 100644 tpl/RAJA/tpl/camp/include/camp/value/eval.hpp create mode 100755 tpl/RAJA/tpl/camp/scripts/travis_build_and_test.sh create mode 100644 tpl/RAJA/tpl/camp/test/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/camp/test/accumulate.cpp create mode 100644 tpl/RAJA/tpl/camp/test/at_key.cpp create mode 100644 tpl/RAJA/tpl/camp/test/filter.cpp create mode 100644 tpl/RAJA/tpl/camp/test/find_if.cpp create mode 100644 tpl/RAJA/tpl/camp/test/flatten.cpp create mode 100644 tpl/RAJA/tpl/camp/test/index_of.cpp create mode 100644 tpl/RAJA/tpl/camp/test/lambda.cpp create mode 100644 tpl/RAJA/tpl/camp/test/number.cpp create mode 100644 tpl/RAJA/tpl/camp/test/resource.cpp create mode 100644 tpl/RAJA/tpl/camp/test/size.cpp create mode 100644 tpl/RAJA/tpl/camp/test/transform.cpp create mode 100644 tpl/RAJA/tpl/camp/test/tuple.cpp create mode 100644 tpl/RAJA/tpl/camp/test/tuple_out_of_range.cpp create mode 100644 tpl/RAJA/tpl/cub/.cproject create mode 100644 tpl/RAJA/tpl/cub/.project create mode 100644 tpl/RAJA/tpl/cub/.settings/.gitignore create mode 100644 tpl/RAJA/tpl/cub/.settings/org.eclipse.cdt.codan.core.prefs create mode 100644 tpl/RAJA/tpl/cub/.settings/org.eclipse.cdt.core.prefs create mode 100644 tpl/RAJA/tpl/cub/.settings/org.eclipse.cdt.ui.prefs create mode 100644 tpl/RAJA/tpl/cub/.settings/org.eclipse.core.runtime.prefs create mode 100644 tpl/RAJA/tpl/cub/CHANGE_LOG.TXT create mode 100644 tpl/RAJA/tpl/cub/LICENSE.TXT create mode 100644 tpl/RAJA/tpl/cub/README.md create mode 100644 tpl/RAJA/tpl/cub/common.mk create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_histogram.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_radix_sort_downsweep.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_radix_sort_upsweep.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_reduce.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_reduce_by_key.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_rle.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_scan.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_segment_fixup.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_select_if.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/agent_spmv_orig.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/agent/single_pass_scan_operators.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_adjacent_difference.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_discontinuity.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_exchange.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_histogram.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_load.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_radix_rank.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_radix_sort.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_raking_layout.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_reduce.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_scan.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_shuffle.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/block_store.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_histogram_atomic.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_histogram_sort.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_reduce_raking.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_reduce_raking_commutative_only.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_reduce_warp_reductions.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_scan_raking.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_scan_warp_scans.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_scan_warp_scans2.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/block/specializations/block_scan_warp_scans3.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/cub.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_histogram.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_partition.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_radix_sort.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_reduce.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_run_length_encode.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_scan.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_segmented_radix_sort.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_segmented_reduce.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_select.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/device_spmv.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_histogram.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_radix_sort.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_reduce.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_reduce_by_key.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_rle.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_scan.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_select_if.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/device/dispatch/dispatch_spmv_orig.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/grid/grid_barrier.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/grid/grid_even_share.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/grid/grid_mapping.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/grid/grid_queue.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/host/mutex.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/arg_index_input_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/cache_modified_input_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/cache_modified_output_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/constant_input_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/counting_input_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/discard_output_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/tex_obj_input_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/tex_ref_input_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/iterator/transform_input_iterator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/thread/thread_load.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/thread/thread_operators.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/thread/thread_reduce.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/thread/thread_scan.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/thread/thread_search.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/thread/thread_store.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_allocator.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_arch.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_debug.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_device.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_macro.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_namespace.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_ptx.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/util_type.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/warp/specializations/warp_reduce_shfl.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/warp/specializations/warp_reduce_smem.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/warp/specializations/warp_scan_shfl.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/warp/specializations/warp_scan_smem.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/warp/warp_reduce.cuh create mode 100644 tpl/RAJA/tpl/cub/cub/warp/warp_scan.cuh create mode 100644 tpl/RAJA/tpl/cub/eclipse code style profile.xml create mode 100644 tpl/RAJA/tpl/cub/examples/block/.gitignore create mode 100644 tpl/RAJA/tpl/cub/examples/block/Makefile create mode 100644 tpl/RAJA/tpl/cub/examples/block/example_block_radix_sort.cu create mode 100644 tpl/RAJA/tpl/cub/examples/block/example_block_reduce.cu create mode 100644 tpl/RAJA/tpl/cub/examples/block/example_block_scan.cu create mode 100644 tpl/RAJA/tpl/cub/examples/block/reduce_by_key.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/.gitignore create mode 100644 tpl/RAJA/tpl/cub/examples/device/Makefile create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_partition_flagged.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_partition_if.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_radix_sort.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_reduce.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_scan.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_select_flagged.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_select_if.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_select_unique.cu create mode 100644 tpl/RAJA/tpl/cub/examples/device/example_device_sort_find_non_trivial_runs.cu create mode 100644 tpl/RAJA/tpl/cub/experimental/.gitignore create mode 100644 tpl/RAJA/tpl/cub/experimental/Makefile create mode 100644 tpl/RAJA/tpl/cub/experimental/defunct/example_coo_spmv.cu create mode 100644 tpl/RAJA/tpl/cub/experimental/defunct/test_device_seg_reduce.cu create mode 100644 tpl/RAJA/tpl/cub/experimental/histogram/histogram_cub.h create mode 100644 tpl/RAJA/tpl/cub/experimental/histogram/histogram_gmem_atomics.h create mode 100644 tpl/RAJA/tpl/cub/experimental/histogram/histogram_smem_atomics.h create mode 100644 tpl/RAJA/tpl/cub/experimental/histogram_compare.cu create mode 100644 tpl/RAJA/tpl/cub/experimental/sparse_matrix.h create mode 100644 tpl/RAJA/tpl/cub/experimental/spmv_compare.cu create mode 100755 tpl/RAJA/tpl/cub/experimental/spmv_script.sh create mode 100644 tpl/RAJA/tpl/cub/test/.gitignore create mode 100644 tpl/RAJA/tpl/cub/test/Makefile create mode 100644 tpl/RAJA/tpl/cub/test/half.h create mode 100644 tpl/RAJA/tpl/cub/test/link_a.cu create mode 100644 tpl/RAJA/tpl/cub/test/link_b.cu create mode 100644 tpl/RAJA/tpl/cub/test/link_main.cpp create mode 100644 tpl/RAJA/tpl/cub/test/mersenne.h create mode 100644 tpl/RAJA/tpl/cub/test/test_allocator.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_block_histogram.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_block_load_store.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_block_radix_sort.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_block_reduce.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_block_scan.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_histogram.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_radix_sort.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_reduce.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_reduce_by_key.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_run_length_encode.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_scan.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_select_if.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_device_select_unique.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_grid_barrier.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_iterator.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_util.h create mode 100644 tpl/RAJA/tpl/cub/test/test_warp_reduce.cu create mode 100644 tpl/RAJA/tpl/cub/test/test_warp_scan.cu create mode 100644 tpl/RAJA/tpl/cub/tune/.gitignore create mode 100644 tpl/RAJA/tpl/cub/tune/Makefile create mode 100644 tpl/RAJA/tpl/cub/tune/tune_device_reduce.cu create mode 100644 tpl/RAJA/tpl/rocPRIM/.clang-format create mode 100755 tpl/RAJA/tpl/rocPRIM/.githooks/install create mode 100755 tpl/RAJA/tpl/rocPRIM/.githooks/pre-commit create mode 100644 tpl/RAJA/tpl/rocPRIM/.gitignore create mode 100644 tpl/RAJA/tpl/rocPRIM/.gitlab-ci.yml create mode 100644 tpl/RAJA/tpl/rocPRIM/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/Jenkinsfile create mode 100644 tpl/RAJA/tpl/rocPRIM/LICENSE.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/NOTICES.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/README.md create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_block_discontinuity.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_block_exchange.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_block_histogram.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_block_radix_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_block_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_block_scan.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_block_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_binary_search.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_histogram.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_memory.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_merge.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_merge_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_partition.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_radix_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_reduce_by_key.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_run_length_encode.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_scan.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_segmented_radix_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_segmented_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_select.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_device_transform.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_utils.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_warp_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_warp_scan.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/benchmark_warp_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/benchmark/cmdparser.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/cmake/Dependencies.cmake create mode 100644 tpl/RAJA/tpl/rocPRIM/cmake/DownloadProject.CMakeLists.cmake.in create mode 100644 tpl/RAJA/tpl/rocPRIM/cmake/DownloadProject.cmake create mode 100644 tpl/RAJA/tpl/rocPRIM/cmake/Summary.cmake create mode 100644 tpl/RAJA/tpl/rocPRIM/cmake/VerifyCompiler.cmake create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/Doxyfile create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/blockmodule.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/devicemodule.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/glossary.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/intrinsicsmodule.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/iteratormodule.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/mainpage.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/primitivesmodule.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/utilsmodule.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/doc/warpmodule.dox create mode 100644 tpl/RAJA/tpl/rocPRIM/docker/dockerfile-build-centos create mode 100644 tpl/RAJA/tpl/rocPRIM/docker/dockerfile-build-sles create mode 100644 tpl/RAJA/tpl/rocPRIM/docker/dockerfile-build-ubuntu-rock create mode 100644 tpl/RAJA/tpl/rocPRIM/docker/dockerfile-install-centos create mode 100644 tpl/RAJA/tpl/rocPRIM/docker/dockerfile-install-sles create mode 100755 tpl/RAJA/tpl/rocPRIM/docker/dockerfile-install-ubuntu create mode 100644 tpl/RAJA/tpl/rocPRIM/example/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/example/example_temporary_storage.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/example/example_utils.hpp create mode 100755 tpl/RAJA/tpl/rocPRIM/install create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_discontinuity.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_exchange.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_histogram.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_load.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_load_func.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_radix_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_store.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/block_store_func.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/detail/block_histogram_atomic.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/detail/block_histogram_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/detail/block_reduce_raking_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/detail/block_reduce_warp_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/detail/block_scan_reduce_then_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/detail/block_scan_warp_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/block/detail/block_sort_bitonic.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/detail/all_true.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/detail/binary_op_wrappers.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/detail/match_result_type.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/detail/radix_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/detail/various.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/config_types.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_binary_search.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_histogram.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_merge.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_merge_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_partition.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_radix_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_reduce_by_key.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_scan_lookback.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_scan_reduce_then_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_segmented_radix_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_segmented_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_segmented_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/device_transform.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/lookback_scan_state.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/ordered_block_id.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/detail/uint_fast_div.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_binary_search.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_histogram.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_histogram_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_merge.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_merge_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_merge_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_merge_sort_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_partition.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_radix_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_radix_sort_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_reduce_by_key.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_reduce_by_key_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_reduce_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_run_length_encode.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_run_length_encode_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_scan_by_key.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_scan_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_segmented_radix_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_segmented_radix_sort_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_segmented_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_segmented_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_select.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_select_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_transform.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/device/device_transform_config.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/functional.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/intrinsics.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/intrinsics/atomic.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/intrinsics/bit.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/intrinsics/thread.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/intrinsics/warp.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/intrinsics/warp_shuffle.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/arg_index_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/constant_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/counting_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/detail/replace_first_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/discard_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/texture_cache_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/transform_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/iterator/zip_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/rocprim.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/rocprim_version.hpp.in create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/type_traits.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/types.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/types/double_buffer.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/types/integer_sequence.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/types/key_value_pair.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/types/tuple.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_reduce_crosslane.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_reduce_dpp.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_reduce_shared_mem.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_reduce_shuffle.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_scan_crosslane.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_scan_dpp.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_scan_shared_mem.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_scan_shuffle.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_segment_bounds.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/detail/warp_sort_shuffle.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/warp_reduce.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/warp_scan.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/rocprim/include/rocprim/warp/warp_sort.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/test/extra/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/test/extra/test_rocprim_package.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/CMakeLists.txt create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/bounds_checking_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/detail/get_rocprim_version.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/detail/get_rocprim_version.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/identity_iterator.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_arg_index_iterator.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_basic.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_discontinuity.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_exchange.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_histogram.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_load_store.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_radix_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_scan.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_block_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_constant_iterator.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_counting_iterator.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_binary_search.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_histogram.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_merge.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_merge_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_partition.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_radix_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_reduce_by_key.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_run_length_encode.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_scan.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_segmented_radix_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_segmented_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_segmented_scan.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_select.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_device_transform.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_discard_iterator.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_intrinsics.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_texture_cache_iterator.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_transform_iterator.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_utils.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_utils_types.hpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_warp_reduce.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_warp_scan.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_warp_sort.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/rocprim/test_zip_iterator.cpp create mode 100644 tpl/RAJA/tpl/rocPRIM/test/test_hip_api.cpp create mode 100644 tpl/RAJA/travis-data/docker/bionic-base/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/bionic-base/generic-setup-18.04.sh create mode 100755 tpl/RAJA/travis-data/docker/build-all.sh create mode 100644 tpl/RAJA/travis-data/docker/clang4/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/clang5/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/clang6/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/clang9/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/gcc49/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/gcc5/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/gcc6/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/gcc7/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/gcc8/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/generic-setup.sh create mode 100644 tpl/RAJA/travis-data/docker/hip/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/hip/generic-setup.sh create mode 100644 tpl/RAJA/travis-data/docker/icc16/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/icc16/generic-setup.sh create mode 100644 tpl/RAJA/travis-data/docker/icc18/Dockerfile create mode 100644 tpl/RAJA/travis-data/docker/nvcc10/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/nvcc10/generic-setup-18.04.sh create mode 100644 tpl/RAJA/travis-data/docker/nvcc8/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/nvcc8/generic-setup.sh create mode 100644 tpl/RAJA/travis-data/docker/nvcc9/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/nvcc9/generic-setup.sh create mode 100644 tpl/RAJA/travis-data/docker/ubuntu-clang-base/Dockerfile create mode 100755 tpl/RAJA/travis-data/docker/ubuntu-clang-base/generic-setup.sh create mode 100644 tpl/RAJA/travis-data/intel2016.lic.enc diff --git a/tpl/RAJA b/tpl/RAJA deleted file mode 160000 index 7b7aaf651..000000000 --- a/tpl/RAJA +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7b7aaf651c57eb2981747edd2465a1c812321c1f diff --git a/tpl/RAJA/.clang-format b/tpl/RAJA/.clang-format new file mode 100644 index 000000000..1d2ad9a77 --- /dev/null +++ b/tpl/RAJA/.clang-format @@ -0,0 +1,27 @@ +BasedOnStyle : google +IndentWidth : 2 +BreakBeforeBraces : Linux +KeepEmptyLinesAtTheStartOfBlocks : true +MaxEmptyLinesToKeep : 2 +AccessModifierOffset : -2 +UseTab: Never +AllowShortIfStatementsOnASingleLine : true +ConstructorInitializerAllOnOneLineOrOnePerLine : true +AllowShortFunctionsOnASingleLine : true +AllowShortLoopsOnASingleLine : false +BinPackParameters : false +AllowAllParametersOfDeclarationOnNextLine : false +AlignTrailingComments : true +ColumnLimit : 80 +PenaltyBreakBeforeFirstCallParameter : 100 +PenaltyReturnTypeOnItsOwnLine : 65000 +PenaltyBreakString : 10 + +# These improve formatting results but require clang 3.6/7 or higher +BreakBeforeBinaryOperators : None +AlignAfterOpenBracket: true +BinPackArguments : false +AlignOperands : true +AlwaysBreakTemplateDeclarations : true +Cpp11BracedListStyle : true + diff --git a/tpl/RAJA/.github/PULL_REQUEST_TEMPLATE.md b/tpl/RAJA/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..81274ee3f --- /dev/null +++ b/tpl/RAJA/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,21 @@ +# Summary + +- This PR is a (refactoring, bugfix, feature, something else) +- It does the following (modify list as needed): + - Modifies/refactors (class or method) (how?) + - Fixes (issue number(s)) + - Adds (specific feature) at the request of (project or person) + +# Design review (for API changes or additions---delete if unneeded) + +On (date), we reviewed this PR. We discussed the design ideas: + +1. First idea or goal +2. Second idea +3. Third idea + +This PR implements 1. and 3. It leaves out 2. for the following reasons + +- (impractical) +- (too big) +- (not a good idea anyway) diff --git a/tpl/RAJA/.gitignore b/tpl/RAJA/.gitignore new file mode 100644 index 000000000..1c0750848 --- /dev/null +++ b/tpl/RAJA/.gitignore @@ -0,0 +1,8 @@ +*.pyc +*.o +*.a +*.exe +*.gch +build/ +build-*/ +/Debug/ diff --git a/tpl/RAJA/.gitmodules b/tpl/RAJA/.gitmodules new file mode 100644 index 000000000..8038924f7 --- /dev/null +++ b/tpl/RAJA/.gitmodules @@ -0,0 +1,12 @@ +[submodule "blt"] + path = blt + url = https://github.com/LLNL/blt.git +[submodule "include/cub"] + path = tpl/cub + url = https://github.com/NVlabs/cub.git +[submodule "include/camp"] + path = tpl/camp + url = https://github.com/llnl/camp +[submodule "tpl/rocPRIM"] + path = tpl/rocPRIM + url = https://github.com/ROCmSoftwarePlatform/rocPRIM.git diff --git a/tpl/RAJA/.travis.yml b/tpl/RAJA/.travis.yml new file mode 100644 index 000000000..dba6d536d --- /dev/null +++ b/tpl/RAJA/.travis.yml @@ -0,0 +1,110 @@ +sudo: required +services: docker +dist: trusty +language: cpp +env: + global: + - secure: xN+lGOH8LzepE1OoOrHelDgu1wf7nL/B7nBWhN7EnCB7S7hZJL/AakruHy4lMfQfF4XkrnPWmBlmc4wdLH+o6jPkUISm4nLRSTMnRV2L+Mjyzg3aIEua0xpO6rLUNgsShB8mfkieTJq+kSj3Yp2CM7GEzm+UNNxeJcY0VdUHy9msRRRbXiLViIrfwBEVC9He7xG9NWfqkpsORfoiPmVDm7YzuXALdB8qkX4AWggysz/BCVj0PwBMr754eEpOodQ9GeKDF2Kwy5vPAqK5f7zwshJtF9VevyA1A2M9y8BHJMymz4wGaSxLNMeUU85AmVIvmzX0weG94JQ7mlUVszNpO5CCIyjwCOF+IDUI8HCDJGOY7+gGnv4H2LhDwAXvFLD65FlMntQQe2e4KRTnFxtJvvghjv5FyxJSHwctLsgeDpr2uZDcAhK1yf8TNsqqMiXQj2yGLByJy8j5PjUyd8oN47uZo0T5DDMd5c3ztUppc5+DisIoqmoYQeom3lYbpeudaf492ZDBWEV4rS9COl1h7CnpanMBpXWLFc2zXyfTpRn3GifutiF8M3rSS2KHcPyb9JLePTrC4+itMkwB4SHo1VYk4H2RQAdPMDFHMKCeVs2Z4sF9pGPJR+JzRekaKFLDm73ihsuE0cnx1oPVQMjSWa0e7A1a9W4UQBvp9xR++i4= + - OMP_NUM_THREADS=3 + - DO_BUILD=yes + - DO_TEST=yes +matrix: + include: + - compiler: gcc49 + env: + - COMPILER=g++ + - IMG=gcc49 + - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On -DENABLE_TBB=On -DRAJA_DEPRECATED_TESTS=On" + - compiler: gcc6 + env: + - COMPILER=g++ + - IMG=gcc6 + - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On -DENABLE_TBB=On" + - compiler: gcc7 + env: + - COMPILER=g++ + - IMG=gcc7 + - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On -DENABLE_TBB=On" + - compiler: gcc8 + env: + - COMPILER=g++ + - IMG=gcc8 + - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On -DENABLE_TBB=On" + - compiler: clang9 + env: + - COMPILER=clang++-9 + - IMG=clang9 + - CMAKE_EXTRA_FLAGS="-DCMAKE_CXX_FLAGS=-fmodules -DENABLE_TBB=On" + - compiler: clang5 + env: + - COMPILER=clang++ + - IMG=clang5 + - CMAKE_EXTRA_FLAGS="-DCMAKE_CXX_FLAGS=-fmodules -DENABLE_TBB=On" + - compiler: intel18 + env: + - COMPILER=/opt/intel/bin/icpc + - IMG=icc18 + - CMAKE_EXTRA_FLAGS="-DENABLE_TBB=On" + - compiler: nvcc9 + env: + - COMPILER=g++ + - IMG=nvcc9 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=On -DENABLE_TBB=On" + - DO_TEST=no + - compiler: nvcc10.2 + env: + - COMPILER=g++ + - IMG=nvcc10.2 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=On -DENABLE_TBB=On" + - DO_TEST=no + - compiler: gcc-4.9-debug + env: + - COMPILER=g++ + - IMG=gcc49 + - CMAKE_EXTRA_FLAGS="-DCMAKE_BUILD_TYPE=Debug -DENABLE_WARNINGS=On -DENABLE_WARNINGS_AS_ERRORS=On -DENABLE_COVERAGE=On -DENABLE_TBB=On" + - compiler: clang-9-debug + env: + - COMPILER=clang++-9 + - IMG=clang9 + - CMAKE_EXTRA_FLAGS="-DCMAKE_BUILD_TYPE=Debug -DENABLE_TBB=On -DCMAKE_CXX_FLAGS=-fsanitize=address" + - ASAN_OPTIONS=detect_leaks=0 + - "LSAN_OPTIONS=verbosity=1:log_threads=1" + - compiler: nvcc-debug + env: + - COMPILER=g++ + - IMG=nvcc10.2 + - CMAKE_EXTRA_FLAGS="-DCMAKE_BUILD_TYPE=Debug -DENABLE_CUDA=On -DENABLE_WARNINGS=On -DENABLE_WARNINGS_AS_ERRORS=On -DENABLE_TBB=On" + - DO_TEST=no + - compiler: clang9-cuda9.1 + env: + - COMPILER=clang++-9 + - IMG=clang9 + - CMAKE_EXTRA_FLAGS="-DCMAKE_BUILD_TYPE=Release -DENABLE_OPENMP=Off -DENABLE_CLANG_CUDA=On -DBLT_CLANG_CUDA_ARCH=sm_60 -DENABLE_CUDA=On -DCUDA_ARCH=sm_60 -DCUDA_TOOLKIT_ROOT_DIR:PATH='/usr/lib/cuda'" + - DO_TEST=no + - compiler: hip + env: + - COMPILER=g++ + - IMG=hip + - HCC_AMDGPU_TARGET=gfx900 + - CMAKE_EXTRA_FLAGS="-DENABLE_HIP=On -DENABLE_OPENMP=Off -DENABLE_CUDA=Off -DENABLE_WARNINGS_AS_ERRORS=Off" + - DO_TEST=no + + +before_install: # don't try to build and run intel when it's impossible +- | + if [[ "x$encrypted_cd1f6303bca7_key" != "x" ]] ; then + openssl aes-256-cbc -K $encrypted_cd1f6303bca7_key -iv $encrypted_cd1f6303bca7_iv -in ${TRAVIS_BUILD_DIR}/travis-data/intel2016.lic.enc -out ${TRAVIS_BUILD_DIR}/travis-data/intel2016.lic -d + else + if [[ $COMPILER == *"icpc"* ]] ; then + export DO_TEST=no DO_BUILD=no + fi + fi +- export LSAN_OPTIONS +- export ASAN_OPTIONS + +script: +- docker run --rm --user='root' -v ${TRAVIS_BUILD_DIR}:/home/raja rajaorg/compiler:$IMG chown -R raja /home/raja +- docker run --rm -v ${TRAVIS_BUILD_DIR}/travis-data:/opt/intel/licenses -v ${TRAVIS_BUILD_DIR}:/home/raja -e ASAN_OPTIONS -e LSAN_OPTIONS -e COMPILER -e DO_BUILD -e DO_TEST -e CMAKE_EXTRA_FLAGS -e HCC_AMDGPU_TARGET rajaorg/compiler:$IMG ./scripts/travis_build_and_test.sh + +after_success: +- if [[ "${CMAKE_EXTRA_FLAGS}" == *"ENABLE_COVERAGE"* ]] ; then bash <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/0b376529f626b50b7d4a9fb734e0e50d28b9b91e/codecov) -a "-f" >& /dev/null; fi diff --git a/tpl/RAJA/CMakeLists.txt b/tpl/RAJA/CMakeLists.txt new file mode 100644 index 000000000..70c657e6d --- /dev/null +++ b/tpl/RAJA/CMakeLists.txt @@ -0,0 +1,309 @@ +############################################################################### +# Copyright (c) 2016-20, Lawrence Livermore National Security, LLC +# and RAJA project contributors. See the RAJA/COPYRIGHT file for details. +# +# SPDX-License-Identifier: (BSD-3-Clause) +############################################################################### + +cmake_policy(SET CMP0042 NEW) +cmake_policy(SET CMP0048 NEW) + +if (APPLE) + cmake_policy(SET CMP0025 NEW) +endif() + +# Set version number +set(RAJA_VERSION_MAJOR 0) +set(RAJA_VERSION_MINOR 11) +set(RAJA_VERSION_PATCHLEVEL 0) + +if (RAJA_LOADED AND (NOT RAJA_LOADED STREQUAL "${RAJA_VERSION_MAJOR}.${RAJA_VERSION_MINOR}.${RAJA_VERSION_PATCHLEVEL}")) + message(FATAL_ERROR "You are mixing RAJA versions. Loaded is ${RAJA_LOADED}, expected ${RAJA_VERSION_MAJOR}.${RAJA_VERSION_MINOR}.${RAJA_VERSION_PATCHLEVEL}") +endif() + +if (RAJA_LOADED) + return() # Stop processing file, avoids nesting the whole file +endif() +set (RAJA_LOADED "${RAJA_VERSION_MAJOR}.${RAJA_VERSION_MINOR}.${RAJA_VERSION_PATCHLEVEL}") + +# Promote RAJA_LOADED to PARENT_SCOPE if it exists, which is only if we are bringing +# in RAJA as a subproject to a larger CMake project +get_directory_property(hasParent PARENT_DIRECTORY) +if(hasParent) + set (RAJA_LOADED ${RAJA_LOADED} PARENT_SCOPE) +endif() + +mark_as_advanced(RAJA_LOADED) + +# C is required for googletest to find Threads +project(RAJA LANGUAGES CXX C + VERSION ${RAJA_LOADED}) + +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/thirdparty" ${CMAKE_MODULE_PATH}) + +# Build options +set(ENABLE_OPENMP On CACHE BOOL "Build OpenMP support") +set(ENABLE_CUDA Off CACHE BOOL "Build CUDA support") +set(ENABLE_COPY_HEADERS Off CACHE BOOL "") +set(ENABLE_WARNINGS_AS_ERRORS Off CACHE BOOL "") +set(ENABLE_GTEST_DEATH_TESTS On CACHE BOOL "Enable tests asserting failure.") + +set(RAJA_CXX_STANDARD_FLAG "default" CACHE STRING "Specific c++ standard flag to use, default attempts to autodetect the highest available") + +option(ENABLE_TBB "Build TBB support" Off) +option(ENABLE_CHAI "Build CHAI support" Off) +option(ENABLE_TARGET_OPENMP "Build OpenMP on target device support" Off) +option(ENABLE_CLANG_CUDA "Use Clang's native CUDA support" Off) +option(ENABLE_EXTERNAL_CUB "Use an external cub for scans" Off) +option(ENABLE_EXTERNAL_ROCPRIM "Use an external rocPRIM for scans" Off) +option(ENABLE_TESTS "Build tests" On) +option(ENABLE_REPRODUCERS "Build issue reproducers" Off) +option(ENABLE_EXAMPLES "Build simple examples" On) +option(ENABLE_EXERCISES "Build exercises " On) +option(ENABLE_MODULES "Enable modules in supporting compilers (clang)" On) +option(ENABLE_WARNINGS "Enable warnings as errors for CI" Off) +option(ENABLE_DOCUMENTATION "Build RAJA documentation" Off) +option(ENABLE_COVERAGE "Enable coverage (only supported with GCC)" Off) +option(ENABLE_FORCEINLINE_RECURSIVE "Enable Forceinline recursive (only supported with Intel compilers)" On) +option(ENABLE_BENCHMARKS "Build benchmarks" Off) +option(RAJA_DEPRECATED_TESTS "Test deprecated features" Off) +option(RAJA_ENABLE_BOUNDS_CHECK "Enable bounds checking in RAJA::Views/Layouts" Off) + +set(TEST_DRIVER "" CACHE STRING "driver used to wrap test commands") + +cmake_minimum_required(VERSION 3.9) + +if (ENABLE_CUDA) + if (DEFINED CUDA_ARCH) + if (CUDA_ARCH MATCHES "^sm_*") + if ("${CUDA_ARCH}" STRLESS "sm_35") + message( FATAL_ERROR "RAJA requires minimum CUDA compute architecture of sm_35") + endif() + endif() + if (CUDA_ARCH MATCHES "^compute_*") + if ("${CUDA_ARCH}" STRLESS "compute_35") + message( FATAL_ERROR "RAJA requires minimum CUDA compute architecture of compute_35") + endif() + endif() + else() + message(STATUS "CUDA compute architecture set to RAJA default sm_35 since it was not specified") + set(CUDA_ARCH "sm_35" CACHE STRING "Set CUDA_ARCH to RAJA minimum supported" FORCE) + endif() + if (CMAKE_CXX_COMPILER_ID MATCHES GNU) + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0) + set (CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler -mno-float128") + endif () + endif () +endif() + +# Detect C++ standard and add appropriate flag _before_ loading BLT +set(COMPILERS_KNOWN_TO_CMAKE33 AppleClang Clang GNU MSVC) + +include(CheckCXXCompilerFlag) +if(RAJA_CXX_STANDARD_FLAG MATCHES default) + if("cxx_std_17" IN_LIST CMAKE_CXX_KNOWN_FEATURES) + #TODO set BLT_CXX_STANDARD + set(CMAKE_CXX_STANDARD 17) + elseif("cxx_std_14" IN_LIST CMAKE_CXX_KNOWN_FEATURES) + set(CMAKE_CXX_STANDARD 14) + elseif("${CMAKE_CXX_COMPILER_ID}" IN_LIST COMPILERS_KNOWN_TO_CMAKE33) + set(CMAKE_CXX_STANDARD 14) + else() #cmake has no idea what to do, do it ourselves... + foreach(flag_var "-std=c++17" "-std=c++1z" "-std=c++14" "-std=c++1y" "-std=c++11") + CHECK_CXX_COMPILER_FLAG(${flag_var} COMPILER_SUPPORTS_${flag_var}) + if(COMPILER_SUPPORTS_${flag_var}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag_var}") + break() + endif() + endforeach(flag_var) + endif() +else(RAJA_CXX_STANDARD_FLAG MATCHES default) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RAJA_CXX_STANDARD_FLAG}") + message("Using C++ standard flag: ${RAJA_CXX_STANDARD_FLAG}") +endif(RAJA_CXX_STANDARD_FLAG MATCHES default) + +set(CMAKE_CXX_EXTENSIONS OFF) + +if (NOT BLT_LOADED) + if (DEFINED BLT_SOURCE_DIR) + if (NOT EXISTS ${BLT_SOURCE_DIR}/SetupBLT.cmake) + message(FATAL_ERROR "Given BLT_SOURCE_DIR does not contain SetupBLT.cmake") + endif() + else () + set (BLT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/blt CACHE PATH "") + + if (NOT EXISTS ${BLT_SOURCE_DIR}/SetupBLT.cmake) + message(FATAL_ERROR "\ + The BLT submodule is not present. \ + If in git repository run the following two commands:\n \ + git submodule init\n \ + git submodule update") + endif () + endif () + + include(${BLT_SOURCE_DIR}/SetupBLT.cmake) +endif() + +# Setup basic CMake options +include(cmake/SetupBasics.cmake) +# Find third-party packages +include(cmake/SetupPackages.cmake) +# Setup vendor-specific compiler flags +include(cmake/SetupCompilers.cmake) +# Setup internal RAJA configuration options +include(cmake/SetupRajaConfig.cmake) +# Macros for building executables and libraries +include (cmake/RAJAMacros.cmake) + +set (raja_sources + src/AlignedRangeIndexSetBuilders.cpp + src/DepGraphNode.cpp + src/LockFreeIndexSetBuilders.cpp + src/MemUtils_CUDA.cpp + src/MemUtils_HIP.cpp + src/PluginStrategy.cpp) + +set (raja_depends) + +if (ENABLE_OPENMP) + set (raja_depends + openmp) +endif() + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17) + message(WARNING "RAJA::simd_exec support requires Intel-17 or greater") +endif() + +if (ENABLE_CUDA) + set (raja_depends + ${raja_depends} + cuda) +endif () + +if (ENABLE_CUDA) + if(ENABLE_EXTERNAL_CUB) + find_package(CUB) + if (CUB_FOUND) + blt_register_library( + NAME cub + INCLUDES ${CUB_INCLUDE_DIRS}) + set(raja_depends + ${raja_depends} + cub) + else() + message(WARNING "External CUB not found.") + set(ENABLE_EXTERNAL_CUB Off) + endif() + endif () +endif () + +if (ENABLE_HIP) + set (raja_depends + ${raja_depends} + hip) +endif () + +if (ENABLE_HIP) + if(ENABLE_EXTERNAL_ROCPRIM) + find_package(ROCPRIM) + if (ROCPRIM_FOUND) + blt_register_library( + NAME rocPRIM + INCLUDES ${ROCPRIM_INCLUDE_DIRS}) + set(raja_depends + ${raja_depends} + rocPRIM) + else() + message(WARNING "External rocPRIM not found.") + set(ENABLE_EXTERNAL_ROCPRIM Off) + endif() + endif () +endif () + +if (ENABLE_CHAI) + set (raja_depends + ${raja_depends} + chai) +endif () + +if (ENABLE_TBB) + set(raja_depends + ${raja_depends} + tbb) +endif () + +set(EXTERNAL_CAMP_SOURCE_DIR "" CACHE FILEPATH "build with a specific external +camp source repository") +if (EXTERNAL_CAMP_SOURCE_DIR) + message(STATUS "Using external source CAMP from: " ${EXTERNAL_CAMP_SOURCE_DIR}) + add_subdirectory(${EXTERNAL_CAMP_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/tpl/camp) +else (EXTERNAL_CAMP_SOURCE_DIR) + find_package(camp QUIET) + if (NOT camp_FOUND) + message(STATUS "Using RAJA CAMP submodule.") + add_subdirectory(tpl/camp) + else (NOT camp_FOUND) + message(STATUS "Using installed CAMP from: ${camp_INSTALL_PREFIX}") + endif(NOT camp_FOUND) +endif (EXTERNAL_CAMP_SOURCE_DIR) + +blt_add_library( + NAME RAJA + SOURCES ${raja_sources} + DEPENDS_ON ${raja_depends} camp) + +install(TARGETS RAJA + EXPORT RAJA + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION lib + ) + +install(EXPORT RAJA DESTINATION share/raja/cmake/) + +target_include_directories(RAJA + PUBLIC + $ + $ + $ + $ + $) + +install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN *.hpp) +if(NOT ENABLE_EXTERNAL_CUB) + install(DIRECTORY tpl/cub/ DESTINATION include FILES_MATCHING PATTERN *.cuh) +endif() +if(NOT ENABLE_EXTERNAL_ROCPRIM) + install(DIRECTORY tpl/rocPRIM/rocprim/include/ DESTINATION include FILES_MATCHING PATTERN *.hpp) +endif() + +install(FILES + ${PROJECT_BINARY_DIR}/include/RAJA/config.hpp + include/RAJA/module.modulemap + include/RAJA/module.private.modulemap + DESTINATION "include/RAJA/") + +if(ENABLE_TESTS) + add_subdirectory(test) +endif() + +if(ENABLE_REPRODUCERS) + add_subdirectory(reproducers) +endif() + +if(ENABLE_EXAMPLES) + add_subdirectory(examples) +endif() + +if(ENABLE_EXERCISES) + add_subdirectory(exercises) +endif() + +if (ENABLE_DOCUMENTATION) + add_subdirectory(docs) +endif () + +if (ENABLE_BENCHMARKS) + add_subdirectory(benchmark) +endif () diff --git a/tpl/RAJA/CODE_OF_CONDUCT.md b/tpl/RAJA/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..52ffc4ef4 --- /dev/null +++ b/tpl/RAJA/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at raja-dev@llnl.gov. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/tpl/RAJA/CONTRIBUTING.md b/tpl/RAJA/CONTRIBUTING.md new file mode 100644 index 000000000..c072b7efc --- /dev/null +++ b/tpl/RAJA/CONTRIBUTING.md @@ -0,0 +1,91 @@ + +[comment]: # (#################################################################) +[comment]: # (Copyright 2016-19, Lawrence Livermore National Security, LLC) +[comment]: # (and RAJA project contributors. See the RAJA/COPYRIGHT file) +[comment]: # (for details.) +[comment]: # +[comment]: # (# SPDX-License-Identifier: BSD-3-Clause) +[comment]: # (#################################################################) + +# Contributing to RAJA + +This document is intended for developers who want to add new features or +bug fixes to RAJA. It assumes you have some familiarity with git and Github. It +will discuss what a good pull request (PR) looks like, and the tests that your +PR must pass before it can be merged into RAJA. + +## Forking RAJA + +If you aren't a RAJA developer at LLNL, then you won't have permission to push +new branches to the repository. First, you should create a +[fork](https://github.com/LLNL/RAJA#fork-destination-box). This will create a +copy of the RAJA repository that you own, and will ensure you can push your +changes up to Github and create pull requests. + +## Developing a New Feature + +New features should be based on the `develop` branch. When you want to create a +new feature, first ensure you have an up-to-date copy of the `develop` branch: + + $ git checkout develop + $ git pull origin develop + +You can now create a new branch to develop your feature on: + + $ git checkout -b feature/ + +Proceed to develop your feature on this branch, and add tests that will exercise +your new code. If you are creating new methods or classes, please add Doxygen +documentation. + +Once your feature is complete and your tests are passing, you can push your +branch to Github and create a PR. + +## Developing a Bug Fix + +First, check if the change you want to make has been fixed in `develop`. If so, +we suggest you either start using the `develop` branch, or temporarily apply the +fix to whichever version of RAJA you are using. + +Assuming there is an unsolved bug, first make sure you have an up-to-date copy +of the develop branch: + + $ git checkout develop + $ git pull origin develop + +Then create a new branch for your bug fix: + + $ git checkout -b bugfix/ + +First, add a test that reproduces the bug you have found. Then develop your +bugfix as normal, and ensure to `make test` to check your changes actually fix +the bug. + +Once you are finished, you can push your branch to Github, then create a PR. + +## Creating a Pull Request + +You can create a new PR [here](https://github.com/LLNL/RAJA/compare). Github +has a good [guide](https://help.github.com/articles/about-pull-requests/) to PR +basics if you want some more information. Ensure that your PR base is the +`develop` branch of RAJA. + +Add a descriptive title explaining the bug you fixed or the feature you have +added, and put a longer description of the changes you have made in the comment +box. + +Once your PR has been created, it will be run through our automated tests and +also be reviewed by RAJA team members. Providing the branch passes both the +tests and reviews, it will be merged into RAJA. + +## Tests + +RAJA uses Travis CI for continuous integration tests. Our tests are +automatically run against every new pull request, and passing all tests is a +requirement for merging your PR. If you are developing a bugfix or a new +feature, please add a test that checks the correctness of your new code. RAJA +is used on a wide variety of systems with a number of configurations, and adding +new tests helps ensure that all features work as expected across these +environments. + +All RAJA tests are in the `test` directory and are split up by backend and feature. diff --git a/tpl/RAJA/Dockerfile b/tpl/RAJA/Dockerfile new file mode 100644 index 000000000..f21c0478e --- /dev/null +++ b/tpl/RAJA/Dockerfile @@ -0,0 +1,23 @@ +############################################################################### +# Copyright (c) 2016-20, Lawrence Livermore National Security, LLC +# and RAJA project contributors. See the RAJA/COPYRIGHT file for details. +# +# SPDX-License-Identifier: (BSD-3-Clause) +############################################################################### + +# +#Builds and installs RAJA using the gcc8 compiler +# + +FROM rajaorg/compiler:gcc8 +MAINTAINER RAJA Development Team + +COPY --chown=raja:raja . /home/raja/workspace + +WORKDIR /home/raja/workspace + +RUN mkdir build && cd build && cmake -DENABLE_CUDA=OFF .. + +RUN cd build && sudo make -j 3 && sudo make install + +CMD ["bash"] diff --git a/tpl/RAJA/LICENSE b/tpl/RAJA/LICENSE new file mode 100644 index 000000000..b40399aa2 --- /dev/null +++ b/tpl/RAJA/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2016-2020, Lawrence Livermore National Security, LLC. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tpl/RAJA/NOTICE b/tpl/RAJA/NOTICE new file mode 100644 index 000000000..d64ac16ab --- /dev/null +++ b/tpl/RAJA/NOTICE @@ -0,0 +1,20 @@ +Additional BSD Notice + +1. This notice is required to be provided under our contract with the U.S. +Department of Energy (DOE). This work was produced at Lawrence Livermore +National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE. + +2. Neither the United States Government nor Lawrence Livermore National +Security, LLC nor any of their employees, makes any warranty, express or +implied, or assumes any liability or responsibility for the accuracy, +completeness, or usefulness of any information, apparatus, product, or process +disclosed, or represents that its use would not infringe privately-owned rights. + +3. Also, reference herein to any specific commercial products, process, or +services by trade name, trademark, manufacturer or otherwise does not +necessarily constitute or imply its endorsement, recommendation, or favoring by +the United States Government or Lawrence Livermore National Security, LLC. The +views and opinions of authors expressed herein do not necessarily state or +reflect those of the United States Government or Lawrence Livermore National +Security, LLC, and shall not be used for advertising or product endorsement +purposes. diff --git a/tpl/RAJA/README.md b/tpl/RAJA/README.md new file mode 100644 index 000000000..6f0ff8f40 --- /dev/null +++ b/tpl/RAJA/README.md @@ -0,0 +1,177 @@ + +[comment]: # (#################################################################) +[comment]: # (Copyright 2016-19, Lawrence Livermore National Security, LLC) +[comment]: # (and RAJA project contributors. See the RAJA/COPYRIGHT file) +[comment]: # (for details.) +[comment]: # +[comment]: # (# SPDX-License-Identifier: BSD-3-Clause) +[comment]: # (#################################################################) + +# RAJA + +[![Build Status](https://travis-ci.org/LLNL/RAJA.svg?branch=develop)](https://travis-ci.org/LLNL/RAJA) +[![Join the chat at https://gitter.im/llnl/raja](https://badges.gitter.im/llnl/raja.svg)](https://gitter.im/llnl/raja?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Coverage](https://img.shields.io/codecov/c/github/LLNL/RAJA/develop.svg)](https://codecov.io/gh/LLNL/RAJA) + +RAJA is a collection of C++ software abstractions, being developed at +Lawrence Livermore National Laboratory (LLNL), that enable architecture +portability for HPC applications. The overarching goals of RAJA are to: + + * Make existing (production) applications *portable with minimal disruption* + * Provide a model for new applications so that they are portable from + inception. + +RAJA uses standard C++11 -- C++ is the predominant programming language in +which many LLNL codes are written. RAJA is rooted in a perspective based on +substantial experience working on production mesh-based multiphysics +applications at LLNL. Another goal of RAJA is to enable application developers +to adapt RAJA concepts and specialize them for different code implementation +patterns and C++ usage, since data structures and algorithms vary widely +across applications. + +RAJA shares goals and concepts found in +other C++ portability abstraction approaches, such as +[Kokkos](https://github.com/kokkos/kokkos) +and [Thrust](https://developer.nvidia.com/thrust). +However, it includes concepts that are absent in other models and which are +fundamental to LLNL codes. + +It is important to note that RAJA is very much a work-in-progress. +The community of researchers and application developers at LLNL that are +actively contributing to it and developing new capabilities is growing. +The publicly-released version contains only core pieces of RAJA as they +exist today. While the basic interfaces are fairly stable, the implementation +of the underlying concepts is being refined. Additional features will appear +in future releases. + +Quick Start +----------- + +The RAJA code lives in a GitHub [repository](https://github.com/llnl/raja). +To clone the repo, use the command: + + git clone --recursive https://github.com/llnl/raja.git + +Then, you can build RAJA like any other CMake project, provided you have a C++ +compiler that supports the C++11 standard. The simplest way to build the code, +using your system default compiler, is to run the following sequence of +commands in the top-level RAJA directory (in-source builds are not allowed!): + + mkdir build + cd build + cmake ../ + make + +More details about RAJA configuration options are located in the User +Documentation. + +We also maintain a [**RAJA Template Project**](https://github.com/LLNL/RAJA-project-template) that shows how to use RAJA in a CMake project, either as a Git +submodule or as an installed library. + +User Documentation +------------------- + +The [**RAJA User Guide and Tutorial**](http://raja.readthedocs.io/en/master/) +is the best place to start learning about RAJA and how to use it. + +To cite RAJA, please use the following references: + +* RAJA Performance Portability Layer. https://github.com/LLNL/RAJA + +* D. A. Beckingsale, J. Burmark, R. Hornung, H. Jones, W. Killian, A. J. Kunen, O. Pearce, P. Robinson, B. S. Ryujin, T. R. W. Scogland, "RAJA: Porrtable Performance for Large-Scale Scientific Applications", 2019 IEEE/ACM International Workshop on Performance, Portability and Productivity in HPC (P3HPC). [Download here](https://conferences.computer.org/sc19w/2019/#!/toc/14) + +Related Software +-------------------- + +The [**RAJA Performance Suite**](https://github.com/LLNL/RAJAPerf) contains +a collection of loop kernels implemented in multiple RAJA and non-RAJA +variants. We use it to monitor and assess RAJA performance on different +platforms using a variety of compilers. + +The [**RAJA Proxies**](https://github.com/LLNL/RAJAProxies) repository +contains RAJA versions of several important HPC proxy applications. + +[**CHAI**](https://github.com/LLNL/CHAI) provides a managed array abstraction +that works with RAJA to automatically copy data used in RAJA kernels to the +appropriate space for execution. It was developed as a complement to RAJA. + +Mailing List +----------------- + +Interested in keeping up with RAJA or communicating with its developers and +users? Please join our mailing list at Google Groups: +- [RAJA Google Group](https://groups.google.com/forum/#!forum/raja-users) + +If you have questions, find a bug, or have ideas about expanding the +functionality or applicability of RAJA and are interested in contributing +to its development, please do not hesitate to contact us. We are very +interested in improving RAJA and exploring new ways to use it. + +Contributions +--------------- + +The RAJA team follows the [GitFlow](http://nvie.com/posts/a-successful-git-branching-model/) development model. Folks wishing to contribute to RAJA, should +include their work in a feature branch created from the RAJA `develop` branch. +Then, create a pull request with the `develop` branch as the destination. That +branch contains the latest work in RAJA. Periodically, we will merge the +develop branch into the `master` branch and tag a new release. + +Authors +----------- + +The original developers of RAJA are: + + * Rich Hornung (hornung1@llnl.gov) + * Jeff Keasler (keasler1@llnl.gov) + +Please see the [RAJA Contributors Page](https://github.com/LLNL/RAJA/graphs/contributors), to see the full list of contributors to the project. + + +License +----------- + +RAJA is licensed under the BSD 3-Clause license, +(BSD-3-Clause or https://opensource.org/licenses/BSD-3-Clause). + +Copyrights and patents in the RAJA project are retained by contributors. +No copyright assignment is required to contribute to RAJA. + +Unlimited Open Source - BSD 3-clause Distribution +`LLNL-CODE-689114` `OCEC-16-063` + +For release details and restrictions, please see the information in the +following: +- [RELEASE](./RELEASE) +- [LICENSE](./LICENSE) +- [NOTICE](./NOTICE) + + +SPDX usage +------------ + +Individual files contain SPDX tags instead of the full license text. +This enables machine processing of license information based on the SPDX +License Identifiers that are available here: https://spdx.org/licenses/ + +Files that are licensed as BSD 3-Clause contain the following +text in the license header: + + SPDX-License-Identifier: (BSD-3-Clause) + +External Packages +------------------- +RAJA bundles its external dependencies as submodules in the git repository. +These packages are covered by various permissive licenses. A summary listing +follows. See the license included with each package for full details. + +PackageName: BLT +PackageHomePage: https://github.com/LLNL/blt +PackageLicenseDeclared: BSD-3-Clause + +PackageName: camp +PackageHomePage: https://github.com/LLNL/camp +PackageLicenseDeclared: BSD-3-Clause + +PackageName: CUB +PackageHomePage: https://github.com/NVlabs/cub +PackageLicenseDeclared: BSD-3-Clause diff --git a/tpl/RAJA/RELEASE b/tpl/RAJA/RELEASE new file mode 100644 index 000000000..7bfcd98fb --- /dev/null +++ b/tpl/RAJA/RELEASE @@ -0,0 +1,29 @@ +******************************************************************************* + +RAJA: ................................, version 0.10.0 + +Copyright (c) 2016-19, Lawrence Livermore National Security, LLC. +Produced at the Lawrence Livermore National Laboratory. +All rights reserved. See details in the RAJA/LICENSE file. + +Unlimited Open Source - BSD Distribution +LLNL-CODE-689114 +OCEC-16-063 + +The RAJA development team and contributors are: + +Rich Hornung (hornung1@llnl.gov) +David Beckingsale (beckingsale1@llnl.gov) +Jason Burmark (burmark1@llnl.gov) +Robert Chen (chen59@llnl.gov) +Matt Cordery (mcorder@us.ibm.com) +Mike Davis (davis291@llnl.gov) +Jeff Hammond (jeff.science@gmail.com) +Holger Jones (jones19@llnl.gov) +Jeff Keasler (keasler1@llnl.gov) +Will Killian (killian4@llnl.gov) +Adam Kunen (kunen1@llnl.gov) +Olga Pearce (pearce8@llnl.gov) +David Poliakoff (poliakoff1@llnl.gov) +Tom Scogland (scogland1@llnl.gov) +Arturo Vargas (vargas45@llnl.gov) diff --git a/tpl/RAJA/RELEASE_NOTES.md b/tpl/RAJA/RELEASE_NOTES.md new file mode 100644 index 000000000..b4a5466ba --- /dev/null +++ b/tpl/RAJA/RELEASE_NOTES.md @@ -0,0 +1,565 @@ + +[comment]: # (#################################################################) +[comment]: # (Copyright 2016-20, Lawrence Livermore National Security, LLC) +[comment]: # (and RAJA project contributors. See the RAJA/COPYRIGHT file) +[comment]: # (for details.) +[comment]: # +[comment]: # (# SPDX-License-Identifier: BSD-3-Clause) +[comment]: # (#################################################################) + +Version vxx.yy.zz -- Release date 20yy-mm-dd +============================================ + +Version v0.11.0 -- Release date 2020-01-29 +========================================== + +This release contains new features, several notable changes, and some bug fixes. + +Notable changes include: + + * New features: + * HIP compiler back-end added to support AMD GPUs. Usage is essentially + the same as for CUDA. Note that this feature is considered a + work-in-progress and not yet production ready. It is undocumented, + but noted here, for friendly users who would like to try it out. + * Updated version of camp third-party library, which includes variety + of portability fixes. Most users should not need to concern + themselves with the details of camp. + * Added new tutorial material and exercises. + * Documentation improvements. + + * API Changes: + * None. + + * Build changes/improvements: + * RAJA version number is now accessible as #define macro variable + constants so that users who need to parameterize their code to support + multiple RAJA versions can do this more easily. See the file + RAJA/include/RAJA/config.hpp for details. RAJA version numbers + are also experted as CMake variables. + * Added support to link to external camp library. By default, the camp + git submodule will be used. If you prefer to use a different version + of camp, set the RAJA CMake variable 'EXTERNAL_CAMP_SOURCE_DIR' to + the location of the desired camp directory. + * BLT submodule (CMake-based build system) has been updated to latest + BLT release (v0.3.0). The release contains a new version of GoogleTest, + which required us to modify our use of gtest macros and our own + testing macros. For the most part, this change should be invisible to + users. However, the new GoogleTest does not work with CUDA versions + 9.1.x or earlier. Therefore, if you compile RAJA with CUDA enabled and + also wish to enable RAJA tests, you must use CUDA 9.2.x or newer. + + * Bug fixes: + * Fixed various issues to make internal implementations more robust, + resolved issues with non fully-qualified types in some places, + and work arounds for some compiler issues. + + +Version v0.10.0 -- Release date 2019-10-31 +========================================== + +This release contains new features, several notable changes, and some bug fixes. + +Notable changes include: + + * New features: + * Added CUDA block direct execution policies, which can be used to map + loop iterations directly to CUDA thread block. These are analogous to + the pre-existing thread direct policies. The new block direct policies + can provide better performance for kernels than the block loop policies + when load balancing may be an issue. Please see the RAJA User Guide for + a description of all available RAJA execution policies. + * Added a plugin registry feature that will allow plugins to be linked + into RAJA that can act before and after kernel launches. One benefit + of this is that RAJA no longer has an explicit CHAI dependency if RAJA + is used with CHAI. Future benefits will include integration with other + tools for performance analysis, etc. + * Added a shift method to RAJA::View, which allows one to create a new + view object from an existing one that is shifted in index space from + the original. Please see the RAJA User Guide for details. + * Added support for RAJA::TypedView and RAJA::TypedOffsetLayout, so that + the index type can be specified as a template parameter. + * Added helper functions to convert a RAJA::Layout object to a + RAJA::OffsetLayout object and RAJA::TypedLayout to + RAJA::TypedOffsetLayout. Please see the RAJA User Guide for details. + * Added a bounds checking option to RAJA Layout types as a debugging + feature. This is a compile-time option that will report user errors + when given View or Layout indices are out-of-bounds. See View/Layout + section in the RAjA User Guide for instructions on enabling this and + how this feature works. + * We've added a RAJA Template Project on GitHub, which shows how to + use RAJA in an application, either as a Git submodule or as an + externally installed library that you link your application against. + It is available here: https://github.com/LLNL/RAJA-project-template. + It is also linked to the main RAJA project page on GitHub. + * Various user documentation improvements. + + * API Change. + * The type alias RAJA::IndexSet that was marked deprecated previously + has been removed. Now, all index set usage must use the type + RAJA::TypedIndexSet and specify all segment types (as template + parameters) that the index set may potentially hold. + + * Bug fixes: + * Fix for issue in OpenMP target offload back-end that previously caused + some RAJA Performance Suite kernels to seg fault when built with the + XL compiler. + * Removed an internal RAJA class constructor to prevent users to do + potentially incorrect, and very difficult to hunt down, things in + their code that are technically not supported in RAJA, such as + inserting RAJA::statement::CudaSyncThreads() in arbitrary places + inside a lambda expression. + + * Build changes/improvements: + * RAJA now enforces a minimum CUDA compute capability of sm_35. Users + can use the CMake variable 'CUDA_ARCH' to specify this. If not + specified, the value of sm_35 will be used and an informational + message will be emitted indicating this. If a user attempts to set + the value lower than sm_35, CMake will error out and a message will + be emitted indicating why this happened. + * Transition to using camp as a submodule after its open source release + (https://github.com/llnl/camp). + * Made minimum required CMake version 3.9. + * Update BLT build system submodule to newer version + (SHA-1 hash: 96419df). + * Cleaned up compiler warnings in OpenMP target back-end implementation. + + +Version v0.9.0 -- Release date 2019-07-25 +========================================= + +This release contains feature enhancements, one breaking change, and some +bug fixes. + + * Breaking change + * The atomic namespace in RAJA has been removed. Now, use atomic operations + as RAJA::atomicAdd(), not RAJA::atomic::atomicAdd(), for example. This + was done to make atomic usage consistent with other RAJA features, such + as reductions, scans, etc. + +Other notable changes include: + + * Features + * The lambda statement interface has been extended in the RAJA kernel API. + Earlier, when multiple lambda expressions were used in a kernel, they + were required to all have the same arguments, although not all + arguments had to be used in each lambda expression. Now, lambda + arguments may be specified in the RAJA::statement::Lambda type so + that each lambda expression need only take the arguments it uses. + However, the previous usage pattern will continue to be supported. + To support the new interface, new statement types have been introduced + to indicate iteration space variables (Segs), local variable/array + parameters (Params), and index offsets (Offsets). The offsets can be used + with a For statement as a replacement for the ForICount statement. The + new API features are described in the RAJA User Guide. + * Minloc and maxloc reductions now support a tuple of index values. So + now if you have a nested loop kernel with i, j, k loops, you can get + the 'loc' value out as an i, j, k triple. + + * Bug Fixes: + * Small change to make RAJA Views work properly with OpenMP target kernels. + * Changes to fix OpenMP target back-end for XL compilers. + * Fix build issue with older versions of GNU compiler. + * Fixes to resolve issues associated with corner cases in choosing + improper number of threads per block or number of thread blocks for + CUDA execution policies. + + * Build changes/improvements: + * A few minor portability improvements + + +Version v0.8.0 -- Release date 2019-03-28 +========================================= + +This release contains one major change and some minor improvements to +compilation and performance. + +Major changes include: + + * Build system updated to use the latest version of BLT (or close to it). + Depending on how one builds RAJA, this could require changes to how + information is passed to CMake. Content has been added to the relevant + sections of the RAJA User Guide which describes how this is done. + +Other notable changes include: + + * Features (These are not yet documented and should be considered + experimental. There will be documentation and usage examples in the + next RAJA release.) + * New thread, warp, and bitmask policies for CUDA. These are not + yet documented and should be considered experimental. + * Added AtomicLocalArray type which returns data elements wrapped + in an AtomicRef object. + + * Bug Fixes: + * Fixed issue in RangeStrideSegment iteration. + * Fix 'align hint' macro to eliminate compile warning when XL compiler + is used with nvcc. + * Fix issues associated with CUDA architecture level (i.e., sm_*) set + too low and generated compiler warning/errors. Caveats for RAJA features + (mostly atomic operations) available at different CUDA architecture + levels added to User Guide. + + * Performance Improvements: + * Some performance improvements in RAJA::kernel usage with CUDA back-end. + + +Version v0.7.0 -- Release date 2019-02-07 +========================================= + +This release contains several major changes, new features, a variety of bug +fixes, and expanded user documentation and accompanying example codes. For +more information and details about any of the changes listed below, please +consult the RAJA documentation for the 0.7.0 release which is linked to +our Github project. + +Major changes include: + + * RAJA::forallN methods were marked deprecated in the 0.6.0 release. They + have been removed. All applications that contain nested loops and + have been using forallN methods should convert them to use the RAJA::kernel + interface. + * RAJA::forall methods that take explicit loop bounds rather than segments + (e.g., RAJA::forall(beg, end, ...) were marked deprecated in the 0.6.0 + release. They have been removed. Hopefully, this will result in faster + compile times due to simpler template resolution. Users who have been + passing loop bounds directly to forall methods should convert those + cases to use RAJA segments instead. + * CUDA execution policies for use in RAJA::kernel policies have been + significantly reworked and redefined. The new set of policies are + much more flexible and provide improved run time performance. + * New, improved support for loop tiling algorithms and support for + CPU cache blocking, CUDA GPU thread local data and shared memory is + available. This includes RAJA::kernel policy statement types to make tile + numbers and local tile indices available in user kernels (TileTCount and + ForICount statement types), and a new RAJA::LocalArray type with various + CPU and GPU memory policies. Due to these new features, RAJA 'shmem window' + statements have been removed. + * This release contains expanded documentation and example codes for the + RAJA::kernel interface, including loop tiling algorithms and support for + CPU cache blocking, CUDA GPU thread local data and shared memory. + +Other notable changes include: + + * Features: + * Initial support for OpenMP target execution policies with RAJA::kernel + added. + * The RAJA::AtomicRef interface is now consistent with the + C++20 std::atomic_ref interface. + * Atomic compare-exchange operations added. + * CUDA reduce policies no longer require a thread-block size parameter. + * New features considered preliminary with no significant documentation or + examples available yet: + * RAJA::statement::Reduce type for use in RAJA::kernel execution + policies. This enables the ability to perform reductions and access + reduced values inside user kernels. + * Warp-level execution policies added for CUDA. + + * Performance improvements: + * Better use of inline directives to improve likelihood of SIMD + instruction generation with the Intel compiler. + + * Bug fixes: + * Several CHAI integration issues resolved. + * Resolve issue with alignx directive when using XL compiler as host + compiler with CUDA. + * Fix issue associated with how XL compiler interprets OpenMP region + definition. + * Various tweaks to camp implementation to improve robustness. + + * Build changes/improvements: + * The minimum required version of CMake has changed to 3.8 for all + programming model back-ends, except CUDA. The minimum CMake version + for CUDA support is 3.9. + * Improved support for clang-cuda compiler. Some features still do not + work with that compiler. + * Update NVIDIA cub module to version 1.8.0. + * Enable use of 'BLT_SOURCE_DIR' CMake variable to help prevent conflicts + with BLT versions in RAJA and other libraries used in applications. + + +Version v0.6.0 -- Release date 2018-07-27 +========================================= + +This release contains two major changes, a variety of bug fixes and feature +enhancements, and expanded user documentation and accompanying example codes. + +Major changes include: + + * RAJA::forallN methods are marked deprecated. They will be removed in + the 0.7.0 release. + * RAJA::forall methods that take loop bounds rather than segments (e.g., + RAJA::forall(beg, end, ...) are marked deprecated. They will be removed + in the 0.7.0 release. + * RAJA::nested has been replaced with RAJA::kernel. The RAJA::kernel interface + is much more flexible and full featured. Going forward, it will be the + supported interface for nested loops and more complex kernels in RAJA. + * This release contains new documentation and example codes for the + RAJA::kernel interface. The documentation described key features and + summarizes available 'statement' types. However, it remains a + work-in-progress and expanded documentation with more examples will be + available in future releases. + * Documentation of other RAJA features have been expanded and improved in + this release along with additional example codes. + +Other notable changes include: + + * New or improved features: + * RAJA CUDA reductions now work with host/device lambdas + * List segments now work with RAJA::kernel loops. + * New and expanded collection of build files for LC and ALCF machines. + Hopefully, these will be helpful to folks getting started. + + * Performance improvements: + * Some RAJA::View use cases + * Unnecessary operations removed in min/max atomics + + * Bug fixes: + * Issues in View with OffsetLayout fixed. + * Construction of a const View from a non-const View now works + * CUDA kernel no longer launched in RAJA::kernel loops when iteration + space has size zero + + +Version v0.5.3 -- Release date 2018-01-31 +========================================= + +This is a bugfix release that fixes bugs in the IndexSetBuilder methods. These +methods now work correctly with the strongly-typed IndexSet. + + +Version v0.5.2 -- Release date 2018-01-30 +========================================= + +This release fixes some small bugs, including compiler warnings issued for +deprecated features, type narrowing, and the slice method for the +RangeStrideSegment class. + +It also adds a new CMake variable, RAJA_LOADED, that is used to determine +whether RAJA's CMakeLists file has already been processed. This is useful when +including RAJA as part of another CMake project. + + +Version v0.5.1 -- Release date 2018-01-17 +========================================= + +This release contains fixes for compiler warnings with newer GCC and Clang +compilers, and allows strongly-typed indices to work with RangeStrideSegment. + +Additionally, the index type for all segments in an IndexSet needs to be the +same. This requirement is enforced with a static_assert. + + +Version v0.5.0 -- Release date 2018-01-11 +========================================= + +This release contains a variety of bug fixes, removes nvcc compiler +warnings, addition of unit tests to expand coverage, and a variety of +other code cleanup and improvements. The most notable changes in this +version include: + + * New RAJA User Guide and Tutorial along with a set of example codes + that illustrate basic usage of RAJA features and which accompany + the tutorial. The examples are in the ``RAJA/examples`` directory. + The user guide is available online here: + [RAJA User Guide and Tutorial](http://raja.readthedocs.io/en/master/). + + * ``RAJA::IndexSet`` is now deprecated. You may still use it until it is + removed in a future release -- you will see a notification message at + compile time that it is deprecated. + + Index set functionality will now be available via ``RAJA::TypedIndexSet`` + where you specify all segment types as template parameters when you + declare an instance of it. This change allows us to: remove all virtual + methods from the index set, be able to use index set objects to CUDA + GPU kernels and all of their functionality, and support any arbitrary + segment type even user-defined. Please see User Guide for details. + + Segment dependencies are being developed for the typed index set and + will be available in a future release. + + * ``RAJA::nested::forall`` changes: + + * Addition of CUDA and OpenMP collapse policies for nested loops. + OpenMP collapse will do what the OpenMP collapse clause does. + CUDA collapse will collapse a loop nest into a single CUDA kernel based + on how nested policies specify how the loop levels should be distributed + over blocks and threads. + + * Added new policy ``RAJA::cuda_loop_exec`` to enable inner loops to run + sequentially inside a CUDA kernel with ``RAJA::nested::forall``. + + * Fixed ``RAJA::nested::forall`` so it now works with RAJA's CUDA Reducer + types. + + * Removed ``TypedFor`` policies. For type safety of nested loop iteration + variables, it makes more sense to use ``TypedRangeSegment`` since the + variables are associated with the loop kernel and not the execution + policy, which may be applied to multiple loops with different variables. + + * Fixed OpenMP scans to calculate chunks of work based on actual number of + threads the OpenMP runtime makes available. + + * Enhancements and fixes to RAJA/CHAI interoperability. + + * Added aliases for several ``camp`` types in the RAJA namespace; e.g., + ``camp::make_tuple`` can now be accessed as ``RAJA::make_tuple``. This + change makes the RAJA API more consistent and clear. + + +Version v0.4.1 -- Release date 2017-10-11 +========================================= + +This release contains a bugfix for warnings when using the -Wpedantic flag. + + +Version v0.4.0 -- Release date 2017-10-11 +========================================= + +This release contains minor fixes for issues in the previous v0.3.1 release, +plus some improvements to documentation, reduction performance, improved +portability across a growing set of compilers and environments (e.g., Windows), +namespace refactoring to avoid cyclic dependencies and leverage argument- +dependent lookup, etc. In addition, the RAJA backend for Intel TBB is now +off by default, whereas previously it was on by default. + +A few major changes are included in this version: + + * Changes to the way RAJA is configured and built. We are now using the + BLT build system which is a Git submodule of RAJA. In addition to + requiring the '--recursive' option to be passed to 'git clone', this + introduces the following major change: RAJA_ENABLE_XXX options passed to + CMake are now just ENABLE_XXX. + + * A new API and implementation for nested-loop RAJA constructs has been + added. It is still a work in progress, but users are welcome to try it + out and provide feedback. Eventually, RAJA::nested::forall will replace + RAJA::forallN. + + +Version v0.3.1 -- Release date 2017-09-21 +========================================= + +This release contains some new RAJA features, plus a bunch of internal changes +including more tests, conversion of nearly all unit tests to use Google Test, +improved testing coverage, and compilation portability improvements (e.g., +Intel, nvcc, msvc). Also, the prefix for all RAJA source files has been changed +from 'cxx'to 'cpp' for consistency with the header file prefix conversion in +the last release. The source file prefix change should not require users to +change anything. + +New features included in this release: + + * Execution policy modifications and additions: + + * seq_exec is now strictly sequential (no SIMD, etc.) + * simd_exec will force SIMD vectorization + * loop_exec (new policy) will allow compiler to optimize however it can, + including SIMD. + + So, loop_exec is really what our previous simd_exec policy was before, + and 'no vector' pragmas have been added to all sequential implementations. + + NOTE: SIMD changes are still being evaluated with different compilers on + different platforms. More information will be provided as we learn more. + + * Added support for atomic operations (min, max, inc, dec, and, or, xor, + exchange, and CAS) for all programming model backends. These appear in the + RAJA::atomic namespace. + + * Support added for Intel Threading Building Blocks backend (considered + experimental at this point). + + * Added macros that will be used to mark features for future deprecation + (please watch for this as we will be deprecating some features in the + next release). + + * Added support for C++17 if CMake knows about it. + + * Remove limit on number of ordered OpenMP reductions that can be used in + a kernel. + + * Remove compile-time error from memutils, add portable aligned allocator. + + * Improved ListSegment implementation. + + * RAJA::Index_type is now ptrdiff_t instead of int. + +Notable bug fixes included in this release: + + * Fixed strided_numeric_iterator to apply stride sign in comparison. + + * Bug in RangeStrideSegment when using CUDA is fixed. + + * Fixed reducer logic for openmp_ordered policy. + + +Version v0.3.0 -- Release date 2017-07-13 +========================================= + +This release contains breaking changes and is not backward compatible with +prior versions. The largest change is a re-organization of header files, +and the switch to .hpp as a file extension for all headers. + +New features included in this release: + + * Re-organization of header files. + + * Renaming of file extensions. + + * Rudimentary OpenMP 4.5 support. + + * CHAI support. + + +Version v0.2.5 -- Release date 2017-03-28 +========================================= + +This release includes some small fixes, as well as an initial re-organization +of the RAJA header files as we move towards a more flexible usage model. + + +Version v0.2.4 -- Release date 2017-02-22 +========================================= + +This release includes the following changes: + + * Initial support of clang-cuda compiler. + + * New, faster OpenMP reductions. + +N.B. The default OpenMP reductions are no longer performed in a ordered + fashion, so results may not be reproducible. The old reductions are + still available with the policy RAJA::omp_reduce_ordered. + + +Version v0.2.3 -- Release date 2016-12-15 +========================================= + +Hotfix to update the URLs used for fetching clang during Travis builds. + + +Version v0.2.2 -- Release date 2016-12-14 +========================================= + +Bugfix release that address an error when launching forall cuda kernels +with a 0-length range. + + +Version v0.2.1 -- Release date 2016-12-07 +========================================= + +This release contains fixes for compiler warnings and removes the usage of +the custom FindCUDA CMake package. + + +Version v0.2.0 -- Release date 2016-12-02 +========================================= + +Includes internal changes for performance and code maintenance. + + +Version v0.1.0 -- Release date 2016-06-22 +========================================= + +Initial release. diff --git a/tpl/RAJA/appveyor.yml b/tpl/RAJA/appveyor.yml new file mode 100644 index 000000000..947fb0569 --- /dev/null +++ b/tpl/RAJA/appveyor.yml @@ -0,0 +1,18 @@ +version: 1.0.{build} +skip_branch_with_pr: true +image: Visual Studio 2017 +build_script: +- cmd: >- + git submodule init + + git submodule update + + mkdir build + + cd build + + cmake ../ + + cmake --build . --config Release +test_script: +- cmd: ctest -VV -C Release diff --git a/tpl/RAJA/benchmark/CMakeLists.txt b/tpl/RAJA/benchmark/CMakeLists.txt new file mode 100644 index 000000000..f140c24c0 --- /dev/null +++ b/tpl/RAJA/benchmark/CMakeLists.txt @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2016-20, Lawrence Livermore National Security, LLC +# and RAJA project contributors. See the RAJA/COPYRIGHT file for details. +# +# SPDX-License-Identifier: (BSD-3-Clause) +############################################################################### + +if (ENABLE_CUDA) + raja_add_benchmark( + NAME benchmark-host-device-lambda + SOURCES host-device-lambda-benchmark.cpp) +endif() diff --git a/tpl/RAJA/benchmark/host-device-lambda-benchmark.cpp b/tpl/RAJA/benchmark/host-device-lambda-benchmark.cpp new file mode 100644 index 000000000..d4b623c15 --- /dev/null +++ b/tpl/RAJA/benchmark/host-device-lambda-benchmark.cpp @@ -0,0 +1,72 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Copyright (c) 2016-20, Lawrence Livermore National Security, LLC +// and RAJA project contributors. See the RAJA/COPYRIGHT file for details. +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +#include + +#include "benchmark/benchmark_api.h" + +#include "RAJA/RAJA.hpp" + +#define N 10000000 + +static void benchmark_daxpy_raw(benchmark::State& state) +{ + double* a = new double[N]; + double* b = new double[N]; + + for (int i = 0; i < N; i++) { + a[i] = 1.0; + b[i] = 2.0; + } + double c = 3.14159; + + while (state.KeepRunning()) { + RAJA::forall(RAJA::RangeSegment(0, N), + [=](int i) { a[i] += b[i] * c; }); + } +} + +static void benchmark_daxpy_host(benchmark::State& state) +{ + double* a = new double[N]; + double* b = new double[N]; + + for (int i = 0; i < N; i++) { + a[i] = 1.0; + b[i] = 2.0; + } + double c = 3.14159; + + while (state.KeepRunning()) { + RAJA::forall(RAJA::RangeSegment(0, N), + [=] __host__(int i) { a[i] += b[i] * c; }); + } +} + +static void benchmark_daxpy_host_device(benchmark::State& state) +{ + double* a = new double[N]; + double* b = new double[N]; + + for (int i = 0; i < N; i++) { + a[i] = 1.0; + b[i] = 2.0; + } + double c = 3.14159; + + while (state.KeepRunning()) { + RAJA::forall(RAJA::RangeSegment(0, N), + [=] RAJA_HOST_DEVICE(int i) { + a[i] += b[i] * c; + }); + } +} + +BENCHMARK(benchmark_daxpy_raw); +BENCHMARK(benchmark_daxpy_host); +BENCHMARK(benchmark_daxpy_host_device); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/.mailmap b/tpl/RAJA/blt/.mailmap new file mode 100644 index 000000000..5be06a215 --- /dev/null +++ b/tpl/RAJA/blt/.mailmap @@ -0,0 +1,10 @@ +George Zagaris George Zagaris +Kenneth Weiss Kenneth Weiss +Kenneth Weiss Kenny Weiss +Kenneth Weiss Kenny Weiss +Peter B. Robinson robinson96 +Peter B. Robinson robinspb +Randolph R. Settgast Randolph R. Settgast +Randolph R. Settgast Randolph Settgast +Randolph R. Settgast Randolph Settgast + diff --git a/tpl/RAJA/blt/.travis.yml b/tpl/RAJA/blt/.travis.yml new file mode 100644 index 000000000..20f8d2789 --- /dev/null +++ b/tpl/RAJA/blt/.travis.yml @@ -0,0 +1,225 @@ +############################################################################### +# Copyright (c) 2017, Lawrence Livermore National Security, LLC. +# +# Produced at the Lawrence Livermore National Laboratory +# +# LLNL-CODE-725085 +# +# All rights reserved. +# +# This file is part of BLT. +# +# For additional details, please also read BLT/LICENSE. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the disclaimer below. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the disclaimer (as noted below) in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the LLNS/LLNL nor the names of its contributors may +# be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY, +# LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################### + +sudo: false + +language: cpp +compiler: + - gcc +env: + global: + # we need to know the root dir for our 3rd party lib installs + - TRAVIS_HOME=`pwd`/.. + - TRAVIS_TPLS_DIR=${TRAVIS_HOME}/tpls + matrix: + # gcc w/ cmake 3.8.0, gmock off + - CMAKE_MAJOR=3.8 + CMAKE_MINOR=0 + BLT_CC=gcc-4.9 + BLT_CXX=g++-4.9 + BLT_FC=gfortran-4.9 + BLT_FORTRAN=ON + BLT_OPENMP=ON + BLT_GTEST=ON + BLT_FRUIT=ON + BLT_GMOCK=OFF + # gcc w/ cmake 3.8.0, all on + - CMAKE_MAJOR=3.8 + CMAKE_MINOR=0 + BLT_CC=gcc-4.9 + BLT_CXX=g++-4.9 + BLT_FC=gfortran-4.9 + BLT_FORTRAN=ON + BLT_OPENMP=ON + BLT_GTEST=ON + BLT_FRUIT=ON + BLT_GMOCK=ON + # gcc w/ cmake 3.8.0, gtest and fruit off + - CMAKE_MAJOR=3.8 + CMAKE_MINOR=0 + BLT_CC=gcc-4.9 + BLT_CXX=g++-4.9 + BLT_FC=gfortran-4.9 + BLT_FORTRAN=ON + BLT_GTEST=OFF + BLT_FRUIT=OFF + # gcc w/ cmake 3.9.6, all on + - CMAKE_MAJOR=3.9 + CMAKE_MINOR=6 + BLT_CC=gcc-4.9 + BLT_CXX=g++-4.9 + BLT_FC=gfortran-4.9 + BLT_FORTRAN=ON + BLT_OPENMP=ON + BLT_GTEST=ON + BLT_FRUIT=ON + BLT_GMOCK=ON + # gcc w/ cmake 3.11.4, all on + - CMAKE_MAJOR=3.11 + CMAKE_MINOR=4 + BLT_CC=gcc-4.9 + BLT_CXX=g++-4.9 + BLT_FC=gfortran-4.9 + BLT_FORTRAN=ON + BLT_OPENMP=ON + BLT_GTEST=ON + BLT_FRUIT=ON + BLT_GMOCK=ON +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-4.9 + - g++-4.9 + - gfortran-4.9 + - mpich + - libmpich-dev +before_install: + # workaround apt related for error: + # Err:6 http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty InRelease + # The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 1E9377A2BA9EF27F + - sudo apt update -o Acquire::Retries=100 -o Acquire::http::Timeout="60" -o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDowngradeToInsecureRepositories=true + + # download the ver of cmake we want to test + - wget --no-check-certificate http://www.cmake.org/files/v${CMAKE_MAJOR}/cmake-${CMAKE_MAJOR}.${CMAKE_MINOR}-Linux-x86_64.sh +install: + # install cmake + - mkdir -p ${TRAVIS_TPLS_DIR}/cmake/ + - sh cmake-${CMAKE_MAJOR}.${CMAKE_MINOR}-Linux-x86_64.sh --skip-license --prefix=${TRAVIS_TPLS_DIR}/cmake/ + - export PATH=${TRAVIS_TPLS_DIR}/cmake/bin:$PATH +script: + # set git user info + - git config --global user.email "blt-dev@llnl.gov" + - git config --global user.name "BLT Robot" + - BLT_SOURCE_DIR=${TRAVIS_BUILD_DIR} + - cmake --version + - cd $TRAVIS_BUILD_DIR/.. + # copy our internal testing project + - cp -r blt/tests/internal blt-test + # create a git repo for blt-test to test the git macros + - cd blt-test + - git init + - git add -A + - git commit -a -m "Initial Commit" + - git checkout -b test-branch + - git tag test-tag + - cd .. + # create an out-of-source build dir and an install dir + - mkdir travis-debug-build + - mkdir travis-debug-install + # sanity check + - ls + - ls blt-test + # change into build dir + - cd travis-debug-build + # point to blt + - CMAKE_OPTS="-DBLT_SOURCE_DIR=${BLT_SOURCE_DIR}" + # build type and install loc + - CMAKE_OPTS="${CMAKE_OPTS} -DCMAKE_BUILD_TYPE=Debug" + - CMAKE_OPTS="${CMAKE_OPTS} -DCMAKE_INSTALL_PREFIX=../travis-debug-install" + # c & c++ compilers + - CMAKE_OPTS="${CMAKE_OPTS} -DCMAKE_C_COMPILER=${BLT_CC}" + - CMAKE_OPTS="${CMAKE_OPTS} -DCMAKE_CXX_COMPILER=${BLT_CXX}" + - CMAKE_OPTS="${CMAKE_OPTS} -DBLT_CXX_STD:STRING=c++11" + # gtest support + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_GTEST=${BLT_GTEST}" + # gmock support + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_GMOCK=${BLT_GMOCK}" + # fruit support + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_FRUIT=${BLT_FRUIT}" + # benchmarking + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_BENCHMARKS=ON" + # enable fortran support + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_FORTRAN=${BLT_FORTRAN}" + - CMAKE_OPTS="${CMAKE_OPTS} -DCMAKE_Fortran_COMPILER=${BLT_FC}" + # openmp support + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_OPENMP=${BLT_OPENMP}" + # mpi support + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_MPI=ON" + - CMAKE_OPTS="${CMAKE_OPTS} -DMPI_C_COMPILER=mpicc" + - CMAKE_OPTS="${CMAKE_OPTS} -DMPI_CXX_COMPILER=mpicc" + - CMAKE_OPTS="${CMAKE_OPTS} -DMPI_Fortran_COMPILER=mpif90" + # test git macros + - CMAKE_OPTS="${CMAKE_OPTS} -DTEST_GIT_MACROS=ON" + # configure with cmake + - cmake ${CMAKE_OPTS} ../blt-test + # build, link, and test + - make + - env CTEST_OUTPUT_ON_FAILURE=1 make test + - make install + ######################################################### + ######################################################### + # tutorial tests + ######################################################### + ######################################################### + # override prev gtest setting, these projects req gtest + - CMAKE_OPTS="${CMAKE_OPTS} -DENABLE_GTEST=ON" + ######################################################### + # test docs/tutorial/blank_project + ######################################################### + - cd ${TRAVIS_BUILD_DIR} + - mkdir -p test-tutorial/blank_project + - cd test-tutorial/blank_project + - cmake ${CMAKE_OPTS} ${BLT_SOURCE_DIR}/docs/tutorial/blank_project + - make + - env CTEST_OUTPUT_ON_FAILURE=1 make test + - make install + ######################################################### + # test docs/tutorial/calc_pi + ######################################################### + - cd ${TRAVIS_BUILD_DIR} + - mkdir -p test-tutorial/calc_pi + - cd test-tutorial/calc_pi + - cmake ${CMAKE_OPTS} ${BLT_SOURCE_DIR}/docs/tutorial/calc_pi + - make + - env CTEST_OUTPUT_ON_FAILURE=1 make test + - make install + + + +notifications: + email: + recipients: + - cyrush@llnl.gov + on_success: always + on_failure: always diff --git a/tpl/RAJA/blt/CODE-OF-CONDUCT.md b/tpl/RAJA/blt/CODE-OF-CONDUCT.md new file mode 100644 index 000000000..b3668d7a5 --- /dev/null +++ b/tpl/RAJA/blt/CODE-OF-CONDUCT.md @@ -0,0 +1,77 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at blt-dev@llnl.gov. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq + diff --git a/tpl/RAJA/blt/CONTRIBUTING.md b/tpl/RAJA/blt/CONTRIBUTING.md new file mode 100644 index 000000000..5547c7d7c --- /dev/null +++ b/tpl/RAJA/blt/CONTRIBUTING.md @@ -0,0 +1,38 @@ +# Contributing to BLT + +We welcome contributions to BLT. To do so please submit a pull request through our +BLT github page at https://github.com/LLNL/blt. + +All contributions to BLT must be made under the BSD License. + +Any questions can be sent to blt-dev@llnl.gov. + +# Attribution + +We want everyone to feel they are getting the proper attribution for their +contributions. Here are some suggestions on how to get that: + +* New files: add your name and a date to the top of the file +* New functions or macros: add your name to the comment above it + +For example: + +``` +# Author: John Doe @ Some Company, Inc. +``` + +# Contributors (In Alphabetical Order) + +* Izaak Beekman +* Robert Blake, LLNL +* Jason Burmark, LLNL +* Ben Corbett, LLNL +* Johann Dahm +* Chip Freitag, AMD, Inc. +* Elsa Gonsiorowski, LLNL +* Burl Hall, LLNL +* Matt Larsen +* Martin McFadden, LLNL +* Mark Miller, LLNL +* David Poliakoff, LLNL + diff --git a/tpl/RAJA/blt/LICENSE b/tpl/RAJA/blt/LICENSE new file mode 100644 index 000000000..a7d513ff3 --- /dev/null +++ b/tpl/RAJA/blt/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tpl/RAJA/blt/NOTICE b/tpl/RAJA/blt/NOTICE new file mode 100644 index 000000000..d64ac16ab --- /dev/null +++ b/tpl/RAJA/blt/NOTICE @@ -0,0 +1,20 @@ +Additional BSD Notice + +1. This notice is required to be provided under our contract with the U.S. +Department of Energy (DOE). This work was produced at Lawrence Livermore +National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE. + +2. Neither the United States Government nor Lawrence Livermore National +Security, LLC nor any of their employees, makes any warranty, express or +implied, or assumes any liability or responsibility for the accuracy, +completeness, or usefulness of any information, apparatus, product, or process +disclosed, or represents that its use would not infringe privately-owned rights. + +3. Also, reference herein to any specific commercial products, process, or +services by trade name, trademark, manufacturer or otherwise does not +necessarily constitute or imply its endorsement, recommendation, or favoring by +the United States Government or Lawrence Livermore National Security, LLC. The +views and opinions of authors expressed herein do not necessarily state or +reflect those of the United States Government or Lawrence Livermore National +Security, LLC, and shall not be used for advertising or product endorsement +purposes. diff --git a/tpl/RAJA/blt/README.md b/tpl/RAJA/blt/README.md new file mode 100644 index 000000000..a329910c3 --- /dev/null +++ b/tpl/RAJA/blt/README.md @@ -0,0 +1,134 @@ +# BLT + +[![Build Status](https://travis-ci.org/LLNL/blt.svg)](https://travis-ci.org/LLNL/blt) +[![Build Status](https://ci.appveyor.com/api/projects/status/fuaftu9mvp0y488j/branch/master?svg=true)](https://ci.appveyor.com/project/cyrush/blt/branch/master) +[![Documentation Status](https://readthedocs.org/projects/llnl-blt/badge/?version=develop)](https://llnl-blt.readthedocs.io/en/develop/?badge=develop) + +BLT is a streamlined [CMake](https://cmake.org)-based foundation for +Building, Linking and Testing large-scale high performance computing (HPC) applications. + +BLT makes it easy to get up and running on a wide range of HPC compilers, +operating systems and technologies: + * Compiler families: + [gcc](https://gcc.gnu.org), + [clang](https://clang.llvm.org), + [Intel](https://software.intel.com/en-us/compilers), + [XL](https://www.ibm.com/us-en/marketplace/ibm-c-and-c-plus-plus-compiler-family), + [Visual Studio](https://visualstudio.microsoft.com/vs/features/cplusplus) + * Operating systems: + Linux, + Mac OS, + Windows + * HPC programming models: + [MPI](https://www.mpi-forum.org/), + [OpenMP](https://www.openmp.org/), + [CUDA](https://developer.nvidia.com/cuda-zone), + [HIP](https://gpuopen.com/compute-product/hip-convert-cuda-to-portable-c-code) + * Unit testing and benchmarking (built-in): + [Google Test (gtest and gmock)](https://github.com/google/googletest), + [FRUIT](https://sourceforge.net/projects/fortranxunit), + [gbenchmark](https://github.com/google/benchmark) + * Documentation: + [Doxygen](http://www.doxygen.nl/), + [Sphinx](http://www.sphinx-doc.org) + * Code style and health: + [Uncrustify](http://uncrustify.sourceforge.net), + [AStyle](http://astyle.sourceforge.net), + [Cppcheck](http://cppcheck.sourceforge.net), + [clang-query](http://clang.llvm.org/docs/LibASTMatchers.html) + + +Getting started +--------------- + +BLT is easy to pull into an existing or new CMake-based project using a single CMake `include()` command: + + ```cmake + include(path/to/blt/SetupBLT.cmake) + ``` + +For more information, please check our [user documentation and tutorial](https://llnl-blt.readthedocs.io). + +Questions +--------- + +Any questions can be sent to blt-dev@llnl.gov. + +Authors +------- + +Developers include: + + * Chris White (white238@llnl.gov) + * Kenneth Weiss (kweiss@llnl.gov) + * Cyrus Harrison (harrison37@llnl.gov) + * George Zagaris (zagaris2@llnl.gov) + * Lee Taylor (taylor16@llnl.gov) + * Aaron Black (black27@llnl.gov) + * David A. Beckingsale (beckingsale1@llnl.gov) + * Richard Hornung (hornung1@llnl.gov) + * Randolph Settgast (settgast1@llnl.gov) + +Please see the [BLT Contributors Page](https://github.com/LLNL/BLT/graphs/contributors) for the full list of project contributors. + +Open-Source Projects using BLT +------------------------------ + + * [Ascent](https://github.com/Alpine-DAV/ascent): A flyweight in-situ visualization and analysis runtime for multi-physics HPC simulations + * [Axom](https://github.com/LLNL/axom): Software infrastructure for the development of multi-physics applications and computational tools + * [CHAI](https://github.com/LLNL/CHAI): Copy-hiding array abstraction to automatically migrate data between memory spaces + * [Conduit](https://github.com/LLNL/conduit): Simplified data exchange for HPC simulations + * [RAJA](https://github.com/LLNL/raja): Performance portability layer for HPC + * [Umpire](https://github.com/LLNL/Umpire): Application-focused API for memory management on NUMA and GPU architectures + * [VTK-h](https://github.com/Alpine-DAV/vtk-h): Scientific visualization algorithms for emerging processor architectures + +If you would like to add a library to this list, please let us know via [email](mailto:blt-dev@llnl.gov) +or by submitting an [issue](https://github.com/LLNL/blt/issues) or [pull-request](https://github.com/LLNL/blt/pulls). + +License +------- + +BLT is licensed under the BSD 3-Clause license, +(BSD-3-Clause or https://opensource.org/licenses/BSD-3-Clause). + +Copyrights and patents in the BLT project are retained by contributors. +No copyright assignment is required to contribute to BLT. + +See [LICENSE](./LICENSE) for details. + +Unlimited Open Source - BSD 3-clause Distribution +`LLNL-CODE-725085` `OCEC-17-023` + +SPDX usage +------------ + +Individual files contain SPDX tags instead of the full license text. +This enables machine processing of license information based on the SPDX +License Identifiers that are available here: https://spdx.org/licenses/ + +Files that are licensed as BSD 3-Clause contain the following +text in the license header: + + SPDX-License-Identifier: (BSD-3-Clause) + +External Packages +------------------- +BLT bundles its external dependencies in thirdparty_builtin/. These +packages are covered by various permissive licenses. A summary listing +follows. See the license included with each package for full details. + +PackageName: fruit +PackageHomePage: https://sourceforge.net/projects/fortranxunit/ +PackageLicenseDeclared: BSD-3-Clause + +PackageName: gbenchmark +PackageHomePage: https://github.com/google/benchmark +PackageLicenseDeclared: Apache-2.0 + +PackageName: gmock +PackageHomePage: https://github.com/google/googlemock +PackageLicenseDeclared: BSD-3-Clause + +PackageName: gtest +PackageHomePage: https://github.com/google/googletest +PackageLicenseDeclared: BSD-3-Clause diff --git a/tpl/RAJA/blt/RELEASE-NOTES.md b/tpl/RAJA/blt/RELEASE-NOTES.md new file mode 100644 index 000000000..3dd782792 --- /dev/null +++ b/tpl/RAJA/blt/RELEASE-NOTES.md @@ -0,0 +1,107 @@ +# BLT Software Release Notes + +Notes describing significant changes in each BLT release are documented +in this file. + +The format of this file is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). + +The project release numbers follow [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] - Release date yyyy-mm-dd + +## [Version 0.3.0] - Release date 2020-01-08 + +### Added +- Sets CMake policy CMP0074 to NEW, when available. +- Added simpler Clang+XLF+Cuda host-config for LLNL's blueos +- API Docs that are public! +- Added the ability to override blt's custom target names, e.g. for code checks, + formatting and generating documentation. The new variables are: ``BLT_CODE_CHECK_TARGET_NAME``, + ``BLT_CODE_STYLE_TARGET_NAME``, ``BLT_DOCS_TARGET_NAME`` and ``BLT_RUN_BENCHMARKS_TARGET_NAME``. +- Clean up linking flags when ``CUDA_LINK_WITH_NVCC`` is ON. Added logic to automatically convert + '-Wl,-rpath' linking flag to '-Xlinker -rpath -Xlinker' and removes ``-pthread`` from from + MPI linking flags returned from FindMPI because it doesn't work + (see https://gitlab.kitware.com/cmake/cmake/issues/18008). +- In CMake 3.13+, "SHELL:" was added to blt_add_target_link_flags. This stops CMake from de-duplicating + needed linker flags. +- Added optional SCOPE to all target property macros, blt_add_target_link_flags, etc. It defaults to PUBLIC. +- Added support for Cray compilers in blt_append_custom_compiler_flag. +- Added ability to add flags to the cppcheck command line through blt_add_code_checks() +- Added ability for blt_add_test() to set required number of OpenMP threads via new option NUM_OMP_THREADS. + +### Changed +- Restructured the host-config directory by site and platform. +- Updated gbenchmark to 1.5.0, note that this requires C++11 to build. +- Updated gtest and gmock to Master as of 2020-01-07, note that this requires C++11 to build. + +### Fixed +- Fixed some warnings in CMake 3.14+ + +## [Version 0.2.5] - Release date 2019-06-13 + +### Added +- Added support for C++17. Note: Neither XL nor CMake's CUDA_STANDARD supports + C++17 (A BLT fatal error will occur). +- Added ability to override all MPI variables: BLT_MPI_COMPILE_FLAGS, + BLT_MPI_INCLUDES, BLT_MPI_LIBRARIES, and BLT_MPI_LINK_FLAGS +- blt_list_remove_duplicates(): macro for removing duplicates from a list that + doesn't error on empty lists. + +### Changed +- Handle CMake 3.10+ changing all the FindMPI output variables. +- BLT_CXX_STD is no longer defined to "c++11" by default. If undefined, BLT will + not try and add any C++ standard flags. +- Handle FindMPI variable MPIEXEC changed to MPIEXEC_EXECUTABLE in CMake 3.10+. + This now works regardless of which the user defines or what CMake returns. +- Handle CMake target property LINK_FLAGS changed to LINK_OPTIONS in CMake 3.13+. + blt_add_target_link_flags() handles this under the covers and converts the + users strings to a list (3.13+) or list to a string (<3.13). New property supports + generator expressions so thats a plus. +- Improved how all BLT MPI information is being merged together and reported to users. +- Increased number of ranks in `blt_mpi_smoke` test to catch regression. +- blt_split_source_list_by_language now supports non-BLT object libraries and errors + out when any other generator expression is given in source list. This is to avoid + very bad side effects of not being able to set source properties on anything + inside the generator expression. This is because BLT cannot evaluate them. + +### Fixed +- Error out with better message when empty file extensions is hit in + blt_split_source_list_by_language. + + +## [Version 0.2.0] - Release date 2019-02-15 + +### Added +- Release notes... +- Explicitly check for CMake 3.8+ for required CMake features (Not fatal error) +- Object library support through blt_add_library(... OBJECT TRUE ...) +- Now reporting BLT version through CMake cache variable BLT_VERSION +- Output CMake version and executable used during CMake step +- Clang-query support now added (Thanks David Poliakoff) + +### Removed + +### Deprecated + +### Changed +- Object libraries no longer call target_link_libraries() but will pass inherited information + because why would anyone ever want to install/export a bunch of object files. +- Remove duplicates of select target properties at the end of blt_add_library and + blt_add_executable. (include directories and compile defines) + +### Fixed +- Incorrect use of cuda vs cuda_runtime targets +- Improved tutorial documentation +- Incorrect use of Fortran flags with CUDA (Thanks Robert Blake) +- Handle correctly CMake version differences with CUDA host compiler variables + (Thanks Randy Settgast) +- Handle uncrustify (version 0.68) command line option changes (--no-backup) + +### Known Bugs + + + +[Unreleased]: https://github.com/LLNL/blt/compare/v0.3.0...develop +[Version 0.3.0]: https://github.com/LLNL/blt/compare/v0.2.5...v0.3.0 +[Version 0.2.5]: https://github.com/LLNL/blt/compare/v0.2.0...v0.2.5 +[Version 0.2.0]: https://github.com/LLNL/blt/compare/v0.1.0...v0.2.0 diff --git a/tpl/RAJA/blt/SetupBLT.cmake b/tpl/RAJA/blt/SetupBLT.cmake new file mode 100644 index 000000000..c0b88f0ff --- /dev/null +++ b/tpl/RAJA/blt/SetupBLT.cmake @@ -0,0 +1,206 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +if (NOT BLT_LOADED) + set(BLT_VERSION "0.3.0" CACHE STRING "") + mark_as_advanced(BLT_VERSION) + message(STATUS "BLT Version: ${BLT_VERSION}") + + set(BLT_LOADED True) + mark_as_advanced(BLT_LOADED) + + set( BLT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "" FORCE ) + + # if an explicit build dir was not specified, set a default. + if( NOT BLT_BUILD_DIR ) + set( BLT_BUILD_DIR ${PROJECT_BINARY_DIR}/blt CACHE PATH "" FORCE ) + endif() + + ################################ + # Prevent in-source builds + ################################ + # Fail if someone tries to config an in-source build. + if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + message(FATAL_ERROR "In-source builds are not supported. Please remove the " + "CMakeFiles directory and CMakeCache.txt from the 'src' " + "dir and configure an out-of-source build in another " + "directory.") + endif() + + ################################# + # Show CMake info right out of the gate + ################################ + message(STATUS "CMake Version: ${CMAKE_VERSION}") + + if(${CMAKE_VERSION} VERSION_LESS 3.8.0) + message("*************************************") + message("* Unsupported version of CMake detected.") + message("* BLT requires CMake 3.8 or above.") + message("* Some BLT features may not work.") + message("*************************************") + endif() + + message(STATUS "CMake Executable: ${CMAKE_COMMAND}") + + + ################################ + # Setup build options and their default values + ################################ + include(${BLT_ROOT_DIR}/cmake/BLTOptions.cmake) + + ################################ + # CMake Policies + ################################ + # Support IN_LIST operator for if() + # Policy added in 3.3+ + if(POLICY CMP0057) + cmake_policy(SET CMP0057 NEW) + endif() + + # Policy to use _ROOT variable in find_ commands + # Policy added in 3.12+ + if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) + endif() + + # New turns relative target_sources() paths to absolute + # Policy added in 3.13+ + # NOTE: this will be deprecated eventually but NEW causes + # problems in header only libraries, OLD keeps current behavior + if(POLICY CMP0076) + cmake_policy(SET CMP0076 OLD) + endif() + + ################################ + # Invoke CMake Fortran setup + # if ENABLE_FORTRAN == ON + ################################ + if(ENABLE_FORTRAN) + enable_language(Fortran) + endif() + + ################################ + # Enable ctest support + ################################ + if(ENABLE_TESTS) + enable_testing() + endif() + + ################################ + # Enable cmake generator folder feature + ################################ + if(ENABLE_FOLDERS) + set_property(GLOBAL PROPERTY USE_FOLDERS ON) + endif() + + + ################################ + # Enable cmake compilation database feature + ################################ + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + + ################################ + # Macros + ################################ + include(${BLT_ROOT_DIR}/cmake/BLTMacros.cmake) + + ################################ + # Standard TPL support + ################################ + include(${BLT_ROOT_DIR}/cmake/thirdparty/SetupThirdParty.cmake) + + ################################ + # Git related Macros + ################################ + if (Git_FOUND) + include(${BLT_ROOT_DIR}/cmake/BLTGitMacros.cmake) + endif() + + ################################ + # Setup docs targets + ################################ + include(${BLT_ROOT_DIR}/cmake/SetupDocs.cmake) + + ################################ + # Setup source checks + ################################ + include(${BLT_ROOT_DIR}/cmake/SetupCodeChecks.cmake) + + ################################ + # Standard Build Layout + ################################ + + # Set the path where all the libraries will be stored + set(LIBRARY_OUTPUT_PATH + ${PROJECT_BINARY_DIR}/lib + CACHE PATH + "Directory where compiled libraries will go in the build tree") + + # Set the path where all the installed executables will go + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/bin + CACHE PATH + "Directory where executables will go in the build tree") + + # Set the path were all test executables will go + set(TEST_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/tests + CACHE PATH + "Directory where test executables will go in the build tree") + + # Set the path were all example test executables will go + set(EXAMPLE_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/examples + CACHE PATH + "Directory where example executables will go in the build tree") + + # Set the Fortran module directory + set(CMAKE_Fortran_MODULE_DIRECTORY + ${PROJECT_BINARY_DIR}/lib/fortran + CACHE PATH + "Directory where all Fortran modules will go in the build tree") + + # Mark as advanced + mark_as_advanced( + LIBRARY_OUTPUT_PATH + CMAKE_RUNTIME_OUTPUT_DIRECTORY + CMAKE_Fortran_MODULE_DIRECTORY) + + ################################ + # Global variables needed by BLT + # + ################################ + set(BLT_C_FILE_EXTS ".cpp" ".hpp" ".cxx" ".hxx" ".c" ".h" ".cc" ".hh" ".inl" ".cu" + CACHE STRING "List of known file extensions used for C/CXX sources") + set(BLT_Fortran_FILE_EXTS ".F" ".f" ".f90" ".F90" + CACHE STRING "List of known file extensions used for Fortran sources") + + + ################################ + # Setup compiler options + # (must be included after HEADER_INCLUDES_DIRECTORY and MPI variables are set) + ################################ + include(${BLT_ROOT_DIR}/cmake/SetupCompilerOptions.cmake) + + ################################ + # Setup code metrics - + # profiling, code coverage, etc. + # (must be included after SetupCompilerOptions) + ################################ + include(${BLT_ROOT_DIR}/cmake/SetupCodeMetrics.cmake) + + ################################ + # builtin third party libs used by BLT + ################################ + add_subdirectory(${BLT_ROOT_DIR}/thirdparty_builtin ${BLT_BUILD_DIR}/thirdparty_builtin) + + ################################ + # BLT smoke tests + ################################ + if(ENABLE_TESTS) + add_subdirectory(${BLT_ROOT_DIR}/tests/smoke ${BLT_BUILD_DIR}/tests/smoke) + endif() + +endif() # only load BLT once! diff --git a/tpl/RAJA/blt/appveyor.yml b/tpl/RAJA/blt/appveyor.yml new file mode 100644 index 000000000..035f49af6 --- /dev/null +++ b/tpl/RAJA/blt/appveyor.yml @@ -0,0 +1,156 @@ +environment: + matrix: + - CMAKE_GENERATOR: "Visual Studio 14 2015" + CONFIG: Release + BUILD_SHARED_LIBS: ON + ENABLE_GMOCK: OFF + ENABLE_BENCHMARKS: OFF + ENABLE_MPI: OFF + MPI_HOME: "C:/Program Files (x86)/Microsoft SDKs/MPI" + - CMAKE_GENERATOR: "Visual Studio 14 2015" + CONFIG: Release + BUILD_SHARED_LIBS: OFF + ENABLE_GMOCK: ON + ENABLE_BENCHMARKS: ON + ENABLE_MPI: OFF + MPI_HOME: "C:/Program Files (x86)/Microsoft SDKs/MPI" + - CMAKE_GENERATOR: "Visual Studio 14 2015" + CONFIG: Release + BUILD_SHARED_LIBS: OFF + ENABLE_GMOCK: OFF + ENABLE_BENCHMARKS: OFF + ENABLE_MPI: ON + MPI_HOME: "C:/Program Files (x86)/Microsoft SDKs/MPI" + +init: + # line endings magic + - git config --global core.autocrlf input + # set git user info + - git config --global user.email "bltdev@llnl.gov" + - git config --global user.name "BLT Robot" + +install: + # Install MS-MPI + - ps: Start-FileDownload 'https://download.microsoft.com/download/B/2/E/B2EB83FE-98C2-4156-834A-E1711E6884FB/MSMpiSetup.exe' + - MSMpiSetup.exe -unattend + - set PATH=C:\Program Files\Microsoft MPI\Bin;%PATH% + + # Install MS-MPI SDK + - ps: Start-FileDownload 'https://download.microsoft.com/download/B/2/E/B2EB83FE-98C2-4156-834A-E1711E6884FB/msmpisdk.msi' + - msmpisdk.msi /passive + + # Install CMake 3.9 + ############################################################################ + #- ps: Start-FileDownload 'https://cmake.org/files/v3.9/cmake-3.9.6-win64-x64.msi' + #- ps: Start-FileDownload 'http://portal.nersc.gov/project/visit/cmake/cmake-3.9.6-win64-x64.msi' + #- cmake-3.9.6-win64-x64.msi /passive + #- set PATH=C:\Program Files\CMake\bin;%PATH% + - cmake --version + +before_build: + # remove some noisy warnings from Xamarin + - del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" + # copy blt into blt-test and setup to build there + - ps: cd .. + - mkdir build + - cp -r blt\tests\internal blt-test + # create a git repo for blt-test to test the git macros + - cd blt-test + - git init + - git add -A + - git commit -a -m "Initial Commit" + - git checkout -b test-branch + - git tag test-tag + - cd ..\build + +build_script: + ######################################################### + ######################################################### + # blt-test + ######################################################### + ######################################################### + # configure + - echo Running cmake ... + - cmake -G "%CMAKE_GENERATOR%" ^ + -D BLT_SOURCE_DIR:PATH="c:\projects\blt" ^ + -D BUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ^ + -D ENABLE_GMOCK=%ENABLE_GMOCK% ^ + -D ENABLE_BENCHMARKS=%ENABLE_BENCHMARKS% ^ + -D ENABLE_OPENMP=ON ^ + -D BLT_CXX_STD:STRING=c++11 ^ + -D ENABLE_MPI=%ENABLE_MPI% ^ + -D MPI_C_INCLUDE_PATH:PATH="%MPI_HOME%/Include" ^ + -D MPI_C_LIBRARIES:PATH="%MPI_HOME%/Lib/x86/msmpi.lib" ^ + -D MPI_CXX_INCLUDE_PATH:PATH="%MPI_HOME%/Include" ^ + -D MPI_CXX_LIBRARIES:PATH="%MPI_HOME%/Lib/x86/msmpi.lib" ^ + -D TEST_GIT_MACROS=ON ^ + ..\blt-test + - cd .. + #build + - echo Building blt-test ... + - cmake --build build --config %CONFIG% + # run our tests + - cmake -E env CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --config %CONFIG% --target RUN_TESTS + - cd .. + ######################################################### + ######################################################### + # tutorial tests + ######################################################### + ######################################################### + ######################################################### + # test docs/tutorial/blank_project + ######################################################### + - mkdir build-tutorial_blank_project + - cd build-tutorial_blank_project + - echo Running cmake ... + - cmake -G "%CMAKE_GENERATOR%" ^ + -D BLT_SOURCE_DIR:PATH="c:\projects\blt" ^ + -D BUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ^ + -D ENABLE_GMOCK=%ENABLE_GMOCK% ^ + -D ENABLE_BENCHMARKS=%ENABLE_BENCHMARKS% ^ + -D ENABLE_OPENMP=ON ^ + -D ENABLE_MPI=%ENABLE_MPI% ^ + -D MPI_C_INCLUDE_PATH:PATH="%MPI_HOME%/Include" ^ + -D MPI_C_LIBRARIES:PATH="%MPI_HOME%/Lib/x86/msmpi.lib" ^ + -D MPI_CXX_INCLUDE_PATH:PATH="%MPI_HOME%/Include" ^ + -D MPI_CXX_LIBRARIES:PATH="%MPI_HOME%/Lib/x86/msmpi.lib" ^ + c:\projects\blt\docs\tutorial\blank_project + - cd .. + #build + - echo Building Tutorial Blank Project ... + - cmake --build build-tutorial_blank_project --config %CONFIG% + # run our tests + - cmake -E env CTEST_OUTPUT_ON_FAILURE=1 cmake --build build-tutorial_blank_project --config %CONFIG% --target RUN_TESTS + - cd .. + ######################################################### + # test docs/tutorial/calc_pi + ######################################################### + - mkdir build-tutorial_calc_pi + - cd build-tutorial_calc_pi + - cmake -G "%CMAKE_GENERATOR%" ^ + -D BLT_SOURCE_DIR:PATH="c:\projects\blt" ^ + -D BUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ^ + -D ENABLE_GMOCK=%ENABLE_GMOCK% ^ + -D ENABLE_BENCHMARKS=%ENABLE_BENCHMARKS% ^ + -D ENABLE_OPENMP=ON ^ + -D ENABLE_MPI=%ENABLE_MPI% ^ + -D MPI_C_INCLUDE_PATH:PATH="%MPI_HOME%/Include" ^ + -D MPI_C_LIBRARIES:PATH="%MPI_HOME%/Lib/x86/msmpi.lib" ^ + -D MPI_CXX_INCLUDE_PATH:PATH="%MPI_HOME%/Include" ^ + -D MPI_CXX_LIBRARIES:PATH="%MPI_HOME%/Lib/x86/msmpi.lib" ^ + c:\projects\blt\docs\tutorial\calc_pi + - cd .. + #build + - echo Building Tutorial Calc Pi ... + - cmake --build build-tutorial_calc_pi --config %CONFIG% + # run our tests + - cmake -E env CTEST_OUTPUT_ON_FAILURE=1 cmake --build build-tutorial_calc_pi --config %CONFIG% --target RUN_TESTS + - cd .. + +on_failure: + - ps: | + Write-Output "CMakeOutput.log" + cat c:\projects\build\CMakeFiles\CMakeOutput.log + Write-Output "CMakeError.log" + cat c:\projects\build\CMakeFiles\CMakeError.log + diff --git a/tpl/RAJA/blt/cmake/BLTGitMacros.cmake b/tpl/RAJA/blt/cmake/BLTGitMacros.cmake new file mode 100644 index 000000000..d6024f6f6 --- /dev/null +++ b/tpl/RAJA/blt/cmake/BLTGitMacros.cmake @@ -0,0 +1,250 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +##------------------------------------------------------------------------------ +## blt_git( SOURCE_DIR +## GIT_COMMAND +## OUTPUT_VARIABLE +## RETURN_CODE +## [QUIET] ) +## +## Runs the supplied git command on the given Git repository. +##------------------------------------------------------------------------------ +macro(blt_git) + + set(options) + set(singleValueArgs SOURCE_DIR OUTPUT_VARIABLE RETURN_CODE) + set(multiValueArgs GIT_COMMAND ) + + ## parse macro arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + ## ensure required arguments are supplied + if ( NOT DEFINED arg_SOURCE_DIR ) + message(FATAL_ERROR "SOURCE_DIR is a required argument to blt_git()") + endif() + + if ( NOT DEFINED arg_GIT_COMMAND ) + message(FATAL_ERROR "GIT_COMMAND is a required argument to blt_git()") + endif() + + if ( NOT DEFINED arg_OUTPUT_VARIABLE ) + message(FATAL_ERROR "OUTPUT_VARIABLE is a required argument to blt_git()") + endif() + + if ( NOT DEFINED arg_RETURN_CODE ) + message(FATAL_ERROR "RETURN_CODE is a required argument to blt_git()") + endif() + + ## check arguments + if (GIT_FOUND) + + ## assemble the Git command + set(git_cmd "${GIT_EXECUTABLE}" "${arg_GIT_COMMAND}" ) + + ## run it + execute_process( COMMAND + ${git_cmd} + WORKING_DIRECTORY + "${arg_SOURCE_DIR}" + RESULT_VARIABLE + ${arg_RETURN_CODE} + OUTPUT_VARIABLE + ${arg_OUTPUT_VARIABLE} + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + + else( ) + message( FATAL_ERROR "Git is not found. Git is required for blt_git()") + endif() + +endmacro(blt_git) + + +##------------------------------------------------------------------------------ +## blt_is_git_repo( OUTPUT_STATE +## [SOURCE_DIR ] ) +## +## Checks if we are working with a valid Git repository. +##------------------------------------------------------------------------------ +macro(blt_is_git_repo) + + set(options) + set(singleValueArgs OUTPUT_STATE SOURCE_DIR ) + set(multiValueArgs) + + ## parse macro arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + ## ensure required variables are supplied + if ( NOT DEFINED arg_OUTPUT_STATE ) + message(FATAL_ERROR "OUTPUT_STATE is a required argument to blt_is_git_repo") + endif() + + ## check if SOURCE_DIR was supplied + if ( NOT DEFINED arg_SOURCE_DIR ) + set(git_dir ${CMAKE_CURRENT_SOURCE_DIR}) + else() + set(git_dir ${arg_SOURCE_DIR}) + endif() + + blt_git( SOURCE_DIR ${git_dir} + GIT_COMMAND rev-parse --show-toplevel + OUTPUT_VARIABLE tmp + RETURN_CODE rc + ) + + if ( NOT ${rc} EQUAL 0 ) + ## rev-parse failed, this is not a git repo + set( ${arg_OUTPUT_STATE} FALSE ) + else() + set( ${arg_OUTPUT_STATE} TRUE ) + endif() + +endmacro(blt_is_git_repo) + +##------------------------------------------------------------------------------ +## blt_git_tag( OUTPUT_TAG +## RETURN_CODE +## [SOURCE_DIR ] +## [ON_BRANCH ] ) +## +## Returns the latest tag on a corresponding Git repository. +##------------------------------------------------------------------------------ +macro(blt_git_tag) + + set(options) + set(singleValueArgs SOURCE_DIR ON_BRANCH OUTPUT_TAG RETURN_CODE ) + set(multiValueArgs) + + ## parse macro arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + ## ensure required arguments are supplied + if ( NOT DEFINED arg_OUTPUT_TAG ) + message(FATAL_ERROR "OUTPUT_TAG is a required argument to blt_git_tag") + endif() + + if ( NOT DEFINED arg_RETURN_CODE ) + message(FATAL_ERROR "RETURN_CODE is a required argument to blt_git_tag") + endif() + + ## git command to execute + if ( NOT DEFINED arg_ON_BRANCH ) + set(git_cmd describe --tags ) + else() + set(git_cmd describe --tags ${arg_ON_BRANCH} ) + endif() + + ## set working directory + if ( NOT DEFINED arg_SOURCE_DIR} ) + set(git_dir ${CMAKE_CURRENT_SOURCE_DIR}) + else() + set(git_dir ${arg_SOURCE_DIR}) + endif() + + blt_git( SOURCE_DIR ${git_dir} + GIT_COMMAND ${git_cmd} + OUTPUT_VARIABLE ${arg_OUTPUT_TAG} + RETURN_CODE ${arg_RETURN_CODE} + ) + +endmacro(blt_git_tag) + +##------------------------------------------------------------------------------ +## blt_git_branch( BRANCH_NAME +## RETURN_CODE +## [SOURCE_DIR ] ) +## +## Returns the name of the active branch in the checkout space. +##------------------------------------------------------------------------------ +macro(blt_git_branch) + + set(options) + set(singleValueArgs SOURCE_DIR BRANCH_NAME RETURN_CODE) + set(multiValueArgs) + + ## parse macro arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + ## ensure required arguments are supplied + if ( NOT DEFINED arg_BRANCH_NAME ) + message(FATAL_ERROR "BRANCH_NAME is a required argument to blt_git_branch" ) + endif() + + if ( NOT DEFINED arg_RETURN_CODE ) + message(FATAL_ERROR "RETURN_CODE is a required argument to blt_git_branch") + endif() + + ## set set working directory + if ( NOT DEFINED arg_SOURCE_DIR ) + set(git_dir ${CMAKE_CURRENT_SOURCE_DIR}) + else() + set(git_dir ${arg_SOURCE_DIR}) + endif() + + blt_git( SOURCE_DIR ${git_dir} + GIT_COMMAND rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE ${arg_BRANCH_NAME} + RETURN_CODE ${arg_RETURN_CODE} + ) + +endmacro(blt_git_branch) + +##------------------------------------------------------------------------------ +## blt_git_hashcode( HASHCODE +## RETURN_CODE +## [SOURCE_DIR ] +## [ON_BRANCH ] +## ) +## +## Returns the SHA-1 hashcode at the tip of a branch. +##------------------------------------------------------------------------------ +macro(blt_git_hashcode) + + set(options) + set(singleValueArgs SOURCE_DIR HASHCODE ON_BRANCH RETURN_CODE) + set(multiValueArgs) + + ## parse macro arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + ## ensure required arguments are supplied + if ( NOT DEFINED arg_HASHCODE ) + message(FATAL_ERROR "HASHCODE is a required argument to blt_git_hashcode" ) + endif() + + if ( NOT DEFINED arg_RETURN_CODE ) + message(FATAL_ERROR "RETURN_CODE is a required argument to blt_git_hashcode" ) + endif() + + ## set working directory + if ( NOT DEFINED arg_SOURCE_DIR ) + set(git_dir ${CMAKE_CURRENT_SOURCE_DIR}) + else() + set(git_dir ${arg_SOURCE_DIR}) + endif() + + ## set target ref + if ( NOT DEFINED arg_ON_BRANCH ) + set(git_cmd rev-parse --short HEAD ) + else() + set(git_cmd rev-parse --short ${arg_ON_BRANCH} ) + endif() + + blt_git( SOURCE_DIR ${git_dir} + GIT_COMMAND ${git_cmd} + OUTPUT_VARIABLE ${arg_HASHCODE} + RETURN_CODE ${arg_RETURN_CODE} + ) + +endmacro(blt_git_hashcode) diff --git a/tpl/RAJA/blt/cmake/BLTMacros.cmake b/tpl/RAJA/blt/cmake/BLTMacros.cmake new file mode 100644 index 000000000..b040162ac --- /dev/null +++ b/tpl/RAJA/blt/cmake/BLTMacros.cmake @@ -0,0 +1,1109 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +include(${BLT_ROOT_DIR}/cmake/BLTPrivateMacros.cmake) + +##------------------------------------------------------------------------------ +## blt_list_append( TO ELEMENTS [ ...] IF ) +## +## Appends elements to a list if the specified bool evaluates to true. +##------------------------------------------------------------------------------ +macro(blt_list_append) + + set(options) + set(singleValueArgs TO IF) + set(multiValueArgs ELEMENTS ) + + # parse macro arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Sanity checks + if( NOT DEFINED arg_TO ) + message(FATAL_ERROR "blt_list_append() requires a TO argument") + endif() + + if ( NOT DEFINED arg_ELEMENTS ) + message(FATAL_ERROR "blt_list_append() requires ELEMENTS to be specified" ) + endif() + + # determine if we should add the elements to the list + set(_shouldAdd FALSE ) + set(_listVar "${ARGN}") # convert macro arguments to list variable + if("IF" IN_LIST _listVar) + set(_shouldAdd ${arg_IF}) # use IF condition, when present + else() + set(_shouldAdd TRUE) # otherwise, always add the elements + endif() + + # append if + if ( ${_shouldAdd} ) + list( APPEND ${arg_TO} ${arg_ELEMENTS} ) + endif() + + unset(_shouldAdd) + unset(_listVar) + +endmacro(blt_list_append) + + +##------------------------------------------------------------------------------ +## blt_list_remove_duplicates( TO ) +## +## Removes duplicate elements from the given TO list. +##------------------------------------------------------------------------------ +macro(blt_list_remove_duplicates) + + set(options) + set(singleValueArgs TO ) + set(multiValueArgs ) + + # parse macro arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Sanity checks + if( NOT DEFINED arg_TO ) + message(FATAL_ERROR "blt_list_append() requires a TO argument") + endif() + + if ( ${arg_TO} ) + list(REMOVE_DUPLICATES ${arg_TO} ) + endif() + +endmacro(blt_list_remove_duplicates) + + +##------------------------------------------------------------------------------ +## blt_add_target_definitions(TO +## SCOPE +## TARGET_DEFINITIONS [FOO [BAR ...]]) +## +## Adds pre-processor definitions to the given target. +##------------------------------------------------------------------------------ +macro(blt_add_target_definitions) + + set(options) + set(singleValueArgs TO SCOPE) + set(multiValueArgs TARGET_DEFINITIONS) + + # Parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Sanity checks + if(NOT TARGET ${arg_TO}) + message(FATAL_ERROR "Target ${arg_TO} passed to blt_add_target_definitions is not a valid cmake target") + endif() + + blt_determine_scope(TARGET ${arg_TO} SCOPE "${arg_SCOPE}" OUT _scope) + + # Only add the flag if it is not empty + string(STRIP "${arg_TARGET_DEFINITIONS}" _strippedDefs) + if(NOT "${_strippedDefs}" STREQUAL "") + target_compile_definitions(${arg_TO} ${_scope} ${_strippedDefs}) + endif() + + unset(_scope) + unset(_strippedDefs) + +endmacro(blt_add_target_definitions) + + +##------------------------------------------------------------------------------ +## blt_add_target_compile_flags(TO +## SCOPE +## FLAGS [FOO [BAR ...]]) +## +## Adds compiler flags to a target (library, executable or interface) by +## appending to the target's existing flags. +##------------------------------------------------------------------------------ +macro(blt_add_target_compile_flags) + + set(options) + set(singleValuedArgs TO SCOPE) + set(multiValuedArgs FLAGS) + + # Parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValuedArgs}" "${multiValuedArgs}" ${ARGN} ) + + # Sanity checks + if(NOT TARGET ${arg_TO}) + message(FATAL_ERROR "Target ${arg_TO} passed to blt_add_target_compile_flags is not a valid cmake target") + endif() + + blt_determine_scope(TARGET ${arg_TO} SCOPE "${arg_SCOPE}" OUT _scope) + + # Only add the flag if it is not empty + string(STRIP "${arg_FLAGS}" _strippedFlags) + if(NOT "${_strippedFlags}" STREQUAL "") + target_compile_options(${arg_TO} ${_scope} ${_strippedFlags}) + endif() + + unset(_strippedFlags) + unset(_scope) + +endmacro(blt_add_target_compile_flags) + + +##------------------------------------------------------------------------------ +## blt_set_target_folder(TARGET FOLDER ) +## +## Sets the folder property of cmake target to . +##------------------------------------------------------------------------------ +macro(blt_set_target_folder) + + set(options) + set(singleValuedArgs TARGET FOLDER) + set(multiValuedArgs) + + # Parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValuedArgs}" "${multiValuedArgs}" ${ARGN} ) + + # Sanity checks + if(NOT DEFINED arg_TARGET) + message(FATAL_ERROR "TARGET is a required parameter for blt_set_target_folder macro") + endif() + + if(NOT TARGET ${arg_TARGET}) + message(FATAL_ERROR "Target ${arg_TARGET} passed to blt_set_target_folder is not a valid cmake target") + endif() + + if(NOT DEFINED arg_FOLDER) + message(FATAL_ERROR "FOLDER is a required parameter for blt_set_target_folder macro") + endif() + + # Set the folder property for this target + if(ENABLE_FOLDERS AND NOT "${arg_FOLDER}" STREQUAL "") + set_property(TARGET ${arg_TARGET} PROPERTY FOLDER "${arg_FOLDER}") + endif() + +endmacro(blt_set_target_folder) + + +##------------------------------------------------------------------------------ +## blt_add_target_link_flags (TO +## SCOPE +## FLAGS [FOO [BAR ...]]) +## +## Adds linker flags to a target by appending to the target's existing flags. +##------------------------------------------------------------------------------ +macro(blt_add_target_link_flags) + + set(options) + set(singleValuedArgs TO SCOPE) + set(multiValuedArgs FLAGS) + + ## parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValuedArgs}" "${multiValuedArgs}" ${ARGN} ) + + set(_flags ${arg_FLAGS}) + # Convert rpath flag if linking with CUDA + if (CUDA_LINK_WITH_NVCC) + string(REPLACE "-Wl,-rpath," "-Xlinker -rpath -Xlinker " + _flags "${_flags}") + endif() + + # Only add the flag if it is not empty + if(NOT "${arg_FLAGS}" STREQUAL "") + if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0" ) + # In CMake 3.13+, LINK_FLAGS was converted to LINK_OPTIONS. + # This now supports generator expressions and scoping but expects a list + # not a string + blt_determine_scope(TARGET ${arg_TO} SCOPE "${arg_SCOPE}" OUT _scope) + + # Note: "SHELL:"" causes the flags to be not de-duplicated and parsed with + # separate_arguments + if(NOT "${arg_FLAGS}" MATCHES SHELL:) + target_link_options(${arg_TO} ${_scope} SHELL:${arg_FLAGS}) + else() + target_link_options(${arg_TO} ${_scope} ${arg_FLAGS}) + endif() + else() + # In CMake <= 3.12, there is no target_link_flags or target_link_options command + get_target_property(_link_flags ${arg_TO} LINK_FLAGS) + if(NOT _link_flags) + set(_link_flags "") + endif() + set(_link_flags "${_flags} ${_link_flags}") + + # Convert from a CMake ;-list to a string + string (REPLACE ";" " " _link_flags_str "${_link_flags}") + set_target_properties(${arg_TO} + PROPERTIES LINK_FLAGS "${_link_flags_str}") + endif() + endif() + + unset(_flags) + unset(_link_flags) + unset(_link_flags_str) + unset(_scope) + +endmacro(blt_add_target_link_flags) + + +##------------------------------------------------------------------------------ +## blt_register_library( NAME +## DEPENDS_ON [dep1 [dep2 ...]] +## INCLUDES [include1 [include2 ...]] +## TREAT_INCLUDES_AS_SYSTEM [ON|OFF] +## FORTRAN_MODULES [ path1 [ path2 ..]] +## LIBRARIES [lib1 [lib2 ...]] +## COMPILE_FLAGS [ flag1 [ flag2 ..]] +## LINK_FLAGS [ flag1 [ flag2 ..]] +## DEFINES [def1 [def2 ...]] ) +## +## Registers a library to the project to ease use in other BLT macro calls. +##------------------------------------------------------------------------------ +macro(blt_register_library) + + set(singleValueArgs NAME OBJECT TREAT_INCLUDES_AS_SYSTEM) + set(multiValueArgs INCLUDES + DEPENDS_ON + FORTRAN_MODULES + LIBRARIES + COMPILE_FLAGS + LINK_FLAGS + DEFINES ) + + ## parse the arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + string(TOUPPER ${arg_NAME} uppercase_name) + + set(BLT_${uppercase_name}_IS_REGISTERED_LIBRARY TRUE CACHE BOOL "" FORCE) + + if( arg_DEPENDS_ON ) + set(BLT_${uppercase_name}_DEPENDS_ON ${arg_DEPENDS_ON} CACHE STRING "" FORCE) + mark_as_advanced(BLT_${uppercase_name}_DEPENDS_ON) + endif() + + if( arg_INCLUDES ) + set(BLT_${uppercase_name}_INCLUDES ${arg_INCLUDES} CACHE STRING "" FORCE) + mark_as_advanced(BLT_${uppercase_name}_INCLUDES) + endif() + + if( ${arg_OBJECT} ) + set(BLT_${uppercase_name}_IS_OBJECT_LIBRARY TRUE CACHE BOOL "" FORCE) + else() + set(BLT_${uppercase_name}_IS_OBJECT_LIBRARY FALSE CACHE BOOL "" FORCE) + endif() + mark_as_advanced(BLT_${uppercase_name}_IS_OBJECT_LIBRARY) + + if( ${arg_TREAT_INCLUDES_AS_SYSTEM} ) + set(BLT_${uppercase_name}_TREAT_INCLUDES_AS_SYSTEM TRUE CACHE BOOL "" FORCE) + else() + set(BLT_${uppercase_name}_TREAT_INCLUDES_AS_SYSTEM FALSE CACHE BOOL "" FORCE) + endif() + mark_as_advanced(BLT_${uppercase_name}_TREAT_INCLUDES_AS_SYSTEM) + + if( ENABLE_FORTRAN AND arg_FORTRAN_MODULES ) + set(BLT_${uppercase_name}_FORTRAN_MODULES ${arg_INCLUDES} CACHE STRING "" FORCE) + mark_as_advanced(BLT_${uppercase_name}_FORTRAN_MODULES) + endif() + + if( arg_LIBRARIES ) + set(BLT_${uppercase_name}_LIBRARIES ${arg_LIBRARIES} CACHE STRING "" FORCE) + else() + # This prevents cmake from falling back on adding -l + # to the command line for BLT registered libraries which are not + # actual CMake targets + set(BLT_${uppercase_name}_LIBRARIES "BLT_NO_LIBRARIES" CACHE STRING "" FORCE) + endif() + mark_as_advanced(BLT_${uppercase_name}_LIBRARIES) + + if( arg_COMPILE_FLAGS ) + set(BLT_${uppercase_name}_COMPILE_FLAGS "${arg_COMPILE_FLAGS}" CACHE STRING "" FORCE) + mark_as_advanced(BLT_${uppercase_name}_COMPILE_FLAGS) + endif() + + if( arg_LINK_FLAGS ) + set(BLT_${uppercase_name}_LINK_FLAGS "${arg_LINK_FLAGS}" CACHE STRING "" FORCE) + mark_as_advanced(BLT_${uppercase_name}_LINK_FLAGS) + endif() + + if( arg_DEFINES ) + set(BLT_${uppercase_name}_DEFINES ${arg_DEFINES} CACHE STRING "" FORCE) + mark_as_advanced(BLT_${uppercase_name}_DEFINES) + endif() + +endmacro(blt_register_library) + + +##------------------------------------------------------------------------------ +## blt_add_library( NAME +## SOURCES [source1 [source2 ...]] +## HEADERS [header1 [header2 ...]] +## INCLUDES [dir1 [dir2 ...]] +## DEFINES [define1 [define2 ...]] +## DEPENDS_ON [dep1 ...] +## OUTPUT_NAME [name] +## OUTPUT_DIR [dir] +## SHARED [TRUE | FALSE] +## OBJECT [TRUE | FALSE] +## CLEAR_PREFIX [TRUE | FALSE] +## FOLDER [name]) +## +## Adds a library target, called , to be built from the given sources. +##------------------------------------------------------------------------------ +macro(blt_add_library) + + set(options) + set(singleValueArgs NAME OUTPUT_NAME OUTPUT_DIR HEADERS_OUTPUT_SUBDIR SHARED OBJECT CLEAR_PREFIX FOLDER) + set(multiValueArgs SOURCES HEADERS INCLUDES DEFINES DEPENDS_ON) + + # parse the arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Sanity checks + if( "${arg_NAME}" STREQUAL "" ) + message(FATAL_ERROR "blt_add_library() must be called with argument NAME ") + endif() + + if (NOT arg_SOURCES AND NOT arg_HEADERS ) + message(FATAL_ERROR "blt_add_library(NAME ${arg_NAME} ...) called with no given sources or headers") + endif() + + if (DEFINED arg_OBJECT AND arg_OBJECT) + if (DEFINED arg_SHARED AND arg_SHARED) + message(FATAL_ERROR "blt_add_library(NAME ${arg_NAME} ...) cannot be called with both OBJECT and SHARED set to TRUE.") + endif() + + if (NOT arg_SOURCES) + message(FATAL_ERROR "blt_add_library(NAME ${arg_NAME} ...) cannot create an object library with no sources.") + endif() + endif() + + if ( arg_SOURCES ) + # Determine type of library to build. STATIC by default and OBJECT takes + # precedence over global BUILD_SHARED_LIBS variable. + set(_build_shared_library ${BUILD_SHARED_LIBS}) + if( DEFINED arg_SHARED ) + set(_build_shared_library ${arg_SHARED}) + endif() + + if ( ${arg_OBJECT} ) + set(_lib_type "OBJECT") + blt_register_library( NAME ${arg_NAME} + DEPENDS_ON ${arg_DEPENDS_ON} + INCLUDES ${arg_INCLUDES} + OBJECT TRUE + DEFINES ${arg_DEFINES} ) + elseif ( ${_build_shared_library} ) + set(_lib_type "SHARED") + else() + set(_lib_type "STATIC") + endif() + + if (ENABLE_HIP) + blt_add_hip_library(NAME ${arg_NAME} + SOURCES ${arg_SOURCES} + HEADERS ${arg_HEADERS} + DEPENDS_ON ${arg_DEPENDS_ON} + LIBRARY_TYPE ${_lib_type} ) + else() + add_library( ${arg_NAME} ${_lib_type} ${arg_SOURCES} ${arg_HEADERS} ) + + if (ENABLE_CUDA AND NOT ENABLE_CLANG_CUDA) + blt_setup_cuda_target( + NAME ${arg_NAME} + SOURCES ${arg_SOURCES} + DEPENDS_ON ${arg_DEPENDS_ON} + LIBRARY_TYPE ${_lib_type}) + endif() + endif() + else() + # + # Header-only library support + # + foreach (_file ${arg_HEADERS}) + # Determine build location of headers + get_filename_component(_absolute ${_file} ABSOLUTE) + list(APPEND _build_headers ${_absolute}) + endforeach() + + #Note: This only works if both libraries are handled in the same directory, + # otherwise just don't include non-header files in your source list. + set_source_files_properties(${_build_headers} PROPERTIES HEADER_FILE_ONLY ON) + + add_library( ${arg_NAME} INTERFACE ) + target_sources( ${arg_NAME} INTERFACE + $) + endif() + + # Clear value of _have_fortran from previous calls + set(_have_fortran False) + + # Must tell fortran where to look for modules + # CMAKE_Fortran_MODULE_DIRECTORY is the location of generated modules + foreach (_file ${arg_SOURCES}) + get_source_file_property(_lang ${_file} LANGUAGE) + if(_lang STREQUAL Fortran) + set(_have_fortran TRUE) + endif() + endforeach() + if(_have_fortran) + target_include_directories(${arg_NAME} PRIVATE ${CMAKE_Fortran_MODULE_DIRECTORY}) + endif() + + blt_setup_target( NAME ${arg_NAME} + DEPENDS_ON ${arg_DEPENDS_ON} + OBJECT ${arg_OBJECT}) + + if ( arg_INCLUDES ) + if (NOT arg_SOURCES ) + # Header only + target_include_directories(${arg_NAME} INTERFACE ${arg_INCLUDES}) + else() + target_include_directories(${arg_NAME} PUBLIC ${arg_INCLUDES}) + endif() + endif() + + if ( arg_DEFINES ) + target_compile_definitions(${arg_NAME} PUBLIC ${arg_DEFINES}) + endif() + + if ( arg_OUTPUT_DIR ) + set_target_properties(${arg_NAME} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${arg_OUTPUT_DIR} ) + endif() + + if ( arg_OUTPUT_NAME ) + set_target_properties(${arg_NAME} PROPERTIES + OUTPUT_NAME ${arg_OUTPUT_NAME} ) + endif() + + if ( arg_CLEAR_PREFIX ) + set_target_properties(${arg_NAME} PROPERTIES + PREFIX "" ) + endif() + + # Handle optional FOLDER keyword for this target + if(ENABLE_FOLDERS AND DEFINED arg_FOLDER) + blt_set_target_folder(TARGET ${arg_NAME} FOLDER "${arg_FOLDER}") + endif() + + blt_update_project_sources( TARGET_SOURCES ${arg_SOURCES} ${arg_HEADERS}) + + if ( arg_SOURCES ) + # Don't clean header-only libraries because you would have to handle + # the white-list of properties that are allowed + blt_clean_target(TARGET ${arg_NAME}) + endif() + +endmacro(blt_add_library) + + +##------------------------------------------------------------------------------ +## blt_add_executable( NAME +## SOURCES [source1 [source2 ...]] +## INCLUDES [dir1 [dir2 ...]] +## DEFINES [define1 [define2 ...]] +## DEPENDS_ON [dep1 [dep2 ...]] +## OUTPUT_DIR [dir] +## FOLDER [name]) +## +## Adds an executable target, called , to be built from the given sources. +##------------------------------------------------------------------------------ +macro(blt_add_executable) + + set(options ) + set(singleValueArgs NAME OUTPUT_DIR FOLDER) + set(multiValueArgs SOURCES INCLUDES DEFINES DEPENDS_ON) + + # Parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Sanity checks + if( "${arg_NAME}" STREQUAL "" ) + message(FATAL_ERROR "blt_add_executable() must be called with argument NAME ") + endif() + + if (NOT arg_SOURCES ) + message(FATAL_ERROR "blt_add_executable(NAME ${arg_NAME} ...) given with no sources") + endif() + + if (ENABLE_HIP) + blt_add_hip_executable(NAME ${arg_NAME} + SOURCES ${arg_SOURCES} + DEPENDS_ON ${arg_DEPENDS_ON}) + else() + add_executable( ${arg_NAME} ${arg_SOURCES} ) + + if (ENABLE_CUDA AND NOT ENABLE_CLANG_CUDA) + blt_setup_cuda_target( + NAME ${arg_NAME} + SOURCES ${arg_SOURCES} + DEPENDS_ON ${arg_DEPENDS_ON}) + endif() + endif() + + # CMake wants to load with C++ if any of the libraries are C++. + # Force to load with Fortran if the first file is Fortran. + list(GET arg_SOURCES 0 _first) + get_source_file_property(_lang ${_first} LANGUAGE) + if(_lang STREQUAL Fortran) + if (NOT CUDA_LINK_WITH_NVCC) + set_target_properties( ${arg_NAME} PROPERTIES LINKER_LANGUAGE Fortran ) + endif() + target_include_directories(${arg_NAME} PRIVATE ${CMAKE_Fortran_MODULE_DIRECTORY}) + endif() + + blt_setup_target(NAME ${arg_NAME} + DEPENDS_ON ${arg_DEPENDS_ON} + OBJECT FALSE) + + # fix the openmp flags for fortran if needed + # NOTE: this needs to be called after blt_setup_target() + if (_lang STREQUAL Fortran) + blt_fix_fortran_openmp_flags( ${arg_NAME} ) + endif() + + if ( arg_INCLUDES ) + target_include_directories(${arg_NAME} PUBLIC ${arg_INCLUDES}) + endif() + + if ( arg_DEFINES ) + target_compile_definitions(${arg_NAME} PUBLIC ${arg_DEFINES}) + endif() + + # when using shared libs on windows, all runtime targets + # (dlls and exes) must live in the same dir + # so we do not set runtime_output_dir in this case + if ( arg_OUTPUT_DIR AND NOT (WIN32 AND BUILD_SHARED_LIBS) ) + set_target_properties(${arg_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${arg_OUTPUT_DIR} ) + endif() + + # Handle optional FOLDER keyword for this target + if(ENABLE_FOLDERS AND DEFINED arg_FOLDER) + blt_set_target_folder(TARGET ${arg_NAME} FOLDER "${arg_FOLDER}") + endif() + + blt_update_project_sources( TARGET_SOURCES ${arg_SOURCES} ) + + blt_clean_target(TARGET ${arg_NAME}) + +endmacro(blt_add_executable) + + +##------------------------------------------------------------------------------ +## blt_add_test( NAME [name] +## COMMAND [command] +## NUM_MPI_TASKS [n] +## NUM_OMP_THREADS [n] +## CONFIGURATIONS [config1 [config2...]]) +## +## Adds a test to the project. +##------------------------------------------------------------------------------ +macro(blt_add_test) + + set(options ) + set(singleValueArgs NAME NUM_MPI_TASKS NUM_OMP_THREADS) + set(multiValueArgs COMMAND CONFIGURATIONS) + + # Parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if ( NOT DEFINED arg_NAME ) + message(FATAL_ERROR "NAME is a required parameter to blt_add_test") + endif() + + if ( NOT DEFINED arg_COMMAND ) + message(FATAL_ERROR "COMMAND is a required parameter to blt_add_test") + endif() + + # Extract test directory and executable from arg_NAME and arg_COMMAND + if ( NOT TARGET ${arg_NAME} ) + # Handle cases where multiple tests are run against one executable + # the NAME will not be the target + list(GET arg_COMMAND 0 test_executable) + get_target_property(test_directory ${test_executable} RUNTIME_OUTPUT_DIRECTORY ) + else() + set(test_executable ${arg_NAME}) + get_target_property(test_directory ${arg_NAME} RUNTIME_OUTPUT_DIRECTORY ) + endif() + + # Append the test_directory to the test argument, accounting for multi-config generators + if(NOT CMAKE_CONFIGURATION_TYPES) + set(test_command ${test_directory}/${arg_COMMAND} ) + else() + list(INSERT arg_COMMAND 0 "$") + list(REMOVE_AT arg_COMMAND 1) + set(test_command ${arg_COMMAND}) + endif() + + # If configuration option ENABLE_WRAP_ALL_TESTS_WITH_MPIEXEC is set, + # ensure NUM_MPI_TASKS is at least one. This invokes the test + # through MPIEXEC. + if ( ENABLE_WRAP_ALL_TESTS_WITH_MPIEXEC AND NOT arg_NUM_MPI_TASKS ) + set( arg_NUM_MPI_TASKS 1 ) + endif() + + # Handle MPI + if( arg_NUM_MPI_TASKS ) + # Handle CMake changing MPIEXEC to MPIEXEC_EXECUTABLE + if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10.0" ) + set(_mpiexec ${MPIEXEC_EXECUTABLE}) + else() + set(_mpiexec ${MPIEXEC}) + endif() + + set(test_command ${_mpiexec} ${MPIEXEC_NUMPROC_FLAG} ${arg_NUM_MPI_TASKS} ${BLT_MPI_COMMAND_APPEND} ${test_command} ) + endif() + + add_test(NAME ${arg_NAME} + COMMAND ${test_command} + CONFIGURATIONS ${arg_CONFIGURATIONS}) + + # Handle OpenMP + if( arg_NUM_OMP_THREADS ) + set_property(TEST ${arg_NAME} + APPEND PROPERTY ENVIRONMENT OMP_NUM_THREADS=${arg_NUM_OMP_THREADS}) + endif() + +endmacro(blt_add_test) + + +##------------------------------------------------------------------------------ +## blt_add_benchmark( NAME [name] +## COMMAND [command] +## NUM_MPI_TASKS [n]) +## +## Adds a benchmark to the project. +##------------------------------------------------------------------------------ +macro(blt_add_benchmark) + + set(options) + set(singleValueArgs NAME NUM_MPI_TASKS) + set(multiValueArgs COMMAND) + + ## parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # The 'CONFIGURATIONS Benchmark' line excludes benchmarks + # from the general list of tests + blt_add_test( NAME ${arg_NAME} + COMMAND ${arg_COMMAND} + NUM_MPI_TASKS ${arg_NUM_MPI_TASKS} + CONFIGURATIONS Benchmark) + +endmacro(blt_add_benchmark) + + +##------------------------------------------------------------------------------ +## blt_append_custom_compiler_flag( +## FLAGS_VAR flagsVar (required) +## DEFAULT defaultFlag (optional) +## GNU gnuFlag (optional) +## CLANG clangFlag (optional) +## HCC hccFlag (optional) +## INTEL intelFlag (optional) +## XL xlFlag (optional) +## MSVC msvcFlag (optional) +## MSVC_INTEL msvcIntelFlag (optional) +## PGI pgiFlag (optional) +## CRAY crayFlag (optional)) +## +## Appends compiler-specific flags to a given variable of flags +##------------------------------------------------------------------------------ +macro(blt_append_custom_compiler_flag) + + set(options) + set(singleValueArgs FLAGS_VAR DEFAULT GNU CLANG HCC PGI INTEL XL MSVC MSVC_INTEL CRAY) + set(multiValueArgs) + + # Parse the arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Sanity check for required keywords + if(NOT DEFINED arg_FLAGS_VAR) + message( FATAL_ERROR "append_custom_compiler_flag macro requires FLAGS_VAR keyword and argument." ) + endif() + + # Set the desired flags based on the compiler family + # MSVC COMPILER FAMILY applies to C/C++ and Fortran + string( TOLOWER ${arg_FLAGS_VAR} lower_flag_var ) + if( DEFINED arg_MSVC_INTEL AND COMPILER_FAMILY_IS_MSVC_INTEL ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_MSVC_INTEL} " ) + elseif( DEFINED arg_MSVC AND (COMPILER_FAMILY_IS_MSVC OR COMPILER_FAMILY_IS_MSVC_INTEL) ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_MSVC} " ) + + #else, if we are setting a fortran flag, check against the fortran compiler family + elseif ( ENABLE_FORTRAN AND ${lower_flag_var} MATCHES "fortran" ) + if( DEFINED arg_CLANG AND Fortran_COMPILER_FAMILY_IS_CLANG ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_CLANG} " ) + elseif( DEFINED arg_XL AND Fortran_COMPILER_FAMILY_IS_XL ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_XL} " ) + elseif( DEFINED arg_INTEL AND Fortran_COMPILER_FAMILY_IS_INTEL ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_INTEL} " ) + elseif( DEFINED arg_PGI AND Fortran_COMPILER_FAMILY_IS_PGI ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_PGI} " ) + elseif( DEFINED arg_GNU AND Fortran_COMPILER_FAMILY_IS_GNU ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_GNU} " ) + elseif( DEFINED arg_CRAY AND Fortran_COMPILER_FAMILY_IS_CRAY ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_CRAY} " ) + elseif( DEFINED arg_DEFAULT ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_DEFAULT} ") + endif() + + #else, we are setting a non MSVC C/C++ flag, check against the C family. + else() + if( DEFINED arg_CLANG AND C_COMPILER_FAMILY_IS_CLANG ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_CLANG} " ) + elseif( DEFINED arg_XL AND C_COMPILER_FAMILY_IS_XL ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_XL} " ) + elseif( DEFINED arg_INTEL AND C_COMPILER_FAMILY_IS_INTEL ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_INTEL} " ) + elseif( DEFINED arg_PGI AND C_COMPILER_FAMILY_IS_PGI ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_PGI} " ) + elseif( DEFINED arg_GNU AND C_COMPILER_FAMILY_IS_GNU ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_GNU} " ) + elseif( DEFINED arg_CRAY AND C_COMPILER_FAMILY_IS_CRAY ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_CRAY} " ) + elseif( DEFINED arg_DEFAULT ) + set (${arg_FLAGS_VAR} "${${arg_FLAGS_VAR}} ${arg_DEFAULT} ") + endif() + endif() + unset(lower_flag_var) + +endmacro(blt_append_custom_compiler_flag) + + +##------------------------------------------------------------------------------ +## blt_find_libraries( FOUND_LIBS +## NAMES [libname1 [libname2 ...]] +## REQUIRED [TRUE (default) | FALSE ] +## PATHS [path1 [path2 ...]] ) +## +## This command is used to find a list of libraries. +##------------------------------------------------------------------------------ +macro(blt_find_libraries) + + set(options ) + set(singleValueArgs FOUND_LIBS REQUIRED ) + set(multiValueArgs NAMES PATHS ) + + ## parse the arguments + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if ( NOT DEFINED arg_FOUND_LIBS ) + message(FATAL_ERROR "The blt_find_libraries required parameter FOUND_LIBS specifies the list that found libraries will be appended to.") + endif() + + if ( NOT DEFINED arg_NAMES ) + message(FATAL_ERROR "The blt_find_libraries required parameter NAMES specifies the library names you are searching for.") + endif() + + if ( NOT DEFINED arg_PATHS ) + message(FATAL_ERROR "The blt_find_libraries required parameter PATHS specifies the paths to search for NAMES.") + endif() + + if ( NOT DEFINED arg_REQUIRED) + set(arg_REQUIRED TRUE) + endif() + + foreach( lib ${arg_NAMES} ) + unset( temp CACHE ) + find_library( temp NAMES ${lib} + PATHS ${arg_PATHS} + NO_DEFAULT_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_CMAKE_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + if( temp ) + list( APPEND ${arg_FOUND_LIBS} ${temp} ) + elseif (${arg_REQUIRED}) + message(FATAL_ERROR "blt_find_libraries required NAMES entry ${lib} not found. These are not the libs you are looking for.") + endif() + endforeach() + +endmacro(blt_find_libraries) + + +##------------------------------------------------------------------------------ +## blt_combine_static_libraries( NAME +## SOURCE_LIBS [lib1 ...] +## LIB_TYPE [STATIC,SHARED] +## LINK_PREPEND [] +## LINK_POSTPEND []) +## +## Adds a library target, called , to be built from the set of +## static libraries given in SOURCE_LIBS. +## +## The LINK_PREPEND argument will be prepended to the library on the link line, +## while the LINK_POSTPEND will be appended to the library on the link line. +## These values are defaulted to the appropriate values for CMAKE_HOST_APPLE and +## CMAKE_HOST_UNIX. +## +## Note: This macro does not currently work for Windows +## +##------------------------------------------------------------------------------ +macro(blt_combine_static_libraries) + + set(options ) + set(singleValueArgs NAME LINK_PREPEND LINK_POSTPEND LIB_TYPE ) + set(multiValueArgs SOURCE_LIBS ) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Sanity checks + if( "${arg_NAME}" STREQUAL "" ) + message(FATAL_ERROR "blt_combine_static_libraries() must be called with argument NAME ") + endif() + + if(TARGET ${arg_NAME}) + message(FATAL_ERROR "A target with the name ${arg_NAME} already exists!") + endif() + + if( NOT arg_SOURCE_LIBS ) + message(FATAL_ERROR "blt_combine_static_libraries(NAME ${arg_NAME} ...) called with no given source libraries") + endif() + + # Default linker flags if not given + if( NOT arg_LINK_PREPEND ) + if( CMAKE_HOST_APPLE ) + set( _link_prepend "-Wl,-force_load" ) + elseif( CMAKE_HOST_UNIX ) + set( _link_prepend "-Wl,--whole-archive" ) + elseif( CMAKE_HOST_WIN32 ) + # This used to work. Needs to be fixed + # set( _link_prepend "-WHOLEARCHIVE:" ) + message(FATAL_ERROR "blt_combine_static_libraries does not support ${CMAKE_HOST_SYSTEM}") + else() + message(FATAL_ERROR "blt_combine_static_libraries does not support ${CMAKE_HOST_SYSTEM}") + endif() + else() + set( _link_prepend ${arg_LINK_PREPEND}) + endif() + + if( NOT arg_LINK_POSTPEND ) + if( CMAKE_HOST_APPLE ) + set( _link_postpend "" ) + elseif( CMAKE_HOST_UNIX ) + set( _link_postpend "-Wl,--no-whole-archive" ) + elseif( CMAKE_HOST_WIN32 ) + set( _link_postpend "" ) + else() + message(FATAL_ERROR "blt_combine_static_libraries does not support ${CMAKE_HOST_SYSTEM}") + endif() + else() + set( _link_postpend ${arg_LINK_POSTPEND}) + endif() + + # Create link line that has all the libraries to combine on it + set( libLinkLine "" ) + foreach( lib ${arg_SOURCE_LIBS} ) + if( CMAKE_HOST_UNIX ) + list( APPEND libLinkLine ${_link_prepend} ${lib} ${_link_postpend} ) + elseif( CMAKE_HOST_WIN32 ) + list( APPEND libLinkLine "${_link_prepend}${lib}" ) + endif() + endforeach() + + # Decide if the created library is static or shared + if( ${arg_LIB_TYPE} STREQUAL "STATIC" ) + set( _lib_type STATIC ) + elseif( ${arg_LIB_TYPE} STREQUAL "SHARED" ) + set( _lib_type SHARED ) + else() + message(FATAL_ERROR "blt_combine_static_libraries(NAME ${arg_NAME} ...) LIB_TYPE must be SHARED OR STATIC") + endif() + + # Create new library with empty source file + add_library( ${arg_NAME} ${_lib_type} + ${BLT_ROOT_DIR}/tests/internal/src/combine_static_library_test/dummy.cpp) + + # Add the combined link line flag + target_link_libraries( ${arg_NAME} PRIVATE ${libLinkLine}) + + # Add the includes that should be inherited from themselves and their dependencies + set( interface_include_directories "" ) + set( interface_system_include_directories "" ) + foreach( source_lib ${arg_SOURCE_LIBS} ) + + get_target_property( source_lib_system_include_directories + ${source_lib} + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ) + + if( source_lib_system_include_directories ) + list( APPEND interface_system_include_directories + ${source_lib_system_include_directories} ) + endif() + + get_target_property( source_lib_include_directories + ${source_lib} + INTERFACE_INCLUDE_DIRECTORIES ) + + if( source_lib_include_directories ) + list( APPEND interface_include_directories ${source_lib_include_directories} ) + endif() + + # Get all includes from the dependencies of the libraries to be combined + get_target_property( interface_link_libs ${source_lib} INTERFACE_LINK_LIBRARIES ) + foreach( interface_link_lib ${interface_link_libs} ) + # Filter out non-CMake targets + if( TARGET ${interface_link_lib} ) + get_target_property( interface_link_lib_include_dir + ${interface_link_lib} + INTERFACE_INCLUDE_DIRECTORIES ) + + if( interface_link_lib_include_dir ) + list( APPEND interface_include_directories ${interface_link_lib_include_dir} ) + endif() + + get_target_property( interface_link_lib_system_include_dir + ${interface_link_lib} + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ) + + if( interface_link_lib_system_include_dir ) + list( APPEND interface_system_include_directories + ${interface_link_lib_system_include_dir} ) + endif() + + get_target_property( target_type ${interface_link_lib} TYPE ) + if( target_type STREQUAL "SHARED_LIBRARY" ) + target_link_libraries( ${arg_NAME} PUBLIC ${interface_link_lib} ) + endif () + + elseif( ${interface_link_lib} MATCHES ".so" OR + ${interface_link_lib} MATCHES ".dll" OR + ${interface_link_lib} MATCHES ".dylib" ) + # Add any shared libraries that were added by file name + target_link_libraries( ${arg_NAME} PUBLIC ${interface_link_lib} ) + endif() + endforeach() + endforeach() + + # Remove duplicates from the includes + blt_list_remove_duplicates(TO interface_include_directories ) + blt_list_remove_duplicates(TO interface_system_include_directories ) + + # Remove any system includes from the regular includes + foreach( include_dir ${interface_system_include_directories} ) + if( ${include_dir} IN_LIST interface_include_directories ) + list( REMOVE_ITEM interface_include_directories ${include_dir} ) + endif() + endforeach() + + target_include_directories( ${arg_NAME} INTERFACE + ${interface_include_directories} ) + + target_include_directories( ${arg_NAME} SYSTEM INTERFACE + ${interface_system_include_directories} ) + + unset( libLinkLine ) + unset( interface_include_directories ) + unset( interface_system_include_directories ) + unset( interface_link_lib_include_dir ) + unset( source_lib_include_directories ) + unset( _lib_type ) + unset( _link_prepend ) + unset( _link_postpend ) +endmacro(blt_combine_static_libraries) + + +##------------------------------------------------------------------------------ +## blt_print_target_properties(TARGET ) +## +## Prints out all properties of the given target. +##------------------------------------------------------------------------------ +macro(blt_print_target_properties) + + set(options) + set(singleValuedArgs TARGET) + set(multiValuedArgs) + + ## parse the arguments to the macro + cmake_parse_arguments(arg + "${options}" "${singleValuedArgs}" "${multiValuedArgs}" ${ARGN}) + + ## check for required arguments + if(NOT DEFINED arg_TARGET) + message(FATAL_ERROR "TARGET is a required parameter for the blt_print_target_properties macro") + endif() + + ## check if this is a valid cmake target of blt_registered target + set(_is_cmake_target FALSE) + if(TARGET ${arg_TARGET}) + set(_is_cmake_target TRUE) + message (STATUS "[${arg_TARGET} property] '${arg_TARGET}' is a cmake target") + endif() + + set(_is_blt_registered_target FALSE) + string(TOUPPER ${arg_TARGET} _target_upper) + if(BLT_${_target_upper}_IS_REGISTERED_LIBRARY) + set(_is_blt_registered_target TRUE) + message (STATUS "[${arg_TARGET} property] '${arg_TARGET}' is a blt_registered target") + endif() + + if(NOT _is_cmake_target AND NOT _is_blt_registered_target) + message (STATUS "[blt_print_target_properties] Invalid argument '${arg_TARGET}'. " + "This macro applies only to valid cmake targets or blt_registered targets.") + endif() + + + if(_is_cmake_target) + ## Solution adapted from https://stackoverflow.com/q/32183975 + ## Create list of cmake properties + set(_property_list) + execute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE _property_list) + string(REGEX REPLACE ";" "\\\\;" _property_list "${_property_list}") + string(REGEX REPLACE "\n" ";" _property_list "${_property_list}") + blt_filter_list(TO _property_list REGEX "^LOCATION$|^LOCATION_|_LOCATION$" OPERATION "exclude") + blt_list_remove_duplicates(TO _property_list) + + ## For interface targets, filter against whitelist of valid properties + get_property(_targetType TARGET ${arg_TARGET} PROPERTY TYPE) + if(${_targetType} STREQUAL "INTERFACE_LIBRARY") + blt_filter_list(TO _property_list + REGEX "^(INTERFACE_|IMPORTED_LIBNAME_|COMPATIBLE_INTERFACE_|MAP_IMPORTED_CONFIG_)|^(NAME|TYPE|EXPORT_NAME)$" + OPERATION "include") + endif() + + ## Print all such properties that have been SET + foreach (prop ${_property_list}) + string(REPLACE "" "${CMAKE_BUILD_TYPE}" prop ${prop}) + get_property(_propval TARGET ${arg_TARGET} PROPERTY ${prop} SET) + if (_propval) + get_target_property(_propval ${arg_TARGET} ${prop}) + message (STATUS "[${arg_TARGET} property] ${prop}: ${_propval}") + endif() + endforeach() + unset(_property_list) + unset(_propval) + endif() + + ## Additionally, output variables generated via blt_register_target of the form "BLT__*" + if(_is_blt_registered_target) + set(_target_prefix "BLT_${_target_upper}_") + + ## Filter to get variables of the form BLT__ and print + get_cmake_property(_variable_names VARIABLES) + foreach (prop ${_variable_names}) + if(prop MATCHES "^${_target_prefix}") + message (STATUS "[${arg_TARGET} property] ${prop}: ${${prop}}") + endif() + endforeach() + unset(_target_prefix) + unset(_variable_names) + endif() + + unset(_target_upper) + unset(_is_blt_registered_target) + unset(_is_cmake_target) +endmacro(blt_print_target_properties) diff --git a/tpl/RAJA/blt/cmake/BLTOptions.cmake b/tpl/RAJA/blt/cmake/BLTOptions.cmake new file mode 100644 index 000000000..35fded947 --- /dev/null +++ b/tpl/RAJA/blt/cmake/BLTOptions.cmake @@ -0,0 +1,138 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) +#------------------------------------------------------------------------------ +# Sets up configuration options for BLT +#------------------------------------------------------------------------------ + +include(CMakeDependentOption) + +#------------------------------------------------------------------------------ +# Build Targets +#------------------------------------------------------------------------------ +option(ENABLE_DOCS "Enables documentation" ON) +option(ENABLE_EXAMPLES "Enables examples" ON) +option(ENABLE_TESTS "Enables tests" ON) +option(ENABLE_BENCHMARKS "Enables benchmarks" OFF) +option(ENABLE_COVERAGE "Enables code coverage support" OFF) + +#------------------------------------------------------------------------------ +# TPL Executable Options +#------------------------------------------------------------------------------ +option(ENABLE_CLANGQUERY "Enables Clang-query support" ON) +option(ENABLE_CPPCHECK "Enables Cppcheck support" ON) +option(ENABLE_DOXYGEN "Enables Doxygen support" ON) +option(ENABLE_GIT "Enables Git support" ON) +option(ENABLE_SPHINX "Enables Sphinx support" ON) +option(ENABLE_UNCRUSTIFY "Enables Uncrustify support" ON) +option(ENABLE_ASTYLE "Enables AStyle support" ON) +option(ENABLE_VALGRIND "Enables Valgrind support" ON) + +#------------------------------------------------------------------------------ +# Build Options +#------------------------------------------------------------------------------ +get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) +if(_languages MATCHES "Fortran") + set(_fortran_already_enabled TRUE) +else() + set(_fortran_already_enabled FALSE) +endif() +option(ENABLE_FORTRAN "Enables Fortran compiler support" ${_fortran_already_enabled}) + +option(ENABLE_MPI "Enables MPI support" OFF) +option(ENABLE_OPENMP "Enables OpenMP compiler support" OFF) +option(ENABLE_CUDA "Enable CUDA support" OFF) +option(ENABLE_CLANG_CUDA "Enable Clang's native CUDA support" OFF) +mark_as_advanced(ENABLE_CLANG_CUDA) +set(BLT_CLANG_CUDA_ARCH "sm_30" CACHE STRING "Compute architecture to use when generating CUDA code with Clang") +mark_as_advanced(BLT_CLANG_CUDA_ARCH) +option(ENABLE_HIP "Enable HIP support" OFF) +option(ENABLE_HCC "Enable HCC support" OFF) +set(BLT_ROCM_ARCH "gfx900" CACHE STRING "gfx architecture to use when generating ROCm code") + +#------------------------------------------------------------------------------ +# Test Options +# +# Options that control if Google Test, Google Mock, and Fruit are built +# and available for use. +# +# If ENABLE_TESTS=OFF, no testing support is built and these option are ignored. +# +# Google Mock requires and always builds Google Test, so ENABLE_GMOCK=ON +# implies ENABLE_GTEST=ON. +#------------------------------------------------------------------------------ +get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) +if(_languages MATCHES "CXX") + set(_CXX_enabled ON) +else() + set(_CXX_enabled OFF) +endif() +option(ENABLE_GTEST "Enable Google Test testing support (if ENABLE_TESTS=ON)" ${_CXX_enabled}) +option(ENABLE_GMOCK "Enable Google Mock testing support (if ENABLE_TESTS=ON)" OFF) +option(ENABLE_FRUIT "Enable Fruit testing support (if ENABLE_TESTS=ON and ENABLE_FORTRAN=ON)" ON) +option(ENABLE_GBENCHMARK "Enable Google Benchmark support (if ENABLE_TESTS=ON)" ${ENABLE_BENCHMARKS}) + + +if( (NOT _CXX_enabled) AND ENABLE_GTEST ) + message( FATAL_ERROR + "You must have CXX enabled in your project to use GTEST!" ) +endif() + +#------------------------------------------------------------------------------ +# Compiler Options +#------------------------------------------------------------------------------ +option(ENABLE_ALL_WARNINGS "Enables all compiler warnings on all build targets" ON) +option(ENABLE_WARNINGS_AS_ERRORS "Enables treating compiler warnings as errors on all build targets" OFF) +cmake_dependent_option(BLT_ENABLE_MSVC_STATIC_MD_TO_MT + "When linking statically with MS Visual Studio, enables changing /MD to /MT" + ON + "NOT BUILD_SHARED_LIBS" + OFF) +mark_as_advanced(BLT_ENABLE_MSVC_STATIC_MD_TO_MT) + +#------------------------------------------------------------------------------ +# Generator Options +#------------------------------------------------------------------------------ +option(ENABLE_FOLDERS "Organize projects using folders (in generators that support this)" OFF) + +#------------------------------------------------------------------------------ +# Advanced configuration options +#------------------------------------------------------------------------------ + +option(ENABLE_FIND_MPI "Enables CMake's Find MPI support (Turn off when compiling with the mpi wrapper directly)" ON) + +option( + ENABLE_GTEST_DEATH_TESTS + "Enables tests that assert application failure. Only valid when tests are enabled" + OFF ) + +option( + ENABLE_WRAP_ALL_TESTS_WITH_MPIEXEC + "Option to ensure that all tests are invoked through mpiexec. Required on some platforms, like IBM's BG/Q." + OFF ) + +if (DEFINED ENABLE_SHARED_LIBS) + message(FATAL_ERROR "ENABLE_SHARED_LIBS is a deprecated BLT option." + "Use the standard CMake option, BUILD_SHARED_LIBS, instead.") +endif() + +# Provide some overridable target names for custom targets that blt defines. +# This can be useful when working with other build systems since CMake requires +# unique names for targets. +set(BLT_CODE_CHECK_TARGET_NAME "check" CACHE STRING "Name of the master code check target") +set(BLT_CODE_STYLE_TARGET_NAME "style" CACHE STRING "Name of the master code formatting target") +set(BLT_DOCS_TARGET_NAME "docs" CACHE STRING "Name of the master documentation generation target") +set(BLT_RUN_BENCHMARKS_TARGET_NAME "run_benchmarks" CACHE STRING "Name of the target to run benchmark tests") + + +# All advanced options should be marked as advanced +mark_as_advanced( + ENABLE_FIND_MPI + ENABLE_GTEST_DEATH_TESTS + ENABLE_WRAP_ALL_TESTS_WITH_MPIEXEC + BLT_CODE_CHECK_TARGET_NAME + BLT_CODE_STYLE_TARGET_NAME + BLT_DOCS_TARGET_NAME + BLT_RUN_BENCHMARKS_TARGET_NAME ) + diff --git a/tpl/RAJA/blt/cmake/BLTPrivateMacros.cmake b/tpl/RAJA/blt/cmake/BLTPrivateMacros.cmake new file mode 100644 index 000000000..32337c480 --- /dev/null +++ b/tpl/RAJA/blt/cmake/BLTPrivateMacros.cmake @@ -0,0 +1,739 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +include(CMakeParseArguments) + +## Internal BLT CMake Macros + + +##----------------------------------------------------------------------------- +## blt_determine_scope(TARGET +## SCOPE +## OUT ) +## +## Returns the normalized scope string for a given SCOPE and TARGET to be used +## in BLT macros. +## +## TARGET - Name of CMake Target that the property is being added to +## Note: the only real purpose of this parameter is to make sure we aren't +## adding returning other than INTERFACE for Interface Libraries +## SCOPE - case-insensitive scope string, defaults to PUBLIC +## OUT - variable that is filled with the uppercased scope +## +##----------------------------------------------------------------------------- +macro(blt_determine_scope) + + set(options) + set(singleValueArgs TARGET SCOPE OUT) + set(multiValueArgs ) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Convert to upper case and strip white space + string(TOUPPER "${arg_SCOPE}" _uppercaseScope) + string(STRIP "${_uppercaseScope}" _uppercaseScope ) + + if("${_uppercaseScope}" STREQUAL "") + # Default to public + set(_uppercaseScope PUBLIC) + elseif(NOT ("${_uppercaseScope}" STREQUAL "PUBLIC" OR + "${_uppercaseScope}" STREQUAL "INTERFACE" OR + "${_uppercaseScope}" STREQUAL "PRIVATE")) + message(FATAL_ERROR "Given SCOPE (${arg_SCOPE}) is not valid, valid options are:" + "PUBLIC, INTERFACE, or PRIVATE") + endif() + + if(TARGET ${arg_TARGET}) + get_property(_targetType TARGET ${arg_TARGET} PROPERTY TYPE) + if(${_targetType} STREQUAL "INTERFACE_LIBRARY") + # Interface targets can only set INTERFACE + if("${_uppercaseScope}" STREQUAL "PUBLIC" OR + "${_uppercaseScope}" STREQUAL "INTERFACE") + set(${arg_OUT} INTERFACE) + else() + message(FATAL_ERROR "Cannot set PRIVATE scope to Interface Library." + "Change to Scope to INTERFACE.") + endif() + else() + set(${arg_OUT} ${_uppercaseScope}) + endif() + else() + set(${arg_OUT} ${_uppercaseScope}) + endif() + + unset(_targetType) + unset(_uppercaseScope) + +endmacro(blt_determine_scope) + + +##----------------------------------------------------------------------------- +## blt_error_if_target_exists() +## +## Checks if target already exists in CMake project and errors out with given +## error_msg. +##----------------------------------------------------------------------------- +function(blt_error_if_target_exists target_name error_msg) + if (TARGET ${target_name}) + message(FATAL_ERROR "${error_msg}Duplicate target name: ${target_name}") + endif() +endfunction() + +##----------------------------------------------------------------------------- +## blt_fix_fortran_openmp_flags() +## +## Fixes the openmp flags for a Fortran target if they are different from the +## corresponding C/C++ openmp flags. +##----------------------------------------------------------------------------- +function(blt_fix_fortran_openmp_flags target_name) + + + if (ENABLE_FORTRAN AND ENABLE_OPENMP AND BLT_OPENMP_FLAGS_DIFFER) + + get_target_property(target_link_flags ${target_name} LINK_FLAGS) + if ( target_link_flags ) + + message(STATUS "Fixing OpenMP Flags for target[${target_name}]") + + string( REPLACE "${OpenMP_CXX_FLAGS}" "${OpenMP_Fortran_FLAGS}" + correct_link_flags + "${target_link_flags}" + ) + + set_target_properties( ${target_name} PROPERTIES LINK_FLAGS + "${correct_link_flags}" ) + endif() + + endif() + +endfunction() + +##----------------------------------------------------------------------------- +## blt_find_executable(NAME +## EXECUTABLES [exe1 [exe2 ...]]) +## +## This macro attempts to find the given executable via either a previously defined +## _EXECUTABLE or using find_program with the given EXECUTABLES. +## if EXECUTABLES is left empty, then NAME is used. +## +## If successful the following variables will be defined: +## _FOUND +## _EXECUTABLE +##----------------------------------------------------------------------------- +macro(blt_find_executable) + + set(options) + set(singleValueArgs NAME) + set(multiValueArgs EXECUTABLES) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_NAME ) + message( FATAL_ERROR "Must provide a NAME argument to the 'blt_find_executable' macro" ) + endif() + + string(TOUPPER ${arg_NAME} _ucname) + + message(STATUS "${arg_NAME} support is ${ENABLE_${_ucname}}") + if (${ENABLE_${_ucname}}) + set(_exes ${arg_NAME}) + if (DEFINED arg_EXECUTABLES) + set(_exes ${arg_EXECUTABLES}) + endif() + + if (${_ucname}_EXECUTABLE) + if (NOT EXISTS ${${_ucname}_EXECUTABLE}) + message(FATAL_ERROR "User defined ${_ucname}_EXECUTABLE does not exist. Fix/unset variable or set ENABLE_${_ucname} to OFF.") + endif() + else() + find_program(${_ucname}_EXECUTABLE + NAMES ${_exes} + DOC "Path to ${arg_NAME} executable") + endif() + + # Handle REQUIRED and QUIET arguments + # this will also set ${_ucname}_FOUND to true if ${_ucname}_EXECUTABLE exists + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(${arg_NAME} + "Failed to locate ${arg_NAME} executable" + ${_ucname}_EXECUTABLE) + endif() +endmacro(blt_find_executable) + + +##------------------------------------------------------------------------------ +## blt_inherit_target_info( TO +## FROM +## OBJECT [TRUE|FALSE]) +## +## The purpose of this macro is if you want to grab all the inheritable info +## from the FROM target but don't want to make the TO target depend on it. +## Which is useful if you don't want to export the FROM target. +## +## The OBJECT parameter is because object libraries can only inherit certain +## properties. +## +## This inherits the following properties: +## INTERFACE_COMPILE_DEFINITIONS +## INTERFACE_INCLUDE_DIRECTORIES +## INTERFACE_LINK_DIRECTORIES +## INTERFACE_LINK_LIBRARIES +## INTERFACE_SYSTEM_INCLUDE_DIRECTORIES +##------------------------------------------------------------------------------ +macro(blt_inherit_target_info) + set(options) + set(singleValueArgs TO FROM OBJECT) + set(multiValueArgs) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_TO ) + message( FATAL_ERROR "Must provide a TO argument to the 'blt_inherit_target' macro" ) + endif() + + if ( NOT DEFINED arg_FROM ) + message( FATAL_ERROR "Must provide a FROM argument to the 'blt_inherit_target' macro" ) + endif() + + get_target_property(_interface_system_includes + ${arg_FROM} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if ( _interface_system_includes ) + target_include_directories(${arg_TO} SYSTEM PUBLIC ${_interface_system_includes}) + endif() + + get_target_property(_interface_includes + ${arg_FROM} INTERFACE_INCLUDE_DIRECTORIES) + if ( _interface_includes ) + target_include_directories(${arg_TO} PUBLIC ${_interface_includes}) + endif() + + get_target_property(_interface_defines + ${arg_FROM} INTERFACE_COMPILE_DEFINITIONS) + if ( _interface_defines ) + target_compile_definitions( ${arg_TO} PUBLIC ${_interface_defines}) + endif() + + if ( NOT arg_OBJECT ) + get_target_property(_interface_link_directories + ${arg_FROM} INTERFACE_LINK_DIRECTORIES) + if ( _interface_link_directories ) + target_link_directories( ${arg_TO} PUBLIC ${_interface_link_directories}) + endif() + + get_target_property(_interface_link_libraries + ${arg_FROM} INTERFACE_LINK_LIBRARIES) + if ( _interface_link_libraries ) + target_link_libraries( ${arg_TO} PUBLIC ${_interface_link_libraries}) + endif() + endif() + +endmacro(blt_inherit_target_info) + + +##------------------------------------------------------------------------------ +## blt_setup_target( NAME [name] +## DEPENDS_ON [dep1 ...] +## OBJECT [TRUE | FALSE]) +##------------------------------------------------------------------------------ +macro(blt_setup_target) + + set(options) + set(singleValueArgs NAME OBJECT) + set(multiValueArgs DEPENDS_ON) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_NAME ) + message( FATAL_ERROR "Must provide a NAME argument to the 'blt_setup_target' macro" ) + endif() + + # Expand dependency list + set(_expanded_DEPENDS_ON ${arg_DEPENDS_ON}) + foreach( i RANGE 50 ) + foreach( dependency ${_expanded_DEPENDS_ON} ) + string(TOUPPER ${dependency} uppercase_dependency ) + + if ( DEFINED BLT_${uppercase_dependency}_DEPENDS_ON ) + foreach(new_dependency ${BLT_${uppercase_dependency}_DEPENDS_ON}) + if (NOT ${new_dependency} IN_LIST _expanded_DEPENDS_ON) + list(APPEND _expanded_DEPENDS_ON ${new_dependency}) + endif() + endforeach() + endif() + endforeach() + endforeach() + + # Add dependency's information + foreach( dependency ${_expanded_DEPENDS_ON} ) + string(TOUPPER ${dependency} uppercase_dependency ) + + if ( NOT arg_OBJECT AND BLT_${uppercase_dependency}_IS_OBJECT_LIBRARY ) + target_sources(${arg_NAME} PRIVATE $) + endif() + + if ( DEFINED BLT_${uppercase_dependency}_INCLUDES ) + if ( BLT_${uppercase_dependency}_TREAT_INCLUDES_AS_SYSTEM ) + target_include_directories( ${arg_NAME} SYSTEM PUBLIC + ${BLT_${uppercase_dependency}_INCLUDES} ) + else() + target_include_directories( ${arg_NAME} PUBLIC + ${BLT_${uppercase_dependency}_INCLUDES} ) + endif() + endif() + + if ( DEFINED BLT_${uppercase_dependency}_FORTRAN_MODULES ) + target_include_directories( ${arg_NAME} PUBLIC + ${BLT_${uppercase_dependency}_FORTRAN_MODULES} ) + endif() + + if ( arg_OBJECT ) + # Object libraries need to inherit info from their CMake targets listed + # in their LIBRARIES + foreach( _library ${BLT_${uppercase_dependency}_LIBRARIES} ) + if(TARGET ${_library}) + blt_inherit_target_info(TO ${arg_NAME} + FROM ${_library} + OBJECT ${arg_OBJECT}) + endif() + endforeach() + endif() + + if ( arg_OBJECT OR BLT_${uppercase_dependency}_IS_OBJECT_LIBRARY ) + # We want object libraries to inherit the vital info but not call + # target_link_libraries() otherwise you have to install the object + # files associated with the object library which noone wants. + if ( TARGET ${dependency} ) + blt_inherit_target_info(TO ${arg_NAME} + FROM ${dependency} + OBJECT ${arg_OBJECT}) + endif() + elseif (DEFINED BLT_${uppercase_dependency}_LIBRARIES) + # This prevents cmake from adding -l to the + # command line for BLT registered libraries which are not + # actual CMake targets + if(NOT "${BLT_${uppercase_dependency}_LIBRARIES}" + STREQUAL "BLT_NO_LIBRARIES" ) + target_link_libraries( ${arg_NAME} PUBLIC + ${BLT_${uppercase_dependency}_LIBRARIES} ) + endif() + else() + target_link_libraries( ${arg_NAME} PUBLIC ${dependency} ) + endif() + + if ( DEFINED BLT_${uppercase_dependency}_DEFINES ) + target_compile_definitions( ${arg_NAME} PUBLIC + ${BLT_${uppercase_dependency}_DEFINES} ) + endif() + + if ( DEFINED BLT_${uppercase_dependency}_COMPILE_FLAGS ) + blt_add_target_compile_flags(TO ${arg_NAME} + FLAGS ${BLT_${uppercase_dependency}_COMPILE_FLAGS} ) + endif() + + if ( NOT arg_OBJECT AND DEFINED BLT_${uppercase_dependency}_LINK_FLAGS ) + blt_add_target_link_flags(TO ${arg_NAME} + FLAGS ${BLT_${uppercase_dependency}_LINK_FLAGS} ) + endif() + + endforeach() + +endmacro(blt_setup_target) + + +##------------------------------------------------------------------------------ +## blt_setup_cuda_target(NAME +## SOURCES +## DEPENDS_ON +## LIBRARY_TYPE ) +##------------------------------------------------------------------------------ +macro(blt_setup_cuda_target) + + set(options) + set(singleValueArgs NAME LIBRARY_TYPE) + set(multiValueArgs SOURCES DEPENDS_ON) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_NAME ) + message( FATAL_ERROR "Must provide a NAME argument to the 'blt_setup_cuda_target' macro") + endif() + + if ( NOT DEFINED arg_SOURCES ) + message( FATAL_ERROR "Must provide SOURCES to the 'blt_setup_cuda_target' macro") + endif() + + # Determine if cuda or cuda_runtime are in DEPENDS_ON + list(FIND arg_DEPENDS_ON "cuda" _cuda_index) + set(_depends_on_cuda FALSE) + if(${_cuda_index} GREATER -1) + set(_depends_on_cuda TRUE) + endif() + list(FIND arg_DEPENDS_ON "cuda_runtime" _cuda_runtime_index) + set(_depends_on_cuda_runtime FALSE) + if(${_cuda_runtime_index} GREATER -1) + set(_depends_on_cuda_runtime TRUE) + endif() + + if (${_depends_on_cuda_runtime} OR ${_depends_on_cuda}) + if (CUDA_LINK_WITH_NVCC) + set_target_properties( ${arg_NAME} PROPERTIES LINKER_LANGUAGE CUDA) + endif() + endif() + + if (${_depends_on_cuda}) + # if cuda is in depends_on, flag each file's language as CUDA + # instead of leaving it up to CMake to decide + # Note: we don't do this when depending on just 'cuda_runtime' + set(_cuda_sources) + set(_non_cuda_sources) + blt_split_source_list_by_language(SOURCES ${arg_SOURCES} + C_LIST _cuda_sources + Fortran_LIST _non_cuda_sources) + + set_source_files_properties( ${_cuda_sources} PROPERTIES + LANGUAGE CUDA) + + if (CUDA_SEPARABLE_COMPILATION) + set_source_files_properties( ${_cuda_sources} PROPERTIES + CUDA_SEPARABLE_COMPILATION ON) + set_target_properties( ${arg_NAME} PROPERTIES + CUDA_SEPARABLE_COMPILATION ON) + endif() + + if (DEFINED arg_LIBRARY_TYPE) + if (${arg_LIBRARY_TYPE} STREQUAL "static") + set_target_properties( ${arg_NAME} PROPERTIES + CMAKE_CUDA_CREATE_STATIC_LIBRARY ON) + else() + set_target_properties( ${arg_NAME} PROPERTIES + CMAKE_CUDA_CREATE_STATIC_LIBRARY OFF) + endif() + endif() + endif() +endmacro(blt_setup_cuda_target) + +##------------------------------------------------------------------------------ +## blt_add_hip_library(NAME +## SOURCES [source1 [source2 ...]] +## HEADERS [header1 [header2 ...]] +## DEPENDS_ON [dep1 ...] +## LIBRARY_TYPE +##------------------------------------------------------------------------------ +macro(blt_add_hip_library) + + set(options) + set(singleValueArgs NAME LIBRARY_TYPE) + set(multiValueArgs SOURCES HEADERS DEPENDS_ON) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_NAME ) + message( FATAL_ERROR "Must provide a NAME argument to the 'blt_add_hip_library' macro") + endif() + + if ( NOT DEFINED arg_SOURCES ) + message( FATAL_ERROR "Must provide SOURCES to the 'blt_add_hip_library' macro") + endif() + + # Determine if hip or hip_runtime are in DEPENDS_ON + list(FIND arg_DEPENDS_ON "hip" _hip_index) + set(_depends_on_hip FALSE) + if(${_hip_index} GREATER -1) + set(_depends_on_hip TRUE) + endif() + list(FIND arg_DEPENDS_ON "hip_runtime" _hip_runtime_index) + set(_depends_on_hip_runtime FALSE) + if(${_hip_runtime_index} GREATER -1) + set(_depends_on_hip_runtime TRUE) + endif() + + if (${_depends_on_hip}) + # if hip is in depends_on, flag each file's language as HIP + # instead of leaving it up to CMake to decide + # Note: we don't do this when depending on just 'hip_runtime' + set(_hip_sources) + set(_non_hip_sources) + blt_split_source_list_by_language(SOURCES ${arg_SOURCES} + C_LIST _hip_sources + Fortran_LIST _non_hip_sources) + + set_source_files_properties( ${_hip_sources} + PROPERTIES + HIP_SOURCE_PROPERTY_FORMAT TRUE) + + hip_add_library( ${arg_NAME} ${arg_SOURCES} ${arg_LIBRARY_TYPE} ) + else() + add_library( ${arg_NAME} ${arg_LIBRARY_TYPE} ${arg_SOURCES} ${arg_HEADERS} ) + endif() + +endmacro(blt_add_hip_library) + +##------------------------------------------------------------------------------ +## blt_add_hip_executable(NAME +## SOURCES [source1 [source2 ...]] +## DEPENDS_ON [dep1 ...] +##------------------------------------------------------------------------------ +macro(blt_add_hip_executable) + + set(options) + set(singleValueArgs NAME) + set(multiValueArgs SOURCES DEPENDS_ON) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_NAME ) + message( FATAL_ERROR "Must provide a NAME argument to the 'blt_add_hip_executable' macro") + endif() + + if ( NOT DEFINED arg_SOURCES ) + message( FATAL_ERROR "Must provide SOURCES to the 'blt_add_hip_executable' macro") + endif() + + # Determine if hip or hip_runtime are in DEPENDS_ON + list(FIND arg_DEPENDS_ON "hip" _hip_index) + set(_depends_on_hip FALSE) + if(${_hip_index} GREATER -1) + set(_depends_on_hip TRUE) + endif() + list(FIND arg_DEPENDS_ON "hip_runtime" _hip_runtime_index) + set(_depends_on_hip_runtime FALSE) + if(${_hip_runtime_index} GREATER -1) + set(_depends_on_hip_runtime TRUE) + endif() + + if (${_depends_on_hip} OR ${_depends_on_hip_runtime}) + # if hip is in depends_on, flag each file's language as HIP + # instead of leaving it up to CMake to decide + # Note: we don't do this when depending on just 'hip_runtime' + set(_hip_sources) + set(_non_hip_sources) + blt_split_source_list_by_language(SOURCES ${arg_SOURCES} + C_LIST _hip_sources + Fortran_LIST _non_hip_sources) + + set_source_files_properties( ${_hip_sources} + PROPERTIES + HIP_SOURCE_PROPERTY_FORMAT TRUE) + + hip_add_executable( ${arg_NAME} ${arg_SOURCES} ) + else() + add_executable( ${arg_NAME} ${arg_SOURCES} ) + endif() + +endmacro(blt_add_hip_executable) + +##------------------------------------------------------------------------------ +## blt_split_source_list_by_language( SOURCES +## C_LIST +## Fortran_LIST ) +## +## Filters source list by file extension into C/C++ and Fortran source lists +## based on BLT_C_FILE_EXTS and BLT_Fortran_FILE_EXTS (global BLT variables). +## Files with no extension or generator expressions that are not object libraries +## (of the form "$") will throw fatal errors. +##------------------------------------------------------------------------------ +macro(blt_split_source_list_by_language) + + set(options) + set(singleValueArgs C_LIST Fortran_LIST) + set(multiValueArgs SOURCES) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_SOURCES ) + message( FATAL_ERROR "Must provide a SOURCES argument to the 'blt_split_source_list_by_language' macro" ) + endif() + + # Generate source lists based on language + foreach(_file ${arg_SOURCES}) + # Allow CMake object libraries but disallow generator expressions + # in source lists due to this causing all sorts of bad side effects + if("${_file}" MATCHES "^\\$ ) +##------------------------------------------------------------------------------ +macro(blt_update_project_sources) + + set(options) + set(singleValueArgs) + set(multiValueArgs TARGET_SOURCES) + + # Parse the arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if ( NOT DEFINED arg_TARGET_SOURCES ) + message( FATAL_ERROR "Must provide target sources" ) + endif() + + ## append the target source to the all project sources + foreach( src ${arg_TARGET_SOURCES} ) + if(IS_ABSOLUTE ${src}) + list(APPEND "${PROJECT_NAME}_ALL_SOURCES" "${src}") + else() + list(APPEND "${PROJECT_NAME}_ALL_SOURCES" + "${CMAKE_CURRENT_SOURCE_DIR}/${src}") + endif() + endforeach() + + set( "${PROJECT_NAME}_ALL_SOURCES" "${${PROJECT_NAME}_ALL_SOURCES}" + CACHE STRING "" FORCE ) + mark_as_advanced("${PROJECT_NAME}_ALL_SOURCES") + +endmacro(blt_update_project_sources) + + +##------------------------------------------------------------------------------ +## blt_filter_list( TO REGEX OPERATION ) +## +## This macro provides the same functionality as cmake's list(FILTER ) +## which is only available in cmake-3.6+. +## +## The TO argument (required) is the name of a list variable. +## The REGEX argument (required) is a string containing a regex. +## The OPERATION argument (required) is a string that defines the macro's operation. +## Supported values are "include" and "exclude" +## +## The filter is applied to the input list, which is modified in place. +##------------------------------------------------------------------------------ +macro(blt_filter_list) + + set(options ) + set(singleValueArgs TO REGEX OPERATION) + set(multiValueArgs ) + + # Parse arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Check arguments + if( NOT DEFINED arg_TO ) + message(FATAL_ERROR "blt_filter_list macro requires a TO argument") + endif() + + if( NOT DEFINED arg_REGEX ) + message(FATAL_ERROR "blt_filter_list macro requires a REGEX argument") + endif() + + # Ensure OPERATION argument is provided with value "include" or "exclude" + set(_exclude) + if( NOT DEFINED arg_OPERATION ) + message(FATAL_ERROR "blt_filter_list macro requires a OPERATION argument") + elseif(NOT arg_OPERATION MATCHES "^(include|exclude)$") + message(FATAL_ERROR "blt_filter_list macro's OPERATION argument must be either 'include' or 'exclude'") + else() + if(${arg_OPERATION} MATCHES "exclude") + set(_exclude TRUE) + else() + set(_exclude FALSE) + endif() + endif() + + # Filter the list + set(_resultList) + foreach(elem ${${arg_TO}}) + if(elem MATCHES ${arg_REGEX}) + if(NOT ${_exclude}) + list(APPEND _resultList ${elem}) + endif() + else() + if(${_exclude}) + list(APPEND _resultList ${elem}) + endif() + endif() + endforeach() + + # Copy result back to input list variable + set(${arg_TO} ${_resultList}) + + unset(_exclude) + unset(_resultList) +endmacro(blt_filter_list) + + +##------------------------------------------------------------------------------ +## blt_clean_target( TARGET ) +## +## This macro removes duplicates in a small subset of target properties that are +## safe to do so. +##------------------------------------------------------------------------------ +macro(blt_clean_target) + + set(options ) + set(singleValueArgs TARGET) + set(multiValueArgs ) + + # Parse arguments + cmake_parse_arguments(arg "${options}" "${singleValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Properties to remove duplicates from + set(_dup_properties + INCLUDE_DIRECTORIES + INTERFACE_COMPILE_DEFINITIONS + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + + foreach(_prop ${_dup_properties}) + get_target_property(_values ${arg_TARGET} ${_prop}) + if ( _values ) + list(REMOVE_DUPLICATES _values) + set_property(TARGET ${arg_TARGET} PROPERTY ${_prop} ${_values}) + endif() + endforeach() + +endmacro(blt_clean_target) diff --git a/tpl/RAJA/blt/cmake/SetupCodeChecks.cmake b/tpl/RAJA/blt/cmake/SetupCodeChecks.cmake new file mode 100644 index 000000000..68f4ce870 --- /dev/null +++ b/tpl/RAJA/blt/cmake/SetupCodeChecks.cmake @@ -0,0 +1,489 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) +#------------------------------------------------------------------------------ +# Targets related to source code checks (formatting, static analysis, etc) +#------------------------------------------------------------------------------ + +add_custom_target(${BLT_CODE_CHECK_TARGET_NAME}) +add_custom_target(${BLT_CODE_STYLE_TARGET_NAME}) + +if(UNCRUSTIFY_FOUND) + # targets for verifying formatting + add_custom_target(uncrustify_check) + add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} uncrustify_check) + + # targets for modifying formatting + add_custom_target(uncrustify_style) + add_dependencies(${BLT_CODE_STYLE_TARGET_NAME} uncrustify_style) +endif() + +if(ASTYLE_FOUND) + # targets for verifying formatting + add_custom_target(astyle_check) + add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} astyle_check) + + # targets for modifying formatting + add_custom_target(astyle_style) + add_dependencies(${BLT_CODE_STYLE_TARGET_NAME} astyle_style) +endif() + +if(CPPCHECK_FOUND) + add_custom_target(cppcheck_check) + add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} cppcheck_check) +endif() + +if(CLANGQUERY_FOUND) + # note: interactive_clang_query_check + # is for the use of code developers who + # want to check specific attributes of + # specific targets, and does not make + # sense as a dependency of check + add_custom_target(clang_query_check) + add_custom_target(interactive_clang_query_check) + add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} clang_query_check) +endif() + +# Code check targets should only be run on demand +foreach(target + check uncrustify_check astyle_check cppcheck_check + style uncrustify_style astyle_style + clang_query_check interactive_clang_query_check) + if(TARGET ${target}) + set_property(TARGET ${target} PROPERTY EXCLUDE_FROM_ALL TRUE) + set_property(TARGET ${target} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endforeach() + + +##------------------------------------------------------------------------------ +## blt_add_code_checks( PREFIX +## SOURCES [source1 [source2 ...]] +## UNCRUSTIFY_CFG_FILE +## ASTYLE_CFG_FILE +## CPPCHECK_FLAGS ) +## +## This macro adds all enabled code check targets for the given SOURCES. It +## filters checks based on file extensions. +##------------------------------------------------------------------------------ + +macro(blt_add_code_checks) + + set(options ) + set(singleValueArgs PREFIX UNCRUSTIFY_CFG_FILE ASTYLE_CFG_FILE) + set(multiValueArgs SOURCES CPPCHECK_FLAGS) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (NOT DEFINED arg_PREFIX) + message(FATAL_ERROR "blt_add_code_checks requires the parameter PREFIX.") + endif() + + if (NOT DEFINED arg_SOURCES) + message(FATAL_ERROR "blt_add_code_checks requires the parameter SOURCES.") + endif() + + # Make the sources relative to the bin directory + set(_rel_sources) + foreach(_file ${arg_SOURCES}) + # Get full path + if(IS_ABSOLUTE ${_file}) + set(_full_path ${_file}) + else() + set(_full_path ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) + endif() + + file(RELATIVE_PATH _rel_path ${CMAKE_BINARY_DIR} ${_full_path}) + list(APPEND _rel_sources ${_rel_path}) + endforeach() + + # Generate source lists based on language + set(_c_sources) + set(_f_sources) + blt_split_source_list_by_language(SOURCES ${_rel_sources} + C_LIST _c_sources + Fortran_LIST _f_sources) + + # Check that at most one formatting config file was supplied + if (DEFINED arg_UNCRUSTIFY_CFG_FILE AND DEFINED arg_ASTYLE_CFG_FILE) + message(FATAL_ERROR + "blt_add_code_checks macro does not support multiple " + "style config parameters within the same invocation. " + "Both UNCRUSTIFY_CFG_FILE and ASTYLE_CFG_FILE were supplied.") + endif() + + # Add code checks + set(_error_msg "blt_add_code_checks tried to create an already existing target with given PREFIX: ${arg_PREFIX}. ") + if (UNCRUSTIFY_FOUND AND DEFINED arg_UNCRUSTIFY_CFG_FILE) + set(_check_target_name ${arg_PREFIX}_uncrustify_check) + blt_error_if_target_exists(${_check_target_name} ${_error_msg}) + set(_style_target_name ${arg_PREFIX}_uncrustify_style) + blt_error_if_target_exists(${_style_target_name} ${_error_msg}) + + blt_add_uncrustify_target( NAME ${_check_target_name} + MODIFY_FILES FALSE + CFG_FILE ${arg_UNCRUSTIFY_CFG_FILE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + SRC_FILES ${_c_sources} ) + + blt_add_uncrustify_target( NAME ${_style_target_name} + MODIFY_FILES TRUE + CFG_FILE ${arg_UNCRUSTIFY_CFG_FILE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + SRC_FILES ${_c_sources} ) + endif() + + if (ASTYLE_FOUND AND DEFINED arg_ASTYLE_CFG_FILE) + set(_check_target_name ${arg_PREFIX}_astyle_check) + blt_error_if_target_exists(${_check_target_name} ${_error_msg}) + set(_style_target_name ${arg_PREFIX}_astyle_style) + blt_error_if_target_exists(${_style_target_name} ${_error_msg}) + + blt_add_astyle_target( NAME ${_check_target_name} + MODIFY_FILES FALSE + CFG_FILE ${arg_ASTYLE_CFG_FILE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + SRC_FILES ${_c_sources} ) + + blt_add_astyle_target( NAME ${_style_target_name} + MODIFY_FILES TRUE + CFG_FILE ${arg_ASTYLE_CFG_FILE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + SRC_FILES ${_c_sources} ) + endif() + + if (CPPCHECK_FOUND) + set(_cppcheck_target_name ${arg_PREFIX}_cppcheck_check) + blt_error_if_target_exists(${_cppcheck_target_name} ${_error_msg}) + + blt_add_cppcheck_target( NAME ${_cppcheck_target_name} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + SRC_FILES ${_c_sources} + PREPEND_FLAGS ${arg_CPPCHECK_FLAGS}) + endif() + + if (CLANGQUERY_FOUND) + set(_clang_query_target_name ${arg_PREFIX}_clang_query_check) + blt_error_if_target_exists(${_clang_query_target_name} ${_error_msg}) + blt_add_clang_query_target( NAME ${_clang_query_target_name} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + SRC_FILES ${_c_sources}) + endif() + +endmacro(blt_add_code_checks) + +##----------------------------------------------------------------------------- +## blt_add_clang_query_target( NAME +## WORKING_DIRECTORY +## COMMENT +## CHECKERS +## DIE_ON_MATCH +## SRC_FILES [FILE1 [FILE2 ...]] ) +## +## Creates a new target with the given NAME for running clang_query over the given SRC_FILES +##----------------------------------------------------------------------------- +macro(blt_add_clang_query_target) + if(CLANGQUERY_FOUND) + + ## parse the arguments to the macro + set(options) + set(singleValueArgs NAME COMMENT WORKING_DIRECTORY DIE_ON_MATCH) + set(multiValueArgs SRC_FILES CHECKERS) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Check required parameters + if(NOT DEFINED arg_NAME) + message(FATAL_ERROR "blt_add_clang_query_target requires a NAME parameter") + endif() + + if(NOT DEFINED arg_SRC_FILES) + message(FATAL_ERROR "blt_add_clang_query_target requires a SRC_FILES parameter") + endif() + + if(DEFINED arg_WORKING_DIRECTORY) + set(_wd ${arg_WORKING_DIRECTORY}) + else() + set(_wd ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + set(interactive_target_name interactive_${arg_NAME}) + set(CLANG_QUERY_HELPER_SCRIPT ${BLT_ROOT_DIR}/cmake/clang-query-wrapper.py) + set(CLANG_QUERY_HELPER_COMMAND python ${CLANG_QUERY_HELPER_SCRIPT} --clang-query ${CLANGQUERY_EXECUTABLE} --checker-directories ${BLT_CLANG_QUERY_CHECKER_DIRECTORIES} --compilation-database-path ${CMAKE_BINARY_DIR}) + + if(arg_DIE_ON_MATCH) + set(CLANG_QUERY_HELPER_COMMAND ${CLANG_QUERY_HELPER_COMMAND} --die-on-match) + endif() + + if(DEFINED arg_CHECKERS) + STRING(REGEX REPLACE " " ":" CHECKER_ARG_STRING ${arg_CHECKERS}) + add_custom_target(${arg_NAME} + COMMAND ${CLANG_QUERY_HELPER_COMMAND} -i --checkers=${CHECKER_ARG_STRING} ${arg_SRC_FILES} + WORKING_DIRECTORY ${_wd} + COMMENT "${arg_COMMENT}Running specified clang_query source code static analysis checks.") + else() #DEFINED CHECKERS + add_custom_target(${arg_NAME} + COMMAND ${CLANG_QUERY_HELPER_COMMAND} ${arg_SRC_FILES} + WORKING_DIRECTORY ${_wd} + COMMENT "${arg_COMMENT}Running all clang_query source code static analysis checks.") + endif() + + add_custom_target(${interactive_target_name} + COMMAND ${CLANG_QUERY_HELPER_COMMAND} -i ${arg_SRC_FILES} + WORKING_DIRECTORY ${_wd} + COMMENT "${arg_COMMENT}Running clang_query source code static analysis checks.") + + # hook our new target into the proper dependency chain + add_dependencies(clang_query_check ${arg_NAME}) + add_dependencies(interactive_clang_query_check ${interactive_target_name}) + + # Code check targets should only be run on demand + set_property(TARGET ${interactive_target_name} PROPERTY EXCLUDE_FROM_ALL TRUE) + set_property(TARGET ${interactive_target_name} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE) + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE) + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endmacro(blt_add_clang_query_target) + + +##----------------------------------------------------------------------------- +## blt_add_cppcheck_target( NAME +## WORKING_DIRECTORY +## PREPEND_FLAGS +## APPEND_FLAGS +## COMMENT +## SRC_FILES [FILE1 [FILE2 ...]] ) +## +## Creates a new target with the given NAME for running cppcheck over the given SRC_FILES +##----------------------------------------------------------------------------- +macro(blt_add_cppcheck_target) + + ## parse the arguments to the macro + set(options) + set(singleValueArgs NAME COMMENT WORKING_DIRECTORY) + set(multiValueArgs SRC_FILES PREPEND_FLAGS APPEND_FLAGS) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Check required parameters + if(NOT DEFINED arg_NAME) + message(FATAL_ERROR "blt_add_cppcheck_target requires a NAME parameter") + endif() + + if(NOT DEFINED arg_SRC_FILES) + message(FATAL_ERROR "blt_add_cppcheck_target requires a SRC_FILES parameter") + endif() + + if(DEFINED arg_WORKING_DIRECTORY) + set(_wd ${arg_WORKING_DIRECTORY}) + else() + set(_wd ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + add_custom_target(${arg_NAME} + COMMAND ${CPPCHECK_EXECUTABLE} ${arg_PREPEND_FLAGS} ${arg_SRC_FILES} ${arg_APPEND_FLAGS} + WORKING_DIRECTORY ${_wd} + COMMENT "${arg_COMMENT}Running cppcheck source code static analysis checks.") + + # hook our new target into the proper dependency chain + add_dependencies(cppcheck_check ${arg_NAME}) + + # Code check targets should only be run on demand + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE) + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE) +endmacro(blt_add_cppcheck_target) + + +##------------------------------------------------------------------------------ +## blt_add_uncrustify_target( NAME +## MODIFY_FILES [TRUE | FALSE (default)] +## CFG_FILE +## PREPEND_FLAGS +## APPEND_FLAGS +## COMMENT +## WORKING_DIRECTORY +## SRC_FILES [FILE1 [FILE2 ...]] ) +## +## Creates a new target with the given NAME for running uncrustify over the given SRC_FILES. +##------------------------------------------------------------------------------ +macro(blt_add_uncrustify_target) + + ## parse the arguments to the macro + set(options) + set(singleValueArgs NAME MODIFY_FILES CFG_FILE COMMENT WORKING_DIRECTORY) + set(multiValueArgs SRC_FILES PREPEND_FLAGS APPEND_FLAGS) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Check/Set required parameters + if(NOT DEFINED arg_NAME) + message(FATAL_ERROR "blt_add_uncrustify_target requires a NAME parameter") + endif() + + if(NOT DEFINED arg_CFG_FILE) + message(FATAL_ERROR "blt_add_uncrustify_target requires a CFG_FILE parameter") + endif() + + if(NOT DEFINED arg_SRC_FILES) + message(FATAL_ERROR "blt_add_uncrustify_target requires a SRC_FILES parameter") + endif() + + if(NOT DEFINED arg_MODIFY_FILES) + set(arg_MODIFY_FILES FALSE) + endif() + + if(DEFINED arg_WORKING_DIRECTORY) + set(_wd ${arg_WORKING_DIRECTORY}) + else() + set(_wd ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + set(_generate_target TRUE) + + if(${arg_MODIFY_FILES}) + set(MODIFY_FILES_FLAG --replace;--no-backup) + else() + set(MODIFY_FILES_FLAG "--check") + + # Check the version -- output is of the form "uncrustify X.Y.Z" + execute_process( + COMMAND ${UNCRUSTIFY_EXECUTABLE} --version + OUTPUT_VARIABLE _version_str + OUTPUT_STRIP_TRAILING_WHITESPACE ) + string(REGEX MATCH "([0-9]+(\\.)?)+(_[a-zA-Z])?" _uncrustify_version ${_version_str}) + + # Skip 'check' target if version is not high enough + if(_uncrustify_version VERSION_LESS 0.61) + set(_generate_target FALSE) + message(WARNING "blt_add_uncrustify_target requires uncrustify v0.61 or greater " + " for style check targets. " + " Current uncrustify executable: '${UNCRUSTIFY_EXECUTABLE}' " + " Current uncrustify version is: ${_uncrustify_version}." ) + endif() + endif() + + if(_generate_target) + add_custom_target(${arg_NAME} + COMMAND ${UNCRUSTIFY_EXECUTABLE} ${arg_PREPEND_FLAGS} + -c ${arg_CFG_FILE} ${MODIFY_FILES_FLAG} ${arg_SRC_FILES} ${arg_APPEND_FLAGS} + WORKING_DIRECTORY ${_wd} + COMMENT "${arg_COMMENT}Running uncrustify source code formatting checks.") + + # hook our new target into the proper dependency chain + if(${arg_MODIFY_FILES}) + add_dependencies(uncrustify_style ${arg_NAME}) + else() + add_dependencies(uncrustify_check ${arg_NAME}) + endif() + + # Code formatting targets should only be run on demand + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE) + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() + +endmacro(blt_add_uncrustify_target) + +##------------------------------------------------------------------------------ +## blt_add_astyle_target( NAME +## MODIFY_FILES [TRUE | FALSE (default)] +## CFG_FILE +## PREPEND_FLAGS +## APPEND_FLAGS +## COMMENT +## WORKING_DIRECTORY +## SRC_FILES [FILE1 [FILE2 ...]] ) +## +## Creates a new target with the given NAME for running astyle over the given SRC_FILES. +##------------------------------------------------------------------------------ +macro(blt_add_astyle_target) + + ## parse the arguments to the macro + set(options) + set(singleValueArgs NAME MODIFY_FILES CFG_FILE COMMENT WORKING_DIRECTORY) + set(multiValueArgs SRC_FILES PREPEND_FLAGS APPEND_FLAGS) + + cmake_parse_arguments(arg + "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Check/Set required parameters + if(NOT DEFINED arg_NAME) + message(FATAL_ERROR "blt_add_astyle_target requires a NAME parameter") + endif() + + if(NOT DEFINED arg_CFG_FILE) + message(FATAL_ERROR "blt_add_astyle_target requires a CFG_FILE parameter") + endif() + + if(NOT DEFINED arg_SRC_FILES) + message(FATAL_ERROR "blt_add_astyle_target requires a SRC_FILES parameter") + endif() + + if(NOT DEFINED arg_MODIFY_FILES) + set(arg_MODIFY_FILES FALSE) + endif() + + if(DEFINED arg_WORKING_DIRECTORY) + set(_wd ${arg_WORKING_DIRECTORY}) + else() + set(_wd ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + set(_generate_target TRUE) + + if(${arg_MODIFY_FILES}) + set(MODIFY_FILES_FLAG --suffix=none) + else() + set(MODIFY_FILES_FLAG --dry-run) + + # Check the version -- output is of the form "Artistic Style Version X.Y.Z" + execute_process( + COMMAND ${ASTYLE_EXECUTABLE} --version + OUTPUT_VARIABLE _version_str + ERROR_VARIABLE _version_str + OUTPUT_STRIP_TRAILING_WHITESPACE ) + string(REGEX MATCH "([0-9]+(\\.)?)+$" _astyle_version ${_version_str}) + + # Skip 'check' target if version is not high enough + if(_astyle_version VERSION_LESS 2.05) + set(_generate_target FALSE) + message(WARNING "blt_add_astyle_target requires AStyle v2.05 or greater " + " for style check targets. " + " Current AStyle executable: '${ASTYLE_EXECUTABLE}' " + " Current AStyle version is: ${_astyle_version}." ) + endif() + endif() + + if(_generate_target) + + # AStyle doesn't report failure when there are files that require formatting. + # Fix this with a wrapper script that parses the output. + set(wrapped_astyle_script ${CMAKE_CURRENT_BINARY_DIR}/WrapAstyle_${arg_NAME}.cmake) + + configure_file( + ${BLT_ROOT_DIR}/cmake/WrapAstyle.cmake.in + ${wrapped_astyle_script} + @ONLY ) + + add_custom_target( + ${arg_NAME} + COMMAND ${CMAKE_COMMAND} -P ${wrapped_astyle_script} + WORKING_DIRECTORY ${_wd} + COMMENT "${arg_COMMENT}Running AStyle source code formatting checks.") + + # Hook our new target into the proper dependency chain + if(${arg_MODIFY_FILES}) + add_dependencies(astyle_style ${arg_NAME}) + else() + add_dependencies(astyle_check ${arg_NAME}) + endif() + + # Code formatting targets should only be run on demand + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE) + set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endmacro(blt_add_astyle_target) diff --git a/tpl/RAJA/blt/cmake/SetupCodeCoverageReports.cmake b/tpl/RAJA/blt/cmake/SetupCodeCoverageReports.cmake new file mode 100644 index 000000000..996037222 --- /dev/null +++ b/tpl/RAJA/blt/cmake/SetupCodeCoverageReports.cmake @@ -0,0 +1,91 @@ +# Copyright (c) 2012 - 2015, Lars Bilke. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + + +# 2012-01-31, Lars Bilke +# - Enable Code Coverage +# +# 2013-09-17, Joakim Soderberg +# - Added support for Clang. +# - Some additional usage instructions. +# +# (Original LCOV + GENHTML CMake Macro) from Lars Bilke + Joakim Soderberg +# +# 2015-07-06, Aaron Black +# - Modified for use by BLT. +# +# 2016-04-04, Kenny Weiss +# - Removed support for clang; simplified flags +# +# 2017-07-25, Cyrus Harrison +# - Refactored to only include report gen logic, not coverage flags +# + +set(BLT_CODE_COVERAGE_REPORTS ON) + +# Check for lcov +if(NOT EXISTS ${LCOV_EXECUTABLE}) + message(STATUS "Code coverage: Unable to find lcov, disabling code coverage reports.") + set(BLT_CODE_COVERAGE_REPORTS OFF) +endif() + +# Check for genthml +if(NOT EXISTS ${GENHTML_EXECUTABLE}) + message(STATUS "Code coverage: Unable to find genhtml, disabling code coverage reports.") + set(BLT_CODE_COVERAGE_REPORTS OFF) +endif() + +# Check for gcov +if(NOT EXISTS ${GCOV_EXECUTABLE}) + message(STATUS "Code coverage: GCOV_EXECUTABLE is not set, disabling code coverage reports") + set(BLT_CODE_COVERAGE_REPORTS OFF) +endif() + +mark_as_advanced(BLT_CODE_COVERAGE_REPORTS) + + +###################################################################### +# Function that adds target that generates code coverage reports +##################################################################### +# Param _targetname The name of new the custom make target and output file name. +# Param _testrunner The name of the target which runs the tests. +# MUST return ZERO always, even on errors. +# If not, no coverage report will be created! +# Optional fourth parameter is passed as arguments to _testrunner +# Pass them in list form, e.g.: "-j;2" for -j 2 +function(add_code_coverage_target _targetname _testrunner) + + # Setup target + add_custom_target(${_targetname} + + # Cleanup lcov + ${LCOV_EXECUTABLE} --no-external --gcov-tool ${GCOV_EXECUTABLE} --directory ${CMAKE_BINARY_DIR} --directory ${CMAKE_SOURCE_DIR}/components --zerocounters + + # Run tests + COMMAND ${_testrunner} ${ARGV2} + + # Capture lcov counters and generating report + COMMAND ${LCOV_EXECUTABLE} --no-external --gcov-tool ${GCOV_EXECUTABLE} --directory ${CMAKE_BINARY_DIR} --directory ${CMAKE_SOURCE_DIR}/components --capture --output-file ${_targetname}.info + COMMAND ${LCOV_EXECUTABLE} --no-external --gcov-tool ${GCOV_EXECUTABLE} --directory ${CMAKE_BINARY_DIR} --directory ${CMAKE_SOURCE_DIR}/components --remove ${_targetname}.info '/usr/include/*' --output-file ${_targetname}.info.cleaned + COMMAND ${GENHTML_EXECUTABLE} -o ${_targetname} ${_targetname}.info.cleaned + COMMAND ${CMAKE_COMMAND} -E remove ${_targetname}.info ${_targetname}.info.cleaned + + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${_targetname} POST_BUILD + COMMAND ; + COMMENT "Open ./${_targetname}/index.html in your browser to view the coverage report." + ) +endfunction() + + +if(BLT_CODE_COVERAGE_REPORTS) + # Add code coverage target + add_code_coverage_target(coverage make test) + message(STATUS "Code coverage: reports enabled via lcov, genthml, and gcov.") +endif() + diff --git a/tpl/RAJA/blt/cmake/SetupCodeMetrics.cmake b/tpl/RAJA/blt/cmake/SetupCodeMetrics.cmake new file mode 100644 index 000000000..720136094 --- /dev/null +++ b/tpl/RAJA/blt/cmake/SetupCodeMetrics.cmake @@ -0,0 +1,45 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) +################################################# +# Setup code metrics - coverage, profiling, etc +################################################# + +######################################## +# Enable code coverage via gcov +# Note: Only supported for gnu or clang. +######################################## +if (ENABLE_COVERAGE) + ########################################################################## + # Setup coverage compiler flags + ########################################################################## + # Set the actual flags for coverage in the COVERAGE_FLAGS variable + # Note: For gcc '--coverage' is equivalent to + # '-fprofile-arcs -ftest-coverage' for compiling and '-lgcov' for linking + # Additional flags that might be useful: + # " -fno-inline -fno-inline-small-functions -fno-default-inline" + blt_append_custom_compiler_flag(FLAGS_VAR COVERAGE_FLAGS + DEFAULT " " + GNU "--coverage" + CLANG "--coverage") + + SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_FLAGS}" ) + SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS}" ) + SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${COVERAGE_FLAGS}" ) + + if(ENABLE_FORTRAN) + SET( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_FLAGS}" ) + endif() + + ###################################### + # Setup Code Coverage Report Targets + ###################################### + include(${BLT_ROOT_DIR}/cmake/SetupCodeCoverageReports.cmake) + +endif() + +if (VALGRIND_FOUND) + set(MEMORYCHECK_COMMAND ${VALGRIND_EXECUTABLE} CACHE PATH "") + set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full" CACHE PATH "") +endif() diff --git a/tpl/RAJA/blt/cmake/SetupCompilerOptions.cmake b/tpl/RAJA/blt/cmake/SetupCompilerOptions.cmake new file mode 100644 index 000000000..49d92c953 --- /dev/null +++ b/tpl/RAJA/blt/cmake/SetupCompilerOptions.cmake @@ -0,0 +1,420 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +############################ +# Setup compiler options +############################ + +##################################################### +# Set some variables to simplify determining compiler +# Compiler string list from: +# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html +####################################################3 + +# use CMAKE_BUILD_TOOL to identify visual studio +# and CMAKE_CXX_COMPILER_ID for all other cases + +if("${CMAKE_BUILD_TOOL}" MATCHES "(msdev|devenv|nmake|MSBuild)") + set(COMPILER_FAMILY_IS_MSVC 1) + message(STATUS "Compiler family is MSVC") + + if(CMAKE_GENERATOR_TOOLSET AND "${CMAKE_GENERATOR_TOOLSET}" MATCHES "Intel") + set(COMPILER_FAMILY_IS_MSVC_INTEL 1) + message(STATUS "Toolset is ${CMAKE_GENERATOR_TOOLSET}") + endif() +else() + #Determine C/C++ compiler family. + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(C_COMPILER_FAMILY_IS_GNU 1) + message(STATUS "C Compiler family is GNU") + + elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # For Clang or AppleClang + set(C_COMPILER_FAMILY_IS_CLANG 1) + message(STATUS "C Compiler family is Clang") + + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL") + set(C_COMPILER_FAMILY_IS_XL 1) + message(STATUS "C Compiler family is XL") + + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + set(C_COMPILER_FAMILY_IS_INTEL 1) + message(STATUS "C Compiler family is Intel") + + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "PGI") + set(C_COMPILER_FAMILY_IS_PGI 1) + message(STATUS "C Compiler family is PGI") + + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Cray") + set(C_COMPILER_FAMILY_IS_CRAY 1) + message(STATUS "C Compiler family is Cray") + + else() + message(STATUS "C Compiler family not set!!!") + endif() + # Determine Fortran compiler family + if("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU") + set(Fortran_COMPILER_FAMILY_IS_GNU 1) + message(STATUS "Fortran Compiler family is GNU") + + elseif("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Clang") # For Clang or AppleClang + set(Fortran_COMPILER_FAMILY_IS_CLANG 1) + message(STATUS "Fortran Compiler family is Clang") + + elseif("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "XL") + set(Fortran_COMPILER_FAMILY_IS_XL 1) + message(STATUS "Fortran Compiler family is XL") + + elseif("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "Intel") + set(Fortran_COMPILER_FAMILY_IS_INTEL 1) + message(STATUS "Fortran Compiler family is Intel") + + elseif("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "PGI") + set(Fortran_COMPILER_FAMILY_IS_PGI 1) + message(STATUS "Fortran Compiler family is PGI") + + elseif("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "Cray") + set(Fortran_COMPILER_FAMILY_IS_CRAY 1) + message(STATUS "Fortran Compiler family is Cray") + + elseif(ENABLE_FORTRAN) + message(STATUS "Fortran Compiler family not set!!!") + endif() +endif() + + +################################################ +# Support for extra compiler flags and defines +################################################ + +message(STATUS "Adding optional BLT definitions and compiler flags") + +#################################################### +# create relocatable static libs by default +#################################################### +set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) + +############################################## +# Support extra definitions for all targets +############################################## +if(BLT_DEFINES) + add_definitions(${BLT_DEFINES}) + message(STATUS "Added \"${BLT_DEFINES}\" to definitions") +endif() + +if(COMPILER_FAMILY_IS_MSVC) + # Visual studio can give a warning that /bigobj is required due to the size of some object files + set( BLT_CXX_FLAGS "${BLT_CXX_FLAGS} /bigobj" ) + set( BLT_C_FLAGS "${BLT_C_FLAGS} /bigobj" ) +endif() + +########################################## +# If set, BLT__FLAGS are added to +# all targets that use -Compiler +########################################## + +########################################## +# Support extra flags for the C compiler. +########################################## +if(BLT_C_FLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BLT_C_FLAGS}") + message(STATUS "Updated CMAKE_C_FLAGS to \"${CMAKE_C_FLAGS}\"") +endif() + +############################################# +# Support extra flags for the C++ compiler. +############################################# +if(BLT_CXX_FLAGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BLT_CXX_FLAGS}") + message(STATUS "Updated CMAKE_CXX_FLAGS to \"${CMAKE_CXX_FLAGS}\"") +endif() + +################################################ +# Support extra flags for the Fortran compiler. +################################################ +if(ENABLE_FORTRAN AND BLT_FORTRAN_FLAGS) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${BLT_FORTRAN_FLAGS}") + message(STATUS "Updated CMAKE_Fortran_FLAGS to \"${CMAKE_Fortran_FLAGS}\"") +endif() + + +############################################################ +# Map Legacy FindCUDA variables to native cmake variables +# Note - we are intentionally breaking the semicolon delimited +# list that FindCUDA demanded of CUDA_NVCC_FLAGS so users +# are forced to clean up their host configs. +############################################################ +if (ENABLE_CUDA) + if (BLT_CUDA_FLAGS) + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${BLT_CUDA_FLAGS}") + endif() + # quirk of ordering means that one needs to define -std=c++11 in CMAKE_CUDA_FLAGS if + # --expt-extended-lambda is being used so cmake can get past the compiler check, + # but the CMAKE_CUDA_STANDARD stuff adds another definition in which breaks things. + # So we rip it out here, but it ends up being inserted in the final build rule by cmake. + if (CMAKE_CUDA_FLAGS) + STRING(REPLACE "-std=c++11" " " CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS} ) + endif() +endif() + + +################################################ +# Support extra linker flags +################################################ +if(BLT_EXE_LINKER_FLAGS) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${BLT_EXE_LINKER_FLAGS}") + message(STATUS "Updated CMAKE_EXE_LINKER_FLAGS to \"${CMAKE_EXE_LINKER_FLAGS}\"") +endif() + + +############################################################### +# Support extra flags based on CMake configuration type +############################################################### +# +# We guard this approach to avoid issues with CMake generators +# that support multiple configurations, like Visual Studio. +# +############################################################### +if(NOT CMAKE_CONFIGURATION_TYPES) + + set(cfg_types DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + + foreach(cfg_type in ${cfg_types}) + # flags for the C compiler + if(BLT_C_FLAGS_${cfg_type}) + set(CMAKE_C_FLAGS_${cfg_type} + "${CMAKE_C_FLAGS_${cfg_type}} ${BLT_C_FLAGS_${cfg_type}}") + message(STATUS "Updated CMAKE_C_FLAGS_${cfg_type} to \"${CMAKE_C_FLAGS_${cfg_type}}\"") + endif() + + # flags for the C++ compiler + if(BLT_CXX_FLAGS_${cfg_type}) + set(CMAKE_CXX_FLAGS_${cfg_type} + "${CMAKE_CXX_FLAGS_${cfg_type}} ${BLT_CXX_FLAGS_${cfg_type}}") + message(STATUS "Updated CMAKE_CXX_FLAGS_${cfg_type} to \"${CMAKE_CXX_FLAGS_${cfg_type}}\"") + endif() + + # flags for the Fortran compiler + if(ENABLE_FORTRAN AND BLT_FORTRAN_FLAGS_${cfg_type}) + set(CMAKE_Fortran_FLAGS_${cfg_type} + "${CMAKE_Fortran_FLAGS_${cfg_type}} ${BLT_FORTRAN_FLAGS_${cfg_type}}") + message(STATUS "Updated CMAKE_Fortran_FLAGS_${cfg_type} to \"${CMAKE_Fortran_FLAGS_${cfg_type}}\"") + endif() + + endforeach() + +endif() + + + +################################ +# RPath Settings +################################ +# only apply rpath settings for builds using shared libs +if(BUILD_SHARED_LIBS) + # use, i.e. don't skip the full RPATH for the build tree + set(CMAKE_SKIP_BUILD_RPATH FALSE) + + # when building, don't use the install RPATH already + # (but later on when installing) + set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib") + + # add the automatically determined parts of the RPATH + # which point to directories outside the build tree to the install RPATH + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + + # the RPATH to be used when installing, but only if it's not a system directory + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) + if("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + endif() +endif() + +################################ +# C++ Standard +################################ + +SET( CMAKE_CXX_EXTENSIONS OFF ) +SET( CMAKE_CXX_STANDARD_REQUIRED ON ) + +set(BLT_CXX_STD "" CACHE STRING "Version of C++ standard") +set_property(CACHE BLT_CXX_STD PROPERTY STRINGS c++98 c++11 c++14 c++17) + +if (BLT_CXX_STD) + if( BLT_CXX_STD STREQUAL c++98 ) + set(CMAKE_CXX_STANDARD 98) + elseif( BLT_CXX_STD STREQUAL c++11 ) + set(CMAKE_CXX_STANDARD 11) + blt_append_custom_compiler_flag( + FLAGS_VAR CMAKE_CXX_FLAGS + DEFAULT " " + XL "-std=c++11" + PGI "--c++11") + elseif( BLT_CXX_STD STREQUAL c++14) + set(CMAKE_CXX_STANDARD 14) + blt_append_custom_compiler_flag( + FLAGS_VAR CMAKE_CXX_FLAGS + DEFAULT " " + XL "-std=c++1y" + PGI "--c++14") + elseif( BLT_CXX_STD STREQUAL c++17) + # Error out on what does not support C++17 + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL") + message(FATAL_ERROR "XL does not support C++17.") + endif() + if (ENABLE_CUDA) + message(FATAL_ERROR "CMake's CUDA_STANDARD does not support C++17.") + endif() + + set(CMAKE_CXX_STANDARD 17) + blt_append_custom_compiler_flag( + FLAGS_VAR CMAKE_CXX_FLAGS + DEFAULT " " + PGI "--c++17") + else() + message(FATAL_ERROR "${BLT_CXX_STD} is an invalid entry for BLT_CXX_STD. " + "Valid Options are ( c++98, c++11, c++14, c++17 )") + endif() + + if (ENABLE_CUDA) + set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD}) + endif() + + message(STATUS "Standard C++${CMAKE_CXX_STANDARD} selected") +endif() + + +################################################################## +# Additional compiler warnings and treatment of warnings as errors +################################################################## + +blt_append_custom_compiler_flag( + FLAGS_VAR BLT_ENABLE_ALL_WARNINGS_C_FLAG + DEFAULT "-Wall -Wextra" + CLANG "-Wall -Wextra" + # Additional possibilities for clang include: + # "-Wdocumentation -Wdeprecated -Weverything" + HCC "-Wall" + PGI "-Minform=warn" + MSVC "/W4" + # Additional possibilities for visual studio include: + # "/Wall /wd4619 /wd4668 /wd4820 /wd4571 /wd4710" + XL " " # qinfo= produces additional messages on XL + # qflag=: defines min severity level to produce messages on XL + # where x is i info, w warning, e error, s severe; default is: + # (default is qflag=i:i) + ) + +blt_append_custom_compiler_flag( + FLAGS_VAR BLT_ENABLE_ALL_WARNINGS_CXX_FLAG + DEFAULT "-Wall -Wextra" + CLANG "-Wall -Wextra" + # Additional possibilities for clang include: + # "-Wdocumentation -Wdeprecated -Weverything" + HCC "-Wall" + PGI "-Minform=warn" + MSVC "/W4" + # Additional possibilities for visual studio include: + # "/Wall /wd4619 /wd4668 /wd4820 /wd4571 /wd4710" + XL " " # qinfo= produces additional messages on XL + # qflag=: defines min severity level to produce messages on XL + # where x is i info, w warning, e error, s severe; default is: + # (default is qflag=i:i) + ) + +blt_append_custom_compiler_flag( + FLAGS_VAR BLT_WARNINGS_AS_ERRORS_CXX_FLAG + DEFAULT "-Werror" + MSVC "/WX" + XL "-qhalt=w" + ) + +blt_append_custom_compiler_flag( + FLAGS_VAR BLT_WARNINGS_AS_ERRORS_C_FLAG + DEFAULT "-Werror" + MSVC "/WX" + PGI " " + XL "-qhalt=w" + ) + +# +# Modify flags to avoid static linking runtime issues on MS Windows. +# +# When building on Windows, you can link in the runtime library +# - statically (with /MT), or +# - dynamically (with /MD). +# See https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=vs-2019. +# +# Mixing /MD with /MT can cause linking errors. CMake specifies +# /MD when generating project files for MSVC and provides no way to +# change this. This can be a problem with Google Test in particular, +# which when building statically replaces all /MD with /MT. HDF5, on +# the other hand, sternly warns against the use of /MT, even when +# built statically. +# +# See https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace. +# Once we require CMake >= 3.15 we can address the issue differently, using +# CMAKE_MSVC_RUNTIME_LIBRARY: +# https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html +# + +if ( COMPILER_FAMILY_IS_MSVC AND NOT BUILD_SHARED_LIBS ) + if ( BLT_ENABLE_MSVC_STATIC_MD_TO_MT ) + foreach(_lang C CXX) + foreach(_build + FLAGS FLAGS_DEBUG FLAGS_RELEASE + FLAGS_MINSIZEREL FLAGS_RELWITHDEBINFO) + set(_flag CMAKE_${_lang}_${_build}) + if(${_flag} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${_flag} "${${_flag}}") + endif() + endforeach() + endforeach() + elseif (ENABLE_GTEST) + message(FATAL_ERROR + "For static linking with MS Visual Studio using GTEST, you must set BLT_ENABLE_MSVC_STATIC_MD_TO_MT to ON in order to enable changing /MD to /MT.") + endif() +endif() + +set(langFlags "CMAKE_C_FLAGS" "CMAKE_CXX_FLAGS") + +if (ENABLE_ALL_WARNINGS) + message(STATUS "Enabling all compiler warnings on all targets.") + + + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BLT_ENABLE_ALL_WARNINGS_CXX_FLAG}") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BLT_ENABLE_ALL_WARNINGS_C_FLAG}") +endif() + +if (ENABLE_WARNINGS_AS_ERRORS) + message(STATUS "Enabling treatment of warnings as errors on all targets.") + + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BLT_WARNINGS_AS_ERRORS_CXX_FLAG}") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BLT_WARNINGS_AS_ERRORS_C_FLAG}") +endif() + +################################ +# Enable Fortran +################################ +if(ENABLE_FORTRAN) + # if enabled but no fortran compiler, halt the configure + if(CMAKE_Fortran_COMPILER) + message(STATUS "Fortran support enabled.") + else() + message(FATAL_ERROR "Fortran support selected, but no Fortran compiler was found.") + endif() + + list(APPEND langFlags "CMAKE_Fortran_FLAGS") +else() + message(STATUS "Fortran support disabled.") +endif() + +################################### +# Output compiler and linker flags +################################### +foreach(flagVar ${langFlags} "CMAKE_EXE_LINKER_FLAGS" ) + message(STATUS "${flagVar} flags are: ${${flagVar}}") +endforeach() diff --git a/tpl/RAJA/blt/cmake/SetupDocs.cmake b/tpl/RAJA/blt/cmake/SetupDocs.cmake new file mode 100644 index 000000000..6b99b0769 --- /dev/null +++ b/tpl/RAJA/blt/cmake/SetupDocs.cmake @@ -0,0 +1,107 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) +#------------------------------------------------------------------------------ +# Sets up targets and macros associated with documentation +#------------------------------------------------------------------------------ + +add_custom_target(${BLT_DOCS_TARGET_NAME}) + +if(DOXYGEN_FOUND) + add_custom_target(doxygen_docs) + add_dependencies(${BLT_DOCS_TARGET_NAME} doxygen_docs) +endif() + +if(SPHINX_FOUND) + add_custom_target(sphinx_docs) + add_dependencies(${BLT_DOCS_TARGET_NAME} sphinx_docs) +endif() + + +##------------------------------------------------------------------------------ +## blt_add_doxygen_target(doxygen_target_name) +## +## Creates a build target for invoking doxygen to generate docs +##------------------------------------------------------------------------------ +macro(blt_add_doxygen_target doxygen_target_name) + + # add a target to generate API documentation with Doxygen + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + add_custom_target(${doxygen_target_name} + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen for ${doxygen_target_name} target" VERBATIM) + + add_dependencies(doxygen_docs ${doxygen_target_name}) + + install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} ${doxygen_target_name} WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") + + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html" + DESTINATION docs/doxygen/${doxygen_target_name} OPTIONAL) + +endmacro(blt_add_doxygen_target) + + +##------------------------------------------------------------------------------ +## blt_add_sphinx_target(sphinx_target_name) +## +## Creates a build target for invoking sphinx to generate docs +##------------------------------------------------------------------------------ +macro(blt_add_sphinx_target sphinx_target_name ) + + # configured documentation tools and intermediate build results + set(SPHINX_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build") + + # Sphinx cache with pickled ReST documents + set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees") + + # HTML output directory + set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html") + + # support both direct use of a conf.py file and a cmake-configured + # sphinx input file (conf.py.in). The cmake-configured input file is + # preferred when both exist. + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in") + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" + "${SPHINX_BUILD_DIR}/conf.py" + @ONLY) + + add_custom_target(${sphinx_target_name} + ${SPHINX_EXECUTABLE} + -q -b html + #-W disable warn on error for now, while our sphinx env is still in flux + -c "${SPHINX_BUILD_DIR}" + -d "${SPHINX_CACHE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" + "${SPHINX_HTML_DIR}" + COMMENT "Building HTML documentation with Sphinx for ${sphinx_target_name} target" + DEPENDS ${deps}) + elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/conf.py") + add_custom_target(${sphinx_target_name} + ${SPHINX_EXECUTABLE} + -q -b html + #-W disable warn on error for now, while our sphinx env is still in flux + -d "${SPHINX_CACHE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" + "${SPHINX_HTML_DIR}" + COMMENT "Building HTML documentation with Sphinx for ${sphinx_target_name} target" + DEPENDS ${deps}) + else() + message(FATAL_ERROR "Failed to find sphinx 'conf.py' or 'conf.py.in' in ${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + # hook our new target into the docs dependency chain + add_dependencies(sphinx_docs ${sphinx_target_name}) + + ###### + # This snippet makes sure if we do a make install w/o the optional "docs" + # target built, it will be built during the install process. + ###### + + install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} ${sphinx_target_name} WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") + + install(DIRECTORY "${SPHINX_HTML_DIR}" + DESTINATION "docs/sphinx/${sphinx_target_name}" OPTIONAL) + +endmacro(blt_add_sphinx_target) diff --git a/tpl/RAJA/blt/cmake/WrapAstyle.cmake.in b/tpl/RAJA/blt/cmake/WrapAstyle.cmake.in new file mode 100644 index 000000000..1ea3dea30 --- /dev/null +++ b/tpl/RAJA/blt/cmake/WrapAstyle.cmake.in @@ -0,0 +1,61 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +############################################################################### +# Wrapper script to attach return codes to AStyle runs for @arg_NAME@ target +# +# BLT code formatting targets are expected to fail when one or more source files +# are improperly formatted. This script runs AStyle and parses the output +# to return an appropriate return code. +# +# All required variables are set up in the 'blt_add_astyle_target' macro. +############################################################################### + +# Set up required variables +set(ASTYLE_TARGET @arg_NAME@) +set(ASTYLE_EXECUTABLE @ASTYLE_EXECUTABLE@) +set(ASTYLE_PREPEND_FLAGS @arg_PREPREND_FLAGS@) +set(ASTYLE_CFG_FILE @arg_CFG_FILE@) +set(ASTYLE_MODIFY_FILES_FLAGS @MODIFY_FILES_FLAG@) +set(ASTYLE_SOURCE_FILES @arg_SRC_FILES@) +set(ASTYLE_APPEND_FLAGS @arg_PREPREND_FLAGS@) +set(ASTYLE_WORKING_DIRECTORY @_wd@) + +# Invoke AStyle +execute_process( + COMMAND ${ASTYLE_EXECUTABLE} + ${ASTYLE_PREPEND_FLAGS} + --options=${ASTYLE_CFG_FILE} --formatted + ${ASTYLE_MODIFY_FILES_FLAGS} + ${ASTYLE_SOURCE_FILES} + ${ASTYLE_APPEND_FLAGS} + WORKING_DIRECTORY ${ASTYLE_WORKING_DIRECTORY} + OUTPUT_VARIABLE _astyle_output_var + ERROR_VARIABLE _astyle_error_var + RESULT_VARIABLE _astyle_result + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE ) + +# Early return if unsuccessful +if(NOT ${_astyle_result} EQUAL 0) + message(FATAL_ERROR ${_astyle_error_var}) +endif() + +# Otherwise, parse the output. +# Script fails where there are lines beginning with "Formatted ..." +if(NOT ${_astyle_output_var} STREQUAL "") + # Display output of AStyle command + message(STATUS "AStyle output for '${ASTYLE_TARGET}' target\n" ${_astyle_output_var}) + + # Convert output to list + string(REGEX REPLACE "\n" ";" _astyle_output_var "${_astyle_output_var}") + + # Apply regex and check for matches + string(REGEX MATCHALL "(;)?Formatted" _matches ${_astyle_output_var}) + list(LENGTH _matches len) + if(NOT ${len} EQUAL 0) + message(FATAL_ERROR "AStyle found ${len} improperly formatted files.") + endif() +endif() \ No newline at end of file diff --git a/tpl/RAJA/blt/cmake/clang-query-wrapper.py b/tpl/RAJA/blt/cmake/clang-query-wrapper.py new file mode 100644 index 000000000..005d4ef58 --- /dev/null +++ b/tpl/RAJA/blt/cmake/clang-query-wrapper.py @@ -0,0 +1,84 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +import sys,os,argparse +import subprocess +import re +#credit: https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python + + + +parser = argparse.ArgumentParser(description="Runs clang-query against a set of files") +parser.add_argument("-i",action="store_true",help="Run in interactive mode (don't error on matches, don't run all matchers)",dest="interactive") +parser.add_argument("--die-on-match",action="store_true",help="Return an error code if matches are found",dest="die_on_match") +parser.add_argument("--checkers",action="store",help="List of checkers to always run",dest="checkers") +parser.add_argument("--clang-query",action="store",help="Location of clang-query executable",dest="query_executable") +parser.add_argument("--compilation-database-path",action="store",help="Location of compilation database",dest="compilation_database_directory") +parser.add_argument("--checker-directories",action="store",help="Directories in which checkers can be found",dest="checker_directories") +parser.add_argument("files",nargs="+",help="Files to query") +args = parser.parse_args() +checker_directories = args.checker_directories + +if len(checker_directories)==0: + print("No directories with checkers found") + sys.exit(1) + +def get_all_checkers(): + checker_files = {} + for directory in checker_directories.split(":"): + for file_name in os.listdir(directory): + checker_key = file_name.split("/")[-1] + checker_files[checker_key] = directory+"/"+file_name + return checker_files + +def get_all_checker_files(checker_dict): + return [checker_dict[key] for key in checker_dict] + +invocation = args.query_executable+" -p="+args.compilation_database_directory+" " +interactive = args.interactive +interpreter = False +arg_checkers = args.checkers +die_on_match = args.die_on_match +available_checkers = get_all_checkers() +checker_files = [] +if interactive: + checker_string = os.getenv("checker") + if checker_string is None: + checker_files = get_all_checker_files(available_checkers) + elif checker_string != "interpreter": + environment_desired_checkers = checker_string.split(":") + arg_desired_checkers = [] + if arg_checkers is not None: + arg_desired_checkers = arg_checkers.split(":") + all_desired_checkers = arg_desired_checkers + environment_desired_checkers + desired_checkers = [checker for checker in all_desired_checkers if len(checker)>0] # filter out the empty entries from unspecified sources + unavailable_checkers = [checker for checker in desired_checkers if checker not in available_checkers] + if len(unavailable_checkers)>0: + print("Error, request for checker(s) "+",".join(unavailable_checkers)+" which could not be found") + sys.exit(1) + checker_files = [available_checkers[checker] for checker in desired_checkers] + else: + interpreter=True +else: + checker_files = get_all_checker_files(available_checkers) + +if len(checker_files)==0 and not interactive: + print("No static analysis files found in static analysis directories, exiting.") + sys.exit(1) + +for file_name in checker_files: + invocation+="-f "+file_name+" " + +invocation+=" ".join(args.files) +if not interpreter: + output = subprocess.check_output(invocation, shell=True) + print(output) + if die_on_match: + if re.search("[1-9][0-9]* matche?s?.",output) is not None: + print("Code fails static analysis CI, exiting") + sys.exit(1) +else: + subprocess.call(invocation, shell=True, stdout=sys.stdout) +sys.exit(0) diff --git a/tpl/RAJA/blt/cmake/thirdparty/FindHIP.cmake b/tpl/RAJA/blt/cmake/thirdparty/FindHIP.cmake new file mode 100644 index 000000000..942a20b2c --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/FindHIP.cmake @@ -0,0 +1,582 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +############################################################################### +# FindHIP.cmake +############################################################################### + +############################################################################### +# SET: Variable defaults +############################################################################### +# User defined flags +set(HIP_HIPCC_FLAGS "" CACHE STRING "Semicolon delimited flags for HIPCC") +set(HIP_HCC_FLAGS "" CACHE STRING "Semicolon delimited flags for HCC") +set(HIP_NVCC_FLAGS "" CACHE STRING "Semicolon delimted flags for NVCC") +mark_as_advanced(HIP_HIPCC_FLAGS HIP_HCC_FLAGS HIP_NVCC_FLAGS) +set(_hip_configuration_types ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE} Debug MinSizeRel Release RelWithDebInfo) +list(REMOVE_DUPLICATES _hip_configuration_types) +foreach(config ${_hip_configuration_types}) + string(TOUPPER ${config} config_upper) + set(HIP_HIPCC_FLAGS_${config_upper} "" CACHE STRING "Semicolon delimited flags for HIPCC") + set(HIP_HCC_FLAGS_${config_upper} "" CACHE STRING "Semicolon delimited flags for HCC") + set(HIP_NVCC_FLAGS_${config_upper} "" CACHE STRING "Semicolon delimited flags for NVCC") + mark_as_advanced(HIP_HIPCC_FLAGS_${config_upper} HIP_HCC_FLAGS_${config_upper} HIP_NVCC_FLAGS_${config_upper}) +endforeach() +option(HIP_HOST_COMPILATION_CPP "Host code compilation mode" ON) +option(HIP_VERBOSE_BUILD "Print out the commands run while compiling the HIP source file. With the Makefile generator this defaults to VERBOSE variable specified on the command line, but can be forced on with this option." OFF) +mark_as_advanced(HIP_HOST_COMPILATION_CPP) + +############################################################################### +# Set HIP CMAKE Flags +############################################################################### +# Copy the invocation styles from CXX to HIP +set(CMAKE_HIP_ARCHIVE_CREATE ${CMAKE_CXX_ARCHIVE_CREATE}) +set(CMAKE_HIP_ARCHIVE_APPEND ${CMAKE_CXX_ARCHIVE_APPEND}) +set(CMAKE_HIP_ARCHIVE_FINISH ${CMAKE_CXX_ARCHIVE_FINISH}) +set(CMAKE_SHARED_LIBRARY_SONAME_HIP_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG}) +set(CMAKE_SHARED_LIBRARY_CREATE_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS}) +set(CMAKE_SHARED_LIBRARY_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +#set(CMAKE_SHARED_LIBRARY_LINK_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS}) +set(CMAKE_SHARED_LIBRARY_RUNTIME_HIP_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}) +set(CMAKE_SHARED_LIBRARY_RUNTIME_HIP_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP}) +set(CMAKE_SHARED_LIBRARY_LINK_STATIC_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_STATIC_CXX_FLAGS}) +set(CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_CXX_FLAGS}) + +# Set the CMake Flags to use the HCC Compilier. +set(CMAKE_HIP_CREATE_SHARED_LIBRARY "${HIP_HIPCC_CMAKE_LINKER_HELPER} ${HCC_PATH} -o ") +set(CMAKE_HIP_CREATE_SHARED_MODULE "${HIP_HIPCC_CMAKE_LINKER_HELPER} ${HCC_PATH} -o -shared" ) +set(CMAKE_HIP_LINK_EXECUTABLE "${HIP_HIPCC_CMAKE_LINKER_HELPER} ${HCC_PATH} -o ") + +############################################################################### +# FIND: HIP and associated helper binaries +############################################################################### +# HIP is supported on Linux only +if(UNIX AND NOT APPLE AND NOT CYGWIN) + # Search for HIP installation + if(NOT HIP_ROOT_DIR) + # Search in user specified path first + find_path( + HIP_ROOT_DIR + NAMES hipconfig + PATHS + ENV ROCM_PATH + ENV HIP_PATH + PATH_SUFFIXES bin + DOC "HIP installed location" + NO_DEFAULT_PATH + ) + # Now search in default path + find_path( + HIP_ROOT_DIR + NAMES hipconfig + PATHS + /opt/rocm + /opt/rocm/hip + PATH_SUFFIXES bin + DOC "HIP installed location" + ) + + # Check if we found HIP installation + if(HIP_ROOT_DIR) + # If so, fix the path + string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" HIP_ROOT_DIR ${HIP_ROOT_DIR}) + # And push it back to the cache + set(HIP_ROOT_DIR ${HIP_ROOT_DIR} CACHE PATH "HIP installed location" FORCE) + endif() + if(NOT EXISTS ${HIP_ROOT_DIR}) + if(HIP_FIND_REQUIRED) + message(FATAL_ERROR "Specify HIP_ROOT_DIR") + elseif(NOT HIP_FIND_QUIETLY) + message("HIP_ROOT_DIR not found or specified") + endif() + endif() + endif() + + # Find HIPCC executable + find_program( + HIP_HIPCC_EXECUTABLE + NAMES hipcc + PATHS + "${HIP_ROOT_DIR}" + ENV ROCM_PATH + ENV HIP_PATH + /opt/rocm + /opt/rocm/hip + PATH_SUFFIXES bin + NO_DEFAULT_PATH + ) + if(NOT HIP_HIPCC_EXECUTABLE) + # Now search in default paths + find_program(HIP_HIPCC_EXECUTABLE hipcc) + endif() + mark_as_advanced(HIP_HIPCC_EXECUTABLE) + + # Find HIPCONFIG executable + find_program( + HIP_HIPCONFIG_EXECUTABLE + NAMES hipconfig + PATHS + "${HIP_ROOT_DIR}" + ENV ROCM_PATH + ENV HIP_PATH + /opt/rocm + /opt/rocm/hip + PATH_SUFFIXES bin + NO_DEFAULT_PATH + ) + if(NOT HIP_HIPCONFIG_EXECUTABLE) + # Now search in default paths + find_program(HIP_HIPCONFIG_EXECUTABLE hipconfig) + endif() + mark_as_advanced(HIP_HIPCONFIG_EXECUTABLE) + + # Find HIPCC_CMAKE_LINKER_HELPER executable + find_program( + HIP_HIPCC_CMAKE_LINKER_HELPER + NAMES hipcc_cmake_linker_helper + PATHS + "${HIP_ROOT_DIR}" + ENV ROCM_PATH + ENV HIP_PATH + /opt/rocm + /opt/rocm/hip + PATH_SUFFIXES bin + NO_DEFAULT_PATH + ) + if(NOT HIP_HIPCC_CMAKE_LINKER_HELPER) + # Now search in default paths + find_program(HIP_HIPCC_CMAKE_LINKER_HELPER hipcc_cmake_linker_helper) + endif() + mark_as_advanced(HIP_HIPCC_CMAKE_LINKER_HELPER) + + if(HIP_HIPCONFIG_EXECUTABLE AND NOT HIP_VERSION) + # Compute the version + execute_process( + COMMAND ${HIP_HIPCONFIG_EXECUTABLE} --version + OUTPUT_VARIABLE _hip_version + ERROR_VARIABLE _hip_error + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + if(NOT _hip_error) + set(HIP_VERSION ${_hip_version} CACHE STRING "Version of HIP as computed from hipcc") + else() + set(HIP_VERSION "0.0.0" CACHE STRING "Version of HIP as computed by FindHIP()") + endif() + mark_as_advanced(HIP_VERSION) + endif() + if(HIP_VERSION) + string(REPLACE "." ";" _hip_version_list "${HIP_VERSION}") + list(GET _hip_version_list 0 HIP_VERSION_MAJOR) + list(GET _hip_version_list 1 HIP_VERSION_MINOR) + list(GET _hip_version_list 2 HIP_VERSION_PATCH) + set(HIP_VERSION_STRING "${HIP_VERSION}") + endif() + + if(HIP_HIPCONFIG_EXECUTABLE AND NOT HIP_PLATFORM) + # Compute the platform + execute_process( + COMMAND ${HIP_HIPCONFIG_EXECUTABLE} --platform + OUTPUT_VARIABLE _hip_platform + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(HIP_PLATFORM ${_hip_platform} CACHE STRING "HIP platform as computed by hipconfig") + mark_as_advanced(HIP_PLATFORM) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + HIP + REQUIRED_VARS + HIP_ROOT_DIR + HIP_HIPCC_EXECUTABLE + HIP_HIPCONFIG_EXECUTABLE + HIP_PLATFORM + VERSION_VAR HIP_VERSION + ) + +############################################################################### +# MACRO: Locate helper files +############################################################################### +macro(HIP_FIND_HELPER_FILE _name _extension) + set(_hip_full_name "${_name}.${_extension}") + get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + set(HIP_${_name} "${CMAKE_CURRENT_LIST_DIR}/FindHIP/${_hip_full_name}") + if(NOT EXISTS "${HIP_${_name}}") + set(error_message "${_hip_full_name} not found in ${CMAKE_CURRENT_LIST_DIR}/FindHIP") + if(HIP_FIND_REQUIRED) + message(FATAL_ERROR "${error_message}") + else() + if(NOT HIP_FIND_QUIETLY) + message(STATUS "${error_message}") + endif() + endif() + endif() + # Set this variable as internal, so the user isn't bugged with it. + set(HIP_${_name} ${HIP_${_name}} CACHE INTERNAL "Location of ${_full_name}" FORCE) +endmacro() + +############################################################################### +hip_find_helper_file(run_make2cmake cmake) +hip_find_helper_file(run_hipcc cmake) +############################################################################### + +############################################################################### +# MACRO: Reset compiler flags +############################################################################### +macro(HIP_RESET_FLAGS) + unset(HIP_HIPCC_FLAGS) + unset(HIP_HCC_FLAGS) + unset(HIP_NVCC_FLAGS) + foreach(config ${_hip_configuration_types}) + string(TOUPPER ${config} config_upper) + unset(HIP_HIPCC_FLAGS_${config_upper}) + unset(HIP_HCC_FLAGS_${config_upper}) + unset(HIP_NVCC_FLAGS_${config_upper}) + endforeach() +endmacro() + +############################################################################### +# MACRO: Separate the options from the sources +############################################################################### +macro(HIP_GET_SOURCES_AND_OPTIONS _sources _cmake_options _hipcc_options _hcc_options _nvcc_options) + set(${_sources}) + set(${_cmake_options}) + set(${_hipcc_options}) + set(${_hcc_options}) + set(${_nvcc_options}) + set(_hipcc_found_options FALSE) + set(_hcc_found_options FALSE) + set(_nvcc_found_options FALSE) + foreach(arg ${ARGN}) + if("x${arg}" STREQUAL "xHIPCC_OPTIONS") + set(_hipcc_found_options TRUE) + set(_hcc_found_options FALSE) + set(_nvcc_found_options FALSE) + elseif("x${arg}" STREQUAL "xHCC_OPTIONS") + set(_hipcc_found_options FALSE) + set(_hcc_found_options TRUE) + set(_nvcc_found_options FALSE) + elseif("x${arg}" STREQUAL "xNVCC_OPTIONS") + set(_hipcc_found_options FALSE) + set(_hcc_found_options FALSE) + set(_nvcc_found_options TRUE) + elseif( + "x${arg}" STREQUAL "xEXCLUDE_FROM_ALL" OR + "x${arg}" STREQUAL "xSTATIC" OR + "x${arg}" STREQUAL "xSHARED" OR + "x${arg}" STREQUAL "xMODULE" + ) + list(APPEND ${_cmake_options} ${arg}) + else() + if(_hipcc_found_options) + list(APPEND ${_hipcc_options} ${arg}) + elseif(_hcc_found_options) + list(APPEND ${_hcc_options} ${arg}) + elseif(_nvcc_found_options) + list(APPEND ${_nvcc_options} ${arg}) + else() + # Assume this is a file + list(APPEND ${_sources} ${arg}) + endif() + endif() + endforeach() +endmacro() + +############################################################################### +# MACRO: Add include directories to pass to the hipcc command +############################################################################### +set(HIP_HIPCC_INCLUDE_ARGS_USER "") +macro(HIP_INCLUDE_DIRECTORIES) + foreach(dir ${ARGN}) + list(APPEND HIP_HIPCC_INCLUDE_ARGS_USER $<$:-I${dir}>) + endforeach() +endmacro() + +############################################################################### +# FUNCTION: Helper to avoid clashes of files with the same basename but different paths +############################################################################### +function(HIP_COMPUTE_BUILD_PATH path build_path) + # Convert to cmake style paths + file(TO_CMAKE_PATH "${path}" bpath) + if(IS_ABSOLUTE "${bpath}") + string(FIND "${bpath}" "${CMAKE_CURRENT_BINARY_DIR}" _binary_dir_pos) + if(_binary_dir_pos EQUAL 0) + file(RELATIVE_PATH bpath "${CMAKE_CURRENT_BINARY_DIR}" "${bpath}") + else() + file(RELATIVE_PATH bpath "${CMAKE_CURRENT_SOURCE_DIR}" "${bpath}") + endif() + endif() + + # Remove leading / + string(REGEX REPLACE "^[/]+" "" bpath "${bpath}") + # Avoid absolute paths by removing ':' + string(REPLACE ":" "_" bpath "${bpath}") + # Avoid relative paths that go up the tree + string(REPLACE "../" "__/" bpath "${bpath}") + # Avoid spaces + string(REPLACE " " "_" bpath "${bpath}") + # Strip off the filename + get_filename_component(bpath "${bpath}" PATH) + + set(${build_path} "${bpath}" PARENT_SCOPE) +endfunction() + +############################################################################### +# MACRO: Parse OPTIONS from ARGN & set variables prefixed by _option_prefix +############################################################################### +macro(HIP_PARSE_HIPCC_OPTIONS _option_prefix) + set(_hip_found_config) + foreach(arg ${ARGN}) + # Determine if we are dealing with a per-configuration flag + foreach(config ${_hip_configuration_types}) + string(TOUPPER ${config} config_upper) + if(arg STREQUAL "${config_upper}") + set(_hip_found_config _${arg}) + # Clear arg to prevent it from being processed anymore + set(arg) + endif() + endforeach() + if(arg) + list(APPEND ${_option_prefix}${_hip_found_config} "${arg}") + endif() + endforeach() +endmacro() + +############################################################################### +# MACRO: Try and include dependency file if it exists +############################################################################### +macro(HIP_INCLUDE_HIPCC_DEPENDENCIES dependency_file) + set(HIP_HIPCC_DEPEND) + set(HIP_HIPCC_DEPEND_REGENERATE FALSE) + + # Create the dependency file if it doesn't exist + if(NOT EXISTS ${dependency_file}) + file(WRITE ${dependency_file} "# Generated by: FindHIP.cmake. Do not edit.\n") + endif() + # Include the dependency file + include(${dependency_file}) + + # Verify the existence of all the included files + if(HIP_HIPCC_DEPEND) + foreach(f ${HIP_HIPCC_DEPEND}) + if(NOT EXISTS ${f}) + # If they aren't there, regenerate the file again + set(HIP_HIPCC_DEPEND_REGENERATE TRUE) + endif() + endforeach() + else() + # No dependencies, so regenerate the file + set(HIP_HIPCC_DEPEND_REGENERATE TRUE) + endif() + + # Regenerate the dependency file if needed + if(HIP_HIPCC_DEPEND_REGENERATE) + set(HIP_HIPCC_DEPEND ${dependency_file}) + file(WRITE ${dependency_file} "# Generated by: FindHIP.cmake. Do not edit.\n") + endif() +endmacro() + +############################################################################### +# MACRO: Prepare cmake commands for the target +############################################################################### +macro(HIP_PREPARE_TARGET_COMMANDS _target _format _generated_files _source_files) + set(_hip_flags "") + string(TOUPPER "${CMAKE_BUILD_TYPE}" _hip_build_configuration) + if(HIP_HOST_COMPILATION_CPP) + set(HIP_C_OR_CXX CXX) + else() + set(HIP_C_OR_CXX C) + endif() + set(generated_extension ${CMAKE_${HIP_C_OR_CXX}_OUTPUT_EXTENSION}) + + # Initialize list of includes with those specified by the user. Append with + # ones specified to cmake directly. + set(HIP_HIPCC_INCLUDE_ARGS ${HIP_HIPCC_INCLUDE_ARGS_USER}) + + # Add the include directories + set(include_directories_generator "$") + list(APPEND HIP_HIPCC_INCLUDE_ARGS "$<$:-I$>") + + get_directory_property(_hip_include_directories INCLUDE_DIRECTORIES) + list(REMOVE_DUPLICATES _hip_include_directories) + if(_hip_include_directories) + foreach(dir ${_hip_include_directories}) + list(APPEND HIP_HIPCC_INCLUDE_ARGS $<$:-I${dir}>) + endforeach() + endif() + + HIP_GET_SOURCES_AND_OPTIONS(_hip_sources _hip_cmake_options _hipcc_options _hcc_options _nvcc_options ${ARGN}) + HIP_PARSE_HIPCC_OPTIONS(HIP_HIPCC_FLAGS ${_hipcc_options}) + HIP_PARSE_HIPCC_OPTIONS(HIP_HCC_FLAGS ${_hcc_options}) + HIP_PARSE_HIPCC_OPTIONS(HIP_NVCC_FLAGS ${_nvcc_options}) + + # Add the compile definitions + set(compile_definition_generator "$") + list(APPEND HIP_HIPCC_FLAGS "$<$:-D$>") + + # Check if we are building shared library. + set(_hip_build_shared_libs FALSE) + list(FIND _hip_cmake_options SHARED _hip_found_SHARED) + list(FIND _hip_cmake_options MODULE _hip_found_MODULE) + if(_hip_found_SHARED GREATER -1 OR _hip_found_MODULE GREATER -1) + set(_hip_build_shared_libs TRUE) + endif() + list(FIND _hip_cmake_options STATIC _hip_found_STATIC) + if(_hip_found_STATIC GREATER -1) + set(_hip_build_shared_libs FALSE) + endif() + + # If we are building a shared library, add extra flags to HIP_HIPCC_FLAGS + if(_hip_build_shared_libs) + list(APPEND HIP_HCC_FLAGS "-fPIC") + list(APPEND HIP_NVCC_FLAGS "--shared -Xcompiler '-fPIC'") + endif() + + # Set host compiler + set(HIP_HOST_COMPILER "${CMAKE_${HIP_C_OR_CXX}_COMPILER}") + + # Set compiler flags + set(_HIP_HOST_FLAGS "set(CMAKE_HOST_FLAGS ${CMAKE_${HIP_C_OR_CXX}_FLAGS})") + set(_HIP_HIPCC_FLAGS "set(HIP_HIPCC_FLAGS ${HIP_HIPCC_FLAGS})") + set(_HIP_HCC_FLAGS "set(HIP_HCC_FLAGS ${HIP_HCC_FLAGS})") + set(_HIP_NVCC_FLAGS "set(HIP_NVCC_FLAGS ${HIP_NVCC_FLAGS})") + foreach(config ${_hip_configuration_types}) + string(TOUPPER ${config} config_upper) + set(_HIP_HOST_FLAGS "${_HIP_HOST_FLAGS}\nset(CMAKE_HOST_FLAGS_${config_upper} ${CMAKE_${HIP_C_OR_CXX}_FLAGS_${config_upper}})") + set(_HIP_HIPCC_FLAGS "${_HIP_HIPCC_FLAGS}\nset(HIP_HIPCC_FLAGS_${config_upper} ${HIP_HIPCC_FLAGS_${config_upper}})") + set(_HIP_HCC_FLAGS "${_HIP_HCC_FLAGS}\nset(HIP_HCC_FLAGS_${config_upper} ${HIP_HCC_FLAGS_${config_upper}})") + set(_HIP_NVCC_FLAGS "${_HIP_NVCC_FLAGS}\nset(HIP_NVCC_FLAGS_${config_upper} ${HIP_NVCC_FLAGS_${config_upper}})") + endforeach() + + # Reset the output variable + set(_hip_generated_files "") + set(_hip_source_files "") + + # Iterate over all arguments and create custom commands for all source files + foreach(file ${ARGN}) + # Ignore any file marked as a HEADER_FILE_ONLY + get_source_file_property(_is_header ${file} HEADER_FILE_ONLY) + # Allow per source file overrides of the format. Also allows compiling non .cu files. + get_source_file_property(_hip_source_format ${file} HIP_SOURCE_PROPERTY_FORMAT) + if((${file} MATCHES "\\.cu$" OR _hip_source_format) AND NOT _is_header) + set(host_flag FALSE) + else() + set(host_flag TRUE) + endif() + + if(NOT host_flag) + # Determine output directory + HIP_COMPUTE_BUILD_PATH("${file}" hip_build_path) + set(hip_compile_output_dir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target}.dir/${hip_build_path}") + + get_filename_component(basename ${file} NAME) + set(generated_file_path "${hip_compile_output_dir}/${CMAKE_CFG_INTDIR}") + set(generated_file_basename "${_target}_generated_${basename}${generated_extension}") + + # Set file names + set(generated_file "${generated_file_path}/${generated_file_basename}") + set(cmake_dependency_file "${hip_compile_output_dir}/${generated_file_basename}.depend") + set(custom_target_script_pregen "${hip_compile_output_dir}/${generated_file_basename}.cmake.pre-gen") + set(custom_target_script "${hip_compile_output_dir}/${generated_file_basename}.cmake") + + # Set properties for object files + set_source_files_properties("${generated_file}" + PROPERTIES + EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked + ) + + # Don't add CMAKE_CURRENT_SOURCE_DIR if the path is already an absolute path + get_filename_component(file_path "${file}" PATH) + if(IS_ABSOLUTE "${file_path}") + set(source_file "${file}") + else() + set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}") + endif() + + # Bring in the dependencies + HIP_INCLUDE_HIPCC_DEPENDENCIES(${cmake_dependency_file}) + + # Configure the build script + configure_file("${HIP_run_hipcc}" "${custom_target_script_pregen}" @ONLY) + file(GENERATE + OUTPUT "${custom_target_script}" + INPUT "${custom_target_script_pregen}" + ) + set(main_dep DEPENDS ${source_file}) + if(CMAKE_GENERATOR MATCHES "Makefiles") + set(verbose_output "$(VERBOSE)") + elseif(HIP_VERBOSE_BUILD) + set(verbose_output ON) + else() + set(verbose_output OFF) + endif() + + # Create up the comment string + file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}") + set(hip_build_comment_string "Building HIPCC object ${generated_file_relative_path}") + + # Build the generated file and dependency file + add_custom_command( + OUTPUT ${generated_file} + # These output files depend on the source_file and the contents of cmake_dependency_file + ${main_dep} + DEPENDS ${HIP_HIPCC_DEPEND} + DEPENDS ${custom_target_script} + # Make sure the output directory exists before trying to write to it. + COMMAND ${CMAKE_COMMAND} -E make_directory "${generated_file_path}" + COMMAND ${CMAKE_COMMAND} ARGS + -D verbose:BOOL=${verbose_output} + -D build_configuration:STRING=${_hip_build_configuration} + -D "generated_file:STRING=${generated_file}" + -P "${custom_target_script}" + WORKING_DIRECTORY "${hip_compile_output_dir}" + COMMENT "${hip_build_comment_string}" + ) + + # Make sure the build system knows the file is generated + set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE) + list(APPEND _hip_generated_files ${generated_file}) + list(APPEND _hip_source_files ${file}) + endif() + endforeach() + + # Set the return parameter + set(${_generated_files} ${_hip_generated_files}) + set(${_source_files} ${_hip_source_files}) +endmacro() + +############################################################################### +# HIP_ADD_EXECUTABLE +############################################################################### +macro(HIP_ADD_EXECUTABLE hip_target) + # Separate the sources from the options + HIP_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _hipcc_options _hcc_options _nvcc_options ${ARGN}) + HIP_PREPARE_TARGET_COMMANDS(${hip_target} OBJ _generated_files _source_files ${_sources} HIPCC_OPTIONS ${_hipcc_options} HCC_OPTIONS ${_hcc_options} NVCC_OPTIONS ${_nvcc_options}) + if(_source_files) + list(REMOVE_ITEM _sources ${_source_files}) + endif() + if("x${HCC_HOME}" STREQUAL "x") + set(HCC_HOME "/opt/rocm/hcc") + endif() + set(CMAKE_HIP_LINK_EXECUTABLE "${HIP_HIPCC_CMAKE_LINKER_HELPER} ${HCC_HOME} -o ") + add_executable(${hip_target} ${_cmake_options} ${_generated_files} ${_sources}) + set_target_properties(${hip_target} PROPERTIES LINKER_LANGUAGE HIP) +endmacro() + +############################################################################### +# HIP_ADD_LIBRARY +############################################################################### +macro(HIP_ADD_LIBRARY hip_target) + # Separate the sources from the options + HIP_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _hipcc_options _hcc_options _nvcc_options ${ARGN}) + HIP_PREPARE_TARGET_COMMANDS(${hip_target} OBJ _generated_files _source_files ${_sources} ${_cmake_options} HIPCC_OPTIONS ${_hipcc_options} HCC_OPTIONS ${_hcc_options} NVCC_OPTIONS ${_nvcc_options}) + if(_source_files) + list(REMOVE_ITEM _sources ${_source_files}) + endif() + add_library(${hip_target} ${_cmake_options} ${_generated_files} ${_sources}) + set_target_properties(${hip_target} PROPERTIES LINKER_LANGUAGE ${HIP_C_OR_CXX}) +endmacro() \ No newline at end of file diff --git a/tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_hipcc.cmake b/tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_hipcc.cmake new file mode 100644 index 000000000..05356c993 --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_hipcc.cmake @@ -0,0 +1,173 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +############################################################################### +# Runs commands using HIPCC +############################################################################### + +############################################################################### +# This file runs the hipcc commands to produce the desired output file +# along with the dependency file needed by CMake to compute dependencies. +# +# Input variables: +# +# verbose:BOOL=<> OFF: Be as quiet as possible (default) +# ON : Describe each step +# build_configuration:STRING=<> Build configuration. Defaults to Debug. +# generated_file:STRING=<> File to generate. Mandatory argument. + +if(NOT build_configuration) + set(build_configuration Debug) +endif() +if(NOT generated_file) + message(FATAL_ERROR "You must specify generated_file on the command line") +endif() + +# Set these up as variables to make reading the generated file easier +set(HIP_HIPCC_EXECUTABLE "@HIP_HIPCC_EXECUTABLE@") # path +set(HIP_HIPCONFIG_EXECUTABLE "@HIP_HIPCONFIG_EXECUTABLE@") #path +set(HIP_HOST_COMPILER "@HIP_HOST_COMPILER@") # path +set(CMAKE_COMMAND "@CMAKE_COMMAND@") # path +set(HIP_run_make2cmake "@HIP_run_make2cmake@") # path +set(HCC_HOME "@HCC_HOME@") #path + +@HIP_HOST_FLAGS@ +@_HIP_HIPCC_FLAGS@ +@_HIP_HCC_FLAGS@ +@_HIP_NVCC_FLAGS@ +set(HIP_HIPCC_INCLUDE_ARGS "@HIP_HIPCC_INCLUDE_ARGS@") # list (needs to be in quotes to handle spaces properly) + +set(cmake_dependency_file "@cmake_dependency_file@") # path +set(source_file "@source_file@") # path +set(host_flag "@host_flag@") # bool + +# Determine compiler and compiler flags +execute_process(COMMAND ${HIP_HIPCONFIG_EXECUTABLE} --platform OUTPUT_VARIABLE HIP_PLATFORM OUTPUT_STRIP_TRAILING_WHITESPACE) +if(NOT host_flag) + set(__CC ${HIP_HIPCC_EXECUTABLE}) + if(HIP_PLATFORM STREQUAL "hcc") + if(NOT "x${HCC_HOME}" STREQUAL "x") + set(ENV{HCC_HOME} ${HCC_HOME}) + endif() + set(__CC_FLAGS ${HIP_HIPCC_FLAGS} ${HIP_HCC_FLAGS} ${HIP_HIPCC_FLAGS_${build_configuration}} ${HIP_HCC_FLAGS_${build_configuration}}) + else() + set(__CC_FLAGS ${HIP_HIPCC_FLAGS} ${HIP_NVCC_FLAGS} ${HIP_HIPCC_FLAGS_${build_configuration}} ${HIP_NVCC_FLAGS_${build_configuration}}) + endif() +else() + set(__CC ${HIP_HOST_COMPILER}) + set(__CC_FLAGS ${CMAKE_HOST_FLAGS} ${CMAKE_HOST_FLAGS_${build_configuration}}) +endif() +set(__CC_INCLUDES ${HIP_HIPCC_INCLUDE_ARGS}) + +# hip_execute_process - Executes a command with optional command echo and status message. +# status - Status message to print if verbose is true +# command - COMMAND argument from the usual execute_process argument structure +# ARGN - Remaining arguments are the command with arguments +# HIP_result - Return value from running the command +macro(hip_execute_process status command) + set(_command ${command}) + if(NOT "x${_command}" STREQUAL "xCOMMAND") + message(FATAL_ERROR "Malformed call to hip_execute_process. Missing COMMAND as second argument. (command = ${command})") + endif() + if(verbose) + execute_process(COMMAND "${CMAKE_COMMAND}" -E echo -- ${status}) + # Build command string to print + set(hip_execute_process_string) + foreach(arg ${ARGN}) + # Escape quotes if any + string(REPLACE "\"" "\\\"" arg ${arg}) + # Surround args with spaces with quotes + if(arg MATCHES " ") + list(APPEND hip_execute_process_string "\"${arg}\"") + else() + list(APPEND hip_execute_process_string ${arg}) + endif() + endforeach() + # Echo the command + execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${hip_execute_process_string}) + endif() + # Run the command + execute_process(COMMAND ${ARGN} RESULT_VARIABLE HIP_result) +endmacro() + +# Delete the target file +hip_execute_process( + "Removing ${generated_file}" + COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}" + ) + +# Generate the dependency file +hip_execute_process( + "Generating dependency file: ${cmake_dependency_file}.pre" + COMMAND "${__CC}" + -M + "${source_file}" + -o "${cmake_dependency_file}.pre" + ${__CC_FLAGS} + ${__CC_INCLUDES} + ) + +if(HIP_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Generate the cmake readable dependency file to a temp file +hip_execute_process( + "Generating temporary cmake readable file: ${cmake_dependency_file}.tmp" + COMMAND "${CMAKE_COMMAND}" + -D "input_file:FILEPATH=${cmake_dependency_file}.pre" + -D "output_file:FILEPATH=${cmake_dependency_file}.tmp" + -D "verbose=${verbose}" + -P "${HIP_run_make2cmake}" + ) + +if(HIP_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Copy the file if it is different +hip_execute_process( + "Copy if different ${cmake_dependency_file}.tmp to ${cmake_dependency_file}" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${cmake_dependency_file}.tmp" "${cmake_dependency_file}" + ) + +if(HIP_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Delete the temporary file +hip_execute_process( + "Removing ${cmake_dependency_file}.tmp and ${cmake_dependency_file}.pre" + COMMAND "${CMAKE_COMMAND}" -E remove "${cmake_dependency_file}.tmp" "${cmake_dependency_file}.pre" + ) + +if(HIP_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Generate the output file +hip_execute_process( + "Generating ${generated_file}" + COMMAND "${__CC}" + -c + "${source_file}" + -o "${generated_file}" + ${__CC_FLAGS} + ${__CC_INCLUDES} + ) + +if(HIP_result) + # Make sure that we delete the output file + hip_execute_process( + "Removing ${generated_file}" + COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}" + ) + message(FATAL_ERROR "Error generating file ${generated_file}") +else() + if(verbose) + message("Generated ${generated_file} successfully.") + endif() +endif() +# vim: ts=4:sw=4:expandtab:smartindent diff --git a/tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_make2cmake.cmake b/tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_make2cmake.cmake new file mode 100644 index 000000000..22c9790e3 --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/FindHIP/run_make2cmake.cmake @@ -0,0 +1,55 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +############################################################################### +# Computes dependencies using HIPCC +############################################################################### + +############################################################################### +# This file converts dependency files generated using hipcc to a format that +# cmake can understand. + +# Input variables: +# +# input_file:STRING=<> Dependency file to parse. Required argument +# output_file:STRING=<> Output file to generate. Required argument + +if(NOT input_file OR NOT output_file) + message(FATAL_ERROR "You must specify input_file and output_file on the command line") +endif() + +file(READ ${input_file} depend_text) + +if (NOT "${depend_text}" STREQUAL "") + string(REPLACE " /" "\n/" depend_text ${depend_text}) + string(REGEX REPLACE "^.*:" "" depend_text ${depend_text}) + string(REGEX REPLACE "[ \\\\]*\n" ";" depend_text ${depend_text}) + + set(dependency_list "") + + foreach(file ${depend_text}) + string(REGEX REPLACE "^ +" "" file ${file}) + if(NOT EXISTS "${file}") + message(WARNING " Removing non-existent dependency file: ${file}") + set(file "") + endif() + + if(NOT IS_DIRECTORY "${file}") + get_filename_component(file_absolute "${file}" ABSOLUTE) + list(APPEND dependency_list "${file_absolute}") + endif() + endforeach() +endif() + +# Remove the duplicate entries and sort them. +list(REMOVE_DUPLICATES dependency_list) +list(SORT dependency_list) + +foreach(file ${dependency_list}) + set(hip_hipcc_depend "${hip_hipcc_depend} \"${file}\"\n") +endforeach() + +file(WRITE ${output_file} "# Generated by: FindHIP.cmake. Do not edit.\nSET(HIP_HIPCC_DEPEND\n ${hip_hipcc_depend})\n\n") +# vim: ts=4:sw=4:expandtab:smartindent diff --git a/tpl/RAJA/blt/cmake/thirdparty/FindROCm.cmake b/tpl/RAJA/blt/cmake/thirdparty/FindROCm.cmake new file mode 100644 index 000000000..56b5deb9f --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/FindROCm.cmake @@ -0,0 +1,27 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +# Author: Chip Freitag @ Advanced Micro Devices, Inc. +# Date: February 14, 2018 + +find_path(ROCM_PATH + NAMES bin/hcc + PATHS + ENV ROCM_DIR + ${ROCM_ROOT_DIR} + /opt/rocm + DOC "Path to ROCm hcc executable") + + +if(ROCM_PATH) + message(STATUS "ROCM_PATH: ${ROCM_PATH}") + set(CMAKE_CXX_COMPILER_ID "HCC") + + set(ROCM_FOUND TRUE) + +else() + set(ROCM_FOUND FALSE) + message(WARNING "ROCm hcc executable not found") +endif() diff --git a/tpl/RAJA/blt/cmake/thirdparty/SetupCUDA.cmake b/tpl/RAJA/blt/cmake/thirdparty/SetupCUDA.cmake new file mode 100644 index 000000000..a574b920e --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/SetupCUDA.cmake @@ -0,0 +1,138 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +################################ +# Sanity Checks +################################ + +# Rare case of two flags being incompatible +if (DEFINED CMAKE_SKIP_BUILD_RPATH AND DEFINED CUDA_LINK_WITH_NVCC) + if (NOT CMAKE_SKIP_BUILD_RPATH AND CUDA_LINK_WITH_NVCC) + message( FATAL_ERROR + "CMAKE_SKIP_BUILD_RPATH (FALSE) and CUDA_LINK_WITH_NVCC (TRUE) " + "are incompatible when linking explicit shared libraries. Set " + "CMAKE_SKIP_BUILD_RPATH to TRUE.") + endif() +endif() + +# CUDA_HOST_COMPILER was changed in 3.9.0 to CMAKE_CUDA_HOST_COMPILER and +# needs to be set prior to enabling the CUDA language +get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) +if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.9.0" ) + if ( NOT CMAKE_CUDA_HOST_COMPILER ) + if("CUDA" IN_LIST _languages ) + message( FATAL_ERROR + "CUDA language enabled prior to setting CMAKE_CUDA_HOST_COMPILER. " + "Please set CMAKE_CUDA_HOST_COMPILER prior to " + "ENABLE_LANGUAGE(CUDA) or PROJECT(.. LANGUAGES CUDA)") + endif() + + if ( CMAKE_CXX_COMPILER ) + set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} CACHE STRING "" FORCE) + else() + set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_C_COMPILER} CACHE STRING "" FORCE) + endif() + endif() +else() + if (NOT CUDA_HOST_COMPILER) + if("CUDA" IN_LIST _languages ) + message( FATAL_ERROR + "CUDA language enabled prior to setting CUDA_HOST_COMPILER. " + "Please set CUDA_HOST_COMPILER prior to " + "ENABLE_LANGUAGE(CUDA) or PROJECT(.. LANGUAGES CUDA)") + endif() + + if ( CMAKE_CXX_COMPILER ) + set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} CACHE STRING "" FORCE) + else() + set(CUDA_HOST_COMPILER ${CMAKE_C_COMPILER} CACHE STRING "" FORCE) + endif() + endif() +endif() + +# Override rpath link flags for nvcc +if (CUDA_LINK_WITH_NVCC) + set(CMAKE_SHARED_LIBRARY_RUNTIME_CUDA_FLAG "-Xlinker -rpath -Xlinker " CACHE STRING "") + set(CMAKE_SHARED_LIBRARY_RPATH_LINK_CUDA_FLAG "-Xlinker -rpath -Xlinker " CACHE STRING "") +endif() + + +############################################################ +# Basics +############################################################ +# language check fails when using clang-cuda +if (NOT ENABLE_CLANG_CUDA) + enable_language(CUDA) +endif () + + +############################################################ +# Map Legacy FindCUDA variables to native cmake variables +############################################################ +# if we are linking with NVCC, define the link rule here +# Note that some mpi wrappers might have things like -Wl,-rpath defined, which when using +# FindMPI can break nvcc. In that case, you should set ENABLE_FIND_MPI to Off and control +# the link using CMAKE_CUDA_LINK_FLAGS. -Wl,-rpath, equivalent would be -Xlinker -rpath -Xlinker +if (CUDA_LINK_WITH_NVCC) + set(CMAKE_CUDA_LINK_EXECUTABLE + "${CMAKE_CUDA_COMPILER} -o ") + # do a no-op for the device links - for some reason the device link library dependencies are only a subset of the + # executable link dependencies so the device link fails if there are any missing CUDA library dependencies. Since + # we are doing a link with the nvcc compiler, the device link step is unnecessary . + # Frustratingly, nvcc-link errors out if you pass it an empty file, so we have to first compile the empty file. + set(CMAKE_CUDA_DEVICE_LINK_LIBRARY "touch .cu ; ${CMAKE_CUDA_COMPILER} -std=c++11 -dc .cu -o ") + set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE "touch .cu ; ${CMAKE_CUDA_COMPILER} -std=c++11 -dc .cu -o ") +endif() + +find_package(CUDA REQUIRED) + +message(STATUS "CUDA Version: ${CUDA_VERSION_STRING}") +message(STATUS "CUDA Compiler: ${CMAKE_CUDA_COMPILER}") +if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.9.0" ) + message(STATUS "CUDA Host Compiler: ${CMAKE_CUDA_HOST_COMPILER}") +else() + message(STATUS "CUDA Host Compiler: ${CUDA_HOST_COMPILER}") +endif() +message(STATUS "CUDA Include Path: ${CUDA_INCLUDE_DIRS}") +message(STATUS "CUDA Libraries: ${CUDA_LIBRARIES}") +message(STATUS "CUDA Compile Flags: ${CMAKE_CUDA_FLAGS}") +message(STATUS "CUDA Link Flags: ${CMAKE_CUDA_LINK_FLAGS}") +message(STATUS "CUDA Separable Compilation: ${CUDA_SEPARABLE_COMPILATION}") +message(STATUS "CUDA Link with NVCC: ${CUDA_LINK_WITH_NVCC}") + +# don't propagate host flags - too easy to break stuff! +set (CUDA_PROPAGATE_HOST_FLAGS Off) +if (CMAKE_CXX_COMPILER) + set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}) +else() + set(CUDA_HOST_COMPILER ${CMAKE_C_COMPILER}) +endif() + +set(_cuda_compile_flags " ") +if (ENABLE_CLANG_CUDA) + set (_cuda_compile_flags -x cuda --cuda-gpu-arch=${BLT_CLANG_CUDA_ARCH} --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}) + message(STATUS "Clang CUDA Enabled. CUDA compile flags added: ${_cuda_compile_flags}") +endif() + +# depend on 'cuda', if you need to use cuda +# headers, link to cuda libs, and need to compile your +# source files with the cuda compiler (nvcc) instead of +# leaving it to the default source file language. +# This logic is handled in the blt_add_library/executable +# macros +blt_register_library(NAME cuda + COMPILE_FLAGS ${_cuda_compile_flags} + INCLUDES ${CUDA_INCLUDE_DIRS} + LIBRARIES ${CUDA_LIBRARIES}) + +# same as 'cuda' but we don't flag your source files as +# CUDA language. This causes your source files to use +# the regular C/CXX compiler. This is separate from +# linking with nvcc. +# This logic is handled in the blt_add_library/executable +# macros +blt_register_library(NAME cuda_runtime + INCLUDES ${CUDA_INCLUDE_DIRS} + LIBRARIES ${CUDA_LIBRARIES}) diff --git a/tpl/RAJA/blt/cmake/thirdparty/SetupHCC.cmake b/tpl/RAJA/blt/cmake/thirdparty/SetupHCC.cmake new file mode 100644 index 000000000..f82524d9a --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/SetupHCC.cmake @@ -0,0 +1,39 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +################################ +# ROCM +################################ + +if (ENABLE_HCC) + set (CMAKE_MODULE_PATH "${BLT_ROOT_DIR}/cmake/thirdparty;${CMAKE_MODULE_PATH}") + find_package(ROCm REQUIRED) + + if (ROCM_FOUND) + message(STATUS "ROCM Compile Flags: ${ROCM_CXX_COMPILE_FLAGS}") + message(STATUS "ROCM Include Path: ${ROCM_INCLUDE_PATH}") + message(STATUS "ROCM Link Flags: ${ROCM_CXX_LINK_FLAGS}") + message(STATUS "ROCM Libraries: ${ROCM_CXX_LIBRARIES}") + message(STATUS "ROCM Device Arch: ${ROCM_ARCH}") + + if (ENABLE_FORTRAN) + message(ERROR "ROCM does not support Fortran at this time") + endif() + else() + message(ERROR "ROCM Executable not found") + endif() +endif() + + + +# register ROCM with blt +blt_register_library(NAME rocm + INCLUDES ${ROCM_CXX_INCLUDE_PATH} + LIBRARIES ${ROCM_CXX_LIBRARIES} + COMPILE_FLAGS ${ROCM_CXX_COMPILE_FLAGS} + LINK_FLAGS ${ROCM_CXX_LINK_FLAGS} + DEFINES USE_ROCM) + + diff --git a/tpl/RAJA/blt/cmake/thirdparty/SetupHIP.cmake b/tpl/RAJA/blt/cmake/thirdparty/SetupHIP.cmake new file mode 100644 index 000000000..cdc917553 --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/SetupHIP.cmake @@ -0,0 +1,46 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +# Author: Noel Chalmers @ Advanced Micro Devices, Inc. +# Date: March 11, 2019 + +################################ +# HIP +################################ +set (CMAKE_MODULE_PATH "${BLT_ROOT_DIR}/cmake/thirdparty;${CMAKE_MODULE_PATH}") +find_package(HIP REQUIRED) + +message(STATUS "HIP version: ${HIP_VERSION_STRING}") +message(STATUS "HIP platform: ${HIP_PLATFORM}") +#message(STATUS "HIP Include Path: ${HIP_INCLUDE_DIRS}") +#message(STATUS "HIP Libraries: ${HIP_LIBRARIES}") + +if(${HIP_PLATFORM} STREQUAL "hcc") + set(HIP_RUNTIME_DEFINE "__HIP_PLATFORM_HCC__") +elseif(${HIP_PLATFORM} STREQUAL "nvcc") + set(HIP_RUNTIME_DEFINE "__HIP_PLATFORM_NVCC__") +endif() +set(HIP_RUNTIME_INCLUDE_DIRS "${HIP_ROOT_DIR}/include;${HIP_ROOT_DIR}/hcc/include") +set(HIP_RUNTIME_COMPILE_FLAGS "${HIP_RUNTIME_COMPILE_FLAGS};-D${HIP_RUNTIME_DEFINE};-Wno-unused-parameter") +# set(HIP_RUNTIME_LIBRARIES "${HIP_ROOT_DIR}/hcc/lib") +# set(HIP_RUNTIME_LIBRARIES "${HIP_ROOT_DIR}/hcc/lib") + +# depend on 'hip', if you need to use hip +# headers, link to hip libs, and need to run your source +# through a hip compiler (hipcc) +blt_register_library(NAME hip + INCLUDES ${HIP_INCLUDE_DIRS} + LIBRARIES ${HIP_LIBRARIES} + TREAT_INCLUDES_AS_SYSTEM ON) + +# depend on 'hip_runtime', if you only need to use hip +# headers or link to hip libs, but don't need to run your source +# through a hip compiler (hipcc) +blt_register_library(NAME hip_runtime + INCLUDES ${HIP_RUNTIME_INCLUDE_DIRS} + DEFINES ${HIP_RUNTIME_DEFINES} + COMPILE_FLAGS ${HIP_RUNTIME_COMPILE_FLAGS} + LIBRARIES ${HIP_RUNTIME_LIBRARIES} + TREAT_INCLUDES_AS_SYSTEM ON) diff --git a/tpl/RAJA/blt/cmake/thirdparty/SetupMPI.cmake b/tpl/RAJA/blt/cmake/thirdparty/SetupMPI.cmake new file mode 100644 index 000000000..9c475fdfd --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/SetupMPI.cmake @@ -0,0 +1,161 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +################################ +# MPI +################################ + +# CMake changed some of the output variables that we use from Find(MPI) +# in 3.10+. This toggles the variables based on the CMake version +# the user is running. +if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10.0" ) + if (NOT MPIEXEC_EXECUTABLE AND MPIEXEC) + set(MPIEXEC_EXECUTABLE ${MPIEXEC} CACHE PATH "" FORCE) + endif() + + set(_mpi_includes_suffix "INCLUDE_DIRS") + set(_mpi_compile_flags_suffix "COMPILE_OPTIONS") +else() + if (MPIEXEC_EXECUTABLE AND NOT MPIEXEC) + set(MPIEXEC ${MPIEXEC_EXECUTABLE} CACHE PATH "" FORCE) + endif() + + set(_mpi_includes_suffix "INCLUDE_PATH") + set(_mpi_compile_flags_suffix "COMPILE_FLAGS") +endif() + +set(_mpi_compile_flags ) +set(_mpi_includes ) +set(_mpi_libraries ) +set(_mpi_link_flags ) + +message(STATUS "Enable FindMPI: ${ENABLE_FIND_MPI}") + +if (ENABLE_FIND_MPI) + find_package(MPI REQUIRED) + + #------------------- + # Merge found MPI info and remove duplication + #------------------- + # Compile flags + set(_c_flag ${MPI_C_${_mpi_compile_flags_suffix}}) + if (_c_flag AND ENABLE_CUDA) + list(APPEND _mpi_compile_flags + $<$>:${_c_flag}> + $<$:-Xcompiler=${_c_flag}>) + else() + list(APPEND _mpi_compile_flags ${_c_flag}) + endif() + + set(_cxx_flag ${MPI_CXX_${_mpi_compile_flags_suffix}}) + if (_cxx_flag AND NOT "${_c_flag}" STREQUAL "${_cxx_flag}") + if (ENABLE_CUDA) + list(APPEND _mpi_compile_flags + $<$>:${_cxx_flag}> + $<$:-Xcompiler=${_cxx_flag}>) + else() + list(APPEND _mpi_compile_flags ${_cxx_flag}) + endif() + endif() + + if (ENABLE_FORTRAN) + set(_f_flag ${MPI_Fortran_${_mpi_compile_flags_suffix}}) + if (_f_flag AND NOT "${c_flg}" STREQUAL "${_f_flag}") + list(APPEND _mpi_compile_flags ${_f_flag}) + endif() + endif() + unset(_c_flag) + unset(_cxx_flag) + unset(_f_flag) + + # Include paths + list(APPEND _mpi_includes ${MPI_C_${_mpi_includes_suffix}} + ${MPI_CXX_${_mpi_includes_suffix}}) + if (ENABLE_FORTRAN) + list(APPEND _mpi_includes ${MPI_Fortran_${_mpi_includes_suffix}}) + endif() + blt_list_remove_duplicates(TO _mpi_includes) + + # Link flags + set(_mpi_link_flags ${MPI_C_LINK_FLAGS}) + if (NOT "${MPI_C_LINK_FLAGS}" STREQUAL "${MPI_CXX_LINK_FLAGS}") + list(APPEND _mpi_link_flags ${MPI_CXX_LINK_FLAGS}) + endif() + if (ENABLE_FORTRAN) + if (NOT "${MPI_C_LINK_FLAGS}" STREQUAL "${MPI_Fortran_LINK_FLAGS}") + list(APPEND _mpi_link_flags ${MPI_CXX_LINK_FLAGS}) + endif() + endif() + # Fixes for linking with NVCC + if (CUDA_LINK_WITH_NVCC) + # Convert rpath flag if linking with CUDA + string(REPLACE "-Wl,-rpath," "-Xlinker -rpath -Xlinker " + _mpi_link_flags "${_mpi_link_flags}") + # -pthread just doesn't work with nvcc + string(REPLACE "-pthread" " " + _mpi_link_flags "${_mpi_link_flags}") + endif() + + # Libraries + set(_mpi_libraries ${MPI_C_LIBRARIES} ${MPI_CXX_LIBRARIES}) + if (ENABLE_FORTRAN) + list(APPEND _mpi_libraries ${MPI_Fortran_LIBRARIES}) + endif() + blt_list_remove_duplicates(TO _mpi_libraries) +endif() + +# Allow users to override CMake's FindMPI +if (BLT_MPI_COMPILE_FLAGS) + set(_mpi_compile_flags ${BLT_MPI_COMPILE_FLAGS}) +endif() +if (BLT_MPI_INCLUDES) + set(_mpi_includes ${BLT_MPI_INCLUDES}) +endif() +if (BLT_MPI_LIBRARIES) + set(_mpi_libraries ${BLT_MPI_LIBRARIES}) +endif() +if (BLT_MPI_LINK_FLAGS) + set(_mpi_link_flags ${BLT_MPI_LINK_FLAGS}) +endif() + + +# Output all MPI information +message(STATUS "BLT MPI Compile Flags: ${_mpi_compile_flags}") +message(STATUS "BLT MPI Include Paths: ${_mpi_includes}") +message(STATUS "BLT MPI Libraries: ${_mpi_libraries}") +message(STATUS "BLT MPI Link Flags: ${_mpi_link_flags}") + +if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10.0" ) + message(STATUS "MPI Executable: ${MPIEXEC_EXECUTABLE}") +else() + message(STATUS "MPI Executable: ${MPIEXEC}") +endif() +message(STATUS "MPI Num Proc Flag: ${MPIEXEC_NUMPROC_FLAG}") +message(STATUS "MPI Command Append: ${BLT_MPI_COMMAND_APPEND}") + +if (ENABLE_FORTRAN) + # Determine if we should use fortran mpif.h header or fortran mpi module + find_path(mpif_path + NAMES "mpif.h" + PATHS ${_mpi_includes} + NO_DEFAULT_PATH + ) + + if(mpif_path) + set(MPI_Fortran_USE_MPIF ON CACHE PATH "") + message(STATUS "Using MPI Fortran header: mpif.h") + else() + set(MPI_Fortran_USE_MPIF OFF CACHE PATH "") + message(STATUS "Using MPI Fortran module: mpi.mod") + endif() +endif() + +# Create the registered library +blt_register_library(NAME mpi + INCLUDES ${_mpi_includes} + TREAT_INCLUDES_AS_SYSTEM ON + LIBRARIES ${_mpi_libraries} + COMPILE_FLAGS ${_mpi_compile_flags} + LINK_FLAGS ${_mpi_link_flags} ) diff --git a/tpl/RAJA/blt/cmake/thirdparty/SetupOpenMP.cmake b/tpl/RAJA/blt/cmake/thirdparty/SetupOpenMP.cmake new file mode 100644 index 000000000..1d7b617e8 --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/SetupOpenMP.cmake @@ -0,0 +1,57 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +################################################# +# OpenMP +# (OpenMP support is provided by the compiler) +################################################# + +find_package(OpenMP REQUIRED) + +# check if the openmp flags used for C/C++ are different from the openmp flags +# used by the Fortran compiler +set(BLT_OPENMP_FLAGS_DIFFER FALSE CACHE BOOL "") +if (ENABLE_FORTRAN) + string(COMPARE NOTEQUAL "${OpenMP_CXX_FLAGS}" "${OpenMP_Fortran_FLAGS}" + BLT_OPENMP_FLAGS_DIFFER ) +endif() + +# avoid generator expressions if possible, as generator expressions can be +# passed as flags to downstream projects that might not be using the same +# languages. See https://github.com/LLNL/blt/issues/205 +set(_compile_flags ${OpenMP_CXX_FLAGS}) +set(_link_flags ${OpenMP_CXX_FLAGS}) + +if(NOT COMPILER_FAMILY_IS_MSVC AND ENABLE_CUDA AND BLT_OPENMP_FLAGS_DIFFER) + set(_compile_flags + $<$>,$>>:${OpenMP_CXX_FLAGS}> + $<$:-Xcompiler=${OpenMP_CXX_FLAGS}> + $<$:${OpenMP_Fortran_FLAGS}>) +elseif(NOT COMPILER_FAMILY_IS_MSVC AND ENABLE_CUDA) + set(_compile_flags + $<$>:${OpenMP_CXX_FLAGS}> + $<$:-Xcompiler=${OpenMP_CXX_FLAGS}>) +elseif(NOT COMPILER_FAMILY_IS_MSVC AND BLT_OPENMP_FLAGS_DIFFER) + set(_compile_flags + $<$>:${OpenMP_CXX_FLAGS}> + $<$:${OpenMP_Fortran_FLAGS}>) +endif() + + +# Allow user to override +if (BLT_OPENMP_COMPILE_FLAGS) + set(_compile_flags ${BLT_OPENMP_COMPILE_FLAGS}) +endif() +if (BLT_OPENMP_LINK_FLAGS) + set(_link_flags ${BLT_OPENMP_LINK_FLAGS}) +endif() + + +message(STATUS "OpenMP Compile Flags: ${_compile_flags}") +message(STATUS "OpenMP Link Flags: ${_link_flags}") + +blt_register_library(NAME openmp + COMPILE_FLAGS ${_compile_flags} + LINK_FLAGS ${_link_flags}) diff --git a/tpl/RAJA/blt/cmake/thirdparty/SetupThirdParty.cmake b/tpl/RAJA/blt/cmake/thirdparty/SetupThirdParty.cmake new file mode 100644 index 000000000..34fe5b9a0 --- /dev/null +++ b/tpl/RAJA/blt/cmake/thirdparty/SetupThirdParty.cmake @@ -0,0 +1,109 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------ +# Git +#------------------------------------ +if (ENABLE_GIT) + find_package(Git) + if (Git_FOUND) + message(STATUS "Git Support is ON") + set(GIT_FOUND TRUE) + message(STATUS "Git Executable: " ${GIT_EXECUTABLE} ) + message(STATUS "Git Version: " ${GIT_VERSION_STRING} ) + else() + message(STATUS "Git Support is OFF") + endif() +else() + message(STATUS "Git Support is OFF") +endif() + + +#------------------------------------ +# MPI +#------------------------------------ +message(STATUS "MPI Support is ${ENABLE_MPI}") +if (ENABLE_MPI) + include(${BLT_ROOT_DIR}/cmake/thirdparty/SetupMPI.cmake) +endif() + + +#------------------------------------ +# OpenMP +#------------------------------------ +message(STATUS "OpenMP Support is ${ENABLE_OPENMP}") +if (ENABLE_OPENMP) + include(${BLT_ROOT_DIR}/cmake/thirdparty/SetupOpenMP.cmake) +endif() + + +#------------------------------------ +# CUDA +#------------------------------------ +message(STATUS "CUDA Support is ${ENABLE_CUDA}") +if (ENABLE_CUDA) + include(${BLT_ROOT_DIR}/cmake/thirdparty/SetupCUDA.cmake) +endif() + + +#------------------------------------ +# HIP +#------------------------------------ +message(STATUS "HIP Support is ${ENABLE_HIP}") +if (ENABLE_HIP) + include(${BLT_ROOT_DIR}/cmake/thirdparty/SetupHIP.cmake) +endif() + +#------------------------------------ +# HCC +#------------------------------------ +message(STATUS "HCC Support is ${ENABLE_HCC}") +if (ENABLE_HCC) + include(${BLT_ROOT_DIR}/cmake/thirdparty/SetupHCC.cmake) +endif() + + +#------------------------------------ +# Documentation Packages +#------------------------------------ +if (ENABLE_DOXYGEN) + find_package(Doxygen) +endif() + +blt_find_executable(NAME Sphinx + EXECUTABLES sphinx-build sphinx-build2) + + +#------------------------------------ +# Valgrind +#------------------------------------ +blt_find_executable(NAME Valgrind + EXECUTABLES valgrind) + + +#------------------------------------ +# linting +#------------------------------------ +blt_find_executable(NAME Uncrustify + EXECUTABLES uncrustify) + +blt_find_executable(NAME AStyle + EXECUTABLES astyle) + + +#------------------------------------ +# Static analysis via Cppcheck +#------------------------------------ +blt_find_executable(NAME Cppcheck + EXECUTABLES cppcheck) + + +#------------------------------------ +# Static analysis via clang-query +#------------------------------------ +if(CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "Ninja") + blt_find_executable(NAME ClangQuery + EXECUTABLES clang-query) +endif() diff --git a/tpl/RAJA/blt/docs/CMakeLists.txt b/tpl/RAJA/blt/docs/CMakeLists.txt new file mode 100644 index 000000000..2d70ebc48 --- /dev/null +++ b/tpl/RAJA/blt/docs/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +cmake_minimum_required(VERSION 3.8) + +project( blt_docs ) + +############################################################################### +# Setup BLT +############################################################################### + +if(NOT BLT_SOURCE_DIR) + set(BLT_SOURCE_DIR "blt") +endif() + +include(${BLT_SOURCE_DIR}/SetupBLT.cmake) + +if (SPHINX_FOUND) + blt_add_sphinx_target(blt_sphinx_tutorial_docs) +endif() diff --git a/tpl/RAJA/blt/docs/api/code_check.rst b/tpl/RAJA/blt/docs/api/code_check.rst new file mode 100644 index 000000000..b9b1cddf4 --- /dev/null +++ b/tpl/RAJA/blt/docs/api/code_check.rst @@ -0,0 +1,254 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Code Check Macros +================== + +blt_add_code_checks +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_code_checks( PREFIX + SOURCES [source1 [source2 ...]] + UNCRUSTIFY_CFG_FILE + ASTYLE_CFG_FILE + CPPCHECK_FLAGS ) + +This macro adds all enabled code check targets for the given SOURCES. + +PREFIX + Prefix used for the created code check build targets. For example: + _uncrustify_check + +SOURCES + Source list that the code checks will be ran on + +UNCRUSTIFY_CFG_FILE + Path to Uncrustify config file + +ASTYLE_CFG_FILE + Path to AStyle config file + +CPPCHECK_FLAGS + List of flags added to Cppcheck + +Sources are filtered based on file extensions for use in these code checks. If you need +additional file extensions defined add them to BLT_C_FILE_EXTS and BLT_Fortran_FILE_EXTS. +Currently this macro only has code checks for C/C++ and simply filters out the Fortran files. + +This macro supports code formatting with either Uncrustify or AStyle (but not both at the same time) +only if the following requirements are met: + +- Uncrustify + + * UNCRUSTIFY_CFG_FILE is given + * UNCRUSTIFY_EXECUTABLE is defined and found prior to calling this macro + +- AStyle + + * ASTYLE_CFG_FILE is given + * ASTYLE_EXECUTABLE is defined and found prior to calling this macro + +Enabled code formatting checks produce a `check` build target that will test to see if you +are out of compliance with your code formatting and a `style` build target that will actually +modify your source files. It also creates smaller child build targets that follow the pattern +`__`. + +This macro supports the following static analysis tools with their requirements: + +- CppCheck + + * CPPCHECK_EXECUTABLE is defined and found prior to calling this macro + * CPPCHECK_FLAGS added to the cppcheck command line before the sources + +- Clang-Query + + * CLANGQUERY_EXECUTABLE is defined and found prior to calling this macro + +These are added as children to the `check` build target and produce child build targets +that follow the pattern `__check`. + +blt_add_clang_query_target +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_clang_query_target( NAME + WORKING_DIRECTORY + COMMENT + CHECKERS + DIE_ON_MATCH + SRC_FILES [source1 [source2 ...]]) + +Creates a new build target for running clang-query. + +NAME + Name of created build target + +WORKING_DIRECTORY + Directory in which the clang-query command is run. Defaults to where macro is called. + +COMMENT + Comment prepended to the build target output + +CHECKERS + list of checkers to be run by created build target + +DIE_ON_MATCH + Causes build failure on first clang-query match. Defaults to FALSE.S + +SRC_FILES + Source list that clang-query will be ran on + +Clang-query is a tool used for examining and matching the Clang AST. It is useful for enforcing +coding standards and rules on your source code. A good primer on how to use clang-query can be +found `here `_. + +Turning on DIE_ON_MATCH is useful if you're using this in CI to enforce rules about your code. + +CHECKERS are the static analysis passes to specifically run on the target. The following checker options +can be given: + + * (no value) : run all available static analysis checks found + * (checker1:checker2) : run checker1 and checker2 + * (interpreter) : run the clang-query interpeter to interactively develop queries + + +blt_add_cppcheck_target +~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_cppcheck_target( NAME + WORKING_DIRECTORY + PREPEND_FLAGS + APPEND_FLAGS + COMMENT + SRC_FILES [source1 [source2 ...]] ) + +Creates a new build target for running cppcheck + +NAME + Name of created build target + +WORKING_DIRECTORY + Directory in which the clang-query command is run. Defaults to where macro is called. + +PREPEND_FLAGS + Additional flags added to the front of the cppcheck flags + +APPEND_FLAGS + Additional flags added to the end of the cppcheck flags + +COMMENT + Comment prepended to the build target output + +SRC_FILES + Source list that cppcheck will be ran on + +Cppcheck is a static analysis tool for C/C++ code. More information about +Cppcheck can be found `here `_. + +blt_add_uncrustify_target +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_uncrustify_target( NAME + MODIFY_FILES [TRUE | FALSE (default)] + CFG_FILE + PREPEND_FLAGS + APPEND_FLAGS + COMMENT + WORKING_DIRECTORY + SRC_FILES [source1 [source2 ...]] ) + +Creates a new build target for running Uncrustify + +NAME + Name of created build target + +MODIFY_FILES + Modify the files in place. Defaults to FALSE. + +CFG_FILE + Path to Uncrustify config file + +PREPEND_FLAGS + Additional flags added to the front of the Uncrustify flags + +APPEND_FLAGS + Additional flags added to the end of the Uncrustify flags + +COMMENT + Comment prepended to the build target output + +WORKING_DIRECTORY + Directory in which the Uncrustify command is run. Defaults to where macro is called. + +SRC_FILES + Source list that Uncrustify will be ran on + +Uncrustify is a Source Code Beautifier for C/C++ code. More information about +Uncrustify can be found `here `_. + +When MODIFY_FILES is set to TRUE, modifies the files in place and adds the created build +target to the parent `style` build target. Otherwise the files are not modified and the +created target is added to the parent `check` build target. This target will notify you +which files do not conform to your style guide. +.. Note:: + Setting MODIFY_FILES to FALSE is only supported in Uncrustify v0.61 or greater. + + +blt_add_astyle_target +~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_astyle_target( NAME + MODIFY_FILES [TRUE | FALSE (default)] + CFG_FILE + PREPEND_FLAGS + APPEND_FLAGS + COMMENT + WORKING_DIRECTORY + SRC_FILES [FILE1 [FILE2 ...]] ) + +Creates a new build target for running AStyle + +NAME + Name of created build target + +MODIFY_FILES + Modify the files in place. Defaults to FALSE. + +CFG_FILE + Path to AStyle config file + +PREPEND_FLAGS + Additional flags added to the front of the AStyle flags + +APPEND_FLAGS + Additional flags added to the end of the AStyle flags + +COMMENT + Comment prepended to the build target output + +WORKING_DIRECTORY + Directory in which the AStyle command is run. Defaults to where macro is called. + +SRC_FILES + Source list that AStyle will be ran on + +AStyle is a Source Code Beautifier for C/C++ code. More information about +AStyle can be found `here `_. + +When MODIFY_FILES is set to TRUE, modifies the files in place and adds the created build +target to the parent `style` build target. Otherwise the files are not modified and the +created target is added to the parent `check` build target. This target will notify you +which files do not conform to your style guide. +.. Note:: + Setting MODIFY_FILES to FALSE is only supported in AStyle v2.05 or greater. diff --git a/tpl/RAJA/blt/docs/api/documentation.rst b/tpl/RAJA/blt/docs/api/documentation.rst new file mode 100644 index 000000000..f1b521cd9 --- /dev/null +++ b/tpl/RAJA/blt/docs/api/documentation.rst @@ -0,0 +1,42 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Documenation Macros +=================== + + +blt_add_doxygen_target +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_doxygen_target(doxygen_target_name) + +Creates a build target for invoking doxygen to generate docs. Expects to +find a Doxyfile.in in the directory the macro is called in. + +This macro sets up the doxygen paths so that the doc builds happen +out of source. For ``make install``, this will place the resulting docs in +docs/doxygen/. + + +blt_add_sphinx_target +~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_sphinx_target(sphinx_target_name) + +Creates a build target for invoking sphinx to generate docs. Expects to +find a conf.py or conf.py.in in the directory the macro is called in. + +If conf.py is found, it is directly used as input to sphinx. + +If conf.py.in is found, this macro uses CMake's configure_file() command +to generate a conf.py, which is then used as input to sphinx. + +This macro sets up the sphinx paths so that the doc builds happen +out of source. For ``make install``, this will place the resulting docs in +docs/sphinx/. diff --git a/tpl/RAJA/blt/docs/api/git.rst b/tpl/RAJA/blt/docs/api/git.rst new file mode 100644 index 000000000..dade2986d --- /dev/null +++ b/tpl/RAJA/blt/docs/api/git.rst @@ -0,0 +1,183 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Git Macros +========== + + +blt_git +~~~~~~~ + +.. code-block:: cmake + + blt_git(SOURCE_DIR + GIT_COMMAND + OUTPUT_VARIABLE + RETURN_CODE + [QUIET] ) + +Runs the supplied git command on the given Git repository. + +This macro runs the user-supplied Git command, given by GIT_COMMAND, on the +given Git repository corresponding to SOURCE_DIR. The supplied GIT_COMMAND +is just a string consisting of the Git command and its arguments. The +resulting output is returned to the supplied CMake variable provided by +the OUTPUT_VARIABLE argument. + +A return code for the Git command is returned to the caller via the CMake +variable provided with the RETURN_CODE argument. A non-zero return code +indicates that an error has occured. + +Note, this macro assumes FindGit() was invoked and was successful. It relies +on the following variables set by FindGit(): + + * Git_FOUND flag that indicates if git is found + * GIT_EXECUTABLE points to the Git binary + +If Git_FOUND is "false" this macro will throw a FATAL_ERROR message. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + blt_git( SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} + GIT_COMMAND describe --tags master + OUTPUT_VARIABLE axom_tag + RETURN_CODE rc ) + if (NOT ${rc} EQUAL 0) + message( FATAL_ERROR "blt_git failed!" ) + endif() + + +blt_is_git_repo +~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_is_git_repo(OUTPUT_STATE + [SOURCE_DIR ] ) + +Checks if we are working with a valid Git repository. + +This macro checks if the corresponding source directory is a valid Git repo. +Nominally, the corresponding source directory that is used is set to +${CMAKE_CURRENT_SOURCE_DIR}. A different source directory may be optionally +specified using the SOURCE_DIR argument. + +The resulting state is stored in the CMake variable specified by the caller +using the OUTPUT_STATE parameter. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + blt_is_git_repo( OUTTPUT_STATE is_git_repo ) + if ( ${is_git_repo} ) + message(STATUS "Pointing to a valid Git repo!") + else() + message(STATUS "Not a Git repo!") + endif() + + +blt_git_tag +~~~~~~~~~~~ + +.. code-block:: cmake + + blt_git_tag( OUTPUT_TAG + RETURN_CODE + [SOURCE_DIR ] + [ON_BRANCH ] ) + +Returns the latest tag on a corresponding Git repository. + +This macro gets the latest tag from a Git repository that can be specified +via the SOURCE_DIR argument. If SOURCE_DIR is not supplied, the macro will +use ${CMAKE_CURRENT_SOURCE_DIR}. By default the macro will return the latest +tag on the branch that is currently checked out. A particular branch may be +specified using the ON_BRANCH option. + +The tag is stored in the CMake variable specified by the caller using the +the OUTPUT_TAG parameter. + +A return code for the Git command is returned to the caller via the CMake +variable provided with the RETURN_CODE argument. A non-zero return code +indicates that an error has occured. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + blt_git_tag( OUTPUT_TAG tag RETURN_CODE rc ON_BRANCH master ) + if ( NOT ${rc} EQUAL 0 ) + message( FATAL_ERROR "blt_git_tag failed!" ) + endif() + message( STATUS "tag=${tag}" ) + + +blt_git_branch +~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_git_branch( BRANCH_NAME + RETURN_CODE + [SOURCE_DIR ] ) + +Returns the name of the active branch in the checkout space. + +This macro gets the name of the current active branch in the checkout space +that can be specified using the SOURCE_DIR argument. If SOURCE_DIR is not +supplied by the caller, this macro will point to the checkout space +corresponding to ${CMAKE_CURRENT_SOURCE_DIR}. + +A return code for the Git command is returned to the caller via the CMake +variable provided with the RETURN_CODE argument. A non-zero return code +indicates that an error has occured. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + blt_git_branch( BRANCH_NAME active_branch RETURN_CODE rc ) + if ( NOT ${rc} EQUAL 0 ) + message( FATAL_ERROR "blt_git_tag failed!" ) + endif() + message( STATUS "active_branch=${active_branch}" ) + + +blt_git_hashcode +~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_git_hashcode( HASHCODE + RETURN_CODE + [SOURCE_DIR ] + [ON_BRANCH ]) + +Returns the SHA-1 hashcode at the tip of a branch. + +This macro returns the SHA-1 hashcode at the tip of a branch that may be +specified with the ON_BRANCH argument. If the ON_BRANCH argument is not +supplied, the macro will return the SHA-1 hash at the tip of the current +branch. In addition, the caller may specify the target Git repository using +the SOURCE_DIR argument. Otherwise, if SOURCE_DIR is not specified, the +macro will use ${CMAKE_CURRENT_SOURCE_DIR}. + +A return code for the Git command is returned to the caller via the CMake +variable provided with the RETURN_CODE argument. A non-zero return code +indicates that an error has occured. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + blt_git_hashcode( HASHCODE sha1 RETURN_CODE rc ) + if ( NOT ${rc} EQUAL 0 ) + message( FATAL_ERROR "blt_git_hashcode failed!" ) + endif() + message( STATUS "sha1=${sha1}" ) + diff --git a/tpl/RAJA/blt/docs/api/index.rst b/tpl/RAJA/blt/docs/api/index.rst new file mode 100644 index 000000000..cee8969f4 --- /dev/null +++ b/tpl/RAJA/blt/docs/api/index.rst @@ -0,0 +1,17 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +API Documentation +================= + +.. toctree:: + :maxdepth: 3 + + target + target_properties + utility + git + code_check + documentation diff --git a/tpl/RAJA/blt/docs/api/target.rst b/tpl/RAJA/blt/docs/api/target.rst new file mode 100644 index 000000000..cb0eb517c --- /dev/null +++ b/tpl/RAJA/blt/docs/api/target.rst @@ -0,0 +1,283 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Target Macros +============= + +.. _blt_add_benchmark: + +blt_add_benchmark +~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_benchmark( NAME [name] + COMMAND [command] + NUM_MPI_TASKS [n]) + +Adds a benchmark to the project. + +NAME + Name that CTest reports. + +COMMAND + Command line that will be used to run the test and can include arguments. + +NUM_MPI_TASKS + Indicates this is an MPI test and how many MPI tasks to use. + +This macro adds a benchmark test to the ``Benchmark`` CTest configuration +which can be run by the ``run_benchmarks`` build target. These tests are +not run when you use the regular ``test`` build target. + +This macro is just a thin wrapper around :ref:`blt_add_test` and assists +with building up the correct command line for running the benchmark. For more +information see :ref:`blt_add_test`. + +The underlying executable should be previously added to the build system +with :ref:`blt_add_executable`. It should include the necessary benchmarking +library in its DEPENDS_ON list. + +Any calls to this macro should be guarded with ENABLE_BENCHMARKS unless this option +is always on in your build project. + +.. note:: + BLT provides a built-in Google Benchmark that is enabled by default if you set + ENABLE_BENCHMARKS=ON and can be turned off with the option ENABLE_GBENCHMARK. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + if(ENABLE_BENCHMARKS) + blt_add_executable(NAME component_benchmark + SOURCES my_benchmark.cpp + DEPENDS gbenchmark) + blt_add_benchmark( + NAME component_benchmark + COMMAND component_benchmark "--benchmark_min_time=0.0 --v=3 --benchmark_format=json") + endif() + +.. _blt_add_executable: + +blt_add_executable +~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_executable( NAME + SOURCES [source1 [source2 ...]] + INCLUDES [dir1 [dir2 ...]] + DEFINES [define1 [define2 ...]] + DEPENDS_ON [dep1 [dep2 ...]] + OUTPUT_DIR [dir] + FOLDER [name]) + +Adds an executable target, called , to be built from the given sources. + +The INCLUDES argument allows you to define what include directories are +needed to compile this executable. + +The DEFINES argument allows you to add needed compiler definitions that are +needed to compile this executable. + +If given a DEPENDS_ON argument, it will add the necessary includes and +libraries if they are already registered with blt_register_library. If +not it will add them as a cmake target dependency. + +The OUTPUT_DIR is used to control the build output directory of this +executable. This is used to overwrite the default bin directory. + +If the first entry in SOURCES is a Fortran source file, the fortran linker +is used. (via setting the CMake target property LINKER_LANGUAGE to Fortran ) +FOLDER is an optional keyword to organize the target into a folder in an IDE. + +This is available when ENABLE_FOLDERS is ON and when using a cmake generator +that supports this feature and will otherwise be ignored. + + +.. _blt_add_library: + +blt_add_library +~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_library( NAME + SOURCES [source1 [source2 ...]] + HEADERS [header1 [header2 ...]] + INCLUDES [dir1 [dir2 ...]] + DEFINES [define1 [define2 ...]] + DEPENDS_ON [dep1 ...] + OUTPUT_NAME [name] + OUTPUT_DIR [dir] + SHARED [TRUE | FALSE] + OBJECT [TRUE | FALSE] + CLEAR_PREFIX [TRUE | FALSE] + FOLDER [name]) + +Adds a library target, called , to be built from the given sources. + +This macro uses the BUILD_SHARED_LIBS, which is defaulted to OFF, to determine +whether the library will be build as shared or static. The optional boolean +SHARED argument can be used to override this choice. + +The OBJECT argument creates a CMake object library. Basically it is a collection +of compiled source files that are not archived or linked. Unlike regular CMake +object libraries you do not have to use the $> syntax, +you can just use . + +Note: Object libraries do not follow CMake's transitivity rules until 3.12. +BLT will add the various information provided in this macro and its +dependencies in the order you provide them to help. + +The INCLUDES argument allows you to define what include directories are +needed by any target that is dependent on this library. These will +be inherited by CMake's target dependency rules. + +The DEFINES argument allows you to add needed compiler definitions that are +needed by any target that is dependent on this library. These will +be inherited by CMake's target dependency rules. + +If given a DEPENDS_ON argument, it will add the necessary includes and +libraries if they are already registered with blt_register_library. If +not it will add them as a CMake target dependency. + +In addition, this macro will add the associated dependencies to the given +library target. Specifically, it will add the dependency for the CMake target +and for copying the headers for that target as well. + +The OUTPUT_DIR is used to control the build output directory of this +library. This is used to overwrite the default lib directory. +OUTPUT_NAME is the name of the output file; the default is NAME. + +It's useful when multiple libraries with the same name need to be created +by different targets. NAME is the target name, OUTPUT_NAME is the library name. +CLEAR_PREFIX allows you to remove the automatically appended "lib" prefix +from your built library. The created library will be foo.a instead of libfoo.a. +FOLDER is an optional keyword to organize the target into a folder in an IDE. + +This is available when ENABLE_FOLDERS is ON and when the cmake generator +supports this feature and will otherwise be ignored. + +Note: Do not use with header-only (INTERFACE) libraries, as this will generate +a CMake configuration error. + + +.. _blt_add_test: + +blt_add_test +~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_test( NAME [name] + COMMAND [command] + NUM_MPI_TASKS [n] + NUM_OMP_THREADS [n] + CONFIGURATIONS [config1 [config2...]]) + +Adds a test to the project. + +NAME + Name that CTest reports. + +COMMAND + Command line that will be used to run the test and can include arguments. + +NUM_MPI_TASKS + Indicates this is an MPI test and how many MPI tasks to use. + +NUM_OMP_THREADS + Indicates this test requires the defined environment variable OMP_NUM_THREADS set to the given variable. + +CONFIGURATIONS + Set the CTest configuration for this test. When not specified, the test + will be added to the default CTest configuration. + +This macro adds the named test to CTest, which is run by the build target ``test``. This macro +does not build the executable and requires a prior call to :ref:`blt_add_executable`. + +This macro assists with building up the correct command line. It will prepend +the RUNTIME_OUTPUT_DIRECTORY target property to the executable. + +If NUM_MPI_TASKS is given or ENABLE_WRAP_ALL_TESTS_WITH_MPIEXEC is set, the macro +will appropiately use MPIEXEC, MPIEXEC_NUMPROC_FLAG, and BLT_MPI_COMMAND_APPEND +to create the MPI run line. + +MPIEXEC and MPIEXEC_NUMPROC_FLAG are filled in by CMake's FindMPI.cmake but can +be overwritten in your host-config specific to your platform. BLT_MPI_COMMAND_APPEND +is useful on machines that require extra arguments to MPIEXEC. + +If NUM_OMP_THREADS is given, this macro will set the environment variable OMP_NUM_THREADS +before running this test. This is done by appending to the CMake tests property. + +.. note:: + If you do not require this macros command line assistance, you can call CMake's + ``add_test()`` directly. For example, you may have a script checked into your + repository you wish to run as a test instead of an executable you built as a part + of your build system. + +Any calls to this macro should be guarded with ENABLE_TESTS unless this option +is always on in your build project. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + if (ENABLE_TESTS) + blt_add_executable(NAME my_test + SOURCES my_test.cpp) + blt_add_test(NAME my_test + COMMAND my_test --with-some-argument) + endif() + + +.. _blt_register_library: + +blt_register_library +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_register_library( NAME + DEPENDS_ON [dep1 [dep2 ...]] + INCLUDES [include1 [include2 ...]] + TREAT_INCLUDES_AS_SYSTEM [ON|OFF] + FORTRAN_MODULES [path1 [path2 ..]] + LIBRARIES [lib1 [lib2 ...]] + COMPILE_FLAGS [flag1 [flag2 ..]] + LINK_FLAGS [flag1 [flag2 ..]] + DEFINES [def1 [def2 ...]] ) + +Registers a library to the project to ease use in other BLT macro calls. + +Stores information about a library in a specific way that is easily recalled +in other macros. For example, after registering gtest, you can add gtest to +the DEPENDS_ON in your blt_add_executable call and it will add the INCLUDES +and LIBRARIES to that executable. + +TREAT_INCLUDES_AS_SYSTEM informs the compiler to treat this library's include paths +as system headers. Only some compilers support this. This is useful if the headers +generate warnings you want to not have them reported in your build. This defaults +to OFF. + +This does not actually build the library. This is strictly to ease use after +discovering it on your system or building it yourself inside your project. + +Note: The OBJECT parameter is for internal BLT support for object libraries +and is not for users. Object libraries are created using blt_add_library(). + +Internally created variables (NAME = "foo"): + | BLT_FOO_IS_REGISTERED_LIBRARY + | BLT_FOO_IS_OBJECT_LIBRARY + | BLT_FOO_DEPENDS_ON + | BLT_FOO_INCLUDES + | BLT_FOO_TREAT_INCLUDES_AS_SYSTEM + | BLT_FOO_FORTRAN_MODULES + | BLT_FOO_LIBRARIES + | BLT_FOO_COMPILE_FLAGS + | BLT_FOO_LINK_FLAGS + | BLT_FOO_DEFINES diff --git a/tpl/RAJA/blt/docs/api/target_properties.rst b/tpl/RAJA/blt/docs/api/target_properties.rst new file mode 100644 index 000000000..be34158f6 --- /dev/null +++ b/tpl/RAJA/blt/docs/api/target_properties.rst @@ -0,0 +1,191 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Target Property Macros +====================== + + +blt_add_target_compile_flags +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_target_compile_flags( TO + SCOPE + FLAGS [FOO [BAR ...]]) + +Appends compiler flags to a CMake target by appending to the target's existing flags. + +TO + Name of CMake target + +SCOPE + Defines the scope of the given flags. Defaults to PUBLIC and is case insensitive. + +FLAGS + List of compile flags + +This macro provides very similar functionality to CMake's native +``add_compile_options`` and ``target_compile_options`` commands, but +provides more fine-grained scoping for the compile flags on a +per target basis. + +The given target must be added via CMake's ``add_executable`` or ``add_library`` commands +or with the corresponding ``blt_add_executable`` and ``blt_add_library`` macros. + +PRIVATE flags are used for the given target. INTERFACE flags are inherited +by any target that depends on this target. PUBLIC flags are both INTERFACE and PRIVATE. + +.. note:: + This macro will strip away leading and trailing whitespace from each flag. + + +blt_add_target_definitions +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_target_definitions( TO + SCOPE + TARGET_DEFINITIONS [FOO [BAR ...]]) + +Appends pre-processor definitions to the given target's existing flags. + +TO + Name of CMake target + +SCOPE + Defines the scope of the given definitions. Defaults to PUBLIC and is case insensitive. + +FLAGS + List of definitions flags + +This macro provides very similar functionality to CMake's native +``add_definitions`` and ``target_add_defintions`` commands, but provides +more fine-grained scoping for the compile definitions on a per target basis. +Given a list of definitions, e.g., FOO and BAR, this macro adds compiler +definitions to the compiler command for the given target, i.e., it will pass +-DFOO and -DBAR. + +The given target must be added via CMake's ``add_executable`` or ``add_library`` commands +or with the corresponding ``blt_add_executable`` and ``blt_add_library`` macros. + +PRIVATE flags are used for the given target. INTERFACE flags are inherited +by any target that depends on this target. PUBLIC flags are both INTERFACE and PRIVATE. + +.. note:: + The target definitions can either include or omit the "-D" characters. + E.g. the following are all valid ways to add two compile definitions + (A=1 and B) to target 'foo'. + +.. note:: + This macro will strip away leading and trailing whitespace from each definition. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + blt_add_target_definitions(TO foo TARGET_DEFINITIONS A=1 B) + blt_add_target_definitions(TO foo TARGET_DEFINITIONS -DA=1 -DB) + blt_add_target_definitions(TO foo TARGET_DEFINITIONS "A=1;-DB") + blt_add_target_definitions(TO foo TARGET_DEFINITIONS " " -DA=1;B) + + +blt_add_target_link_flags +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_add_target_link_flags( TO + SCOPE + FLAGS [FOO [BAR ...]]) + +Appends linker flags to a the given target's existing flags. + +TO + Name of CMake target + +SCOPE + Defines the scope of the given flags. Defaults to PUBLIC and is case insensitive. + +FLAGS + List of linker flags + +This macro provides very similar functionality to CMake's native +``add_link_options`` and ``target_link_options`` commands, but provides +more fine-grained scoping for the compile definitions on a per target basis. + +The given target must be added via CMake's ``add_executable`` or ``add_library`` commands +or with the corresponding ``blt_add_executable`` and ``blt_add_library`` macros. + +PRIVATE flags are used for the given target. INTERFACE flags are inherited +by any target that depends on this target. PUBLIC flags are both INTERFACE and PRIVATE. + +If `CUDA_LINK_WITH_NVCC` is set to ON, this macro will automatically convert +"-Wl,-rpath," to "-Xlinker -rpath -Xlinker ". + +.. note:: + This macro also handles the various changes that CMake made in 3.13. For example, + the target property LINK_FLAGS was changes to LINK_OPTIONS and was changed from a + string to a list. New versions now support Generator Expressions. Also pre-3.13, + there were no macros to add link flags to targets so we do this by setting the properties + directly. + +.. note:: + In CMake versions prior to 3.13, this list is converted to a string internally + and any ; characters will be removed. + +.. note:: + In CMake versions 3.13 and above, this list is prepended with "SHELL:" which stops + CMake from de-duplicating flags. This is especially bad when linking with NVCC when + you have groups of flags like "-Xlinker -rpath -Xlinker ". + + +blt_print_target_properties +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_print_target_properties(TARGET ) + +Prints out all properties of the given target. + +TARGET + Name of CMake target + +The given target must be added via ``add_executable`` or ``add_library`` or +with the corresponding ``blt_add_executable``, ``blt_add_library``, or +``blt_register_library`` macros. + +Output is of the form for each property: + | [ property] : + + +blt_set_target_folder +~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_set_target_folder( TARGET + FOLDER ) + +Sets the FOLDER property of the given CMake target. + +TARGET + Name of CMake target + +FOLDER + Name of the folder + +This is used to organize properties in an IDE. + +This feature is only available when BLT's `ENABLE_FOLDERS` option is ON and +in CMake generators that support folders (but is safe to call regardless +of the generator or value of ENABLE_FOLDERS). + +.. note:: + Do not use this macro on header-only (INTERFACE) library targets, since + this will generate a CMake configuration error. + diff --git a/tpl/RAJA/blt/docs/api/utility.rst b/tpl/RAJA/blt/docs/api/utility.rst new file mode 100644 index 000000000..f462e00d7 --- /dev/null +++ b/tpl/RAJA/blt/docs/api/utility.rst @@ -0,0 +1,124 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Utility Macros +============== + + +blt_append_custom_compiler_flag +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_append_custom_compiler_flag( + FLAGS_VAR flagsVar (required) + DEFAULT defaultFlag (optional) + GNU gnuFlag (optional) + CLANG clangFlag (optional) + HCC hccFlag (optional) + INTEL intelFlag (optional) + XL xlFlag (optional) + MSVC msvcFlag (optional) + MSVC_INTEL msvcIntelFlag (optional) + PGI pgiFlag (optional) + CRAY crayFlag (optional)) + +Appends compiler-specific flags to a given variable of flags + +If a custom flag is given for the current compiler, we use that. +Otherwise, we will use the DEFAULT flag (if present). + +If ENABLE_FORTRAN is On, any flagsVar with "fortran" (any capitalization) +in its name will pick the compiler family (GNU,CLANG, INTEL, etc) based on +the fortran compiler family type. This allows mixing C and Fortran compiler +families, e.g. using Intel fortran compilers with clang C compilers. + +When using the Intel toolchain within visual studio, we use the +MSVC_INTEL flag, when provided, with a fallback to the MSVC flag. + + +blt_find_libraries +~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_find_libraries( FOUND_LIBS + NAMES [libname1 [libname2 ...]] + REQUIRED [TRUE (default) | FALSE ] + PATHS [path1 [path2 ...]]) + +This command is used to find a list of libraries. + +If the libraries are found the results are appended to the given FOUND_LIBS variable name. +NAMES lists the names of the libraries that will be searched for in the given PATHS. + +If REQUIRED is set to TRUE, BLT will produce an error message if any of the +given libraries are not found. The default value is TRUE. + +PATH lists the paths in which to search for NAMES. No system paths will be searched. + + +blt_list_append +~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_list_append(TO + ELEMENTS [...] + IF ) + +Appends elements to a list if the specified bool evaluates to true. + +This macro is essentially a wrapper around CMake's ``list(APPEND ...)`` +command which allows inlining a conditional check within the same call +for clarity and convenience. + +This macro requires specifying: + + * The target list to append to by passing ``TO `` + * A condition to check by passing ``IF `` + * The list of elements to append by passing ``ELEMENTS [...]`` + +Note, the argument passed to the IF option has to be a single boolean value +and cannot be a boolean expression since CMake cannot evaluate those inline. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + set(mylist A B) + + set(ENABLE_C TRUE) + blt_list_append( TO mylist ELEMENTS C IF ${ENABLE_C} ) # Appends 'C' + + set(ENABLE_D TRUE) + blt_list_append( TO mylist ELEMENTS D IF ENABLE_D ) # Appends 'D' + + set(ENABLE_E FALSE) + blt_list_append( TO mylist ELEMENTS E IF ENABLE_E ) # Does not append 'E' + + unset(_undefined) + blt_list_append( TO mylist ELEMENTS F IF _undefined ) # Does not append 'F' + + +blt_list_remove_duplicates +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: cmake + + blt_list_remove_duplicates(TO ) + +Removes duplicate elements from the given TO list. + +This macro is essentially a wrapper around CMake's ``list(REMOVE_DUPLICATES ...)`` +command but doesn't throw an error if the list is empty or not defined. + +.. code-block:: cmake + :caption: **Example** + :linenos: + + set(mylist A B A) + blt_list_remove_duplicates( TO mylist ) + diff --git a/tpl/RAJA/blt/docs/conf.py b/tpl/RAJA/blt/docs/conf.py new file mode 100644 index 000000000..1134ebf06 --- /dev/null +++ b/tpl/RAJA/blt/docs/conf.py @@ -0,0 +1,224 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +# -*- coding: utf-8 -*- +# +# BLT Tutorial documentation build configuration file, created by +# sphinx-quickstart on Wed Apr 22 14:00:36 2015. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.imgmath'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'BLT: Build, Link, and Test' +copyright = u'2017-2019, BLT Development Team' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +#version = '0.1' +# The full version, including alpha/beta/rc tags. +#release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['tutorial/calc_pi/docs'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +try: + import sphinx_rtd_theme +except: + html_theme = 'classic' + html_theme_options = { + 'codebgcolor': 'lightgrey', + 'stickysidebar': 'true' + } + html_theme_path = [] +else: + html_theme = 'sphinx_rtd_theme' + html_theme_options = {} + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'BLTTutorialGuidedoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'BLTTutorialGuide.tex', u'BLT Tutorial Guide', + u'BLT Team', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'blttutorialguide', u'BLT Tutorial Guide', + [u'BLT Team'], 1) +] diff --git a/tpl/RAJA/blt/docs/index.rst b/tpl/RAJA/blt/docs/index.rst new file mode 100644 index 000000000..aad69cf40 --- /dev/null +++ b/tpl/RAJA/blt/docs/index.rst @@ -0,0 +1,69 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +BLT +=== + +**Build, Link, and Test** + +BLT is a composition of CMake macros and several widely used open source tools +assembled to simplify HPC software development. + +BLT was released by Lawrence Livermore National Laboratory (LLNL) under a BSD-style open source license. +It is developed on github under LLNL's github organization: https://github.com/llnl/blt + +.. note:: + BLT officially supports CMake 3.8 and above. However we only print a warning if you + are below this version. Some features in earlier versions may or may not work. Use at your own risk. + + +BLT at a Glance +~~~~~~~~~~~~~~~~~~ + +* Simplifies setting up a CMake-based build system + + * CMake macros for: + + * Creating libraries and executables + * Managing compiler flags + * Managing external dependencies + + * Multi-platform support (HPC Platforms, OSX, Windows) + +* Batteries included + + * Built-in support for HPC Basics: MPI, OpenMP, and CUDA + * Built-in support for unit testing in C/C++ and Fortran + +* Streamlines development processes + + * Support for documentation generation + * Support for code health tools: + + * Runtime and static analysis, benchmarking + +Developers +~~~~~~~~~~ + + * Chris White (white238@llnl.gov) + * Cyrus Harrison (harrison37@llnl.gov) + * George Zagaris (zagaris2@llnl.gov) + * Kenneth Weiss (kweiss@llnl.gov) + * Lee Taylor (taylor16@llnl.gov) + * Aaron Black (black27@llnl.gov) + * David A. Beckingsale (beckingsale1@llnl.gov) + * Richard Hornung (hornung1@llnl.gov) + * Randolph Settgast (settgast1@llnl.gov) + * Peter Robinson (robinson96@llnl.gov) + + +Documentation +~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 2 + + User Tutorial + API Documentation diff --git a/tpl/RAJA/blt/docs/tutorial/blank_project/CMakeLists.txt b/tpl/RAJA/blt/docs/tutorial/blank_project/CMakeLists.txt new file mode 100644 index 000000000..5cb199f71 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/blank_project/CMakeLists.txt @@ -0,0 +1,32 @@ +#------------------------------------------------------------------------------ +# BLT Tutorial Example: Blank Project. +#------------------------------------------------------------------------------ + +cmake_minimum_required(VERSION 3.8) +project( blank ) + +#------------------------------------------------------------------------------ +# Setup BLT +#------------------------------------------------------------------------------ + +# _blt_tutorial_include_blt_start +if (DEFINED BLT_SOURCE_DIR) + # Support having a shared BLT outside of the repository if given a BLT_SOURCE_DIR + if (NOT EXISTS ${BLT_SOURCE_DIR}/SetupBLT.cmake) + message(FATAL_ERROR "Given BLT_SOURCE_DIR does not contain SetupBLT.cmake") + endif() +else() + # Use internal BLT if no BLT_SOURCE_DIR is given + set(BLT_SOURCE_DIR "${PROJECT_SOURCE_DIR}/cmake/blt" CACHE PATH "") + if (NOT EXISTS ${BLT_SOURCE_DIR}/SetupBLT.cmake) + message(FATAL_ERROR + "The BLT git submodule is not present. " + "Either run the following two commands in your git repository: \n" + " git submodule init\n" + " git submodule update\n" + "Or add -DBLT_SOURCE_DIR=/path/to/blt to your CMake command." ) + endif() +endif() + +include(${BLT_SOURCE_DIR}/SetupBLT.cmake) +# _blt_tutorial_include_blt_end diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/CMakeLists.txt b/tpl/RAJA/blt/docs/tutorial/calc_pi/CMakeLists.txt new file mode 100644 index 000000000..6ac7a8563 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/CMakeLists.txt @@ -0,0 +1,123 @@ +#------------------------------------------------------------------------------ +# BLT Tutorial Example: Calc Pi. +#------------------------------------------------------------------------------ + +cmake_minimum_required(VERSION 3.8) + +project( pi_playground ) + +#------------------------------------------------------------------------------ +# Setup BLT +#------------------------------------------------------------------------------ +# Set BLT_SOURCE_DIR to default location, if not set by user +if(NOT BLT_SOURCE_DIR) + set(BLT_SOURCE_DIR "blt") +endif() + +include(${BLT_SOURCE_DIR}/SetupBLT.cmake) + +#------------------------------------------------------------------------------ +# Example 1: Creating a simple executable. +#------------------------------------------------------------------------------ +# _blt_tutorial_example_executable_start +blt_add_executable( NAME example_1 + SOURCES example_1.cpp ) +# _blt_tutorial_example_executable_end + +#------------------------------------------------------------------------------ +# Example 2: Creating a library and an executable using our library. +#------------------------------------------------------------------------------ +# _blt_tutorial_calcpi_library_start +blt_add_library( NAME calc_pi + HEADERS calc_pi.hpp calc_pi_exports.h + SOURCES calc_pi.cpp ) +# _blt_tutorial_calcpi_library_end + +if(WIN32 AND BUILD_SHARED_LIBS) + target_compile_definitions(calc_pi PUBLIC WIN32_SHARED_LIBS) +endif() + +# _blt_tutorial_calcpi_example2_start +blt_add_executable( NAME example_2 + SOURCES example_2.cpp + DEPENDS_ON calc_pi) +# _blt_tutorial_calcpi_example2_end + +#------------------------------------------------------------------------------ +# Test 1: Creating an executable using gtest, using the executable via ctest. +#------------------------------------------------------------------------------ +# _blt_tutorial_calcpi_test1_executable_start +blt_add_executable( NAME test_1 + SOURCES test_1.cpp + DEPENDS_ON calc_pi gtest) +# _blt_tutorial_calcpi_test1_executable_end + +# _blt_tutorial_calcpi_test1_test_start +blt_add_test( NAME test_1 + COMMAND test_1) +# _blt_tutorial_calcpi_test1_test_end + +#------------------------------------------------------------------------------ +# Test 2: Add mpi version of calc_pi, and expand test 1 to also test +# the mpi version. +#------------------------------------------------------------------------------ +if(MPI_FOUND) +# _blt_tutorial_calcpi_test2_executable_start + blt_add_library( NAME calc_pi_mpi + HEADERS calc_pi_mpi.hpp calc_pi_mpi_exports.h + SOURCES calc_pi_mpi.cpp + DEPENDS_ON mpi) + + if(WIN32 AND BUILD_SHARED_LIBS) + target_compile_definitions(calc_pi_mpi PUBLIC WIN32_SHARED_LIBS) + endif() + + blt_add_executable( NAME test_2 + SOURCES test_2.cpp + DEPENDS_ON calc_pi calc_pi_mpi gtest) +# _blt_tutorial_calcpi_test2_executable_end + +# _blt_tutorial_calcpi_test2_test_start + blt_add_test( NAME test_2 + COMMAND test_2 + NUM_MPI_TASKS 2) # number of mpi tasks to use +# _blt_tutorial_calcpi_test2_test_end +endif() + +#------------------------------------------------------------------------------ +# Test 3: Add cuda version of calc_pi, and expand test 1 to also test +# the cuda version. +#------------------------------------------------------------------------------ +if(CUDA_FOUND) +# _blt_tutorial_calcpi_cuda_start + # avoid warnings about sm_20 deprecated + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-arch=sm_30) + + blt_add_library( NAME calc_pi_cuda + HEADERS calc_pi_cuda.hpp calc_pi_cuda_exports.h + SOURCES calc_pi_cuda.cpp + DEPENDS_ON cuda) + + if(WIN32 AND BUILD_SHARED_LIBS) + target_compile_definitions(calc_pi_cuda PUBLIC WIN32_SHARED_LIBS) + endif() + + + + blt_add_executable( NAME test_3 + SOURCES test_3.cpp + DEPENDS_ON calc_pi calc_pi_cuda gtest cuda_runtime) + + blt_add_test( NAME test_3 + COMMAND test_3) +# _blt_tutorial_calcpi_cuda_end +endif() + + +#------------------------------------------------------------------------------ +# Add Documentation Examples +#------------------------------------------------------------------------------ +add_subdirectory(docs) + + + diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.cpp new file mode 100644 index 000000000..b0d3c6337 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.cpp @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: calc_pi.cpp +// +// Source file for calc_pi library example. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// +#include "calc_pi.hpp" +// -- calculate pi via simple integration -- // +double calc_pi(int num_intervals) +{ + int i =0; + + double h = 1.0 / (double) num_intervals; + double sum = 0.0; + + while(i != num_intervals) + { + double x = h * ((double)i + 0.5); + sum += (4.0 / (1.0 + x*x)); + i++; + } + + double pi = h * sum; + + return pi; +} diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.hpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.hpp new file mode 100644 index 000000000..6d16d0a56 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi.hpp @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +/// +/// \file calc_pi.hpp +/// +/// Header file for calc_pi library example. +/// +/// Adapted from: +/// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CALC_PI_HPP +#define CALC_PI_HPP +#include "calc_pi_exports.h" +/// +/// \brief calculate pi +/// +/// Estimate pi by integrating f(x) = 4/(1+x^2) from 0 to 1 using +/// numerical integration over a given number of intervals. +/// +double CALC_PI_API calc_pi(int num_intervals); + +#endif diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.cpp new file mode 100644 index 000000000..327445ab8 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.cpp @@ -0,0 +1,134 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: calc_pi_cuda.cpp +// +// Source file for calc_pi_cuda library example. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#include +#include "calc_pi_cuda.hpp" +const int block_size = 512; + +// -- helper for calcing number of blocks to launch -- // +int iDivUp(int a, int b) +{ + return (a % b != 0) ? (a / b + 1) : (a / b); +} + +// -- atomic add of doubles for older cuda archs -- // +// from http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#atomic-functions +#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600 +// cuda 8 provides atomicAdd for doubles for all arches +#else +__device__ double atomicAdd(double *address, + double val) +{ + unsigned long long int* address_as_ull = (unsigned long long int*)address; + + // orig: + // unsigned long long int old = *address_as_ull, assumed; + + // less clever version: + unsigned long long int old = *address_as_ull; + unsigned long long int assumed; + do + { + assumed = old; + old = atomicCAS(address_as_ull, + assumed, + __double_as_longlong(val + __longlong_as_double(assumed))); + // Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN) + } + while (assumed != old); + + return __longlong_as_double(old); +} +#endif + + +// -- cuda kernel to calculate pi via simple integration -- // +__global__ void calc_pi_kernel(int num_intervals, + double *pi) +{ + // local thread id + int tid = threadIdx.x; + // calc id + int i = blockIdx.x*blockDim.x + threadIdx.x; + + __shared__ double sum[block_size]; + + double h = 1.0 / (double) num_intervals; + + // calc sum contrib in parallel + double x = h * ((double)i + 0.5); + double thread_sum = 4.0 / (1.0 + x*x); + + // save to shared memory, last block may pad with 0’s + sum[tid] = (i < num_intervals) ? thread_sum : 0.0; + __syncthreads(); + + // Build summation tree over elements + for(int s=blockDim.x/2; s>0; s=s/2) + { + if(tid < s) + { + sum[tid] += sum[tid + s]; + } + __syncthreads(); + } + // Thread 0 adds the partial sum to the total sum + if( tid == 0 ) + { + atomicAdd(pi, sum[tid]); + } +} + +// -- helper to check for cuda errors -- // +bool check_cuda_error(cudaError_t cuda_result) +{ + bool res = false; + if (cuda_result != cudaSuccess) + { + std::cerr << "CUDA ERROR:" + << cudaGetErrorString(cuda_result) + << std::endl;; + res = true; + } + + return res; +} + +// -- calculate pi via simple integration -- // +double calc_pi_cuda(int num_intervals) +{ + int num_threads = block_size; + int num_blocks = iDivUp(num_intervals, block_size); + + double h_pi = 0.0; + double *d_pi = NULL; + + check_cuda_error( cudaMalloc((void**)&d_pi, sizeof(double)) ); + + check_cuda_error( cudaMemset(d_pi, 0, sizeof(double)) ); + + calc_pi_kernel<<>>(num_intervals, d_pi); + + check_cuda_error( cudaGetLastError() ); + + check_cuda_error( cudaMemcpy(&h_pi, d_pi, + sizeof(double), + cudaMemcpyDeviceToHost) ); + + check_cuda_error( cudaDeviceSynchronize() ); + + check_cuda_error( cudaFree(d_pi)) ; + + // final scaling + return h_pi / (double) num_intervals; +} + + + diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.hpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.hpp new file mode 100644 index 000000000..cbac98a80 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda.hpp @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +/// +/// \file calc_pi_cuda.hpp +/// +/// Header file for calc_pi_cuda library example. +/// +/// Adapted from: +/// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CALC_PI_CUDA_HPP +#define CALC_PI_CUDA_HPP +#include "calc_pi_cuda_exports.h" +/// +/// \brief calculate pi using cuda +/// +/// Estimate pi by integrating f(x) = 4/(1+x^2) from 0 to 1 using +/// numerical integration over a given number of intervals. +/// +double CALC_PI_CUDA_API calc_pi_cuda(int num_intervals); + +#endif diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda_exports.h b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda_exports.h new file mode 100644 index 000000000..b32f71d01 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_cuda_exports.h @@ -0,0 +1,37 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// calc_pi_cuda_exports.h +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +#ifndef CALC_PI_CUDA_EXPORTS_H +#define CALC_PI_CUDA_EXPORTS_H + +//----------------------------------------------------------------------------- +// -- define proper lib exports for various platforms -- +//----------------------------------------------------------------------------- +#if defined(_WIN32) + #if defined(WIN32_SHARED_LIBS) + #if defined(CALC_PI_CUDA_EXPORTS) || defined(calc_pi_cuda_EXPORTS) + #define CALC_PI_CUDA_API __declspec(dllexport) + #else + #define CALC_PI_CUDA_API __declspec(dllimport) + #endif + #else + #define CALC_PI_CUDA_API /* not needed for static on windows */ + #endif + #if defined(_MSC_VER) + /* Turn off warning about lack of DLL interface */ + #pragma warning(disable:4251) + /* Turn off warning non-dll class is base for dll-interface class. */ + #pragma warning(disable:4275) + /* Turn off warning about identifier truncation */ + #pragma warning(disable:4786) + #endif +#else +# if __GNUC__ >= 4 && (defined(CALC_PI_CUDA_EXPORTS) || defined(calc_pi_cuda_EXPORTS)) +# define CALC_PI_CUDA_API __attribute__ ((visibility("default"))) +# else +# define CALC_PI_CUDA_API /* hidden by default */ +# endif +#endif + +#endif diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_exports.h b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_exports.h new file mode 100644 index 000000000..a541ab6ea --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_exports.h @@ -0,0 +1,37 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// calc_pi_exports.h +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +#ifndef CALC_PI_EXPORTS_H +#define CALC_PI_EXPORTS_H + +//----------------------------------------------------------------------------- +// -- define proper lib exports for various platforms -- +//----------------------------------------------------------------------------- +#if defined(_WIN32) + #if defined(WIN32_SHARED_LIBS) + #if defined(CALC_PI_EXPORTS) || defined(calc_pi_EXPORTS) + #define CALC_PI_API __declspec(dllexport) + #else + #define CALC_PI_API __declspec(dllimport) + #endif + #else + #define CALC_PI_API /* not needed for static on windows */ + #endif + #if defined(_MSC_VER) + /* Turn off warning about lack of DLL interface */ + #pragma warning(disable:4251) + /* Turn off warning non-dll class is base for dll-interface class. */ + #pragma warning(disable:4275) + /* Turn off warning about identifier truncation */ + #pragma warning(disable:4786) + #endif +#else +# if __GNUC__ >= 4 && (defined(CALC_PI_EXPORTS) || defined(calc_pi_EXPORTS)) +# define CALC_PI_API __attribute__ ((visibility("default"))) +# else +# define CALC_PI_API /* hidden by default */ +# endif +#endif + +#endif diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.cpp new file mode 100644 index 000000000..4f05522e0 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.cpp @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: calc_pi_mpi.cpp +// +// Source file for calc_pi_mpi library example. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#include "mpi.h" +#include "calc_pi_mpi.hpp" +// -- calculate pi via simple integration -- // +double calc_pi_mpi(int num_intervals) +{ + int num_tasks = 0; + int task_id = 0; + + MPI_Comm_size(MPI_COMM_WORLD, &num_tasks); + MPI_Comm_rank(MPI_COMM_WORLD, &task_id); + + double h = 1.0 / (double) num_intervals; + double sum = 0.0; + + for(int i = task_id + 1; i <= num_intervals; i+= num_tasks) + { + double x = h * ((double)i - 0.5); + sum += (4.0 / (1.0 + x*x)); + } + + double pi_local = h * sum; + double pi = 0; + + MPI_Allreduce(&pi_local, + &pi, + 1, + MPI_DOUBLE, + MPI_SUM, + MPI_COMM_WORLD); + + + return pi; +} diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.hpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.hpp new file mode 100644 index 000000000..01ca7f835 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi.hpp @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +/// +/// \file calc_pi_mpi.hpp +/// +/// Header file for calc_pi_mpi library example. +/// +/// Adapted from: +/// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CALC_PI_MPI_HPP +#define CALC_PI_MPI_HPP +#include "calc_pi_mpi_exports.h" +/// +/// \brief calculate pi using mpi +/// +/// Estimate pi by integrating f(x) = 4/(1+x^2) from 0 to 1 using +/// numerical integration over a given number of intervals. +/// +double CALC_PI_MPI_API calc_pi_mpi(int num_intervals); + +#endif diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi_exports.h b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi_exports.h new file mode 100644 index 000000000..6dc0eaf1a --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/calc_pi_mpi_exports.h @@ -0,0 +1,37 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// calc_pi_mpi_exports.h +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +#ifndef CALC_PI_MPI_EXPORTS_H +#define CALC_PI_MPI_EXPORTS_H + +//----------------------------------------------------------------------------- +// -- define proper lib exports for various platforms -- +//----------------------------------------------------------------------------- +#if defined(_WIN32) + #if defined(WIN32_SHARED_LIBS) + #if defined(CALC_PI_MPI_EXPORTS) || defined(calc_pi_mpi_EXPORTS) + #define CALC_PI_MPI_API __declspec(dllexport) + #else + #define CALC_PI_MPI_API __declspec(dllimport) + #endif + #else + #define CALC_PI_MPI_API /* not needed for static on windows */ + #endif + #if defined(_MSC_VER) + /* Turn off warning about lack of DLL interface */ + #pragma warning(disable:4251) + /* Turn off warning non-dll class is base for dll-interface class. */ + #pragma warning(disable:4275) + /* Turn off warning about identifier truncation */ + #pragma warning(disable:4786) + #endif +#else +# if __GNUC__ >= 4 && (defined(CALC_PI_MPI_EXPORTS) || defined(calc_pi_mpi_EXPORTS)) +# define CALC_PI_MPI_API __attribute__ ((visibility("default"))) +# else +# define CALC_PI_MPI_API /* hidden by default */ +# endif +#endif + +#endif diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/CMakeLists.txt b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/CMakeLists.txt new file mode 100644 index 000000000..7ce16d717 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/CMakeLists.txt @@ -0,0 +1,7 @@ +######################### +# documentation targets +######################### + +add_subdirectory(doxygen) +add_subdirectory(sphinx) + diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/CMakeLists.txt b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/CMakeLists.txt new file mode 100644 index 000000000..be6c9e1a1 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/CMakeLists.txt @@ -0,0 +1,8 @@ +#------------------------------------------------------------------------------ +# add a target to generate documentation with Doxygen +#------------------------------------------------------------------------------ + +if(DOXYGEN_FOUND) + blt_add_doxygen_target( calc_pi_doxygen ) +endif() + diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/Doxyfile.in b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/Doxyfile.in new file mode 100644 index 000000000..a4e608236 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/doxygen/Doxyfile.in @@ -0,0 +1,14 @@ +#--------------------------------------- +# Doxygen Config for Calc Pi Example +#--------------------------------------- + +PROJECT_NAME = Calc Pi +PROJECT_BRIEF = "Calc Pi" + +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../../ + +GENERATE_XML = NO +GENERATE_LATEX = NO + +RECURSIVE = NO +STRIP_CODE_COMMENTS = NO diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/CMakeLists.txt b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/CMakeLists.txt new file mode 100644 index 000000000..3f96021f2 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/CMakeLists.txt @@ -0,0 +1,7 @@ +#------------------------------------------------------------------------------ +# add a target to generate documentation with sphinx +#------------------------------------------------------------------------------ + +if(SPHINX_FOUND) + blt_add_sphinx_target( calc_pi_sphinx ) +endif() diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/conf.py b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/conf.py new file mode 100644 index 000000000..7b35c555d --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/conf.py @@ -0,0 +1,356 @@ +# -*- coding: utf-8 -*- +# +# Calc Pi documentation build configuration file, created by +# sphinx-quickstart on Sun Sep 10 21:47:20 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.imgmath', + 'sphinx.ext.githubpages', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +# +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Calc Pi' +copyright = u'Calc Pi Developers' +author = u'Calc Pi Developers' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'0.0.1' +# The full version, including alpha/beta/rc tags. +release = u'0.0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# +# today = '' +# +# Else, today_fmt is used as the format for a strftime call. +# +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# + +try: + import sphinx_rtd_theme +except: + html_theme = 'classic' + html_theme_options = { + 'codebgcolor': 'lightgrey', + 'stickysidebar': 'true' + } + html_theme_path = [] +else: + html_theme = 'sphinx_rtd_theme' + html_theme_options = {} + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + + + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. +# " v documentation" by default. +# +# html_title = u'Calc Pi v0.0.1' + +# A shorter title for the navigation bar. Default is the same as html_title. +# +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# +# html_logo = None + +# The name of an image file (relative to this directory) to use as a favicon of +# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# +# html_extra_path = [] + +# If not None, a 'Last updated on:' timestamp is inserted at every page +# bottom, using the given strftime format. +# The empty string is equivalent to '%b %d, %Y'. +# +# html_last_updated_fmt = None + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# +# html_additional_pages = {} + +# If false, no module index is generated. +# +# html_domain_indices = True + +# If false, no index is generated. +# +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' +# +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# 'ja' uses this config value. +# 'zh' user can custom change `jieba` dictionary path. +# +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'CalcPidoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'CalcPi.tex', u'Calc Pi Documentation', + u'Calc Pi Developers', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# +# latex_use_parts = False + +# If true, show page references after internal links. +# +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# +# latex_appendices = [] + +# It false, will not define \strong, \code, itleref, \crossref ... but only +# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added +# packages. +# +# latex_keep_old_macro_names = True + +# If false, no module index is generated. +# +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'calcpi', u'Calc Pi Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +# +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'CalcPi', u'Calc Pi Documentation', + author, 'CalcPi', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +# +# texinfo_appendices = [] + +# If false, no module index is generated. +# +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# +# texinfo_no_detailmenu = False diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/index.rst b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/index.rst new file mode 100644 index 000000000..ac3fe076e --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/docs/sphinx/index.rst @@ -0,0 +1,25 @@ +.. Calc Pi documentation master file, created by + sphinx-quickstart on Sun Sep 10 21:47:20 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Calc Pi's documentation! +=================================== + + +This is a tutorial example for BLT (https://github.com/llnl/blt) that creates +C++ libraries that calculate :math:`\pi` serially and in parallel using MPI +and CUDA. + +These libraries calculate :math:`\pi` by approximating the integral +:math:`f(x) = \int_0^14/(1+x^2)` using numerical integration. +In the MPI implementation, the intervals are distributed across MPI tasks and +a MPI_AllReduce calculates the final result. In the CUDA implementation, the +intervals are distributed across CUDA blocks and threads and a tree reduction +calculates the final result. + + +The method is adapted from: +https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html + + diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/example_1.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/example_1.cpp new file mode 100644 index 000000000..7f1191bf1 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/example_1.cpp @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: calc_pi_example_1.cpp +// +// Simple example that calculates pi via simple integration. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +// -- calculate pi via simple integration -- // +double calc_pi(int num_intervals) +{ + int i =0; + + double h = 1.0 / (double) num_intervals; + double sum = 0.0; + + while(i != num_intervals) + { + double x = h * ((double)i + 0.5); + sum += (4.0 / (1.0 + x*x)); + i++; + } + + double pi = h * sum; + + return pi; +} + +// -- main driver -- // +int main(int argc, char * argv[] ) +{ + double PI_REF = 3.141592653589793238462643; + + int num_intervals = 100; + if(argc >1) + { + num_intervals = std::atoi(argv[1]); + } + + std::cout << "calculating pi using " + << num_intervals + << " intervals." + << std::endl; + + double pi = calc_pi(num_intervals); + + std::cout.precision(16); + + std::cout << "pi is approximately " + << pi + << " , Error is " + << fabs(pi - PI_REF) + << std::endl; + +} diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/example_2.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/example_2.cpp new file mode 100644 index 000000000..ab61beeba --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/example_2.cpp @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: calc_pi_example_2.cpp +// +// Simple example that calculates pi via simple integration. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +#include "calc_pi.hpp" + +// -- main driver -- // +int main(int argc, char * argv[] ) +{ + double PI_REF = 3.141592653589793238462643; + + int num_intervals = 100; + if(argc >1) + { + num_intervals = std::atoi(argv[1]); + } + + std::cout << "calculating pi using " + << num_intervals + << " intervals." + << std::endl; + + double pi = calc_pi(num_intervals); + + std::cout.precision(16); + + std::cout << "pi is approximately " + << pi + << " , Error is " + << fabs(pi - PI_REF) + << std::endl; + +} \ No newline at end of file diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/test_1.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/test_1.cpp new file mode 100644 index 000000000..2aaac6783 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/test_1.cpp @@ -0,0 +1,21 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: test_1.cpp +// +// Simple example that calculates pi via simple integration. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +// _blt_tutorial_calpi_test1_start +#include + +#include "calc_pi.hpp" + +TEST(calc_pi, serial_example) +{ + double PI_REF = 3.141592653589793238462643; + ASSERT_NEAR(calc_pi(1000),PI_REF,1e-6); +} +// _blt_tutorial_calpi_test1_end diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/test_2.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/test_2.cpp new file mode 100644 index 000000000..0b6cbaa73 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/test_2.cpp @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: test_2.cpp +// +// Simple example that calculates pi via simple integration. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#include + +#include "mpi.h" + +#include "calc_pi.hpp" +#include "calc_pi_mpi.hpp" + +const double PI_REF = 3.141592653589793238462643; + +// test serial lib +TEST(calc_pi_mpi, serial_example) +{ + ASSERT_NEAR(calc_pi(1000),PI_REF,1e-6); +} + + +// test mpi lib +TEST(calc_pi_mpi, mpi_example) +{ + ASSERT_NEAR(calc_pi_mpi(1000),PI_REF,1e-6); +} + +// compare mpi and serial +TEST(calc_pi_mpi, compare_mpi_serial) +{ + ASSERT_NEAR(calc_pi(1000),calc_pi_mpi(1000),1e-12); +} + +// _blt_tutorial_calcpi_test2_main_start +// main driver that allows using mpi w/ google test +int main(int argc, char * argv[]) +{ + int result = 0; + + ::testing::InitGoogleTest(&argc, argv); + + MPI_Init(&argc, &argv); + + result = RUN_ALL_TESTS(); + + MPI_Finalize(); + + return result; +} +//_blt_tutorial_calcpi_test2_main_end diff --git a/tpl/RAJA/blt/docs/tutorial/calc_pi/test_3.cpp b/tpl/RAJA/blt/docs/tutorial/calc_pi/test_3.cpp new file mode 100644 index 000000000..15fe10515 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/calc_pi/test_3.cpp @@ -0,0 +1,36 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// file: test_3.cpp +// +// Simple example that calculates pi via simple integration. +// +// Adapted from: +// https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html +/////////////////////////////////////////////////////////////////////////////// + +#include + +#include "calc_pi.hpp" +#include "calc_pi_cuda.hpp" + +const double PI_REF = 3.141592653589793238462643; + +// test serial lib +TEST(calc_pi_cuda, serial_example) +{ + ASSERT_NEAR(calc_pi(1000),PI_REF,1e-6); +} + + +// test cuda lib +TEST(calc_pi_cuda, cuda_example) +{ + ASSERT_NEAR(calc_pi_cuda(1000),PI_REF,1e-6); +} + +// compare serial and cuda +TEST(calc_pi_cuda, compare_serial_cuda) +{ + ASSERT_NEAR(calc_pi(1000),calc_pi_cuda(1000),1e-12); +} + diff --git a/tpl/RAJA/blt/docs/tutorial/creating_documentation.rst b/tpl/RAJA/blt/docs/tutorial/creating_documentation.rst new file mode 100644 index 000000000..fa1068d7f --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/creating_documentation.rst @@ -0,0 +1,140 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Creating Documentation +====================== + +BLT provides macros to build documentation using `Sphinx `_ +and `Doxygen `_. + + +Sphinx is the documentation system used by the Python programming +language project (among many others). + +Doxygen is a widely used system that generates documentation from annotated source code. +Doxygen is heavily used for documenting C++ software. + +Sphinx and Doxygen are not built into BLT, so the ``sphinx-build`` and ``doxygen`` executables +must be available via a user's ``PATH`` at configuration time, or explicitly specified using the +CMake variables ``SPHINX_EXECUTABLE`` and ``DOXYGEN_EXECUTABLE``. + + +Here is an example of setting ``sphinx-build`` and ``doxygen`` paths in a host-config file: + +.. code-block:: cmake + + set(SPHINX_EXECUTABLE "/usr/bin/sphinx-build" CACHE FILEPATH "") + + set(DOXYGEN_EXECUTABLE "/usr/bin/doxygen" CACHE FILEPATH "") + + +The ``calc_pi`` example provides examples of both Sphinx and Doxygen documentation. + + +Calc Pi Sphinx Example +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sphinx is a python package that depends on several other packages. +It can be installed via `spack `_, pip, anaconda, etc... + +``sphinx-build`` processes a ``config.py`` file which includes a tree of `reStructuredText` files. +The Sphinx ``sphinx-quickstart`` utility helps you generate a new sphinx project, including +selecting common settings for the ``config.py``. + + +BLT provides a ``blt_add_sphinx_target()`` macro which, which will look for a ``conf.py`` file +in the current directory and add a command to build the Sphinx docs using this file to the ``docs`` +CMake target. + +.. admonition:: blt_add_sphinx_target + :class: hint + + A macro to create a named sphinx target for user documentation. + Assumes there is a ``conf.py`` sphinx configuration file in the current directory. + This macro is active when BLT is configured with a valid ``SPHINX_EXECUTABLE`` path. + + +Here is an example of using ``blt_add_sphinx_target()`` in a CMakeLists.txt file: + +.. literalinclude:: calc_pi/docs/sphinx/CMakeLists.txt + :language: rst + + +Here is the example reStructuredText file that contains documentation for the *calc_pi* example. + +.. literalinclude:: calc_pi/docs/sphinx/index.rst + :language: rst + + +Calc Pi Doxygen Example +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Doxygen is a compiled executable that can be installed via spack, built-by-hand, etc... + +``doxygen`` processes a ``Doxyfile`` which specifies options, including where to look for +annotated source files. + +BLT provides a ``blt_add_doxygen_target()`` macro which, which will look for a ``Doxyfile.in`` +file in the current directory, configure this file to create a ``Doxyfile`` in the build directory, +and add a command to build the Doxygen docs using this file to the ``docs`` CMake target. + +.. admonition:: blt_add_doxygen_target + :class: hint + + A macro to create a named doxygen target for API documentation. + Assumes there is a ``Doxyfile.in`` doxygen configuration file in the current directory. + This macro is active when BLT is configured with a valid ``DOXYGEN_EXECUTABLE`` path. + + +Here is an example of using ``blt_add_doxygen_target()`` in a CMakeLists.txt file: + +.. literalinclude:: calc_pi/docs/doxygen/CMakeLists.txt + :language: rst + + +Here is the example ``Doxyfile.in`` file that is configured by CMake and passed to ``doxygen``. + +.. literalinclude:: calc_pi/docs/doxygen/Doxyfile.in + :language: rst + + + +Building the Calc Pi Example Documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Here is an example of building both the calc_pi Sphinx and Doxygen docs using the ``docs`` CMake target: + +.. code-block:: console + + cd build-calc-pi + make docs + ... + [ 50%] Building HTML documentation with Sphinx + [ 50%] Built target calc_pi_sphinx + [ 50%] Built target sphinx_docs + [100%] Generating API documentation with Doxygen + Searching for include files... + Searching for example files... + Searching for images... + Searching for dot files... + ... + lookup cache used 3/65536 hits=3 misses=3 + finished... + [100%] Built target calc_pi_doxygen + [100%] Built target doxygen_docs + [100%] Built target docs + + + + +After this, you can view the Sphinx docs at: + +* ``build-calc-pi/docs/sphinx/html/index.html`` + +and the Doxygen docs at: + +* ``build-calc-pi/docs/doxygen/html/index.html`` + diff --git a/tpl/RAJA/blt/docs/tutorial/creating_execs_and_libs.rst b/tpl/RAJA/blt/docs/tutorial/creating_execs_and_libs.rst new file mode 100644 index 000000000..6f02cfa39 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/creating_execs_and_libs.rst @@ -0,0 +1,124 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +.. _AddTarget: + +Creating Libraries and Executables +================================== + +In the previous section, we learned the basics about how to create a CMake +project with BLT, how to configure the project and how to build and test BLT's built-in third party libraries. + +We now move on to creating libraries and executables +using two of BLT's core macros: ``blt_add_library()`` and ``blt_add_executable()``. + +We begin with a simple executable that calculates :math:`\pi` by numerical integration +(``example_1``). We will then extract that code into a library, which we link +into a new executable (``example_2``). + + +Example 1: Basic executable +--------------------------- + +This example is as basic as it gets. After setting up a BLT CMake project, +like ``blank_project`` in the previous section, we can start using BLT's macros. +Creating an executable is as simple as calling the following macro: + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_example_executable_start + :end-before: _blt_tutorial_example_executable_end + :language: cmake + +This tells CMake to create an executable named ``example_1`` with one source file +(``example_1.cpp``). + +You can create this project yourself or you can run the already provided +``tutorial/calc_pi`` project. For ease of use, we have combined many examples +into this one CMake project. After running the following commands, you will +create the executable ``/bin/example_1``: + +.. code-block:: bash + + cd /bin`` + (unless overridden with the macro parameter ``OUTPUT_DIR``) and handles + internal and external dependencies in a greatly simplified manner. There + will be more on that in the following section. + + +Example 2: One library, one executable +-------------------------------------- + +This example is a bit more exciting. This time we are creating a library +that calculates the value of pi and then linking that library into an executable. + +First, we create the library with the following BLT code: + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_library_start + :end-before: _blt_tutorial_calcpi_library_end + :language: cmake + +Just like before, this creates a CMake library target that will get built to +``/lib/libcalc_pi.a``. + +Next, we create an executable named ``example_2`` and link in the previously +created library target: + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_example2_start + :end-before: _blt_tutorial_calcpi_example2_end + :language: cmake + +The ``DEPENDS_ON`` parameter properly links the previously defined library +into this executable without any more work or CMake function calls. + + +.. admonition:: blt_add_library + :class: hint + + This is another core BLT macro. It creates a CMake library target and associates + the given sources and headers along with handling dependencies the same way as + ``blt_add_executable`` does. It also provides a few commonly used build options, + such as overriding the output name of the library and the output directory. + It defaults to building a static library unless you override it with + ``SHARED`` or with the global CMake option ``BUILD_SHARED_LIBS``. + +Object Libraries +---------------- + +BLT has simplified the use of CMake object libraries through the +``blt_add_library`` macro. Object libraries are a collection of object files +that are not linked or archived into a library. They are used in other libraries +or executables through the ``DEPENDS_ON`` macro argument. This is generally +useful for combining smaller libraries into a larger library without +the linker removing unused symbols in the larger library. + +.. code-block:: cmake + + blt_add_library(NAME myObjectLibrary + SOURCES source1.cpp + HEADERS header1.cpp + OBJECT TRUE) + + blt_add_exectuble(NAME helloWorld + SOURCES main.cpp + DEPENDS_ON myObjectLibrary) + +.. note:: + Due to record keeping on BLT's part to make object libraries as easy to use + as possible, you need to define object libraries before you use them + if you need their inheritable information to be correct. diff --git a/tpl/RAJA/blt/docs/tutorial/external_dependencies.rst b/tpl/RAJA/blt/docs/tutorial/external_dependencies.rst new file mode 100644 index 000000000..9f3d30c3d --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/external_dependencies.rst @@ -0,0 +1,319 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +External Dependencies +===================== + +One key goal for BLT is to simplify the use of external dependencies when building your libraries and executables. + +To accomplish this BLT provides a ``DEPENDS_ON`` option for the +``blt_add_library()`` and ``blt_add_executable()`` macros that supports both CMake targets +and external dependencies registered using the ``blt_register_library()`` macro. + +The ``blt_register_library()`` macro allows you to reuse all information needed +for an external dependency under a single name. This includes any include +directories, libraries, compile flags, link flags, defines, etc. You can also +hide any warnings created by their headers by setting the +``TREAT_INCLUDES_AS_SYSTEM`` argument. + +For example, to find and register the external dependency *axom* as a BLT registered library, you can simply use: + +.. code-block:: cmake + + # FindAxom.cmake takes in AXOM_DIR, which is a installed Axom build and + # sets variables AXOM_INCLUDES, AXOM_LIBRARIES + include(FindAxom.cmake) + blt_register_library(NAME axom + TREAT_INCLUDES_AS_SYSTEM ON + DEFINES HAVE_AXOM=1 + INCLUDES ${AXOM_INCLUDES} + LIBRARIES ${AXOM_LIBRARIES}) + +Then *axom* is available to be used in the DEPENDS_ON list in the following +``blt_add_executable()`` or ``blt_add_library()`` calls. + +This is especially helpful for external libraries that are not built with CMake +and don't provide CMake-friendly imported targets. Our ultimate goal is to use ``blt_register_library()`` +to import all external dependencies as first-class imported CMake targets to take full advanced of CMake's dependency lattice. + +MPI, CUDA, and OpenMP are all registered via ``blt_register_library()``. +You can see how in ``blt/thirdparty_builtin/CMakelists.txt``. + +BLT also supports using ``blt_register_library()`` to provide additional options for existing CMake targets. +The implementation doesn't modify the properties of the existing targets, +it just exposes these options via BLT's support for ``DEPENDS_ON``. + +.. admonition:: blt_register_library + :class: hint + + A macro to register external libraries and dependencies with BLT. + The named target can be added to the ``DEPENDS_ON`` argument of other BLT macros, + like ``blt_add_library()`` and ``blt_add_executable()``. + + +You have already seen one use of ``DEPENDS_ON`` for a BLT +registered dependency in test_1: ``gtest`` + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_test1_executable_start + :end-before: _blt_tutorial_calcpi_test1_executable_end + :language: cmake + + +``gtest`` is the name for the Google Test dependency in BLT registered via +``blt_register_library()``. Even though Google Test is built-in and uses CMake, +``blt_register_library()`` allows us to easily set defines needed by all dependent +targets. + + +MPI Example +~~~~~~~~~~~~~~~~~~~~~ + +Our next example, ``test_2``, builds and tests the ``calc_pi_mpi`` library, +which uses MPI to parallelize the calculation over the integration intervals. + + +To enable MPI, we set ``ENABLE_MPI``, ``MPI_C_COMPILER``, and ``MPI_CXX_COMPILER`` in our host config file. Here is a snippet with these settings for LLNL's Surface Cluster: + +.. literalinclude:: ../../host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake + :start-after: _blt_tutorial_surface_mpi_config_start + :end-before: _blt_tutorial_surface_mpi_config_end + :language: cmake + + +Here, you can see how ``calc_pi_mpi`` and ``test_2`` use ``DEPENDS_ON``: + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_test2_executable_start + :end-before: _blt_tutorial_calcpi_test2_executable_end + :language: cmake + + +For MPI unit tests, you also need to specify the number of MPI Tasks +to launch. We use the ``NUM_MPI_TASKS`` argument to ``blt_add_test()`` macro. + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_test2_test_start + :end-before: _blt_tutorial_calcpi_test2_test_end + :language: cmake + + +As mentioned in :ref:`UnitTesting`, google test provides a default ``main()`` +driver that will execute all unit tests defined in the source. To test MPI code, +we need to create a main that initializes and finalizes MPI in addition to Google +Test. ``test_2.cpp`` provides an example driver for MPI with Google Test. + +.. literalinclude:: calc_pi/test_2.cpp + :start-after: _blt_tutorial_calcpi_test2_main_start + :end-before: _blt_tutorial_calcpi_test2_main_end + :language: cpp + +.. note:: + While we have tried to ensure that BLT chooses the correct setup information + for MPI, there are several niche cases where the default behavior is + insufficient. We have provided several available override variables: + + * ``BLT_MPI_COMPILE_FLAGS`` + * ``BLT_MPI_INCLUDES`` + * ``BLT_MPI_LIBRARIES`` + * ``BLT_MPI_LINK_FLAGS`` + + BLT also has the variable ``ENABLE_FIND_MPI`` which turns off all CMake's ``FindMPI`` + logic and then uses the MPI wrapper directly when you provide them as the default + compilers. + + +CUDA Example +~~~~~~~~~~~~~~~~~~~~~ + +Finally, ``test_3`` builds and tests the ``calc_pi_cuda`` library, +which uses CUDA to parallelize the calculation over the integration intervals. + +To enable CUDA, we set ``ENABLE_CUDA``, ``CMAKE_CUDA_COMPILER``, and +``CUDA_TOOLKIT_ROOT_DIR`` in our host config file. Also before enabling the +CUDA language in CMake, you need to set ``CMAKE_CUDA_HOST_COMPILER`` in CMake 3.9+ +or ``CUDA_HOST_COMPILER`` in previous versions. If you do not call +``enable_language(CUDA)``, BLT will set the appropriate host compiler variable +for you and enable the CUDA language. + +Here is a snippet with these settings for LLNL's Surface Cluster: + +.. literalinclude:: ../../host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake + :start-after: _blt_tutorial_surface_cuda_config_start + :end-before: _blt_tutorial_surface_cuda_config_end + :language: cmake + +Here, you can see how ``calc_pi_cuda`` and ``test_3`` use ``DEPENDS_ON``: + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_cuda_start + :end-before: _blt_tutorial_calcpi_cuda_end + :language: cmake + +The ``cuda`` dependency for ``calc_pi_cuda`` is a little special, +along with adding the normal CUDA library and headers to your library or executable, +it also tells BLT that this target's C/CXX/CUDA source files need to be compiled via +``nvcc`` or ``cuda-clang``. If this is not a requirement, you can use the dependency +``cuda_runtime`` which also adds the CUDA runtime library and headers but will not +compile each source file with ``nvcc``. + +Some other useful CUDA flags are: + +.. code-block:: cmake + + # Enable separable compilation of all CUDA files for given target or all following targets + set(CUDA_SEPARABLE_COMPILIATION ON CACHE BOOL “”) + set(CUDA_ARCH “sm_60” CACHE STRING “”) + set(CMAKE_CUDA_FLAGS “-restrict –arch ${CUDA_ARCH} –std=c++11” CACHE STRING “”) + set(CMAKE_CUDA_LINK_FLAGS “-Xlinker –rpath –Xlinker /path/to/mpi” CACHE STRING “”) + # Needed when you have CUDA decorations exposed in libraries + set(CUDA_LINK_WITH_NVCC ON CACHE BOOL “”) + + +OpenMP +~~~~~~ + +To enable OpenMP, set ``ENABLE_OPENMP`` in your host-config file or before loading +``SetupBLT.cmake``. Once OpenMP is enabled, simply add ``openmp`` to your library +executable's ``DEPENDS_ON`` list. + +Here is an example of how to add an OpenMP enabled executable: + + .. literalinclude:: ../../tests/smoke/CMakeLists.txt + :start-after: _blt_tutorial_openmp_executable_start + :end-before: _blt_tutorial_openmp_executable_end + :language: cmake + +.. note:: + While we have tried to ensure that BLT chooses the correct compile and link flags for + OpenMP, there are several niche cases where the default options are insufficient. + For example, linking with NVCC requires to link in the OpenMP libraries directly instead + of relying on the compile and link flags returned by CMake's FindOpenMP package. An + example of this is in ``host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_link_with_nvcc.cmake``. + We provide two variables to override BLT's OpenMP flag logic: + + * ``BLT_OPENMP_COMPILE_FLAGS`` + * ``BLT_OPENMP_LINK_FLAGS`` + +Here is an example of how to add an OpenMP enabled test that sets the amount of threads used: + + .. literalinclude:: ../../tests/smoke/CMakeLists.txt + :start-after: _blt_tutorial_openmp_test_start + :end-before: _blt_tutorial_openmp_test_end + :language: cmake + + +Example Host-configs +~~~~~~~~~~~~~~~~~~~~ + +Here are the full example host-config files that use gcc 4.9.3 for LLNL's Surface, Ray and Quartz Clusters. + +:download:`llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake <../../host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake>` + +:download:`llnl/blueos_3_ppc64le_ib_p9/clang@upstream_nvcc_xlf <../../host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_nvcc_xlf.cmake>` + +:download:`llnl/toss_3_x86_64_ib/gcc@4.9.3.cmake <../../host-configs/llnl/toss_3_x86_64_ib/gcc@4.9.3.cmake>` + +.. note:: Quartz does not have GPUs, so CUDA is not enabled in the Quartz host-config. + +Here is a full example host-config file for an OSX laptop, using a set of dependencies built with spack. + +:download:`darwin/elcapitan-x86_64/naples-clang@7.3.0.cmake <../../host-configs/darwin/elcapitan-x86_64/naples-clang@7.3.0.cmake>` + + +Building and testing on Surface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here is how you can use the host-config file to configure a build of the ``calc_pi`` project with MPI and CUDA enabled on Surface: + +.. code-block:: bash + + # load new cmake b/c default on surface is too old + ml cmake/3.9.2 + # create build dir + mkdir build + cd build + # configure using host-config + cmake -C ../../host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake \ + -DBLT_SOURCE_DIR=../../../../blt .. + +After building (``make``), you can run ``make test`` on a batch node (where the GPUs reside) +to run the unit tests that are using MPI and CUDA: + +.. code-block:: console + + bash-4.1$ salloc -A + bash-4.1$ make + bash-4.1$ make test + + Running tests... + Test project blt/docs/tutorial/calc_pi/build + Start 1: test_1 + 1/8 Test #1: test_1 ........................... Passed 0.01 sec + Start 2: test_2 + 2/8 Test #2: test_2 ........................... Passed 2.79 sec + Start 3: test_3 + 3/8 Test #3: test_3 ........................... Passed 0.54 sec + Start 4: blt_gtest_smoke + 4/8 Test #4: blt_gtest_smoke .................. Passed 0.01 sec + Start 5: blt_fruit_smoke + 5/8 Test #5: blt_fruit_smoke .................. Passed 0.01 sec + Start 6: blt_mpi_smoke + 6/8 Test #6: blt_mpi_smoke .................... Passed 2.82 sec + Start 7: blt_cuda_smoke + 7/8 Test #7: blt_cuda_smoke ................... Passed 0.48 sec + Start 8: blt_cuda_runtime_smoke + 8/8 Test #8: blt_cuda_runtime_smoke ........... Passed 0.11 sec + + 100% tests passed, 0 tests failed out of 8 + + Total Test time (real) = 6.80 sec + + +Building and testing on Ray +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here is how you can use the host-config file to configure a build of the ``calc_pi`` project with MPI and CUDA +enabled on the blue_os Ray cluster: + +.. code-block:: bash + + # load new cmake b/c default on ray is too old + ml cmake + # create build dir + mkdir build + cd build + # configure using host-config + cmake -C ../../host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_nvcc_xlf.cmake \ + -DBLT_SOURCE_DIR=../../../../blt .. + +And here is how to build and test the code on Ray: + +.. code-block:: console + + bash-4.2$ lalloc 1 -G + bash-4.2$ make + bash-4.2$ make test + + Running tests... + Test project projects/blt/docs/tutorial/calc_pi/build + Start 1: test_1 + 1/7 Test #1: test_1 ........................... Passed 0.01 sec + Start 2: test_2 + 2/7 Test #2: test_2 ........................... Passed 1.24 sec + Start 3: test_3 + 3/7 Test #3: test_3 ........................... Passed 0.17 sec + Start 4: blt_gtest_smoke + 4/7 Test #4: blt_gtest_smoke .................. Passed 0.01 sec + Start 5: blt_mpi_smoke + 5/7 Test #5: blt_mpi_smoke .................... Passed 0.82 sec + Start 6: blt_cuda_smoke + 6/7 Test #6: blt_cuda_smoke ................... Passed 0.15 sec + Start 7: blt_cuda_runtime_smoke + 7/7 Test #7: blt_cuda_runtime_smoke ........... Passed 0.04 sec + + 100% tests passed, 0 tests failed out of 7 + + Total Test time (real) = 2.47 sec diff --git a/tpl/RAJA/blt/docs/tutorial/index.rst b/tpl/RAJA/blt/docs/tutorial/index.rst new file mode 100644 index 000000000..3ed60f49d --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/index.rst @@ -0,0 +1,37 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +User Tutorial +============= + +This tutorial provides instructions for: + + * Adding BLT to a CMake project + * Setting up *host-config* files to handle multiple platform configurations + * Building, linking, and installing libraries and executables + * Setting up unit tests with GTest + * Using external project dependencies + * Creating documentation with Sphinx and Doxygen + +The tutorial provides several examples that calculate the value of :math:`\pi` +by approximating the integral :math:`f(x) = \int_0^14/(1+x^2)` using numerical +integration. The code is adapted from: +https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/simplempi/cpi_c.html. + +The tutorial requires a C++ compiler and CMake, we recommend using CMake 3.8.0 or newer. +Parts of the tutorial also require MPI, CUDA, Sphinx and Doxygen. + + +.. toctree:: + :maxdepth: 3 + :caption: Tutorial Contents + + setup_blt + creating_execs_and_libs + using_flags + unit_testing + external_dependencies + creating_documentation + recommendations diff --git a/tpl/RAJA/blt/docs/tutorial/recommendations.rst b/tpl/RAJA/blt/docs/tutorial/recommendations.rst new file mode 100644 index 000000000..6f55becdf --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/recommendations.rst @@ -0,0 +1,104 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +.. _Recommendations: + +CMake Recommendations +====================== + +This section includes several recommendations for how to wield CMake. +Some of them are embodied in BLT, others are broader suggestions for CMake bliss. + + +.. rubric:: Disable in-source builds + +*BLT Enforces This* + + +In-source builds clutter source code with temporary build files and prevent other out-of-source builds +from being created. Disabling in-source builds avoids clutter and accidental checkins of temporary build files. + +.. rubric:: Avoid using globs to identify source files + +Globs are evaluated at CMake configure time - not build time. This means CMake will not detect new source files +when they are added to the file system unless there are other changes that trigger CMake to reconfigure. + +The CMake documentation also warns against this: +https://cmake.org/cmake/help/v3.10/command/file.html?highlight=glob#file + + +.. rubric:: Use arguments instead of options in CMake Macros and Functions + +``CMAKE_PARSE_ARGUMENTS`` allows Macros or Functions to support options. Options are enabled by passing them +by name when calling a Macro or Function. Because of this, wrapping an existing Macro or Function in a way +that passes through options requires if tests and multiple copies of the call. For example: + +.. code-block:: cmake + + if(OPTION) + my_function(arg1 arg2 arg3 OPTION) + else() + my_function(arg1 arg2 arg3) + endif() + +Adding more options compounds the logic to achieve these type of calls. + +To simplify calling logic, we recommend using an argument instead of an option. + +.. code-block:: cmake + + if(OPTION) + set(arg4_value ON) + endif() + + my_function(arg1 arg2 arg3 ${arg4_value}) + + +.. rubric:: Prefer explicit paths to locate third-party dependencies + +Require passing explicit paths (ex: ``ZZZ_DIR``) for third-party dependency locations. +This avoids surprises with incompatible installs sprinkled in various system locations. +If you are using off-the-shelf *FindZZZ* logic, also consider adding CMake checks +to verify that *FindZZZ* logic actually found the dependencies at the location specified. + +.. rubric:: Emit a configure error if an explicitly identified third-party dependency is not found or an incorrect version is found. + +If an explicit path to a dependency is given (ex: ``ZZZ_DIR``) it should be valid or result in a CMake configure error. + +In contrast, if you only issue a warning and automatically disable a feature when a third-party dependency is bad, +the warning often goes unnoticed and may not be caught until folks using your software are surprised. +Emitting a configure error stops CMake and draws attention to the fact that something is wrong. +Optional dependencies are still supported by including them only if an explicit path +to the dependency is provided (ex: ``ZZZ_DIR``). + + +.. rubric:: Add headers as source files to targets + +*BLT Macros Support This* + +This ensures headers are tracked as dependencies and are included in the projects +created by CMake's IDE generators, like Xcode or Eclipse. + + +.. rubric:: Always support `make install` + +This allows CMake to do the right thing based on ``CMAKE_INSTALL_PREFIX``, +and also helps support CPack create release packages. This is especially important for libraries. +In addition to targets, header files require an explicit install command. + +Here is an example that installs a target and its headers: + +.. code-block:: cmake + + #-------------------------------------------------------- + # Install Targets for example lib + #-------------------------------------------------------- + install(FILES ${example_headers} DESTINATION include) + install(TARGETS example + EXPORT example + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + diff --git a/tpl/RAJA/blt/docs/tutorial/setup_blt.rst b/tpl/RAJA/blt/docs/tutorial/setup_blt.rst new file mode 100644 index 000000000..645db8b2f --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/setup_blt.rst @@ -0,0 +1,227 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Setup BLT in your CMake Project +================================= + +BLT is easy to include in your CMake project whether it is an existing project or +you are starting from scratch. You simply pull it into your project using a CMake +``include()`` command. + +.. code-block:: cmake + + include(path/to/blt/SetupBLT.cmake) + +You can include the BLT source in your repository or pass the location +of BLT at CMake configure time through the optional ``BLT_SOURCE_DIR`` +CMake variable. + +There are two standard choices for including the BLT source in your repository: + +1. Add BLT as a git submodule +2. Copy BLT into a subdirectory in your repository + + +BLT as a Git Submodule +-------------------------- + +This example adds BLT as a submodule, commits, and pushes the changes to your repository. + +.. code-block:: bash + + cd + git submodule add https://github.com/LLNL/blt.git blt + git commit -m "Adding BLT" + git push + +Copy BLT into your repository +----------------------------- + +This example will clone BLT into your repository and remove the unneeded +git files from the clone. It then commits and pushes the changes to your +repository. + +.. code-block:: bash + + cd + git clone https://github.com/LLNL/blt.git + rm -rf blt/.git + git commit -m "Adding BLT" + git push + + +Include BLT in your project +--------------------------- + +In most projects, including BLT is as simple as including the following CMake +line in your base ``CMakeLists.txt`` after your ``project()`` call. + +.. code-block:: cmake + + include(blt/SetupBLT.cmake) + +This enables all of BLT's features in your project. + +However if your project is likely to be used by other projects. The following +is recommended: + +.. literalinclude:: blank_project/CMakeLists.txt + :start-after: _blt_tutorial_include_blt_start + :end-before: _blt_tutorial_include_blt_end + :language: cmake + +This is a robust way of setting up BLT and supports an optional external BLT source +directory. This allows the use of a common BLT across large projects. There are some +helpful error messages if the BLT submodule is missing as well as the commands to solve +it. + +.. note:: + Throughout this tutorial, we pass the path to BLT using ``BLT_SOURCE_DIR`` since + our tutorial is part of the blt repository and we want this project to be + automatically tested using a single clone of our repository. + + + +Running CMake +------------- + +To configure a project with CMake, first create a build directory and ``cd`` into it. +Then run cmake with the path to your project. + +.. code-block:: bash + + cd + mkdir build + cd build + cmake .. + +If you are using BLT outside of your project pass the location of BLT as follows: + +.. code-block:: bash + + cd + mkdir build + cd build + cmake -DBLT_SOURCE_DIR="path/to/blt" .. + +Example: blank_project +---------------------- + +The ``blank_project`` example is provided to show you some of BLT's built-in +features. It demonstrates the bare minimum required for testing purposes. + +Here is the entire CMakeLists.txt file for ``blank_project``: + +.. literalinclude:: blank_project/CMakeLists.txt + :language: cmake + +BLT also enforces some best practices for building, such as not allowing +in-source builds. This means that BLT prevents you from generating a +project configuration directly in your project. + +For example if you run the following commands: + +.. code-block:: bash + + cd /docs/tutorial/blank_project + cmake -DBLT_SOURCE_DIR=../.. + +you will get the following error: + +.. code-block:: bash + + CMake Error at blt/SetupBLT.cmake:59 (message): + In-source builds are not supported. Please remove CMakeCache.txt from the + 'src' dir and configure an out-of-source build in another directory. + Call Stack (most recent call first): + CMakeLists.txt:55 (include) + + + -- Configuring incomplete, errors occurred! + +To correctly run cmake, create a build directory and run cmake from there: + +.. code-block:: bash + + cd /docs/blank_project + mkdir build + cd build + cmake -DBLT_SOURCE_DIR=../../.. .. + +This will generate a configured ``Makefile`` in your build directory to build +``blank_project``. The generated makefile includes gtest and several built-in +BLT *smoke* tests, depending on the features that you have enabled in your build. + +To build the project, use the following command: + +.. code-block:: bash + + make + +As with any other ``make``-based project, you can utilize parallel job tasks +to speed up the build with the following command: + +.. code-block:: bash + + make -j8 + +Next, run all tests in this project with the following command: + +.. code-block:: bash + + make test + +If everything went correctly, you should have the following output: + +.. code-block:: bash + + Running tests... + Test project blt/docs/tutorial/blank_project/build + Start 1: blt_gtest_smoke + 1/1 Test #1: blt_gtest_smoke .................. Passed 0.01 sec + + 100% tests passed, 0 tests failed out of 1 + + Total Test time (real) = 0.10 sec + +Note that the default options for ``blank_project`` only include a single test +``blt_gtest_smoke``. As we will see later on, BLT includes additional smoke +tests that are activated when BLT is configured with other options enabled, +like Fortran, MPI, OpenMP, and Cuda. + +Host-configs +------------ + +To capture (and revision control) build options, third party library paths, etc., +we recommend using CMake's initial-cache file mechanism. This feature allows you +to pass a file to CMake that provides variables to bootstrap the configuration +process. + +You can pass initial-cache files to cmake via the ``-C`` command line option. + +.. code-block:: bash + + cmake -C config_file.cmake + + +We call these initial-cache files ``host-config`` files since we typically create +a file for each platform or for specific hosts, if necessary. + +These files use standard CMake commands. CMake ``set()`` commands need to specify +``CACHE`` as follows: + +.. code-block:: cmake + + set(CMAKE_VARIABLE_NAME {VALUE} CACHE PATH "") + +Here is a snippet from a host-config file that specifies compiler details for +using gcc 4.9.3 on LLNL's surface cluster. + +.. literalinclude:: ../../host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake + :start-after: _blt_tutorial_surface_compiler_config_start + :end-before: _blt_tutorial_surface_compiler_config_end + :language: cmake + + diff --git a/tpl/RAJA/blt/docs/tutorial/unit_testing.rst b/tpl/RAJA/blt/docs/tutorial/unit_testing.rst new file mode 100644 index 000000000..5a4d1a3b7 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/unit_testing.rst @@ -0,0 +1,251 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +.. _UnitTesting: + +Unit Testing +============ + +BLT has a built-in copy of the +`Google Test framework (gtest) `_ for C +and C++ unit tests and the +`Fortran Unit Test Framework (FRUIT) `_ +for Fortran unit tests. + +Each Google Test or FRUIT file may contain multiple tests and is compiled into +its own executable that can be run directly or as a ``make`` target. + +In this section, we give a brief overview of GTest and discuss how to add unit +tests using the ``blt_add_test()`` macro. + + +Configuring tests within BLT +---------------------------- + +Unit testing in BLT is controlled by the ``ENABLE_TESTS`` cmake option and is on +by default. + +For additional configuration granularity, BLT provides configuration options +for the individual built-in unit testing libraries. The following additional +options are available when ``ENABLE_TESTS`` is on: + +``ENABLE_GTEST`` + Option to enable gtest (default: ``ON``). +``ENABLE_GMOCK`` + Option to control gmock (default: ``OFF``). + Since gmock requires gtest, gtest is also enabled whenever ``ENABLE_GMOCK`` is true, + regardless of the value of ``ENABLE_GTEST``. +``ENABLE_FRUIT`` + Option to control FRUIT (Default ``ON``). It is only active when ``ENABLE_FORTRAN`` is enabled. + + +Google Test (C++/C Tests) +-------------------------- + +The contents of a typical Google Test file look like this: + +.. code:: cpp + + #include "gtest/gtest.h" + + #include ... // include headers needed to compile tests in file + + // ... + + TEST(, ) + { + // Test 1 code here... + // ASSERT_EQ(...); + } + + TEST(, ) + { + // Test 2 code here... + // EXPECT_TRUE(...); + } + + // Etc. + +Each unit test is defined by the Google Test ``TEST()`` macro which accepts a +*test case name* identifier, such as the name of the C++ class being tested, +and a *test name*, which indicates the functionality being verified by the +test. Within a test, failure of logical assertions (macros prefixed by ``ASSERT_``) +will cause the test to fail immediately, while failures of expected values +(macros prefixed by ``EXPECT_``) will cause the test to fail, but will +continue running code within the test. + +Note that the Google Test framework will generate a ``main()`` routine for +each test file if it is not explicitly provided. However, sometimes it is +necessary to provide a ``main()`` routine that contains operation to run +before or after the unit tests in a file; e.g., initialization code or +pre-/post-processing operations. A ``main()`` routine provided in a test +file should be placed at the end of the file in which it resides. + + +Note that Google Test is initialized before ``MPI_Init()`` is called. + +Other Google Test features, such as *fixtures* and *mock* objects (gmock) may +be used as well. + +See the `Google Test Primer `_ +for a discussion of Google Test concepts, how to use them, and a listing of +available assertion macros, etc. + +FRUIT (Fortran Tests) +-------------------------- + +Fortran unit tests using the FRUIT framework are similar in structure to +the Google Test tests for C and C++ described above. + +The contents of a typical FRUIT test file look like this:: + + module + use iso_c_binding + use fruit + use + implicit none + + contains + + subroutine test_name_1 + ! Test 1 code here... + ! call assert_equals(...) + end subroutine test_name_1 + + subroutine test_name_2 + ! Test 2 code here... + ! call assert_true(...) + end subroutine test_name_2 + + ! Etc. + +The tests in a FRUIT test file are placed in a Fortran *module* named for +the *test case name*, such as the name of the C++ class whose Fortran interface +is being tested. Each unit test is in its own Fortran subroutine named +for the *test name*, which indicates the functionality being verified by the +unit test. Within each unit test, logical assertions are defined using +FRUIT methods. Failure of expected values will cause the test +to fail, but other tests will continue to run. + +Note that each FRUIT test file defines an executable Fortran program. The +program is defined at the end of the test file and is organized as follows:: + + program fortran_test + use fruit + use + implicit none + logical ok + + ! initialize fruit + call init_fruit + + ! run tests + call test_name_1 + call test_name_2 + + ! compile summary and finalize fruit + call fruit_summary + call fruit_finalize + + call is_all_successful(ok) + if (.not. ok) then + call exit(1) + endif + end program fortran_test + + +Please refer to the `FRUIT documentation `_ for more information. + + +Adding a BLT unit test +---------------------- + +After writing a unit test, we add it to the project's build system +by first generating an executable for the test using the +``blt_add_executable()`` macro. We then register the test using the +``blt_add_test()`` macro. + +.. admonition:: blt_add_test + :class: hint + + This macro generates a named unit test from an existing executable + and allows users to pass in command line arguments. + + +Returning to our running example (see :ref:`AddTarget`), +let's add a simple test for the ``calc_pi`` library, +which has a single function with signature: + + .. code-block:: cpp + + double calc_pi(int num_intervals); + +We add a simple unit test that invokes ``calc_pi()`` +and compares the result to :math:`\pi`, within a given tolerance (``1e-6``). +Here is the test code: + +.. literalinclude:: calc_pi/test_1.cpp + :start-after: _blt_tutorial_calpi_test1_start + :end-before: _blt_tutorial_calpi_test1_end + :language: cpp + +To add this test to the build system, we first generate a test executable: + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_test1_executable_start + :end-before: _blt_tutorial_calcpi_test1_executable_end + :language: cmake + +Note that this test executable depends on two targets: ``calc_pi`` and ``gtest``. + +We then register this executable as a test: + +.. literalinclude:: calc_pi/CMakeLists.txt + :start-after: _blt_tutorial_calcpi_test1_test_start + :end-before: _blt_tutorial_calcpi_test1_test_end + :language: cmake + +.. Hide these for now until we bring into an example +.. .. note:: +.. The ``COMMAND`` parameter can be used to pass arguments into a test executable. +.. This feature is not exercised in this example. +.. +.. .. note:: +.. The ``NAME`` of the test can be different from the test executable, +.. which is passed in through the ``COMMAND`` parameter. +.. This feature is not exercised in this example. + + +Running tests and examples +-------------------------- + +To run the tests, type the following command in the build directory: + +.. code-block:: bash + + $ make test + +This will run all tests through cmake's ``ctest`` tool +and report a summary of passes and failures. +Detailed output on individual tests is suppressed. + +If a test fails, you can invoke its executable directly to see the detailed +output of which checks passed or failed. This is especially useful when +you are modifying or adding code and need to understand how unit test details +are working, for example. + +.. note:: + You can pass arguments to ctest via the ``TEST_ARGS`` parameter, e.g. + ``make test TEST_ARGS="..."`` + Useful arguments include: + + -R + Regular expression filtering of tests. + E.g. ``-R foo`` only runs tests whose names contain ``foo`` + -j + Run tests in parallel, E.g. ``-j 16`` will run tests using 16 processors + -VV + (Very verbose) Dump test output to stdout + diff --git a/tpl/RAJA/blt/docs/tutorial/using_flags.rst b/tpl/RAJA/blt/docs/tutorial/using_flags.rst new file mode 100644 index 000000000..787692603 --- /dev/null +++ b/tpl/RAJA/blt/docs/tutorial/using_flags.rst @@ -0,0 +1,69 @@ +.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +.. # other BLT Project Developers. See the top-level COPYRIGHT file for details +.. # +.. # SPDX-License-Identifier: (BSD-3-Clause) + +Portable compiler flags +========================= + +To simplify the development of code that is portable across different architectures +and compilers, BLT provides the ``blt_append_custom_compiler_flag()`` macro, +which allows users to easily place a compiler dependent flag into a CMake variable. + +.. admonition:: blt_append_custom_compiler_flag + :class: hint + + To use this macro, supply a cmake variable in which to append a flag (``FLAGS_VAR``), + and the appropriate flag for each of our supported compilers. + + This macro currently supports the following compilers: + + * GNU + * CLANG + * XL (IBM compiler) + * INTEL (Intel compiler) + * MSVC (Microsoft Visual Studio) + * MSVC_INTEL (Intel toolchain in Microsoft Visual Studio) + * PGI + * HCC (AMD GPU) + +Here is an example for setting the appropriate flag to treat warnings as errors: + +.. code-block:: cmake + + blt_append_custom_compiler_flag( + FLAGS_VAR BLT_WARNINGS_AS_ERRORS_FLAG + DEFAULT "-Werror" + MSVC "/WX" + XL "qhalt=w" + ) + +Since values for ``GNU``, ``CLANG`` and ``INTEL`` are not supplied, +they will get the default value (``-Werror``) +which is supplied by the macro's ``DEFAULT`` argument. + +BLT also provides a simple macro to add compiler flags to a target. +You can append the above compiler flag to an already defined executable, +such as ``example_1`` with the following line: + +.. code-block:: cmake + + blt_add_target_compile_flags(TO example_1 + FLAGS BLT_WARNINGS_AS_ERRORS_FLAG ) + +Here is another example to disable warnings about unknown OpenMP pragmas in the code: + +.. code-block:: cmake + + # Flag for disabling warnings about omp pragmas in the code + blt_append_custom_compiler_flag( + FLAGS_VAR DISABLE_OMP_PRAGMA_WARNINGS_FLAG + DEFAULT "-Wno-unknown-pragmas" + XL "-qignprag=omp" + INTEL "-diag-disable 3180" + MSVC "/wd4068" + ) + +Note that GNU does not have a way to only disable warnings about openmp pragmas, +so one must disable warnings about all unknown pragmas on this compiler. + diff --git a/tpl/RAJA/blt/host-configs/darwin/elcapitan-x86_64/naples-clang@7.3.0.cmake b/tpl/RAJA/blt/host-configs/darwin/elcapitan-x86_64/naples-clang@7.3.0.cmake new file mode 100644 index 000000000..995ecbfb0 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/darwin/elcapitan-x86_64/naples-clang@7.3.0.cmake @@ -0,0 +1,54 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +######################################################################## +# host-config for naples +######################################################################## + +######################################################################## +# Dependencies were built with spack (https://github.com/llnl/spack) +######################################################################## +# spack install cmake@3.8.2 +# spack install mpich +# spack install py-sphinx +# spack activate py-sphinx +# spack install doxygen + + +######################################################################## +# cmake path +######################################################################## +# /Users/harrison37/Work/blt_tutorial/tpls/spack/opt/spack/darwin-elcapitan-x86_64/clang-7.3.0-apple/cmake-3.8.2-n2i4ijlet37i3jhmjfhzms2wo3b4ybcm/bin/cmake + +######################################################################## +# mpi from spack +######################################################################## +set(ENABLE_MPI ON CACHE PATH "") + +set(MPI_BASE_DIR "/Users/harrison37/Work/blt_tutorial/tpls/spack/opt/spack/darwin-elcapitan-x86_64/clang-7.3.0-apple/mpich-3.2-yc7ipshe7e3w4ohtgjtms2agecxruavw/bin" CACHE PATH "") + +set(MPI_C_COMPILER "${MPI_BASE_DIR}/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "${MPI_BASE_DIR}/mpicxx" CACHE PATH "") +set(MPIEXEC "${MPI_BASE_DIR}/mpiexec" CACHE PATH "") + +######################################################################## +# Cuda Support (standard osx cuda toolkit install) +######################################################################## +set(ENABLE_CUDA ON CACHE BOOL "") + +set(CUDA_TOOLKIT_ROOT_DIR "/Developer/NVIDIA/CUDA-8.0/" CACHE PATH "") +set(CUDA_BIN_DIR "/Developer/NVIDIA/CUDA-8.0/bin/" CACHE PATH "") + +######################################################################## +# sphinx from spack +######################################################################## +set(SPHINX_EXECUTABLE "/Users/harrison37/Work/blt_tutorial/tpls/spack/opt/spack/darwin-elcapitan-x86_64/clang-7.3.0-apple/python-2.7.13-jmhznopgz2j5zkmuzjygg5oyxnxtc653/bin/sphinx-build" CACHE PATH "") + +######################################################################## +# doxygen from spack +######################################################################## +set(DOXYGEN_EXECUTABLE "/Users/harrison37/Work/blt_tutorial/tpls/spack/opt/spack/darwin-elcapitan-x86_64/clang-7.3.0-apple/doxygen-1.8.12-mji43fu4hxuu6js5irshpihkwwucn7rv/bin/doxygen" CACHE PATH "") + + diff --git a/tpl/RAJA/blt/host-configs/llnl/bgqos_0/clang@4.0.0_xlf.cmake b/tpl/RAJA/blt/host-configs/llnl/bgqos_0/clang@4.0.0_xlf.cmake new file mode 100644 index 000000000..4d24224b1 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/bgqos_0/clang@4.0.0_xlf.cmake @@ -0,0 +1,51 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for clang C/C++ compiler +# paired with xlf Fortran compiler on LLNL's bgq machine +#------------------------------------------------------------------------------ + +set(CLANG_HOME "/collab/usr/gapps/opnsrc/gnu/dev/lnx-2.12-ppc/bgclang/r284961-stable") +set(CMAKE_C_COMPILER "${CLANG_HOME}/llnl/bin/mpiclang" CACHE PATH "") +set(CMAKE_CXX_COMPILER "${CLANG_HOME}/llnl/bin/mpiclang++11" CACHE PATH "") + +# Set Fortran compiler +set(ENABLE_FORTRAN ON CACHE BOOL "") +set(CMAKE_Fortran_COMPILER "/opt/ibmcmp/xlf/bg/14.1/bin/bgxlf2003" CACHE PATH "") + + +#------------------------------------------------------------------------------ +# Extra options and flags +#------------------------------------------------------------------------------ + +set(ENABLE_DOCS OFF CACHE BOOL "") +set(CMAKE_SKIP_RPATH TRUE CACHE BOOL "") + +# Use clang's libc++ instead of libstdc++ +set(BLT_CXX_FLAGS "-stdlib=libc++" CACHE STRING "") +set(gtest_defines "-DGTEST_HAS_CXXABI_H_=0" CACHE STRING "") + +# Converts C-style comments to Fortran style in preprocessed files +set(BLT_FORTRAN_FLAGS "-WF,-C!" CACHE STRING "") + + +#------------------------------------------------------------------------------ +# MPI Support +# Note: On BGQ, CMake uses the wrong linker flags when using FindMPI. +# Disable FindMPI to use LLNL wrapper scripts via CMake compiler variables. +#------------------------------------------------------------------------------ + +set(ENABLE_MPI ON CACHE BOOL "") +set(ENABLE_FIND_MPI OFF CACHE BOOL "") + +# Pass in an explicit path to help find mpif.h +set(MPI_Fortran_INCLUDE_PATH "/usr/local/tools/deg/drivers/V1R2M0/ppc64/comm/gcc/include" CACHE PATH "") + +set(MPIEXEC "/usr/bin/srun" CACHE PATH "") +set(MPIEXEC_NUMPROC_FLAG "-n" CACHE PATH "") + +# Ensures that tests will be wrapped with srun to run on the backend nodes +set(ENABLE_WRAP_ALL_TESTS_WITH_MPIEXEC TRUE CACHE BOOL "Run tests on backend nodes") diff --git a/tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_link_with_nvcc.cmake b/tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_link_with_nvcc.cmake new file mode 100644 index 000000000..13e109399 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_link_with_nvcc.cmake @@ -0,0 +1,73 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for the blue_os cluster at LLNL +#------------------------------------------------------------------------------ +# +# This file provides CMake with paths / details for: +# C/C++, OpenMP, MPI, and Cuda +# +# It demonstrates a more complex build, where the code is linked with nvcc. +#------------------------------------------------------------------------------ +# Warning: This host-config does not currently work with CMake@3.13 or above +# due to a linking error. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Compilers +#------------------------------------------------------------------------------ + +# Use Clang compilers for C/C++ +set(CLANG_VERSION "clang-upstream-2019.08.15" CACHE STRING "") +set(CLANG_HOME "/usr/tce/packages/clang/${CLANG_VERSION}") + +set(CMAKE_C_COMPILER "${CLANG_HOME}/bin/clang" CACHE PATH "") +set(CMAKE_CXX_COMPILER "${CLANG_HOME}/bin/clang++" CACHE PATH "") +set(BLT_CXX_STD "c++11" CACHE STRING "") + +# Disable Fortran +set(ENABLE_FORTRAN OFF CACHE BOOL "") + +#------------------------------------------------------------------------------ +# MPI Support +#------------------------------------------------------------------------------ +set(ENABLE_MPI ON CACHE BOOL "") + +set(MPI_HOME "/usr/tce/packages/spectrum-mpi/spectrum-mpi-rolling-release-${CLANG_VERSION}") +set(MPI_C_COMPILER "${MPI_HOME}/bin/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "${MPI_HOME}/bin/mpicxx" CACHE PATH "") + +set(MPIEXEC "${MPI_HOME}/bin/mpirun" CACHE PATH "") +set(MPIEXEC_NUMPROC_FLAG "-np" CACHE PATH "") +set(BLT_MPI_COMMAND_APPEND "mpibind" CACHE PATH "") + +#------------------------------------------------------------------------------ +# OpenMP support +#------------------------------------------------------------------------------ +set(ENABLE_OPENMP ON CACHE BOOL "") + +# Override default link flags because linking with nvcc +set(OMP_HOME ${CLANG_HOME}/release) +set(BLT_OPENMP_LINK_FLAGS "-Xlinker -rpath -Xlinker ${OMP_HOME}/lib -L${OMP_HOME}/lib -lomp -lomptarget-nvptx" CACHE STRING "") + +#------------------------------------------------------------------------------ +# CUDA support +#------------------------------------------------------------------------------ +set(ENABLE_CUDA ON CACHE BOOL "") + +set(CUDA_TOOLKIT_ROOT_DIR "/usr/tce/packages/cuda/cuda-10.1.168" CACHE PATH "") +set(CMAKE_CUDA_COMPILER "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" CACHE PATH "") +set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "") + +set (_cuda_arch "sm_70") +set (CMAKE_CUDA_FLAGS "-restrict -arch ${_cuda_arch} -std=c++11 --expt-extended-lambda -G" CACHE STRING "" ) + +set (CUDA_SEPARABLE_COMPILATION ON CACHE BOOL "" ) +set (CUDA_LINK_WITH_NVCC ON CACHE BOOL "") + +# nvcc does not like gtest's 'pthreads' flag +set(gtest_disable_pthreads ON CACHE BOOL "") + diff --git a/tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_nvcc_xlf.cmake b/tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_nvcc_xlf.cmake new file mode 100644 index 000000000..478393d07 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/blueos_3_ppc64le_ib_p9/clang@upstream_nvcc_xlf.cmake @@ -0,0 +1,77 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for the blue_os cluster at LLNL +#------------------------------------------------------------------------------ +# +# This file provides CMake with paths / details for: +# C/C++: Clang +# Fortran: XLF +# MPI +# Cuda +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Compilers +#------------------------------------------------------------------------------ + +# Use Clang compilers for C/C++ +set(CLANG_VERSION "clang-upstream-2019.08.15" CACHE STRING "") +set(CLANG_HOME "/usr/tce/packages/clang/${CLANG_VERSION}") + +set(CMAKE_C_COMPILER "${CLANG_HOME}/bin/clang" CACHE PATH "") +set(CMAKE_CXX_COMPILER "${CLANG_HOME}/bin/clang++" CACHE PATH "") +set(BLT_CXX_STD "c++11" CACHE STRING "") + +# Use XL compiler for Fortran +set(ENABLE_FORTRAN ON CACHE BOOL "") +set(XL_VERSION "xl-2019.06.12") +set(XL_HOME "/usr/tce/packages/xl/${XL_VERSION}") +set(CMAKE_Fortran_COMPILER "${XL_HOME}/bin/xlf2003" CACHE PATH "") + +#------------------------------------------------------------------------------ +# MPI Support +#------------------------------------------------------------------------------ + +set(ENABLE_MPI ON CACHE BOOL "") + +set(MPI_HOME "/usr/tce/packages/spectrum-mpi/spectrum-mpi-rolling-release-${CLANG_VERSION}") +set(MPI_Fortran_HOME "/usr/tce/packages/spectrum-mpi/spectrum-mpi-rolling-release-${XL_VERSION}") + +set(MPI_C_COMPILER "${MPI_HOME}/bin/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "${MPI_HOME}/bin/mpicxx" CACHE PATH "") +set(MPI_Fortran_COMPILER "${MPI_Fortran_HOME}/bin/mpif90" CACHE PATH "") + +set(MPIEXEC "${MPI_HOME}/bin/mpirun" CACHE PATH "") +set(MPIEXEC_NUMPROC_FLAG "-np" CACHE PATH "") +set(BLT_MPI_COMMAND_APPEND "mpibind" CACHE PATH "") + +#------------------------------------------------------------------------------ +# Other machine specifics +#------------------------------------------------------------------------------ + +set(CMAKE_Fortran_COMPILER_ID "XL" CACHE PATH "All of BlueOS compilers report clang due to nvcc, override to proper compiler family") +set(BLT_FORTRAN_FLAGS "-WF,-C!" CACHE PATH "Converts C-style comments to Fortran style in preprocessed files") + +#------------------------------------------------------------------------------ +# CUDA support +#------------------------------------------------------------------------------ + +set(ENABLE_CUDA ON CACHE BOOL "") + +set(CUDA_TOOLKIT_ROOT_DIR "/usr/tce/packages/cuda/cuda-10.1.168" CACHE PATH "") +set(CMAKE_CUDA_COMPILER "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" CACHE PATH "") +set(CMAKE_CUDA_HOST_COMPILER "${MPI_CXX_COMPILER}" CACHE PATH "") + +set(_cuda_arch "sm_70") +set(CMAKE_CUDA_FLAGS "-restrict -arch ${_cuda_arch} -std=c++11 --expt-extended-lambda -G" CACHE STRING "") + +set(CUDA_SEPARABLE_COMPILATION ON CACHE BOOL "" ) + +# nvcc does not like gtest's 'pthreads' flag +set(gtest_disable_pthreads ON CACHE BOOL "") + diff --git a/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@4.0.0-libcxx.cmake b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@4.0.0-libcxx.cmake new file mode 100644 index 000000000..e34094a6c --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@4.0.0-libcxx.cmake @@ -0,0 +1,51 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for the quartz cluster at LLNL +#------------------------------------------------------------------------------ +# +# This file provides CMake with paths / details for: +# C,C++, & Fortran compilers + MPI +#------------------------------------------------------------------------------ +# clang-4.0.0 / gfortran@4.9.3 compilers +# Uses clang's 'libc++' instead of 'libstdc++' + +set(CLANG_HOME "/usr/tce/packages/clang/clang-4.0.0") +set(GNU_HOME "/usr/tce/packages/gcc/gcc-4.9.3") + +# c compiler +set(CMAKE_C_COMPILER "${CLANG_HOME}/bin/clang" CACHE PATH "") + +# cpp compiler +set(CMAKE_CXX_COMPILER "${CLANG_HOME}/bin/clang++" CACHE PATH "") + +# fortran support +set(ENABLE_FORTRAN ON CACHE BOOL "") + +# fortran compiler +set(CMAKE_Fortran_COMPILER "${GNU_HOME}/bin/gfortran" CACHE PATH "") + +#------------------------------------------------------------------------------ +# Extra flags +#------------------------------------------------------------------------------ + +# Use clang's libc++ instead of libstdc++ +set(BLT_CXX_FLAGS "-stdlib=libc++" CACHE STRING "") +set(gtest_defines "-DGTEST_HAS_CXXABI_H_=0" CACHE STRING "") + +#------------------------------------------------------------------------------ +# MPI Support +#------------------------------------------------------------------------------ +set(ENABLE_MPI ON CACHE BOOL "") + +set(MPI_HOME "/usr/tce/packages/mvapich2/mvapich2-2.3-clang-4.0.0" CACHE PATH "") +set(MPI_C_COMPILER "${MPI_HOME}/bin/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "${MPI_HOME}/bin/mpicxx" CACHE PATH "") +set(MPI_Fortran_COMPILER "${MPI_HOME}/bin/mpifort" CACHE PATH "") + +set(MPIEXEC "/usr/bin/srun" CACHE PATH "") +set(MPIEXEC_NUMPROC_FLAG "-n" CACHE PATH "") + diff --git a/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@6.0.0-static-analysis.cmake b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@6.0.0-static-analysis.cmake new file mode 100644 index 000000000..1e4e0164c --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/clang@6.0.0-static-analysis.cmake @@ -0,0 +1,57 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for the quartz cluster at LLNL +#------------------------------------------------------------------------------ +# +# This file provides CMake with paths / details for: +# C,C++, & Fortran compilers + MPI +#------------------------------------------------------------------------------ +# clang-4.0.0 / gfortran@4.9.3 compilers +# Uses clang's 'libc++' instead of 'libstdc++' + +set(CLANG_HOME "/usr/tce/packages/clang/clang-6.0.0") +set(GNU_HOME "/usr/tce/packages/gcc/gcc-4.9.3") + +# c compiler +set(CMAKE_C_COMPILER "${CLANG_HOME}/bin/clang" CACHE PATH "") + +# cpp compiler +set(CMAKE_CXX_COMPILER "${CLANG_HOME}/bin/clang++" CACHE PATH "") + +# fortran support +set(ENABLE_FORTRAN ON CACHE BOOL "") + +# fortran compiler +set(CMAKE_Fortran_COMPILER "${GNU_HOME}/bin/gfortran" CACHE PATH "") + +#------------------------------------------------------------------------------ +# Extra flags +#------------------------------------------------------------------------------ + +# Use clang's libc++ instead of libstdc++ +set(BLT_CXX_FLAGS "-stdlib=libc++" CACHE STRING "") +set(gtest_defines "-DGTEST_HAS_CXXABI_H_=0" CACHE STRING "") + +#------------------------------------------------------------------------------ +# Static Analysis Support +#------------------------------------------------------------------------------ +set(ClangQuery_DIR ${CLANG_HOME}/bin) +set(ENABLE_CLANGQUERY ON CACHE BOOL "") + +#------------------------------------------------------------------------------ +# MPI Support +#------------------------------------------------------------------------------ +set(ENABLE_MPI ON CACHE BOOL "") + +set(MPI_HOME "/usr/tce/packages/mvapich2/mvapich2-2.3-clang-6.0.0" CACHE PATH "") +set(MPI_C_COMPILER "${MPI_HOME}/bin/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "${MPI_HOME}/bin/mpicxx" CACHE PATH "") +set(MPI_Fortran_COMPILER "${MPI_HOME}/bin/mpifort" CACHE PATH "") + +set(MPIEXEC "/usr/bin/srun" CACHE PATH "") +set(MPIEXEC_NUMPROC_FLAG "-n" CACHE PATH "") + diff --git a/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/gcc@4.9.3.cmake b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/gcc@4.9.3.cmake new file mode 100644 index 000000000..061a12928 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/gcc@4.9.3.cmake @@ -0,0 +1,46 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for the quartz cluster at LLNL +#------------------------------------------------------------------------------ +# +# This file provides CMake with paths / details for: +# C,C++, & Fortran compilers + MPI +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# gcc@4.9.3 compilers +#------------------------------------------------------------------------------ + +set(GCC_VERSION "gcc-4.9.3") +set(GCC_HOME "/usr/tce/packages/gcc/${GCC_VERSION}") + +# c compiler +set(CMAKE_C_COMPILER "${GCC_HOME}/bin/gcc" CACHE PATH "") + +# cpp compiler +set(CMAKE_CXX_COMPILER "${GCC_HOME}/bin/g++" CACHE PATH "") + +# fortran support +set(ENABLE_FORTRAN ON CACHE BOOL "") + +# fortran compiler +set(CMAKE_Fortran_COMPILER "${GCC_HOME}/bin/gfortran" CACHE PATH "") + +#------------------------------------------------------------------------------ +# MPI Support +#------------------------------------------------------------------------------ +set(ENABLE_MPI ON CACHE BOOL "") + +set(MPI_HOME "/usr/tce/packages/mvapich2/mvapich2-2.3-${GCC_VERSION}" CACHE PATH "") + +set(MPI_C_COMPILER "${MPI_HOME}/bin/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "${MPI_HOME}/bin/mpicxx" CACHE PATH "") +set(MPI_Fortran_COMPILER "${MPI_HOME}/bin/mpif90" CACHE PATH "") + +set(MPIEXEC "/usr/bin/srun" CACHE PATH "") +set(MPIEXEC_NUMPROC_FLAG "-n" CACHE PATH "") diff --git a/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/pgi@18.5.cmake b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/pgi@18.5.cmake new file mode 100644 index 000000000..336c3c11d --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/toss_3_x86_64_ib/pgi@18.5.cmake @@ -0,0 +1,43 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example pgi@18.5 host-config for LLNL toss3 machines +#------------------------------------------------------------------------------ + +set(COMPILER_HOME "/usr/tce/packages/pgi/pgi-18.5") + +# c compiler +set(CMAKE_C_COMPILER "${COMPILER_HOME}/bin/pgcc" CACHE PATH "") + +# cpp compiler +set(CMAKE_CXX_COMPILER "${COMPILER_HOME}/bin/pgc++" CACHE PATH "") + +# fortran support +set(ENABLE_FORTRAN ON CACHE BOOL "") + +# fortran support +set(CMAKE_Fortran_COMPILER "${COMPILER_HOME}/bin/pgfortran" CACHE PATH "") + +#------------------------------------------------------------------------------ +# Extra options and flags +#------------------------------------------------------------------------------ + +set(ENABLE_OPENMP ON CACHE BOOL "") + + +#------------------------------------------------------------------------------ +# MPI Support +#------------------------------------------------------------------------------ + +set(ENABLE_MPI ON CACHE BOOL "") + +set(MPI_HOME "/usr/tce/packages/mvapich2/mvapich2-2.2-pgi-18.5") + +set(MPI_C_COMPILER "${MPI_HOME}/bin/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "${MPI_HOME}/bin/mpicxx" CACHE PATH "") +set(MPI_Fortran_COMPILER "${MPI_HOME}/bin/mpif90" CACHE PATH "") +set(MPIEXEC "/usr/bin/srun" CACHE PATH "") +set(MPIEXEC_NUMPROC_FLAG "-n" CACHE PATH "") diff --git a/tpl/RAJA/blt/host-configs/llnl/windows/sqa-uno-msvc@15.cmake b/tpl/RAJA/blt/host-configs/llnl/windows/sqa-uno-msvc@15.cmake new file mode 100644 index 000000000..efbafd339 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/llnl/windows/sqa-uno-msvc@15.cmake @@ -0,0 +1,45 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for 'sqa-uno` windows machine at LLNL +#------------------------------------------------------------------------------ +# +# This file provides CMake with paths / details for: +# The Microsoft Visual Studio 15 compiler + MPI +# +# Run the following from a build dir for a 32-bit configuration +# cmake -G "Visual Studio 15 2017" \ +# -C ..\host-configs\llnl-sqa-uno-windows-msvc@15.cmake \ +# +# +# Run the following from a build dir for a 64-bit configuration +# cmake -G "Visual Studio 15 2017 Win64" \ +# -C ..\host-configs\llnl-sqa-uno-windows-msvc@15.cmake \ +# +# +# Build the code from the command line as follows +# (use -m for parallel build in msbuild, if desired): +# cmake --build . --config {Release,Debug,RelWithDebInfo} [-- /m:8] +# +# Test the code as follows (use -j for parallel testing): +# ctest -j8 -C {Release,Debug,RelWithDebInfo} +# +# Install the code from the command line as follows: +# cmake --build . --config {Release,Debug,RelWithDebInfo} --target install +# +#------------------------------------------------------------------------------ + +# Set the HOME variable (%USERPROFILE% in Windows) +string(REPLACE "\\" "/" HOME "$ENV{USERPROFILE}") + +# Setup MPI -- assumes MPI is installed in default location +set(ENABLE_MPI ON CACHE BOOL "") +set(MPI_HOME "C:/Program Files/Microsoft HPC Pack 2008 R2" CACHE PATH "") +set(MPI_GUESS_LIBRARY_NAME "MSMPI" CACHE STRING "") + +### Set some additional options +set(ENABLE_FOLDERS ON CACHE BOOL "") +set(ENABLE_GTEST_DEATH_TESTS ON CACHE BOOL "") diff --git a/tpl/RAJA/blt/host-configs/other/hcc.cmake b/tpl/RAJA/blt/host-configs/other/hcc.cmake new file mode 100644 index 000000000..15469bd24 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/other/hcc.cmake @@ -0,0 +1,66 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +# The CMake command line to use this host config file must have certain +# defines enabled. Here is an example script for an out-of-place build of the +# tutorial blank project template: +## hcc.sh +##!/bin/bash +#rm -rf build-hcc-release 2>/dev/null +#mkdir build-hcc-release && cd build-hcc-release + +#BLT_DIR=$(git rev-parse --show-toplevel) + +#cmake \ +# -DCMAKE_BUILD_TYPE=Release \ +# -DENABLE_HCC=ON -DBLT_SOURCE_DIR=${BLT_DIR} \ +# -DROCM_ARCH=gfx900 \ +# -C ${BLT_DIR}/host-configs/hcc.cmake \ +# -DCMAKE_INSTALL_PREFIX=../install-hcc-release \ +# "$@" \ +# ${BLT_DIR}/docs/tutorial/blank_project + + +########################################################### +# standard ROCm HCC compiler +########################################################### + +set(ENABLE_HCC ON CACHE BOOL "") +set(ENABLE_OPENMP OFF CACHE BOOL "") + +set(ROCM_ROOT_DIR "/opt/rocm" CACHE PATH "ROCm ROOT directory path") + +set(ROCM_INCLUDE_PATH "${ROCM_ROOT_DIR}/hcc/include;${ROCM_ROOT_DIR}/include" CACHE PATH "") +set(ROCM_CXX_LIBRARIES "-L${ROCM_ROOT_DIR}/lib -lhc_am -lhip_hcc" CACHE STRING "") + +########################################################### +# specify the target architecture +# Default with ROCm 1.7 is gfx803 (Fiji) +# Other options: +# gfx700 Hawaii +# gfx803 Polaris (RX580) +# gfx900 Vega +# gfx901 +########################################################### +set(ROCM_ARCH_FLAG "-amdgpu-target=${ROCM_ARCH}" CACHE STRING "") + +########################################################### +# get compile/link flags from hcc-config +########################################################### +# execute_process(COMMAND ${ROCM_ROOT_DIR}/hcc/bin/hcc-config --cxxflags OUTPUT_VARIABLE ROCM_CXX_COMPILE_FLAGS) +# execute_process(COMMAND ${ROCM_ROOT_DIR}/hcc/bin/hcc-config --ldflags OUTPUT_VARIABLE ROCM_CXX_LINK_FLAGS) +set(ROCM_CXX_COMPILE_FLAGS "-hc;-std=c++amp") +set(ROCM_CXX_LINK_FLAGS "-hc -std=c++amp") + +set(ROCM_CXX_COMPILE_FLAGS "${ROCM_CXX_COMPILE_FLAGS};-Wno-unused-parameter;-DHCC_ENABLE_ACCELERATOR_PRINTF" CACHE STRING "") +set(ROCM_CXX_LINK_FLAGS "${ROCM_CXX_LINK_FLAGS} ${ROCM_ARCH_FLAG} ${ROCM_CXX_LIBRARIES}" CACHE STRING "") + +########################################################### +# set CMake cache variables +########################################################### +set(CMAKE_CXX_COMPILER "${ROCM_ROOT_DIR}/hcc/bin/hcc" CACHE FILEPATH "ROCm HCC compiler") +# set(BLT_CXX_FLAGS "${ROCM_CXX_COMPILE_FLAGS}" CACHE STRING "HCC compiler flags") + +set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_COMPILER} ${ROCM_CXX_LINK_FLAGS} -o " CACHE STRING "HCC linker command line") diff --git a/tpl/RAJA/blt/host-configs/other/hip.cmake b/tpl/RAJA/blt/host-configs/other/hip.cmake new file mode 100644 index 000000000..21d2537b5 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/other/hip.cmake @@ -0,0 +1,32 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +# The CMake command line to use this host config file must have certain +# defines enabled. Here is an example script for an out-of-place build of the +# tutorial blank project template: +## hip.sh +##!/bin/bash +#rm -rf build-hip-release 2>/dev/null +#mkdir build-hip-release && cd build-hip-release + +#BLT_DIR=$(git rev-parse --show-toplevel) + +#cmake \ +# -DCMAKE_BUILD_TYPE=Release \ +# -DENABLE_HIP=ON -DBLT_SOURCE_DIR=${BLT_DIR} \ +# -C ${BLT_DIR}/host-configs/hip.cmake \ +# -DCMAKE_INSTALL_PREFIX=../install-hip-release \ +# "$@" \ +# ${BLT_DIR}/docs/tutorial/blank_project + + +########################################################### +# standard ROCm HIP compiler +########################################################### + +set(ENABLE_HIP ON CACHE BOOL "") +set(ENABLE_OPENMP OFF CACHE BOOL "") + +set(HIP_ROOT_DIR "/opt/rocm" CACHE PATH "HIP ROOT directory path") diff --git a/tpl/RAJA/blt/host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake b/tpl/RAJA/blt/host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake new file mode 100644 index 000000000..0cb0a2623 --- /dev/null +++ b/tpl/RAJA/blt/host-configs/other/llnl-surface-chaos_5_x86_64_ib-gcc@4.9.3.cmake @@ -0,0 +1,50 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Example host-config file for the surface cluster at LLNL +#------------------------------------------------------------------------------ +# +# This file provides CMake with paths / details for: +# C,C++, & Fortran compilers + MPI & CUDA +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# gcc@4.9.3 compilers +#------------------------------------------------------------------------------ +# _blt_tutorial_surface_compiler_config_start +set(CMAKE_C_COMPILER "/usr/apps/gnu/4.9.3/bin/gcc" CACHE PATH "") +set(CMAKE_CXX_COMPILER "/usr/apps/gnu/4.9.3/bin/g++" CACHE PATH "") + +# Fortran support +set(ENABLE_FORTRAN ON CACHE BOOL "") +set(CMAKE_Fortran_COMPILER "/usr/apps/gnu/4.9.3/bin/gfortran" CACHE PATH "") +# _blt_tutorial_surface_compiler_config_end + +#------------------------------------------------------------------------------ +# MPI Support +#------------------------------------------------------------------------------ +# _blt_tutorial_surface_mpi_config_start +set(ENABLE_MPI ON CACHE BOOL "") + +set(MPI_C_COMPILER "/usr/local/tools/mvapich2-gnu-2.0/bin/mpicc" CACHE PATH "") + +set(MPI_CXX_COMPILER "/usr/local/tools/mvapich2-gnu-2.0/bin/mpicc" CACHE PATH "") + +set(MPI_Fortran_COMPILER "/usr/local/tools/mvapich2-gnu-2.0/bin/mpif90" CACHE PATH "") +# _blt_tutorial_surface_mpi_config_end + +#------------------------------------------------------------------------------ +# CUDA support +#------------------------------------------------------------------------------ +# _blt_tutorial_surface_cuda_config_start +set(ENABLE_CUDA ON CACHE BOOL "") + +set(CUDA_TOOLKIT_ROOT_DIR "/opt/cudatoolkit-8.0" CACHE PATH "") +set(CMAKE_CUDA_COMPILER "/opt/cudatoolkit-8.0/bin/nvcc" CACHE PATH "") +set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}" CACHE PATH "") +set(CUDA_SEPARABLE_COMPILATION ON CACHE BOOL "") +# _blt_tutorial_surface_cuda_config_end + diff --git a/tpl/RAJA/blt/share/blt/logo/blt_logo.png b/tpl/RAJA/blt/share/blt/logo/blt_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..45dce76396212cac2e4c5d6c91023adc470d476c GIT binary patch literal 22594 zcmZVl1CS?A@FotAZQHhO?s#@=+qSV|?97gB+qP|6pRuj~e1CWE-9@}z5gpZ4na@*M z5nYwpSskG$F9{EW0|NvE1TXbVObG}GnE$6f4+Zga=la6*0|J8Sw-gmsloAysQgpI6 zv$Qb<0{Rt^lnkkoIEFED@;;ACj}-ZDHiIY&XxjSy6gUmJMs1Ccsi>svF+pon5f4bI`p&_ z1PB`>f~tQfiU2c5XoMfwLCki_VhzUA#w>{ z31QDInNszcbQlW53r(`v+hL3t#SO`yIV-n4^rX5x4PgQ-qty8UP$nGdoh^-%MA)zi zA_HcrGii}I`)HOz4{!}b+t93&hOb~_%f(?3GY%{}anuu}h7wb?RIDP&IkZnPnTE+0 zZj6>%jU_hv49dx@jN~+Ke;Qty^H}NRqu|nGZj)cd=b_fp62<-Maaafa%c5rf4aq3w zgP5?_o6QWPkBm+C?!CQ?e*{@*Ml0@x)s_~fqB|ASPz&!Cyv9w z`zb0Bw($rUj1d<;LPvkr|CcZAbqy}0f;9le3xK@=>Lx-8Ax;_$CJ%^NObk>>096ZM z&xQIIKyLt93iRG9tOy$$bdU?433Ada?tuOfsJ#n}1vIcrjs;HG%LOLP6%O*7*!34A zOUNWKZa8q8aJM288t{;41QH^Okdg&>BL+>NbRG-w?}+&*5l?kmDVBQVuQt6p^$MN4?o|_?@V4T%vR{Nx zwolpz^sDt<4H^`T1k5%JU8pKd5{xa3JK8W>S>$r0VI+1WE;=Huo|;c}h%$@Po$5Xn zIt{)GPYs)x`0vNEZ50kz`bVTk5LXTC3Y*GF6?s*L-vZ^E6@2CSg+?VP1ql^OWlmbA z0e|wb=TaM8*3H%(*KOA^Rq0g~RIAS*mLQhS%L$i`OFc^+mm-&Nmh8%Wf0tCemzR{; ztJ?qeFAQ8}TF}V-TTrKd5HwuDJ?^Y?Tzi5x!!2;qO;KrCjGfn}bDwJ#cbuBsoZOSF zXq~d`S*5=!T`7J3l~X!1tFXLNy;CM=m1~S-RNJ4sz1vOP7jKwq)Vff+aZ~WO?sw&! zR{=)B$*|S1>;d0_*FhKs8mfCDT_R0lMzMzSAItPpf&~HA)yZwTq00G-bZ(m~gK5qk z<847q))mWY1G}Y7UJMghg(#aSuP9-ebkkbXK+~wBb5DqSlw;eh75?jvq%PI=CE^Om zW$ER>W$@+8WqaF6n^le^4o+L@X20eNTW#B&)wB)A%cu3Nrjqrr)tZ*;#_!`@0Fjf0 z1C}G3gRINurAJuaB$T<0iH=i0mnV0X8_&_h+FGCHzR%{X0w!zqzhDYfyA2_~7^D?c~BD>(YJri8UiF<6rf}6-j&Z z>!fXb0V+cO9HSgPeexZP9hjXFKQBMN9*2`G*GtCpoWvRwuW*2F#`?#{+a>0NZq+k zeG5?M;poU)e-}rK{)UkXig}9L#(E*yqR_`&MgNV{L{rARXI`dkW^*I5)7uUx z{didh(-DysaqV9f*$L&vKwzxbS7`)1866C@MKLnYX(V(XJ}A8wRTfdAFh|rygrWA- z_iLzD){&XbUlsmt=Jcj~Cm#uJ$YSkxJxX@UA@86_p%6T2yKBCcP})=;SJJ!fdPV=> zECVikR}w4^Em|s+D;z22G}~oGVOq8def zYvfoVhK(%3uY`Kab8676?PmH^l9`%`+7{Usw3%&cHo-yXoqUq=yx{cU^mI3k-cGw* ziKTPecGpW|p*mkaz4TTAtB!c`ezHb+XQnD8@BvfQ^A-( zi-NwTd0p?fg9spe5qz+#-Kw=7cs7#1O+u+is86WDUBj*Uu=q57jYG{y;C!@mTkUj* zb&E2XxU9O;ww6Jcxt9)W4z;n~mfz9q{QQh9;$=u#OS;^U+N9p%RwU5bZl5q%N!Hb; zRid#|^-|@yTHfq3d>-M?X{s^VN%{QvbVqz4w5Vn&r{N9fPxZYy%}W*C z5@hx(uUIZ+DEm?)EyXU4DZMOruB_m#^z?A%*I}$8VyPn}!_fd5G z@2YHkfu@8rhd7&>kJXXm`a&bD_F##7yDe|JC<}3VB&%nwDYxQTWHwX=^OGU_`sqTz zd+c$(Y+^cPqnfF@QOC7)ebabn;i2NQMy?B?Yib3rrs;|MvFUl{TF`mx^Q{e6fRka{ zWV_Rg_Cf9Y60qTZP1nxqkmCIO+V$XVe`UTy=pX-$bYJ`Ox4)o%Bt5RekM*<4vDa|- zA$P`LCUKM!@z1I#qd(^Nmuu?{^^xToYnHj|jBR!f&Moe#ciqj;80h_JrwFK&e zGJAPd`4~tj1`=rQ6$p$J$CQx;4w-`VzEC#u4yd-O%I0HXaIBeQp=~t0e9$L7)uRL) zs2V@OK0hMjmLC;$2Z1=O3sOjOxzR3%jV^ykCPo#|UQtc9b`%YMRa;XRLn04b8#`wn4}OyWk>L5M z|JTe&Li9f(F4p`c8ghz6qV`UvMC=S~3``^fFhoQ|d`>22JW65`|6Bd%iJ!#6#l?Y# zkSx=`H$%TT>opFrXH66m&wlgf1CAVAme{MjLZy7jQK# z1HE#dmtT+#2L7)E0*gLO3Nc|ZVR5NrF^OI4xVBhU_676>5PO-yVf~a$S~#qH_v-cy zwq=7}gIrdznM_1Zj(L}nl&c%|KbLRLD^~7R?vFlsOLvbx1Bb|14%kWPtSE30a1hg| z5Ih5?S(MS~%{V_u7BN3ujaLMqng8K0{IJbfMyJ31C)qgs!>8pQ2R!}5(QEm`c)}(j z=lkDywTyd__^UcbfXtZ;n0DD9;O3lh3W^2(8+#SAL3sA^mT>^<&+r{^K>q-^V}2{= z{D;2$gRXFX#oUYiL(KIbaprJo*~|~Rko6CGiR&}g?tjFY{}Ia@FE0Lvp34r=sU^B{ z(2G8H%oxt7`yu$1s?ra15N@o@tY))Hvz1~zA#xDWSu{?gQ|h&3A4*pwnRIuH{K0t}wBvex&oxkvFzS%g;5Fau-%HXNB_2a5XAm>f~0rl~F{mC5*&380}8n zf{V$F{m8^yWy(sx!P|vk$IQFJ>*Ak2!Q@AebiT1|R>r6Vb=E|9U?*CaT*j^HdU%x* z8t6Mwht#RjKfl8?f6DOe(vrK@-%B~C`odUrA~$!-CjfJMUrOEEnZQw-+$|X9Xq)#Y z5op1N9_5*e&+^W*7A*ljb=86|foJgczwMHO-8X(-8~Yt+Bp&%@=d9il_-~<@{^20i z$cw{>uQ}2T@$N{K9|+<4#Zn-9BJkMKM=51QXSKF{GM9=w6;HH=cis%~Gw2c&p88-e z0`93nSB7`3K4^DvzkBiX!p%bj&qZiH@{%iu;a?LXt;B;(Y; zlQI$71|du?7&FL%5lTm)A}!0t&(xR53V%f@M4C7EM`-`H-;&!4a?@xP#W%MP zamrm!_CB)B3V=J3_M6e+MAi#R$U4tG5fUtY=a1#81RnhtddT(H-1)=VR|&PMkC5?K z2|x)@<>GoM^%i-0V(Dc-u$eCzKozkwu;U2v^=8d1Rs*LVNsk$f`8lAoe%I&g<@;>< zc5y6e$^FGs1oIyB9@R=|IsdH2OytqgzX8IaPd4f(Jtnhelt4k+aOkFuzy0aQD7-Qi zCB`A|T}EF=e@20Kv~x_ag`hngZ=O0lpnOzQvF$wLtodbn3-KNKErj);(20^IYsGM* z{E8v=CYAuYhUjTC+Yp|tkK*Bd30QDB02n_|PV|V+#Pq~qEJwLNKJW zst*a8#J@73TCy-Zb%^Ceuc*_Zrr6*R?BARBGmN6ybXrSbekqOm zri=v5L^!ToXYJDV_4U+#5x-4TeGAVh`0)Bp?R%f@&#L|%5m*uHL-=AALmX8@jpdEz z?pSfRo6Xt!hU#j4Hs3wVXS>iX9P4&;srWaA7GLuBUjbHgON!WEJ2y8{CU=r+3IwnD zUVE?&q2mNs>CU5UD7nNP+)_fiVqgQmCr2&+_%$9!E=7OxuB^n7mi5z{eSwP%p1%n;B&`;!wR(4jLnv2P#)#$2V0De$#HoC`rNuW=AdcoLD^sY3R z4tzM7TS5lfls#-3QDVS-MlUc7M4xy;chu@_A%JuHCFNmwFXdF5@KZP)$nWyLM%ja> zMN9!sB3knJ%7gYj?MSdBZu1k!w&-d;-aSy`gGjzceyw}?j7o24{uN9&oG(zB&oz9m z_o7VI6S2oQ(>b!Zz@XuAAPhxn@>$BaVKMB&pqovY8`~He`fCX_(ra zQ-}Yi9+Y{&3)` z6aVUkyk7tMSnEy)Z(kGS2L@#FooIKHI+i&&{Nu@=dZ5*?_`t`#czh^Eb1$@@aexlP z@>To$*0MV{iCjgV7Hpcu(S=}sX6avYXCnO4UwgAERW(=RdwNoPpoPK9cnqQ<^KDdHco!(-+2f8Hk+ki=(yuLio$0^t6X58?l+{pAxkV=;0wzJ zK4g-Z+E~Y(pyRRnLAUP*1KRmX>rL8v;)p`qDFOReat!fr2o`T;n38#9$^Py`H&Ez# zceBDakMKMXuDxqmC+kDnCE^0C`?q2*O>;XI?WMGNHsCfnS*~x@csNY|-SzFW=oxg( z*?@a@AvnUYgDEP#VTfyTL1M4WSjVr(m(W_97O!d*XGChXP$0Yuh9M*7_L0PkPw#_E z2l_D-$Eux$e^bgfU>Cl?=AFV;G~iL_n9tO5@|nu_u&-vmDl3J2&{k|Gjl#=qdSAir zo8WV7yk%4WR8U|<{HG2b8G z6bmjkl7Om`nM1Bbim2x}yC92oTNTrcshu;d-OxXm&iA!LU%?waa$`E13D-?wcUhYG zlo0ttBV7*9-}Bd-ubi_P?ct@B3eb^C#+pYs=$fXjZcso-z8G3#P;*!cVDxg3U12K+*|jp55Isr(XotLuxc!kx}X`?@;_ z@b^iU&S|nE=oTtGdbi_@H~&!Z#Z0w=XCbs*W(|jZufLFgtiiSuy6kcSnzApeM#BX! zG>@oSg6sV@PnQ_L3#NN)fYEP4PUSD|U5w9RK~&hyGDF@ck@?G_PAJ^=U$kq!NaSr6 z;_E^j_@)ypStCw3YTih{G*fffDUhz=Lbg7~-Ha9z%G}B&&#Y_EB3do^RC;)+y{EK^ zyiWU(U&K$nw!WryR>FX@&h z5ngt(;Ra}HG+D!U?L!)FG*O3esLo?^^(`NZ)TjK)#HpEslGwVIq3F;HmLS&u`HE5a z`UG0G?8>9nAV0+beC5kJ{`wcWs(3uE&2rjAcgkkqX4I1EE*IMOX+o>NMv5~@Es#v~ zTb5|)mN=hx$P1M@c7|fs)`;lXZh00Q>XDKA3|z9P=+=(o_NXFRyIeDUPXVOpHbXXy?f|YzE-I` zF;Nw*V^O$rvN(Jr+RsNEOK=bBVr zg`;On0iVm&XG8oT1Mx}JG%hZFBvF-BiR?mh}7Ku4OiK0`To^YduBreQKbEnw9xwSeK^V0reLt>N&RFRUGFZu_Mtt zTMCTVeh9aP3n(gKv+E0DamWL~N&JNV4_DW}>AVAMtMF>K&J-!U#`YOvg!__6`<<;! z?p$E6n*COADsN@shF@AjH^?!70f|Hjy~#9Caa`kJ+55Xz15^>*C%OuJLLCGnN%EKF z@Lk*X$gDW>xNe3MosgmSl*$UI{LxH*^)|jxNRmH+@ldB-Y_+{NsZ*g|?CI#T;JBy* z_`f7-bjM<)&G!sY?NV052r_T27oafWYG2nHzb$cK5TIMnG)osF*u1YbBey~3aDO89 zJiQ~&1K>FsG&jprK(lDmxRqBjU~B+3MbY4+po1`E;a>og_UYBK2!YYdu1wV&(Om3P zxm(iMr!O69XhGnH?#b}P+yGdtF)HFK1@-`d?uR@2Ri(1(VqzW=OK>>NqypXp{LL7y5u7m3}Mx=CauFjMn7Inf`)D8?e=+_}t10_BZ7n7G)B0#erE%~U+ z>jC;@U6RO7w!E71VqZhmjE-qZBOXu@2!arK3YqoQ_^`7rS$dBp5MU|M7ZwkBsZ$bcE9AoDq~t#ruxqG}y-9h%!^ zqLy#|#Ih47yn-@u;-x30Oe|wgP9t?K@6oZRwxDg^%v61Hqr(^!u2<9<=fwQ&MmQZbYALz8Buve0hXQMJ$9k{#`cElan%ycmE+{yWd))Ci z4v3?reHR_pBO78>r#pBMF(x3H=##`|A{5+zKJ196RtmSE>zB;fcjamtU<+7|FDULL zCA?}b;2)xOr$g-i3zF+?Nm&h?UgChL)5Cz>MBAp02B)A;D#5X>nZ2^b8niFDj^9E5 zi3=gl(tU^WE7@Eg?>tXTp0bF&rkY!&+ftSVWN=Scki-Qx$xA>GL5K0EI?&T^^otDi z6-^ALXUHOe)p$qI_KiC7QRNHQc8RB+^@{{1;IZ24W69Ka!S**L?$37(*80Tphh&rg zF!fTQZ~a!!SyXSbleARLJH7-%O)i)e=xV&DeknHfw|R?ZN#-xSgF?agKq!_~s?hIU zK?^Ucu8u^c)Gt;3MR|VM-ukJ-*`cc?wOJf*4WW>!U6&P*f?2HMC~jl_suk0)aGu=Y zz}YQYw+Yi}qK|qeU6R6k%^kogp__Fd)F3U(8`iQ-?8O&&vvWMh<9mAZJ)8R6&H;(F ziC?*k!$>!013(G&RjSC*ygyD@*z(~)ll}rw0XJH3ZfsteF6Z`O1uj-h&-w9;A{-k0 z6$^axy=TMP)o8-V6EIDuHp-?iw4`m59mp;@ENhGrZ=A7q)vZtmPYH*ksj{GB%M%tdJon@Pt>z8oRXhrRnO5)+cmucBEEg0eqvCIL{dLx+^XVJLkQxF*$IfjtFN(0Pkfz_8PKc;y2ch5t$z1T)6NH8Rj_^ zNlSm-xz*E^WFXP*n4+hh6Q_Wo=>ky4&<^I$J5Cz1I^vdubjv{(9MQ*Q!ddi>$6S+Z+CukG)ag z%X~eQA*6Xy#MZ{Ii=Qu154SPjQrFp^1YRpc_H^7Ls@kgFwoTQlUvP(dw70ywN)nBv zUT_5)mrbW9Yq!c3t{?LIZCQ2y(pu|3PjS5&Ma_nt=(`eJs*&@!x%7?(4HeF{*)DKb z4>*`5mZ${$Xlh!wz0MdI)la)i!nd{Hq$7v0WdFD9BnBqwCKJ|y7=zXr~1WY+GtJnQ%w)ZI*`^y zhr-w`Rx~x?4aRQX6HCOt@w2kw5HxjDL2HucsBhYknx2hKv>Ii0%<5LmnL6q!w8>Mdi>J;O>{0KOyGCihrJ5S8$_#WD zmdI{8&pG#uML(inqW^iqH8l0z&ATy|q^%JLFN(|!sITq%mvd8D(9Z;htVArIP4!peK!?9olnN>Mo zfLbz=DUC5r4AGg$)tQzuHRqsFMX*)!c~Rf^GHW@96o&O%>%u=8WEKcXO7ue&r(_+K ze`%&;j2VE>_>~Xpu)vCES!=k+=$gfHj>-< ziM70wS3$Tj%8fKEPL`yU>AxE^m5qehC7%yK&;@@~9dWsyS1QMAVB3u%m{s{*E{4;))M@ zDyap=ZLSEvztoJMOXD=QBy&Rb#ECL*^h@IP*V3M+bFbm%tOI|QjWr-L;#*RQ)JuoU z)9PKjxZcOJfDUSJ5nq#Z)xLSxMz%51RJfJqH5*Ev`kuOt73FM@6R4;46NBAiS~ZJz zs`y*Q9B5suylVA4-7UMaIaB42+!{uyiN!fWdIHFdc%R=PtJEw9DOUPfw_X1L*dq|L z`6hom!~-CqP`0l9z|OP&o@C9J*m_P$*ZFxgX)5@pb=SU?t?$%QTnbxZZobltpB5XD zEvZT<$ZGK}mCbi*9kecY&@5$n_~dtnkY`6MSltzex8-Bb9SBKlJ5)QS{RvjHIYGV2 zu}E{{{BL*X*uV+1iKxr&j2m01S&Ce-Y4B>o^Tr~$(J91q{{{h0Z5a$wiP%ui+!l7q zX=b(mWj}^9M&{u?40~z=psCaRC;K+3CGK}n#>Le&1M0s8Z=f%rhph}QJ)7$frh_Vf zB))SN+~edias5c)h0%Dy?#k_^oStLJ<~jb?bNTvJF*qqjpZjg65#RWc7=x{p`pw}S z^^|OpzMBd`#05pFb_W3?NfsQ_P})p=7I|wk;@SDowDhX`bwQ<745*H%!#*|AOF?PEbGq!7|bmkW9NNR$zpyJjW z&4oYE+Bf6|t^~F^-YC?2_kjVHmG4;P--Sj~fp$-1?-7g!0GUO(J#QrpAjQB4xm0JE z>BEV^U#-nW|6RQ-rjUhn2XZSTJB+yOD8x5A&qT4 zm}+-=k8z}JcXuK*NPLo}Qj~hsP~E6TTjT`>yFG-n%dr8RR1W>GxCh&ezDkMF!+W@mO$s|< zC`1{Ms>9j@iLTnK=)xHfH?SRf}@OHx7+yP`nj_6&Y!`@k-ULH5jDmGg)`XaU$c zG~$k%>*Qea?jIB2n>w6bD)rsSKRN?*sq;GU<;lZz1=`_*Mh2p&rC~vP_1Z*Nz-?w$ z8(?_lZK;;5B>v017FP0U*F)t)t`+FL93)=rrVD2p$R}{mIV>T~s(vkC=dXasukLy= zz62jO1iYMi)#8!?!)4yW35@nuZ;#+>02OT9J+v zywIF5Uy(#h$S^zncF+(4CBO`lFa)xQs=;K;!}W?7bM9n`?}2WW;+&p~Y(!aO_x@32 z&aKd)iZW%*;$7q_yydF;4twcnJ5n*akM5TEiOKi}*r~Nca~k-meM4%Emx;MozI3H^ zL+bkC!3JQvS5-e@XjGHPk5bWc(U=ptR$~wxQrp-cld6YolPRb)6{+e+^dCP_ zbwnjfJ~b4p_edc}z&hHI&nYvV-%hkT{bqybcKhSb2^E!#{N;gcoUw7+`%$OVLJ)2Z z1w$V}FahmBQrGt=z3&RsQ9?YmU_N9FcYkA|TT`&f^O5BXyn+YX51m$kJIEkS+HFpK zxICknLuopflsmWk56fcn7)6rugwA$Q?Ubkk#u~&8v>0*jfO#leh5`v#-gZWelI9j z*|i*uNZNK%U}0@7Hw4I&=3sFeszP%b&jRxBA zBG>Efba=N{KjYZY4top#J25KTAGWQuPwsKmRlIfxoC2vDqzlINl^*&nq#)0Kpg0j% z@fw^V{?`8$W?6oXZL8*8wu&qHu|9!zqq+UZR$1ARh8b&|(#cxUpexdE0-v*dLfytW zBZ#-`b(Eb8r*?NGq8=z2&WM*$xQzEA8x-+!aJmn>@ZQJd*(i8BiVZCxnXc>C4HmAJ zlNU_dyMx@nv4QjI6v<+<4YE>x*|!~eU%dzs4qTcnGY;-)w7QeNCJ27|nu?yW^mXOv zmb$Ti0XayM01m3p^w~v(&z*!gZk6p zMBXST064@)1x%Zsg=cC)BoFGoLDi<`v3}4%B7_tf!K-G$W0b_J2wZ^@E*l}rkA@b* zxmS;ZKx{2KqJ=o!5st{KQx4~LY97faGU9L)DE^Y~*VUZXohp(K*Uq5W66sj)0`LqN zRM%ay^);p^zKr;(@P}z{b;`A98~X_HpKnJP$o^^9w1KRK*wyK}&1^2R2IG~z88%h? zcV)b=SIrzr&d;oWoNa47+9h zq23V;S=6AJD&tqY4hBLfD$)A`4%$`cS3cVk{RX47(vm8p;>Wv9LA*#Ou#E;|(O2Ua z?Qaol_EOz`rw0ZaCCdG`U4Czibxv;B%#L-rT} z^$-bqM*K6+iXLeSs?Kq=0fhKDHRAdtb63Ps=6C)?^k8G!CUlN}j2O6V*Y&=|x+!?> zoY_0Mu!@zc8?53M>yJ}rXGfvgrtOtDh1&bNBRYrqKv6^3UFnVFUK>ot`}AazZszjR zIfKPqo}-O#_^$b->#5U}r+yFYFrrU|iFPEY>(Oe@?|xpWeDG9x=Xz!xOPL3^ z+I?~drO|R?9`a)Z4|21aI_FQPC1;dw9RW#guFr?QbYVFN%5(c7hNl9KRZbD%ntu^V zGqM7G+wzrBq0)@pl{%#$7nhtqHqIL`40!a`b8%aX7@OzzyN7N-zBN&F>UTe(2G>PS ze!No+B9u4#sm#N!C}Y}AorxC@u?9*Pu`%ybq z`rNDrcNOg%CxsWTVTf?cA9+rOeuv`r~XY{sMz8*2(a#3qmvM9t=2>RTXV z?0*6SdIYVW6`d@9O^wbX=9l4-t?rbP!bRjn#fyw9T7j!Lhy75t1mZ)$s1jCGJ1 z8!LlBB{OCG&R&&O4nhlgQ6ti)M_D_+qnnk2)gcwB$vqkFtAVst_|~N-^G~ zf1VCqELkkVTs-?n^GrYO%mcM6;1xsF8bU7t(5MQ08O5=m_96qNv97A^-I0OPx zS3YF9B~i|jpqM0e*tCre5{zjp9i#hK}#wN7`o7PZtg=dRDqCh!yW@rYj zgKoH=Nj$957{crEU<|=%Sl+d;U~w2*6M0epcDLMFl@5*lm&B0fF~Luej?7MTHK_OL zXQdFLhGr#!Q&+~vzoulu$F|fC($>|7pi{9W2a_x*17$(z#%P2AIMe~XQw*nv@KF#F zR4%7cJ@bZCoU5a0B=NG!cIaHZe2AGZpJ%qod?UsP$3(h!2Gf%$6xtjE?sdKHMa194 z&V-SoWM#rk2Y=>9?G*79i0Y^U>h&|y&uo<$@LbA3XK{P^dpKR-V!7)`wXAi<*3LwO zk-ndXMNetBA7JyVVk_qC9eIc3C;dL>9Laj=z{&H(U1gTCK3_GGvTG{B%Fmvw10PTZ z1lBIV?U{)MB<*X2SmMr`rkc6kXB#JhS51V&)R7UmmbF9MRdFMclen+4Ix&f`Z}g($ zb61MkXN;vuku=H}%&U*&9&Jzg7ISXLPOW3=%)S0=8(B|w(Ziz2j&fYabDLNWvbz6R ztsS+YeLLc;Ln(|ytY+~wl&y;L%6KSa(Q4>mdk;9CL9Fjqhjz`LXU&>7-t@}k>HtWR zQPAZ=l0I9%1a_~&0oA_hDN?x}u;J$v#-ZfC2O4i%xyqbBTx9eQ8$L2^1XVk z9qpF?*VVjX@{;dEWCZcZhX9>su|=+e6)jb2hOKkUgr(>MnsdAapx0ZnCU7Hgt4u91 zj5CV>>MZ3{1VHon+}B4*(a95FQAD~#7Ck_|Ap9ht=KYCQ@7yS7-0xUQMiRN8>@;HW zh9r+-Cu*7DOL!*w(CW_;|92W9r!ZH)J#pT0zWnx{=#A%9cXIE1h}`+RUg^%E)ZN(V z-;A7Zcs4lppq2w(JH?^rQLo#3He}(1YQSX~ORKw?Q-##%tuJb2M))@x^Ql`#T5BE5 zoWo85ha~8TVi|S%w2^m48?noS%SN_oEj!`!jA-4mQn>&`PlbA9Z(ZmN4aj;2`-1&p zw>ftM;$J9A(qwb=r9Ist9c#k>qD!FP8H#pt$FU(w_40{fkO2<)fR0}W$fhn;Paae5 zL1cv&&6MKjWAA8=`XH7|Cl9gQe|4DQ<5;4IyeP9IVO9e%t(Qs5#fD8DwZzCYlN1oW>5g zjXio@ixZIBundON>dzsJ%g#@he<)qpI0)sJ*xpQK=0fXr2D&RWYUjG4Z6!6lq7Ri3y12?tix(7bVCH>^a`0>GM?Ck*lrWM(I3kk@ z=mN88j53FXL=!sFoAE5nF_SZ`ge*g%IN~}HNJd*~``xUsbXCLGKyFI!as}lPrnMb_qWXE^TY`|Nxagu@zjhbvfA@@=p zOgUY~oa^3DVNu^29fwu2u{M{RerVZGfC+hXPv7-S`ODA_OF7 z&t#@fkwhg<>+2|D>~woi?ncE6`|Q5f9QP-~wt#F|%E;Z7Nb1kn1|Q^0bX1EYr=8uH zW|RrRuiU?9J&|?f0B*HONM69zt0nn;UQ(R^#;gbEQM*g7BxIfUD6tTJSmaxatyxez zCOFjcLg@nG>iS8qq)MaMRv`ef1JY_MhX})yx^Ee5?4gezGy9#mwg#5kQ20`m;eZ-cGSi1VabmJBYM&}rd zik~lxuZ6@P3aK_7b97}vxuTTlzt|%*f*0(Z_>T1Ft%Dk>z6myHFvvy<(3O3rvnc?A zUDw&5I;|c9O6k9bkHPEh8p-Pp!_hQbQct~_w$rpJ#m!l)6_zL}P;9X%7}tA6{5vc5 zb3>N5L;e9RV+N-7f{zu@UXGtJ(~QLjR2-bLEB1SAE7KUe8KnX(^dcl8I~{JyrFg;A zBi@-QYiySfY^{9jjuu8pwK=c8R`~Nu)6rqp#hyneegl7Mr(hyj0Y;bu6~3tm{T`Kz>(}+1p&jfQ zO*=P^fprjHkn&9LKvQF`VH#RX*{ccsawNKnpL%~v6&xd$G+Hf2Ph2Vqz&!?vAb32} zvAtCawU4_m6lPO%+Spd^bZkORBA@`?jKiPb6EhK#7~K^Y2ykKXC9W0C2l2u+>Iw@} zO<7B!?)H?5J3+4riG8;gVWZoQys(NcX`|mZuYQ(-CBIqFrYlpYMkvgQir(yGIKz}D zVCgrUUH$5L|7{}lJbpymQ?cr*hG~9>jc2eGoW*_7+Qc*18w4y9o$HMk%dQe_0IB{O z`RjCZpxW8XXlbBbDS&#~FI^W^RW0BWPkOwE>=IFQTPFTQDzKUe;%E)06Y~;+`KWKG z`qsDFu`0X^E;g%pt@nP>9=cuu!8-zcd%fNr$&EU6DOZ@Tk+p-}k^i$1r%RI99?VIS zQV~_FJ}kuP*|@IP9b@k*zPrrH%t>+pQ$th?S+OBIj92|H^Q*zs8KjJy zm{2-N(5zP{$?kdA{1S?Jw*>wQD##>!OK)95kUdaJ6Ku)jSTbDb)y-;h zd##@}x;ZR0a;%>~?geuZCNj`$~42MPJ zJ)q@d1!6}jvOuYf%sKZW=P&4pItsoD%|e9vW(#-g0gm{ny$pBm4sy~H=-7$}=NQFY&J8i|X{hGFE|6gko_v)s6 z=!x{#XX^P8S<7*!Z%7J%D==(3!Q2_paVu{w5L~F`wwW7?Bh(~FrkQLQMjXGKx&~EB z+*Jf5?T!;hCf3&uxIYk!h1f|PY0HW-N3x8Rj?OV2>l4E}`SkW_^D?8e1(p4Ew^40a1V$ zsvhs&JnX_X2~gHOeYoI~`lpWv)}=}M?r<6Ons@=~>QbYA*n=SNQ4Q&28McA93PJ$3 z-q5hG8NdKG;Wck;aE)KjVS)nPvD(fxMTh1g=apZ2 zh|R?5Kci3^y-Q&gR~!vKskKU*RY3-Mf{Bf)mjo9M__S@`QxqwFx*4D8E6<8_>OqHf zf8df&L_#2Hm)i0f`QyOF_dz?6ltHnKM_f#incffCo>UU~T`Aancc6_04?jX5f-u!Z z%O|FhL{vQ@5nxXX`X46$pbCPps)><=Zs*=dRueNMyx7Xj&%_ng82cA!IGFl8WF zUnH=1!AIH8a`&U>vtBdS?w|$UwyKpFliKm1n^fy8pLL6D6$N03W>jmONV2o*9k)Z1 z{9}k|3cAPQyW2{HS`G0DNjjd{iWAep9(1v|jv$8|MJ~yGN1tRR^-v2wp;YVeqI@E+ z^Tq27@UXm;Acl&H+D~Fcwd6jjRBc=kzR5MzOEVjM?Fg*s`(|&Qgbe7VC1wEsq()Lm0JyWNIr+o2BW4YH6QrQ+4iBwncVc67W-Z#~TR)a(tO zPYJbWJ^BCZ<*dJ=`o2CcA|Xf&Ez(GL=a3^Hse~Y1f;31o3@IfgB_cYMAcB;9Xol_{ zhmN6Ph#`lrXZZdR&yRPlbNAWz-o4k}XWjjNeOxpK_ezwUT@wSP>An#MS`LevmwU&> ziJbMj9?06u4ydTrJoEHC_8i=n1PkY-3697S%2bop>&K)DBYsaqd>B zXFk7Dh+ZJcHa8tOuRYPFl{Ski0E6_jsb~xTzGPSsa@kZuB$;sb$dc&Fx$0VJDW8f; z!_>L;RX-2^W#XLGoZJ*=fSEAIyGU~qluA`S<4bV`sV+Oq1Wg5T_^$Xkm3~y@7!sJ_ zBjMtR_=l&)wS>CdawDA!4{+C`bIQ!|k%222sN2zzn`iUI*Hio(`5I?dNHxf?ye8xD z14*x&?A7%s;>Ykvlu+j(XQ|cWmtp5McQXlPw*8LHv)uVW)y(q3zJ5qiU2Vc_IRGf3 z^S6P4@!b^5+)Bo4AX>j7=W0|_^*CgoLA%&lF4>+vBnjbsxf?Jh3?HP*?EWpKm_Z!< z+*R|@=cv^&bXRRrJf4d|{jx5Rjqa%DHa)z$!b|odMXnP9aYl5p;s>J=&uN@^^)1Lp zsqtXStf`-QX-|>zCt{A`xE^lDl?^aWNK4uw2oza%@?F65w7PVSw(5tk>Du~l;IVQh zK2sWt%TICiTJ9D-+#vBF2u8>4{RR3hOP)w*;e6dlff&}VytwAo*UM``(bk?sc1t$H zp`XFO@LpxAr9XyZOC@4M)guBiK_pp6WB+Hv`|I3CD5u$9LmEb(0>FGs$7_|vdVv)y zDHf+YsU{7~nxPHH0=YTe)4YHyxvT$#2$dxx{E|C7tow}3J`eYxR4a#v!^OsRBz;Zg z<_<0KlV!25s^FRI*{mEutfZXgR}w{)nhr=UuK$nnYA|S&p1hfN z1i!*IBO%4oYSEC!&>}`G&kqe3~DSPtO z+Eyhxz6+_%oG-F%FJ1U8)j|I_t?%NXCbhqim5bcO{-kmlRt?P*`aupE3aBQQ8ycks+8 zZNH%N8utKYG44$}=Ce=6Y-_)q;m{|iB{r~ClDNTBE|fFadADTYssAmIQYCbQ=qcb( z$UYFPP-@PUoVrH=bTR8vIjkEF26i8n2H4itFMMsWUBUjQQ9->X{L5EtJ{^{7X5LS& zAa~^l(r!w?<6|8vah(|%=2(ri@QRX;TuSfZ`_D|jt?az3{#sax<<*bxfVWDp_VK$MySmyZ~%mm>5Ny5 z9yiUZ`Scv3aqb?>Oe(i>7*Yb?ZTE{Y~Mvh~0o& zQXK-?sK*(ye~Jkr{4Il-Ew)0FY=ya~lB{=le0q*5-A?TTF7piDzCaS;oil5@nppZ` zT!I11@-Zx$DzB|rL{))kL8!ydcjyDR^c!6o|S-xmGKcBFra zktR$h3YpLe_FI{o zvXGd`RH>+9wk4()PnJK+|A<+#I?cMKhHy8Q)?I3Q_KyiM9*?#))vjB%KD1B-eK)H$ zaFE|hr=vezk*7{=ukeW|v#5Npj;YU!IIz(?xHCwRxg6P11nqyl!w>R0M)=rW#s3Fw zdGTy(RG-FdG56|W?dyNTfYQdwp^uam#fiG+uMZe*m*e`{T{+pl#2;{av2cnz0CMdA zc1HMHT&o2k#=SBBHXKnC=uDL5F2374%kaA{>=&BnZkS@j@!C zCdIEF+1g4<)pOrM(A}*s_|(swgj%#1o?o+6>s0Nsq8)3=3nX7QWl@W4k&6ByB%&tr zjCLn2azk`(G+NLFkd-xDD~Zr=o8EkB_g{IlzHFsy9uw4aw%vGLhxGrhS7_?%$#exa zDq>(dF<(>1Y1X5bA|L9>LdZd(fKF%+WZ~p~#(SW$ShEdKF8%h9s(3c7j@)YQA|kW@Et} zgGccmS_axMV=_a_(%4Ix*U`)+A9z(SJZ7%+FaB<>cY|6qD-C&!OD&};{?Cq?M`=>u~t_h_7noOFN zw2hVpZ$%Y|>BNVgl3ev#w;x6N*r4*mG-}KudS$BSZQ&sw&RxQs8pgKA@T0X2NOF9O|4Tjx++6b&=AabLKoT*+UzrE?n zN-r&>$2-tG1)SADJE^qrY2xih%0IZ!`F(u-H&%OHegR@?CD%w?;BB=plW&alfs#+o zS6Uu|aL#PO+%bjU$5!0rHvMG6Hd=`A|1hQc=&UVs%}X>_O?*``bV?4K=c7Xf=1=kG zuRk*Q_-eq0Dv#f)!3gQRU)r8KAaP_FjO(Vh`sBd_;^=!8z{e$V(pn1s;ou5-*G2_n zH$$`{iSFKD&|q=%y6+e0;0cukltF6!f^UH@K+8A7@$W?0(HF<6#krj-D{tr#7~J4I zWxmn;(_0HOqD7GHcQ3O4-W3Kv0>+Vf-wWD3dqkG{w#uL?8)8WBqCk9HU{W{&B#m~4 zvV$tj+UkgTiY&20`ta)b@Go(evY8b0n<~r09hC7Px0nxPHhOW|F6+xGHQT>2xCA9N&2Szciqk(LmYRL211*Eq;g<;Zw4}^5J^{RvxWj57v3$KhNWZ! zgMAdgR_je=j9SuKGpv7O{yhC^@(w#A`U)j1Y0#1(szV7x{u7O&>ip);M-`4j@MQ6_=e(9GWq2!Rz;MSuWAD>PK!&7fM4IgRUc+tS3pK2UPiCQ z&p}naF!5@M&-PH+#}XxD>Y^|*Dvt>1ZPW8SnaYVnfNDwxY=g+_%V{$?c8<4L3VFHc$S-Dpg}aka|( zWai1Sl`R-r@k(uPayg0-fOT7;eO>K*J|xKJe3(iI+35}|UqFyxx3~L z2Mb-314RxwXHxfK4|T2KI7A#}ybkyqD3t>lz%mpslk*<+@ZIW3u^alN-5&uKytCLj zP`NDIm3(7br2DB&=gg|D<%W^mL@;v7#q_3P?p%0L3JZ>S55U!?G)e13_ao}euVTbe z%qhQWrk`$qHsuVOCq%A%I7s{T3tE`#_zI+*c^WD!4sWx@=GK_ZlS;NvF{j>jTXRA; z&n=!o^g~Q3BYNAgk58r25PqD;^`gta8>hs7V+xC%SlYE~8zjZEc0Tn*C@SrnTnE9e zy#nAIKbke^{6C_2(*Dy}d;nCuQji@G3ZDcsoaO2N#@WcivMiL&MA}jz3iZ-MZey#F z9tEv8s53T@gVOFpY6wapo#LT-ER%8f_;&;%%}P15V^kT!f&V<9OYFG!f7{xIIVyMu z^arPNMjT_v%I_Xk>9i~zh|f-zFnK1Rcuq3lV~=3qTRHAGCK9q>qCu>;O9{40fMzN& z8R)~Cwv(KqnQ%O}$4vf_cA!z@uh9{po*qd{Onw6+gXh;Yb2;~+n)bH0?P2r(f>=BC zmVVYMDPE2X{hNUAm{Q93zzVRUEihp50c4eZ@kOBV(6$vYsbqA(S_~~rhmypnipd<| z>RTUyC(EA@W2C7*uYakX8=JUo!QK}JmcV{96!jC0 zh$$|6?D3nF0eNNPb(p{saP;|&2WPKW{x5SSZ-S78b&sOD#85KEbxBs#?oNh+gy(%G z8+M1q2Ma1P+8aAPilJ7#7^+B@mgfvu_&{q!Jx?UWz!h{&g53D4CRth;+`FonK>6cs z-`VM--rmxW{{yJNqHv&fg757r0Uc@^_(0&1?j_tY1X`Y;@Ot*&>BDxrKTVYc9?ux{ z)hEwRJ>V4~TaG9em>#Q5RmxTwlhhdflkYB1+Ik)mq-LpnT8WalEFxCa+=m?rMEnMf zD1nD2TgpJmy>V>8Se+YDM_u-8uJZo#e71KN=msXuqCX3l?!xz&1F%RVVi$-6}Tly0LBE7+8{jc`-h!a};>4b6I zUe>B>g~CsBn56#w!ZY9zT70gR<$;m6sZjAwWDz?kSwq&XXOf+^B?)g2eDrgr}L!39qNB6q@kZv{%VNWHq#3|R&%iU)A1MbvF({3 zJ+aQGeJI}ENK#u8CGb{SvWaVYHKPEGX_#pJNjs^aL69Y&d>&jbe6aw?TkO4vkNvO5 z%(_LiADdUXmQRGk?L>RS8K#e41LR7c)K+*6&`@@qz3YS(N7xy>UoJ`r}HXf5kO^hKs zZy6_cR6fYlGrP9H>_4bUenyvosSYw9jg`w+;Qt<-AWN#$lNMj1)-HEASRtU5iddOJ zg}*B4l63_CR9NtCm9K1Iv_9CoK*StnQlk{B!BmefY8%o5+ zu1{&a5|{VY8;$TTiKDf6Cr@t{pKeAXFxPv|^GAtSn<(2g*~I7`CvI_V?|TKHv{!y$ zf|RnL09(+?`qM^u1nOn5?N^l$h(U03CIC~M^=U8uhIQupu+GZ4ZL_RE%2{X>6+qn@cf*?##oR)j=ht7c+a#l5vL zQNqL@j#LV(_sm;OPwA|KXU2{}lM8!9-?Ad;VNeaPZ~P17HVXx>QjVSSJqI zPvfP2cy}EW$_r>u;~4sZts!llpuKBAy=Fl!SF9yR+eMb`U@1&$6x&EJ;ww$@E9}in zz>xT7|Cy~qQ{WSG&p7WPN=kDgV>DCxZZWgLSSZtd(7(i@lct`pXp7ueW@Hx@odlcl zz<0jC;>5C;EYo7ey6-D}5G9tybmGwZwD`UO`F6ihhi!!F9@B)IL!{9{eRi);0{N#i@2)|*8+JDOMCf37gVld9r1r?$_Ft3 literal 0 HcmV?d00001 diff --git a/tpl/RAJA/blt/tests/internal/CMakeLists.txt b/tpl/RAJA/blt/tests/internal/CMakeLists.txt new file mode 100644 index 000000000..517091c26 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/CMakeLists.txt @@ -0,0 +1,337 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# BLT Internal Testing Project +#------------------------------------------------------------------------------ + +cmake_minimum_required(VERSION 3.8) + +project(blt-example LANGUAGES C CXX) + +#------------------------------------------------------------------------------ +# Setup BLT +#------------------------------------------------------------------------------ +# Set BLT_SOURCE_DIR to default location, if not set by user +if(NOT BLT_SOURCE_DIR) + set(BLT_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../..") +endif() + +include(${BLT_SOURCE_DIR}/SetupBLT.cmake) + +#------------------------------------------------------------------------------ +# Project options +#------------------------------------------------------------------------------ +option(TEST_GIT_MACROS + "Toggle smoke tests for git macros. Off by default since it requires a modified git repo." + OFF) + + +#------------------------------------------------------------------------------ +# Add a library +#------------------------------------------------------------------------------ + +blt_add_library( NAME example + SOURCES "src/Example.cpp" + HEADERS "src/Example.hpp" + ) + +if(WIN32 AND BUILD_SHARED_LIBS) + target_compile_definitions(example PUBLIC WIN32_SHARED_LIBS) +endif() + +if(ENABLE_GTEST) + #------------------------------------------------------ + # Add an executable + # (which happens to be a test) + #------------------------------------------------------ + blt_add_executable( + NAME t_example_smoke + SOURCES "src/t_example_smoke.cpp" + DEPENDS_ON example gtest) + + #------------------------------------------------------ + # Register our test w/ ctest + #------------------------------------------------------ + blt_add_test(NAME t_example_smoke + COMMAND t_example_smoke) + + + #------------------------------------------------------ + # Header-only test + #------------------------------------------------------ + + blt_add_library(NAME blt_header_only + HEADERS "src/HeaderOnly.hpp") + + # This executable depends on the header-only library + + blt_add_executable( + NAME t_header_only_smoke + SOURCES "src/t_header_only_smoke.cpp" + DEPENDS_ON blt_header_only gtest) + + blt_add_test(NAME t_header_only_smoke + COMMAND t_header_only_smoke) + + #------------------------------------------------------ + # Tests blt_combine_static_libs macro + # Note: Does not currently work on Windows or BGQ + #------------------------------------------------------ + set(_try_combine_static_libs ON) + + if(CMAKE_HOST_WIN32) + set(_try_combine_static_libs OFF) + endif() + + if ("$ENV{SYS_TYPE}" STREQUAL "bgqos_0") + set(_try_combine_static_libs OFF) + endif() + + if ( ${_try_combine_static_libs} ) + add_subdirectory( src/combine_static_library_test ) + endif () + + #------------------------------------------------------ + # Git Macros test + #------------------------------------------------------ + if ( GIT_FOUND AND TEST_GIT_MACROS) + + blt_is_git_repo( OUTPUT_STATE is_git_repo + SOURCE_DIR ${PROJECT_SOURCE_DIR} ) + + if ( ${is_git_repo} ) + + ## get the latest tag from the master branch + blt_git_tag( OUTPUT_TAG blt_tag + RETURN_CODE rc + ON_BRANCH master + SOURCE_DIR ${PROJECT_SOURCE_DIR} + ) + if ( NOT ${rc} EQUAL 0 ) + message(FATAL_ERROR "blt_git_tag failed!") + endif() + + ## get the name of the current (i.e., checked out) branch + blt_git_branch( BRANCH_NAME blt_branch + RETURN_CODE rc + SOURCE_DIR ${PROJECT_SOURCE_DIR} + ) + if ( NOT ${rc} EQUAL 0 ) + message(FATAL_ERROR "blt_git_branch failed!" ) + endif() + + ## get sha1 at the tip of the current branch + blt_git_hashcode ( HASHCODE blt_sha1 + RETURN_CODE rc + SOURCE_DIR ${PROJECT_SOURCE_DIR} + ) + if ( NOT ${rc} EQUAL 0 ) + message(FATAL_ERROR "blt_git_hashcode failed!") + endif() + + set(BLT_TEST_TAG ${blt_tag}) + set(BLT_TEST_SHA1 ${blt_sha1}) + set(BLT_TEST_BRANCH ${blt_branch}) + + configure_file( src/t_git_macros_smoke.cpp.in + ${CMAKE_BINARY_DIR}/t_git_macros_smoke.cpp ) + + blt_add_executable( + NAME t_git_macros_smoke + SOURCES ${CMAKE_BINARY_DIR}/t_git_macros_smoke.cpp + DEPENDS_ON gtest + ) + + blt_add_test( NAME t_git_macros_smoke + COMMAND t_git_macros_smoke ) + + endif() # endif is_git_repo + + endif() # endif Git_FOUND + + #------------------------------------------------------ + # CUDA tests + #------------------------------------------------------ + if (ENABLE_CUDA) + add_subdirectory(src/test_cuda_device_call_from_kernel) + endif() + + #------------------------------------------------------ + # Tests blt_add_target_definitions macro + # + # Four variants of a test with a list of two definitions + #------------------------------------------------------ + set(_variant_1 BLT_A=1 BLT_B) # neither use '-D' + set(_variant_2 -DBLT_A=1 -DBLT_B) # both uses '-D' + set(_variant_3 "BLT_A=1;-DBLT_B") # list passed in as string + set(_variant_4 " " "-DBLT_A=1;BLT_B") # list can contain empty strings + foreach(i RANGE 1 4) + set(_casename "_variant_${i}") + set(_testname "t_example_compile_definitions_test${_casename}") + + blt_add_executable( + NAME ${_testname} + SOURCES src/t_example_compile_definitions.cpp + DEPENDS_ON gtest) + + blt_add_target_definitions( + TO ${_testname} + TARGET_DEFINITIONS ${${_casename}}) + + blt_add_test( + NAME ${_testname} + COMMAND ${_testname}) + endforeach() + + #------------------------------------------------------ + # Tests the IF clause of the blt_list_append macro + # + # We expect variables that are not defined to be omitted. + # For defined variables, we expect them to be added when + # they evaluate to TRUE, whether or not they are escaped. + #------------------------------------------------------ + + unset(_existing_true_var) + unset(_existing_false_var) + + set(_existing_true_var TRUE) + set(_existing_false_var FALSE) + set(_defined_empty_var "") + set(_defined_nonempty_var "") + unset(_undefined_var) + + unset(_actual_list) # blt_list_append can work on an initially undefined list + + # The following will be added to the list + blt_list_append(TO _actual_list ELEMENTS "true_literal" IF TRUE) + blt_list_append(TO _actual_list ELEMENTS "true_nonescaped" IF _existing_true_var) + blt_list_append(TO _actual_list ELEMENTS "true_escaped" IF ${_existing_true_var}) + blt_list_append(TO _actual_list ELEMENTS "nonempty_nonescaped" IF _defined_nonempty_var) + set(_expected_list "true_literal" "true_nonescaped" "true_escaped" "nonempty_nonescaped") + set(_expected_size 4) + + # The following will not be added to the list + blt_list_append(TO _actual_list ELEMENTS "false_literal" IF FALSE) + blt_list_append(TO _actual_list ELEMENTS "false_nonescaped" IF _existing_false_var) + blt_list_append(TO _actual_list ELEMENTS "false_escaped" IF ${_existing_false_var}) + blt_list_append(TO _actual_list ELEMENTS "undefined_nonescaped" IF _nonexisting_var) + blt_list_append(TO _actual_list ELEMENTS "undefined_escaped" IF ${_nonexisting_var}) + blt_list_append(TO _actual_list ELEMENTS "empty_nonescaped" IF _defined_empty_var) + blt_list_append(TO _actual_list ELEMENTS "empty_escaped" IF ${_defined_empty_var}) + blt_list_append(TO _actual_list ELEMENTS "nonempty_escaped" IF ${_defined_nonempty_var}) + + # Check the results + list(LENGTH _actual_list _actual_size) + if(NOT "${_actual_list}" STREQUAL "${_expected_list}" + OR NOT ${_actual_size} EQUAL ${_expected_size}) + message(FATAL_ERROR "[blt_list_append] Unexpected evaluation: " + "\n\t" "Expected: '${_expected_list}'" + "\n\t" "Got: '${_actual_list}'" ) + endif() + +endif() # endif ENABLE_GTEST + +if (ENABLE_CUDA AND ENABLE_MPI AND + "${BLT_CXX_STD}" MATCHES c\\+\\+1) + blt_add_executable( + NAME test_cuda_mpi + SOURCES src/test_cuda_mpi.cpp + DEPENDS_ON cuda mpi hwloc) + + # Tests on a 2^24 elements array. + # It can go much bigger, but will not + # exceed memory capacity in most computers. + blt_add_test(NAME test_cuda_mpi + COMMAND test_cuda_mpi 24 + NUM_MPI_TASKS 4) +endif() + +message(STATUS "Exercising blt_print_target_properties macro on some targets and non-targets.") +message(STATUS "") +foreach(_target gtest example t_example_smoke not-a-target blt_header_only mpi) + blt_print_target_properties(TARGET ${_target}) +endforeach() + +add_subdirectory(src/object_library_test) + +if(ENABLE_CLANGQUERY) + add_subdirectory(src/static_analysis) +endif() + +#------------------------------------------------------------------------------ +# Format the testing code using AStyle +#------------------------------------------------------------------------------ +if(ASTYLE_FOUND) + + set(smoke_tests_srcs + ../smoke/blt_cuda_mpi_smoke.cpp + ../smoke/blt_cuda_openmp_smoke.cpp + ../smoke/blt_cuda_runtime_smoke.cpp + ../smoke/blt_cuda_smoke.cpp + ../smoke/blt_fruit_smoke.f90 + ../smoke/blt_gbenchmark_smoke.cpp + ../smoke/blt_gmock_smoke.cpp + ../smoke/blt_gtest_smoke.cpp + ../smoke/blt_hcc_runtime_smoke.cpp + ../smoke/blt_hcc_smoke.cpp + ../smoke/blt_hip_runtime_smoke.cpp + ../smoke/blt_hip_smoke.cpp + ../smoke/blt_mpi_smoke.cpp + ../smoke/blt_openmp_smoke.cpp + ../smoke/fortran_driver.cpp + ) + + set(internal_tests_srcs + src/Example.cpp + src/Example.hpp + src/Example_Exports.h + src/HeaderOnly.hpp + + src/combine_static_library_test/Foo1.cpp + src/combine_static_library_test/Foo1.hpp + src/combine_static_library_test/Foo2.cpp + src/combine_static_library_test/Foo2.hpp + src/combine_static_library_test/Foo3.cpp + src/combine_static_library_test/Foo3.hpp + src/combine_static_library_test/blt_combine_static_libraries_shared_smoke.cpp + src/combine_static_library_test/blt_combine_static_libraries_static_smoke.cpp + src/combine_static_library_test/dummy.cpp + src/combine_static_library_test/main.cpp + + src/object_library_test/base_object.cpp + src/object_library_test/base_object.hpp + + src/object_library_test/inherited_base/inherited_base.cpp + src/object_library_test/inherited_base/inherited_base.hpp + src/object_library_test/main.cpp + src/object_library_test/object.cpp + src/object_library_test/object.hpp + + src/static_analysis/well_analyzed_source.cpp + src/t_example_compile_definitions.cpp + src/t_example_smoke.cpp + src/t_header_only_smoke.cpp + src/test_cuda_mpi.cpp + + src/test_cuda_device_call_from_kernel/Child.cpp + src/test_cuda_device_call_from_kernel/Child.hpp + src/test_cuda_device_call_from_kernel/CudaTests.cpp + src/test_cuda_device_call_from_kernel/Parent.cpp + src/test_cuda_device_call_from_kernel/Parent.hpp + ) + + blt_add_code_checks( + PREFIX smoke_tests + SOURCES ${smoke_tests_srcs} + ASTYLE_CFG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/astyle.cfg ) + + blt_add_code_checks( + PREFIX internal_tests + SOURCES ${internal_tests_srcs} + ASTYLE_CFG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/astyle.cfg ) + + +endif() diff --git a/tpl/RAJA/blt/tests/internal/astyle.cfg b/tpl/RAJA/blt/tests/internal/astyle.cfg new file mode 100644 index 000000000..2cf713b87 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/astyle.cfg @@ -0,0 +1,13 @@ +--style=allman +--indent=spaces=2 +--max-code-length=80 +--keep-one-line-statements +--keep-one-line-blocks +--indent-preproc-block +--indent-preproc-cond +--indent-preproc-define +--indent-col1-comments +--indent-labels +--add-brackets +--convert-tabs +--preserve-date diff --git a/tpl/RAJA/blt/tests/internal/src/Example.cpp b/tpl/RAJA/blt/tests/internal/src/Example.cpp new file mode 100644 index 000000000..0aa0b2070 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/Example.cpp @@ -0,0 +1,25 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "Example.hpp" + +//------------------------------------------------------------------------------ +Example::Example() +{ + // empty +} + +//------------------------------------------------------------------------------ +Example::~Example() +{ + // empty +} + +//------------------------------------------------------------------------------ +bool Example::ReturnTrue() +{ + return true; +} + diff --git a/tpl/RAJA/blt/tests/internal/src/Example.hpp b/tpl/RAJA/blt/tests/internal/src/Example.hpp new file mode 100644 index 000000000..d39936e64 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/Example.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef _EXAMPLE_HPP_ +#define _EXAMPLE_HPP_ + +#include "Example_Exports.h" + +//------------------------------------------------------------------------------ +class EXAMPLE_API Example +{ +public: + Example(); + ~Example(); + + bool ReturnTrue(); +}; +#endif diff --git a/tpl/RAJA/blt/tests/internal/src/Example_Exports.h b/tpl/RAJA/blt/tests/internal/src/Example_Exports.h new file mode 100644 index 000000000..6c5c9413c --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/Example_Exports.h @@ -0,0 +1,38 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef _EXAMPLE_EXPORTS_H_ +#define _EXAMPLE_EXPORTS_H_ + +//----------------------------------------------------------------------------- +// -- define proper lib exports for various platforms -- +//----------------------------------------------------------------------------- +#if defined(_WIN32) + #if defined(WIN32_SHARED_LIBS) + #if defined(EXAMPLE_EXPORTS) || defined(example_EXPORTS) + #define EXAMPLE_API __declspec(dllexport) + #else + #define EXAMPLE_API __declspec(dllimport) + #endif + #else + #define EXAMPLE_API /* not needed for static on windows */ + #endif + #if defined(_MSC_VER) + /* Turn off warning about lack of DLL interface */ + #pragma warning(disable:4251) + /* Turn off warning non-dll class is base for dll-interface class. */ + #pragma warning(disable:4275) + /* Turn off warning about identifier truncation */ + #pragma warning(disable:4786) + #endif +#else + #if __GNUC__ >= 4 && (defined(EXAMPLE_EXPORTS) || defined(example_EXPORTS)) + #define EXAMPLE_API __attribute__ ((visibility("default"))) + #else + #define EXAMPLE_API /* hidden by default */ + #endif +#endif + +#endif diff --git a/tpl/RAJA/blt/tests/internal/src/HeaderOnly.hpp b/tpl/RAJA/blt/tests/internal/src/HeaderOnly.hpp new file mode 100644 index 000000000..d23209473 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/HeaderOnly.hpp @@ -0,0 +1,19 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef BLT_HEADER_ONLY_HPP +#define BLT_HEADER_ONLY_HPP + +namespace blt +{ + +inline bool ReturnTrue() +{ + return true; +} + +} // end of namespace blt + +#endif diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/CMakeLists.txt b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/CMakeLists.txt new file mode 100644 index 000000000..8c097da3f --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/CMakeLists.txt @@ -0,0 +1,55 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +############################################################################### +# +# Simple example that uses the blt_combine_static_libraries macro +# +############################################################################### + +blt_add_library( NAME Foo1 + SOURCES Foo1.cpp + HEADERS Foo1.hpp + SHARED FALSE + ) + +blt_add_library( NAME Foo23 + SOURCES Foo2.cpp Foo3.cpp + HEADERS Foo2.hpp Foo3.hpp + SHARED FALSE + ) + +blt_combine_static_libraries( NAME FooStatic + SOURCE_LIBS Foo1 Foo23 + LIB_TYPE STATIC + LINK_PREPEND "" + LINK_POSTPEND "" + ) + +blt_add_executable( NAME blt_combine_static_libraries_static_smoke + SOURCES blt_combine_static_libraries_static_smoke.cpp + DEPENDS_ON FooStatic gtest + ) +blt_add_test( NAME blt_combine_static_libraries_static_smoke + COMMAND blt_combine_static_libraries_static_smoke + ) + +if(NOT WIN32) + blt_combine_static_libraries( NAME FooShared + SOURCE_LIBS Foo1 Foo23 + LIB_TYPE SHARED + LINK_PREPEND "" + LINK_POSTPEND "" + ) + + blt_add_executable( NAME blt_combine_static_libraries_shared_smoke + SOURCES blt_combine_static_libraries_shared_smoke.cpp + DEPENDS_ON FooShared gtest + ) + + blt_add_test( NAME blt_combine_static_libraries_shared_smoke + COMMAND blt_combine_static_libraries_shared_smoke + ) +endif() diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.cpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.cpp new file mode 100644 index 000000000..22b5e4df9 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include +#include "Foo1.hpp" + +namespace blt_test +{ + +Foo1::Foo1() +{ + // TODO Auto-generated constructor stub + +} + +Foo1::~Foo1() +{ + // TODO Auto-generated destructor stub +} + +std::string Foo1::output() +{ + return "I am Foo #1"; +} + +} /* namespace blt_test */ diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.hpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.hpp new file mode 100644 index 000000000..a6763fdbf --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo1.hpp @@ -0,0 +1,25 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO1_HPP_ +#define TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO1_HPP_ + +#include + +namespace blt_test +{ + +class Foo1 +{ +public: + Foo1(); + ~Foo1(); + + std::string output(); +}; + +} /* namespace blt_test */ + +#endif /* TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO1_HPP_ */ diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.cpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.cpp new file mode 100644 index 000000000..0075b7b67 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "Foo2.hpp" + +namespace blt_test +{ + +Foo2::Foo2() +{ + // TODO Auto-generated constructor stub + +} + +Foo2::~Foo2() +{ + // TODO Auto-generated destructor stub +} + +std::string Foo2::output() +{ + return "I am Foo #2"; +} + +} /* namespace blt_test */ diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.hpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.hpp new file mode 100644 index 000000000..d8a4b5199 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo2.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO2_HPP_ +#define TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO2_HPP_ + +#include + +namespace blt_test +{ + +class Foo2 +{ +public: + Foo2(); + ~Foo2(); + + std::string output(); + +}; + +} /* namespace blt_test */ + +#endif /* TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO2_HPP_ */ diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.cpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.cpp new file mode 100644 index 000000000..b500b77da --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "Foo3.hpp" + +namespace blt_test +{ + +Foo3::Foo3() +{ + // TODO Auto-generated constructor stub + +} + +Foo3::~Foo3() +{ + // TODO Auto-generated destructor stub +} + +std::string Foo3::output() +{ + return "I am Foo #3"; +} +} /* namespace blt_test */ diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.hpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.hpp new file mode 100644 index 000000000..e4aa72a43 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/Foo3.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO3_HPP_ +#define TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO3_HPP_ + +#include + +namespace blt_test +{ + +class Foo3 +{ +public: + Foo3(); + ~Foo3(); + + std::string output(); + +}; + +} /* namespace blt_test */ + +#endif /* TESTS_INTERNAL_SRC_COMBINE_STATIC_LIBRARY_TEST_FOO3_HPP_ */ diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_shared_smoke.cpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_shared_smoke.cpp new file mode 100644 index 000000000..01149851b --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_shared_smoke.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" +#include +#include +#include "Foo1.hpp" +#include "Foo2.hpp" +#include "Foo3.hpp" + +using namespace blt_test; +//------------------------------------------------------------------------------ +// Simple smoke test for gtest +//------------------------------------------------------------------------------ +TEST(blt_combine_static_library_smoke_static, test) +{ + Foo1 foo1; + Foo2 foo2; + Foo3 foo3; + + EXPECT_TRUE( foo1.output() == "I am Foo #1" ); + EXPECT_TRUE( foo2.output() == "I am Foo #2" ); + EXPECT_TRUE( foo3.output() == "I am Foo #3" ); +} + + diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_static_smoke.cpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_static_smoke.cpp new file mode 100644 index 000000000..01149851b --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/blt_combine_static_libraries_static_smoke.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" +#include +#include +#include "Foo1.hpp" +#include "Foo2.hpp" +#include "Foo3.hpp" + +using namespace blt_test; +//------------------------------------------------------------------------------ +// Simple smoke test for gtest +//------------------------------------------------------------------------------ +TEST(blt_combine_static_library_smoke_static, test) +{ + Foo1 foo1; + Foo2 foo2; + Foo3 foo3; + + EXPECT_TRUE( foo1.output() == "I am Foo #1" ); + EXPECT_TRUE( foo2.output() == "I am Foo #2" ); + EXPECT_TRUE( foo3.output() == "I am Foo #3" ); +} + + diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/dummy.cpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/dummy.cpp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/dummy.cpp @@ -0,0 +1 @@ + diff --git a/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/main.cpp b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/main.cpp new file mode 100644 index 000000000..3f0b0ce35 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/combine_static_library_test/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include +#include "Foo1.hpp" +#include "Foo2.hpp" + +using namespace blt_test; +int main( int, char ** ) +{ + Foo1 foo1; + Foo2 foo2; + Foo3 foo3; + + std::cout< + +int main() +{ + bool failed = false; + + int number = object_number(); + if(number != 6) + { + std::cerr << "Error:" + << number + << " was returned from all libraries." + << std::endl + << "6 was the correct number." + << std::endl; + failed = true; + } + else + { + std::cout << number + << " was correctly returned from all libraries." + << std::endl; + } + + int iNumber = inherited_number(); + if(iNumber != 3) + { + std::cerr << "Error:" + << iNumber + << " was returned from the inherited library." + << std::endl + << "3 was the correct number." + << std::endl; + failed = true; + } + else + { + std::cout << iNumber + << " was correctly returned from inherited library." + << std::endl; + } + + if (failed) + { + return 1; + } + return 0; +} diff --git a/tpl/RAJA/blt/tests/internal/src/object_library_test/object.cpp b/tpl/RAJA/blt/tests/internal/src/object_library_test/object.cpp new file mode 100644 index 000000000..0997719e8 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/object_library_test/object.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "base_object.hpp" +#include "object.hpp" + +int object_number() +{ + return 1 + base_number(); +} diff --git a/tpl/RAJA/blt/tests/internal/src/object_library_test/object.hpp b/tpl/RAJA/blt/tests/internal/src/object_library_test/object.hpp new file mode 100644 index 000000000..b8dcaf497 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/object_library_test/object.hpp @@ -0,0 +1,11 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef OBJECT_HPP +#define OBJECT_HPP + +int object_number(); + +#endif diff --git a/tpl/RAJA/blt/tests/internal/src/static_analysis/CMakeLists.txt b/tpl/RAJA/blt/tests/internal/src/static_analysis/CMakeLists.txt new file mode 100644 index 000000000..fc457bb1b --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/static_analysis/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +##################################### +# Test clang-query static analysis +# Clang Query needs to be enabled, with appropriate Flags set up for building and running +# your code +##################################### + +set(BLT_CLANG_QUERY_CHECKER_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/static_analysis_passes) +blt_add_executable( NAME well_analyzed_executable + SOURCES well_analyzed_source.cpp +) +blt_add_code_checks(PREFIX all + SOURCES well_analyzed_source.cpp) +blt_add_clang_query_target(NAME filtered CHECKERS "if-stmt" + SRC_FILES well_analyzed_source.cpp) + diff --git a/tpl/RAJA/blt/tests/internal/src/static_analysis/static_analysis_passes/if-stmt b/tpl/RAJA/blt/tests/internal/src/static_analysis/static_analysis_passes/if-stmt new file mode 100644 index 000000000..bb62251ce --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/static_analysis/static_analysis_passes/if-stmt @@ -0,0 +1 @@ +match ifStmt(isExpansionInMainFile()) diff --git a/tpl/RAJA/blt/tests/internal/src/static_analysis/well_analyzed_source.cpp b/tpl/RAJA/blt/tests/internal/src/static_analysis/well_analyzed_source.cpp new file mode 100644 index 000000000..ab7f6edd0 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/static_analysis/well_analyzed_source.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +/** + * This file contains sample code for clang-query to match + * + * When a target which analyzes the source code for if statements is run, + * the if statement should be highlighted. + * + * Some useful targets + * + * 1) "make filtered" + * + * Will run a matcher "match if-stmt" and produce the output + * + * [100%] Running specified clang_query source code static analysis checks. + * + * Match #1: + * + * /blt/root/dir/blt/tests/internal/src/static_analysis/well_analyzed_source.cpp:2:2: note: "root" binds here + * if(true){} + * ^~~~~~~~~~ + * 1 match. + * + * 2) "checker=interpreter make filtered" + * + * Will open up the clang-query REPL (Interpreter) and allow you to write your own queries in the language + * described here, but which can mostly be learned through tab completion in that interpreter: + * + * https://clang.llvm.org/docs/LibASTMatchersReference.html + */ +int main() +{ + if(true) {} +} diff --git a/tpl/RAJA/blt/tests/internal/src/t_example_compile_definitions.cpp b/tpl/RAJA/blt/tests/internal/src/t_example_compile_definitions.cpp new file mode 100644 index 000000000..3d0b185df --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/t_example_compile_definitions.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" + +//------------------------------------------------------------------------------ + +// Simple test that expects symbol BLT_A to be defined as a non-zero number +TEST(blt_compile_definitions,check_BLT_A_defined) +{ + #if BLT_A + SUCCEED(); + #else + FAIL() << "Compiler define A was not defined as a non-zero number"; + #endif +} + +// Simple test that expects symbol BLT_B to be defined +TEST(blt_compile_definitions,check_BLT_B_defined) +{ + #ifdef BLT_B + SUCCEED(); + #else + FAIL() << "Compiler define B was not defined"; + #endif +} diff --git a/tpl/RAJA/blt/tests/internal/src/t_example_smoke.cpp b/tpl/RAJA/blt/tests/internal/src/t_example_smoke.cpp new file mode 100644 index 000000000..caa2d17d9 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/t_example_smoke.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" +#include "Example.hpp" + +//------------------------------------------------------------------------------ + +TEST(blt_gtest_smoke,basic_assert_example) +{ + Example e; + + EXPECT_TRUE( e.ReturnTrue() ); +} diff --git a/tpl/RAJA/blt/tests/internal/src/t_git_macros_smoke.cpp.in b/tpl/RAJA/blt/tests/internal/src/t_git_macros_smoke.cpp.in new file mode 100644 index 000000000..327c8141f --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/t_git_macros_smoke.cpp.in @@ -0,0 +1,24 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" + +#include // for std::string + +TEST( blt_git_macros_smoke, basic_usage_test ) +{ + const std::string EXPECTED_TAG = "test-tag"; + const std::string ACTUAL_TAG = "@BLT_TEST_TAG@"; + EXPECT_EQ( EXPECTED_TAG, ACTUAL_TAG ); + + const std::string EXPECTED_BRANCH = "test-branch"; + const std::string ACTUAL_BRANCH = "@BLT_TEST_BRANCH@"; + EXPECT_EQ( EXPECTED_BRANCH, ACTUAL_BRANCH ); + + const std::string ACTUAL_HASHCODE = "@BLT_TEST_SHA1@"; + EXPECT_FALSE( ACTUAL_HASHCODE.empty() ); +} + + diff --git a/tpl/RAJA/blt/tests/internal/src/t_header_only_smoke.cpp b/tpl/RAJA/blt/tests/internal/src/t_header_only_smoke.cpp new file mode 100644 index 000000000..2aef8efc9 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/t_header_only_smoke.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" +#include "HeaderOnly.hpp" + +TEST(blt_header_only_smoke,basic_assert_example) +{ + EXPECT_TRUE( blt::ReturnTrue() ); +} diff --git a/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CMakeLists.txt b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CMakeLists.txt new file mode 100644 index 000000000..5e242f732 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +#------------------------------------------------------------------------------ +# Test CUDA virtual device method call from kernels across library boundary +# CUDA needs to be enabled, with appropriate Flags set up for building and +# running on your current GPU architecture. +#------------------------------------------------------------------------------ +set(t_cuda_device_call_from_kernel_headers + Child.hpp + Parent.hpp) + +set(t_cuda_device_call_from_kernel_sources + Child.cpp + Parent.cpp) + +blt_add_library(NAME t_cuda_device_call_from_kernel_lib + SOURCES ${t_cuda_device_call_from_kernel_sources} + HEADERS ${t_cuda_device_call_from_kernel_headers} + DEPENDS_ON cuda) + +set(t_cuda_device_call_from_kernel_exec_src + CudaTests.cpp) + +blt_add_executable( NAME t_cuda_device_call_from_kernel_exec + SOURCES ${t_cuda_device_call_from_kernel_exec_src} + DEPENDS_ON t_cuda_device_call_from_kernel_lib gtest cuda) + +blt_add_test(NAME t_cuda_device_call_from_kernel + COMMAND t_cuda_device_call_from_kernel_exec) + diff --git a/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.cpp b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.cpp new file mode 100644 index 000000000..03009801e --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include +#include "Child.hpp" + +__global__ void kernelCreateChild(Parent **myGpuParent, + double a, double b, + double c, double d) +{ + *myGpuParent = new Child(a, b, c, d); +} + +__host__ __device__ Child::Child(double a, double b, double c, double d) + : Parent("", 0) + , m_a(a) + , m_b(b) + , m_c(c) + , m_d(d) +{ + #ifndef __CUDA_ARCH__ + cudaMalloc(&(m_gpuParent), sizeof(Parent **)); + + kernelCreateChild<<<1,1>>>(m_gpuParent, a, b, c, d); + cudaDeviceSynchronize(); + #endif +} + +__host__ __device__ Child::~Child() +{ +} + +__host__ __device__ +double Child::Evaluate(const double ain, const double bin, + const double cin, const double din) const +{ + double bb, cc; + double e = 0.0; + + e = (din-m_d); + e = (ain-m_a); + e = (bin-m_b); + e = (cin-m_c); + bb = (bin-m_b); + cc = (cin-m_c); + e = sqrt(bb*bb+cc*cc); + + return e; +} diff --git a/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.hpp b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.hpp new file mode 100644 index 000000000..e148050bd --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Child.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef __Child_h +#define __Child_h + +#include "Parent.hpp" + +class Child : public Parent +{ +public: + __host__ __device__ Child(double a, double b, double c, double d); + + __host__ __device__ virtual ~Child() ; + + __host__ __device__ double Evaluate(const double ain, const double bin, + const double cin, const double din) const; + + __host__ __device__ inline double Evaluate(const double *args) const + { + return Evaluate(args[0], args[1], args[2], args[3]) ; + } + +private: + double m_a, m_b, m_c, m_d; +}; + +#endif diff --git a/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CudaTests.cpp b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CudaTests.cpp new file mode 100644 index 000000000..2ee6aa53d --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/CudaTests.cpp @@ -0,0 +1,38 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include +#include "Parent.hpp" +#include "Child.hpp" + +inline void gpuAssert(cudaError_t code, const char *file, int line, + bool abort=true) +{ + if (code != cudaSuccess) + { + fprintf(stderr, "GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); + if (abort) + { + exit(code); + } + } +} +__global__ void kernelApply(Parent** myGpuParent) +{ + double *input = new double[4]; + input[0] = 1.0; + input[1] = 2.0; + input[2] = 3.0; + input[3] = 4.0; + (*myGpuParent)->Evaluate(input); +} + +int main(void) +{ + Child *c = new Child(0.0, 0.0, 0.0, 0.0); + kernelApply<<<1, 1>>>(c->m_gpuParent); + gpuAssert(cudaDeviceSynchronize(),__FILE__,__LINE__); + return 0; +} diff --git a/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.cpp b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.cpp new file mode 100644 index 000000000..0ca76ce8a --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "Parent.hpp" +#include + +__host__ __device__ Parent::Parent(const char *id, int order) + : m_gpuParent(NULL) + , m_gpuExtractedParents(NULL) +{} + +__global__ void kernelDelete(Parent** myGpuParent) {} +__global__ void kernelDeleteExtracted(Parent*** gpuExtractedParents) {} + diff --git a/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.hpp b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.hpp new file mode 100644 index 000000000..eb10ee708 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/test_cuda_device_call_from_kernel/Parent.hpp @@ -0,0 +1,23 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#ifndef __Parent_h +#define __Parent_h + +class Parent +{ +public: + + Parent** m_gpuParent; + Parent*** m_gpuExtractedParents; + + __host__ __device__ Parent(const char *id, int order); + + __host__ __device__ virtual double Evaluate(const double * args) const = 0; + + +}; + +#endif diff --git a/tpl/RAJA/blt/tests/internal/src/test_cuda_mpi.cpp b/tpl/RAJA/blt/tests/internal/src/test_cuda_mpi.cpp new file mode 100644 index 000000000..975cc3439 --- /dev/null +++ b/tpl/RAJA/blt/tests/internal/src/test_cuda_mpi.cpp @@ -0,0 +1,418 @@ + +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Note: This is a simple CUDA/MPI example +// The program generates an arbitrarily (very) large array of floats, it +// initializes it only locally on the master MPI rank (rank 0) to the value 998. +// It then splits it into chunks that the master MPI rank sends to the slave +// ranks. Each rank will run individually a simple CUDA kernel that will add 1 +// to each element of their respective local array chunks and sends the +// modified array back to the master MPI rank, that will update the dataset. +// If all elements of the initial large array contain the value 999, the +// program has been completed successfully. If not, it will give you a +// detailed error. +// +// Technical notes: +// - This program uses hwloc for determining CPU and GPU affinities. +// - This program does NOT currently support MPI sends above INT_MAX elements. +// - Tested successfully on multiGPU/multiNode configurations. +// - MPI calls are in C99 style, although it is a C++ source code +// +// Code design notes: +// This program is a realistic example of what the skeleton of production +// codes using CUDA and MPI look like. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +// +// file: test_cuda_mpi.cpp +// +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// This macro is to report the CUDA errors it can detect in a nice readable form. +#define cuChk(call) \ + { \ + const cudaError_t cudaError = call; \ + if (cudaError != cudaSuccess) \ + { \ + printf("\nError %s: %d, ", __FILE__, __LINE__ ); \ + printf("Code %d, reason %s\n", cudaError, cudaGetErrorString(cudaError)); \ + exit(1); \ + } \ + } \ + +// Simple CUDA kernel adding 1 to each element of an existing array +__global__ void addOne(float* a, int bufsize) +{ + // The size_t type is needed to avoid memory address overflows with large arrays + size_t index = blockIdx.x * blockDim.x + threadIdx.x; + size_t stride = blockDim.x * gridDim.x; + size_t sbufsize = (size_t) bufsize; + for (size_t i = index; i < sbufsize; i+=stride) + { + a[i]+=1.f; + } +} + +int main(int argc, char **argv) +{ + hwloc_topology_t topology; + hwloc_cpuset_t cpuset; + // Initial values are set negative for early error detection. + int cpu = -1; int ii = -1; + int rank = -1, local_rank = -1, totalRanks = -1; + int cuDevice = -1; + + int Npower = 0; // Stores power of 2 for the number of elements + + // Do not mess with the following lines unless you know what you are doing + // -------------------------------------------------------------------------------------- + #ifdef OPEN_MPI + rank = atoi(std::getenv("OMPI_COMM_WORLD_RANK")); + local_rank = atoi(std::getenv("OMPI_COMM_WORLD_LOCAL_RANK")); + #endif + + #ifdef MPICH + rank = atoi(std::getenv("MV2_COMM_WORLD_RANK")); + local_rank = atoi(std::getenv("MV2_COMM_WORLD_LOCAL_RANK")); + #endif + + if (rank < 0 || local_rank < 0) + { + std::cout << "FATAL ERROR: MPI LIBRARY NOT SUPPORTED. EXITING ..." << std::endl; + std::cout << "This program only supports " + << "Open MPI, MPICH, MVAPICH2 and compatible" << std::endl; + exit(-1); + } + + // -------------------------------------------------------------------------------------- + + if (rank == 0) { std::cout << "*** Simple CUDA+MPI smoke test for BLT ***" << std::endl << std::endl; } + + hwloc_topology_init(&topology); // Creates a hwloc topology + // Gets the topology of the system, including attached devices + hwloc_topology_set_flags(topology, HWLOC_TOPOLOGY_FLAG_WHOLE_IO); + hwloc_topology_load(topology); + + int cuDevCount = 0; + cuChk(cudaGetDeviceCount(&cuDevCount)); + + // For each local rank (rank running on each node), select CUDA device number matching the rank number + cuChk(cudaSetDevice(local_rank % cuDevCount)); + cuChk(cudaGetDevice(&cuDevice)); // Get properties of the currently selected GPU + + // Select cores in node and get the logical processors near the selected GPU + cpuset = hwloc_bitmap_alloc(); + hwloc_cudart_get_device_cpuset(topology, cuDevice, cpuset); + + // Cycle through all logical processors in the cpuset. + // * NOTE: This is a preprocessor MACRO. No terminating semicolon. * + int match = 0; + hwloc_bitmap_foreach_begin(ii, cpuset) + + if (match == local_rank) + { + cpu = ii; + break; + } + // * NOTE: This is a preprocessor MACRO too, but needs a terminating semicolon. * + hwloc_bitmap_foreach_end(); + + hwloc_bitmap_t onecpu = hwloc_bitmap_alloc(); + hwloc_bitmap_set(onecpu, cpu); + hwloc_set_cpubind(topology, onecpu, 0); + + hwloc_bitmap_free(onecpu); + hwloc_bitmap_free(cpuset); + hwloc_topology_destroy(topology); + + char hostname[MPI_MAX_PROCESSOR_NAME]; + gethostname(hostname, sizeof(hostname)); + cpu = sched_getcpu(); + + + // -------------------------------- MPI REGION BEGINS + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &totalRanks); + char procname[MPI_MAX_PROCESSOR_NAME]; + int length; + if (MPI_SUCCESS != MPI_Get_processor_name(procname, &length)) + { + strcpy(procname, "unknown"); + } + + if (argc == 2) // If we have one exact command line argument ... + { + Npower = atoi(argv[1]); + } + else // else ignore everything + { + Npower = 10; // Sets a default value in case no command line argument is specified + } + size_t N = (size_t) 1 << Npower; // Allocates 2^Npower entries + size_t Nbytes = N * (size_t) sizeof(float); + + size_t cudaStreams = (size_t) totalRanks; + size_t sbufsize = (N/cudaStreams) + (N % cudaStreams); + + std::cout << "MPI rank " << rank << " using GPU " << cuDevice << " and CPU " << + cpu << " on host " << hostname << std::endl; + MPI_Barrier(MPI_COMM_WORLD); + + if ( rank == 0 && sbufsize > (size_t) INT_MAX ) + { + printf("Bufsize requested: %lu\n", sbufsize); + printf("Maximum bufsize currently supported: %d\n", INT_MAX); + printf("Retry to run the program with more MPI ranks\n"); + printf("Exiting ...\n\n\n"); + exit(-1); + } + int bufsize = (int) sbufsize; + + // CUDA Kernel run parameters + dim3 block(1024); + dim3 grid((bufsize+block.x-1)/block.x); + float *h_master; + + // Gets free and total memory of each GPU device + size_t devFreeMem, devTotMem; + cuChk( cudaMemGetInfo(&devFreeMem, &devTotMem) ); + + std::cout << "Device " << cuDevice << " on host " << hostname << " has " + << devFreeMem/(1 << 20) << " MB of free memory" << std::endl; + MPI_Barrier(MPI_COMM_WORLD); + + // Fills the master array with synthetic data (an array of ones) + if (rank == 0) + { + // This is some eye-candy to have dynamic units for memory + size_t szkB = (size_t) 1 << 10; + size_t szMB = (size_t) 1 << 20; + size_t szGB = (size_t) 1 << 30; + + char NbytesScale[4][3] = {" B", "kB", "MB", "GB"}; + int scaleIdx = 3; + size_t NbytesScaled = Nbytes/szGB; + if (NbytesScaled == 0) + { + NbytesScaled = Nbytes/szMB; + scaleIdx = 2; + if (NbytesScaled == 0) + { + NbytesScaled = Nbytes/szkB; + scaleIdx = 1; + if (Nbytes/szkB == 0) + { + NbytesScaled = Nbytes; + scaleIdx = 0; + } + } + } + std::cout << std::endl << "Elements in N: " << N << "\t Required memory: " + << NbytesScaled << " " << NbytesScale[scaleIdx] << std::endl; + h_master = (float *) malloc(Nbytes); + for (size_t i = 0U; i < N; ++i) + { + h_master[i] = 998.0f; + // Displays progress of filling the bigmem array as a percentage. + // * This eye-candy slows the process down a bit, but for large memory + // * allocations it will let you know if the program si stuck or is + // * actually doing something. + if (i % (1 << 24) == 0 || i > N - (1 << 2)) + { + size_t iN = ((i+1)*100)/N; + printf("Filling master array ... %lu%% completed. \r", iN); + } + } + std::cout << std::endl; + } + + // This is needed to allow the master array to fill before MPI Communication can occur safely + MPI_Barrier(MPI_COMM_WORLD); + // Uncomment below as needed + + if (rank == 0 ) // Some runtime info + { + std::cout << " INT_MAX = " << INT_MAX << std::endl; + std::cout << " bufsize = " << bufsize << std::endl; + std::cout << " bufByte = " << (size_t) (bufsize * sizeof(float)) << std::endl; + std::cout << "blockSize = " << block.x << std::endl; + std::cout << "numBlocks = " << grid.x << std::endl; + } + + + // rank-local variables for storing chunks of the master array + float *h_buf=NULL; + float *d_buf=NULL; + + + // No CUDA streams, no party! + cudaStream_t cuStreams[cudaStreams]; + cuChk(cudaStreamCreate(&cuStreams[rank])); + + // This is needed for pinned memory access + cuChk(cudaHostAlloc(&h_buf, bufsize * sizeof(float), cudaHostAllocPortable)); + cuChk(cudaMalloc(&d_buf, bufsize * sizeof(float))); + + cuChk(cudaMemGetInfo(&devFreeMem, &devTotMem)); + std::cout << "Device " << cuDevice << " on host " << hostname << " has " + << devFreeMem/(1<<20) << " MB of free memory" << std::endl; + + MPI_Request sreq, rreq; + + if (rank == 0) + { + for (int j = 1; j < totalRanks; j++) + { + for (size_t i = 0; i < sbufsize; ++i) + { + size_t Nchunk = i + sbufsize * (size_t) j; + if (Nchunk < N) + { + h_buf[i] = h_master[Nchunk]; + } + } + std::cout << "MPI_Isend from rank " << rank << " to rank " << j << " ... "; + MPI_Isend(h_buf, bufsize, MPI_FLOAT, j, 0, MPI_COMM_WORLD, &sreq); + MPI_Status mpiStatus; + MPI_Wait(&sreq, &mpiStatus); + std::cout << "Done!" << std::endl; + } + + for (size_t i = 0; i < sbufsize; ++i) + { + h_buf[i] = h_master[i]; + } + cuChk(cudaMemcpy(d_buf, h_buf, bufsize*sizeof(float), cudaMemcpyHostToDevice)); + std::cout << "Rank " << rank << ": launching CUDA kernels ... "; + addOne<<>>(d_buf, bufsize); + cudaError_t cuErr = cudaGetLastError(); + std::cout << cudaGetErrorString(cuErr) <>>(d_buf, bufsize); + cudaError_t cuErr = cudaGetLastError(); + std::cout << cudaGetErrorString(cuErr) < 0) + { + printf("Rank %d returns h_buf[%lu] = %10.5f\n", rank, i, h_buf[i]); + iErr--; + } + else + { + exit(-1); + } + } + } + + MPI_Request sreq; + MPI_Status mpiStatus; + std::cout << "Rank " << rank << " MPI_Isend to rank 0 ..."; + MPI_Isend(h_buf, bufsize, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, &sreq); + MPI_Wait(&sreq, &mpiStatus); + std::cout << "Done!" << std::endl; + } + + if (rank == 0) + { + for (int j = 1; j < totalRanks; j++) + { + MPI_Status mpiStatus; + MPI_Irecv(h_buf, bufsize, MPI_FLOAT, j, 0, MPI_COMM_WORLD, &rreq); + MPI_Wait(&rreq, &mpiStatus); + for (int bi = 0; bi < bufsize; bi++) + { + size_t bufIdx = (size_t) bi + (size_t) j * (size_t) (bufsize); + if (bufIdx < N) + { + h_master[bufIdx] = h_buf[bi]; + } + if (bufIdx >= N) { break; } + } + } + } + + MPI_Barrier(MPI_COMM_WORLD); + if (rank == 0) + { + int passedBool = 1; + int errLines = 10; + std::cout << "Validating the result ... "; + for (size_t i = 0; i < N; ++i) + { + if (h_master[i] != 999.0) + { + std::cout << "Something is wrong: h_master[" << i << "] = " << h_master[i] + << " instead of 999.0" << std::endl; + passedBool = 0; + errLines--; + if (errLines == 0) + { + MPI_Finalize(); + exit(-1); + } + } + } + if (passedBool) { std::cout << "PASSED!" << std::endl; } + } + + cuChk(cudaFree(d_buf)); + cuChk(cudaFreeHost(h_buf)); + if (rank == 0) { free(h_master); } + MPI_Finalize(); + return 0; +} diff --git a/tpl/RAJA/blt/tests/smoke/CMakeLists.txt b/tpl/RAJA/blt/tests/smoke/CMakeLists.txt new file mode 100644 index 000000000..88449a1fa --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/CMakeLists.txt @@ -0,0 +1,196 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +# +# Smoke tests for BLT TPLs +# + +################ +# gtest test +################ +if(ENABLE_GTEST) + blt_add_executable(NAME blt_gtest_smoke + SOURCES blt_gtest_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON gtest + FOLDER blt/tests ) + + blt_add_test( NAME blt_gtest_smoke + COMMAND blt_gtest_smoke) +endif() + +################ +# gmock test +################ +if(ENABLE_GMOCK) + blt_add_executable(NAME blt_gmock_smoke + SOURCES blt_gmock_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON gtest gmock + FOLDER blt/tests ) + + blt_add_test( NAME blt_gmock_smoke + COMMAND blt_gmock_smoke) +endif() + + +################ +# gbenchmark test +################ +if (ENABLE_BENCHMARKS) + blt_add_executable(NAME blt_gbenchmark_smoke + SOURCES blt_gbenchmark_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON gbenchmark + FOLDER blt/benchmarks ) + + blt_add_benchmark( NAME blt_gbenchmark_smoke + COMMAND blt_gbenchmark_smoke "--benchmark_min_time=0.0001") +endif() + + +################ +# fruit test +################ +if (ENABLE_FORTRAN AND ENABLE_FRUIT) + blt_add_executable(NAME blt_fruit_smoke + SOURCES blt_fruit_smoke.f90 + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON fruit + FOLDER blt/tests ) + + blt_add_test(NAME blt_fruit_smoke + COMMAND blt_fruit_smoke) +endif() + + +################ +# OpenMP test +################ +if (ENABLE_OPENMP) + # _blt_tutorial_openmp_executable_start + blt_add_executable(NAME blt_openmp_smoke + SOURCES blt_openmp_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON openmp + FOLDER blt/tests ) + # _blt_tutorial_openmp_executable_end + + # _blt_tutorial_openmp_test_start + blt_add_test(NAME blt_openmp_smoke + COMMAND blt_openmp_smoke + NUM_OMP_THREADS 4) + # _blt_tutorial_openmp_test_end +endif() + + +################ +# MPI test +################ +if (ENABLE_MPI) + blt_add_executable(NAME blt_mpi_smoke + SOURCES blt_mpi_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON mpi + FOLDER blt/tests ) + + blt_add_test(NAME blt_mpi_smoke + COMMAND blt_mpi_smoke + NUM_MPI_TASKS 4) +endif() + +################ +# CUDA tests +################ +if (ENABLE_CUDA) + blt_add_executable(NAME blt_cuda_smoke + SOURCES blt_cuda_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON cuda + FOLDER blt/tests ) + + blt_add_test(NAME blt_cuda_smoke + COMMAND blt_cuda_smoke) + + blt_add_executable(NAME blt_cuda_runtime_smoke + SOURCES blt_cuda_runtime_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON cuda_runtime + FOLDER blt/tests ) + + blt_add_test(NAME blt_cuda_runtime_smoke + COMMAND blt_cuda_runtime_smoke) + + if (ENABLE_OPENMP) + blt_add_executable(NAME blt_cuda_openmp_smoke + SOURCES blt_cuda_openmp_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON cuda openmp + FOLDER blt/tests ) + + blt_add_test(NAME blt_cuda_openmp_smoke + COMMAND blt_cuda_openmp_smoke) + endif() + + if (ENABLE_MPI) + blt_add_executable(NAME blt_cuda_mpi_smoke + SOURCES blt_cuda_mpi_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON cuda mpi + FOLDER blt/tests ) + blt_add_test(NAME blt_cuda_mpi_smoke + COMMAND blt_cuda_mpi_smoke + NUM_MPI_TASKS 4) + endif() +endif() + +################ +# HCC test +################ +if (ENABLE_HCC) + blt_add_executable(NAME blt_hcc_smoke + SOURCES blt_hcc_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON rocm + FOLDER blt/tests ) + + blt_add_test(NAME blt_hcc_smoke + COMMAND blt_hcc_smoke) + + blt_add_executable(NAME blt_hcc_runtime_smoke + SOURCES blt_hcc_runtime_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON rocm + FOLDER blt/tests ) + + blt_add_test(NAME blt_hcc_runtime_smoke + COMMAND blt_hcc_runtime_smoke) + + +endif() + +################ +# HIP test +################ +if (ENABLE_HIP) + blt_add_executable(NAME blt_hip_smoke + SOURCES blt_hip_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON hip + FOLDER blt/tests ) + + blt_add_test(NAME blt_hip_smoke + COMMAND blt_hip_smoke) + + blt_add_executable(NAME blt_hip_runtime_smoke + SOURCES blt_hip_runtime_smoke.cpp + OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} + DEPENDS_ON hip_runtime + FOLDER blt/tests ) + + blt_add_test(NAME blt_hip_runtime_smoke + COMMAND blt_hip_runtime_smoke) + +endif() diff --git a/tpl/RAJA/blt/tests/smoke/blt_cuda_mpi_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_cuda_mpi_smoke.cpp new file mode 100644 index 000000000..d1f0ed0e4 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_cuda_mpi_smoke.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Note: Parts of this are a CUDA Hello world example from NVIDIA: +// Obtained from here: https://developer.nvidia.com/cuda-education +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +// +// file: blt_cuda_mpi_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +__device__ const char *STR = "HELLO WORLD!"; +const char STR_LENGTH = 12; + +__global__ void hello() +{ + printf("%c\n", STR[threadIdx.x % STR_LENGTH]); +} + +int main(int argc, char** argv) +{ + // CUDA smoke test + int num_threads = STR_LENGTH; + int num_blocks = 1; + hello<<>>(); + cudaDeviceSynchronize(); + + // MPI smoke test + // Initialize MPI and get rank and comm size + MPI_Init(&argc, &argv); + + int commRank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &commRank); + int commSize = -1; + MPI_Comm_size(MPI_COMM_WORLD, &commSize); + + // Do a basic mpi reduce to determine this actually works + int globalValue = 0; + int valueToSend = 1; + MPI_Reduce(&valueToSend, &globalValue, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); + + // Finalize MPI + MPI_Finalize(); + + if (commRank == 0) + { + std::cout << "Count should be equal to rank size" << std::endl; + std::cout << "Count = " << globalValue << ", Size = " << commSize << std::endl; + + if (globalValue != commSize) + { + return 1; + } + } + + return 0; +} + + diff --git a/tpl/RAJA/blt/tests/smoke/blt_cuda_openmp_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_cuda_openmp_smoke.cpp new file mode 100644 index 000000000..d1532cb5e --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_cuda_openmp_smoke.cpp @@ -0,0 +1,54 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Note: Parts of this are a CUDA Hello world example from NVIDIA: +// Obtained from here: https://developer.nvidia.com/cuda-education +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +// +// file: blt_cuda_openmp_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +__device__ const char *STR = "HELLO WORLD!"; +const char STR_LENGTH = 12; + +__global__ void hello() +{ + printf("%c\n", STR[threadIdx.x % STR_LENGTH]); +} + +int main() +{ + // CUDA smoke test + int num_threads = STR_LENGTH; + int num_blocks = 1; + hello<<>>(); + cudaDeviceSynchronize(); + + // OpenMP smoke test + #pragma omp parallel + { + int thId = omp_get_thread_num(); + int thNum = omp_get_num_threads(); + int thMax = omp_get_max_threads(); + + #pragma omp critical + std::cout <<"\nMy thread id is: " << thId + <<"\nNum threads is: " << thNum + <<"\nMax threads is: " << thMax + << std::endl; + } + + return 0; +} + + diff --git a/tpl/RAJA/blt/tests/smoke/blt_cuda_runtime_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_cuda_runtime_smoke.cpp new file mode 100644 index 000000000..ccff05c56 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_cuda_runtime_smoke.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Note: This is a CUDA example from NVIDIA: +// Obtained from here: +// https://devblogs.nvidia.com/parallelforall/how-query-device-properties-and-handle-errors-cuda-cc/ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +// +// file: blt_cuda_runtime_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include "cuda_runtime_api.h" +#include + +int main() +{ + int nDevices; + + cudaGetDeviceCount(&nDevices); + for (int i = 0; i < nDevices; i++) + { + cudaDeviceProp prop; + cudaGetDeviceProperties(&prop, i); + printf("Device Number: %d\n", i); + printf(" Device name: %s\n", prop.name); + printf(" Memory Clock Rate (KHz): %d\n", + prop.memoryClockRate); + printf(" Memory Bus Width (bits): %d\n", + prop.memoryBusWidth); + printf(" Peak Memory Bandwidth (GB/s): %f\n\n", + 2.0*prop.memoryClockRate*(prop.memoryBusWidth/8)/1.0e6); + } + + return 0; +} + diff --git a/tpl/RAJA/blt/tests/smoke/blt_cuda_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_cuda_smoke.cpp new file mode 100644 index 000000000..a2c3d4e75 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_cuda_smoke.cpp @@ -0,0 +1,38 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Note: This is a CUDA Hello world example from NVIDIA: +// Obtained from here: https://developer.nvidia.com/cuda-education +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +// +// file: blt_cuda_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include + +__device__ const char *STR = "HELLO WORLD!"; +const char STR_LENGTH = 12; + +__global__ void hello() +{ + printf("%c\n", STR[threadIdx.x % STR_LENGTH]); +} + +int main() +{ + int num_threads = STR_LENGTH; + int num_blocks = 1; + hello<<>>(); + cudaDeviceSynchronize(); + + return 0; +} + + diff --git a/tpl/RAJA/blt/tests/smoke/blt_fruit_smoke.f90 b/tpl/RAJA/blt/tests/smoke/blt_fruit_smoke.f90 new file mode 100644 index 000000000..ad3b25c69 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_fruit_smoke.f90 @@ -0,0 +1,48 @@ +! Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +! other BLT Project Developers. See the top-level COPYRIGHT file for details +! +! SPDX-License-Identifier: (BSD-3-Clause) + +!------------------------------------------------------------------------------ +! +! blt_fruit_smoke.f90 +! +!------------------------------------------------------------------------------ +module fruit_smoke + use iso_c_binding + use fruit + implicit none + +contains +!------------------------------------------------------------------------------ + + subroutine simple_test + call assert_equals (42, 42) + end subroutine simple_test + + +!---------------------------------------------------------------------- +end module fruit_smoke +!---------------------------------------------------------------------- + +program fortran_test + use fruit + use fruit_smoke + implicit none + logical ok + + call init_fruit +!---------- +! Our tests + call simple_test +!---------- + + call fruit_summary + call fruit_finalize + call is_all_successful(ok) + if (.not. ok) then + call exit(1) + endif + +end program fortran_test + diff --git a/tpl/RAJA/blt/tests/smoke/blt_gbenchmark_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_gbenchmark_smoke.cpp new file mode 100644 index 000000000..357d99654 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_gbenchmark_smoke.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include + +//------------------------------------------------------------------------------ + +#define BASIC_BENCHMARK_TEST(x) \ + BENCHMARK(x)->Arg( 1<<3 )->Arg( 1<<9 )->Arg( 1 << 13 ) + +void benchmark_smoke_empty(benchmark::State& state) +{ + for (auto _ : state) + { + benchmark::DoNotOptimize(state.iterations()); + } +} +BENCHMARK(benchmark_smoke_empty); + + +void benchmark_smoke_spin_loop(benchmark::State& state) +{ + for (auto _ : state) + { + for (int i=0; i < state.range(0); ++i) + { + benchmark::DoNotOptimize(i); + } + } + state.SetItemsProcessed(state.iterations() * state.range(0)); + +} +BASIC_BENCHMARK_TEST(benchmark_smoke_spin_loop); + + +void benchmark_smoke_accum_loop(benchmark::State& state) +{ + for (auto _ : state) + { + int accum = 0; + for (int i=0; i < state.range(0); ++i) + { + accum += i; + } + benchmark::DoNotOptimize(accum); + } + state.SetItemsProcessed(state.iterations() * state.range(0)); + +} +BASIC_BENCHMARK_TEST(benchmark_smoke_accum_loop); + +BENCHMARK_MAIN(); + diff --git a/tpl/RAJA/blt/tests/smoke/blt_gmock_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_gmock_smoke.cpp new file mode 100644 index 000000000..c7fbc1320 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_gmock_smoke.cpp @@ -0,0 +1,79 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Interface to Mock +//------------------------------------------------------------------------------ +class Thing +{ +public: + virtual ~Thing() {} + virtual void Method() = 0; +}; + +//------------------------------------------------------------------------------ +// Interface User +//------------------------------------------------------------------------------ +class MethodCaller +{ +public: + MethodCaller(Thing *thing) + : m_thing(thing) + { + // empty + } + + void Go() + { + // call Method() on thing 2 times + m_thing->Method(); + m_thing->Method(); + } + +private: + Thing* m_thing; +}; + +//------------------------------------------------------------------------------ +// Mocked Interface +//------------------------------------------------------------------------------ +class MockThing : public Thing +{ +public: + MOCK_METHOD0(Method, void()); +}; + + +//------------------------------------------------------------------------------ +// Actual Test +//------------------------------------------------------------------------------ +using ::testing::AtLeast; +TEST(blt_gtest_smoke,basic_mock_test) +{ + MockThing m; + EXPECT_CALL(m, Method()).Times(AtLeast(2)); + + MethodCaller mcaller(&m); + + mcaller.Go(); +} + + +//------------------------------------------------------------------------------ +// Main Driver +//------------------------------------------------------------------------------ +int main(int argc, char** argv) +{ + // The following lines must be executed to initialize Google Test + // and Google Mock before running the tests. + ::testing::InitGoogleTest(&argc, argv); + ::testing::InitGoogleMock(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tpl/RAJA/blt/tests/smoke/blt_gtest_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_gtest_smoke.cpp new file mode 100644 index 000000000..6047be56b --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_gtest_smoke.cpp @@ -0,0 +1,35 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" +#include + + +//------------------------------------------------------------------------------ +// Simple smoke test for gtest +//------------------------------------------------------------------------------ +TEST(blt_gtest_smoke,basic_assert_example) +{ + EXPECT_TRUE( true ); +} + + +//------------------------------------------------------------------------------ +// Tests the gtest death test feature, which are disabled by default. +// +// Exits program with non-zero exit code, passing the test. +// Note: To enable death tests, configure BLT with ENABLE_GTEST_DEATH_TESTS. +//------------------------------------------------------------------------------ +TEST(blt_gtest_smoke,death_test) +{ + #if (GTEST_HAS_DEATH_TEST == 0) + std::cout <<"Note: Death tests disabled in this configuration." << std::endl; + #endif + + // Invoke death test function whether death tests enabled or disabled. + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + EXPECT_DEATH_IF_SUPPORTED( exit(1), ""); +} + diff --git a/tpl/RAJA/blt/tests/smoke/blt_hcc_runtime_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_hcc_runtime_smoke.cpp new file mode 100644 index 000000000..b45a08f34 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_hcc_runtime_smoke.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Note: This is a ROCm example from AMD: +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +// +// file: blt_hcc_runtime_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include +#include "hc.hpp" + +int main() +{ + using namespace hc; + accelerator acc; + std::vector accv = acc.get_all() ; + + std::cout << "Found " << accv.size() << " accelerators." << std::endl; + std::cout << std::endl; + + unsigned long idefault = 0; + for(unsigned long i=0; i< accv.size(); i++) + { + accelerator a = accv[i]; + std::cout << "Accelerator " << i << ": " ; + std::wcout << a.get_device_path() << L" : " << a.get_description(); + std::cout << " : " << (a.get_version()>>16) << "." + << (a.get_version()&0xff); + std::cout << std::endl; + if (a == acc) { idefault = i; } + } + + std::cout << std::endl; + std::cout << "Default Accelerator " << ": " << idefault << " : " ; + std::wcout << acc.get_device_path() << std::endl; + + return 0; +} + diff --git a/tpl/RAJA/blt/tests/smoke/blt_hcc_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_hcc_smoke.cpp new file mode 100644 index 000000000..48c2ceb08 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_hcc_smoke.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Note: This is a ROCM Hello world example from AMD: +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +// +// file: blt_hcc_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include + +int main() +{ + hc::parallel_for_each(hc::extent<1>(1), []() [[hc]] + { + hc::printf("Accelerator: Hello World!\n"); + }).wait(); + + return 0; +} + + diff --git a/tpl/RAJA/blt/tests/smoke/blt_hip_runtime_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_hip_runtime_smoke.cpp new file mode 100644 index 000000000..e908f1f0b --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_hip_runtime_smoke.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//----------------------------------------------------------------------------- +// +// file: blt_hip_runtime_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include "hip/hip_runtime_api.h" +#include + +int main() +{ + int nDevices; + + hipGetDeviceCount(&nDevices); + for (int i = 0; i < nDevices; i++) + { + hipDeviceProp_t prop; + hipGetDeviceProperties(&prop, i); + printf("Device Number: %d\n", i); + printf(" Device name: %s\n", prop.name); + printf(" Memory Clock Rate (KHz): %d\n", + prop.memoryClockRate); + printf(" Memory Bus Width (bits): %d\n", + prop.memoryBusWidth); + printf(" Peak Memory Bandwidth (GB/s): %f\n\n", + 2.0*prop.memoryClockRate*(prop.memoryBusWidth/8)/1.0e6); + } + + return 0; +} + diff --git a/tpl/RAJA/blt/tests/smoke/blt_hip_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_hip_smoke.cpp new file mode 100644 index 000000000..ac825099a --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_hip_smoke.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//----------------------------------------------------------------------------- +// +// file: blt_hip_smoke.cpp +// +//----------------------------------------------------------------------------- + +#include +#include +#include "hip/hip_runtime.h" + +__device__ const char *STR = "HELLO WORLD!"; +const char STR_LENGTH = 12; + +__global__ void hello() +{ + printf("%c\n", STR[threadIdx.x % STR_LENGTH]); +} + +int main() +{ + int num_threads = STR_LENGTH; + int num_blocks = 1; + hipLaunchKernelGGL((hello), dim3(num_blocks), dim3(num_threads),0,0); + hipDeviceSynchronize(); + + return 0; +} + + diff --git a/tpl/RAJA/blt/tests/smoke/blt_mpi_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_mpi_smoke.cpp new file mode 100644 index 000000000..967ed1f88 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_mpi_smoke.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +/*! + ******************************************************************************* + * \file blt_mpi_smoke.cpp + * \author Chris White (white238@llnl.gov) + ******************************************************************************* + */ + +#include +#include +#include + +//------------------------------------------------------------------------------ +int main(int argc, char** argv) +{ + // Initialize MPI and get rank and comm size + MPI_Init(&argc, &argv); + + int commRank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &commRank); + int commSize = -1; + MPI_Comm_size(MPI_COMM_WORLD, &commSize); + + // Do a basic mpi reduce to determine this actually works + int globalValue = 0; + int valueToSend = 1; + MPI_Reduce(&valueToSend, &globalValue, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); + + // Finalize MPI + MPI_Finalize(); + + if (commRank == 0) + { + std::cout << "Count should be equal to rank size" << std::endl; + std::cout << "Count = " << globalValue << ", Size = " << commSize << std::endl; + + if (globalValue != commSize) + { + return 1; + } + } + + return 0; +} diff --git a/tpl/RAJA/blt/tests/smoke/blt_openmp_smoke.cpp b/tpl/RAJA/blt/tests/smoke/blt_openmp_smoke.cpp new file mode 100644 index 000000000..74a5f0d68 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/blt_openmp_smoke.cpp @@ -0,0 +1,30 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include +#include + +/** + * Simple test program that uses OpenMP without guards. Should only be compiled when OpenMP is enabled. + */ +int main() +{ + + #pragma omp parallel + { + int thId = omp_get_thread_num(); + int thNum = omp_get_num_threads(); + int thMax = omp_get_max_threads(); + + #pragma omp critical + std::cout <<"\nMy thread id is: " << thId + <<"\nNum threads is: " << thNum + <<"\nMax threads is: " << thMax + << std::endl; + } + + return 0; +} + diff --git a/tpl/RAJA/blt/tests/smoke/fortran_driver.cpp b/tpl/RAJA/blt/tests/smoke/fortran_driver.cpp new file mode 100644 index 000000000..489009785 --- /dev/null +++ b/tpl/RAJA/blt/tests/smoke/fortran_driver.cpp @@ -0,0 +1,17 @@ +// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +// other BLT Project Developers. See the top-level COPYRIGHT file for details +// +// SPDX-License-Identifier: (BSD-3-Clause) + +//---------------------------------------------------------------------- +extern "C" int fortran_test(); + +int main() +{ + int result = 0; + + // finalized when exiting main scope + result = fortran_test(); + + return result; +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/CMakeLists.txt new file mode 100644 index 000000000..c49c12485 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/CMakeLists.txt @@ -0,0 +1,172 @@ +# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and +# other BLT Project Developers. See the top-level COPYRIGHT file for details +# +# SPDX-License-Identifier: (BSD-3-Clause) + +set(_blt_tpl_targets) # tracks names of enabled tpl targets + +if(ENABLE_TESTS) + include(CTest) + + # Note: Users can pass extra compiler flags to gtest + # with the 'gtest_extra_flags' variable and extra + # compile definitions with the 'gtest_defines' variable. + + + # The following flag should be added to gtest's dependents, + # but not to gtest in shared Windows builds + if(WIN32 AND BUILD_SHARED_LIBS) + list(APPEND gtest_export_defines "-DGTEST_LINKED_AS_SHARED_LIBRARY=1") + endif() + + # Explicitly enable/disable death tests + if(ENABLE_GTEST_DEATH_TESTS) + list(APPEND gtest_defines "-DGTEST_HAS_DEATH_TEST=1") + else() + list(APPEND gtest_defines "-DGTEST_HAS_DEATH_TEST=0") + endif() + + if(gtest_disable_pthreads) + list(APPEND gtest_defines "-DGTEST_HAS_PTHREAD=0") + endif() + + # + # Use BLT's ENABLE_GMOCK option to set the build options for + # gtest's cmake project + # + + if(ENABLE_GMOCK) + + # In BLT ENABLE_GMOCK implies ENABLE_GTEST, + # IF ENABLE_GTEST is OFF, force to ON + if(NOT ENABLE_GTEST) + set(ENABLE_GTEST ON CACHE BOOL "") + endif() + + set(BUILD_GMOCK ON CACHE BOOL "") + set(BUILD_GTEST OFF CACHE BOOL "") + else() + set(BUILD_GMOCK OFF CACHE BOOL "") + set(BUILD_GTEST ON CACHE BOOL "") + endif() + + message(STATUS "Google Test Support is ${ENABLE_GTEST}") + message(STATUS "Google Mock Support is ${ENABLE_GMOCK}") + + # + # Guard of googletest w/ ENABLE_GTEST + # In BLT, ENABLE_GTEST is also required when using ENABLE_GMOCK + # + + if(ENABLE_GTEST) + + if(CMAKE_CXX_STANDARD LESS 11) + message(WARNING "C++11 is required to compile gtest or gmock.") + endif() + + # + # gtest 1.8 emits many warnings related to dll-interface + # issues on windows, so we add flags to work around these + # warnings, so they don't mask warnings we care about + # + # For more info see: https://github.com/LLNL/blt/issues/79 + # + + blt_append_custom_compiler_flag( FLAGS_VAR gtest_extra_flags + DEFAULT " " + MSVC "/wd4251" "/wd4275" ) + + set (INSTALL_GMOCK OFF CACHE BOOL "") + set (INSTALL_GTEST OFF CACHE BOOL "") + + # Enable builtin google test + add_subdirectory(googletest-master-2020-01-07 + ${BLT_BUILD_DIR}/thirdparty_builtin/googletest-master-2020-01-07) + + if(UNIX AND NOT APPLE) + find_package( Threads ) + set(gtest_extra_libs ${CMAKE_THREAD_LIBS_INIT}) + endif() + + blt_register_library(NAME gtest + INCLUDES ${gtest_SOURCE_DIR}/include + LIBRARIES gtest_main gtest ${gtest_extra_libs} + COMPILE_FLAGS ${gtest_extra_flags} + DEFINES ${gtest_defines} ${gtest_export_defines} + TREAT_INCLUDES_AS_SYSTEM ON + ) + + blt_add_target_definitions(TO gtest TARGET_DEFINITIONS ${gtest_defines}) + + list(APPEND _blt_tpl_targets gtest gtest_main) + + if(ENABLE_GMOCK) + blt_register_library(NAME gmock + INCLUDES ${gmock_SOURCE_DIR}/include + LIBRARIES gmock_main gmock + COMPILE_FLAGS ${gtest_extra_flags} + DEFINES ${gtest_defines} + TREAT_INCLUDES_AS_SYSTEM ON + ) + list(APPEND _blt_tpl_targets gmock gmock_main) + endif() + endif() + + # Enable Fruit (FortRan UnIT testing) support + if (ENABLE_FORTRAN) + message(STATUS "Fruit Support is ${ENABLE_FRUIT}") + if(ENABLE_FRUIT) + add_subdirectory(fruit-3.4.1 + ${BLT_BUILD_DIR}/thirdparty_builtin/fruit-3.4.1) + list(APPEND _blt_tpl_targets fruit) + endif() + endif() + +endif() + +if(ENABLE_BENCHMARKS) + if(NOT ENABLE_TESTS) + message(FATAL_ERROR "ENABLE_BENCHMARKS requires ENABLE_TESTS to be ON") + endif() + + message(STATUS "Google Benchmark Support is ${ENABLE_GBENCHMARK}") + + if(ENABLE_GBENCHMARK) + if(WIN32 AND BUILD_SHARED_LIBS) + message(FATAL_ERROR "Google Benchmark cannot be built when BUILD_SHARED_LIBS=ON or on Windows") + endif() + + if(CMAKE_CXX_STANDARD LESS 11) + message(WARNING "C++11 is required to compile gbenchmark.") + endif() + + set(BENCHMARK_ENABLE_TESTING OFF CACHE "" BOOL) + add_subdirectory(benchmark-1.5.0 + ${BLT_BUILD_DIR}/thirdparty_builtin/benchmark-1.5.0) + + if (UNIX AND NOT APPLE) + find_library(RT_LIBRARIES rt) + endif() + + blt_register_library(NAME gbenchmark + INCLUDES ${benchmark_SOURCE_DIR}/include ${benchmark_SOURCE_DIR} + LIBRARIES benchmark ${RT_LIBRARIES} + TREAT_INCLUDES_AS_SYSTEM ON) + + list(APPEND _blt_tpl_targets gbenchmark) + endif() + + # This sets up a target to run the benchmarks + add_custom_target(${BLT_RUN_BENCHMARKS_TARGET_NAME} + COMMAND ctest -C Benchmark -VV + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) +endif() + +# Set the folder property of the blt thirdparty libraries +if(ENABLE_FOLDERS) + foreach(tpl ${_blt_tpl_targets}) + blt_set_target_folder(TARGET ${tpl} FOLDER blt/thirdparty) + endforeach() +endif() + + diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.clang-format b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.clang-format new file mode 100644 index 000000000..e7d00feaa --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.clang-format @@ -0,0 +1,5 @@ +--- +Language: Cpp +BasedOnStyle: Google +PointerAlignment: Left +... diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.gitignore b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.gitignore new file mode 100644 index 000000000..806d04c6b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.gitignore @@ -0,0 +1,61 @@ +*.a +*.so +*.so.?* +*.dll +*.exe +*.dylib +*.cmake +!/cmake/*.cmake +!/test/AssemblyTests.cmake +*~ +*.pyc +__pycache__ + +# lcov +*.lcov +/lcov + +# cmake files. +/Testing +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake + +# makefiles. +Makefile + +# in-source build. +bin/ +lib/ +/test/*_test + +# exuberant ctags. +tags + +# YouCompleteMe configuration. +.ycm_extra_conf.pyc + +# ninja generated files. +.ninja_deps +.ninja_log +build.ninja +install_manifest.txt +rules.ninja + +# bazel output symlinks. +bazel-* + +# out-of-source build top-level folders. +build/ +_build/ +build*/ + +# in-source dependencies +/googletest/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +CMakeSettings.json + +# Visual Studio Code cache/options directory +.vscode/ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis-libcxx-setup.sh b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis-libcxx-setup.sh new file mode 100644 index 000000000..a591743c6 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis-libcxx-setup.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Install a newer CMake version +curl -sSL https://cmake.org/files/v3.6/cmake-3.6.1-Linux-x86_64.sh -o install-cmake.sh +chmod +x install-cmake.sh +sudo ./install-cmake.sh --prefix=/usr/local --skip-license + +# Checkout LLVM sources +git clone --depth=1 https://github.com/llvm-mirror/llvm.git llvm-source +git clone --depth=1 https://github.com/llvm-mirror/libcxx.git llvm-source/projects/libcxx +git clone --depth=1 https://github.com/llvm-mirror/libcxxabi.git llvm-source/projects/libcxxabi + +# Setup libc++ options +if [ -z "$BUILD_32_BITS" ]; then + export BUILD_32_BITS=OFF && echo disabling 32 bit build +fi + +# Build and install libc++ (Use unstable ABI for better sanitizer coverage) +mkdir llvm-build && cd llvm-build +cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr \ + -DLIBCXX_ABI_UNSTABLE=ON \ + -DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \ + -DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \ + ../llvm-source +make cxx -j2 +sudo make install-cxxabi install-cxx +cd ../ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis.yml b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis.yml new file mode 100644 index 000000000..6b6cfc704 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.travis.yml @@ -0,0 +1,235 @@ +sudo: required +dist: trusty +language: cpp + +env: + global: + - /usr/local/bin:$PATH + +matrix: + include: + - compiler: gcc + addons: + apt: + packages: + - lcov + env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Coverage + - compiler: gcc + env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Debug + - compiler: gcc + env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Release + - compiler: gcc + addons: + apt: + packages: + - g++-multilib + - libc6:i386 + env: + - COMPILER=g++ + - C_COMPILER=gcc + - BUILD_TYPE=Debug + - BUILD_32_BITS=ON + - EXTRA_FLAGS="-m32" + - compiler: gcc + addons: + apt: + packages: + - g++-multilib + - libc6:i386 + env: + - COMPILER=g++ + - C_COMPILER=gcc + - BUILD_TYPE=Release + - BUILD_32_BITS=ON + - EXTRA_FLAGS="-m32" + - compiler: gcc + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=g++-6 C_COMPILER=gcc-6 BUILD_TYPE=Debug + - ENABLE_SANITIZER=1 + - EXTRA_FLAGS="-fno-omit-frame-pointer -g -O2 -fsanitize=undefined,address -fuse-ld=gold" + - compiler: clang + env: COMPILER=clang++ C_COMPILER=clang BUILD_TYPE=Debug + - compiler: clang + env: COMPILER=clang++ C_COMPILER=clang BUILD_TYPE=Release + # Clang w/ libc++ + - compiler: clang + dist: xenial + addons: + apt: + packages: + clang-3.8 + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug + - LIBCXX_BUILD=1 + - EXTRA_CXX_FLAGS="-stdlib=libc++" + - compiler: clang + dist: xenial + addons: + apt: + packages: + clang-3.8 + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release + - LIBCXX_BUILD=1 + - EXTRA_CXX_FLAGS="-stdlib=libc++" + # Clang w/ 32bit libc++ + - compiler: clang + dist: xenial + addons: + apt: + packages: + - clang-3.8 + - g++-multilib + - libc6:i386 + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug + - LIBCXX_BUILD=1 + - BUILD_32_BITS=ON + - EXTRA_FLAGS="-m32" + - EXTRA_CXX_FLAGS="-stdlib=libc++" + # Clang w/ 32bit libc++ + - compiler: clang + dist: xenial + addons: + apt: + packages: + - clang-3.8 + - g++-multilib + - libc6:i386 + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release + - LIBCXX_BUILD=1 + - BUILD_32_BITS=ON + - EXTRA_FLAGS="-m32" + - EXTRA_CXX_FLAGS="-stdlib=libc++" + # Clang w/ libc++, ASAN, UBSAN + - compiler: clang + dist: xenial + addons: + apt: + packages: + clang-3.8 + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug + - LIBCXX_BUILD=1 LIBCXX_SANITIZER="Undefined;Address" + - ENABLE_SANITIZER=1 + - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=undefined,address -fno-sanitize-recover=all" + - EXTRA_CXX_FLAGS="-stdlib=libc++" + - UBSAN_OPTIONS=print_stacktrace=1 + # Clang w/ libc++ and MSAN + - compiler: clang + dist: xenial + addons: + apt: + packages: + clang-3.8 + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug + - LIBCXX_BUILD=1 LIBCXX_SANITIZER=MemoryWithOrigins + - ENABLE_SANITIZER=1 + - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=memory -fsanitize-memory-track-origins" + - EXTRA_CXX_FLAGS="-stdlib=libc++" + # Clang w/ libc++ and MSAN + - compiler: clang + dist: xenial + addons: + apt: + packages: + clang-3.8 + env: + - INSTALL_GCC6_FROM_PPA=1 + - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=RelWithDebInfo + - LIBCXX_BUILD=1 LIBCXX_SANITIZER=Thread + - ENABLE_SANITIZER=1 + - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all" + - EXTRA_CXX_FLAGS="-stdlib=libc++" + - os: osx + osx_image: xcode8.3 + compiler: clang + env: + - COMPILER=clang++ BUILD_TYPE=Debug + - os: osx + osx_image: xcode8.3 + compiler: clang + env: + - COMPILER=clang++ BUILD_TYPE=Release + - os: osx + osx_image: xcode8.3 + compiler: clang + env: + - COMPILER=clang++ + - BUILD_TYPE=Release + - BUILD_32_BITS=ON + - EXTRA_FLAGS="-m32" + - os: osx + osx_image: xcode8.3 + compiler: gcc + env: + - COMPILER=g++-7 C_COMPILER=gcc-7 BUILD_TYPE=Debug + +before_script: + - if [ -n "${LIBCXX_BUILD}" ]; then + source .travis-libcxx-setup.sh; + fi + - if [ -n "${ENABLE_SANITIZER}" ]; then + export EXTRA_OPTIONS="-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF"; + else + export EXTRA_OPTIONS=""; + fi + - mkdir -p build && cd build + +before_install: + - if [ -z "$BUILD_32_BITS" ]; then + export BUILD_32_BITS=OFF && echo disabling 32 bit build; + fi + - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then + sudo add-apt-repository -y "ppa:ubuntu-toolchain-r/test"; + sudo apt-get update --option Acquire::Retries=100 --option Acquire::http::Timeout="60"; + fi + +install: + - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then + travis_wait sudo -E apt-get -yq --no-install-suggests --no-install-recommends install g++-6; + fi + - if [ "${TRAVIS_OS_NAME}" == "linux" -a "${BUILD_32_BITS}" == "OFF" ]; then + travis_wait sudo -E apt-get -y --no-install-suggests --no-install-recommends install llvm-3.9-tools; + sudo cp /usr/lib/llvm-3.9/bin/FileCheck /usr/local/bin/; + fi + - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then + PATH=~/.local/bin:${PATH}; + pip install --user --upgrade pip; + travis_wait pip install --user cpp-coveralls; + fi + - if [ "${C_COMPILER}" == "gcc-7" -a "${TRAVIS_OS_NAME}" == "osx" ]; then + rm -f /usr/local/include/c++; + brew update; + travis_wait brew install gcc@7; + fi + - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then + sudo apt-get update -qq; + sudo apt-get install -qq unzip cmake3; + wget https://github.com/bazelbuild/bazel/releases/download/0.10.1/bazel-0.10.1-installer-linux-x86_64.sh --output-document bazel-installer.sh; + travis_wait sudo bash bazel-installer.sh; + fi + - if [ "${TRAVIS_OS_NAME}" == "osx" ]; then + curl -L -o bazel-installer.sh https://github.com/bazelbuild/bazel/releases/download/0.10.1/bazel-0.10.1-installer-darwin-x86_64.sh; + travis_wait sudo bash bazel-installer.sh; + fi + +script: + - cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_C_FLAGS="${EXTRA_FLAGS}" -DCMAKE_CXX_FLAGS="${EXTRA_FLAGS} ${EXTRA_CXX_FLAGS}" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBENCHMARK_BUILD_32_BITS=${BUILD_32_BITS} ${EXTRA_OPTIONS} .. + - make + - ctest -C ${BUILD_TYPE} --output-on-failure + - bazel test -c dbg --define google_benchmark.have_regex=posix --announce_rc --verbose_failures --test_output=errors --keep_going //test/... + +after_success: + - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then + coveralls --include src --include include --gcov-options '\-lp' --root .. --build-root .; + fi diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.ycm_extra_conf.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.ycm_extra_conf.py new file mode 100644 index 000000000..5649ddcc7 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/.ycm_extra_conf.py @@ -0,0 +1,115 @@ +import os +import ycm_core + +# These are the compilation flags that will be used in case there's no +# compilation database set (by default, one is not set). +# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. +flags = [ +'-Wall', +'-Werror', +'-pedantic-errors', +'-std=c++0x', +'-fno-strict-aliasing', +'-O3', +'-DNDEBUG', +# ...and the same thing goes for the magic -x option which specifies the +# language that the files to be compiled are written in. This is mostly +# relevant for c++ headers. +# For a C project, you would set this to 'c' instead of 'c++'. +'-x', 'c++', +'-I', 'include', +'-isystem', '/usr/include', +'-isystem', '/usr/local/include', +] + + +# Set this to the absolute path to the folder (NOT the file!) containing the +# compile_commands.json file to use that instead of 'flags'. See here for +# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html +# +# Most projects will NOT need to set this to anything; you can just change the +# 'flags' list of compilation flags. Notice that YCM itself uses that approach. +compilation_database_folder = '' + +if os.path.exists( compilation_database_folder ): + database = ycm_core.CompilationDatabase( compilation_database_folder ) +else: + database = None + +SOURCE_EXTENSIONS = [ '.cc' ] + +def DirectoryOfThisScript(): + return os.path.dirname( os.path.abspath( __file__ ) ) + + +def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): + if not working_directory: + return list( flags ) + new_flags = [] + make_next_absolute = False + path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] + for flag in flags: + new_flag = flag + + if make_next_absolute: + make_next_absolute = False + if not flag.startswith( '/' ): + new_flag = os.path.join( working_directory, flag ) + + for path_flag in path_flags: + if flag == path_flag: + make_next_absolute = True + break + + if flag.startswith( path_flag ): + path = flag[ len( path_flag ): ] + new_flag = path_flag + os.path.join( working_directory, path ) + break + + if new_flag: + new_flags.append( new_flag ) + return new_flags + + +def IsHeaderFile( filename ): + extension = os.path.splitext( filename )[ 1 ] + return extension in [ '.h', '.hxx', '.hpp', '.hh' ] + + +def GetCompilationInfoForFile( filename ): + # The compilation_commands.json file generated by CMake does not have entries + # for header files. So we do our best by asking the db for flags for a + # corresponding source file, if any. If one exists, the flags for that file + # should be good enough. + if IsHeaderFile( filename ): + basename = os.path.splitext( filename )[ 0 ] + for extension in SOURCE_EXTENSIONS: + replacement_file = basename + extension + if os.path.exists( replacement_file ): + compilation_info = database.GetCompilationInfoForFile( + replacement_file ) + if compilation_info.compiler_flags_: + return compilation_info + return None + return database.GetCompilationInfoForFile( filename ) + + +def FlagsForFile( filename, **kwargs ): + if database: + # Bear in mind that compilation_info.compiler_flags_ does NOT return a + # python list, but a "list-like" StringVec object + compilation_info = GetCompilationInfoForFile( filename ) + if not compilation_info: + return None + + final_flags = MakeRelativePathsInFlagsAbsolute( + compilation_info.compiler_flags_, + compilation_info.compiler_working_dir_ ) + else: + relative_to = DirectoryOfThisScript() + final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) + + return { + 'flags': final_flags, + 'do_cache': True + } diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/AUTHORS b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/AUTHORS new file mode 100644 index 000000000..912cbbc13 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/AUTHORS @@ -0,0 +1,51 @@ +# This is the official list of benchmark authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. +# +# Names should be added to this file as: +# Name or Organization +# The email address is not required for organizations. +# +# Please keep the list sorted. + +Albert Pretorius +Alex Steele +Andriy Berestovskyy +Arne Beer +Carto +Christopher Seymour +Daniel Harvey +David Coeurjolly +Deniz Evrenci +Dirac Research +Dominik Czarnota +Eric Fiselier +Eugene Zhuk +Evgeny Safronov +Federico Ficarelli +Felix Homann +Google Inc. +International Business Machines Corporation +Ismael Jimenez Martinez +Jern-Kuan Leong +JianXiong Zhou +Joao Paulo Magalhaes +Jussi Knuuttila +Kaito Udagawa +Kishan Kumar +Lei Xu +Matt Clarkson +Maxim Vafin +MongoDB Inc. +Nick Hutchinson +Oleksandr Sochka +Ori Livneh +Paul Redmond +Radoslav Yovchev +Roman Lebedev +Shuo Chen +Steinar H. Gunderson +Stripe, Inc. +Yixuan Qiu +Yusuke Suzuki +Zbigniew Skowron diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/BUILD.bazel b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/BUILD.bazel new file mode 100644 index 000000000..6ee69f290 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/BUILD.bazel @@ -0,0 +1,42 @@ +licenses(["notice"]) + +config_setting( + name = "windows", + values = { + "cpu": "x64_windows", + }, + visibility = [":__subpackages__"], +) + +cc_library( + name = "benchmark", + srcs = glob( + [ + "src/*.cc", + "src/*.h", + ], + exclude = ["src/benchmark_main.cc"], + ), + hdrs = ["include/benchmark/benchmark.h"], + linkopts = select({ + ":windows": ["-DEFAULTLIB:shlwapi.lib"], + "//conditions:default": ["-pthread"], + }), + strip_include_prefix = "include", + visibility = ["//visibility:public"], +) + +cc_library( + name = "benchmark_main", + srcs = ["src/benchmark_main.cc"], + hdrs = ["include/benchmark/benchmark.h"], + strip_include_prefix = "include", + visibility = ["//visibility:public"], + deps = [":benchmark"], +) + +cc_library( + name = "benchmark_internal_headers", + hdrs = glob(["src/*.h"]), + visibility = ["//test:__pkg__"], +) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CMakeLists.txt new file mode 100644 index 000000000..d115ede39 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CMakeLists.txt @@ -0,0 +1,274 @@ +foreach(p + CMP0048 # OK to clear PROJECT_VERSION on project() + CMP0054 # CMake 3.1 + CMP0056 # export EXE_LINKER_FLAGS to try_run + CMP0057 # Support no if() IN_LIST operator + CMP0063 # Honor visibility properties for all targets + ) + if(POLICY ${p}) + cmake_policy(SET ${p} NEW) + endif() +endforeach() + +project (benchmark CXX) + +option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON) +option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON) +option(BENCHMARK_ENABLE_LTO "Enable link time optimisation of the benchmark library." OFF) +option(BENCHMARK_USE_LIBCXX "Build and test using libc++ as the standard library." OFF) +if(NOT MSVC) + option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF) +else() + set(BENCHMARK_BUILD_32_BITS OFF CACHE BOOL "Build a 32 bit version of the library - unsupported when using MSVC)" FORCE) +endif() +option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON) + +# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which +# may require downloading the source code. +option(BENCHMARK_DOWNLOAD_DEPENDENCIES "Allow the downloading and in-tree building of unmet dependencies" OFF) + +# This option can be used to disable building and running unit tests which depend on gtest +# in cases where it is not possible to build or find a valid version of gtest. +option(BENCHMARK_ENABLE_GTEST_TESTS "Enable building the unit tests which depend on gtest" ON) + +set(ENABLE_ASSEMBLY_TESTS_DEFAULT OFF) +function(should_enable_assembly_tests) + if(CMAKE_BUILD_TYPE) + string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) + if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage") + # FIXME: The --coverage flag needs to be removed when building assembly + # tests for this to work. + return() + endif() + endif() + if (MSVC) + return() + elseif(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + return() + elseif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + # FIXME: Make these work on 32 bit builds + return() + elseif(BENCHMARK_BUILD_32_BITS) + # FIXME: Make these work on 32 bit builds + return() + endif() + find_program(LLVM_FILECHECK_EXE FileCheck) + if (LLVM_FILECHECK_EXE) + set(LLVM_FILECHECK_EXE "${LLVM_FILECHECK_EXE}" CACHE PATH "llvm filecheck" FORCE) + message(STATUS "LLVM FileCheck Found: ${LLVM_FILECHECK_EXE}") + else() + message(STATUS "Failed to find LLVM FileCheck") + return() + endif() + set(ENABLE_ASSEMBLY_TESTS_DEFAULT ON PARENT_SCOPE) +endfunction() +should_enable_assembly_tests() + +# This option disables the building and running of the assembly verification tests +option(BENCHMARK_ENABLE_ASSEMBLY_TESTS "Enable building and running the assembly tests" + ${ENABLE_ASSEMBLY_TESTS_DEFAULT}) + +# Make sure we can import out CMake functions +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + + +# Read the git tags to determine the project version +include(GetGitVersion) +get_git_version(GIT_VERSION) + +# Tell the user what versions we are using +string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION ${GIT_VERSION}) +message(STATUS "Version: ${VERSION}") + +# The version of the libraries +set(GENERIC_LIB_VERSION ${VERSION}) +string(SUBSTRING ${VERSION} 0 1 GENERIC_LIB_SOVERSION) + +# Import our CMake modules +include(CheckCXXCompilerFlag) +include(AddCXXCompilerFlag) +include(CXXFeatureCheck) + +if (BENCHMARK_BUILD_32_BITS) + add_required_cxx_compiler_flag(-m32) +endif() + +if (MSVC) + # Turn compiler warnings up to 11 + string(REGEX REPLACE "[-/]W[1-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + + if (NOT BENCHMARK_ENABLE_EXCEPTIONS) + add_cxx_compiler_flag(-EHs-) + add_cxx_compiler_flag(-EHa-) + add_definitions(-D_HAS_EXCEPTIONS=0) + endif() + # Link time optimisation + if (BENCHMARK_ENABLE_LTO) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL") + set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG") + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") + + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL") + string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}") + set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") + string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}") + set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") + string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") + + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /GL") + set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL "${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} /LTCG") + set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /LTCG") + set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /LTCG") + endif() +else() + # Try and enable C++11. Don't use C++14 because it doesn't work in some + # configurations. + add_cxx_compiler_flag(-std=c++11) + if (NOT HAVE_CXX_FLAG_STD_CXX11) + add_cxx_compiler_flag(-std=c++0x) + endif() + + # Turn compiler warnings up to 11 + add_cxx_compiler_flag(-Wall) + add_cxx_compiler_flag(-Wextra) + add_cxx_compiler_flag(-Wshadow) + add_cxx_compiler_flag(-Werror RELEASE) + add_cxx_compiler_flag(-Werror RELWITHDEBINFO) + add_cxx_compiler_flag(-Werror MINSIZEREL) + add_cxx_compiler_flag(-pedantic) + add_cxx_compiler_flag(-pedantic-errors) + add_cxx_compiler_flag(-Wshorten-64-to-32) + add_cxx_compiler_flag(-fstrict-aliasing) + # Disable warnings regarding deprecated parts of the library while building + # and testing those parts of the library. + add_cxx_compiler_flag(-Wno-deprecated-declarations) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + # Intel silently ignores '-Wno-deprecated-declarations', + # warning no. 1786 must be explicitly disabled. + # See #631 for rationale. + add_cxx_compiler_flag(-wd1786) + endif() + # Disable deprecation warnings for release builds (when -Werror is enabled). + add_cxx_compiler_flag(-Wno-deprecated RELEASE) + add_cxx_compiler_flag(-Wno-deprecated RELWITHDEBINFO) + add_cxx_compiler_flag(-Wno-deprecated MINSIZEREL) + if (NOT BENCHMARK_ENABLE_EXCEPTIONS) + add_cxx_compiler_flag(-fno-exceptions) + endif() + + if (HAVE_CXX_FLAG_FSTRICT_ALIASING) + if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel") #ICC17u2: Many false positives for Wstrict-aliasing + add_cxx_compiler_flag(-Wstrict-aliasing) + endif() + endif() + # ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially overridden + # (because of deprecated overload) + add_cxx_compiler_flag(-wd654) + add_cxx_compiler_flag(-Wthread-safety) + if (HAVE_CXX_FLAG_WTHREAD_SAFETY) + cxx_feature_check(THREAD_SAFETY_ATTRIBUTES) + endif() + + # On most UNIX like platforms g++ and clang++ define _GNU_SOURCE as a + # predefined macro, which turns on all of the wonderful libc extensions. + # However g++ doesn't do this in Cygwin so we have to define it ourselfs + # since we depend on GNU/POSIX/BSD extensions. + if (CYGWIN) + add_definitions(-D_GNU_SOURCE=1) + endif() + + if (QNXNTO) + add_definitions(-D_QNX_SOURCE) + endif() + + # Link time optimisation + if (BENCHMARK_ENABLE_LTO) + add_cxx_compiler_flag(-flto) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + find_program(GCC_AR gcc-ar) + if (GCC_AR) + set(CMAKE_AR ${GCC_AR}) + endif() + find_program(GCC_RANLIB gcc-ranlib) + if (GCC_RANLIB) + set(CMAKE_RANLIB ${GCC_RANLIB}) + endif() + elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + include(llvm-toolchain) + endif() + endif() + + # Coverage build type + set(BENCHMARK_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}" + CACHE STRING "Flags used by the C++ compiler during coverage builds." + FORCE) + set(BENCHMARK_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" + CACHE STRING "Flags used for linking binaries during coverage builds." + FORCE) + set(BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" + CACHE STRING "Flags used by the shared libraries linker during coverage builds." + FORCE) + mark_as_advanced( + BENCHMARK_CXX_FLAGS_COVERAGE + BENCHMARK_EXE_LINKER_FLAGS_COVERAGE + BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE) + set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") + add_cxx_compiler_flag(--coverage COVERAGE) +endif() + +if (BENCHMARK_USE_LIBCXX) + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + add_cxx_compiler_flag(-stdlib=libc++) + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + add_cxx_compiler_flag(-nostdinc++) + message(WARNING "libc++ header path must be manually specified using CMAKE_CXX_FLAGS") + # Adding -nodefaultlibs directly to CMAKE__LINKER_FLAGS will break + # configuration checks such as 'find_package(Threads)' + list(APPEND BENCHMARK_CXX_LINKER_FLAGS -nodefaultlibs) + # -lc++ cannot be added directly to CMAKE__LINKER_FLAGS because + # linker flags appear before all linker inputs and -lc++ must appear after. + list(APPEND BENCHMARK_CXX_LIBRARIES c++) + else() + message(FATAL_ERROR "-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler") + endif() +endif(BENCHMARK_USE_LIBCXX) + +# C++ feature checks +# Determine the correct regular expression engine to use +cxx_feature_check(STD_REGEX) +cxx_feature_check(GNU_POSIX_REGEX) +cxx_feature_check(POSIX_REGEX) +if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX) + message(FATAL_ERROR "Failed to determine the source files for the regular expression backend") +endif() +if (NOT BENCHMARK_ENABLE_EXCEPTIONS AND HAVE_STD_REGEX + AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX) + message(WARNING "Using std::regex with exceptions disabled is not fully supported") +endif() +cxx_feature_check(STEADY_CLOCK) +# Ensure we have pthreads +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + +# Set up directories +include_directories(${PROJECT_SOURCE_DIR}/include) + +# Build the targets +add_subdirectory(src) + +if (BENCHMARK_ENABLE_TESTING) + enable_testing() + if (BENCHMARK_ENABLE_GTEST_TESTS AND + NOT (TARGET gtest AND TARGET gtest_main AND + TARGET gmock AND TARGET gmock_main)) + include(GoogleTest) + endif() + add_subdirectory(test) +endif() diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTING.md b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTING.md new file mode 100644 index 000000000..43de4c9d4 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# How to contribute # + +We'd love to accept your patches and contributions to this project. There are +a just a few small guidelines you need to follow. + + +## Contributor License Agreement ## + +Contributions to any Google project must be accompanied by a Contributor +License Agreement. This is not a copyright **assignment**, it simply gives +Google permission to use and redistribute your contributions as part of the +project. + + * If you are an individual writing original source code and you're sure you + own the intellectual property, then you'll need to sign an [individual + CLA][]. + + * If you work for a company that wants to allow you to contribute your work, + then you'll need to sign a [corporate CLA][]. + +You generally only need to submit a CLA once, so if you've already submitted +one (even if it was for a different project), you probably don't need to do it +again. + +[individual CLA]: https://developers.google.com/open-source/cla/individual +[corporate CLA]: https://developers.google.com/open-source/cla/corporate + +Once your CLA is submitted (or if you already submitted one for +another Google project), make a commit adding yourself to the +[AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part +of your first [pull request][]. + +[AUTHORS]: AUTHORS +[CONTRIBUTORS]: CONTRIBUTORS + + +## Submitting a patch ## + + 1. It's generally best to start by opening a new issue describing the bug or + feature you're intending to fix. Even if you think it's relatively minor, + it's helpful to know what people are working on. Mention in the initial + issue that you are planning to work on that bug or feature so that it can + be assigned to you. + + 1. Follow the normal process of [forking][] the project, and setup a new + branch to work in. It's important that each group of changes be done in + separate branches in order to ensure that a pull request only includes the + commits related to that bug or feature. + + 1. Do your best to have [well-formed commit messages][] for each change. + This provides consistency throughout the project, and ensures that commit + messages are able to be formatted properly by various git tools. + + 1. Finally, push the commits to your fork and submit a [pull request][]. + +[forking]: https://help.github.com/articles/fork-a-repo +[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html +[pull request]: https://help.github.com/articles/creating-a-pull-request diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTORS b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTORS new file mode 100644 index 000000000..b680efc8c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/CONTRIBUTORS @@ -0,0 +1,72 @@ +# People who have agreed to one of the CLAs and can contribute patches. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# https://developers.google.com/open-source/cla/individual +# https://developers.google.com/open-source/cla/corporate +# +# The agreement for individuals can be filled out on the web. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. +# +# Names should be added to this file as: +# Name +# +# Please keep the list sorted. + +Albert Pretorius +Alex Steele +Andriy Berestovskyy +Arne Beer +Billy Robert O'Neal III +Chris Kennelly +Christopher Seymour +Cyrille Faucheux +Daniel Harvey +David Coeurjolly +Deniz Evrenci +Dominic Hamon +Dominik Czarnota +Eric Fiselier +Eugene Zhuk +Evgeny Safronov +Federico Ficarelli +Felix Homann +Hannes Hauswedell +Ismael Jimenez Martinez +Jern-Kuan Leong +JianXiong Zhou +Joao Paulo Magalhaes +John Millikin +Jussi Knuuttila +Kai Wolf +Kishan Kumar +Kaito Udagawa +Lei Xu +Matt Clarkson +Maxim Vafin +Nick Hutchinson +Oleksandr Sochka +Ori Livneh +Pascal Leroy +Paul Redmond +Pierre Phaneuf +Radoslav Yovchev +Raul Marin +Ray Glover +Robert Guo +Roman Lebedev +Shuo Chen +Tobias Ulvgård +Tom Madams +Yixuan Qiu +Yusuke Suzuki +Zbigniew Skowron diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/LICENSE b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/README.md b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/README.md new file mode 100644 index 000000000..45e415884 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/README.md @@ -0,0 +1,1179 @@ +# Benchmark +[![Build Status](https://travis-ci.org/google/benchmark.svg?branch=master)](https://travis-ci.org/google/benchmark) +[![Build status](https://ci.appveyor.com/api/projects/status/u0qsyp7t1tk7cpxs/branch/master?svg=true)](https://ci.appveyor.com/project/google/benchmark/branch/master) +[![Coverage Status](https://coveralls.io/repos/google/benchmark/badge.svg)](https://coveralls.io/r/google/benchmark) +[![slackin](https://slackin-iqtfqnpzxd.now.sh/badge.svg)](https://slackin-iqtfqnpzxd.now.sh/) + + +A library to benchmark code snippets, similar to unit tests. Example: + +```c++ +#include + +static void BM_SomeFunction(benchmark::State& state) { + // Perform setup here + for (auto _ : state) { + // This code gets timed + SomeFunction(); + } +} +// Register the function as a benchmark +BENCHMARK(BM_SomeFunction); +// Run the benchmark +BENCHMARK_MAIN(); +``` + +To get started, see [Requirements](#requirements) and +[Installation](#installation). See [Usage](#usage) for a full example and the +[User Guide](#user-guide) for a more comprehensive feature overview. + +It may also help to read the [Google Test documentation](https://github.com/google/googletest/blob/master/googletest/docs/primer.md) +as some of the structural aspects of the APIs are similar. + +### Resources + +[Discussion group](https://groups.google.com/d/forum/benchmark-discuss) + +IRC channel: [freenode](https://freenode.net) #googlebenchmark + +[Additional Tooling Documentation](docs/tools.md) + +[Assembly Testing Documentation](docs/AssemblyTests.md) + +## Requirements + +The library can be used with C++03. However, it requires C++11 to build, +including compiler and standard library support. + +The following minimum versions are required to build the library: + +* GCC 4.8 +* Clang 3.4 +* Visual Studio 2013 +* Intel 2015 Update 1 + +## Installation + +This describes the installation process using cmake. As pre-requisites, you'll +need git and cmake installed. + +_See [dependencies.md](dependencies.md) for more details regarding supported +versions of build tools._ + +```bash +# Check out the library. +$ git clone https://github.com/google/benchmark.git +# Benchmark requires Google Test as a dependency. Add the source tree as a subdirectory. +$ git clone https://github.com/google/googletest.git benchmark/googletest +# Make a build directory to place the build output. +$ mkdir build && cd build +# Generate a Makefile with cmake. +# Use cmake -G to generate a different file type. +$ cmake ../benchmark +# Build the library. +$ make +``` +This builds the `benchmark` and `benchmark_main` libraries and tests. +On a unix system, the build directory should now look something like this: + +``` +/benchmark +/build + /src + /libbenchmark.a + /libbenchmark_main.a + /test + ... +``` + +Next, you can run the tests to check the build. + +```bash +$ make test +``` + +If you want to install the library globally, also run: + +``` +sudo make install +``` + +Note that Google Benchmark requires Google Test to build and run the tests. This +dependency can be provided two ways: + +* Checkout the Google Test sources into `benchmark/googletest` as above. +* Otherwise, if `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` is specified during + configuration, the library will automatically download and build any required + dependencies. + +If you do not wish to build and run the tests, add `-DBENCHMARK_ENABLE_GTEST_TESTS=OFF` +to `CMAKE_ARGS`. + +### Debug vs Release + +By default, benchmark builds as a debug library. You will see a warning in the +output when this is the case. To build it as a release library instead, use: + +``` +cmake -DCMAKE_BUILD_TYPE=Release +``` + +To enable link-time optimisation, use + +``` +cmake -DCMAKE_BUILD_TYPE=Release -DBENCHMARK_ENABLE_LTO=true +``` + +If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake +cache variables, if autodetection fails. + +If you are using clang, you may need to set `LLVMAR_EXECUTABLE`, +`LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables. + + +### Stable and Experimental Library Versions + +The main branch contains the latest stable version of the benchmarking library; +the API of which can be considered largely stable, with source breaking changes +being made only upon the release of a new major version. + +Newer, experimental, features are implemented and tested on the +[`v2` branch](https://github.com/google/benchmark/tree/v2). Users who wish +to use, test, and provide feedback on the new features are encouraged to try +this branch. However, this branch provides no stability guarantees and reserves +the right to change and break the API at any time. + +## Usage +### Basic usage +Define a function that executes the code to measure, register it as a benchmark +function using the `BENCHMARK` macro, and ensure an appropriate `main` function +is available: + +```c++ +#include + +static void BM_StringCreation(benchmark::State& state) { + for (auto _ : state) + std::string empty_string; +} +// Register the function as a benchmark +BENCHMARK(BM_StringCreation); + +// Define another benchmark +static void BM_StringCopy(benchmark::State& state) { + std::string x = "hello"; + for (auto _ : state) + std::string copy(x); +} +BENCHMARK(BM_StringCopy); + +BENCHMARK_MAIN(); +``` + +To run the benchmark, compile and link against the `benchmark` library +(libbenchmark.a/.so). If you followed the build steps above, this +library will be under the build directory you created. + +```bash +# Example on linux after running the build steps above. Assumes the +# `benchmark` and `build` directories are under the current directory. +$ g++ -std=c++11 -isystem benchmark/include -Lbuild/src -lpthread \ + -lbenchmark mybenchmark.cc -o mybenchmark +``` + +Alternatively, link against the `benchmark_main` library and remove +`BENCHMARK_MAIN();` above to get the same behavior. + +The compiled executable will run all benchmarks by default. Pass the `--help` +flag for option information or see the guide below. + +### Platform-specific instructions + +When the library is built using GCC it is necessary to link with the pthread +library due to how GCC implements `std::thread`. Failing to link to pthread will +lead to runtime exceptions (unless you're using libc++), not linker errors. See +[issue #67](https://github.com/google/benchmark/issues/67) for more details. You +can link to pthread by adding `-pthread` to your linker command. Note, you can +also use `-lpthread`, but there are potential issues with ordering of command +line parameters if you use that. + +If you're running benchmarks on Windows, the shlwapi library (`-lshlwapi`) is +also required. + +If you're running benchmarks on solaris, you'll want the kstat library linked in +too (`-lkstat`). + +## User Guide + +### Command Line +[Output Formats](#output-formats) + +[Output Files](#output-files) + +[Running a Subset of Benchmarks](#running-a-subset-of-benchmarks) + +[Result Comparison](#result-comparison) + +### Library +[Runtime and Reporting Considerations](#runtime-and-reporting-considerations) + +[Passing Arguments](#passing-arguments) + +[Calculating Asymptotic Complexity](#asymptotic-complexity) + +[Templated Benchmarks](#templated-benchmarks) + +[Fixtures](#fixtures) + +[Custom Counters](#custom-counters) + +[Multithreaded Benchmarks](#multithreaded-benchmarks) + +[CPU Timers](#cpu-timers) + +[Manual Timing](#manual-timing) + +[Setting the Time Unit](#setting-the-time-unit) + +[Preventing Optimization](#preventing-optimization) + +[Reporting Statistics](#reporting-statistics) + +[Custom Statistics](#custom-statistics) + +[Using RegisterBenchmark](#using-register-benchmark) + +[Exiting with an Error](#exiting-with-an-error) + +[A Faster KeepRunning Loop](#a-faster-keep-running-loop) + +[Disabling CPU Frequency Scaling](#disabling-cpu-frequency-scaling) + + + +### Output Formats + +The library supports multiple output formats. Use the +`--benchmark_format=` flag to set the format type. `console` +is the default format. + +The Console format is intended to be a human readable format. By default +the format generates color output. Context is output on stderr and the +tabular data on stdout. Example tabular output looks like: +``` +Benchmark Time(ns) CPU(ns) Iterations +---------------------------------------------------------------------- +BM_SetInsert/1024/1 28928 29349 23853 133.097kB/s 33.2742k items/s +BM_SetInsert/1024/8 32065 32913 21375 949.487kB/s 237.372k items/s +BM_SetInsert/1024/10 33157 33648 21431 1.13369MB/s 290.225k items/s +``` + +The JSON format outputs human readable json split into two top level attributes. +The `context` attribute contains information about the run in general, including +information about the CPU and the date. +The `benchmarks` attribute contains a list of every benchmark run. Example json +output looks like: +```json +{ + "context": { + "date": "2015/03/17-18:40:25", + "num_cpus": 40, + "mhz_per_cpu": 2801, + "cpu_scaling_enabled": false, + "build_type": "debug" + }, + "benchmarks": [ + { + "name": "BM_SetInsert/1024/1", + "iterations": 94877, + "real_time": 29275, + "cpu_time": 29836, + "bytes_per_second": 134066, + "items_per_second": 33516 + }, + { + "name": "BM_SetInsert/1024/8", + "iterations": 21609, + "real_time": 32317, + "cpu_time": 32429, + "bytes_per_second": 986770, + "items_per_second": 246693 + }, + { + "name": "BM_SetInsert/1024/10", + "iterations": 21393, + "real_time": 32724, + "cpu_time": 33355, + "bytes_per_second": 1199226, + "items_per_second": 299807 + } + ] +} +``` + +The CSV format outputs comma-separated values. The `context` is output on stderr +and the CSV itself on stdout. Example CSV output looks like: +``` +name,iterations,real_time,cpu_time,bytes_per_second,items_per_second,label +"BM_SetInsert/1024/1",65465,17890.7,8407.45,475768,118942, +"BM_SetInsert/1024/8",116606,18810.1,9766.64,3.27646e+06,819115, +"BM_SetInsert/1024/10",106365,17238.4,8421.53,4.74973e+06,1.18743e+06, +``` + + + +### Output Files + +Write benchmark results to a file with the `--benchmark_out=` option. +Specify the output format with `--benchmark_out_format={json|console|csv}`. Note that Specifying +`--benchmark_out` does not suppress the console output. + + + +### Running a Subset of Benchmarks + +The `--benchmark_filter=` option can be used to only run the benchmarks +which match the specified ``. For example: + +```bash +$ ./run_benchmarks.x --benchmark_filter=BM_memcpy/32 +Run on (1 X 2300 MHz CPU ) +2016-06-25 19:34:24 +Benchmark Time CPU Iterations +---------------------------------------------------- +BM_memcpy/32 11 ns 11 ns 79545455 +BM_memcpy/32k 2181 ns 2185 ns 324074 +BM_memcpy/32 12 ns 12 ns 54687500 +BM_memcpy/32k 1834 ns 1837 ns 357143 +``` + + + +### Result comparison + +It is possible to compare the benchmarking results. See [Additional Tooling Documentation](docs/tools.md) + + + +### Runtime and Reporting Considerations + +When the benchmark binary is executed, each benchmark function is run serially. +The number of iterations to run is determined dynamically by running the +benchmark a few times and measuring the time taken and ensuring that the +ultimate result will be statistically stable. As such, faster benchmark +functions will be run for more iterations than slower benchmark functions, and +the number of iterations is thus reported. + +In all cases, the number of iterations for which the benchmark is run is +governed by the amount of time the benchmark takes. Concretely, the number of +iterations is at least one, not more than 1e9, until CPU time is greater than +the minimum time, or the wallclock time is 5x minimum time. The minimum time is +set per benchmark by calling `MinTime` on the registered benchmark object. + +Average timings are then reported over the iterations run. If multiple +repetitions are requested using the `--benchmark_repetitions` command-line +option, or at registration time, the benchmark function will be run several +times and statistical results across these repetitions will also be reported. + +As well as the per-benchmark entries, a preamble in the report will include +information about the machine on which the benchmarks are run. + + + +### Passing Arguments + +Sometimes a family of benchmarks can be implemented with just one routine that +takes an extra argument to specify which one of the family of benchmarks to +run. For example, the following code defines a family of benchmarks for +measuring the speed of `memcpy()` calls of different lengths: + +```c++ +static void BM_memcpy(benchmark::State& state) { + char* src = new char[state.range(0)]; + char* dst = new char[state.range(0)]; + memset(src, 'x', state.range(0)); + for (auto _ : state) + memcpy(dst, src, state.range(0)); + state.SetBytesProcessed(int64_t(state.iterations()) * + int64_t(state.range(0))); + delete[] src; + delete[] dst; +} +BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10); +``` + +The preceding code is quite repetitive, and can be replaced with the following +short-hand. The following invocation will pick a few appropriate arguments in +the specified range and will generate a benchmark for each such argument. + +```c++ +BENCHMARK(BM_memcpy)->Range(8, 8<<10); +``` + +By default the arguments in the range are generated in multiples of eight and +the command above selects [ 8, 64, 512, 4k, 8k ]. In the following code the +range multiplier is changed to multiples of two. + +```c++ +BENCHMARK(BM_memcpy)->RangeMultiplier(2)->Range(8, 8<<10); +``` +Now arguments generated are [ 8, 16, 32, 64, 128, 256, 512, 1024, 2k, 4k, 8k ]. + +You might have a benchmark that depends on two or more inputs. For example, the +following code defines a family of benchmarks for measuring the speed of set +insertion. + +```c++ +static void BM_SetInsert(benchmark::State& state) { + std::set data; + for (auto _ : state) { + state.PauseTiming(); + data = ConstructRandomSet(state.range(0)); + state.ResumeTiming(); + for (int j = 0; j < state.range(1); ++j) + data.insert(RandomNumber()); + } +} +BENCHMARK(BM_SetInsert) + ->Args({1<<10, 128}) + ->Args({2<<10, 128}) + ->Args({4<<10, 128}) + ->Args({8<<10, 128}) + ->Args({1<<10, 512}) + ->Args({2<<10, 512}) + ->Args({4<<10, 512}) + ->Args({8<<10, 512}); +``` + +The preceding code is quite repetitive, and can be replaced with the following +short-hand. The following macro will pick a few appropriate arguments in the +product of the two specified ranges and will generate a benchmark for each such +pair. + +```c++ +BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}}); +``` + +For more complex patterns of inputs, passing a custom function to `Apply` allows +programmatic specification of an arbitrary set of arguments on which to run the +benchmark. The following example enumerates a dense range on one parameter, +and a sparse range on the second. + +```c++ +static void CustomArguments(benchmark::internal::Benchmark* b) { + for (int i = 0; i <= 10; ++i) + for (int j = 32; j <= 1024*1024; j *= 8) + b->Args({i, j}); +} +BENCHMARK(BM_SetInsert)->Apply(CustomArguments); +``` + +#### Passing Arbitrary Arguments to a Benchmark + +In C++11 it is possible to define a benchmark that takes an arbitrary number +of extra arguments. The `BENCHMARK_CAPTURE(func, test_case_name, ...args)` +macro creates a benchmark that invokes `func` with the `benchmark::State` as +the first argument followed by the specified `args...`. +The `test_case_name` is appended to the name of the benchmark and +should describe the values passed. + +```c++ +template +void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) { + [...] +} +// Registers a benchmark named "BM_takes_args/int_string_test" that passes +// the specified values to `extra_args`. +BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc")); +``` +Note that elements of `...args` may refer to global variables. Users should +avoid modifying global state inside of a benchmark. + + + +### Calculating Asymptotic Complexity (Big O) + +Asymptotic complexity might be calculated for a family of benchmarks. The +following code will calculate the coefficient for the high-order term in the +running time and the normalized root-mean square error of string comparison. + +```c++ +static void BM_StringCompare(benchmark::State& state) { + std::string s1(state.range(0), '-'); + std::string s2(state.range(0), '-'); + for (auto _ : state) { + benchmark::DoNotOptimize(s1.compare(s2)); + } + state.SetComplexityN(state.range(0)); +} +BENCHMARK(BM_StringCompare) + ->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity(benchmark::oN); +``` + +As shown in the following invocation, asymptotic complexity might also be +calculated automatically. + +```c++ +BENCHMARK(BM_StringCompare) + ->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity(); +``` + +The following code will specify asymptotic complexity with a lambda function, +that might be used to customize high-order term calculation. + +```c++ +BENCHMARK(BM_StringCompare)->RangeMultiplier(2) + ->Range(1<<10, 1<<18)->Complexity([](int64_t n)->double{return n; }); +``` + + + +### Templated Benchmarks + +This example produces and consumes messages of size `sizeof(v)` `range_x` +times. It also outputs throughput in the absence of multiprogramming. + +```c++ +template void BM_Sequential(benchmark::State& state) { + Q q; + typename Q::value_type v; + for (auto _ : state) { + for (int i = state.range(0); i--; ) + q.push(v); + for (int e = state.range(0); e--; ) + q.Wait(&v); + } + // actually messages, not bytes: + state.SetBytesProcessed( + static_cast(state.iterations())*state.range(0)); +} +BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10); +``` + +Three macros are provided for adding benchmark templates. + +```c++ +#ifdef BENCHMARK_HAS_CXX11 +#define BENCHMARK_TEMPLATE(func, ...) // Takes any number of parameters. +#else // C++ < C++11 +#define BENCHMARK_TEMPLATE(func, arg1) +#endif +#define BENCHMARK_TEMPLATE1(func, arg1) +#define BENCHMARK_TEMPLATE2(func, arg1, arg2) +``` + + + +### Fixtures + +Fixture tests are created by first defining a type that derives from +`::benchmark::Fixture` and then creating/registering the tests using the +following macros: + +* `BENCHMARK_F(ClassName, Method)` +* `BENCHMARK_DEFINE_F(ClassName, Method)` +* `BENCHMARK_REGISTER_F(ClassName, Method)` + +For Example: + +```c++ +class MyFixture : public benchmark::Fixture { +public: + void SetUp(const ::benchmark::State& state) { + } + + void TearDown(const ::benchmark::State& state) { + } +}; + +BENCHMARK_F(MyFixture, FooTest)(benchmark::State& st) { + for (auto _ : st) { + ... + } +} + +BENCHMARK_DEFINE_F(MyFixture, BarTest)(benchmark::State& st) { + for (auto _ : st) { + ... + } +} +/* BarTest is NOT registered */ +BENCHMARK_REGISTER_F(MyFixture, BarTest)->Threads(2); +/* BarTest is now registered */ +``` + +#### Templated Fixtures + +Also you can create templated fixture by using the following macros: + +* `BENCHMARK_TEMPLATE_F(ClassName, Method, ...)` +* `BENCHMARK_TEMPLATE_DEFINE_F(ClassName, Method, ...)` + +For example: +```c++ +template +class MyFixture : public benchmark::Fixture {}; + +BENCHMARK_TEMPLATE_F(MyFixture, IntTest, int)(benchmark::State& st) { + for (auto _ : st) { + ... + } +} + +BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, DoubleTest, double)(benchmark::State& st) { + for (auto _ : st) { + ... + } +} + +BENCHMARK_REGISTER_F(MyFixture, DoubleTest)->Threads(2); +``` + + + +### Custom Counters + +You can add your own counters with user-defined names. The example below +will add columns "Foo", "Bar" and "Baz" in its output: + +```c++ +static void UserCountersExample1(benchmark::State& state) { + double numFoos = 0, numBars = 0, numBazs = 0; + for (auto _ : state) { + // ... count Foo,Bar,Baz events + } + state.counters["Foo"] = numFoos; + state.counters["Bar"] = numBars; + state.counters["Baz"] = numBazs; +} +``` + +The `state.counters` object is a `std::map` with `std::string` keys +and `Counter` values. The latter is a `double`-like class, via an implicit +conversion to `double&`. Thus you can use all of the standard arithmetic +assignment operators (`=,+=,-=,*=,/=`) to change the value of each counter. + +In multithreaded benchmarks, each counter is set on the calling thread only. +When the benchmark finishes, the counters from each thread will be summed; +the resulting sum is the value which will be shown for the benchmark. + +The `Counter` constructor accepts three parameters: the value as a `double` +; a bit flag which allows you to show counters as rates, and/or as per-thread +iteration, and/or as per-thread averages, and/or iteration invariants; +and a flag specifying the 'unit' - i.e. is 1k a 1000 (default, +`benchmark::Counter::OneK::kIs1000`), or 1024 +(`benchmark::Counter::OneK::kIs1024`)? + +```c++ + // sets a simple counter + state.counters["Foo"] = numFoos; + + // Set the counter as a rate. It will be presented divided + // by the duration of the benchmark. + state.counters["FooRate"] = Counter(numFoos, benchmark::Counter::kIsRate); + + // Set the counter as a thread-average quantity. It will + // be presented divided by the number of threads. + state.counters["FooAvg"] = Counter(numFoos, benchmark::Counter::kAvgThreads); + + // There's also a combined flag: + state.counters["FooAvgRate"] = Counter(numFoos,benchmark::Counter::kAvgThreadsRate); + + // This says that we process with the rate of state.range(0) bytes every iteration: + state.counters["BytesProcessed"] = Counter(state.range(0), benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::OneK::kIs1024); +``` + +When you're compiling in C++11 mode or later you can use `insert()` with +`std::initializer_list`: + +```c++ + // With C++11, this can be done: + state.counters.insert({{"Foo", numFoos}, {"Bar", numBars}, {"Baz", numBazs}}); + // ... instead of: + state.counters["Foo"] = numFoos; + state.counters["Bar"] = numBars; + state.counters["Baz"] = numBazs; +``` + +#### Counter Reporting + +When using the console reporter, by default, user counters are are printed at +the end after the table, the same way as ``bytes_processed`` and +``items_processed``. This is best for cases in which there are few counters, +or where there are only a couple of lines per benchmark. Here's an example of +the default output: + +``` +------------------------------------------------------------------------------ +Benchmark Time CPU Iterations UserCounters... +------------------------------------------------------------------------------ +BM_UserCounter/threads:8 2248 ns 10277 ns 68808 Bar=16 Bat=40 Baz=24 Foo=8 +BM_UserCounter/threads:1 9797 ns 9788 ns 71523 Bar=2 Bat=5 Baz=3 Foo=1024m +BM_UserCounter/threads:2 4924 ns 9842 ns 71036 Bar=4 Bat=10 Baz=6 Foo=2 +BM_UserCounter/threads:4 2589 ns 10284 ns 68012 Bar=8 Bat=20 Baz=12 Foo=4 +BM_UserCounter/threads:8 2212 ns 10287 ns 68040 Bar=16 Bat=40 Baz=24 Foo=8 +BM_UserCounter/threads:16 1782 ns 10278 ns 68144 Bar=32 Bat=80 Baz=48 Foo=16 +BM_UserCounter/threads:32 1291 ns 10296 ns 68256 Bar=64 Bat=160 Baz=96 Foo=32 +BM_UserCounter/threads:4 2615 ns 10307 ns 68040 Bar=8 Bat=20 Baz=12 Foo=4 +BM_Factorial 26 ns 26 ns 26608979 40320 +BM_Factorial/real_time 26 ns 26 ns 26587936 40320 +BM_CalculatePiRange/1 16 ns 16 ns 45704255 0 +BM_CalculatePiRange/8 73 ns 73 ns 9520927 3.28374 +BM_CalculatePiRange/64 609 ns 609 ns 1140647 3.15746 +BM_CalculatePiRange/512 4900 ns 4901 ns 142696 3.14355 +``` + +If this doesn't suit you, you can print each counter as a table column by +passing the flag `--benchmark_counters_tabular=true` to the benchmark +application. This is best for cases in which there are a lot of counters, or +a lot of lines per individual benchmark. Note that this will trigger a +reprinting of the table header any time the counter set changes between +individual benchmarks. Here's an example of corresponding output when +`--benchmark_counters_tabular=true` is passed: + +``` +--------------------------------------------------------------------------------------- +Benchmark Time CPU Iterations Bar Bat Baz Foo +--------------------------------------------------------------------------------------- +BM_UserCounter/threads:8 2198 ns 9953 ns 70688 16 40 24 8 +BM_UserCounter/threads:1 9504 ns 9504 ns 73787 2 5 3 1 +BM_UserCounter/threads:2 4775 ns 9550 ns 72606 4 10 6 2 +BM_UserCounter/threads:4 2508 ns 9951 ns 70332 8 20 12 4 +BM_UserCounter/threads:8 2055 ns 9933 ns 70344 16 40 24 8 +BM_UserCounter/threads:16 1610 ns 9946 ns 70720 32 80 48 16 +BM_UserCounter/threads:32 1192 ns 9948 ns 70496 64 160 96 32 +BM_UserCounter/threads:4 2506 ns 9949 ns 70332 8 20 12 4 +-------------------------------------------------------------- +Benchmark Time CPU Iterations +-------------------------------------------------------------- +BM_Factorial 26 ns 26 ns 26392245 40320 +BM_Factorial/real_time 26 ns 26 ns 26494107 40320 +BM_CalculatePiRange/1 15 ns 15 ns 45571597 0 +BM_CalculatePiRange/8 74 ns 74 ns 9450212 3.28374 +BM_CalculatePiRange/64 595 ns 595 ns 1173901 3.15746 +BM_CalculatePiRange/512 4752 ns 4752 ns 147380 3.14355 +BM_CalculatePiRange/4k 37970 ns 37972 ns 18453 3.14184 +BM_CalculatePiRange/32k 303733 ns 303744 ns 2305 3.14162 +BM_CalculatePiRange/256k 2434095 ns 2434186 ns 288 3.1416 +BM_CalculatePiRange/1024k 9721140 ns 9721413 ns 71 3.14159 +BM_CalculatePi/threads:8 2255 ns 9943 ns 70936 +``` +Note above the additional header printed when the benchmark changes from +``BM_UserCounter`` to ``BM_Factorial``. This is because ``BM_Factorial`` does +not have the same counter set as ``BM_UserCounter``. + + + +### Multithreaded Benchmarks + +In a multithreaded test (benchmark invoked by multiple threads simultaneously), +it is guaranteed that none of the threads will start until all have reached +the start of the benchmark loop, and all will have finished before any thread +exits the benchmark loop. (This behavior is also provided by the `KeepRunning()` +API) As such, any global setup or teardown can be wrapped in a check against the thread +index: + +```c++ +static void BM_MultiThreaded(benchmark::State& state) { + if (state.thread_index == 0) { + // Setup code here. + } + for (auto _ : state) { + // Run the test as normal. + } + if (state.thread_index == 0) { + // Teardown code here. + } +} +BENCHMARK(BM_MultiThreaded)->Threads(2); +``` + +If the benchmarked code itself uses threads and you want to compare it to +single-threaded code, you may want to use real-time ("wallclock") measurements +for latency comparisons: + +```c++ +BENCHMARK(BM_test)->Range(8, 8<<10)->UseRealTime(); +``` + +Without `UseRealTime`, CPU time is used by default. + + + +### CPU Timers + +By default, the CPU timer only measures the time spent by the main thread. +If the benchmark itself uses threads internally, this measurement may not +be what you are looking for. Instead, there is a way to measure the total +CPU usage of the process, by all the threads. + +```c++ +void callee(int i); + +static void MyMain(int size) { +#pragma omp parallel for + for(int i = 0; i < size; i++) + callee(i); +} + +static void BM_OpenMP(benchmark::State& state) { + for (auto _ : state) + MyMain(state.range(0); +} + +// Measure the time spent by the main thread, use it to decide for how long to +// run the benchmark loop. Depending on the internal implementation detail may +// measure to anywhere from near-zero (the overhead spent before/after work +// handoff to worker thread[s]) to the whole single-thread time. +BENCHMARK(BM_OpenMP)->Range(8, 8<<10); + +// Measure the user-visible time, the wall clock (literally, the time that +// has passed on the clock on the wall), use it to decide for how long to +// run the benchmark loop. This will always be meaningful, an will match the +// time spent by the main thread in single-threaded case, in general decreasing +// with the number of internal threads doing the work. +BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->UseRealTime(); + +// Measure the total CPU consumption, use it to decide for how long to +// run the benchmark loop. This will always measure to no less than the +// time spent by the main thread in single-threaded case. +BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->MeasureProcessCPUTime(); + +// A mixture of the last two. Measure the total CPU consumption, but use the +// wall clock to decide for how long to run the benchmark loop. +BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->MeasureProcessCPUTime()->UseRealTime(); +``` + +#### Controlling Timers + +Normally, the entire duration of the work loop (`for (auto _ : state) {}`) +is measured. But sometimes, it is necessary to do some work inside of +that loop, every iteration, but without counting that time to the benchmark time. +That is possible, althought it is not recommended, since it has high overhead. + +```c++ +static void BM_SetInsert_With_Timer_Control(benchmark::State& state) { + std::set data; + for (auto _ : state) { + state.PauseTiming(); // Stop timers. They will not count until they are resumed. + data = ConstructRandomSet(state.range(0)); // Do something that should not be measured + state.ResumeTiming(); // And resume timers. They are now counting again. + // The rest will be measured. + for (int j = 0; j < state.range(1); ++j) + data.insert(RandomNumber()); + } +} +BENCHMARK(BM_SetInsert_With_Timer_Control)->Ranges({{1<<10, 8<<10}, {128, 512}}); +``` + + + +### Manual Timing + +For benchmarking something for which neither CPU time nor real-time are +correct or accurate enough, completely manual timing is supported using +the `UseManualTime` function. + +When `UseManualTime` is used, the benchmarked code must call +`SetIterationTime` once per iteration of the benchmark loop to +report the manually measured time. + +An example use case for this is benchmarking GPU execution (e.g. OpenCL +or CUDA kernels, OpenGL or Vulkan or Direct3D draw calls), which cannot +be accurately measured using CPU time or real-time. Instead, they can be +measured accurately using a dedicated API, and these measurement results +can be reported back with `SetIterationTime`. + +```c++ +static void BM_ManualTiming(benchmark::State& state) { + int microseconds = state.range(0); + std::chrono::duration sleep_duration { + static_cast(microseconds) + }; + + for (auto _ : state) { + auto start = std::chrono::high_resolution_clock::now(); + // Simulate some useful workload with a sleep + std::this_thread::sleep_for(sleep_duration); + auto end = std::chrono::high_resolution_clock::now(); + + auto elapsed_seconds = + std::chrono::duration_cast>( + end - start); + + state.SetIterationTime(elapsed_seconds.count()); + } +} +BENCHMARK(BM_ManualTiming)->Range(1, 1<<17)->UseManualTime(); +``` + + + +### Setting the Time Unit + +If a benchmark runs a few milliseconds it may be hard to visually compare the +measured times, since the output data is given in nanoseconds per default. In +order to manually set the time unit, you can specify it manually: + +```c++ +BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); +``` + + + +### Preventing Optimization + +To prevent a value or expression from being optimized away by the compiler +the `benchmark::DoNotOptimize(...)` and `benchmark::ClobberMemory()` +functions can be used. + +```c++ +static void BM_test(benchmark::State& state) { + for (auto _ : state) { + int x = 0; + for (int i=0; i < 64; ++i) { + benchmark::DoNotOptimize(x += i); + } + } +} +``` + +`DoNotOptimize()` forces the *result* of `` to be stored in either +memory or a register. For GNU based compilers it acts as read/write barrier +for global memory. More specifically it forces the compiler to flush pending +writes to memory and reload any other values as necessary. + +Note that `DoNotOptimize()` does not prevent optimizations on `` +in any way. `` may even be removed entirely when the result is already +known. For example: + +```c++ + /* Example 1: `` is removed entirely. */ + int foo(int x) { return x + 42; } + while (...) DoNotOptimize(foo(0)); // Optimized to DoNotOptimize(42); + + /* Example 2: Result of '' is only reused */ + int bar(int) __attribute__((const)); + while (...) DoNotOptimize(bar(0)); // Optimized to: + // int __result__ = bar(0); + // while (...) DoNotOptimize(__result__); +``` + +The second tool for preventing optimizations is `ClobberMemory()`. In essence +`ClobberMemory()` forces the compiler to perform all pending writes to global +memory. Memory managed by block scope objects must be "escaped" using +`DoNotOptimize(...)` before it can be clobbered. In the below example +`ClobberMemory()` prevents the call to `v.push_back(42)` from being optimized +away. + +```c++ +static void BM_vector_push_back(benchmark::State& state) { + for (auto _ : state) { + std::vector v; + v.reserve(1); + benchmark::DoNotOptimize(v.data()); // Allow v.data() to be clobbered. + v.push_back(42); + benchmark::ClobberMemory(); // Force 42 to be written to memory. + } +} +``` + +Note that `ClobberMemory()` is only available for GNU or MSVC based compilers. + + + +### Statistics: Reporting the Mean, Median and Standard Deviation of Repeated Benchmarks + +By default each benchmark is run once and that single result is reported. +However benchmarks are often noisy and a single result may not be representative +of the overall behavior. For this reason it's possible to repeatedly rerun the +benchmark. + +The number of runs of each benchmark is specified globally by the +`--benchmark_repetitions` flag or on a per benchmark basis by calling +`Repetitions` on the registered benchmark object. When a benchmark is run more +than once the mean, median and standard deviation of the runs will be reported. + +Additionally the `--benchmark_report_aggregates_only={true|false}`, +`--benchmark_display_aggregates_only={true|false}` flags or +`ReportAggregatesOnly(bool)`, `DisplayAggregatesOnly(bool)` functions can be +used to change how repeated tests are reported. By default the result of each +repeated run is reported. When `report aggregates only` option is `true`, +only the aggregates (i.e. mean, median and standard deviation, maybe complexity +measurements if they were requested) of the runs is reported, to both the +reporters - standard output (console), and the file. +However when only the `display aggregates only` option is `true`, +only the aggregates are displayed in the standard output, while the file +output still contains everything. +Calling `ReportAggregatesOnly(bool)` / `DisplayAggregatesOnly(bool)` on a +registered benchmark object overrides the value of the appropriate flag for that +benchmark. + + + +### Custom Statistics + +While having mean, median and standard deviation is nice, this may not be +enough for everyone. For example you may want to know what the largest +observation is, e.g. because you have some real-time constraints. This is easy. +The following code will specify a custom statistic to be calculated, defined +by a lambda function. + +```c++ +void BM_spin_empty(benchmark::State& state) { + for (auto _ : state) { + for (int x = 0; x < state.range(0); ++x) { + benchmark::DoNotOptimize(x); + } + } +} + +BENCHMARK(BM_spin_empty) + ->ComputeStatistics("max", [](const std::vector& v) -> double { + return *(std::max_element(std::begin(v), std::end(v))); + }) + ->Arg(512); +``` + + + +### Using RegisterBenchmark(name, fn, args...) + +The `RegisterBenchmark(name, func, args...)` function provides an alternative +way to create and register benchmarks. +`RegisterBenchmark(name, func, args...)` creates, registers, and returns a +pointer to a new benchmark with the specified `name` that invokes +`func(st, args...)` where `st` is a `benchmark::State` object. + +Unlike the `BENCHMARK` registration macros, which can only be used at the global +scope, the `RegisterBenchmark` can be called anywhere. This allows for +benchmark tests to be registered programmatically. + +Additionally `RegisterBenchmark` allows any callable object to be registered +as a benchmark. Including capturing lambdas and function objects. + +For Example: +```c++ +auto BM_test = [](benchmark::State& st, auto Inputs) { /* ... */ }; + +int main(int argc, char** argv) { + for (auto& test_input : { /* ... */ }) + benchmark::RegisterBenchmark(test_input.name(), BM_test, test_input); + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); +} +``` + + + +### Exiting with an Error + +When errors caused by external influences, such as file I/O and network +communication, occur within a benchmark the +`State::SkipWithError(const char* msg)` function can be used to skip that run +of benchmark and report the error. Note that only future iterations of the +`KeepRunning()` are skipped. For the ranged-for version of the benchmark loop +Users must explicitly exit the loop, otherwise all iterations will be performed. +Users may explicitly return to exit the benchmark immediately. + +The `SkipWithError(...)` function may be used at any point within the benchmark, +including before and after the benchmark loop. + +For example: + +```c++ +static void BM_test(benchmark::State& state) { + auto resource = GetResource(); + if (!resource.good()) { + state.SkipWithError("Resource is not good!"); + // KeepRunning() loop will not be entered. + } + for (state.KeepRunning()) { + auto data = resource.read_data(); + if (!resource.good()) { + state.SkipWithError("Failed to read data!"); + break; // Needed to skip the rest of the iteration. + } + do_stuff(data); + } +} + +static void BM_test_ranged_fo(benchmark::State & state) { + state.SkipWithError("test will not be entered"); + for (auto _ : state) { + state.SkipWithError("Failed!"); + break; // REQUIRED to prevent all further iterations. + } +} +``` + + +### A Faster KeepRunning Loop + +In C++11 mode, a ranged-based for loop should be used in preference to +the `KeepRunning` loop for running the benchmarks. For example: + +```c++ +static void BM_Fast(benchmark::State &state) { + for (auto _ : state) { + FastOperation(); + } +} +BENCHMARK(BM_Fast); +``` + +The reason the ranged-for loop is faster than using `KeepRunning`, is +because `KeepRunning` requires a memory load and store of the iteration count +ever iteration, whereas the ranged-for variant is able to keep the iteration count +in a register. + +For example, an empty inner loop of using the ranged-based for method looks like: + +```asm +# Loop Init + mov rbx, qword ptr [r14 + 104] + call benchmark::State::StartKeepRunning() + test rbx, rbx + je .LoopEnd +.LoopHeader: # =>This Inner Loop Header: Depth=1 + add rbx, -1 + jne .LoopHeader +.LoopEnd: +``` + +Compared to an empty `KeepRunning` loop, which looks like: + +```asm +.LoopHeader: # in Loop: Header=BB0_3 Depth=1 + cmp byte ptr [rbx], 1 + jne .LoopInit +.LoopBody: # =>This Inner Loop Header: Depth=1 + mov rax, qword ptr [rbx + 8] + lea rcx, [rax + 1] + mov qword ptr [rbx + 8], rcx + cmp rax, qword ptr [rbx + 104] + jb .LoopHeader + jmp .LoopEnd +.LoopInit: + mov rdi, rbx + call benchmark::State::StartKeepRunning() + jmp .LoopBody +.LoopEnd: +``` + +Unless C++03 compatibility is required, the ranged-for variant of writing +the benchmark loop should be preferred. + + + +### Disabling CPU Frequency Scaling +If you see this error: +``` +***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead. +``` +you might want to disable the CPU frequency scaling while running the benchmark: +```bash +sudo cpupower frequency-set --governor performance +./mybench +sudo cpupower frequency-set --governor powersave +``` diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/WORKSPACE b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/WORKSPACE new file mode 100644 index 000000000..9a75f968d --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/WORKSPACE @@ -0,0 +1,9 @@ +workspace(name = "com_github_google_benchmark") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "com_google_googletest", + urls = ["https://github.com/google/googletest/archive/3f0cf6b62ad1eb50d8736538363d3580dd640c3e.zip"], + strip_prefix = "googletest-3f0cf6b62ad1eb50d8736538363d3580dd640c3e", +) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/_config.yml b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/_config.yml new file mode 100644 index 000000000..18854876c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-midnight \ No newline at end of file diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/appveyor.yml b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/appveyor.yml new file mode 100644 index 000000000..cf240190b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/appveyor.yml @@ -0,0 +1,50 @@ +version: '{build}' + +image: Visual Studio 2017 + +configuration: + - Debug + - Release + +environment: + matrix: + - compiler: msvc-15-seh + generator: "Visual Studio 15 2017" + + - compiler: msvc-15-seh + generator: "Visual Studio 15 2017 Win64" + + - compiler: msvc-14-seh + generator: "Visual Studio 14 2015" + + - compiler: msvc-14-seh + generator: "Visual Studio 14 2015 Win64" + + - compiler: gcc-5.3.0-posix + generator: "MinGW Makefiles" + cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin' + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + +matrix: + fast_finish: true + +install: + # git bash conflicts with MinGW makefiles + - if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%") + - if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%") + +build_script: + - md _build -Force + - cd _build + - echo %configuration% + - cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%configuration%" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON .. + - cmake --build . --config %configuration% + +test_script: + - ctest -c %configuration% --timeout 300 --output-on-failure + +artifacts: + - path: '_build/CMakeFiles/*.log' + name: logs + - path: '_build/Testing/**/*.xml' + name: test_results diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/AddCXXCompilerFlag.cmake b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/AddCXXCompilerFlag.cmake new file mode 100644 index 000000000..d0d209981 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/AddCXXCompilerFlag.cmake @@ -0,0 +1,74 @@ +# - Adds a compiler flag if it is supported by the compiler +# +# This function checks that the supplied compiler flag is supported and then +# adds it to the corresponding compiler flags +# +# add_cxx_compiler_flag( []) +# +# - Example +# +# include(AddCXXCompilerFlag) +# add_cxx_compiler_flag(-Wall) +# add_cxx_compiler_flag(-no-strict-aliasing RELEASE) +# Requires CMake 2.6+ + +if(__add_cxx_compiler_flag) + return() +endif() +set(__add_cxx_compiler_flag INCLUDED) + +include(CheckCXXCompilerFlag) + +function(mangle_compiler_flag FLAG OUTPUT) + string(TOUPPER "HAVE_CXX_FLAG_${FLAG}" SANITIZED_FLAG) + string(REPLACE "+" "X" SANITIZED_FLAG ${SANITIZED_FLAG}) + string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) + string(REGEX REPLACE "_+" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) + set(${OUTPUT} "${SANITIZED_FLAG}" PARENT_SCOPE) +endfunction(mangle_compiler_flag) + +function(add_cxx_compiler_flag FLAG) + mangle_compiler_flag("${FLAG}" MANGLED_FLAG) + set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}") + check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG}) + set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}") + if(${MANGLED_FLAG}) + set(VARIANT ${ARGV1}) + if(ARGV1) + string(TOUPPER "_${VARIANT}" VARIANT) + endif() + set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${BENCHMARK_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE) + endif() +endfunction() + +function(add_required_cxx_compiler_flag FLAG) + mangle_compiler_flag("${FLAG}" MANGLED_FLAG) + set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}") + check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG}) + set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}") + if(${MANGLED_FLAG}) + set(VARIANT ${ARGV1}) + if(ARGV1) + string(TOUPPER "_${VARIANT}" VARIANT) + endif() + set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE) + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}" PARENT_SCOPE) + else() + message(FATAL_ERROR "Required flag '${FLAG}' is not supported by the compiler") + endif() +endfunction() + +function(check_cxx_warning_flag FLAG) + mangle_compiler_flag("${FLAG}" MANGLED_FLAG) + set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + # Add -Werror to ensure the compiler generates an error if the warning flag + # doesn't exist. + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror ${FLAG}") + check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG}) + set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}") +endfunction() diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/CXXFeatureCheck.cmake b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/CXXFeatureCheck.cmake new file mode 100644 index 000000000..99b56dd62 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/CXXFeatureCheck.cmake @@ -0,0 +1,64 @@ +# - Compile and run code to check for C++ features +# +# This functions compiles a source file under the `cmake` folder +# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake +# environment +# +# cxx_feature_check( []) +# +# - Example +# +# include(CXXFeatureCheck) +# cxx_feature_check(STD_REGEX) +# Requires CMake 2.8.12+ + +if(__cxx_feature_check) + return() +endif() +set(__cxx_feature_check INCLUDED) + +function(cxx_feature_check FILE) + string(TOLOWER ${FILE} FILE) + string(TOUPPER ${FILE} VAR) + string(TOUPPER "HAVE_${VAR}" FEATURE) + if (DEFINED HAVE_${VAR}) + set(HAVE_${VAR} 1 PARENT_SCOPE) + add_definitions(-DHAVE_${VAR}) + return() + endif() + + if (NOT DEFINED COMPILE_${FEATURE}) + message(STATUS "Performing Test ${FEATURE}") + if(CMAKE_CROSSCOMPILING) + try_compile(COMPILE_${FEATURE} + ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp + CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS} + LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}) + if(COMPILE_${FEATURE}) + message(WARNING + "If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0") + set(RUN_${FEATURE} 0) + else() + set(RUN_${FEATURE} 1) + endif() + else() + message(STATUS "Performing Test ${FEATURE}") + try_run(RUN_${FEATURE} COMPILE_${FEATURE} + ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp + CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS} + LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}) + endif() + endif() + + if(RUN_${FEATURE} EQUAL 0) + message(STATUS "Performing Test ${FEATURE} -- success") + set(HAVE_${VAR} 1 PARENT_SCOPE) + add_definitions(-DHAVE_${VAR}) + else() + if(NOT COMPILE_${FEATURE}) + message(STATUS "Performing Test ${FEATURE} -- failed to compile") + else() + message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run") + endif() + endif() +endfunction() diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/Config.cmake.in b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/Config.cmake.in new file mode 100644 index 000000000..6e9256eea --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/Config.cmake.in @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GetGitVersion.cmake b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GetGitVersion.cmake new file mode 100644 index 000000000..4f10f226d --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GetGitVersion.cmake @@ -0,0 +1,54 @@ +# - Returns a version string from Git tags +# +# This function inspects the annotated git tags for the project and returns a string +# into a CMake variable +# +# get_git_version() +# +# - Example +# +# include(GetGitVersion) +# get_git_version(GIT_VERSION) +# +# Requires CMake 2.8.11+ +find_package(Git) + +if(__get_git_version) + return() +endif() +set(__get_git_version INCLUDED) + +function(get_git_version var) + if(GIT_EXECUTABLE) + execute_process(COMMAND ${GIT_EXECUTABLE} describe --match "v[0-9]*.[0-9]*.[0-9]*" --abbrev=8 + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + RESULT_VARIABLE status + OUTPUT_VARIABLE GIT_VERSION + ERROR_QUIET) + if(${status}) + set(GIT_VERSION "v0.0.0") + else() + string(STRIP ${GIT_VERSION} GIT_VERSION) + string(REGEX REPLACE "-[0-9]+-g" "-" GIT_VERSION ${GIT_VERSION}) + endif() + + # Work out if the repository is dirty + execute_process(COMMAND ${GIT_EXECUTABLE} update-index -q --refresh + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_QUIET + ERROR_QUIET) + execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_DIFF_INDEX + ERROR_QUIET) + string(COMPARE NOTEQUAL "${GIT_DIFF_INDEX}" "" GIT_DIRTY) + if (${GIT_DIRTY}) + set(GIT_VERSION "${GIT_VERSION}-dirty") + endif() + else() + set(GIT_VERSION "v0.0.0") + endif() + + message(STATUS "git Version: ${GIT_VERSION}") + set(${var} ${GIT_VERSION} PARENT_SCOPE) +endfunction() diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake new file mode 100644 index 000000000..fb7c6be25 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake @@ -0,0 +1,41 @@ +# Download and unpack googletest at configure time +set(GOOGLETEST_PREFIX "${benchmark_BINARY_DIR}/third_party/googletest") +configure_file(${benchmark_SOURCE_DIR}/cmake/GoogleTest.cmake.in ${GOOGLETEST_PREFIX}/CMakeLists.txt @ONLY) + +set(GOOGLETEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}/googletest") # Mind the quotes +execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" + -DALLOW_DOWNLOADING_GOOGLETEST=${BENCHMARK_DOWNLOAD_DEPENDENCIES} -DGOOGLETEST_PATH:PATH=${GOOGLETEST_PATH} . + RESULT_VARIABLE result + WORKING_DIRECTORY ${GOOGLETEST_PREFIX} +) + +if(result) + message(FATAL_ERROR "CMake step for googletest failed: ${result}") +endif() + +execute_process( + COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${GOOGLETEST_PREFIX} +) + +if(result) + message(FATAL_ERROR "Build step for googletest failed: ${result}") +endif() + +# Prevent overriding the parent project's compiler/linker +# settings on Windows +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +include(${GOOGLETEST_PREFIX}/googletest-paths.cmake) + +# Add googletest directly to our build. This defines +# the gtest and gtest_main targets. +add_subdirectory(${GOOGLETEST_SOURCE_DIR} + ${GOOGLETEST_BINARY_DIR} + EXCLUDE_FROM_ALL) + +set_target_properties(gtest PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) +set_target_properties(gtest_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) +set_target_properties(gmock PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) +set_target_properties(gmock_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake.in b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake.in new file mode 100644 index 000000000..28818ee29 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/GoogleTest.cmake.in @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 2.8.12) + +project(googletest-download NONE) + +# Enable ExternalProject CMake module +include(ExternalProject) + +option(ALLOW_DOWNLOADING_GOOGLETEST "If googletest src tree is not found in location specified by GOOGLETEST_PATH, do fetch the archive from internet" OFF) +set(GOOGLETEST_PATH "/usr/src/googletest" CACHE PATH + "Path to the googletest root tree. Should contain googletest and googlemock subdirs. And CMakeLists.txt in root, and in both of these subdirs") + +# Download and install GoogleTest + +message(STATUS "Looking for Google Test sources") +message(STATUS "Looking for Google Test sources in ${GOOGLETEST_PATH}") +if(EXISTS "${GOOGLETEST_PATH}" AND IS_DIRECTORY "${GOOGLETEST_PATH}" AND EXISTS "${GOOGLETEST_PATH}/CMakeLists.txt" AND + EXISTS "${GOOGLETEST_PATH}/googletest" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googletest" AND EXISTS "${GOOGLETEST_PATH}/googletest/CMakeLists.txt" AND + EXISTS "${GOOGLETEST_PATH}/googlemock" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googlemock" AND EXISTS "${GOOGLETEST_PATH}/googlemock/CMakeLists.txt") + message(STATUS "Found Google Test in ${GOOGLETEST_PATH}") + + ExternalProject_Add( + googletest + PREFIX "${CMAKE_BINARY_DIR}" + DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download" + SOURCE_DIR "${GOOGLETEST_PATH}" # use existing src dir. + BINARY_DIR "${CMAKE_BINARY_DIR}/build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" + ) +else() + if(NOT ALLOW_DOWNLOADING_GOOGLETEST) + message(SEND_ERROR "Did not find Google Test sources! Either pass correct path in GOOGLETEST_PATH, or enable ALLOW_DOWNLOADING_GOOGLETEST, or disable BENCHMARK_ENABLE_GTEST_TESTS / BENCHMARK_ENABLE_TESTING.") + else() + message(WARNING "Did not find Google Test sources! Fetching from web...") + ExternalProject_Add( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG master + PREFIX "${CMAKE_BINARY_DIR}" + STAMP_DIR "${CMAKE_BINARY_DIR}/stamp" + DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download" + SOURCE_DIR "${CMAKE_BINARY_DIR}/src" + BINARY_DIR "${CMAKE_BINARY_DIR}/build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" + ) + endif() +endif() + +ExternalProject_Get_Property(googletest SOURCE_DIR BINARY_DIR) +file(WRITE googletest-paths.cmake +"set(GOOGLETEST_SOURCE_DIR \"${SOURCE_DIR}\") +set(GOOGLETEST_BINARY_DIR \"${BINARY_DIR}\") +") diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/benchmark.pc.in b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/benchmark.pc.in new file mode 100644 index 000000000..43ca8f91d --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/benchmark.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: @PROJECT_NAME@ +Description: Google microbenchmark framework +Version: @VERSION@ + +Libs: -L${libdir} -lbenchmark +Libs.private: -lpthread +Cflags: -I${includedir} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/gnu_posix_regex.cpp b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/gnu_posix_regex.cpp new file mode 100644 index 000000000..b5b91cdab --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/gnu_posix_regex.cpp @@ -0,0 +1,12 @@ +#include +#include +int main() { + std::string str = "test0159"; + regex_t re; + int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB); + if (ec != 0) { + return ec; + } + return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0; +} + diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/llvm-toolchain.cmake b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/llvm-toolchain.cmake new file mode 100644 index 000000000..fc119e52f --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/llvm-toolchain.cmake @@ -0,0 +1,8 @@ +find_package(LLVMAr REQUIRED) +set(CMAKE_AR "${LLVMAR_EXECUTABLE}" CACHE FILEPATH "" FORCE) + +find_package(LLVMNm REQUIRED) +set(CMAKE_NM "${LLVMNM_EXECUTABLE}" CACHE FILEPATH "" FORCE) + +find_package(LLVMRanLib REQUIRED) +set(CMAKE_RANLIB "${LLVMRANLIB_EXECUTABLE}" CACHE FILEPATH "" FORCE) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/posix_regex.cpp b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/posix_regex.cpp new file mode 100644 index 000000000..466dc6256 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/posix_regex.cpp @@ -0,0 +1,14 @@ +#include +#include +int main() { + std::string str = "test0159"; + regex_t re; + int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB); + if (ec != 0) { + return ec; + } + int ret = regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0; + regfree(&re); + return ret; +} + diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/split_list.cmake b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/split_list.cmake new file mode 100644 index 000000000..67aed3fdc --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/split_list.cmake @@ -0,0 +1,3 @@ +macro(split_list listname) + string(REPLACE ";" " " ${listname} "${${listname}}") +endmacro() diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/std_regex.cpp b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/std_regex.cpp new file mode 100644 index 000000000..696f2a26b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/std_regex.cpp @@ -0,0 +1,10 @@ +#include +#include +int main() { + const std::string str = "test0159"; + std::regex re; + re = std::regex("^[a-z]+[0-9]+$", + std::regex_constants::extended | std::regex_constants::nosubs); + return std::regex_search(str, re) ? 0 : -1; +} + diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/steady_clock.cpp b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/steady_clock.cpp new file mode 100644 index 000000000..66d50d17e --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/steady_clock.cpp @@ -0,0 +1,7 @@ +#include + +int main() { + typedef std::chrono::steady_clock Clock; + Clock::time_point tp = Clock::now(); + ((void)tp); +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/thread_safety_attributes.cpp b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/thread_safety_attributes.cpp new file mode 100644 index 000000000..46161babd --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/cmake/thread_safety_attributes.cpp @@ -0,0 +1,4 @@ +#define HAVE_THREAD_SAFETY_ATTRIBUTES +#include "../src/mutex.h" + +int main() {} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/CMakeLists.txt new file mode 100644 index 000000000..15b92ca91 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8.11) +project(cmake_wrapper) + +include(conanbuildinfo.cmake) +conan_basic_setup() + +include(${CMAKE_SOURCE_DIR}/CMakeListsOriginal.txt) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/CMakeLists.txt new file mode 100644 index 000000000..089a6c729 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 2.8.11) +project(test_package) + +set(CMAKE_VERBOSE_MAKEFILE TRUE) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/conanfile.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/conanfile.py new file mode 100644 index 000000000..d63f4088c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/conanfile.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from conans import ConanFile, CMake +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + bin_path = os.path.join("bin", "test_package") + self.run(bin_path, run_environment=True) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/test_package.cpp b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/test_package.cpp new file mode 100644 index 000000000..4fa7ec0bf --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conan/test_package/test_package.cpp @@ -0,0 +1,18 @@ +#include "benchmark/benchmark.h" + +void BM_StringCreation(benchmark::State& state) { + while (state.KeepRunning()) + std::string empty_string; +} + +BENCHMARK(BM_StringCreation); + +void BM_StringCopy(benchmark::State& state) { + std::string x = "hello"; + while (state.KeepRunning()) + std::string copy(x); +} + +BENCHMARK(BM_StringCopy); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conanfile.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conanfile.py new file mode 100644 index 000000000..e31fc5268 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/conanfile.py @@ -0,0 +1,79 @@ +from conans import ConanFile, CMake, tools +from conans.errors import ConanInvalidConfiguration +import shutil +import os + + +class GoogleBenchmarkConan(ConanFile): + name = "benchmark" + description = "A microbenchmark support library." + topics = ("conan", "benchmark", "google", "microbenchmark") + url = "https://github.com/google/benchmark" + homepage = "https://github.com/google/benchmark" + author = "Google Inc." + license = "Apache-2.0" + exports_sources = ["*"] + generators = "cmake" + + settings = "arch", "build_type", "compiler", "os" + options = { + "shared": [True, False], + "fPIC": [True, False], + "enable_lto": [True, False], + "enable_exceptions": [True, False] + } + default_options = {"shared": False, "fPIC": True, "enable_lto": False, "enable_exceptions": True} + + _build_subfolder = "." + + def source(self): + # Wrap the original CMake file to call conan_basic_setup + shutil.move("CMakeLists.txt", "CMakeListsOriginal.txt") + shutil.move(os.path.join("conan", "CMakeLists.txt"), "CMakeLists.txt") + + def config_options(self): + if self.settings.os == "Windows": + if self.settings.compiler == "Visual Studio" and float(self.settings.compiler.version.value) <= 12: + raise ConanInvalidConfiguration("{} {} does not support Visual Studio <= 12".format(self.name, self.version)) + del self.options.fPIC + + def configure(self): + if self.settings.os == "Windows" and self.options.shared: + raise ConanInvalidConfiguration("Windows shared builds are not supported right now, see issue #639") + + def _configure_cmake(self): + cmake = CMake(self) + + cmake.definitions["BENCHMARK_ENABLE_TESTING"] = "OFF" + cmake.definitions["BENCHMARK_ENABLE_GTEST_TESTS"] = "OFF" + cmake.definitions["BENCHMARK_ENABLE_LTO"] = "ON" if self.options.enable_lto else "OFF" + cmake.definitions["BENCHMARK_ENABLE_EXCEPTIONS"] = "ON" if self.options.enable_exceptions else "OFF" + + # See https://github.com/google/benchmark/pull/638 for Windows 32 build explanation + if self.settings.os != "Windows": + cmake.definitions["BENCHMARK_BUILD_32_BITS"] = "ON" if "64" not in str(self.settings.arch) else "OFF" + cmake.definitions["BENCHMARK_USE_LIBCXX"] = "ON" if (str(self.settings.compiler.libcxx) == "libc++") else "OFF" + else: + cmake.definitions["BENCHMARK_USE_LIBCXX"] = "OFF" + + cmake.configure(build_folder=self._build_subfolder) + return cmake + + def build(self): + cmake = self._configure_cmake() + cmake.build() + + def package(self): + cmake = self._configure_cmake() + cmake.install() + + self.copy(pattern="LICENSE", dst="licenses") + + def package_info(self): + self.cpp_info.libs = tools.collect_libs(self) + if self.settings.os == "Linux": + self.cpp_info.libs.extend(["pthread", "rt"]) + elif self.settings.os == "Windows": + self.cpp_info.libs.append("shlwapi") + elif self.settings.os == "SunOS": + self.cpp_info.libs.append("kstat") diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/dependencies.md b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/dependencies.md new file mode 100644 index 000000000..6289b4e35 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/dependencies.md @@ -0,0 +1,18 @@ +# Build tool dependency policy + +To ensure the broadest compatibility when building the benchmark library, but +still allow forward progress, we require any build tooling to be available for: + +* Debian stable AND +* The last two Ubuntu LTS releases AND + +Currently, this means using build tool versions that are available for Ubuntu +16.04 (Xenial), Ubuntu 18.04 (Bionic), and Debian stretch. + +_Note, [travis](.travis.yml) runs under Ubuntu 14.04 (Trusty) for linux builds._ + +## cmake +The current supported version is cmake 3.5.1 as of 2018-06-06. + +_Note, this version is also available for Ubuntu 14.04, the previous Ubuntu LTS +release, as `cmake3`._ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/AssemblyTests.md b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/AssemblyTests.md new file mode 100644 index 000000000..1fbdc269b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/AssemblyTests.md @@ -0,0 +1,147 @@ +# Assembly Tests + +The Benchmark library provides a number of functions whose primary +purpose in to affect assembly generation, including `DoNotOptimize` +and `ClobberMemory`. In addition there are other functions, +such as `KeepRunning`, for which generating good assembly is paramount. + +For these functions it's important to have tests that verify the +correctness and quality of the implementation. This requires testing +the code generated by the compiler. + +This document describes how the Benchmark library tests compiler output, +as well as how to properly write new tests. + + +## Anatomy of a Test + +Writing a test has two steps: + +* Write the code you want to generate assembly for. +* Add `// CHECK` lines to match against the verified assembly. + +Example: +```c++ + +// CHECK-LABEL: test_add: +extern "C" int test_add() { + extern int ExternInt; + return ExternInt + 1; + + // CHECK: movl ExternInt(%rip), %eax + // CHECK: addl %eax + // CHECK: ret +} + +``` + +#### LLVM Filecheck + +[LLVM's Filecheck](https://llvm.org/docs/CommandGuide/FileCheck.html) +is used to test the generated assembly against the `// CHECK` lines +specified in the tests source file. Please see the documentation +linked above for information on how to write `CHECK` directives. + +#### Tips and Tricks: + +* Tests should match the minimal amount of output required to establish +correctness. `CHECK` directives don't have to match on the exact next line +after the previous match, so tests should omit checks for unimportant +bits of assembly. ([`CHECK-NEXT`](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-next-directive) +can be used to ensure a match occurs exactly after the previous match). + +* The tests are compiled with `-O3 -g0`. So we're only testing the +optimized output. + +* The assembly output is further cleaned up using `tools/strip_asm.py`. +This removes comments, assembler directives, and unused labels before +the test is run. + +* The generated and stripped assembly file for a test is output under +`/test/.s` + +* Filecheck supports using [`CHECK` prefixes](https://llvm.org/docs/CommandGuide/FileCheck.html#cmdoption-check-prefixes) +to specify lines that should only match in certain situations. +The Benchmark tests use `CHECK-CLANG` and `CHECK-GNU` for lines that +are only expected to match Clang or GCC's output respectively. Normal +`CHECK` lines match against all compilers. (Note: `CHECK-NOT` and +`CHECK-LABEL` are NOT prefixes. They are versions of non-prefixed +`CHECK` lines) + +* Use `extern "C"` to disable name mangling for specific functions. This +makes them easier to name in the `CHECK` lines. + + +## Problems Writing Portable Tests + +Writing tests which check the code generated by a compiler are +inherently non-portable. Different compilers and even different compiler +versions may generate entirely different code. The Benchmark tests +must tolerate this. + +LLVM Filecheck provides a number of mechanisms to help write +"more portable" tests; including [matching using regular expressions](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-pattern-matching-syntax), +allowing the creation of [named variables](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-variables) +for later matching, and [checking non-sequential matches](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-dag-directive). + +#### Capturing Variables + +For example, say GCC stores a variable in a register but Clang stores +it in memory. To write a test that tolerates both cases we "capture" +the destination of the store, and then use the captured expression +to write the remainder of the test. + +```c++ +// CHECK-LABEL: test_div_no_op_into_shr: +extern "C" void test_div_no_op_into_shr(int value) { + int divisor = 2; + benchmark::DoNotOptimize(divisor); // hide the value from the optimizer + return value / divisor; + + // CHECK: movl $2, [[DEST:.*]] + // CHECK: idivl [[DEST]] + // CHECK: ret +} +``` + +#### Using Regular Expressions to Match Differing Output + +Often tests require testing assembly lines which may subtly differ +between compilers or compiler versions. A common example of this +is matching stack frame addresses. In this case regular expressions +can be used to match the differing bits of output. For example: + +```c++ +int ExternInt; +struct Point { int x, y, z; }; + +// CHECK-LABEL: test_store_point: +extern "C" void test_store_point() { + Point p{ExternInt, ExternInt, ExternInt}; + benchmark::DoNotOptimize(p); + + // CHECK: movl ExternInt(%rip), %eax + // CHECK: movl %eax, -{{[0-9]+}}(%rsp) + // CHECK: movl %eax, -{{[0-9]+}}(%rsp) + // CHECK: movl %eax, -{{[0-9]+}}(%rsp) + // CHECK: ret +} +``` + +## Current Requirements and Limitations + +The tests require Filecheck to be installed along the `PATH` of the +build machine. Otherwise the tests will be disabled. + +Additionally, as mentioned in the previous section, codegen tests are +inherently non-portable. Currently the tests are limited to: + +* x86_64 targets. +* Compiled with GCC or Clang + +Further work could be done, at least on a limited basis, to extend the +tests to other architectures and compilers (using `CHECK` prefixes). + +Furthermore, the tests fail for builds which specify additional flags +that modify code generation, including `--coverage` or `-fsanitize=`. + diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/_config.yml b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/_config.yml new file mode 100644 index 000000000..18854876c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-midnight \ No newline at end of file diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/tools.md b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/tools.md new file mode 100644 index 000000000..4a3b2e9bd --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/docs/tools.md @@ -0,0 +1,199 @@ +# Benchmark Tools + +## compare.py + +The `compare.py` can be used to compare the result of benchmarks. + +**NOTE**: the utility relies on the scipy package which can be installed using [these instructions](https://www.scipy.org/install.html). + +### Displaying aggregates only + +The switch `-a` / `--display_aggregates_only` can be used to control the +displayment of the normal iterations vs the aggregates. When passed, it will +be passthrough to the benchmark binaries to be run, and will be accounted for +in the tool itself; only the aggregates will be displayed, but not normal runs. +It only affects the display, the separate runs will still be used to calculate +the U test. + +### Modes of operation + +There are three modes of operation: + +1. Just compare two benchmarks +The program is invoked like: + +``` bash +$ compare.py benchmarks [benchmark options]... +``` +Where `` and `` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file. + +`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes. + +Example output: +``` +$ ./compare.py benchmarks ./a.out ./a.out +RUNNING: ./a.out --benchmark_out=/tmp/tmprBT5nW +Run on (8 X 4000 MHz CPU s) +2017-11-07 21:16:44 +------------------------------------------------------ +Benchmark Time CPU Iterations +------------------------------------------------------ +BM_memcpy/8 36 ns 36 ns 19101577 211.669MB/s +BM_memcpy/64 76 ns 76 ns 9412571 800.199MB/s +BM_memcpy/512 84 ns 84 ns 8249070 5.64771GB/s +BM_memcpy/1024 116 ns 116 ns 6181763 8.19505GB/s +BM_memcpy/8192 643 ns 643 ns 1062855 11.8636GB/s +BM_copy/8 222 ns 222 ns 3137987 34.3772MB/s +BM_copy/64 1608 ns 1608 ns 432758 37.9501MB/s +BM_copy/512 12589 ns 12589 ns 54806 38.7867MB/s +BM_copy/1024 25169 ns 25169 ns 27713 38.8003MB/s +BM_copy/8192 201165 ns 201112 ns 3486 38.8466MB/s +RUNNING: ./a.out --benchmark_out=/tmp/tmpt1wwG_ +Run on (8 X 4000 MHz CPU s) +2017-11-07 21:16:53 +------------------------------------------------------ +Benchmark Time CPU Iterations +------------------------------------------------------ +BM_memcpy/8 36 ns 36 ns 19397903 211.255MB/s +BM_memcpy/64 73 ns 73 ns 9691174 839.635MB/s +BM_memcpy/512 85 ns 85 ns 8312329 5.60101GB/s +BM_memcpy/1024 118 ns 118 ns 6438774 8.11608GB/s +BM_memcpy/8192 656 ns 656 ns 1068644 11.6277GB/s +BM_copy/8 223 ns 223 ns 3146977 34.2338MB/s +BM_copy/64 1611 ns 1611 ns 435340 37.8751MB/s +BM_copy/512 12622 ns 12622 ns 54818 38.6844MB/s +BM_copy/1024 25257 ns 25239 ns 27779 38.6927MB/s +BM_copy/8192 205013 ns 205010 ns 3479 38.108MB/s +Comparing ./a.out to ./a.out +Benchmark Time CPU Time Old Time New CPU Old CPU New +------------------------------------------------------------------------------------------------------ +BM_memcpy/8 +0.0020 +0.0020 36 36 36 36 +BM_memcpy/64 -0.0468 -0.0470 76 73 76 73 +BM_memcpy/512 +0.0081 +0.0083 84 85 84 85 +BM_memcpy/1024 +0.0098 +0.0097 116 118 116 118 +BM_memcpy/8192 +0.0200 +0.0203 643 656 643 656 +BM_copy/8 +0.0046 +0.0042 222 223 222 223 +BM_copy/64 +0.0020 +0.0020 1608 1611 1608 1611 +BM_copy/512 +0.0027 +0.0026 12589 12622 12589 12622 +BM_copy/1024 +0.0035 +0.0028 25169 25257 25169 25239 +BM_copy/8192 +0.0191 +0.0194 201165 205013 201112 205010 +``` + +What it does is for the every benchmark from the first run it looks for the benchmark with exactly the same name in the second run, and then compares the results. If the names differ, the benchmark is omitted from the diff. +As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`. + +2. Compare two different filters of one benchmark +The program is invoked like: + +``` bash +$ compare.py filters [benchmark options]... +``` +Where `` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file. + +Where `` and `` are the same regex filters that you would pass to the `[--benchmark_filter=]` parameter of the benchmark binary. + +`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes. + +Example output: +``` +$ ./compare.py filters ./a.out BM_memcpy BM_copy +RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmpBWKk0k +Run on (8 X 4000 MHz CPU s) +2017-11-07 21:37:28 +------------------------------------------------------ +Benchmark Time CPU Iterations +------------------------------------------------------ +BM_memcpy/8 36 ns 36 ns 17891491 211.215MB/s +BM_memcpy/64 74 ns 74 ns 9400999 825.646MB/s +BM_memcpy/512 87 ns 87 ns 8027453 5.46126GB/s +BM_memcpy/1024 111 ns 111 ns 6116853 8.5648GB/s +BM_memcpy/8192 657 ns 656 ns 1064679 11.6247GB/s +RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpAvWcOM +Run on (8 X 4000 MHz CPU s) +2017-11-07 21:37:33 +---------------------------------------------------- +Benchmark Time CPU Iterations +---------------------------------------------------- +BM_copy/8 227 ns 227 ns 3038700 33.6264MB/s +BM_copy/64 1640 ns 1640 ns 426893 37.2154MB/s +BM_copy/512 12804 ns 12801 ns 55417 38.1444MB/s +BM_copy/1024 25409 ns 25407 ns 27516 38.4365MB/s +BM_copy/8192 202986 ns 202990 ns 3454 38.4871MB/s +Comparing BM_memcpy to BM_copy (from ./a.out) +Benchmark Time CPU Time Old Time New CPU Old CPU New +-------------------------------------------------------------------------------------------------------------------- +[BM_memcpy vs. BM_copy]/8 +5.2829 +5.2812 36 227 36 227 +[BM_memcpy vs. BM_copy]/64 +21.1719 +21.1856 74 1640 74 1640 +[BM_memcpy vs. BM_copy]/512 +145.6487 +145.6097 87 12804 87 12801 +[BM_memcpy vs. BM_copy]/1024 +227.1860 +227.1776 111 25409 111 25407 +[BM_memcpy vs. BM_copy]/8192 +308.1664 +308.2898 657 202986 656 202990 +``` + +As you can see, it applies filter to the benchmarks, both when running the benchmark, and before doing the diff. And to make the diff work, the matches are replaced with some common string. Thus, you can compare two different benchmark families within one benchmark binary. +As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`. + +3. Compare filter one from benchmark one to filter two from benchmark two: +The program is invoked like: + +``` bash +$ compare.py filters [benchmark options]... +``` + +Where `` and `` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file. + +Where `` and `` are the same regex filters that you would pass to the `[--benchmark_filter=]` parameter of the benchmark binary. + +`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes. + +Example output: +``` +$ ./compare.py benchmarksfiltered ./a.out BM_memcpy ./a.out BM_copy +RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmp_FvbYg +Run on (8 X 4000 MHz CPU s) +2017-11-07 21:38:27 +------------------------------------------------------ +Benchmark Time CPU Iterations +------------------------------------------------------ +BM_memcpy/8 37 ns 37 ns 18953482 204.118MB/s +BM_memcpy/64 74 ns 74 ns 9206578 828.245MB/s +BM_memcpy/512 91 ns 91 ns 8086195 5.25476GB/s +BM_memcpy/1024 120 ns 120 ns 5804513 7.95662GB/s +BM_memcpy/8192 664 ns 664 ns 1028363 11.4948GB/s +RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpDfL5iE +Run on (8 X 4000 MHz CPU s) +2017-11-07 21:38:32 +---------------------------------------------------- +Benchmark Time CPU Iterations +---------------------------------------------------- +BM_copy/8 230 ns 230 ns 2985909 33.1161MB/s +BM_copy/64 1654 ns 1653 ns 419408 36.9137MB/s +BM_copy/512 13122 ns 13120 ns 53403 37.2156MB/s +BM_copy/1024 26679 ns 26666 ns 26575 36.6218MB/s +BM_copy/8192 215068 ns 215053 ns 3221 36.3283MB/s +Comparing BM_memcpy (from ./a.out) to BM_copy (from ./a.out) +Benchmark Time CPU Time Old Time New CPU Old CPU New +-------------------------------------------------------------------------------------------------------------------- +[BM_memcpy vs. BM_copy]/8 +5.1649 +5.1637 37 230 37 230 +[BM_memcpy vs. BM_copy]/64 +21.4352 +21.4374 74 1654 74 1653 +[BM_memcpy vs. BM_copy]/512 +143.6022 +143.5865 91 13122 91 13120 +[BM_memcpy vs. BM_copy]/1024 +221.5903 +221.4790 120 26679 120 26666 +[BM_memcpy vs. BM_copy]/8192 +322.9059 +323.0096 664 215068 664 215053 +``` +This is a mix of the previous two modes, two (potentially different) benchmark binaries are run, and a different filter is applied to each one. +As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`. + +### U test + +If there is a sufficient repetition count of the benchmarks, the tool can do +a [U Test](https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test), of the +null hypothesis that it is equally likely that a randomly selected value from +one sample will be less than or greater than a randomly selected value from a +second sample. + +If the calculated p-value is below this value is lower than the significance +level alpha, then the result is said to be statistically significant and the +null hypothesis is rejected. Which in other words means that the two benchmarks +aren't identical. + +**WARNING**: requires **LARGE** (no less than 9) number of repetitions to be +meaningful! diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/include/benchmark/benchmark.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/include/benchmark/benchmark.h new file mode 100644 index 000000000..6cb96f546 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/include/benchmark/benchmark.h @@ -0,0 +1,1583 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Support for registering benchmarks for functions. + +/* Example usage: +// Define a function that executes the code to be measured a +// specified number of times: +static void BM_StringCreation(benchmark::State& state) { + for (auto _ : state) + std::string empty_string; +} + +// Register the function as a benchmark +BENCHMARK(BM_StringCreation); + +// Define another benchmark +static void BM_StringCopy(benchmark::State& state) { + std::string x = "hello"; + for (auto _ : state) + std::string copy(x); +} +BENCHMARK(BM_StringCopy); + +// Augment the main() program to invoke benchmarks if specified +// via the --benchmarks command line flag. E.g., +// my_unittest --benchmark_filter=all +// my_unittest --benchmark_filter=BM_StringCreation +// my_unittest --benchmark_filter=String +// my_unittest --benchmark_filter='Copy|Creation' +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); + return 0; +} + +// Sometimes a family of microbenchmarks can be implemented with +// just one routine that takes an extra argument to specify which +// one of the family of benchmarks to run. For example, the following +// code defines a family of microbenchmarks for measuring the speed +// of memcpy() calls of different lengths: + +static void BM_memcpy(benchmark::State& state) { + char* src = new char[state.range(0)]; char* dst = new char[state.range(0)]; + memset(src, 'x', state.range(0)); + for (auto _ : state) + memcpy(dst, src, state.range(0)); + state.SetBytesProcessed(state.iterations() * state.range(0)); + delete[] src; delete[] dst; +} +BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10); + +// The preceding code is quite repetitive, and can be replaced with the +// following short-hand. The following invocation will pick a few +// appropriate arguments in the specified range and will generate a +// microbenchmark for each such argument. +BENCHMARK(BM_memcpy)->Range(8, 8<<10); + +// You might have a microbenchmark that depends on two inputs. For +// example, the following code defines a family of microbenchmarks for +// measuring the speed of set insertion. +static void BM_SetInsert(benchmark::State& state) { + set data; + for (auto _ : state) { + state.PauseTiming(); + data = ConstructRandomSet(state.range(0)); + state.ResumeTiming(); + for (int j = 0; j < state.range(1); ++j) + data.insert(RandomNumber()); + } +} +BENCHMARK(BM_SetInsert) + ->Args({1<<10, 128}) + ->Args({2<<10, 128}) + ->Args({4<<10, 128}) + ->Args({8<<10, 128}) + ->Args({1<<10, 512}) + ->Args({2<<10, 512}) + ->Args({4<<10, 512}) + ->Args({8<<10, 512}); + +// The preceding code is quite repetitive, and can be replaced with +// the following short-hand. The following macro will pick a few +// appropriate arguments in the product of the two specified ranges +// and will generate a microbenchmark for each such pair. +BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}}); + +// For more complex patterns of inputs, passing a custom function +// to Apply allows programmatic specification of an +// arbitrary set of arguments to run the microbenchmark on. +// The following example enumerates a dense range on +// one parameter, and a sparse range on the second. +static void CustomArguments(benchmark::internal::Benchmark* b) { + for (int i = 0; i <= 10; ++i) + for (int j = 32; j <= 1024*1024; j *= 8) + b->Args({i, j}); +} +BENCHMARK(BM_SetInsert)->Apply(CustomArguments); + +// Templated microbenchmarks work the same way: +// Produce then consume 'size' messages 'iters' times +// Measures throughput in the absence of multiprogramming. +template int BM_Sequential(benchmark::State& state) { + Q q; + typename Q::value_type v; + for (auto _ : state) { + for (int i = state.range(0); i--; ) + q.push(v); + for (int e = state.range(0); e--; ) + q.Wait(&v); + } + // actually messages, not bytes: + state.SetBytesProcessed(state.iterations() * state.range(0)); +} +BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10); + +Use `Benchmark::MinTime(double t)` to set the minimum time used to run the +benchmark. This option overrides the `benchmark_min_time` flag. + +void BM_test(benchmark::State& state) { + ... body ... +} +BENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds. + +In a multithreaded test, it is guaranteed that none of the threads will start +until all have reached the loop start, and all will have finished before any +thread exits the loop body. As such, any global setup or teardown you want to +do can be wrapped in a check against the thread index: + +static void BM_MultiThreaded(benchmark::State& state) { + if (state.thread_index == 0) { + // Setup code here. + } + for (auto _ : state) { + // Run the test as normal. + } + if (state.thread_index == 0) { + // Teardown code here. + } +} +BENCHMARK(BM_MultiThreaded)->Threads(4); + + +If a benchmark runs a few milliseconds it may be hard to visually compare the +measured times, since the output data is given in nanoseconds per default. In +order to manually set the time unit, you can specify it manually: + +BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); +*/ + +#ifndef BENCHMARK_BENCHMARK_H_ +#define BENCHMARK_BENCHMARK_H_ + +// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer. +#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) +#define BENCHMARK_HAS_CXX11 +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BENCHMARK_HAS_CXX11) +#include +#include +#include +#endif + +#if defined(_MSC_VER) +#include // for _ReadWriteBarrier +#endif + +#ifndef BENCHMARK_HAS_CXX11 +#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + TypeName& operator=(const TypeName&) +#else +#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + TypeName& operator=(const TypeName&) = delete +#endif + +#if defined(__GNUC__) +#define BENCHMARK_UNUSED __attribute__((unused)) +#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline)) +#define BENCHMARK_NOEXCEPT noexcept +#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x) +#elif defined(_MSC_VER) && !defined(__clang__) +#define BENCHMARK_UNUSED +#define BENCHMARK_ALWAYS_INLINE __forceinline +#if _MSC_VER >= 1900 +#define BENCHMARK_NOEXCEPT noexcept +#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x) +#else +#define BENCHMARK_NOEXCEPT +#define BENCHMARK_NOEXCEPT_OP(x) +#endif +#define __func__ __FUNCTION__ +#else +#define BENCHMARK_UNUSED +#define BENCHMARK_ALWAYS_INLINE +#define BENCHMARK_NOEXCEPT +#define BENCHMARK_NOEXCEPT_OP(x) +#endif + +#define BENCHMARK_INTERNAL_TOSTRING2(x) #x +#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x) + +#if defined(__GNUC__) || defined(__clang__) +#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y) +#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) +#else +#define BENCHMARK_BUILTIN_EXPECT(x, y) x +#define BENCHMARK_DEPRECATED_MSG(msg) +#define BENCHMARK_WARNING_MSG(msg) \ + __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \ + __LINE__) ") : warning note: " msg)) +#endif + +#if defined(__GNUC__) && !defined(__clang__) +#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +#if defined(__GNUC__) || __has_builtin(__builtin_unreachable) +#define BENCHMARK_UNREACHABLE() __builtin_unreachable() +#elif defined(_MSC_VER) +#define BENCHMARK_UNREACHABLE() __assume(false) +#else +#define BENCHMARK_UNREACHABLE() ((void)0) +#endif + +namespace benchmark { +class BenchmarkReporter; +class MemoryManager; + +void Initialize(int* argc, char** argv); + +// Report to stdout all arguments in 'argv' as unrecognized except the first. +// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1). +bool ReportUnrecognizedArguments(int argc, char** argv); + +// Generate a list of benchmarks matching the specified --benchmark_filter flag +// and if --benchmark_list_tests is specified return after printing the name +// of each matching benchmark. Otherwise run each matching benchmark and +// report the results. +// +// The second and third overload use the specified 'display_reporter' and +// 'file_reporter' respectively. 'file_reporter' will write to the file +// specified +// by '--benchmark_output'. If '--benchmark_output' is not given the +// 'file_reporter' is ignored. +// +// RETURNS: The number of matching benchmarks. +size_t RunSpecifiedBenchmarks(); +size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter); +size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, + BenchmarkReporter* file_reporter); + +// Register a MemoryManager instance that will be used to collect and report +// allocation measurements for benchmark runs. +void RegisterMemoryManager(MemoryManager* memory_manager); + +namespace internal { +class Benchmark; +class BenchmarkImp; +class BenchmarkFamilies; + +void UseCharPointer(char const volatile*); + +// Take ownership of the pointer and register the benchmark. Return the +// registered benchmark. +Benchmark* RegisterBenchmarkInternal(Benchmark*); + +// Ensure that the standard streams are properly initialized in every TU. +int InitializeStreams(); +BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams(); + +} // namespace internal + +#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \ + defined(__EMSCRIPTEN__) +#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY +#endif + +// The DoNotOptimize(...) function can be used to prevent a value or +// expression from being optimized away by the compiler. This function is +// intended to add little to no overhead. +// See: https://youtu.be/nXaxk27zwlk?t=2441 +#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY +template +inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { + asm volatile("" : : "r,m"(value) : "memory"); +} + +template +inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { +#if defined(__clang__) + asm volatile("" : "+r,m"(value) : : "memory"); +#else + asm volatile("" : "+m,r"(value) : : "memory"); +#endif +} + +// Force the compiler to flush pending writes to global memory. Acts as an +// effective read/write barrier +inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { + asm volatile("" : : : "memory"); +} +#elif defined(_MSC_VER) +template +inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { + internal::UseCharPointer(&reinterpret_cast(value)); + _ReadWriteBarrier(); +} + +inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); } +#else +template +inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { + internal::UseCharPointer(&reinterpret_cast(value)); +} +// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers +#endif + +// This class is used for user-defined counters. +class Counter { + public: + enum Flags { + kDefaults = 0, + // Mark the counter as a rate. It will be presented divided + // by the duration of the benchmark. + kIsRate = 1U << 0U, + // Mark the counter as a thread-average quantity. It will be + // presented divided by the number of threads. + kAvgThreads = 1U << 1U, + // Mark the counter as a thread-average rate. See above. + kAvgThreadsRate = kIsRate | kAvgThreads, + // Mark the counter as a constant value, valid/same for *every* iteration. + // When reporting, it will be *multiplied* by the iteration count. + kIsIterationInvariant = 1U << 2U, + // Mark the counter as a constant rate. + // When reporting, it will be *multiplied* by the iteration count + // and then divided by the duration of the benchmark. + kIsIterationInvariantRate = kIsRate | kIsIterationInvariant, + // Mark the counter as a iteration-average quantity. + // It will be presented divided by the number of iterations. + kAvgIterations = 1U << 3U, + // Mark the counter as a iteration-average rate. See above. + kAvgIterationsRate = kIsRate | kAvgIterations + }; + + enum OneK { + // 1'000 items per 1k + kIs1000 = 1000, + // 1'024 items per 1k + kIs1024 = 1024 + }; + + double value; + Flags flags; + OneK oneK; + + BENCHMARK_ALWAYS_INLINE + Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000) + : value(v), flags(f), oneK(k) {} + + BENCHMARK_ALWAYS_INLINE operator double const&() const { return value; } + BENCHMARK_ALWAYS_INLINE operator double&() { return value; } +}; + +// A helper for user code to create unforeseen combinations of Flags, without +// having to do this cast manually each time, or providing this operator. +Counter::Flags inline operator|(const Counter::Flags& LHS, + const Counter::Flags& RHS) { + return static_cast(static_cast(LHS) | + static_cast(RHS)); +} + +// This is the container for the user-defined counters. +typedef std::map UserCounters; + +// TimeUnit is passed to a benchmark in order to specify the order of magnitude +// for the measured time. +enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond }; + +// BigO is passed to a benchmark in order to specify the asymptotic +// computational +// complexity for the benchmark. In case oAuto is selected, complexity will be +// calculated automatically to the best fit. +enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda }; + +typedef uint64_t IterationCount; + +// BigOFunc is passed to a benchmark in order to specify the asymptotic +// computational complexity for the benchmark. +typedef double(BigOFunc)(IterationCount); + +// StatisticsFunc is passed to a benchmark in order to compute some descriptive +// statistics over all the measurements of some type +typedef double(StatisticsFunc)(const std::vector&); + +namespace internal { +struct Statistics { + std::string name_; + StatisticsFunc* compute_; + + Statistics(const std::string& name, StatisticsFunc* compute) + : name_(name), compute_(compute) {} +}; + +struct BenchmarkInstance; +class ThreadTimer; +class ThreadManager; + +enum AggregationReportMode +#if defined(BENCHMARK_HAS_CXX11) + : unsigned +#else +#endif +{ + // The mode has not been manually specified + ARM_Unspecified = 0, + // The mode is user-specified. + // This may or may not be set when the following bit-flags are set. + ARM_Default = 1U << 0U, + // File reporter should only output aggregates. + ARM_FileReportAggregatesOnly = 1U << 1U, + // Display reporter should only output aggregates + ARM_DisplayReportAggregatesOnly = 1U << 2U, + // Both reporters should only display aggregates. + ARM_ReportAggregatesOnly = + ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly +}; + +} // namespace internal + +// State is passed to a running Benchmark and contains state for the +// benchmark to use. +class State { + public: + struct StateIterator; + friend struct StateIterator; + + // Returns iterators used to run each iteration of a benchmark using a + // C++11 ranged-based for loop. These functions should not be called directly. + // + // REQUIRES: The benchmark has not started running yet. Neither begin nor end + // have been called previously. + // + // NOTE: KeepRunning may not be used after calling either of these functions. + BENCHMARK_ALWAYS_INLINE StateIterator begin(); + BENCHMARK_ALWAYS_INLINE StateIterator end(); + + // Returns true if the benchmark should continue through another iteration. + // NOTE: A benchmark may not return from the test until KeepRunning() has + // returned false. + bool KeepRunning(); + + // Returns true iff the benchmark should run n more iterations. + // REQUIRES: 'n' > 0. + // NOTE: A benchmark must not return from the test until KeepRunningBatch() + // has returned false. + // NOTE: KeepRunningBatch() may overshoot by up to 'n' iterations. + // + // Intended usage: + // while (state.KeepRunningBatch(1000)) { + // // process 1000 elements + // } + bool KeepRunningBatch(IterationCount n); + + // REQUIRES: timer is running and 'SkipWithError(...)' has not been called + // by the current thread. + // Stop the benchmark timer. If not called, the timer will be + // automatically stopped after the last iteration of the benchmark loop. + // + // For threaded benchmarks the PauseTiming() function only pauses the timing + // for the current thread. + // + // NOTE: The "real time" measurement is per-thread. If different threads + // report different measurements the largest one is reported. + // + // NOTE: PauseTiming()/ResumeTiming() are relatively + // heavyweight, and so their use should generally be avoided + // within each benchmark iteration, if possible. + void PauseTiming(); + + // REQUIRES: timer is not running and 'SkipWithError(...)' has not been called + // by the current thread. + // Start the benchmark timer. The timer is NOT running on entrance to the + // benchmark function. It begins running after control flow enters the + // benchmark loop. + // + // NOTE: PauseTiming()/ResumeTiming() are relatively + // heavyweight, and so their use should generally be avoided + // within each benchmark iteration, if possible. + void ResumeTiming(); + + // REQUIRES: 'SkipWithError(...)' has not been called previously by the + // current thread. + // Report the benchmark as resulting in an error with the specified 'msg'. + // After this call the user may explicitly 'return' from the benchmark. + // + // If the ranged-for style of benchmark loop is used, the user must explicitly + // break from the loop, otherwise all future iterations will be run. + // If the 'KeepRunning()' loop is used the current thread will automatically + // exit the loop at the end of the current iteration. + // + // For threaded benchmarks only the current thread stops executing and future + // calls to `KeepRunning()` will block until all threads have completed + // the `KeepRunning()` loop. If multiple threads report an error only the + // first error message is used. + // + // NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit + // the current scope immediately. If the function is called from within + // the 'KeepRunning()' loop the current iteration will finish. It is the users + // responsibility to exit the scope as needed. + void SkipWithError(const char* msg); + + // REQUIRES: called exactly once per iteration of the benchmarking loop. + // Set the manually measured time for this benchmark iteration, which + // is used instead of automatically measured time if UseManualTime() was + // specified. + // + // For threaded benchmarks the final value will be set to the largest + // reported values. + void SetIterationTime(double seconds); + + // Set the number of bytes processed by the current benchmark + // execution. This routine is typically called once at the end of a + // throughput oriented benchmark. + // + // REQUIRES: a benchmark has exited its benchmarking loop. + BENCHMARK_ALWAYS_INLINE + void SetBytesProcessed(int64_t bytes) { + counters["bytes_per_second"] = + Counter(static_cast(bytes), Counter::kIsRate, Counter::kIs1024); + } + + BENCHMARK_ALWAYS_INLINE + int64_t bytes_processed() const { + if (counters.find("bytes_per_second") != counters.end()) + return static_cast(counters.at("bytes_per_second")); + return 0; + } + + // If this routine is called with complexity_n > 0 and complexity report is + // requested for the + // family benchmark, then current benchmark will be part of the computation + // and complexity_n will + // represent the length of N. + BENCHMARK_ALWAYS_INLINE + void SetComplexityN(int64_t complexity_n) { complexity_n_ = complexity_n; } + + BENCHMARK_ALWAYS_INLINE + int64_t complexity_length_n() { return complexity_n_; } + + // If this routine is called with items > 0, then an items/s + // label is printed on the benchmark report line for the currently + // executing benchmark. It is typically called at the end of a processing + // benchmark where a processing items/second output is desired. + // + // REQUIRES: a benchmark has exited its benchmarking loop. + BENCHMARK_ALWAYS_INLINE + void SetItemsProcessed(int64_t items) { + counters["items_per_second"] = + Counter(static_cast(items), benchmark::Counter::kIsRate); + } + + BENCHMARK_ALWAYS_INLINE + int64_t items_processed() const { + if (counters.find("items_per_second") != counters.end()) + return static_cast(counters.at("items_per_second")); + return 0; + } + + // If this routine is called, the specified label is printed at the + // end of the benchmark report line for the currently executing + // benchmark. Example: + // static void BM_Compress(benchmark::State& state) { + // ... + // double compress = input_size / output_size; + // state.SetLabel(StrFormat("compress:%.1f%%", 100.0*compression)); + // } + // Produces output that looks like: + // BM_Compress 50 50 14115038 compress:27.3% + // + // REQUIRES: a benchmark has exited its benchmarking loop. + void SetLabel(const char* label); + + void BENCHMARK_ALWAYS_INLINE SetLabel(const std::string& str) { + this->SetLabel(str.c_str()); + } + + // Range arguments for this run. CHECKs if the argument has been set. + BENCHMARK_ALWAYS_INLINE + int64_t range(std::size_t pos = 0) const { + assert(range_.size() > pos); + return range_[pos]; + } + + BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead") + int64_t range_x() const { return range(0); } + + BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead") + int64_t range_y() const { return range(1); } + + BENCHMARK_ALWAYS_INLINE + IterationCount iterations() const { + if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) { + return 0; + } + return max_iterations - total_iterations_ + batch_leftover_; + } + + private + : // items we expect on the first cache line (ie 64 bytes of the struct) + // When total_iterations_ is 0, KeepRunning() and friends will return false. + // May be larger than max_iterations. + IterationCount total_iterations_; + + // When using KeepRunningBatch(), batch_leftover_ holds the number of + // iterations beyond max_iters that were run. Used to track + // completed_iterations_ accurately. + IterationCount batch_leftover_; + + public: + const IterationCount max_iterations; + + private: + bool started_; + bool finished_; + bool error_occurred_; + + private: // items we don't need on the first cache line + std::vector range_; + + int64_t complexity_n_; + + public: + // Container for user-defined counters. + UserCounters counters; + // Index of the executing thread. Values from [0, threads). + const int thread_index; + // Number of threads concurrently executing the benchmark. + const int threads; + + private: + State(IterationCount max_iters, const std::vector& ranges, + int thread_i, int n_threads, internal::ThreadTimer* timer, + internal::ThreadManager* manager); + + void StartKeepRunning(); + // Implementation of KeepRunning() and KeepRunningBatch(). + // is_batch must be true unless n is 1. + bool KeepRunningInternal(IterationCount n, bool is_batch); + void FinishKeepRunning(); + internal::ThreadTimer* timer_; + internal::ThreadManager* manager_; + + friend struct internal::BenchmarkInstance; +}; + +inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() { + return KeepRunningInternal(1, /*is_batch=*/false); +} + +inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningBatch(IterationCount n) { + return KeepRunningInternal(n, /*is_batch=*/true); +} + +inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningInternal(IterationCount n, + bool is_batch) { + // total_iterations_ is set to 0 by the constructor, and always set to a + // nonzero value by StartKepRunning(). + assert(n > 0); + // n must be 1 unless is_batch is true. + assert(is_batch || n == 1); + if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) { + total_iterations_ -= n; + return true; + } + if (!started_) { + StartKeepRunning(); + if (!error_occurred_ && total_iterations_ >= n) { + total_iterations_ -= n; + return true; + } + } + // For non-batch runs, total_iterations_ must be 0 by now. + if (is_batch && total_iterations_ != 0) { + batch_leftover_ = n - total_iterations_; + total_iterations_ = 0; + return true; + } + FinishKeepRunning(); + return false; +} + +struct State::StateIterator { + struct BENCHMARK_UNUSED Value {}; + typedef std::forward_iterator_tag iterator_category; + typedef Value value_type; + typedef Value reference; + typedef Value pointer; + typedef std::ptrdiff_t difference_type; + + private: + friend class State; + BENCHMARK_ALWAYS_INLINE + StateIterator() : cached_(0), parent_() {} + + BENCHMARK_ALWAYS_INLINE + explicit StateIterator(State* st) + : cached_(st->error_occurred_ ? 0 : st->max_iterations), parent_(st) {} + + public: + BENCHMARK_ALWAYS_INLINE + Value operator*() const { return Value(); } + + BENCHMARK_ALWAYS_INLINE + StateIterator& operator++() { + assert(cached_ > 0); + --cached_; + return *this; + } + + BENCHMARK_ALWAYS_INLINE + bool operator!=(StateIterator const&) const { + if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0, true)) return true; + parent_->FinishKeepRunning(); + return false; + } + + private: + IterationCount cached_; + State* const parent_; +}; + +inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() { + return StateIterator(this); +} +inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() { + StartKeepRunning(); + return StateIterator(); +} + +namespace internal { + +typedef void(Function)(State&); + +// ------------------------------------------------------ +// Benchmark registration object. The BENCHMARK() macro expands +// into an internal::Benchmark* object. Various methods can +// be called on this object to change the properties of the benchmark. +// Each method returns "this" so that multiple method calls can +// chained into one expression. +class Benchmark { + public: + virtual ~Benchmark(); + + // Note: the following methods all return "this" so that multiple + // method calls can be chained together in one expression. + + // Run this benchmark once with "x" as the extra argument passed + // to the function. + // REQUIRES: The function passed to the constructor must accept an arg1. + Benchmark* Arg(int64_t x); + + // Run this benchmark with the given time unit for the generated output report + Benchmark* Unit(TimeUnit unit); + + // Run this benchmark once for a number of values picked from the + // range [start..limit]. (start and limit are always picked.) + // REQUIRES: The function passed to the constructor must accept an arg1. + Benchmark* Range(int64_t start, int64_t limit); + + // Run this benchmark once for all values in the range [start..limit] with + // specific step + // REQUIRES: The function passed to the constructor must accept an arg1. + Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1); + + // Run this benchmark once with "args" as the extra arguments passed + // to the function. + // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... + Benchmark* Args(const std::vector& args); + + // Equivalent to Args({x, y}) + // NOTE: This is a legacy C++03 interface provided for compatibility only. + // New code should use 'Args'. + Benchmark* ArgPair(int64_t x, int64_t y) { + std::vector args; + args.push_back(x); + args.push_back(y); + return Args(args); + } + + // Run this benchmark once for a number of values picked from the + // ranges [start..limit]. (starts and limits are always picked.) + // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... + Benchmark* Ranges(const std::vector >& ranges); + + // Equivalent to ArgNames({name}) + Benchmark* ArgName(const std::string& name); + + // Set the argument names to display in the benchmark name. If not called, + // only argument values will be shown. + Benchmark* ArgNames(const std::vector& names); + + // Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}). + // NOTE: This is a legacy C++03 interface provided for compatibility only. + // New code should use 'Ranges'. + Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) { + std::vector > ranges; + ranges.push_back(std::make_pair(lo1, hi1)); + ranges.push_back(std::make_pair(lo2, hi2)); + return Ranges(ranges); + } + + // Pass this benchmark object to *func, which can customize + // the benchmark by calling various methods like Arg, Args, + // Threads, etc. + Benchmark* Apply(void (*func)(Benchmark* benchmark)); + + // Set the range multiplier for non-dense range. If not called, the range + // multiplier kRangeMultiplier will be used. + Benchmark* RangeMultiplier(int multiplier); + + // Set the minimum amount of time to use when running this benchmark. This + // option overrides the `benchmark_min_time` flag. + // REQUIRES: `t > 0` and `Iterations` has not been called on this benchmark. + Benchmark* MinTime(double t); + + // Specify the amount of iterations that should be run by this benchmark. + // REQUIRES: 'n > 0' and `MinTime` has not been called on this benchmark. + // + // NOTE: This function should only be used when *exact* iteration control is + // needed and never to control or limit how long a benchmark runs, where + // `--benchmark_min_time=N` or `MinTime(...)` should be used instead. + Benchmark* Iterations(IterationCount n); + + // Specify the amount of times to repeat this benchmark. This option overrides + // the `benchmark_repetitions` flag. + // REQUIRES: `n > 0` + Benchmark* Repetitions(int n); + + // Specify if each repetition of the benchmark should be reported separately + // or if only the final statistics should be reported. If the benchmark + // is not repeated then the single result is always reported. + // Applies to *ALL* reporters (display and file). + Benchmark* ReportAggregatesOnly(bool value = true); + + // Same as ReportAggregatesOnly(), but applies to display reporter only. + Benchmark* DisplayAggregatesOnly(bool value = true); + + // By default, the CPU time is measured only for the main thread, which may + // be unrepresentative if the benchmark uses threads internally. If called, + // the total CPU time spent by all the threads will be measured instead. + // By default, the only the main thread CPU time will be measured. + Benchmark* MeasureProcessCPUTime(); + + // If a particular benchmark should use the Wall clock instead of the CPU time + // (be it either the CPU time of the main thread only (default), or the + // total CPU usage of the benchmark), call this method. If called, the elapsed + // (wall) time will be used to control how many iterations are run, and in the + // printing of items/second or MB/seconds values. + // If not called, the CPU time used by the benchmark will be used. + Benchmark* UseRealTime(); + + // If a benchmark must measure time manually (e.g. if GPU execution time is + // being + // measured), call this method. If called, each benchmark iteration should + // call + // SetIterationTime(seconds) to report the measured time, which will be used + // to control how many iterations are run, and in the printing of items/second + // or MB/second values. + Benchmark* UseManualTime(); + + // Set the asymptotic computational complexity for the benchmark. If called + // the asymptotic computational complexity will be shown on the output. + Benchmark* Complexity(BigO complexity = benchmark::oAuto); + + // Set the asymptotic computational complexity for the benchmark. If called + // the asymptotic computational complexity will be shown on the output. + Benchmark* Complexity(BigOFunc* complexity); + + // Add this statistics to be computed over all the values of benchmark run + Benchmark* ComputeStatistics(std::string name, StatisticsFunc* statistics); + + // Support for running multiple copies of the same benchmark concurrently + // in multiple threads. This may be useful when measuring the scaling + // of some piece of code. + + // Run one instance of this benchmark concurrently in t threads. + Benchmark* Threads(int t); + + // Pick a set of values T from [min_threads,max_threads]. + // min_threads and max_threads are always included in T. Run this + // benchmark once for each value in T. The benchmark run for a + // particular value t consists of t threads running the benchmark + // function concurrently. For example, consider: + // BENCHMARK(Foo)->ThreadRange(1,16); + // This will run the following benchmarks: + // Foo in 1 thread + // Foo in 2 threads + // Foo in 4 threads + // Foo in 8 threads + // Foo in 16 threads + Benchmark* ThreadRange(int min_threads, int max_threads); + + // For each value n in the range, run this benchmark once using n threads. + // min_threads and max_threads are always included in the range. + // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts + // a benchmark with 1, 4, 7 and 8 threads. + Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1); + + // Equivalent to ThreadRange(NumCPUs(), NumCPUs()) + Benchmark* ThreadPerCpu(); + + virtual void Run(State& state) = 0; + + protected: + explicit Benchmark(const char* name); + Benchmark(Benchmark const&); + void SetName(const char* name); + + int ArgsCnt() const; + + private: + friend class BenchmarkFamilies; + + std::string name_; + AggregationReportMode aggregation_report_mode_; + std::vector arg_names_; // Args for all benchmark runs + std::vector > args_; // Args for all benchmark runs + TimeUnit time_unit_; + int range_multiplier_; + double min_time_; + IterationCount iterations_; + int repetitions_; + bool measure_process_cpu_time_; + bool use_real_time_; + bool use_manual_time_; + BigO complexity_; + BigOFunc* complexity_lambda_; + std::vector statistics_; + std::vector thread_counts_; + + Benchmark& operator=(Benchmark const&); +}; + +} // namespace internal + +// Create and register a benchmark with the specified 'name' that invokes +// the specified functor 'fn'. +// +// RETURNS: A pointer to the registered benchmark. +internal::Benchmark* RegisterBenchmark(const char* name, + internal::Function* fn); + +#if defined(BENCHMARK_HAS_CXX11) +template +internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn); +#endif + +// Remove all registered benchmarks. All pointers to previously registered +// benchmarks are invalidated. +void ClearRegisteredBenchmarks(); + +namespace internal { +// The class used to hold all Benchmarks created from static function. +// (ie those created using the BENCHMARK(...) macros. +class FunctionBenchmark : public Benchmark { + public: + FunctionBenchmark(const char* name, Function* func) + : Benchmark(name), func_(func) {} + + virtual void Run(State& st); + + private: + Function* func_; +}; + +#ifdef BENCHMARK_HAS_CXX11 +template +class LambdaBenchmark : public Benchmark { + public: + virtual void Run(State& st) { lambda_(st); } + + private: + template + LambdaBenchmark(const char* name, OLambda&& lam) + : Benchmark(name), lambda_(std::forward(lam)) {} + + LambdaBenchmark(LambdaBenchmark const&) = delete; + + private: + template + friend Benchmark* ::benchmark::RegisterBenchmark(const char*, Lam&&); + + Lambda lambda_; +}; +#endif + +} // namespace internal + +inline internal::Benchmark* RegisterBenchmark(const char* name, + internal::Function* fn) { + return internal::RegisterBenchmarkInternal( + ::new internal::FunctionBenchmark(name, fn)); +} + +#ifdef BENCHMARK_HAS_CXX11 +template +internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn) { + using BenchType = + internal::LambdaBenchmark::type>; + return internal::RegisterBenchmarkInternal( + ::new BenchType(name, std::forward(fn))); +} +#endif + +#if defined(BENCHMARK_HAS_CXX11) && \ + (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409) +template +internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn, + Args&&... args) { + return benchmark::RegisterBenchmark( + name, [=](benchmark::State& st) { fn(st, args...); }); +} +#else +#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK +#endif + +// The base class for all fixture tests. +class Fixture : public internal::Benchmark { + public: + Fixture() : internal::Benchmark("") {} + + virtual void Run(State& st) { + this->SetUp(st); + this->BenchmarkCase(st); + this->TearDown(st); + } + + // These will be deprecated ... + virtual void SetUp(const State&) {} + virtual void TearDown(const State&) {} + // ... In favor of these. + virtual void SetUp(State& st) { SetUp(const_cast(st)); } + virtual void TearDown(State& st) { TearDown(const_cast(st)); } + + protected: + virtual void BenchmarkCase(State&) = 0; +}; + +} // namespace benchmark + +// ------------------------------------------------------ +// Macro to register benchmarks + +// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1 +// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be +// empty. If X is empty the expression becomes (+1 == +0). +#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0) +#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__ +#else +#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__ +#endif + +// Helpers for generating unique variable names +#define BENCHMARK_PRIVATE_NAME(n) \ + BENCHMARK_PRIVATE_CONCAT(_benchmark_, BENCHMARK_PRIVATE_UNIQUE_ID, n) +#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c) +#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c + +#define BENCHMARK_PRIVATE_DECLARE(n) \ + static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \ + BENCHMARK_UNUSED + +#define BENCHMARK(n) \ + BENCHMARK_PRIVATE_DECLARE(n) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + new ::benchmark::internal::FunctionBenchmark(#n, n))) + +// Old-style macros +#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a)) +#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)}) +#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t)) +#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi)) +#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \ + BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}}) + +#ifdef BENCHMARK_HAS_CXX11 + +// Register a benchmark which invokes the function specified by `func` +// with the additional arguments specified by `...`. +// +// For example: +// +// template ` +// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) { +// [...] +//} +// /* Registers a benchmark named "BM_takes_args/int_string_test` */ +// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc")); +#define BENCHMARK_CAPTURE(func, test_case_name, ...) \ + BENCHMARK_PRIVATE_DECLARE(func) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + new ::benchmark::internal::FunctionBenchmark( \ + #func "/" #test_case_name, \ + [](::benchmark::State& st) { func(st, __VA_ARGS__); }))) + +#endif // BENCHMARK_HAS_CXX11 + +// This will register a benchmark for a templatized function. For example: +// +// template +// void BM_Foo(int iters); +// +// BENCHMARK_TEMPLATE(BM_Foo, 1); +// +// will register BM_Foo<1> as a benchmark. +#define BENCHMARK_TEMPLATE1(n, a) \ + BENCHMARK_PRIVATE_DECLARE(n) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n))) + +#define BENCHMARK_TEMPLATE2(n, a, b) \ + BENCHMARK_PRIVATE_DECLARE(n) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \ + n))) + +#ifdef BENCHMARK_HAS_CXX11 +#define BENCHMARK_TEMPLATE(n, ...) \ + BENCHMARK_PRIVATE_DECLARE(n) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + new ::benchmark::internal::FunctionBenchmark( \ + #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>))) +#else +#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a) +#endif + +#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ + class BaseClass##_##Method##_Benchmark : public BaseClass { \ + public: \ + BaseClass##_##Method##_Benchmark() : BaseClass() { \ + this->SetName(#BaseClass "/" #Method); \ + } \ + \ + protected: \ + virtual void BenchmarkCase(::benchmark::State&); \ + }; + +#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \ + class BaseClass##_##Method##_Benchmark : public BaseClass { \ + public: \ + BaseClass##_##Method##_Benchmark() : BaseClass() { \ + this->SetName(#BaseClass "<" #a ">/" #Method); \ + } \ + \ + protected: \ + virtual void BenchmarkCase(::benchmark::State&); \ + }; + +#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ + class BaseClass##_##Method##_Benchmark : public BaseClass { \ + public: \ + BaseClass##_##Method##_Benchmark() : BaseClass() { \ + this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \ + } \ + \ + protected: \ + virtual void BenchmarkCase(::benchmark::State&); \ + }; + +#ifdef BENCHMARK_HAS_CXX11 +#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \ + class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \ + public: \ + BaseClass##_##Method##_Benchmark() : BaseClass<__VA_ARGS__>() { \ + this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \ + } \ + \ + protected: \ + virtual void BenchmarkCase(::benchmark::State&); \ + }; +#else +#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \ + BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a) +#endif + +#define BENCHMARK_DEFINE_F(BaseClass, Method) \ + BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase + +#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \ + BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase + +#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \ + BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase + +#ifdef BENCHMARK_HAS_CXX11 +#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \ + BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase +#else +#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \ + BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) +#endif + +#define BENCHMARK_REGISTER_F(BaseClass, Method) \ + BENCHMARK_PRIVATE_REGISTER_F(BaseClass##_##Method##_Benchmark) + +#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \ + BENCHMARK_PRIVATE_DECLARE(TestName) = \ + (::benchmark::internal::RegisterBenchmarkInternal(new TestName())) + +// This macro will define and register a benchmark within a fixture class. +#define BENCHMARK_F(BaseClass, Method) \ + BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ + BENCHMARK_REGISTER_F(BaseClass, Method); \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase + +#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \ + BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \ + BENCHMARK_REGISTER_F(BaseClass, Method); \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase + +#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \ + BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ + BENCHMARK_REGISTER_F(BaseClass, Method); \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase + +#ifdef BENCHMARK_HAS_CXX11 +#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \ + BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \ + BENCHMARK_REGISTER_F(BaseClass, Method); \ + void BaseClass##_##Method##_Benchmark::BenchmarkCase +#else +#define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \ + BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) +#endif + +// Helper macro to create a main routine in a test that runs the benchmarks +#define BENCHMARK_MAIN() \ + int main(int argc, char** argv) { \ + ::benchmark::Initialize(&argc, argv); \ + if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \ + ::benchmark::RunSpecifiedBenchmarks(); \ + } \ + int main(int, char**) + +// ------------------------------------------------------ +// Benchmark Reporters + +namespace benchmark { + +struct CPUInfo { + struct CacheInfo { + std::string type; + int level; + int size; + int num_sharing; + }; + + int num_cpus; + double cycles_per_second; + std::vector caches; + bool scaling_enabled; + std::vector load_avg; + + static const CPUInfo& Get(); + + private: + CPUInfo(); + BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo); +}; + +// Adding Struct for System Information +struct SystemInfo { + std::string name; + static const SystemInfo& Get(); + + private: + SystemInfo(); + BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo); +}; + +// BenchmarkName contains the components of the Benchmark's name +// which allows individual fields to be modified or cleared before +// building the final name using 'str()'. +struct BenchmarkName { + std::string function_name; + std::string args; + std::string min_time; + std::string iterations; + std::string repetitions; + std::string time_type; + std::string threads; + + // Return the full name of the benchmark with each non-empty + // field separated by a '/' + std::string str() const; +}; + +// Interface for custom benchmark result printers. +// By default, benchmark reports are printed to stdout. However an application +// can control the destination of the reports by calling +// RunSpecifiedBenchmarks and passing it a custom reporter object. +// The reporter object must implement the following interface. +class BenchmarkReporter { + public: + struct Context { + CPUInfo const& cpu_info; + SystemInfo const& sys_info; + // The number of chars in the longest benchmark name. + size_t name_field_width; + static const char* executable_name; + Context(); + }; + + struct Run { + static const int64_t no_repetition_index = -1; + enum RunType { RT_Iteration, RT_Aggregate }; + + Run() + : run_type(RT_Iteration), + error_occurred(false), + iterations(1), + threads(1), + time_unit(kNanosecond), + real_accumulated_time(0), + cpu_accumulated_time(0), + max_heapbytes_used(0), + complexity(oNone), + complexity_lambda(), + complexity_n(0), + report_big_o(false), + report_rms(false), + counters(), + has_memory_result(false), + allocs_per_iter(0.0), + max_bytes_used(0) {} + + std::string benchmark_name() const; + BenchmarkName run_name; + RunType run_type; + std::string aggregate_name; + std::string report_label; // Empty if not set by benchmark. + bool error_occurred; + std::string error_message; + + IterationCount iterations; + int64_t threads; + int64_t repetition_index; + int64_t repetitions; + TimeUnit time_unit; + double real_accumulated_time; + double cpu_accumulated_time; + + // Return a value representing the real time per iteration in the unit + // specified by 'time_unit'. + // NOTE: If 'iterations' is zero the returned value represents the + // accumulated time. + double GetAdjustedRealTime() const; + + // Return a value representing the cpu time per iteration in the unit + // specified by 'time_unit'. + // NOTE: If 'iterations' is zero the returned value represents the + // accumulated time. + double GetAdjustedCPUTime() const; + + // This is set to 0.0 if memory tracing is not enabled. + double max_heapbytes_used; + + // Keep track of arguments to compute asymptotic complexity + BigO complexity; + BigOFunc* complexity_lambda; + int64_t complexity_n; + + // what statistics to compute from the measurements + const std::vector* statistics; + + // Inform print function whether the current run is a complexity report + bool report_big_o; + bool report_rms; + + UserCounters counters; + + // Memory metrics. + bool has_memory_result; + double allocs_per_iter; + int64_t max_bytes_used; + }; + + // Construct a BenchmarkReporter with the output stream set to 'std::cout' + // and the error stream set to 'std::cerr' + BenchmarkReporter(); + + // Called once for every suite of benchmarks run. + // The parameter "context" contains information that the + // reporter may wish to use when generating its report, for example the + // platform under which the benchmarks are running. The benchmark run is + // never started if this function returns false, allowing the reporter + // to skip runs based on the context information. + virtual bool ReportContext(const Context& context) = 0; + + // Called once for each group of benchmark runs, gives information about + // cpu-time and heap memory usage during the benchmark run. If the group + // of runs contained more than two entries then 'report' contains additional + // elements representing the mean and standard deviation of those runs. + // Additionally if this group of runs was the last in a family of benchmarks + // 'reports' contains additional entries representing the asymptotic + // complexity and RMS of that benchmark family. + virtual void ReportRuns(const std::vector& report) = 0; + + // Called once and only once after ever group of benchmarks is run and + // reported. + virtual void Finalize() {} + + // REQUIRES: The object referenced by 'out' is valid for the lifetime + // of the reporter. + void SetOutputStream(std::ostream* out) { + assert(out); + output_stream_ = out; + } + + // REQUIRES: The object referenced by 'err' is valid for the lifetime + // of the reporter. + void SetErrorStream(std::ostream* err) { + assert(err); + error_stream_ = err; + } + + std::ostream& GetOutputStream() const { return *output_stream_; } + + std::ostream& GetErrorStream() const { return *error_stream_; } + + virtual ~BenchmarkReporter(); + + // Write a human readable string to 'out' representing the specified + // 'context'. + // REQUIRES: 'out' is non-null. + static void PrintBasicContext(std::ostream* out, Context const& context); + + private: + std::ostream* output_stream_; + std::ostream* error_stream_; +}; + +// Simple reporter that outputs benchmark data to the console. This is the +// default reporter used by RunSpecifiedBenchmarks(). +class ConsoleReporter : public BenchmarkReporter { + public: + enum OutputOptions { + OO_None = 0, + OO_Color = 1, + OO_Tabular = 2, + OO_ColorTabular = OO_Color | OO_Tabular, + OO_Defaults = OO_ColorTabular + }; + explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults) + : output_options_(opts_), + name_field_width_(0), + prev_counters_(), + printed_header_(false) {} + + virtual bool ReportContext(const Context& context); + virtual void ReportRuns(const std::vector& reports); + + protected: + virtual void PrintRunData(const Run& report); + virtual void PrintHeader(const Run& report); + + OutputOptions output_options_; + size_t name_field_width_; + UserCounters prev_counters_; + bool printed_header_; +}; + +class JSONReporter : public BenchmarkReporter { + public: + JSONReporter() : first_report_(true) {} + virtual bool ReportContext(const Context& context); + virtual void ReportRuns(const std::vector& reports); + virtual void Finalize(); + + private: + void PrintRunData(const Run& report); + + bool first_report_; +}; + +class BENCHMARK_DEPRECATED_MSG( + "The CSV Reporter will be removed in a future release") CSVReporter + : public BenchmarkReporter { + public: + CSVReporter() : printed_header_(false) {} + virtual bool ReportContext(const Context& context); + virtual void ReportRuns(const std::vector& reports); + + private: + void PrintRunData(const Run& report); + + bool printed_header_; + std::set user_counter_names_; +}; + +// If a MemoryManager is registered, it can be used to collect and report +// allocation metrics for a run of the benchmark. +class MemoryManager { + public: + struct Result { + Result() : num_allocs(0), max_bytes_used(0) {} + + // The number of allocations made in total between Start and Stop. + int64_t num_allocs; + + // The peak memory use between Start and Stop. + int64_t max_bytes_used; + }; + + virtual ~MemoryManager() {} + + // Implement this to start recording allocation information. + virtual void Start() = 0; + + // Implement this to stop recording and fill out the given Result structure. + virtual void Stop(Result* result) = 0; +}; + +inline const char* GetTimeUnitString(TimeUnit unit) { + switch (unit) { + case kMillisecond: + return "ms"; + case kMicrosecond: + return "us"; + case kNanosecond: + return "ns"; + } + BENCHMARK_UNREACHABLE(); +} + +inline double GetTimeUnitMultiplier(TimeUnit unit) { + switch (unit) { + case kMillisecond: + return 1e3; + case kMicrosecond: + return 1e6; + case kNanosecond: + return 1e9; + } + BENCHMARK_UNREACHABLE(); +} + +} // namespace benchmark + +#endif // BENCHMARK_BENCHMARK_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/mingw.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/mingw.py new file mode 100644 index 000000000..706ad559d --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/mingw.py @@ -0,0 +1,320 @@ +#! /usr/bin/env python +# encoding: utf-8 + +import argparse +import errno +import logging +import os +import platform +import re +import sys +import subprocess +import tempfile + +try: + import winreg +except ImportError: + import _winreg as winreg +try: + import urllib.request as request +except ImportError: + import urllib as request +try: + import urllib.parse as parse +except ImportError: + import urlparse as parse + +class EmptyLogger(object): + ''' + Provides an implementation that performs no logging + ''' + def debug(self, *k, **kw): + pass + def info(self, *k, **kw): + pass + def warn(self, *k, **kw): + pass + def error(self, *k, **kw): + pass + def critical(self, *k, **kw): + pass + def setLevel(self, *k, **kw): + pass + +urls = ( + 'http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20' + 'targetting%20Win32/Personal%20Builds/mingw-builds/installer/' + 'repository.txt', + 'http://downloads.sourceforge.net/project/mingwbuilds/host-windows/' + 'repository.txt' +) +''' +A list of mingw-build repositories +''' + +def repository(urls = urls, log = EmptyLogger()): + ''' + Downloads and parse mingw-build repository files and parses them + ''' + log.info('getting mingw-builds repository') + versions = {} + re_sourceforge = re.compile(r'http://sourceforge.net/projects/([^/]+)/files') + re_sub = r'http://downloads.sourceforge.net/project/\1' + for url in urls: + log.debug(' - requesting: %s', url) + socket = request.urlopen(url) + repo = socket.read() + if not isinstance(repo, str): + repo = repo.decode(); + socket.close() + for entry in repo.split('\n')[:-1]: + value = entry.split('|') + version = tuple([int(n) for n in value[0].strip().split('.')]) + version = versions.setdefault(version, {}) + arch = value[1].strip() + if arch == 'x32': + arch = 'i686' + elif arch == 'x64': + arch = 'x86_64' + arch = version.setdefault(arch, {}) + threading = arch.setdefault(value[2].strip(), {}) + exceptions = threading.setdefault(value[3].strip(), {}) + revision = exceptions.setdefault(int(value[4].strip()[3:]), + re_sourceforge.sub(re_sub, value[5].strip())) + return versions + +def find_in_path(file, path=None): + ''' + Attempts to find an executable in the path + ''' + if platform.system() == 'Windows': + file += '.exe' + if path is None: + path = os.environ.get('PATH', '') + if type(path) is type(''): + path = path.split(os.pathsep) + return list(filter(os.path.exists, + map(lambda dir, file=file: os.path.join(dir, file), path))) + +def find_7zip(log = EmptyLogger()): + ''' + Attempts to find 7zip for unpacking the mingw-build archives + ''' + log.info('finding 7zip') + path = find_in_path('7z') + if not path: + key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\7-Zip') + path, _ = winreg.QueryValueEx(key, 'Path') + path = [os.path.join(path, '7z.exe')] + log.debug('found \'%s\'', path[0]) + return path[0] + +find_7zip() + +def unpack(archive, location, log = EmptyLogger()): + ''' + Unpacks a mingw-builds archive + ''' + sevenzip = find_7zip(log) + log.info('unpacking %s', os.path.basename(archive)) + cmd = [sevenzip, 'x', archive, '-o' + location, '-y'] + log.debug(' - %r', cmd) + with open(os.devnull, 'w') as devnull: + subprocess.check_call(cmd, stdout = devnull) + +def download(url, location, log = EmptyLogger()): + ''' + Downloads and unpacks a mingw-builds archive + ''' + log.info('downloading MinGW') + log.debug(' - url: %s', url) + log.debug(' - location: %s', location) + + re_content = re.compile(r'attachment;[ \t]*filename=(")?([^"]*)(")?[\r\n]*') + + stream = request.urlopen(url) + try: + content = stream.getheader('Content-Disposition') or '' + except AttributeError: + content = stream.headers.getheader('Content-Disposition') or '' + matches = re_content.match(content) + if matches: + filename = matches.group(2) + else: + parsed = parse.urlparse(stream.geturl()) + filename = os.path.basename(parsed.path) + + try: + os.makedirs(location) + except OSError as e: + if e.errno == errno.EEXIST and os.path.isdir(location): + pass + else: + raise + + archive = os.path.join(location, filename) + with open(archive, 'wb') as out: + while True: + buf = stream.read(1024) + if not buf: + break + out.write(buf) + unpack(archive, location, log = log) + os.remove(archive) + + possible = os.path.join(location, 'mingw64') + if not os.path.exists(possible): + possible = os.path.join(location, 'mingw32') + if not os.path.exists(possible): + raise ValueError('Failed to find unpacked MinGW: ' + possible) + return possible + +def root(location = None, arch = None, version = None, threading = None, + exceptions = None, revision = None, log = EmptyLogger()): + ''' + Returns the root folder of a specific version of the mingw-builds variant + of gcc. Will download the compiler if needed + ''' + + # Get the repository if we don't have all the information + if not (arch and version and threading and exceptions and revision): + versions = repository(log = log) + + # Determine some defaults + version = version or max(versions.keys()) + if not arch: + arch = platform.machine().lower() + if arch == 'x86': + arch = 'i686' + elif arch == 'amd64': + arch = 'x86_64' + if not threading: + keys = versions[version][arch].keys() + if 'posix' in keys: + threading = 'posix' + elif 'win32' in keys: + threading = 'win32' + else: + threading = keys[0] + if not exceptions: + keys = versions[version][arch][threading].keys() + if 'seh' in keys: + exceptions = 'seh' + elif 'sjlj' in keys: + exceptions = 'sjlj' + else: + exceptions = keys[0] + if revision == None: + revision = max(versions[version][arch][threading][exceptions].keys()) + if not location: + location = os.path.join(tempfile.gettempdir(), 'mingw-builds') + + # Get the download url + url = versions[version][arch][threading][exceptions][revision] + + # Tell the user whatzzup + log.info('finding MinGW %s', '.'.join(str(v) for v in version)) + log.debug(' - arch: %s', arch) + log.debug(' - threading: %s', threading) + log.debug(' - exceptions: %s', exceptions) + log.debug(' - revision: %s', revision) + log.debug(' - url: %s', url) + + # Store each specific revision differently + slug = '{version}-{arch}-{threading}-{exceptions}-rev{revision}' + slug = slug.format( + version = '.'.join(str(v) for v in version), + arch = arch, + threading = threading, + exceptions = exceptions, + revision = revision + ) + if arch == 'x86_64': + root_dir = os.path.join(location, slug, 'mingw64') + elif arch == 'i686': + root_dir = os.path.join(location, slug, 'mingw32') + else: + raise ValueError('Unknown MinGW arch: ' + arch) + + # Download if needed + if not os.path.exists(root_dir): + downloaded = download(url, os.path.join(location, slug), log = log) + if downloaded != root_dir: + raise ValueError('The location of mingw did not match\n%s\n%s' + % (downloaded, root_dir)) + + return root_dir + +def str2ver(string): + ''' + Converts a version string into a tuple + ''' + try: + version = tuple(int(v) for v in string.split('.')) + if len(version) is not 3: + raise ValueError() + except ValueError: + raise argparse.ArgumentTypeError( + 'please provide a three digit version string') + return version + +def main(): + ''' + Invoked when the script is run directly by the python interpreter + ''' + parser = argparse.ArgumentParser( + description = 'Downloads a specific version of MinGW', + formatter_class = argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument('--location', + help = 'the location to download the compiler to', + default = os.path.join(tempfile.gettempdir(), 'mingw-builds')) + parser.add_argument('--arch', required = True, choices = ['i686', 'x86_64'], + help = 'the target MinGW architecture string') + parser.add_argument('--version', type = str2ver, + help = 'the version of GCC to download') + parser.add_argument('--threading', choices = ['posix', 'win32'], + help = 'the threading type of the compiler') + parser.add_argument('--exceptions', choices = ['sjlj', 'seh', 'dwarf'], + help = 'the method to throw exceptions') + parser.add_argument('--revision', type=int, + help = 'the revision of the MinGW release') + group = parser.add_mutually_exclusive_group() + group.add_argument('-v', '--verbose', action='store_true', + help='increase the script output verbosity') + group.add_argument('-q', '--quiet', action='store_true', + help='only print errors and warning') + args = parser.parse_args() + + # Create the logger + logger = logging.getLogger('mingw') + handler = logging.StreamHandler() + formatter = logging.Formatter('%(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.INFO) + if args.quiet: + logger.setLevel(logging.WARN) + if args.verbose: + logger.setLevel(logging.DEBUG) + + # Get MinGW + root_dir = root(location = args.location, arch = args.arch, + version = args.version, threading = args.threading, + exceptions = args.exceptions, revision = args.revision, + log = logger) + + sys.stdout.write('%s\n' % os.path.join(root_dir, 'bin')) + +if __name__ == '__main__': + try: + main() + except IOError as e: + sys.stderr.write('IO error: %s\n' % e) + sys.exit(1) + except OSError as e: + sys.stderr.write('OS error: %s\n' % e) + sys.exit(1) + except KeyboardInterrupt as e: + sys.stderr.write('Killed\n') + sys.exit(1) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/releasing.md b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/releasing.md new file mode 100644 index 000000000..f0cd7010e --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/releasing.md @@ -0,0 +1,16 @@ +# How to release + +* Make sure you're on master and synced to HEAD +* Ensure the project builds and tests run (sanity check only, obviously) + * `parallel -j0 exec ::: test/*_test` can help ensure everything at least + passes +* Prepare release notes + * `git log $(git describe --abbrev=0 --tags)..HEAD` gives you the list of + commits between the last annotated tag and HEAD + * Pick the most interesting. +* Create a release through github's interface + * Note this will create a lightweight tag. + * Update this to an annotated tag: + * `git pull --tags` + * `git tag -a -f ` + * `git push --force origin` diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/CMakeLists.txt new file mode 100644 index 000000000..b47de6791 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/CMakeLists.txt @@ -0,0 +1,112 @@ +# Allow the source files to find headers in src/ +include(GNUInstallDirs) +include_directories(${PROJECT_SOURCE_DIR}/src) + +if (DEFINED BENCHMARK_CXX_LINKER_FLAGS) + list(APPEND CMAKE_SHARED_LINKER_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}) + list(APPEND CMAKE_MODULE_LINKER_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}) +endif() + +file(GLOB + SOURCE_FILES + *.cc + ${PROJECT_SOURCE_DIR}/include/benchmark/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/*.h) +file(GLOB BENCHMARK_MAIN "benchmark_main.cc") +foreach(item ${BENCHMARK_MAIN}) + list(REMOVE_ITEM SOURCE_FILES "${item}") +endforeach() + +add_library(benchmark ${SOURCE_FILES}) +set_target_properties(benchmark PROPERTIES + OUTPUT_NAME "benchmark" + VERSION ${GENERIC_LIB_VERSION} + SOVERSION ${GENERIC_LIB_SOVERSION} +) +target_include_directories(benchmark PUBLIC + $ + ) + +# Link threads. +target_link_libraries(benchmark ${BENCHMARK_CXX_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) +find_library(LIBRT rt) +if(LIBRT) + target_link_libraries(benchmark ${LIBRT}) +endif() + +if(CMAKE_BUILD_TYPE) + string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER) +endif() +if(NOT CMAKE_THREAD_LIBS_INIT AND "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}}" MATCHES ".*-fsanitize=[^ ]*address.*") + message(WARNING "CMake's FindThreads.cmake did not fail, but CMAKE_THREAD_LIBS_INIT ended up being empty. This was fixed in https://github.com/Kitware/CMake/commit/d53317130e84898c5328c237186dbd995aaf1c12 Let's guess that -pthread is sufficient.") + target_link_libraries(benchmark -pthread) +endif() + +# We need extra libraries on Windows +if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + target_link_libraries(benchmark Shlwapi) +endif() + +# We need extra libraries on Solaris +if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + target_link_libraries(benchmark kstat) +endif() + +# Benchmark main library +add_library(benchmark_main "benchmark_main.cc") +set_target_properties(benchmark_main PROPERTIES + OUTPUT_NAME "benchmark_main" + VERSION ${GENERIC_LIB_VERSION} + SOVERSION ${GENERIC_LIB_SOVERSION} +) +target_include_directories(benchmark PUBLIC + $ + ) +target_link_libraries(benchmark_main benchmark) + + +set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") + +set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") +set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") +set(pkg_config "${generated_dir}/${PROJECT_NAME}.pc") +set(targets_export_name "${PROJECT_NAME}Targets") + +set(namespace "${PROJECT_NAME}::") + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${version_config}" VERSION ${GENERIC_LIB_VERSION} COMPATIBILITY SameMajorVersion +) + +configure_file("${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in" "${project_config}" @ONLY) +configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in" "${pkg_config}" @ONLY) + +if (BENCHMARK_ENABLE_INSTALL) + # Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable) + install( + TARGETS benchmark benchmark_main + EXPORT ${targets_export_name} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + install( + DIRECTORY "${PROJECT_SOURCE_DIR}/include/benchmark" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.*h") + + install( + FILES "${project_config}" "${version_config}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + + install( + FILES "${pkg_config}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + + install( + EXPORT "${targets_export_name}" + NAMESPACE "${namespace}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") +endif() diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/arraysize.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/arraysize.h new file mode 100644 index 000000000..51a50f2df --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/arraysize.h @@ -0,0 +1,33 @@ +#ifndef BENCHMARK_ARRAYSIZE_H_ +#define BENCHMARK_ARRAYSIZE_H_ + +#include "internal_macros.h" + +namespace benchmark { +namespace internal { +// The arraysize(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. If you use arraysize on +// a pointer by mistake, you will get a compile-time error. +// + +// This template function declaration is used in defining arraysize. +// Note that the function doesn't need an implementation, as we only +// use its type. +template +char (&ArraySizeHelper(T (&array)[N]))[N]; + +// That gcc wants both of these prototypes seems mysterious. VC, for +// its part, can't decide which to use (another mystery). Matching of +// template overloads: the final frontier. +#ifndef COMPILER_MSVC +template +char (&ArraySizeHelper(const T (&array)[N]))[N]; +#endif + +#define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array))) + +} // end namespace internal +} // end namespace benchmark + +#endif // BENCHMARK_ARRAYSIZE_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark.cc new file mode 100644 index 000000000..29bfa3512 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark.cc @@ -0,0 +1,494 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" +#include "benchmark_api_internal.h" +#include "benchmark_runner.h" +#include "internal_macros.h" + +#ifndef BENCHMARK_OS_WINDOWS +#ifndef BENCHMARK_OS_FUCHSIA +#include +#endif +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "colorprint.h" +#include "commandlineflags.h" +#include "complexity.h" +#include "counter.h" +#include "internal_macros.h" +#include "log.h" +#include "mutex.h" +#include "re.h" +#include "statistics.h" +#include "string_util.h" +#include "thread_manager.h" +#include "thread_timer.h" + +DEFINE_bool(benchmark_list_tests, false, + "Print a list of benchmarks. This option overrides all other " + "options."); + +DEFINE_string(benchmark_filter, ".", + "A regular expression that specifies the set of benchmarks " + "to execute. If this flag is empty, or if this flag is the " + "string \"all\", all benchmarks linked into the binary are " + "run."); + +DEFINE_double(benchmark_min_time, 0.5, + "Minimum number of seconds we should run benchmark before " + "results are considered significant. For cpu-time based " + "tests, this is the lower bound on the total cpu time " + "used by all threads that make up the test. For real-time " + "based tests, this is the lower bound on the elapsed time " + "of the benchmark execution, regardless of number of " + "threads."); + +DEFINE_int32(benchmark_repetitions, 1, + "The number of runs of each benchmark. If greater than 1, the " + "mean and standard deviation of the runs will be reported."); + +DEFINE_bool( + benchmark_report_aggregates_only, false, + "Report the result of each benchmark repetitions. When 'true' is specified " + "only the mean, standard deviation, and other statistics are reported for " + "repeated benchmarks. Affects all reporters."); + +DEFINE_bool( + benchmark_display_aggregates_only, false, + "Display the result of each benchmark repetitions. When 'true' is " + "specified only the mean, standard deviation, and other statistics are " + "displayed for repeated benchmarks. Unlike " + "benchmark_report_aggregates_only, only affects the display reporter, but " + "*NOT* file reporter, which will still contain all the output."); + +DEFINE_string(benchmark_format, "console", + "The format to use for console output. Valid values are " + "'console', 'json', or 'csv'."); + +DEFINE_string(benchmark_out_format, "json", + "The format to use for file output. Valid values are " + "'console', 'json', or 'csv'."); + +DEFINE_string(benchmark_out, "", "The file to write additional output to"); + +DEFINE_string(benchmark_color, "auto", + "Whether to use colors in the output. Valid values: " + "'true'/'yes'/1, 'false'/'no'/0, and 'auto'. 'auto' means to use " + "colors if the output is being sent to a terminal and the TERM " + "environment variable is set to a terminal type that supports " + "colors."); + +DEFINE_bool(benchmark_counters_tabular, false, + "Whether to use tabular format when printing user counters to " + "the console. Valid values: 'true'/'yes'/1, 'false'/'no'/0." + "Defaults to false."); + +DEFINE_int32(v, 0, "The level of verbose logging to output"); + +namespace benchmark { + +namespace internal { + +// FIXME: wouldn't LTO mess this up? +void UseCharPointer(char const volatile*) {} + +} // namespace internal + +State::State(IterationCount max_iters, const std::vector& ranges, + int thread_i, int n_threads, internal::ThreadTimer* timer, + internal::ThreadManager* manager) + : total_iterations_(0), + batch_leftover_(0), + max_iterations(max_iters), + started_(false), + finished_(false), + error_occurred_(false), + range_(ranges), + complexity_n_(0), + counters(), + thread_index(thread_i), + threads(n_threads), + timer_(timer), + manager_(manager) { + CHECK(max_iterations != 0) << "At least one iteration must be run"; + CHECK_LT(thread_index, threads) << "thread_index must be less than threads"; + + // Note: The use of offsetof below is technically undefined until C++17 + // because State is not a standard layout type. However, all compilers + // currently provide well-defined behavior as an extension (which is + // demonstrated since constexpr evaluation must diagnose all undefined + // behavior). However, GCC and Clang also warn about this use of offsetof, + // which must be suppressed. +#if defined(__INTEL_COMPILER) +#pragma warning push +#pragma warning(disable:1875) +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winvalid-offsetof" +#endif + // Offset tests to ensure commonly accessed data is on the first cache line. + const int cache_line_size = 64; + static_assert(offsetof(State, error_occurred_) <= + (cache_line_size - sizeof(error_occurred_)), + ""); +#if defined(__INTEL_COMPILER) +#pragma warning pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif +} + +void State::PauseTiming() { + // Add in time accumulated so far + CHECK(started_ && !finished_ && !error_occurred_); + timer_->StopTimer(); +} + +void State::ResumeTiming() { + CHECK(started_ && !finished_ && !error_occurred_); + timer_->StartTimer(); +} + +void State::SkipWithError(const char* msg) { + CHECK(msg); + error_occurred_ = true; + { + MutexLock l(manager_->GetBenchmarkMutex()); + if (manager_->results.has_error_ == false) { + manager_->results.error_message_ = msg; + manager_->results.has_error_ = true; + } + } + total_iterations_ = 0; + if (timer_->running()) timer_->StopTimer(); +} + +void State::SetIterationTime(double seconds) { + timer_->SetIterationTime(seconds); +} + +void State::SetLabel(const char* label) { + MutexLock l(manager_->GetBenchmarkMutex()); + manager_->results.report_label_ = label; +} + +void State::StartKeepRunning() { + CHECK(!started_ && !finished_); + started_ = true; + total_iterations_ = error_occurred_ ? 0 : max_iterations; + manager_->StartStopBarrier(); + if (!error_occurred_) ResumeTiming(); +} + +void State::FinishKeepRunning() { + CHECK(started_ && (!finished_ || error_occurred_)); + if (!error_occurred_) { + PauseTiming(); + } + // Total iterations has now wrapped around past 0. Fix this. + total_iterations_ = 0; + finished_ = true; + manager_->StartStopBarrier(); +} + +namespace internal { +namespace { + +void RunBenchmarks(const std::vector& benchmarks, + BenchmarkReporter* display_reporter, + BenchmarkReporter* file_reporter) { + // Note the file_reporter can be null. + CHECK(display_reporter != nullptr); + + // Determine the width of the name field using a minimum width of 10. + bool might_have_aggregates = FLAGS_benchmark_repetitions > 1; + size_t name_field_width = 10; + size_t stat_field_width = 0; + for (const BenchmarkInstance& benchmark : benchmarks) { + name_field_width = + std::max(name_field_width, benchmark.name.str().size()); + might_have_aggregates |= benchmark.repetitions > 1; + + for (const auto& Stat : *benchmark.statistics) + stat_field_width = std::max(stat_field_width, Stat.name_.size()); + } + if (might_have_aggregates) name_field_width += 1 + stat_field_width; + + // Print header here + BenchmarkReporter::Context context; + context.name_field_width = name_field_width; + + // Keep track of running times of all instances of current benchmark + std::vector complexity_reports; + + // We flush streams after invoking reporter methods that write to them. This + // ensures users get timely updates even when streams are not line-buffered. + auto flushStreams = [](BenchmarkReporter* reporter) { + if (!reporter) return; + std::flush(reporter->GetOutputStream()); + std::flush(reporter->GetErrorStream()); + }; + + if (display_reporter->ReportContext(context) && + (!file_reporter || file_reporter->ReportContext(context))) { + flushStreams(display_reporter); + flushStreams(file_reporter); + + for (const auto& benchmark : benchmarks) { + RunResults run_results = RunBenchmark(benchmark, &complexity_reports); + + auto report = [&run_results](BenchmarkReporter* reporter, + bool report_aggregates_only) { + assert(reporter); + // If there are no aggregates, do output non-aggregates. + report_aggregates_only &= !run_results.aggregates_only.empty(); + if (!report_aggregates_only) + reporter->ReportRuns(run_results.non_aggregates); + if (!run_results.aggregates_only.empty()) + reporter->ReportRuns(run_results.aggregates_only); + }; + + report(display_reporter, run_results.display_report_aggregates_only); + if (file_reporter) + report(file_reporter, run_results.file_report_aggregates_only); + + flushStreams(display_reporter); + flushStreams(file_reporter); + } + } + display_reporter->Finalize(); + if (file_reporter) file_reporter->Finalize(); + flushStreams(display_reporter); + flushStreams(file_reporter); +} + +std::unique_ptr CreateReporter( + std::string const& name, ConsoleReporter::OutputOptions output_opts) { + typedef std::unique_ptr PtrType; + if (name == "console") { + return PtrType(new ConsoleReporter(output_opts)); + } else if (name == "json") { + return PtrType(new JSONReporter); + } else if (name == "csv") { + return PtrType(new CSVReporter); + } else { + std::cerr << "Unexpected format: '" << name << "'\n"; + std::exit(1); + } +} + +} // end namespace + +bool IsZero(double n) { + return std::abs(n) < std::numeric_limits::epsilon(); +} + +ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) { + int output_opts = ConsoleReporter::OO_Defaults; + auto is_benchmark_color = [force_no_color] () -> bool { + if (force_no_color) { + return false; + } + if (FLAGS_benchmark_color == "auto") { + return IsColorTerminal(); + } + return IsTruthyFlagValue(FLAGS_benchmark_color); + }; + if (is_benchmark_color()) { + output_opts |= ConsoleReporter::OO_Color; + } else { + output_opts &= ~ConsoleReporter::OO_Color; + } + if (FLAGS_benchmark_counters_tabular) { + output_opts |= ConsoleReporter::OO_Tabular; + } else { + output_opts &= ~ConsoleReporter::OO_Tabular; + } + return static_cast(output_opts); +} + +} // end namespace internal + +size_t RunSpecifiedBenchmarks() { + return RunSpecifiedBenchmarks(nullptr, nullptr); +} + +size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter) { + return RunSpecifiedBenchmarks(display_reporter, nullptr); +} + +size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, + BenchmarkReporter* file_reporter) { + std::string spec = FLAGS_benchmark_filter; + if (spec.empty() || spec == "all") + spec = "."; // Regexp that matches all benchmarks + + // Setup the reporters + std::ofstream output_file; + std::unique_ptr default_display_reporter; + std::unique_ptr default_file_reporter; + if (!display_reporter) { + default_display_reporter = internal::CreateReporter( + FLAGS_benchmark_format, internal::GetOutputOptions()); + display_reporter = default_display_reporter.get(); + } + auto& Out = display_reporter->GetOutputStream(); + auto& Err = display_reporter->GetErrorStream(); + + std::string const& fname = FLAGS_benchmark_out; + if (fname.empty() && file_reporter) { + Err << "A custom file reporter was provided but " + "--benchmark_out= was not specified." + << std::endl; + std::exit(1); + } + if (!fname.empty()) { + output_file.open(fname); + if (!output_file.is_open()) { + Err << "invalid file name: '" << fname << std::endl; + std::exit(1); + } + if (!file_reporter) { + default_file_reporter = internal::CreateReporter( + FLAGS_benchmark_out_format, ConsoleReporter::OO_None); + file_reporter = default_file_reporter.get(); + } + file_reporter->SetOutputStream(&output_file); + file_reporter->SetErrorStream(&output_file); + } + + std::vector benchmarks; + if (!FindBenchmarksInternal(spec, &benchmarks, &Err)) return 0; + + if (benchmarks.empty()) { + Err << "Failed to match any benchmarks against regex: " << spec << "\n"; + return 0; + } + + if (FLAGS_benchmark_list_tests) { + for (auto const& benchmark : benchmarks) + Out << benchmark.name.str() << "\n"; + } else { + internal::RunBenchmarks(benchmarks, display_reporter, file_reporter); + } + + return benchmarks.size(); +} + +void RegisterMemoryManager(MemoryManager* manager) { + internal::memory_manager = manager; +} + +namespace internal { + +void PrintUsageAndExit() { + fprintf(stdout, + "benchmark" + " [--benchmark_list_tests={true|false}]\n" + " [--benchmark_filter=]\n" + " [--benchmark_min_time=]\n" + " [--benchmark_repetitions=]\n" + " [--benchmark_report_aggregates_only={true|false}]\n" + " [--benchmark_display_aggregates_only={true|false}]\n" + " [--benchmark_format=]\n" + " [--benchmark_out=]\n" + " [--benchmark_out_format=]\n" + " [--benchmark_color={auto|true|false}]\n" + " [--benchmark_counters_tabular={true|false}]\n" + " [--v=]\n"); + exit(0); +} + +void ParseCommandLineFlags(int* argc, char** argv) { + using namespace benchmark; + BenchmarkReporter::Context::executable_name = + (argc && *argc > 0) ? argv[0] : "unknown"; + for (int i = 1; i < *argc; ++i) { + if (ParseBoolFlag(argv[i], "benchmark_list_tests", + &FLAGS_benchmark_list_tests) || + ParseStringFlag(argv[i], "benchmark_filter", &FLAGS_benchmark_filter) || + ParseDoubleFlag(argv[i], "benchmark_min_time", + &FLAGS_benchmark_min_time) || + ParseInt32Flag(argv[i], "benchmark_repetitions", + &FLAGS_benchmark_repetitions) || + ParseBoolFlag(argv[i], "benchmark_report_aggregates_only", + &FLAGS_benchmark_report_aggregates_only) || + ParseBoolFlag(argv[i], "benchmark_display_aggregates_only", + &FLAGS_benchmark_display_aggregates_only) || + ParseStringFlag(argv[i], "benchmark_format", &FLAGS_benchmark_format) || + ParseStringFlag(argv[i], "benchmark_out", &FLAGS_benchmark_out) || + ParseStringFlag(argv[i], "benchmark_out_format", + &FLAGS_benchmark_out_format) || + ParseStringFlag(argv[i], "benchmark_color", &FLAGS_benchmark_color) || + // "color_print" is the deprecated name for "benchmark_color". + // TODO: Remove this. + ParseStringFlag(argv[i], "color_print", &FLAGS_benchmark_color) || + ParseBoolFlag(argv[i], "benchmark_counters_tabular", + &FLAGS_benchmark_counters_tabular) || + ParseInt32Flag(argv[i], "v", &FLAGS_v)) { + for (int j = i; j != *argc - 1; ++j) argv[j] = argv[j + 1]; + + --(*argc); + --i; + } else if (IsFlag(argv[i], "help")) { + PrintUsageAndExit(); + } + } + for (auto const* flag : + {&FLAGS_benchmark_format, &FLAGS_benchmark_out_format}) + if (*flag != "console" && *flag != "json" && *flag != "csv") { + PrintUsageAndExit(); + } + if (FLAGS_benchmark_color.empty()) { + PrintUsageAndExit(); + } +} + +int InitializeStreams() { + static std::ios_base::Init init; + return 0; +} + +} // end namespace internal + +void Initialize(int* argc, char** argv) { + internal::ParseCommandLineFlags(argc, argv); + internal::LogLevel() = FLAGS_v; +} + +bool ReportUnrecognizedArguments(int argc, char** argv) { + for (int i = 1; i < argc; ++i) { + fprintf(stderr, "%s: error: unrecognized command-line flag: %s\n", argv[0], + argv[i]); + } + return argc > 1; +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.cc new file mode 100644 index 000000000..d468a257e --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.cc @@ -0,0 +1,15 @@ +#include "benchmark_api_internal.h" + +namespace benchmark { +namespace internal { + +State BenchmarkInstance::Run(IterationCount iters, int thread_id, + internal::ThreadTimer* timer, + internal::ThreadManager* manager) const { + State st(iters, arg, thread_id, threads, timer, manager); + benchmark->Run(st); + return st; +} + +} // internal +} // benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.h new file mode 100644 index 000000000..264eff95c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_api_internal.h @@ -0,0 +1,53 @@ +#ifndef BENCHMARK_API_INTERNAL_H +#define BENCHMARK_API_INTERNAL_H + +#include "benchmark/benchmark.h" +#include "commandlineflags.h" + +#include +#include +#include +#include +#include +#include + +namespace benchmark { +namespace internal { + +// Information kept per benchmark we may want to run +struct BenchmarkInstance { + BenchmarkName name; + Benchmark* benchmark; + AggregationReportMode aggregation_report_mode; + std::vector arg; + TimeUnit time_unit; + int range_multiplier; + bool measure_process_cpu_time; + bool use_real_time; + bool use_manual_time; + BigO complexity; + BigOFunc* complexity_lambda; + UserCounters counters; + const std::vector* statistics; + bool last_benchmark_instance; + int repetitions; + double min_time; + IterationCount iterations; + int threads; // Number of concurrent threads to us + + State Run(IterationCount iters, int thread_id, internal::ThreadTimer* timer, + internal::ThreadManager* manager) const; +}; + +bool FindBenchmarksInternal(const std::string& re, + std::vector* benchmarks, + std::ostream* Err); + +bool IsZero(double n); + +ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color = false); + +} // end namespace internal +} // end namespace benchmark + +#endif // BENCHMARK_API_INTERNAL_H diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_main.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_main.cc new file mode 100644 index 000000000..b3b247831 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_main.cc @@ -0,0 +1,17 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_name.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_name.cc new file mode 100644 index 000000000..2a17ebce2 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_name.cc @@ -0,0 +1,58 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +namespace benchmark { + +namespace { + +// Compute the total size of a pack of std::strings +size_t size_impl() { return 0; } + +template +size_t size_impl(const Head& head, const Tail&... tail) { + return head.size() + size_impl(tail...); +} + +// Join a pack of std::strings using a delimiter +// TODO: use absl::StrJoin +void join_impl(std::string&, char) {} + +template +void join_impl(std::string& s, const char delimiter, const Head& head, + const Tail&... tail) { + if (!s.empty() && !head.empty()) { + s += delimiter; + } + + s += head; + + join_impl(s, delimiter, tail...); +} + +template +std::string join(char delimiter, const Ts&... ts) { + std::string s; + s.reserve(sizeof...(Ts) + size_impl(ts...)); + join_impl(s, delimiter, ts...); + return s; +} +} // namespace + +std::string BenchmarkName::str() const { + return join('/', function_name, args, min_time, iterations, repetitions, + time_type, threads); +} +} // namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.cc new file mode 100644 index 000000000..6696c382b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.cc @@ -0,0 +1,504 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark_register.h" + +#ifndef BENCHMARK_OS_WINDOWS +#ifndef BENCHMARK_OS_FUCHSIA +#include +#endif +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __STDC_FORMAT_MACROS +#include + +#include "benchmark/benchmark.h" +#include "benchmark_api_internal.h" +#include "check.h" +#include "commandlineflags.h" +#include "complexity.h" +#include "internal_macros.h" +#include "log.h" +#include "mutex.h" +#include "re.h" +#include "statistics.h" +#include "string_util.h" +#include "timers.h" + +namespace benchmark { + +namespace { +// For non-dense Range, intermediate values are powers of kRangeMultiplier. +static const int kRangeMultiplier = 8; +// The size of a benchmark family determines is the number of inputs to repeat +// the benchmark on. If this is "large" then warn the user during configuration. +static const size_t kMaxFamilySize = 100; +} // end namespace + +namespace internal { + +//=============================================================================// +// BenchmarkFamilies +//=============================================================================// + +// Class for managing registered benchmarks. Note that each registered +// benchmark identifies a family of related benchmarks to run. +class BenchmarkFamilies { + public: + static BenchmarkFamilies* GetInstance(); + + // Registers a benchmark family and returns the index assigned to it. + size_t AddBenchmark(std::unique_ptr family); + + // Clear all registered benchmark families. + void ClearBenchmarks(); + + // Extract the list of benchmark instances that match the specified + // regular expression. + bool FindBenchmarks(std::string re, + std::vector* benchmarks, + std::ostream* Err); + + private: + BenchmarkFamilies() {} + + std::vector> families_; + Mutex mutex_; +}; + +BenchmarkFamilies* BenchmarkFamilies::GetInstance() { + static BenchmarkFamilies instance; + return &instance; +} + +size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr family) { + MutexLock l(mutex_); + size_t index = families_.size(); + families_.push_back(std::move(family)); + return index; +} + +void BenchmarkFamilies::ClearBenchmarks() { + MutexLock l(mutex_); + families_.clear(); + families_.shrink_to_fit(); +} + +bool BenchmarkFamilies::FindBenchmarks( + std::string spec, std::vector* benchmarks, + std::ostream* ErrStream) { + CHECK(ErrStream); + auto& Err = *ErrStream; + // Make regular expression out of command-line flag + std::string error_msg; + Regex re; + bool isNegativeFilter = false; + if (spec[0] == '-') { + spec.replace(0, 1, ""); + isNegativeFilter = true; + } + if (!re.Init(spec, &error_msg)) { + Err << "Could not compile benchmark re: " << error_msg << std::endl; + return false; + } + + // Special list of thread counts to use when none are specified + const std::vector one_thread = {1}; + + MutexLock l(mutex_); + for (std::unique_ptr& family : families_) { + // Family was deleted or benchmark doesn't match + if (!family) continue; + + if (family->ArgsCnt() == -1) { + family->Args({}); + } + const std::vector* thread_counts = + (family->thread_counts_.empty() + ? &one_thread + : &static_cast&>(family->thread_counts_)); + const size_t family_size = family->args_.size() * thread_counts->size(); + // The benchmark will be run at least 'family_size' different inputs. + // If 'family_size' is very large warn the user. + if (family_size > kMaxFamilySize) { + Err << "The number of inputs is very large. " << family->name_ + << " will be repeated at least " << family_size << " times.\n"; + } + // reserve in the special case the regex ".", since we know the final + // family size. + if (spec == ".") benchmarks->reserve(family_size); + + for (auto const& args : family->args_) { + for (int num_threads : *thread_counts) { + BenchmarkInstance instance; + instance.name.function_name = family->name_; + instance.benchmark = family.get(); + instance.aggregation_report_mode = family->aggregation_report_mode_; + instance.arg = args; + instance.time_unit = family->time_unit_; + instance.range_multiplier = family->range_multiplier_; + instance.min_time = family->min_time_; + instance.iterations = family->iterations_; + instance.repetitions = family->repetitions_; + instance.measure_process_cpu_time = family->measure_process_cpu_time_; + instance.use_real_time = family->use_real_time_; + instance.use_manual_time = family->use_manual_time_; + instance.complexity = family->complexity_; + instance.complexity_lambda = family->complexity_lambda_; + instance.statistics = &family->statistics_; + instance.threads = num_threads; + + // Add arguments to instance name + size_t arg_i = 0; + for (auto const& arg : args) { + if (!instance.name.args.empty()) { + instance.name.args += '/'; + } + + if (arg_i < family->arg_names_.size()) { + const auto& arg_name = family->arg_names_[arg_i]; + if (!arg_name.empty()) { + instance.name.args += StrFormat("%s:", arg_name.c_str()); + } + } + + instance.name.args += StrFormat("%" PRId64, arg); + ++arg_i; + } + + if (!IsZero(family->min_time_)) + instance.name.min_time = + StrFormat("min_time:%0.3f", family->min_time_); + if (family->iterations_ != 0) { + instance.name.iterations = + StrFormat("iterations:%lu", + static_cast(family->iterations_)); + } + if (family->repetitions_ != 0) + instance.name.repetitions = + StrFormat("repeats:%d", family->repetitions_); + + if (family->measure_process_cpu_time_) { + instance.name.time_type = "process_time"; + } + + if (family->use_manual_time_) { + if (!instance.name.time_type.empty()) { + instance.name.time_type += '/'; + } + instance.name.time_type += "manual_time"; + } else if (family->use_real_time_) { + if (!instance.name.time_type.empty()) { + instance.name.time_type += '/'; + } + instance.name.time_type += "real_time"; + } + + // Add the number of threads used to the name + if (!family->thread_counts_.empty()) { + instance.name.threads = StrFormat("threads:%d", instance.threads); + } + + const auto full_name = instance.name.str(); + if ((re.Match(full_name) && !isNegativeFilter) || + (!re.Match(full_name) && isNegativeFilter)) { + instance.last_benchmark_instance = (&args == &family->args_.back()); + benchmarks->push_back(std::move(instance)); + } + } + } + } + return true; +} + +Benchmark* RegisterBenchmarkInternal(Benchmark* bench) { + std::unique_ptr bench_ptr(bench); + BenchmarkFamilies* families = BenchmarkFamilies::GetInstance(); + families->AddBenchmark(std::move(bench_ptr)); + return bench; +} + +// FIXME: This function is a hack so that benchmark.cc can access +// `BenchmarkFamilies` +bool FindBenchmarksInternal(const std::string& re, + std::vector* benchmarks, + std::ostream* Err) { + return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err); +} + +//=============================================================================// +// Benchmark +//=============================================================================// + +Benchmark::Benchmark(const char* name) + : name_(name), + aggregation_report_mode_(ARM_Unspecified), + time_unit_(kNanosecond), + range_multiplier_(kRangeMultiplier), + min_time_(0), + iterations_(0), + repetitions_(0), + measure_process_cpu_time_(false), + use_real_time_(false), + use_manual_time_(false), + complexity_(oNone), + complexity_lambda_(nullptr) { + ComputeStatistics("mean", StatisticsMean); + ComputeStatistics("median", StatisticsMedian); + ComputeStatistics("stddev", StatisticsStdDev); +} + +Benchmark::~Benchmark() {} + +Benchmark* Benchmark::Arg(int64_t x) { + CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); + args_.push_back({x}); + return this; +} + +Benchmark* Benchmark::Unit(TimeUnit unit) { + time_unit_ = unit; + return this; +} + +Benchmark* Benchmark::Range(int64_t start, int64_t limit) { + CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); + std::vector arglist; + AddRange(&arglist, start, limit, range_multiplier_); + + for (int64_t i : arglist) { + args_.push_back({i}); + } + return this; +} + +Benchmark* Benchmark::Ranges( + const std::vector>& ranges) { + CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast(ranges.size())); + std::vector> arglists(ranges.size()); + std::size_t total = 1; + for (std::size_t i = 0; i < ranges.size(); i++) { + AddRange(&arglists[i], ranges[i].first, ranges[i].second, + range_multiplier_); + total *= arglists[i].size(); + } + + std::vector ctr(arglists.size(), 0); + + for (std::size_t i = 0; i < total; i++) { + std::vector tmp; + tmp.reserve(arglists.size()); + + for (std::size_t j = 0; j < arglists.size(); j++) { + tmp.push_back(arglists[j].at(ctr[j])); + } + + args_.push_back(std::move(tmp)); + + for (std::size_t j = 0; j < arglists.size(); j++) { + if (ctr[j] + 1 < arglists[j].size()) { + ++ctr[j]; + break; + } + ctr[j] = 0; + } + } + return this; +} + +Benchmark* Benchmark::ArgName(const std::string& name) { + CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); + arg_names_ = {name}; + return this; +} + +Benchmark* Benchmark::ArgNames(const std::vector& names) { + CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast(names.size())); + arg_names_ = names; + return this; +} + +Benchmark* Benchmark::DenseRange(int64_t start, int64_t limit, int step) { + CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); + CHECK_LE(start, limit); + for (int64_t arg = start; arg <= limit; arg += step) { + args_.push_back({arg}); + } + return this; +} + +Benchmark* Benchmark::Args(const std::vector& args) { + CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast(args.size())); + args_.push_back(args); + return this; +} + +Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) { + custom_arguments(this); + return this; +} + +Benchmark* Benchmark::RangeMultiplier(int multiplier) { + CHECK(multiplier > 1); + range_multiplier_ = multiplier; + return this; +} + +Benchmark* Benchmark::MinTime(double t) { + CHECK(t > 0.0); + CHECK(iterations_ == 0); + min_time_ = t; + return this; +} + +Benchmark* Benchmark::Iterations(IterationCount n) { + CHECK(n > 0); + CHECK(IsZero(min_time_)); + iterations_ = n; + return this; +} + +Benchmark* Benchmark::Repetitions(int n) { + CHECK(n > 0); + repetitions_ = n; + return this; +} + +Benchmark* Benchmark::ReportAggregatesOnly(bool value) { + aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default; + return this; +} + +Benchmark* Benchmark::DisplayAggregatesOnly(bool value) { + // If we were called, the report mode is no longer 'unspecified', in any case. + aggregation_report_mode_ = static_cast( + aggregation_report_mode_ | ARM_Default); + + if (value) { + aggregation_report_mode_ = static_cast( + aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly); + } else { + aggregation_report_mode_ = static_cast( + aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly); + } + + return this; +} + +Benchmark* Benchmark::MeasureProcessCPUTime() { + // Can be used together with UseRealTime() / UseManualTime(). + measure_process_cpu_time_ = true; + return this; +} + +Benchmark* Benchmark::UseRealTime() { + CHECK(!use_manual_time_) + << "Cannot set UseRealTime and UseManualTime simultaneously."; + use_real_time_ = true; + return this; +} + +Benchmark* Benchmark::UseManualTime() { + CHECK(!use_real_time_) + << "Cannot set UseRealTime and UseManualTime simultaneously."; + use_manual_time_ = true; + return this; +} + +Benchmark* Benchmark::Complexity(BigO complexity) { + complexity_ = complexity; + return this; +} + +Benchmark* Benchmark::Complexity(BigOFunc* complexity) { + complexity_lambda_ = complexity; + complexity_ = oLambda; + return this; +} + +Benchmark* Benchmark::ComputeStatistics(std::string name, + StatisticsFunc* statistics) { + statistics_.emplace_back(name, statistics); + return this; +} + +Benchmark* Benchmark::Threads(int t) { + CHECK_GT(t, 0); + thread_counts_.push_back(t); + return this; +} + +Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) { + CHECK_GT(min_threads, 0); + CHECK_GE(max_threads, min_threads); + + AddRange(&thread_counts_, min_threads, max_threads, 2); + return this; +} + +Benchmark* Benchmark::DenseThreadRange(int min_threads, int max_threads, + int stride) { + CHECK_GT(min_threads, 0); + CHECK_GE(max_threads, min_threads); + CHECK_GE(stride, 1); + + for (auto i = min_threads; i < max_threads; i += stride) { + thread_counts_.push_back(i); + } + thread_counts_.push_back(max_threads); + return this; +} + +Benchmark* Benchmark::ThreadPerCpu() { + thread_counts_.push_back(CPUInfo::Get().num_cpus); + return this; +} + +void Benchmark::SetName(const char* name) { name_ = name; } + +int Benchmark::ArgsCnt() const { + if (args_.empty()) { + if (arg_names_.empty()) return -1; + return static_cast(arg_names_.size()); + } + return static_cast(args_.front().size()); +} + +//=============================================================================// +// FunctionBenchmark +//=============================================================================// + +void FunctionBenchmark::Run(State& st) { func_(st); } + +} // end namespace internal + +void ClearRegisteredBenchmarks() { + internal::BenchmarkFamilies::GetInstance()->ClearBenchmarks(); +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.h new file mode 100644 index 000000000..61377d742 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_register.h @@ -0,0 +1,107 @@ +#ifndef BENCHMARK_REGISTER_H +#define BENCHMARK_REGISTER_H + +#include + +#include "check.h" + +namespace benchmark { +namespace internal { + +// Append the powers of 'mult' in the closed interval [lo, hi]. +// Returns iterator to the start of the inserted range. +template +typename std::vector::iterator +AddPowers(std::vector* dst, T lo, T hi, int mult) { + CHECK_GE(lo, 0); + CHECK_GE(hi, lo); + CHECK_GE(mult, 2); + + const size_t start_offset = dst->size(); + + static const T kmax = std::numeric_limits::max(); + + // Space out the values in multiples of "mult" + for (T i = 1; i <= hi; i *= mult) { + if (i >= lo) { + dst->push_back(i); + } + // Break the loop here since multiplying by + // 'mult' would move outside of the range of T + if (i > kmax / mult) break; + } + + return dst->begin() + start_offset; +} + +template +void AddNegatedPowers(std::vector* dst, T lo, T hi, int mult) { + // We negate lo and hi so we require that they cannot be equal to 'min'. + CHECK_GT(lo, std::numeric_limits::min()); + CHECK_GT(hi, std::numeric_limits::min()); + CHECK_GE(hi, lo); + CHECK_LE(hi, 0); + + // Add positive powers, then negate and reverse. + // Casts necessary since small integers get promoted + // to 'int' when negating. + const auto lo_complement = static_cast(-lo); + const auto hi_complement = static_cast(-hi); + + const auto it = AddPowers(dst, hi_complement, lo_complement, mult); + + std::for_each(it, dst->end(), [](T& t) { t *= -1; }); + std::reverse(it, dst->end()); +} + +template +void AddRange(std::vector* dst, T lo, T hi, int mult) { + static_assert(std::is_integral::value && std::is_signed::value, + "Args type must be a signed integer"); + + CHECK_GE(hi, lo); + CHECK_GE(mult, 2); + + // Add "lo" + dst->push_back(lo); + + // Handle lo == hi as a special case, so we then know + // lo < hi and so it is safe to add 1 to lo and subtract 1 + // from hi without falling outside of the range of T. + if (lo == hi) return; + + // Ensure that lo_inner <= hi_inner below. + if (lo + 1 == hi) { + dst->push_back(hi); + return; + } + + // Add all powers of 'mult' in the range [lo+1, hi-1] (inclusive). + const auto lo_inner = static_cast(lo + 1); + const auto hi_inner = static_cast(hi - 1); + + // Insert negative values + if (lo_inner < 0) { + AddNegatedPowers(dst, lo_inner, std::min(hi_inner, T{-1}), mult); + } + + // Treat 0 as a special case (see discussion on #762). + if (lo <= 0 && hi >= 0) { + dst->push_back(0); + } + + // Insert positive values + if (hi_inner > 0) { + AddPowers(dst, std::max(lo_inner, T{1}), hi_inner, mult); + } + + // Add "hi" (if different from last value). + if (hi != dst->back()) { + dst->push_back(hi); + } +} + +} // namespace internal +} // namespace benchmark + +#endif // BENCHMARK_REGISTER_H diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.cc new file mode 100644 index 000000000..0bae6a545 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.cc @@ -0,0 +1,361 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark_runner.h" +#include "benchmark/benchmark.h" +#include "benchmark_api_internal.h" +#include "internal_macros.h" + +#ifndef BENCHMARK_OS_WINDOWS +#ifndef BENCHMARK_OS_FUCHSIA +#include +#endif +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "colorprint.h" +#include "commandlineflags.h" +#include "complexity.h" +#include "counter.h" +#include "internal_macros.h" +#include "log.h" +#include "mutex.h" +#include "re.h" +#include "statistics.h" +#include "string_util.h" +#include "thread_manager.h" +#include "thread_timer.h" + +namespace benchmark { + +namespace internal { + +MemoryManager* memory_manager = nullptr; + +namespace { + +static constexpr IterationCount kMaxIterations = 1000000000; + +BenchmarkReporter::Run CreateRunReport( + const benchmark::internal::BenchmarkInstance& b, + const internal::ThreadManager::Result& results, + IterationCount memory_iterations, + const MemoryManager::Result& memory_result, double seconds, + int64_t repetition_index) { + // Create report about this benchmark run. + BenchmarkReporter::Run report; + + report.run_name = b.name; + report.error_occurred = results.has_error_; + report.error_message = results.error_message_; + report.report_label = results.report_label_; + // This is the total iterations across all threads. + report.iterations = results.iterations; + report.time_unit = b.time_unit; + report.threads = b.threads; + report.repetition_index = repetition_index; + report.repetitions = b.repetitions; + + if (!report.error_occurred) { + if (b.use_manual_time) { + report.real_accumulated_time = results.manual_time_used; + } else { + report.real_accumulated_time = results.real_time_used; + } + report.cpu_accumulated_time = results.cpu_time_used; + report.complexity_n = results.complexity_n; + report.complexity = b.complexity; + report.complexity_lambda = b.complexity_lambda; + report.statistics = b.statistics; + report.counters = results.counters; + + if (memory_iterations > 0) { + report.has_memory_result = true; + report.allocs_per_iter = + memory_iterations ? static_cast(memory_result.num_allocs) / + memory_iterations + : 0; + report.max_bytes_used = memory_result.max_bytes_used; + } + + internal::Finish(&report.counters, results.iterations, seconds, b.threads); + } + return report; +} + +// Execute one thread of benchmark b for the specified number of iterations. +// Adds the stats collected for the thread into *total. +void RunInThread(const BenchmarkInstance* b, IterationCount iters, + int thread_id, ThreadManager* manager) { + internal::ThreadTimer timer( + b->measure_process_cpu_time + ? internal::ThreadTimer::CreateProcessCpuTime() + : internal::ThreadTimer::Create()); + State st = b->Run(iters, thread_id, &timer, manager); + CHECK(st.iterations() >= st.max_iterations) + << "Benchmark returned before State::KeepRunning() returned false!"; + { + MutexLock l(manager->GetBenchmarkMutex()); + internal::ThreadManager::Result& results = manager->results; + results.iterations += st.iterations(); + results.cpu_time_used += timer.cpu_time_used(); + results.real_time_used += timer.real_time_used(); + results.manual_time_used += timer.manual_time_used(); + results.complexity_n += st.complexity_length_n(); + internal::Increment(&results.counters, st.counters); + } + manager->NotifyThreadComplete(); +} + +class BenchmarkRunner { + public: + BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_, + std::vector* complexity_reports_) + : b(b_), + complexity_reports(*complexity_reports_), + min_time(!IsZero(b.min_time) ? b.min_time : FLAGS_benchmark_min_time), + repeats(b.repetitions != 0 ? b.repetitions + : FLAGS_benchmark_repetitions), + has_explicit_iteration_count(b.iterations != 0), + pool(b.threads - 1), + iters(has_explicit_iteration_count ? b.iterations : 1) { + run_results.display_report_aggregates_only = + (FLAGS_benchmark_report_aggregates_only || + FLAGS_benchmark_display_aggregates_only); + run_results.file_report_aggregates_only = + FLAGS_benchmark_report_aggregates_only; + if (b.aggregation_report_mode != internal::ARM_Unspecified) { + run_results.display_report_aggregates_only = + (b.aggregation_report_mode & + internal::ARM_DisplayReportAggregatesOnly); + run_results.file_report_aggregates_only = + (b.aggregation_report_mode & internal::ARM_FileReportAggregatesOnly); + } + + for (int repetition_num = 0; repetition_num < repeats; repetition_num++) { + DoOneRepetition(repetition_num); + } + + // Calculate additional statistics + run_results.aggregates_only = ComputeStats(run_results.non_aggregates); + + // Maybe calculate complexity report + if ((b.complexity != oNone) && b.last_benchmark_instance) { + auto additional_run_stats = ComputeBigO(complexity_reports); + run_results.aggregates_only.insert(run_results.aggregates_only.end(), + additional_run_stats.begin(), + additional_run_stats.end()); + complexity_reports.clear(); + } + } + + RunResults&& get_results() { return std::move(run_results); } + + private: + RunResults run_results; + + const benchmark::internal::BenchmarkInstance& b; + std::vector& complexity_reports; + + const double min_time; + const int repeats; + const bool has_explicit_iteration_count; + + std::vector pool; + + IterationCount iters; // preserved between repetitions! + // So only the first repetition has to find/calculate it, + // the other repetitions will just use that precomputed iteration count. + + struct IterationResults { + internal::ThreadManager::Result results; + IterationCount iters; + double seconds; + }; + IterationResults DoNIterations() { + VLOG(2) << "Running " << b.name.str() << " for " << iters << "\n"; + + std::unique_ptr manager; + manager.reset(new internal::ThreadManager(b.threads)); + + // Run all but one thread in separate threads + for (std::size_t ti = 0; ti < pool.size(); ++ti) { + pool[ti] = std::thread(&RunInThread, &b, iters, static_cast(ti + 1), + manager.get()); + } + // And run one thread here directly. + // (If we were asked to run just one thread, we don't create new threads.) + // Yes, we need to do this here *after* we start the separate threads. + RunInThread(&b, iters, 0, manager.get()); + + // The main thread has finished. Now let's wait for the other threads. + manager->WaitForAllThreads(); + for (std::thread& thread : pool) thread.join(); + + IterationResults i; + // Acquire the measurements/counters from the manager, UNDER THE LOCK! + { + MutexLock l(manager->GetBenchmarkMutex()); + i.results = manager->results; + } + + // And get rid of the manager. + manager.reset(); + + // Adjust real/manual time stats since they were reported per thread. + i.results.real_time_used /= b.threads; + i.results.manual_time_used /= b.threads; + // If we were measuring whole-process CPU usage, adjust the CPU time too. + if (b.measure_process_cpu_time) i.results.cpu_time_used /= b.threads; + + VLOG(2) << "Ran in " << i.results.cpu_time_used << "/" + << i.results.real_time_used << "\n"; + + // So for how long were we running? + i.iters = iters; + // Base decisions off of real time if requested by this benchmark. + i.seconds = i.results.cpu_time_used; + if (b.use_manual_time) { + i.seconds = i.results.manual_time_used; + } else if (b.use_real_time) { + i.seconds = i.results.real_time_used; + } + + return i; + } + + IterationCount PredictNumItersNeeded(const IterationResults& i) const { + // See how much iterations should be increased by. + // Note: Avoid division by zero with max(seconds, 1ns). + double multiplier = min_time * 1.4 / std::max(i.seconds, 1e-9); + // If our last run was at least 10% of FLAGS_benchmark_min_time then we + // use the multiplier directly. + // Otherwise we use at most 10 times expansion. + // NOTE: When the last run was at least 10% of the min time the max + // expansion should be 14x. + bool is_significant = (i.seconds / min_time) > 0.1; + multiplier = is_significant ? multiplier : std::min(10.0, multiplier); + if (multiplier <= 1.0) multiplier = 2.0; + + // So what seems to be the sufficiently-large iteration count? Round up. + const IterationCount max_next_iters = + 0.5 + std::max(multiplier * i.iters, i.iters + 1.0); + // But we do have *some* sanity limits though.. + const IterationCount next_iters = std::min(max_next_iters, kMaxIterations); + + VLOG(3) << "Next iters: " << next_iters << ", " << multiplier << "\n"; + return next_iters; // round up before conversion to integer. + } + + bool ShouldReportIterationResults(const IterationResults& i) const { + // Determine if this run should be reported; + // Either it has run for a sufficient amount of time + // or because an error was reported. + return i.results.has_error_ || + i.iters >= kMaxIterations || // Too many iterations already. + i.seconds >= min_time || // The elapsed time is large enough. + // CPU time is specified but the elapsed real time greatly exceeds + // the minimum time. + // Note that user provided timers are except from this sanity check. + ((i.results.real_time_used >= 5 * min_time) && !b.use_manual_time); + } + + void DoOneRepetition(int64_t repetition_index) { + const bool is_the_first_repetition = repetition_index == 0; + IterationResults i; + + // We *may* be gradually increasing the length (iteration count) + // of the benchmark until we decide the results are significant. + // And once we do, we report those last results and exit. + // Please do note that the if there are repetitions, the iteration count + // is *only* calculated for the *first* repetition, and other repetitions + // simply use that precomputed iteration count. + for (;;) { + i = DoNIterations(); + + // Do we consider the results to be significant? + // If we are doing repetitions, and the first repetition was already done, + // it has calculated the correct iteration time, so we have run that very + // iteration count just now. No need to calculate anything. Just report. + // Else, the normal rules apply. + const bool results_are_significant = !is_the_first_repetition || + has_explicit_iteration_count || + ShouldReportIterationResults(i); + + if (results_are_significant) break; // Good, let's report them! + + // Nope, bad iteration. Let's re-estimate the hopefully-sufficient + // iteration count, and run the benchmark again... + + iters = PredictNumItersNeeded(i); + assert(iters > i.iters && + "if we did more iterations than we want to do the next time, " + "then we should have accepted the current iteration run."); + } + + // Oh, one last thing, we need to also produce the 'memory measurements'.. + MemoryManager::Result memory_result; + IterationCount memory_iterations = 0; + if (memory_manager != nullptr) { + // Only run a few iterations to reduce the impact of one-time + // allocations in benchmarks that are not properly managed. + memory_iterations = std::min(16, iters); + memory_manager->Start(); + std::unique_ptr manager; + manager.reset(new internal::ThreadManager(1)); + RunInThread(&b, memory_iterations, 0, manager.get()); + manager->WaitForAllThreads(); + manager.reset(); + + memory_manager->Stop(&memory_result); + } + + // Ok, now actualy report. + BenchmarkReporter::Run report = + CreateRunReport(b, i.results, memory_iterations, memory_result, + i.seconds, repetition_index); + + if (!report.error_occurred && b.complexity != oNone) + complexity_reports.push_back(report); + + run_results.non_aggregates.push_back(report); + } +}; + +} // end namespace + +RunResults RunBenchmark( + const benchmark::internal::BenchmarkInstance& b, + std::vector* complexity_reports) { + internal::BenchmarkRunner r(b, complexity_reports); + return r.get_results(); +} + +} // end namespace internal + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.h new file mode 100644 index 000000000..96e8282a1 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/benchmark_runner.h @@ -0,0 +1,51 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef BENCHMARK_RUNNER_H_ +#define BENCHMARK_RUNNER_H_ + +#include "benchmark_api_internal.h" +#include "internal_macros.h" + +DECLARE_double(benchmark_min_time); + +DECLARE_int32(benchmark_repetitions); + +DECLARE_bool(benchmark_report_aggregates_only); + +DECLARE_bool(benchmark_display_aggregates_only); + +namespace benchmark { + +namespace internal { + +extern MemoryManager* memory_manager; + +struct RunResults { + std::vector non_aggregates; + std::vector aggregates_only; + + bool display_report_aggregates_only = false; + bool file_report_aggregates_only = false; +}; + +RunResults RunBenchmark( + const benchmark::internal::BenchmarkInstance& b, + std::vector* complexity_reports); + +} // namespace internal + +} // end namespace benchmark + +#endif // BENCHMARK_RUNNER_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/check.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/check.h new file mode 100644 index 000000000..f5f8253f8 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/check.h @@ -0,0 +1,82 @@ +#ifndef CHECK_H_ +#define CHECK_H_ + +#include +#include +#include + +#include "internal_macros.h" +#include "log.h" + +namespace benchmark { +namespace internal { + +typedef void(AbortHandlerT)(); + +inline AbortHandlerT*& GetAbortHandler() { + static AbortHandlerT* handler = &std::abort; + return handler; +} + +BENCHMARK_NORETURN inline void CallAbortHandler() { + GetAbortHandler()(); + std::abort(); // fallback to enforce noreturn +} + +// CheckHandler is the class constructed by failing CHECK macros. CheckHandler +// will log information about the failures and abort when it is destructed. +class CheckHandler { + public: + CheckHandler(const char* check, const char* file, const char* func, int line) + : log_(GetErrorLogInstance()) { + log_ << file << ":" << line << ": " << func << ": Check `" << check + << "' failed. "; + } + + LogType& GetLog() { return log_; } + + BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) { + log_ << std::endl; + CallAbortHandler(); + } + + CheckHandler& operator=(const CheckHandler&) = delete; + CheckHandler(const CheckHandler&) = delete; + CheckHandler() = delete; + + private: + LogType& log_; +}; + +} // end namespace internal +} // end namespace benchmark + +// The CHECK macro returns a std::ostream object that can have extra information +// written to it. +#ifndef NDEBUG +#define CHECK(b) \ + (b ? ::benchmark::internal::GetNullLogInstance() \ + : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \ + .GetLog()) +#else +#define CHECK(b) ::benchmark::internal::GetNullLogInstance() +#endif + +// clang-format off +// preserve whitespacing between operators for alignment +#define CHECK_EQ(a, b) CHECK((a) == (b)) +#define CHECK_NE(a, b) CHECK((a) != (b)) +#define CHECK_GE(a, b) CHECK((a) >= (b)) +#define CHECK_LE(a, b) CHECK((a) <= (b)) +#define CHECK_GT(a, b) CHECK((a) > (b)) +#define CHECK_LT(a, b) CHECK((a) < (b)) + +#define CHECK_FLOAT_EQ(a, b, eps) CHECK(std::fabs((a) - (b)) < (eps)) +#define CHECK_FLOAT_NE(a, b, eps) CHECK(std::fabs((a) - (b)) >= (eps)) +#define CHECK_FLOAT_GE(a, b, eps) CHECK((a) - (b) > -(eps)) +#define CHECK_FLOAT_LE(a, b, eps) CHECK((b) - (a) > -(eps)) +#define CHECK_FLOAT_GT(a, b, eps) CHECK((a) - (b) > (eps)) +#define CHECK_FLOAT_LT(a, b, eps) CHECK((b) - (a) > (eps)) +//clang-format on + +#endif // CHECK_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.cc new file mode 100644 index 000000000..fff6a9881 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.cc @@ -0,0 +1,188 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "colorprint.h" + +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "internal_macros.h" + +#ifdef BENCHMARK_OS_WINDOWS +#include +#include +#else +#include +#endif // BENCHMARK_OS_WINDOWS + +namespace benchmark { +namespace { +#ifdef BENCHMARK_OS_WINDOWS +typedef WORD PlatformColorCode; +#else +typedef const char* PlatformColorCode; +#endif + +PlatformColorCode GetPlatformColorCode(LogColor color) { +#ifdef BENCHMARK_OS_WINDOWS + switch (color) { + case COLOR_RED: + return FOREGROUND_RED; + case COLOR_GREEN: + return FOREGROUND_GREEN; + case COLOR_YELLOW: + return FOREGROUND_RED | FOREGROUND_GREEN; + case COLOR_BLUE: + return FOREGROUND_BLUE; + case COLOR_MAGENTA: + return FOREGROUND_BLUE | FOREGROUND_RED; + case COLOR_CYAN: + return FOREGROUND_BLUE | FOREGROUND_GREEN; + case COLOR_WHITE: // fall through to default + default: + return 0; + } +#else + switch (color) { + case COLOR_RED: + return "1"; + case COLOR_GREEN: + return "2"; + case COLOR_YELLOW: + return "3"; + case COLOR_BLUE: + return "4"; + case COLOR_MAGENTA: + return "5"; + case COLOR_CYAN: + return "6"; + case COLOR_WHITE: + return "7"; + default: + return nullptr; + }; +#endif +} + +} // end namespace + +std::string FormatString(const char* msg, va_list args) { + // we might need a second shot at this, so pre-emptivly make a copy + va_list args_cp; + va_copy(args_cp, args); + + std::size_t size = 256; + char local_buff[256]; + auto ret = vsnprintf(local_buff, size, msg, args_cp); + + va_end(args_cp); + + // currently there is no error handling for failure, so this is hack. + CHECK(ret >= 0); + + if (ret == 0) // handle empty expansion + return {}; + else if (static_cast(ret) < size) + return local_buff; + else { + // we did not provide a long enough buffer on our first attempt. + size = (size_t)ret + 1; // + 1 for the null byte + std::unique_ptr buff(new char[size]); + ret = vsnprintf(buff.get(), size, msg, args); + CHECK(ret > 0 && ((size_t)ret) < size); + return buff.get(); + } +} + +std::string FormatString(const char* msg, ...) { + va_list args; + va_start(args, msg); + auto tmp = FormatString(msg, args); + va_end(args); + return tmp; +} + +void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + ColorPrintf(out, color, fmt, args); + va_end(args); +} + +void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, + va_list args) { +#ifdef BENCHMARK_OS_WINDOWS + ((void)out); // suppress unused warning + + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetPlatformColorCode(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + const char* color_code = GetPlatformColorCode(color); + if (color_code) out << FormatString("\033[0;3%sm", color_code); + out << FormatString(fmt, args) << "\033[m"; +#endif +} + +bool IsColorTerminal() { +#if BENCHMARK_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return 0 != _isatty(_fileno(stdout)); +#else + // On non-Windows platforms, we rely on the TERM variable. This list of + // supported TERM values is copied from Google Test: + // . + const char* const SUPPORTED_TERM_VALUES[] = { + "xterm", "xterm-color", "xterm-256color", + "screen", "screen-256color", "tmux", + "tmux-256color", "rxvt-unicode", "rxvt-unicode-256color", + "linux", "cygwin", + }; + + const char* const term = getenv("TERM"); + + bool term_supports_color = false; + for (const char* candidate : SUPPORTED_TERM_VALUES) { + if (term && 0 == strcmp(term, candidate)) { + term_supports_color = true; + break; + } + } + + return 0 != isatty(fileno(stdout)) && term_supports_color; +#endif // BENCHMARK_OS_WINDOWS +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.h new file mode 100644 index 000000000..9f6fab9b3 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/colorprint.h @@ -0,0 +1,33 @@ +#ifndef BENCHMARK_COLORPRINT_H_ +#define BENCHMARK_COLORPRINT_H_ + +#include +#include +#include + +namespace benchmark { +enum LogColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW, + COLOR_BLUE, + COLOR_MAGENTA, + COLOR_CYAN, + COLOR_WHITE +}; + +std::string FormatString(const char* msg, va_list args); +std::string FormatString(const char* msg, ...); + +void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, + va_list args); +void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...); + +// Returns true if stdout appears to be a terminal that supports colored +// output, false otherwise. +bool IsColorTerminal(); + +} // end namespace benchmark + +#endif // BENCHMARK_COLORPRINT_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.cc new file mode 100644 index 000000000..6bd65c5ae --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.cc @@ -0,0 +1,222 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "commandlineflags.h" + +#include +#include +#include +#include +#include + +namespace benchmark { +namespace { + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const std::string& src_text, const char* str, int32_t* value) { + // Parses the environment variable as a decimal integer. + char* end = nullptr; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + std::cerr << src_text << " is expected to be a 32-bit integer, " + << "but actually has value \"" << str << "\".\n"; + return false; + } + + // Is the parsed value in the range of an Int32? + const int32_t result = static_cast(long_value); + if (long_value == std::numeric_limits::max() || + long_value == std::numeric_limits::min() || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + std::cerr << src_text << " is expected to be a 32-bit integer, " + << "but actually has value \"" << str << "\", " + << "which overflows.\n"; + return false; + } + + *value = result; + return true; +} + +// Parses 'str' for a double. If successful, writes the result to *value and +// returns true; otherwise leaves *value unchanged and returns false. +bool ParseDouble(const std::string& src_text, const char* str, double* value) { + // Parses the environment variable as a decimal integer. + char* end = nullptr; + const double double_value = strtod(str, &end); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + std::cerr << src_text << " is expected to be a double, " + << "but actually has value \"" << str << "\".\n"; + return false; + } + + *value = double_value; + return true; +} + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "BENCHMARK_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string flag_str(flag); + + std::string env_var; + for (size_t i = 0; i != flag_str.length(); ++i) + env_var += static_cast(::toupper(flag_str.c_str()[i])); + + return "BENCHMARK_" + env_var; +} + +} // namespace + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromEnv(const char* flag, bool default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = getenv(env_var.c_str()); + return string_value == nullptr ? default_value + : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +int32_t Int32FromEnv(const char* flag, int32_t default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = getenv(env_var.c_str()); + if (string_value == nullptr) { + // The environment variable is not set. + return default_value; + } + + int32_t result = default_value; + if (!ParseInt32(std::string("Environment variable ") + env_var, string_value, + &result)) { + std::cout << "The default value " << default_value << " is used.\n"; + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromEnv(const char* flag, const char* default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const value = getenv(env_var.c_str()); + return value == nullptr ? default_value : value; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or nullptr if the parsing failed. +const char* ParseFlagValue(const char* str, const char* flag, + bool def_optional) { + // str and flag must not be nullptr. + if (str == nullptr || flag == nullptr) return nullptr; + + // The flag must start with "--". + const std::string flag_str = std::string("--") + std::string(flag); + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) return flag_end; + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return nullptr; + + // Returns the string after "=". + return flag_end + 1; +} + +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Converts the string value to a bool. + *value = IsTruthyFlagValue(value_str); + return true; +} + +bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Sets *value to the value of the flag. + return ParseInt32(std::string("The value of flag --") + flag, value_str, + value); +} + +bool ParseDoubleFlag(const char* str, const char* flag, double* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Sets *value to the value of the flag. + return ParseDouble(std::string("The value of flag --") + flag, value_str, + value); +} + +bool ParseStringFlag(const char* str, const char* flag, std::string* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + *value = value_str; + return true; +} + +bool IsFlag(const char* str, const char* flag) { + return (ParseFlagValue(str, flag, true) != nullptr); +} + +bool IsTruthyFlagValue(const std::string& value) { + if (value.empty()) return true; + char ch = value[0]; + return isalnum(ch) && + !(ch == '0' || ch == 'f' || ch == 'F' || ch == 'n' || ch == 'N'); +} +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.h new file mode 100644 index 000000000..5eaea82a5 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/commandlineflags.h @@ -0,0 +1,73 @@ +#ifndef BENCHMARK_COMMANDLINEFLAGS_H_ +#define BENCHMARK_COMMANDLINEFLAGS_H_ + +#include +#include + +// Macro for referencing flags. +#define FLAG(name) FLAGS_##name + +// Macros for declaring flags. +#define DECLARE_bool(name) extern bool FLAG(name) +#define DECLARE_int32(name) extern int32_t FLAG(name) +#define DECLARE_int64(name) extern int64_t FLAG(name) +#define DECLARE_double(name) extern double FLAG(name) +#define DECLARE_string(name) extern std::string FLAG(name) + +// Macros for defining flags. +#define DEFINE_bool(name, default_val, doc) bool FLAG(name) = (default_val) +#define DEFINE_int32(name, default_val, doc) int32_t FLAG(name) = (default_val) +#define DEFINE_int64(name, default_val, doc) int64_t FLAG(name) = (default_val) +#define DEFINE_double(name, default_val, doc) double FLAG(name) = (default_val) +#define DEFINE_string(name, default_val, doc) \ + std::string FLAG(name) = (default_val) + +namespace benchmark { +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromEnv(const char* flag, bool default_val); +int32_t Int32FromEnv(const char* flag, int32_t default_val); +const char* StringFromEnv(const char* flag, const char* default_val); + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true if it passes IsTruthyValue(). +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value); + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, int32_t* value); + +// Parses a string for a Double flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseDoubleFlag(const char* str, const char* flag, double* value); + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, std::string* value); + +// Returns true if the string matches the flag. +bool IsFlag(const char* str, const char* flag); + +// Returns true unless value starts with one of: '0', 'f', 'F', 'n' or 'N', or +// some non-alphanumeric character. As a special case, also returns true if +// value is the empty string. +bool IsTruthyFlagValue(const std::string& value); +} // end namespace benchmark + +#endif // BENCHMARK_COMMANDLINEFLAGS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.cc new file mode 100644 index 000000000..aeed67f0c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.cc @@ -0,0 +1,238 @@ +// Copyright 2016 Ismael Jimenez Martinez. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Source project : https://github.com/ismaelJimenez/cpp.leastsq +// Adapted to be used with google benchmark + +#include "benchmark/benchmark.h" + +#include +#include +#include "check.h" +#include "complexity.h" + +namespace benchmark { + +// Internal function to calculate the different scalability forms +BigOFunc* FittingCurve(BigO complexity) { + static const double kLog2E = 1.44269504088896340736; + switch (complexity) { + case oN: + return [](IterationCount n) -> double { return static_cast(n); }; + case oNSquared: + return [](IterationCount n) -> double { return std::pow(n, 2); }; + case oNCubed: + return [](IterationCount n) -> double { return std::pow(n, 3); }; + case oLogN: + /* Note: can't use log2 because Android's GNU STL lacks it */ + return + [](IterationCount n) { return kLog2E * log(static_cast(n)); }; + case oNLogN: + /* Note: can't use log2 because Android's GNU STL lacks it */ + return [](IterationCount n) { + return kLog2E * n * log(static_cast(n)); + }; + case o1: + default: + return [](IterationCount) { return 1.0; }; + } +} + +// Function to return an string for the calculated complexity +std::string GetBigOString(BigO complexity) { + switch (complexity) { + case oN: + return "N"; + case oNSquared: + return "N^2"; + case oNCubed: + return "N^3"; + case oLogN: + return "lgN"; + case oNLogN: + return "NlgN"; + case o1: + return "(1)"; + default: + return "f(N)"; + } +} + +// Find the coefficient for the high-order term in the running time, by +// minimizing the sum of squares of relative error, for the fitting curve +// given by the lambda expression. +// - n : Vector containing the size of the benchmark tests. +// - time : Vector containing the times for the benchmark tests. +// - fitting_curve : lambda expression (e.g. [](int64_t n) {return n; };). + +// For a deeper explanation on the algorithm logic, please refer to +// https://en.wikipedia.org/wiki/Least_squares#Least_squares,_regression_analysis_and_statistics + +LeastSq MinimalLeastSq(const std::vector& n, + const std::vector& time, + BigOFunc* fitting_curve) { + double sigma_gn = 0.0; + double sigma_gn_squared = 0.0; + double sigma_time = 0.0; + double sigma_time_gn = 0.0; + + // Calculate least square fitting parameter + for (size_t i = 0; i < n.size(); ++i) { + double gn_i = fitting_curve(n[i]); + sigma_gn += gn_i; + sigma_gn_squared += gn_i * gn_i; + sigma_time += time[i]; + sigma_time_gn += time[i] * gn_i; + } + + LeastSq result; + result.complexity = oLambda; + + // Calculate complexity. + result.coef = sigma_time_gn / sigma_gn_squared; + + // Calculate RMS + double rms = 0.0; + for (size_t i = 0; i < n.size(); ++i) { + double fit = result.coef * fitting_curve(n[i]); + rms += pow((time[i] - fit), 2); + } + + // Normalized RMS by the mean of the observed values + double mean = sigma_time / n.size(); + result.rms = sqrt(rms / n.size()) / mean; + + return result; +} + +// Find the coefficient for the high-order term in the running time, by +// minimizing the sum of squares of relative error. +// - n : Vector containing the size of the benchmark tests. +// - time : Vector containing the times for the benchmark tests. +// - complexity : If different than oAuto, the fitting curve will stick to +// this one. If it is oAuto, it will be calculated the best +// fitting curve. +LeastSq MinimalLeastSq(const std::vector& n, + const std::vector& time, const BigO complexity) { + CHECK_EQ(n.size(), time.size()); + CHECK_GE(n.size(), 2); // Do not compute fitting curve is less than two + // benchmark runs are given + CHECK_NE(complexity, oNone); + + LeastSq best_fit; + + if (complexity == oAuto) { + std::vector fit_curves = {oLogN, oN, oNLogN, oNSquared, oNCubed}; + + // Take o1 as default best fitting curve + best_fit = MinimalLeastSq(n, time, FittingCurve(o1)); + best_fit.complexity = o1; + + // Compute all possible fitting curves and stick to the best one + for (const auto& fit : fit_curves) { + LeastSq current_fit = MinimalLeastSq(n, time, FittingCurve(fit)); + if (current_fit.rms < best_fit.rms) { + best_fit = current_fit; + best_fit.complexity = fit; + } + } + } else { + best_fit = MinimalLeastSq(n, time, FittingCurve(complexity)); + best_fit.complexity = complexity; + } + + return best_fit; +} + +std::vector ComputeBigO( + const std::vector& reports) { + typedef BenchmarkReporter::Run Run; + std::vector results; + + if (reports.size() < 2) return results; + + // Accumulators. + std::vector n; + std::vector real_time; + std::vector cpu_time; + + // Populate the accumulators. + for (const Run& run : reports) { + CHECK_GT(run.complexity_n, 0) << "Did you forget to call SetComplexityN?"; + n.push_back(run.complexity_n); + real_time.push_back(run.real_accumulated_time / run.iterations); + cpu_time.push_back(run.cpu_accumulated_time / run.iterations); + } + + LeastSq result_cpu; + LeastSq result_real; + + if (reports[0].complexity == oLambda) { + result_cpu = MinimalLeastSq(n, cpu_time, reports[0].complexity_lambda); + result_real = MinimalLeastSq(n, real_time, reports[0].complexity_lambda); + } else { + result_cpu = MinimalLeastSq(n, cpu_time, reports[0].complexity); + result_real = MinimalLeastSq(n, real_time, result_cpu.complexity); + } + + // Drop the 'args' when reporting complexity. + auto run_name = reports[0].run_name; + run_name.args.clear(); + + // Get the data from the accumulator to BenchmarkReporter::Run's. + Run big_o; + big_o.run_name = run_name; + big_o.run_type = BenchmarkReporter::Run::RT_Aggregate; + big_o.repetitions = reports[0].repetitions; + big_o.repetition_index = Run::no_repetition_index; + big_o.threads = reports[0].threads; + big_o.aggregate_name = "BigO"; + big_o.report_label = reports[0].report_label; + big_o.iterations = 0; + big_o.real_accumulated_time = result_real.coef; + big_o.cpu_accumulated_time = result_cpu.coef; + big_o.report_big_o = true; + big_o.complexity = result_cpu.complexity; + + // All the time results are reported after being multiplied by the + // time unit multiplier. But since RMS is a relative quantity it + // should not be multiplied at all. So, here, we _divide_ it by the + // multiplier so that when it is multiplied later the result is the + // correct one. + double multiplier = GetTimeUnitMultiplier(reports[0].time_unit); + + // Only add label to mean/stddev if it is same for all runs + Run rms; + rms.run_name = run_name; + rms.run_type = BenchmarkReporter::Run::RT_Aggregate; + rms.aggregate_name = "RMS"; + rms.report_label = big_o.report_label; + rms.iterations = 0; + rms.repetition_index = Run::no_repetition_index; + rms.repetitions = reports[0].repetitions; + rms.threads = reports[0].threads; + rms.real_accumulated_time = result_real.rms / multiplier; + rms.cpu_accumulated_time = result_cpu.rms / multiplier; + rms.report_rms = true; + rms.complexity = result_cpu.complexity; + // don't forget to keep the time unit, or we won't be able to + // recover the correct value. + rms.time_unit = reports[0].time_unit; + + results.push_back(big_o); + results.push_back(rms); + return results; +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.h new file mode 100644 index 000000000..df29b48d2 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/complexity.h @@ -0,0 +1,55 @@ +// Copyright 2016 Ismael Jimenez Martinez. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Source project : https://github.com/ismaelJimenez/cpp.leastsq +// Adapted to be used with google benchmark + +#ifndef COMPLEXITY_H_ +#define COMPLEXITY_H_ + +#include +#include + +#include "benchmark/benchmark.h" + +namespace benchmark { + +// Return a vector containing the bigO and RMS information for the specified +// list of reports. If 'reports.size() < 2' an empty vector is returned. +std::vector ComputeBigO( + const std::vector& reports); + +// This data structure will contain the result returned by MinimalLeastSq +// - coef : Estimated coeficient for the high-order term as +// interpolated from data. +// - rms : Normalized Root Mean Squared Error. +// - complexity : Scalability form (e.g. oN, oNLogN). In case a scalability +// form has been provided to MinimalLeastSq this will return +// the same value. In case BigO::oAuto has been selected, this +// parameter will return the best fitting curve detected. + +struct LeastSq { + LeastSq() : coef(0.0), rms(0.0), complexity(oNone) {} + + double coef; + double rms; + BigO complexity; +}; + +// Function to return an string for the calculated complexity +std::string GetBigOString(BigO complexity); + +} // end namespace benchmark + +#endif // COMPLEXITY_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/console_reporter.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/console_reporter.cc new file mode 100644 index 000000000..cc8ae276f --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/console_reporter.cc @@ -0,0 +1,179 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" +#include "complexity.h" +#include "counter.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "colorprint.h" +#include "commandlineflags.h" +#include "internal_macros.h" +#include "string_util.h" +#include "timers.h" + +namespace benchmark { + +bool ConsoleReporter::ReportContext(const Context& context) { + name_field_width_ = context.name_field_width; + printed_header_ = false; + prev_counters_.clear(); + + PrintBasicContext(&GetErrorStream(), context); + +#ifdef BENCHMARK_OS_WINDOWS + if ((output_options_ & OO_Color) && &std::cout != &GetOutputStream()) { + GetErrorStream() + << "Color printing is only supported for stdout on windows." + " Disabling color printing\n"; + output_options_ = static_cast< OutputOptions >(output_options_ & ~OO_Color); + } +#endif + + return true; +} + +void ConsoleReporter::PrintHeader(const Run& run) { + std::string str = FormatString("%-*s %13s %15s %12s", static_cast(name_field_width_), + "Benchmark", "Time", "CPU", "Iterations"); + if(!run.counters.empty()) { + if(output_options_ & OO_Tabular) { + for(auto const& c : run.counters) { + str += FormatString(" %10s", c.first.c_str()); + } + } else { + str += " UserCounters..."; + } + } + std::string line = std::string(str.length(), '-'); + GetOutputStream() << line << "\n" << str << "\n" << line << "\n"; +} + +void ConsoleReporter::ReportRuns(const std::vector& reports) { + for (const auto& run : reports) { + // print the header: + // --- if none was printed yet + bool print_header = !printed_header_; + // --- or if the format is tabular and this run + // has different fields from the prev header + print_header |= (output_options_ & OO_Tabular) && + (!internal::SameNames(run.counters, prev_counters_)); + if (print_header) { + printed_header_ = true; + prev_counters_ = run.counters; + PrintHeader(run); + } + // As an alternative to printing the headers like this, we could sort + // the benchmarks by header and then print. But this would require + // waiting for the full results before printing, or printing twice. + PrintRunData(run); + } +} + +static void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt, + ...) { + va_list args; + va_start(args, fmt); + out << FormatString(fmt, args); + va_end(args); +} + + +static std::string FormatTime(double time) { + // Align decimal places... + if (time < 1.0) { + return FormatString("%10.3f", time); + } + if (time < 10.0) { + return FormatString("%10.2f", time); + } + if (time < 100.0) { + return FormatString("%10.1f", time); + } + return FormatString("%10.0f", time); +} + +void ConsoleReporter::PrintRunData(const Run& result) { + typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...); + auto& Out = GetOutputStream(); + PrinterFn* printer = (output_options_ & OO_Color) ? + (PrinterFn*)ColorPrintf : IgnoreColorPrint; + auto name_color = + (result.report_big_o || result.report_rms) ? COLOR_BLUE : COLOR_GREEN; + printer(Out, name_color, "%-*s ", name_field_width_, + result.benchmark_name().c_str()); + + if (result.error_occurred) { + printer(Out, COLOR_RED, "ERROR OCCURRED: \'%s\'", + result.error_message.c_str()); + printer(Out, COLOR_DEFAULT, "\n"); + return; + } + + const double real_time = result.GetAdjustedRealTime(); + const double cpu_time = result.GetAdjustedCPUTime(); + const std::string real_time_str = FormatTime(real_time); + const std::string cpu_time_str = FormatTime(cpu_time); + + + if (result.report_big_o) { + std::string big_o = GetBigOString(result.complexity); + printer(Out, COLOR_YELLOW, "%10.2f %-4s %10.2f %-4s ", real_time, big_o.c_str(), + cpu_time, big_o.c_str()); + } else if (result.report_rms) { + printer(Out, COLOR_YELLOW, "%10.0f %-4s %10.0f %-4s ", real_time * 100, "%", + cpu_time * 100, "%"); + } else { + const char* timeLabel = GetTimeUnitString(result.time_unit); + printer(Out, COLOR_YELLOW, "%s %-4s %s %-4s ", real_time_str.c_str(), timeLabel, + cpu_time_str.c_str(), timeLabel); + } + + if (!result.report_big_o && !result.report_rms) { + printer(Out, COLOR_CYAN, "%10lld", result.iterations); + } + + for (auto& c : result.counters) { + const std::size_t cNameLen = std::max(std::string::size_type(10), + c.first.length()); + auto const& s = HumanReadableNumber(c.second.value, c.second.oneK); + if (output_options_ & OO_Tabular) { + if (c.second.flags & Counter::kIsRate) { + printer(Out, COLOR_DEFAULT, " %*s/s", cNameLen - 2, s.c_str()); + } else { + printer(Out, COLOR_DEFAULT, " %*s", cNameLen, s.c_str()); + } + } else { + const char* unit = (c.second.flags & Counter::kIsRate) ? "/s" : ""; + printer(Out, COLOR_DEFAULT, " %s=%s%s", c.first.c_str(), s.c_str(), + unit); + } + } + + if (!result.report_label.empty()) { + printer(Out, COLOR_DEFAULT, " %s", result.report_label.c_str()); + } + + printer(Out, COLOR_DEFAULT, "\n"); +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.cc new file mode 100644 index 000000000..c248ea110 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.cc @@ -0,0 +1,76 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "counter.h" + +namespace benchmark { +namespace internal { + +double Finish(Counter const& c, IterationCount iterations, double cpu_time, + double num_threads) { + double v = c.value; + if (c.flags & Counter::kIsRate) { + v /= cpu_time; + } + if (c.flags & Counter::kAvgThreads) { + v /= num_threads; + } + if (c.flags & Counter::kIsIterationInvariant) { + v *= iterations; + } + if (c.flags & Counter::kAvgIterations) { + v /= iterations; + } + return v; +} + +void Finish(UserCounters* l, IterationCount iterations, double cpu_time, + double num_threads) { + for (auto& c : *l) { + c.second.value = Finish(c.second, iterations, cpu_time, num_threads); + } +} + +void Increment(UserCounters* l, UserCounters const& r) { + // add counters present in both or just in *l + for (auto& c : *l) { + auto it = r.find(c.first); + if (it != r.end()) { + c.second.value = c.second + it->second; + } + } + // add counters present in r, but not in *l + for (auto const& tc : r) { + auto it = l->find(tc.first); + if (it == l->end()) { + (*l)[tc.first] = tc.second; + } + } +} + +bool SameNames(UserCounters const& l, UserCounters const& r) { + if (&l == &r) return true; + if (l.size() != r.size()) { + return false; + } + for (auto const& c : l) { + if (r.find(c.first) == r.end()) { + return false; + } + } + return true; +} + +} // end namespace internal +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.h new file mode 100644 index 000000000..1ad46d494 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/counter.h @@ -0,0 +1,27 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" + +namespace benchmark { + +// these counter-related functions are hidden to reduce API surface. +namespace internal { +void Finish(UserCounters* l, IterationCount iterations, double time, + double num_threads); +void Increment(UserCounters* l, UserCounters const& r); +bool SameNames(UserCounters const& l, UserCounters const& r); +} // end namespace internal + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/csv_reporter.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/csv_reporter.cc new file mode 100644 index 000000000..af2c18fc8 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/csv_reporter.cc @@ -0,0 +1,154 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" +#include "complexity.h" + +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "string_util.h" +#include "timers.h" + +// File format reference: http://edoceo.com/utilitas/csv-file-format. + +namespace benchmark { + +namespace { +std::vector elements = { + "name", "iterations", "real_time", "cpu_time", + "time_unit", "bytes_per_second", "items_per_second", "label", + "error_occurred", "error_message"}; +} // namespace + +std::string CsvEscape(const std::string & s) { + std::string tmp; + tmp.reserve(s.size() + 2); + for (char c : s) { + switch (c) { + case '"' : tmp += "\"\""; break; + default : tmp += c; break; + } + } + return '"' + tmp + '"'; +} + +bool CSVReporter::ReportContext(const Context& context) { + PrintBasicContext(&GetErrorStream(), context); + return true; +} + +void CSVReporter::ReportRuns(const std::vector& reports) { + std::ostream& Out = GetOutputStream(); + + if (!printed_header_) { + // save the names of all the user counters + for (const auto& run : reports) { + for (const auto& cnt : run.counters) { + if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second") + continue; + user_counter_names_.insert(cnt.first); + } + } + + // print the header + for (auto B = elements.begin(); B != elements.end();) { + Out << *B++; + if (B != elements.end()) Out << ","; + } + for (auto B = user_counter_names_.begin(); + B != user_counter_names_.end();) { + Out << ",\"" << *B++ << "\""; + } + Out << "\n"; + + printed_header_ = true; + } else { + // check that all the current counters are saved in the name set + for (const auto& run : reports) { + for (const auto& cnt : run.counters) { + if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second") + continue; + CHECK(user_counter_names_.find(cnt.first) != user_counter_names_.end()) + << "All counters must be present in each run. " + << "Counter named \"" << cnt.first + << "\" was not in a run after being added to the header"; + } + } + } + + // print results for each run + for (const auto& run : reports) { + PrintRunData(run); + } +} + +void CSVReporter::PrintRunData(const Run& run) { + std::ostream& Out = GetOutputStream(); + Out << CsvEscape(run.benchmark_name()) << ","; + if (run.error_occurred) { + Out << std::string(elements.size() - 3, ','); + Out << "true,"; + Out << CsvEscape(run.error_message) << "\n"; + return; + } + + // Do not print iteration on bigO and RMS report + if (!run.report_big_o && !run.report_rms) { + Out << run.iterations; + } + Out << ","; + + Out << run.GetAdjustedRealTime() << ","; + Out << run.GetAdjustedCPUTime() << ","; + + // Do not print timeLabel on bigO and RMS report + if (run.report_big_o) { + Out << GetBigOString(run.complexity); + } else if (!run.report_rms) { + Out << GetTimeUnitString(run.time_unit); + } + Out << ","; + + if (run.counters.find("bytes_per_second") != run.counters.end()) { + Out << run.counters.at("bytes_per_second"); + } + Out << ","; + if (run.counters.find("items_per_second") != run.counters.end()) { + Out << run.counters.at("items_per_second"); + } + Out << ","; + if (!run.report_label.empty()) { + Out << CsvEscape(run.report_label); + } + Out << ",,"; // for error_occurred and error_message + + // Print user counters + for (const auto& ucn : user_counter_names_) { + auto it = run.counters.find(ucn); + if (it == run.counters.end()) { + Out << ","; + } else { + Out << "," << it->second; + } + } + Out << '\n'; +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/cycleclock.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/cycleclock.h new file mode 100644 index 000000000..f5e37b011 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/cycleclock.h @@ -0,0 +1,177 @@ +// ---------------------------------------------------------------------- +// CycleClock +// A CycleClock tells you the current time in Cycles. The "time" +// is actually time since power-on. This is like time() but doesn't +// involve a system call and is much more precise. +// +// NOTE: Not all cpu/platform/kernel combinations guarantee that this +// clock increments at a constant rate or is synchronized across all logical +// cpus in a system. +// +// If you need the above guarantees, please consider using a different +// API. There are efforts to provide an interface which provides a millisecond +// granularity and implemented as a memory read. A memory read is generally +// cheaper than the CycleClock for many architectures. +// +// Also, in some out of order CPU implementations, the CycleClock is not +// serializing. So if you're trying to count at cycles granularity, your +// data might be inaccurate due to out of order instruction execution. +// ---------------------------------------------------------------------- + +#ifndef BENCHMARK_CYCLECLOCK_H_ +#define BENCHMARK_CYCLECLOCK_H_ + +#include + +#include "benchmark/benchmark.h" +#include "internal_macros.h" + +#if defined(BENCHMARK_OS_MACOSX) +#include +#endif +// For MSVC, we want to use '_asm rdtsc' when possible (since it works +// with even ancient MSVC compilers), and when not possible the +// __rdtsc intrinsic, declared in . Unfortunately, in some +// environments, and have conflicting +// declarations of some other intrinsics, breaking compilation. +// Therefore, we simply declare __rdtsc ourselves. See also +// http://connect.microsoft.com/VisualStudio/feedback/details/262047 +#if defined(COMPILER_MSVC) && !defined(_M_IX86) +extern "C" uint64_t __rdtsc(); +#pragma intrinsic(__rdtsc) +#endif + +#if !defined(BENCHMARK_OS_WINDOWS) || defined(BENCHMARK_OS_MINGW) +#include +#include +#endif + +#ifdef BENCHMARK_OS_EMSCRIPTEN +#include +#endif + +namespace benchmark { +// NOTE: only i386 and x86_64 have been well tested. +// PPC, sparc, alpha, and ia64 are based on +// http://peter.kuscsik.com/wordpress/?p=14 +// with modifications by m3b. See also +// https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h +namespace cycleclock { +// This should return the number of cycles since power-on. Thread-safe. +inline BENCHMARK_ALWAYS_INLINE int64_t Now() { +#if defined(BENCHMARK_OS_MACOSX) + // this goes at the top because we need ALL Macs, regardless of + // architecture, to return the number of "mach time units" that + // have passed since startup. See sysinfo.cc where + // InitializeSystemInfo() sets the supposed cpu clock frequency of + // macs to the number of mach time units per second, not actual + // CPU clock frequency (which can change in the face of CPU + // frequency scaling). Also note that when the Mac sleeps, this + // counter pauses; it does not continue counting, nor does it + // reset to zero. + return mach_absolute_time(); +#elif defined(BENCHMARK_OS_EMSCRIPTEN) + // this goes above x86-specific code because old versions of Emscripten + // define __x86_64__, although they have nothing to do with it. + return static_cast(emscripten_get_now() * 1e+6); +#elif defined(__i386__) + int64_t ret; + __asm__ volatile("rdtsc" : "=A"(ret)); + return ret; +#elif defined(__x86_64__) || defined(__amd64__) + uint64_t low, high; + __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); + return (high << 32) | low; +#elif defined(__powerpc__) || defined(__ppc__) + // This returns a time-base, which is not always precisely a cycle-count. + int64_t tbl, tbu0, tbu1; + asm("mftbu %0" : "=r"(tbu0)); + asm("mftb %0" : "=r"(tbl)); + asm("mftbu %0" : "=r"(tbu1)); + tbl &= -static_cast(tbu0 == tbu1); + // high 32 bits in tbu1; low 32 bits in tbl (tbu0 is garbage) + return (tbu1 << 32) | tbl; +#elif defined(__sparc__) + int64_t tick; + asm(".byte 0x83, 0x41, 0x00, 0x00"); + asm("mov %%g1, %0" : "=r"(tick)); + return tick; +#elif defined(__ia64__) + int64_t itc; + asm("mov %0 = ar.itc" : "=r"(itc)); + return itc; +#elif defined(COMPILER_MSVC) && defined(_M_IX86) + // Older MSVC compilers (like 7.x) don't seem to support the + // __rdtsc intrinsic properly, so I prefer to use _asm instead + // when I know it will work. Otherwise, I'll use __rdtsc and hope + // the code is being compiled with a non-ancient compiler. + _asm rdtsc +#elif defined(COMPILER_MSVC) + return __rdtsc(); +#elif defined(BENCHMARK_OS_NACL) + // Native Client validator on x86/x86-64 allows RDTSC instructions, + // and this case is handled above. Native Client validator on ARM + // rejects MRC instructions (used in the ARM-specific sequence below), + // so we handle it here. Portable Native Client compiles to + // architecture-agnostic bytecode, which doesn't provide any + // cycle counter access mnemonics. + + // Native Client does not provide any API to access cycle counter. + // Use clock_gettime(CLOCK_MONOTONIC, ...) instead of gettimeofday + // because is provides nanosecond resolution (which is noticable at + // least for PNaCl modules running on x86 Mac & Linux). + // Initialize to always return 0 if clock_gettime fails. + struct timespec ts = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &ts); + return static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; +#elif defined(__aarch64__) + // System timer of ARMv8 runs at a different frequency than the CPU's. + // The frequency is fixed, typically in the range 1-50MHz. It can be + // read at CNTFRQ special register. We assume the OS has set up + // the virtual timer properly. + int64_t virtual_timer_value; + asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); + return virtual_timer_value; +#elif defined(__ARM_ARCH) + // V6 is the earliest arch that has a standard cyclecount + // Native Client validator doesn't allow MRC instructions. +#if (__ARM_ARCH >= 6) + uint32_t pmccntr; + uint32_t pmuseren; + uint32_t pmcntenset; + // Read the user mode perf monitor counter access permissions. + asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren)); + if (pmuseren & 1) { // Allows reading perfmon counters for user mode code. + asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset)); + if (pmcntenset & 0x80000000ul) { // Is it counting? + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr)); + // The counter is set up to count every 64th cycle + return static_cast(pmccntr) * 64; // Should optimize to << 6 + } + } +#endif + struct timeval tv; + gettimeofday(&tv, nullptr); + return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; +#elif defined(__mips__) + // mips apparently only allows rdtsc for superusers, so we fall + // back to gettimeofday. It's possible clock_gettime would be better. + struct timeval tv; + gettimeofday(&tv, nullptr); + return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; +#elif defined(__s390__) // Covers both s390 and s390x. + // Return the CPU clock. + uint64_t tsc; + asm("stck %0" : "=Q"(tsc) : : "cc"); + return tsc; +#else +// The soft failover to a generic implementation is automatic only for ARM. +// For other platforms the developer is expected to make an attempt to create +// a fast implementation and use generic version if nothing better is available. +#error You need to define CycleTimer for your OS and CPU +#endif +} +} // end namespace cycleclock +} // end namespace benchmark + +#endif // BENCHMARK_CYCLECLOCK_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/internal_macros.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/internal_macros.h new file mode 100644 index 000000000..6adf00d05 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/internal_macros.h @@ -0,0 +1,94 @@ +#ifndef BENCHMARK_INTERNAL_MACROS_H_ +#define BENCHMARK_INTERNAL_MACROS_H_ + +#include "benchmark/benchmark.h" + +/* Needed to detect STL */ +#include + +// clang-format off + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if defined(__clang__) + #if !defined(COMPILER_CLANG) + #define COMPILER_CLANG + #endif +#elif defined(_MSC_VER) + #if !defined(COMPILER_MSVC) + #define COMPILER_MSVC + #endif +#elif defined(__GNUC__) + #if !defined(COMPILER_GCC) + #define COMPILER_GCC + #endif +#endif + +#if __has_feature(cxx_attributes) + #define BENCHMARK_NORETURN [[noreturn]] +#elif defined(__GNUC__) + #define BENCHMARK_NORETURN __attribute__((noreturn)) +#elif defined(COMPILER_MSVC) + #define BENCHMARK_NORETURN __declspec(noreturn) +#else + #define BENCHMARK_NORETURN +#endif + +#if defined(__CYGWIN__) + #define BENCHMARK_OS_CYGWIN 1 +#elif defined(_WIN32) + #define BENCHMARK_OS_WINDOWS 1 + #if defined(__MINGW32__) + #define BENCHMARK_OS_MINGW 1 + #endif +#elif defined(__APPLE__) + #define BENCHMARK_OS_APPLE 1 + #include "TargetConditionals.h" + #if defined(TARGET_OS_MAC) + #define BENCHMARK_OS_MACOSX 1 + #if defined(TARGET_OS_IPHONE) + #define BENCHMARK_OS_IOS 1 + #endif + #endif +#elif defined(__FreeBSD__) + #define BENCHMARK_OS_FREEBSD 1 +#elif defined(__NetBSD__) + #define BENCHMARK_OS_NETBSD 1 +#elif defined(__OpenBSD__) + #define BENCHMARK_OS_OPENBSD 1 +#elif defined(__linux__) + #define BENCHMARK_OS_LINUX 1 +#elif defined(__native_client__) + #define BENCHMARK_OS_NACL 1 +#elif defined(__EMSCRIPTEN__) + #define BENCHMARK_OS_EMSCRIPTEN 1 +#elif defined(__rtems__) + #define BENCHMARK_OS_RTEMS 1 +#elif defined(__Fuchsia__) +#define BENCHMARK_OS_FUCHSIA 1 +#elif defined (__SVR4) && defined (__sun) +#define BENCHMARK_OS_SOLARIS 1 +#elif defined(__QNX__) +#define BENCHMARK_OS_QNX 1 +#endif + +#if defined(__ANDROID__) && defined(__GLIBCXX__) +#define BENCHMARK_STL_ANDROID_GNUSTL 1 +#endif + +#if !__has_feature(cxx_exceptions) && !defined(__cpp_exceptions) \ + && !defined(__EXCEPTIONS) + #define BENCHMARK_HAS_NO_EXCEPTIONS +#endif + +#if defined(COMPILER_CLANG) || defined(COMPILER_GCC) + #define BENCHMARK_MAYBE_UNUSED __attribute__((unused)) +#else + #define BENCHMARK_MAYBE_UNUSED +#endif + +// clang-format on + +#endif // BENCHMARK_INTERNAL_MACROS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/json_reporter.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/json_reporter.cc new file mode 100644 index 000000000..11db2b99d --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/json_reporter.cc @@ -0,0 +1,253 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" +#include "complexity.h" + +#include +#include +#include +#include // for setprecision +#include +#include +#include +#include +#include + +#include "string_util.h" +#include "timers.h" + +namespace benchmark { + +namespace { + +std::string StrEscape(const std::string & s) { + std::string tmp; + tmp.reserve(s.size()); + for (char c : s) { + switch (c) { + case '\b': tmp += "\\b"; break; + case '\f': tmp += "\\f"; break; + case '\n': tmp += "\\n"; break; + case '\r': tmp += "\\r"; break; + case '\t': tmp += "\\t"; break; + case '\\': tmp += "\\\\"; break; + case '"' : tmp += "\\\""; break; + default : tmp += c; break; + } + } + return tmp; +} + +std::string FormatKV(std::string const& key, std::string const& value) { + return StrFormat("\"%s\": \"%s\"", StrEscape(key).c_str(), StrEscape(value).c_str()); +} + +std::string FormatKV(std::string const& key, const char* value) { + return StrFormat("\"%s\": \"%s\"", StrEscape(key).c_str(), StrEscape(value).c_str()); +} + +std::string FormatKV(std::string const& key, bool value) { + return StrFormat("\"%s\": %s", StrEscape(key).c_str(), value ? "true" : "false"); +} + +std::string FormatKV(std::string const& key, int64_t value) { + std::stringstream ss; + ss << '"' << StrEscape(key) << "\": " << value; + return ss.str(); +} + +std::string FormatKV(std::string const& key, IterationCount value) { + std::stringstream ss; + ss << '"' << StrEscape(key) << "\": " << value; + return ss.str(); +} + +std::string FormatKV(std::string const& key, double value) { + std::stringstream ss; + ss << '"' << StrEscape(key) << "\": "; + + if (std::isnan(value)) + ss << (value < 0 ? "-" : "") << "NaN"; + else if (std::isinf(value)) + ss << (value < 0 ? "-" : "") << "Infinity"; + else { + const auto max_digits10 = + std::numeric_limits::max_digits10; + const auto max_fractional_digits10 = max_digits10 - 1; + ss << std::scientific << std::setprecision(max_fractional_digits10) + << value; + } + return ss.str(); +} + +int64_t RoundDouble(double v) { return static_cast(v + 0.5); } + +} // end namespace + +bool JSONReporter::ReportContext(const Context& context) { + std::ostream& out = GetOutputStream(); + + out << "{\n"; + std::string inner_indent(2, ' '); + + // Open context block and print context information. + out << inner_indent << "\"context\": {\n"; + std::string indent(4, ' '); + + std::string walltime_value = LocalDateTimeString(); + out << indent << FormatKV("date", walltime_value) << ",\n"; + + out << indent << FormatKV("host_name", context.sys_info.name) << ",\n"; + + if (Context::executable_name) { + out << indent << FormatKV("executable", Context::executable_name) << ",\n"; + } + + CPUInfo const& info = context.cpu_info; + out << indent << FormatKV("num_cpus", static_cast(info.num_cpus)) + << ",\n"; + out << indent + << FormatKV("mhz_per_cpu", + RoundDouble(info.cycles_per_second / 1000000.0)) + << ",\n"; + out << indent << FormatKV("cpu_scaling_enabled", info.scaling_enabled) + << ",\n"; + + out << indent << "\"caches\": [\n"; + indent = std::string(6, ' '); + std::string cache_indent(8, ' '); + for (size_t i = 0; i < info.caches.size(); ++i) { + auto& CI = info.caches[i]; + out << indent << "{\n"; + out << cache_indent << FormatKV("type", CI.type) << ",\n"; + out << cache_indent << FormatKV("level", static_cast(CI.level)) + << ",\n"; + out << cache_indent + << FormatKV("size", static_cast(CI.size) * 1000u) << ",\n"; + out << cache_indent + << FormatKV("num_sharing", static_cast(CI.num_sharing)) + << "\n"; + out << indent << "}"; + if (i != info.caches.size() - 1) out << ","; + out << "\n"; + } + indent = std::string(4, ' '); + out << indent << "],\n"; + out << indent << "\"load_avg\": ["; + for (auto it = info.load_avg.begin(); it != info.load_avg.end();) { + out << *it++; + if (it != info.load_avg.end()) out << ","; + } + out << "],\n"; + +#if defined(NDEBUG) + const char build_type[] = "release"; +#else + const char build_type[] = "debug"; +#endif + out << indent << FormatKV("library_build_type", build_type) << "\n"; + // Close context block and open the list of benchmarks. + out << inner_indent << "},\n"; + out << inner_indent << "\"benchmarks\": [\n"; + return true; +} + +void JSONReporter::ReportRuns(std::vector const& reports) { + if (reports.empty()) { + return; + } + std::string indent(4, ' '); + std::ostream& out = GetOutputStream(); + if (!first_report_) { + out << ",\n"; + } + first_report_ = false; + + for (auto it = reports.begin(); it != reports.end(); ++it) { + out << indent << "{\n"; + PrintRunData(*it); + out << indent << '}'; + auto it_cp = it; + if (++it_cp != reports.end()) { + out << ",\n"; + } + } +} + +void JSONReporter::Finalize() { + // Close the list of benchmarks and the top level object. + GetOutputStream() << "\n ]\n}\n"; +} + +void JSONReporter::PrintRunData(Run const& run) { + std::string indent(6, ' '); + std::ostream& out = GetOutputStream(); + out << indent << FormatKV("name", run.benchmark_name()) << ",\n"; + out << indent << FormatKV("run_name", run.run_name.str()) << ",\n"; + out << indent << FormatKV("run_type", [&run]() -> const char* { + switch (run.run_type) { + case BenchmarkReporter::Run::RT_Iteration: + return "iteration"; + case BenchmarkReporter::Run::RT_Aggregate: + return "aggregate"; + } + BENCHMARK_UNREACHABLE(); + }()) << ",\n"; + out << indent << FormatKV("repetitions", run.repetitions) << ",\n"; + if (run.run_type != BenchmarkReporter::Run::RT_Aggregate) { + out << indent << FormatKV("repetition_index", run.repetition_index) + << ",\n"; + } + out << indent << FormatKV("threads", run.threads) << ",\n"; + if (run.run_type == BenchmarkReporter::Run::RT_Aggregate) { + out << indent << FormatKV("aggregate_name", run.aggregate_name) << ",\n"; + } + if (run.error_occurred) { + out << indent << FormatKV("error_occurred", run.error_occurred) << ",\n"; + out << indent << FormatKV("error_message", run.error_message) << ",\n"; + } + if (!run.report_big_o && !run.report_rms) { + out << indent << FormatKV("iterations", run.iterations) << ",\n"; + out << indent << FormatKV("real_time", run.GetAdjustedRealTime()) << ",\n"; + out << indent << FormatKV("cpu_time", run.GetAdjustedCPUTime()); + out << ",\n" + << indent << FormatKV("time_unit", GetTimeUnitString(run.time_unit)); + } else if (run.report_big_o) { + out << indent << FormatKV("cpu_coefficient", run.GetAdjustedCPUTime()) + << ",\n"; + out << indent << FormatKV("real_coefficient", run.GetAdjustedRealTime()) + << ",\n"; + out << indent << FormatKV("big_o", GetBigOString(run.complexity)) << ",\n"; + out << indent << FormatKV("time_unit", GetTimeUnitString(run.time_unit)); + } else if (run.report_rms) { + out << indent << FormatKV("rms", run.GetAdjustedCPUTime()); + } + + for (auto& c : run.counters) { + out << ",\n" << indent << FormatKV(c.first, c.second); + } + + if (run.has_memory_result) { + out << ",\n" << indent << FormatKV("allocs_per_iter", run.allocs_per_iter); + out << ",\n" << indent << FormatKV("max_bytes_used", run.max_bytes_used); + } + + if (!run.report_label.empty()) { + out << ",\n" << indent << FormatKV("label", run.report_label); + } + out << '\n'; +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/log.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/log.h new file mode 100644 index 000000000..47d0c35c0 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/log.h @@ -0,0 +1,74 @@ +#ifndef BENCHMARK_LOG_H_ +#define BENCHMARK_LOG_H_ + +#include +#include + +#include "benchmark/benchmark.h" + +namespace benchmark { +namespace internal { + +typedef std::basic_ostream&(EndLType)(std::basic_ostream&); + +class LogType { + friend LogType& GetNullLogInstance(); + friend LogType& GetErrorLogInstance(); + + // FIXME: Add locking to output. + template + friend LogType& operator<<(LogType&, Tp const&); + friend LogType& operator<<(LogType&, EndLType*); + + private: + LogType(std::ostream* out) : out_(out) {} + std::ostream* out_; + BENCHMARK_DISALLOW_COPY_AND_ASSIGN(LogType); +}; + +template +LogType& operator<<(LogType& log, Tp const& value) { + if (log.out_) { + *log.out_ << value; + } + return log; +} + +inline LogType& operator<<(LogType& log, EndLType* m) { + if (log.out_) { + *log.out_ << m; + } + return log; +} + +inline int& LogLevel() { + static int log_level = 0; + return log_level; +} + +inline LogType& GetNullLogInstance() { + static LogType log(nullptr); + return log; +} + +inline LogType& GetErrorLogInstance() { + static LogType log(&std::clog); + return log; +} + +inline LogType& GetLogInstanceForLevel(int level) { + if (level <= LogLevel()) { + return GetErrorLogInstance(); + } + return GetNullLogInstance(); +} + +} // end namespace internal +} // end namespace benchmark + +// clang-format off +#define VLOG(x) \ + (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \ + " ") +// clang-format on +#endif diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/mutex.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/mutex.h new file mode 100644 index 000000000..5f461d05a --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/mutex.h @@ -0,0 +1,155 @@ +#ifndef BENCHMARK_MUTEX_H_ +#define BENCHMARK_MUTEX_H_ + +#include +#include + +#include "check.h" + +// Enable thread safety attributes only with clang. +// The attributes can be safely erased when compiling with other compilers. +#if defined(HAVE_THREAD_SAFETY_ATTRIBUTES) +#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) +#else +#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op +#endif + +#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) + +#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) + +#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) + +#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) + +#define ACQUIRED_BEFORE(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) + +#define ACQUIRED_AFTER(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) + +#define REQUIRES(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) + +#define REQUIRES_SHARED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) + +#define ACQUIRE(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) + +#define ACQUIRE_SHARED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) + +#define RELEASE(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) + +#define RELEASE_SHARED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) + +#define TRY_ACQUIRE(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) + +#define TRY_ACQUIRE_SHARED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) + +#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) + +#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) + +#define ASSERT_SHARED_CAPABILITY(x) \ + THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) + +#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) + +#define NO_THREAD_SAFETY_ANALYSIS \ + THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) + +namespace benchmark { + +typedef std::condition_variable Condition; + +// NOTE: Wrappers for std::mutex and std::unique_lock are provided so that +// we can annotate them with thread safety attributes and use the +// -Wthread-safety warning with clang. The standard library types cannot be +// used directly because they do not provided the required annotations. +class CAPABILITY("mutex") Mutex { + public: + Mutex() {} + + void lock() ACQUIRE() { mut_.lock(); } + void unlock() RELEASE() { mut_.unlock(); } + std::mutex& native_handle() { return mut_; } + + private: + std::mutex mut_; +}; + +class SCOPED_CAPABILITY MutexLock { + typedef std::unique_lock MutexLockImp; + + public: + MutexLock(Mutex& m) ACQUIRE(m) : ml_(m.native_handle()) {} + ~MutexLock() RELEASE() {} + MutexLockImp& native_handle() { return ml_; } + + private: + MutexLockImp ml_; +}; + +class Barrier { + public: + Barrier(int num_threads) : running_threads_(num_threads) {} + + // Called by each thread + bool wait() EXCLUDES(lock_) { + bool last_thread = false; + { + MutexLock ml(lock_); + last_thread = createBarrier(ml); + } + if (last_thread) phase_condition_.notify_all(); + return last_thread; + } + + void removeThread() EXCLUDES(lock_) { + MutexLock ml(lock_); + --running_threads_; + if (entered_ != 0) phase_condition_.notify_all(); + } + + private: + Mutex lock_; + Condition phase_condition_; + int running_threads_; + + // State for barrier management + int phase_number_ = 0; + int entered_ = 0; // Number of threads that have entered this barrier + + // Enter the barrier and wait until all other threads have also + // entered the barrier. Returns iff this is the last thread to + // enter the barrier. + bool createBarrier(MutexLock& ml) REQUIRES(lock_) { + CHECK_LT(entered_, running_threads_); + entered_++; + if (entered_ < running_threads_) { + // Wait for all threads to enter + int phase_number_cp = phase_number_; + auto cb = [this, phase_number_cp]() { + return this->phase_number_ > phase_number_cp || + entered_ == running_threads_; // A thread has aborted in error + }; + phase_condition_.wait(ml.native_handle(), cb); + if (phase_number_ > phase_number_cp) return false; + // else (running_threads_ == entered_) and we are the last thread. + } + // Last thread has reached the barrier + phase_number_++; + entered_ = 0; + return true; + } +}; + +} // end namespace benchmark + +#endif // BENCHMARK_MUTEX_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/re.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/re.h new file mode 100644 index 000000000..fbe25037b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/re.h @@ -0,0 +1,158 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef BENCHMARK_RE_H_ +#define BENCHMARK_RE_H_ + +#include "internal_macros.h" + +// clang-format off + +#if !defined(HAVE_STD_REGEX) && \ + !defined(HAVE_GNU_POSIX_REGEX) && \ + !defined(HAVE_POSIX_REGEX) + // No explicit regex selection; detect based on builtin hints. + #if defined(BENCHMARK_OS_LINUX) || defined(BENCHMARK_OS_APPLE) + #define HAVE_POSIX_REGEX 1 + #elif __cplusplus >= 199711L + #define HAVE_STD_REGEX 1 + #endif +#endif + +// Prefer C regex libraries when compiling w/o exceptions so that we can +// correctly report errors. +#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && \ + defined(BENCHMARK_HAVE_STD_REGEX) && \ + (defined(HAVE_GNU_POSIX_REGEX) || defined(HAVE_POSIX_REGEX)) + #undef HAVE_STD_REGEX +#endif + +#if defined(HAVE_STD_REGEX) + #include +#elif defined(HAVE_GNU_POSIX_REGEX) + #include +#elif defined(HAVE_POSIX_REGEX) + #include +#else +#error No regular expression backend was found! +#endif + +// clang-format on + +#include + +#include "check.h" + +namespace benchmark { + +// A wrapper around the POSIX regular expression API that provides automatic +// cleanup +class Regex { + public: + Regex() : init_(false) {} + + ~Regex(); + + // Compile a regular expression matcher from spec. Returns true on success. + // + // On failure (and if error is not nullptr), error is populated with a human + // readable error message if an error occurs. + bool Init(const std::string& spec, std::string* error); + + // Returns whether str matches the compiled regular expression. + bool Match(const std::string& str); + + private: + bool init_; +// Underlying regular expression object +#if defined(HAVE_STD_REGEX) + std::regex re_; +#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX) + regex_t re_; +#else +#error No regular expression backend implementation available +#endif +}; + +#if defined(HAVE_STD_REGEX) + +inline bool Regex::Init(const std::string& spec, std::string* error) { +#ifdef BENCHMARK_HAS_NO_EXCEPTIONS + ((void)error); // suppress unused warning +#else + try { +#endif + re_ = std::regex(spec, std::regex_constants::extended); + init_ = true; +#ifndef BENCHMARK_HAS_NO_EXCEPTIONS +} +catch (const std::regex_error& e) { + if (error) { + *error = e.what(); + } +} +#endif +return init_; +} + +inline Regex::~Regex() {} + +inline bool Regex::Match(const std::string& str) { + if (!init_) { + return false; + } + return std::regex_search(str, re_); +} + +#else +inline bool Regex::Init(const std::string& spec, std::string* error) { + int ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB); + if (ec != 0) { + if (error) { + size_t needed = regerror(ec, &re_, nullptr, 0); + char* errbuf = new char[needed]; + regerror(ec, &re_, errbuf, needed); + + // regerror returns the number of bytes necessary to null terminate + // the string, so we move that when assigning to error. + CHECK_NE(needed, 0); + error->assign(errbuf, needed - 1); + + delete[] errbuf; + } + + return false; + } + + init_ = true; + return true; +} + +inline Regex::~Regex() { + if (init_) { + regfree(&re_); + } +} + +inline bool Regex::Match(const std::string& str) { + if (!init_) { + return false; + } + return regexec(&re_, str.c_str(), 0, nullptr, 0) == 0; +} +#endif + +} // end namespace benchmark + +#endif // BENCHMARK_RE_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/reporter.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/reporter.cc new file mode 100644 index 000000000..4d3e477d4 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/reporter.cc @@ -0,0 +1,105 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" +#include "timers.h" + +#include + +#include +#include +#include + +#include "check.h" +#include "string_util.h" + +namespace benchmark { + +BenchmarkReporter::BenchmarkReporter() + : output_stream_(&std::cout), error_stream_(&std::cerr) {} + +BenchmarkReporter::~BenchmarkReporter() {} + +void BenchmarkReporter::PrintBasicContext(std::ostream *out, + Context const &context) { + CHECK(out) << "cannot be null"; + auto &Out = *out; + + Out << LocalDateTimeString() << "\n"; + + if (context.executable_name) + Out << "Running " << context.executable_name << "\n"; + + const CPUInfo &info = context.cpu_info; + Out << "Run on (" << info.num_cpus << " X " + << (info.cycles_per_second / 1000000.0) << " MHz CPU " + << ((info.num_cpus > 1) ? "s" : "") << ")\n"; + if (info.caches.size() != 0) { + Out << "CPU Caches:\n"; + for (auto &CInfo : info.caches) { + Out << " L" << CInfo.level << " " << CInfo.type << " " + << (CInfo.size / 1000) << "K"; + if (CInfo.num_sharing != 0) + Out << " (x" << (info.num_cpus / CInfo.num_sharing) << ")"; + Out << "\n"; + } + } + if (!info.load_avg.empty()) { + Out << "Load Average: "; + for (auto It = info.load_avg.begin(); It != info.load_avg.end();) { + Out << StrFormat("%.2f", *It++); + if (It != info.load_avg.end()) Out << ", "; + } + Out << "\n"; + } + + if (info.scaling_enabled) { + Out << "***WARNING*** CPU scaling is enabled, the benchmark " + "real time measurements may be noisy and will incur extra " + "overhead.\n"; + } + +#ifndef NDEBUG + Out << "***WARNING*** Library was built as DEBUG. Timings may be " + "affected.\n"; +#endif +} + +// No initializer because it's already initialized to NULL. +const char *BenchmarkReporter::Context::executable_name; + +BenchmarkReporter::Context::Context() + : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {} + +std::string BenchmarkReporter::Run::benchmark_name() const { + std::string name = run_name.str(); + if (run_type == RT_Aggregate) { + name += "_" + aggregate_name; + } + return name; +} + +double BenchmarkReporter::Run::GetAdjustedRealTime() const { + double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit); + if (iterations != 0) new_time /= static_cast(iterations); + return new_time; +} + +double BenchmarkReporter::Run::GetAdjustedCPUTime() const { + double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit); + if (iterations != 0) new_time /= static_cast(iterations); + return new_time; +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.cc new file mode 100644 index 000000000..1512ac90f --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.cc @@ -0,0 +1,51 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "sleep.h" + +#include +#include +#include + +#include "internal_macros.h" + +#ifdef BENCHMARK_OS_WINDOWS +#include +#endif + +namespace benchmark { +#ifdef BENCHMARK_OS_WINDOWS +// Window's Sleep takes milliseconds argument. +void SleepForMilliseconds(int milliseconds) { Sleep(milliseconds); } +void SleepForSeconds(double seconds) { + SleepForMilliseconds(static_cast(kNumMillisPerSecond * seconds)); +} +#else // BENCHMARK_OS_WINDOWS +void SleepForMicroseconds(int microseconds) { + struct timespec sleep_time; + sleep_time.tv_sec = microseconds / kNumMicrosPerSecond; + sleep_time.tv_nsec = (microseconds % kNumMicrosPerSecond) * kNumNanosPerMicro; + while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) + ; // Ignore signals and wait for the full interval to elapse. +} + +void SleepForMilliseconds(int milliseconds) { + SleepForMicroseconds(milliseconds * kNumMicrosPerMilli); +} + +void SleepForSeconds(double seconds) { + SleepForMicroseconds(static_cast(seconds * kNumMicrosPerSecond)); +} +#endif // BENCHMARK_OS_WINDOWS +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.h new file mode 100644 index 000000000..f98551afe --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sleep.h @@ -0,0 +1,15 @@ +#ifndef BENCHMARK_SLEEP_H_ +#define BENCHMARK_SLEEP_H_ + +namespace benchmark { +const int kNumMillisPerSecond = 1000; +const int kNumMicrosPerMilli = 1000; +const int kNumMicrosPerSecond = kNumMillisPerSecond * 1000; +const int kNumNanosPerMicro = 1000; +const int kNumNanosPerSecond = kNumNanosPerMicro * kNumMicrosPerSecond; + +void SleepForMilliseconds(int milliseconds); +void SleepForSeconds(double seconds); +} // end namespace benchmark + +#endif // BENCHMARK_SLEEP_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.cc new file mode 100644 index 000000000..bd5a3d659 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.cc @@ -0,0 +1,193 @@ +// Copyright 2016 Ismael Jimenez Martinez. All rights reserved. +// Copyright 2017 Roman Lebedev. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" + +#include +#include +#include +#include +#include +#include "check.h" +#include "statistics.h" + +namespace benchmark { + +auto StatisticsSum = [](const std::vector& v) { + return std::accumulate(v.begin(), v.end(), 0.0); +}; + +double StatisticsMean(const std::vector& v) { + if (v.empty()) return 0.0; + return StatisticsSum(v) * (1.0 / v.size()); +} + +double StatisticsMedian(const std::vector& v) { + if (v.size() < 3) return StatisticsMean(v); + std::vector copy(v); + + auto center = copy.begin() + v.size() / 2; + std::nth_element(copy.begin(), center, copy.end()); + + // did we have an odd number of samples? + // if yes, then center is the median + // it no, then we are looking for the average between center and the value + // before + if (v.size() % 2 == 1) return *center; + auto center2 = copy.begin() + v.size() / 2 - 1; + std::nth_element(copy.begin(), center2, copy.end()); + return (*center + *center2) / 2.0; +} + +// Return the sum of the squares of this sample set +auto SumSquares = [](const std::vector& v) { + return std::inner_product(v.begin(), v.end(), v.begin(), 0.0); +}; + +auto Sqr = [](const double dat) { return dat * dat; }; +auto Sqrt = [](const double dat) { + // Avoid NaN due to imprecision in the calculations + if (dat < 0.0) return 0.0; + return std::sqrt(dat); +}; + +double StatisticsStdDev(const std::vector& v) { + const auto mean = StatisticsMean(v); + if (v.empty()) return mean; + + // Sample standard deviation is undefined for n = 1 + if (v.size() == 1) return 0.0; + + const double avg_squares = SumSquares(v) * (1.0 / v.size()); + return Sqrt(v.size() / (v.size() - 1.0) * (avg_squares - Sqr(mean))); +} + +std::vector ComputeStats( + const std::vector& reports) { + typedef BenchmarkReporter::Run Run; + std::vector results; + + auto error_count = + std::count_if(reports.begin(), reports.end(), + [](Run const& run) { return run.error_occurred; }); + + if (reports.size() - error_count < 2) { + // We don't report aggregated data if there was a single run. + return results; + } + + // Accumulators. + std::vector real_accumulated_time_stat; + std::vector cpu_accumulated_time_stat; + + real_accumulated_time_stat.reserve(reports.size()); + cpu_accumulated_time_stat.reserve(reports.size()); + + // All repetitions should be run with the same number of iterations so we + // can take this information from the first benchmark. + const IterationCount run_iterations = reports.front().iterations; + // create stats for user counters + struct CounterStat { + Counter c; + std::vector s; + }; + std::map counter_stats; + for (Run const& r : reports) { + for (auto const& cnt : r.counters) { + auto it = counter_stats.find(cnt.first); + if (it == counter_stats.end()) { + counter_stats.insert({cnt.first, {cnt.second, std::vector{}}}); + it = counter_stats.find(cnt.first); + it->second.s.reserve(reports.size()); + } else { + CHECK_EQ(counter_stats[cnt.first].c.flags, cnt.second.flags); + } + } + } + + // Populate the accumulators. + for (Run const& run : reports) { + CHECK_EQ(reports[0].benchmark_name(), run.benchmark_name()); + CHECK_EQ(run_iterations, run.iterations); + if (run.error_occurred) continue; + real_accumulated_time_stat.emplace_back(run.real_accumulated_time); + cpu_accumulated_time_stat.emplace_back(run.cpu_accumulated_time); + // user counters + for (auto const& cnt : run.counters) { + auto it = counter_stats.find(cnt.first); + CHECK_NE(it, counter_stats.end()); + it->second.s.emplace_back(cnt.second); + } + } + + // Only add label if it is same for all runs + std::string report_label = reports[0].report_label; + for (std::size_t i = 1; i < reports.size(); i++) { + if (reports[i].report_label != report_label) { + report_label = ""; + break; + } + } + + const double iteration_rescale_factor = + double(reports.size()) / double(run_iterations); + + for (const auto& Stat : *reports[0].statistics) { + // Get the data from the accumulator to BenchmarkReporter::Run's. + Run data; + data.run_name = reports[0].run_name; + data.run_type = BenchmarkReporter::Run::RT_Aggregate; + data.threads = reports[0].threads; + data.repetitions = reports[0].repetitions; + data.repetition_index = Run::no_repetition_index; + data.aggregate_name = Stat.name_; + data.report_label = report_label; + + // It is incorrect to say that an aggregate is computed over + // run's iterations, because those iterations already got averaged. + // Similarly, if there are N repetitions with 1 iterations each, + // an aggregate will be computed over N measurements, not 1. + // Thus it is best to simply use the count of separate reports. + data.iterations = reports.size(); + + data.real_accumulated_time = Stat.compute_(real_accumulated_time_stat); + data.cpu_accumulated_time = Stat.compute_(cpu_accumulated_time_stat); + + // We will divide these times by data.iterations when reporting, but the + // data.iterations is not nessesairly the scale of these measurements, + // because in each repetition, these timers are sum over all the iterations. + // And if we want to say that the stats are over N repetitions and not + // M iterations, we need to multiply these by (N/M). + data.real_accumulated_time *= iteration_rescale_factor; + data.cpu_accumulated_time *= iteration_rescale_factor; + + data.time_unit = reports[0].time_unit; + + // user counters + for (auto const& kv : counter_stats) { + // Do *NOT* rescale the custom counters. They are already properly scaled. + const auto uc_stat = Stat.compute_(kv.second.s); + auto c = Counter(uc_stat, counter_stats[kv.first].c.flags, + counter_stats[kv.first].c.oneK); + data.counters[kv.first] = c; + } + + results.push_back(data); + } + + return results; +} + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.h new file mode 100644 index 000000000..7eccc8553 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/statistics.h @@ -0,0 +1,37 @@ +// Copyright 2016 Ismael Jimenez Martinez. All rights reserved. +// Copyright 2017 Roman Lebedev. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STATISTICS_H_ +#define STATISTICS_H_ + +#include + +#include "benchmark/benchmark.h" + +namespace benchmark { + +// Return a vector containing the mean, median and standard devation information +// (and any user-specified info) for the specified list of reports. If 'reports' +// contains less than two non-errored runs an empty vector is returned +std::vector ComputeStats( + const std::vector& reports); + +double StatisticsMean(const std::vector& v); +double StatisticsMedian(const std::vector& v); +double StatisticsStdDev(const std::vector& v); + +} // end namespace benchmark + +#endif // STATISTICS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.cc new file mode 100644 index 000000000..39b01a171 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.cc @@ -0,0 +1,252 @@ +#include "string_util.h" + +#include +#include +#include +#include +#include +#include + +#include "arraysize.h" + +namespace benchmark { +namespace { + +// kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta. +const char kBigSIUnits[] = "kMGTPEZY"; +// Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi. +const char kBigIECUnits[] = "KMGTPEZY"; +// milli, micro, nano, pico, femto, atto, zepto, yocto. +const char kSmallSIUnits[] = "munpfazy"; + +// We require that all three arrays have the same size. +static_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits), + "SI and IEC unit arrays must be the same size"); +static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits), + "Small SI and Big SI unit arrays must be the same size"); + +static const int64_t kUnitsSize = arraysize(kBigSIUnits); + +void ToExponentAndMantissa(double val, double thresh, int precision, + double one_k, std::string* mantissa, + int64_t* exponent) { + std::stringstream mantissa_stream; + + if (val < 0) { + mantissa_stream << "-"; + val = -val; + } + + // Adjust threshold so that it never excludes things which can't be rendered + // in 'precision' digits. + const double adjusted_threshold = + std::max(thresh, 1.0 / std::pow(10.0, precision)); + const double big_threshold = adjusted_threshold * one_k; + const double small_threshold = adjusted_threshold; + // Values in ]simple_threshold,small_threshold[ will be printed as-is + const double simple_threshold = 0.01; + + if (val > big_threshold) { + // Positive powers + double scaled = val; + for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) { + scaled /= one_k; + if (scaled <= big_threshold) { + mantissa_stream << scaled; + *exponent = i + 1; + *mantissa = mantissa_stream.str(); + return; + } + } + mantissa_stream << val; + *exponent = 0; + } else if (val < small_threshold) { + // Negative powers + if (val < simple_threshold) { + double scaled = val; + for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) { + scaled *= one_k; + if (scaled >= small_threshold) { + mantissa_stream << scaled; + *exponent = -static_cast(i + 1); + *mantissa = mantissa_stream.str(); + return; + } + } + } + mantissa_stream << val; + *exponent = 0; + } else { + mantissa_stream << val; + *exponent = 0; + } + *mantissa = mantissa_stream.str(); +} + +std::string ExponentToPrefix(int64_t exponent, bool iec) { + if (exponent == 0) return ""; + + const int64_t index = (exponent > 0 ? exponent - 1 : -exponent - 1); + if (index >= kUnitsSize) return ""; + + const char* array = + (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits); + if (iec) + return array[index] + std::string("i"); + else + return std::string(1, array[index]); +} + +std::string ToBinaryStringFullySpecified(double value, double threshold, + int precision, double one_k = 1024.0) { + std::string mantissa; + int64_t exponent; + ToExponentAndMantissa(value, threshold, precision, one_k, &mantissa, + &exponent); + return mantissa + ExponentToPrefix(exponent, false); +} + +} // end namespace + +void AppendHumanReadable(int n, std::string* str) { + std::stringstream ss; + // Round down to the nearest SI prefix. + ss << ToBinaryStringFullySpecified(n, 1.0, 0); + *str += ss.str(); +} + +std::string HumanReadableNumber(double n, double one_k) { + // 1.1 means that figures up to 1.1k should be shown with the next unit down; + // this softens edge effects. + // 1 means that we should show one decimal place of precision. + return ToBinaryStringFullySpecified(n, 1.1, 1, one_k); +} + +std::string StrFormatImp(const char* msg, va_list args) { + // we might need a second shot at this, so pre-emptivly make a copy + va_list args_cp; + va_copy(args_cp, args); + + // TODO(ericwf): use std::array for first attempt to avoid one memory + // allocation guess what the size might be + std::array local_buff; + std::size_t size = local_buff.size(); + // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation + // in the android-ndk + auto ret = vsnprintf(local_buff.data(), size, msg, args_cp); + + va_end(args_cp); + + // handle empty expansion + if (ret == 0) return std::string{}; + if (static_cast(ret) < size) + return std::string(local_buff.data()); + + // we did not provide a long enough buffer on our first attempt. + // add 1 to size to account for null-byte in size cast to prevent overflow + size = static_cast(ret) + 1; + auto buff_ptr = std::unique_ptr(new char[size]); + // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation + // in the android-ndk + ret = vsnprintf(buff_ptr.get(), size, msg, args); + return std::string(buff_ptr.get()); +} + +std::string StrFormat(const char* format, ...) { + va_list args; + va_start(args, format); + std::string tmp = StrFormatImp(format, args); + va_end(args); + return tmp; +} + +#ifdef BENCHMARK_STL_ANDROID_GNUSTL +/* + * GNU STL in Android NDK lacks support for some C++11 functions, including + * stoul, stoi, stod. We reimplement them here using C functions strtoul, + * strtol, strtod. Note that reimplemented functions are in benchmark:: + * namespace, not std:: namespace. + */ +unsigned long stoul(const std::string& str, size_t* pos, int base) { + /* Record previous errno */ + const int oldErrno = errno; + errno = 0; + + const char* strStart = str.c_str(); + char* strEnd = const_cast(strStart); + const unsigned long result = strtoul(strStart, &strEnd, base); + + const int strtoulErrno = errno; + /* Restore previous errno */ + errno = oldErrno; + + /* Check for errors and return */ + if (strtoulErrno == ERANGE) { + throw std::out_of_range( + "stoul failed: " + str + " is outside of range of unsigned long"); + } else if (strEnd == strStart || strtoulErrno != 0) { + throw std::invalid_argument( + "stoul failed: " + str + " is not an integer"); + } + if (pos != nullptr) { + *pos = static_cast(strEnd - strStart); + } + return result; +} + +int stoi(const std::string& str, size_t* pos, int base) { + /* Record previous errno */ + const int oldErrno = errno; + errno = 0; + + const char* strStart = str.c_str(); + char* strEnd = const_cast(strStart); + const long result = strtol(strStart, &strEnd, base); + + const int strtolErrno = errno; + /* Restore previous errno */ + errno = oldErrno; + + /* Check for errors and return */ + if (strtolErrno == ERANGE || long(int(result)) != result) { + throw std::out_of_range( + "stoul failed: " + str + " is outside of range of int"); + } else if (strEnd == strStart || strtolErrno != 0) { + throw std::invalid_argument( + "stoul failed: " + str + " is not an integer"); + } + if (pos != nullptr) { + *pos = static_cast(strEnd - strStart); + } + return int(result); +} + +double stod(const std::string& str, size_t* pos) { + /* Record previous errno */ + const int oldErrno = errno; + errno = 0; + + const char* strStart = str.c_str(); + char* strEnd = const_cast(strStart); + const double result = strtod(strStart, &strEnd); + + /* Restore previous errno */ + const int strtodErrno = errno; + errno = oldErrno; + + /* Check for errors and return */ + if (strtodErrno == ERANGE) { + throw std::out_of_range( + "stoul failed: " + str + " is outside of range of int"); + } else if (strEnd == strStart || strtodErrno != 0) { + throw std::invalid_argument( + "stoul failed: " + str + " is not an integer"); + } + if (pos != nullptr) { + *pos = static_cast(strEnd - strStart); + } + return result; +} +#endif + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.h new file mode 100644 index 000000000..09d7b4bd2 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/string_util.h @@ -0,0 +1,59 @@ +#ifndef BENCHMARK_STRING_UTIL_H_ +#define BENCHMARK_STRING_UTIL_H_ + +#include +#include +#include +#include "internal_macros.h" + +namespace benchmark { + +void AppendHumanReadable(int n, std::string* str); + +std::string HumanReadableNumber(double n, double one_k = 1024.0); + +#if defined(__MINGW32__) +__attribute__((format(__MINGW_PRINTF_FORMAT, 1, 2))) +#elif defined(__GNUC__) +__attribute__((format(printf, 1, 2))) +#endif +std::string +StrFormat(const char* format, ...); + +inline std::ostream& StrCatImp(std::ostream& out) BENCHMARK_NOEXCEPT { + return out; +} + +template +inline std::ostream& StrCatImp(std::ostream& out, First&& f, Rest&&... rest) { + out << std::forward(f); + return StrCatImp(out, std::forward(rest)...); +} + +template +inline std::string StrCat(Args&&... args) { + std::ostringstream ss; + StrCatImp(ss, std::forward(args)...); + return ss.str(); +} + +#ifdef BENCHMARK_STL_ANDROID_GNUSTL +/* + * GNU STL in Android NDK lacks support for some C++11 functions, including + * stoul, stoi, stod. We reimplement them here using C functions strtoul, + * strtol, strtod. Note that reimplemented functions are in benchmark:: + * namespace, not std:: namespace. + */ +unsigned long stoul(const std::string& str, size_t* pos = nullptr, + int base = 10); +int stoi(const std::string& str, size_t* pos = nullptr, int base = 10); +double stod(const std::string& str, size_t* pos = nullptr); +#else +using std::stoul; +using std::stoi; +using std::stod; +#endif + +} // end namespace benchmark + +#endif // BENCHMARK_STRING_UTIL_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sysinfo.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sysinfo.cc new file mode 100644 index 000000000..28126470b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/sysinfo.cc @@ -0,0 +1,699 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "internal_macros.h" + +#ifdef BENCHMARK_OS_WINDOWS +#include +#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA +#include +#include +#include +#else +#include +#ifndef BENCHMARK_OS_FUCHSIA +#include +#endif +#include +#include // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD +#include +#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX || \ + defined BENCHMARK_OS_NETBSD || defined BENCHMARK_OS_OPENBSD +#define BENCHMARK_HAS_SYSCTL +#include +#endif +#endif +#if defined(BENCHMARK_OS_SOLARIS) +#include +#endif +#if defined(BENCHMARK_OS_QNX) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "cycleclock.h" +#include "internal_macros.h" +#include "log.h" +#include "sleep.h" +#include "string_util.h" + +namespace benchmark { +namespace { + +void PrintImp(std::ostream& out) { out << std::endl; } + +template +void PrintImp(std::ostream& out, First&& f, Rest&&... rest) { + out << std::forward(f); + PrintImp(out, std::forward(rest)...); +} + +template +BENCHMARK_NORETURN void PrintErrorAndDie(Args&&... args) { + PrintImp(std::cerr, std::forward(args)...); + std::exit(EXIT_FAILURE); +} + +#ifdef BENCHMARK_HAS_SYSCTL + +/// ValueUnion - A type used to correctly alias the byte-for-byte output of +/// `sysctl` with the result type it's to be interpreted as. +struct ValueUnion { + union DataT { + uint32_t uint32_value; + uint64_t uint64_value; + // For correct aliasing of union members from bytes. + char bytes[8]; + }; + using DataPtr = std::unique_ptr; + + // The size of the data union member + its trailing array size. + size_t Size; + DataPtr Buff; + + public: + ValueUnion() : Size(0), Buff(nullptr, &std::free) {} + + explicit ValueUnion(size_t BuffSize) + : Size(sizeof(DataT) + BuffSize), + Buff(::new (std::malloc(Size)) DataT(), &std::free) {} + + ValueUnion(ValueUnion&& other) = default; + + explicit operator bool() const { return bool(Buff); } + + char* data() const { return Buff->bytes; } + + std::string GetAsString() const { return std::string(data()); } + + int64_t GetAsInteger() const { + if (Size == sizeof(Buff->uint32_value)) + return static_cast(Buff->uint32_value); + else if (Size == sizeof(Buff->uint64_value)) + return static_cast(Buff->uint64_value); + BENCHMARK_UNREACHABLE(); + } + + uint64_t GetAsUnsigned() const { + if (Size == sizeof(Buff->uint32_value)) + return Buff->uint32_value; + else if (Size == sizeof(Buff->uint64_value)) + return Buff->uint64_value; + BENCHMARK_UNREACHABLE(); + } + + template + std::array GetAsArray() { + const int ArrSize = sizeof(T) * N; + CHECK_LE(ArrSize, Size); + std::array Arr; + std::memcpy(Arr.data(), data(), ArrSize); + return Arr; + } +}; + +ValueUnion GetSysctlImp(std::string const& Name) { +#if defined BENCHMARK_OS_OPENBSD + int mib[2]; + + mib[0] = CTL_HW; + if ((Name == "hw.ncpu") || (Name == "hw.cpuspeed")){ + ValueUnion buff(sizeof(int)); + + if (Name == "hw.ncpu") { + mib[1] = HW_NCPU; + } else { + mib[1] = HW_CPUSPEED; + } + + if (sysctl(mib, 2, buff.data(), &buff.Size, nullptr, 0) == -1) { + return ValueUnion(); + } + return buff; + } + return ValueUnion(); +#else + size_t CurBuffSize = 0; + if (sysctlbyname(Name.c_str(), nullptr, &CurBuffSize, nullptr, 0) == -1) + return ValueUnion(); + + ValueUnion buff(CurBuffSize); + if (sysctlbyname(Name.c_str(), buff.data(), &buff.Size, nullptr, 0) == 0) + return buff; + return ValueUnion(); +#endif +} + +BENCHMARK_MAYBE_UNUSED +bool GetSysctl(std::string const& Name, std::string* Out) { + Out->clear(); + auto Buff = GetSysctlImp(Name); + if (!Buff) return false; + Out->assign(Buff.data()); + return true; +} + +template ::value>::type> +bool GetSysctl(std::string const& Name, Tp* Out) { + *Out = 0; + auto Buff = GetSysctlImp(Name); + if (!Buff) return false; + *Out = static_cast(Buff.GetAsUnsigned()); + return true; +} + +template +bool GetSysctl(std::string const& Name, std::array* Out) { + auto Buff = GetSysctlImp(Name); + if (!Buff) return false; + *Out = Buff.GetAsArray(); + return true; +} +#endif + +template +bool ReadFromFile(std::string const& fname, ArgT* arg) { + *arg = ArgT(); + std::ifstream f(fname.c_str()); + if (!f.is_open()) return false; + f >> *arg; + return f.good(); +} + +bool CpuScalingEnabled(int num_cpus) { + // We don't have a valid CPU count, so don't even bother. + if (num_cpus <= 0) return false; +#ifdef BENCHMARK_OS_QNX + return false; +#endif +#ifndef BENCHMARK_OS_WINDOWS + // On Linux, the CPUfreq subsystem exposes CPU information as files on the + // local file system. If reading the exported files fails, then we may not be + // running on Linux, so we silently ignore all the read errors. + std::string res; + for (int cpu = 0; cpu < num_cpus; ++cpu) { + std::string governor_file = + StrCat("/sys/devices/system/cpu/cpu", cpu, "/cpufreq/scaling_governor"); + if (ReadFromFile(governor_file, &res) && res != "performance") return true; + } +#endif + return false; +} + +int CountSetBitsInCPUMap(std::string Val) { + auto CountBits = [](std::string Part) { + using CPUMask = std::bitset; + Part = "0x" + Part; + CPUMask Mask(benchmark::stoul(Part, nullptr, 16)); + return static_cast(Mask.count()); + }; + size_t Pos; + int total = 0; + while ((Pos = Val.find(',')) != std::string::npos) { + total += CountBits(Val.substr(0, Pos)); + Val = Val.substr(Pos + 1); + } + if (!Val.empty()) { + total += CountBits(Val); + } + return total; +} + +BENCHMARK_MAYBE_UNUSED +std::vector GetCacheSizesFromKVFS() { + std::vector res; + std::string dir = "/sys/devices/system/cpu/cpu0/cache/"; + int Idx = 0; + while (true) { + CPUInfo::CacheInfo info; + std::string FPath = StrCat(dir, "index", Idx++, "/"); + std::ifstream f(StrCat(FPath, "size").c_str()); + if (!f.is_open()) break; + std::string suffix; + f >> info.size; + if (f.fail()) + PrintErrorAndDie("Failed while reading file '", FPath, "size'"); + if (f.good()) { + f >> suffix; + if (f.bad()) + PrintErrorAndDie( + "Invalid cache size format: failed to read size suffix"); + else if (f && suffix != "K") + PrintErrorAndDie("Invalid cache size format: Expected bytes ", suffix); + else if (suffix == "K") + info.size *= 1000; + } + if (!ReadFromFile(StrCat(FPath, "type"), &info.type)) + PrintErrorAndDie("Failed to read from file ", FPath, "type"); + if (!ReadFromFile(StrCat(FPath, "level"), &info.level)) + PrintErrorAndDie("Failed to read from file ", FPath, "level"); + std::string map_str; + if (!ReadFromFile(StrCat(FPath, "shared_cpu_map"), &map_str)) + PrintErrorAndDie("Failed to read from file ", FPath, "shared_cpu_map"); + info.num_sharing = CountSetBitsInCPUMap(map_str); + res.push_back(info); + } + + return res; +} + +#ifdef BENCHMARK_OS_MACOSX +std::vector GetCacheSizesMacOSX() { + std::vector res; + std::array CacheCounts{{0, 0, 0, 0}}; + GetSysctl("hw.cacheconfig", &CacheCounts); + + struct { + std::string name; + std::string type; + int level; + uint64_t num_sharing; + } Cases[] = {{"hw.l1dcachesize", "Data", 1, CacheCounts[1]}, + {"hw.l1icachesize", "Instruction", 1, CacheCounts[1]}, + {"hw.l2cachesize", "Unified", 2, CacheCounts[2]}, + {"hw.l3cachesize", "Unified", 3, CacheCounts[3]}}; + for (auto& C : Cases) { + int val; + if (!GetSysctl(C.name, &val)) continue; + CPUInfo::CacheInfo info; + info.type = C.type; + info.level = C.level; + info.size = val; + info.num_sharing = static_cast(C.num_sharing); + res.push_back(std::move(info)); + } + return res; +} +#elif defined(BENCHMARK_OS_WINDOWS) +std::vector GetCacheSizesWindows() { + std::vector res; + DWORD buffer_size = 0; + using PInfo = SYSTEM_LOGICAL_PROCESSOR_INFORMATION; + using CInfo = CACHE_DESCRIPTOR; + + using UPtr = std::unique_ptr; + GetLogicalProcessorInformation(nullptr, &buffer_size); + UPtr buff((PInfo*)malloc(buffer_size), &std::free); + if (!GetLogicalProcessorInformation(buff.get(), &buffer_size)) + PrintErrorAndDie("Failed during call to GetLogicalProcessorInformation: ", + GetLastError()); + + PInfo* it = buff.get(); + PInfo* end = buff.get() + (buffer_size / sizeof(PInfo)); + + for (; it != end; ++it) { + if (it->Relationship != RelationCache) continue; + using BitSet = std::bitset; + BitSet B(it->ProcessorMask); + // To prevent duplicates, only consider caches where CPU 0 is specified + if (!B.test(0)) continue; + CInfo* Cache = &it->Cache; + CPUInfo::CacheInfo C; + C.num_sharing = static_cast(B.count()); + C.level = Cache->Level; + C.size = Cache->Size; + switch (Cache->Type) { + case CacheUnified: + C.type = "Unified"; + break; + case CacheInstruction: + C.type = "Instruction"; + break; + case CacheData: + C.type = "Data"; + break; + case CacheTrace: + C.type = "Trace"; + break; + default: + C.type = "Unknown"; + break; + } + res.push_back(C); + } + return res; +} +#elif BENCHMARK_OS_QNX +std::vector GetCacheSizesQNX() { + std::vector res; + struct cacheattr_entry *cache = SYSPAGE_ENTRY(cacheattr); + uint32_t const elsize = SYSPAGE_ELEMENT_SIZE(cacheattr); + int num = SYSPAGE_ENTRY_SIZE(cacheattr) / elsize ; + for(int i = 0; i < num; ++i ) { + CPUInfo::CacheInfo info; + switch (cache->flags){ + case CACHE_FLAG_INSTR : + info.type = "Instruction"; + info.level = 1; + break; + case CACHE_FLAG_DATA : + info.type = "Data"; + info.level = 1; + break; + case CACHE_FLAG_UNIFIED : + info.type = "Unified"; + info.level = 2; + case CACHE_FLAG_SHARED : + info.type = "Shared"; + info.level = 3; + default : + continue; + break; + } + info.size = cache->line_size * cache->num_lines; + info.num_sharing = 0; + res.push_back(std::move(info)); + cache = SYSPAGE_ARRAY_ADJ_OFFSET(cacheattr, cache, elsize); + } + return res; +} +#endif + +std::vector GetCacheSizes() { +#ifdef BENCHMARK_OS_MACOSX + return GetCacheSizesMacOSX(); +#elif defined(BENCHMARK_OS_WINDOWS) + return GetCacheSizesWindows(); +#elif defined(BENCHMARK_OS_QNX) + return GetCacheSizesQNX(); +#else + return GetCacheSizesFromKVFS(); +#endif +} + +std::string GetSystemName() { +#if defined(BENCHMARK_OS_WINDOWS) + std::string str; + const unsigned COUNT = MAX_COMPUTERNAME_LENGTH+1; + TCHAR hostname[COUNT] = {'\0'}; + DWORD DWCOUNT = COUNT; + if (!GetComputerName(hostname, &DWCOUNT)) + return std::string(""); +#ifndef UNICODE + str = std::string(hostname, DWCOUNT); +#else + //Using wstring_convert, Is deprecated in C++17 + using convert_type = std::codecvt_utf8; + std::wstring_convert converter; + std::wstring wStr(hostname, DWCOUNT); + str = converter.to_bytes(wStr); +#endif + return str; +#else // defined(BENCHMARK_OS_WINDOWS) +#ifdef BENCHMARK_HAS_SYSCTL // BSD/Mac Doesnt have HOST_NAME_MAX defined +#define HOST_NAME_MAX 64 +#elif defined(BENCHMARK_OS_QNX) +#define HOST_NAME_MAX 154 +#endif + char hostname[HOST_NAME_MAX]; + int retVal = gethostname(hostname, HOST_NAME_MAX); + if (retVal != 0) return std::string(""); + return std::string(hostname); +#endif // Catch-all POSIX block. +} + +int GetNumCPUs() { +#ifdef BENCHMARK_HAS_SYSCTL + int NumCPU = -1; + if (GetSysctl("hw.ncpu", &NumCPU)) return NumCPU; + fprintf(stderr, "Err: %s\n", strerror(errno)); + std::exit(EXIT_FAILURE); +#elif defined(BENCHMARK_OS_WINDOWS) + SYSTEM_INFO sysinfo; + // Use memset as opposed to = {} to avoid GCC missing initializer false + // positives. + std::memset(&sysinfo, 0, sizeof(SYSTEM_INFO)); + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; // number of logical + // processors in the current + // group +#elif defined(BENCHMARK_OS_SOLARIS) + // Returns -1 in case of a failure. + int NumCPU = sysconf(_SC_NPROCESSORS_ONLN); + if (NumCPU < 0) { + fprintf(stderr, + "sysconf(_SC_NPROCESSORS_ONLN) failed with error: %s\n", + strerror(errno)); + } + return NumCPU; +#elif defined(BENCHMARK_OS_QNX) + return static_cast(_syspage_ptr->num_cpu); +#else + int NumCPUs = 0; + int MaxID = -1; + std::ifstream f("/proc/cpuinfo"); + if (!f.is_open()) { + std::cerr << "failed to open /proc/cpuinfo\n"; + return -1; + } + const std::string Key = "processor"; + std::string ln; + while (std::getline(f, ln)) { + if (ln.empty()) continue; + size_t SplitIdx = ln.find(':'); + std::string value; +#if defined(__s390__) + // s390 has another format in /proc/cpuinfo + // it needs to be parsed differently + if (SplitIdx != std::string::npos) value = ln.substr(Key.size()+1,SplitIdx-Key.size()-1); +#else + if (SplitIdx != std::string::npos) value = ln.substr(SplitIdx + 1); +#endif + if (ln.size() >= Key.size() && ln.compare(0, Key.size(), Key) == 0) { + NumCPUs++; + if (!value.empty()) { + int CurID = benchmark::stoi(value); + MaxID = std::max(CurID, MaxID); + } + } + } + if (f.bad()) { + std::cerr << "Failure reading /proc/cpuinfo\n"; + return -1; + } + if (!f.eof()) { + std::cerr << "Failed to read to end of /proc/cpuinfo\n"; + return -1; + } + f.close(); + + if ((MaxID + 1) != NumCPUs) { + fprintf(stderr, + "CPU ID assignments in /proc/cpuinfo seem messed up." + " This is usually caused by a bad BIOS.\n"); + } + return NumCPUs; +#endif + BENCHMARK_UNREACHABLE(); +} + +double GetCPUCyclesPerSecond() { +#if defined BENCHMARK_OS_LINUX || defined BENCHMARK_OS_CYGWIN + long freq; + + // If the kernel is exporting the tsc frequency use that. There are issues + // where cpuinfo_max_freq cannot be relied on because the BIOS may be + // exporintg an invalid p-state (on x86) or p-states may be used to put the + // processor in a new mode (turbo mode). Essentially, those frequencies + // cannot always be relied upon. The same reasons apply to /proc/cpuinfo as + // well. + if (ReadFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", &freq) + // If CPU scaling is in effect, we want to use the *maximum* frequency, + // not whatever CPU speed some random processor happens to be using now. + || ReadFromFile("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", + &freq)) { + // The value is in kHz (as the file name suggests). For example, on a + // 2GHz warpstation, the file contains the value "2000000". + return freq * 1000.0; + } + + const double error_value = -1; + double bogo_clock = error_value; + + std::ifstream f("/proc/cpuinfo"); + if (!f.is_open()) { + std::cerr << "failed to open /proc/cpuinfo\n"; + return error_value; + } + + auto startsWithKey = [](std::string const& Value, std::string const& Key) { + if (Key.size() > Value.size()) return false; + auto Cmp = [&](char X, char Y) { + return std::tolower(X) == std::tolower(Y); + }; + return std::equal(Key.begin(), Key.end(), Value.begin(), Cmp); + }; + + std::string ln; + while (std::getline(f, ln)) { + if (ln.empty()) continue; + size_t SplitIdx = ln.find(':'); + std::string value; + if (SplitIdx != std::string::npos) value = ln.substr(SplitIdx + 1); + // When parsing the "cpu MHz" and "bogomips" (fallback) entries, we only + // accept positive values. Some environments (virtual machines) report zero, + // which would cause infinite looping in WallTime_Init. + if (startsWithKey(ln, "cpu MHz")) { + if (!value.empty()) { + double cycles_per_second = benchmark::stod(value) * 1000000.0; + if (cycles_per_second > 0) return cycles_per_second; + } + } else if (startsWithKey(ln, "bogomips")) { + if (!value.empty()) { + bogo_clock = benchmark::stod(value) * 1000000.0; + if (bogo_clock < 0.0) bogo_clock = error_value; + } + } + } + if (f.bad()) { + std::cerr << "Failure reading /proc/cpuinfo\n"; + return error_value; + } + if (!f.eof()) { + std::cerr << "Failed to read to end of /proc/cpuinfo\n"; + return error_value; + } + f.close(); + // If we found the bogomips clock, but nothing better, we'll use it (but + // we're not happy about it); otherwise, fallback to the rough estimation + // below. + if (bogo_clock >= 0.0) return bogo_clock; + +#elif defined BENCHMARK_HAS_SYSCTL + constexpr auto* FreqStr = +#if defined(BENCHMARK_OS_FREEBSD) || defined(BENCHMARK_OS_NETBSD) + "machdep.tsc_freq"; +#elif defined BENCHMARK_OS_OPENBSD + "hw.cpuspeed"; +#else + "hw.cpufrequency"; +#endif + unsigned long long hz = 0; +#if defined BENCHMARK_OS_OPENBSD + if (GetSysctl(FreqStr, &hz)) return hz * 1000000; +#else + if (GetSysctl(FreqStr, &hz)) return hz; +#endif + fprintf(stderr, "Unable to determine clock rate from sysctl: %s: %s\n", + FreqStr, strerror(errno)); + +#elif defined BENCHMARK_OS_WINDOWS + // In NT, read MHz from the registry. If we fail to do so or we're in win9x + // then make a crude estimate. + DWORD data, data_size = sizeof(data); + if (IsWindowsXPOrGreater() && + SUCCEEDED( + SHGetValueA(HKEY_LOCAL_MACHINE, + "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", + "~MHz", nullptr, &data, &data_size))) + return static_cast((int64_t)data * + (int64_t)(1000 * 1000)); // was mhz +#elif defined (BENCHMARK_OS_SOLARIS) + kstat_ctl_t *kc = kstat_open(); + if (!kc) { + std::cerr << "failed to open /dev/kstat\n"; + return -1; + } + kstat_t *ksp = kstat_lookup(kc, (char*)"cpu_info", -1, (char*)"cpu_info0"); + if (!ksp) { + std::cerr << "failed to lookup in /dev/kstat\n"; + return -1; + } + if (kstat_read(kc, ksp, NULL) < 0) { + std::cerr << "failed to read from /dev/kstat\n"; + return -1; + } + kstat_named_t *knp = + (kstat_named_t*)kstat_data_lookup(ksp, (char*)"current_clock_Hz"); + if (!knp) { + std::cerr << "failed to lookup data in /dev/kstat\n"; + return -1; + } + if (knp->data_type != KSTAT_DATA_UINT64) { + std::cerr << "current_clock_Hz is of unexpected data type: " + << knp->data_type << "\n"; + return -1; + } + double clock_hz = knp->value.ui64; + kstat_close(kc); + return clock_hz; +#elif defined (BENCHMARK_OS_QNX) + return static_cast((int64_t)(SYSPAGE_ENTRY(cpuinfo)->speed) * + (int64_t)(1000 * 1000)); +#endif + // If we've fallen through, attempt to roughly estimate the CPU clock rate. + const int estimate_time_ms = 1000; + const auto start_ticks = cycleclock::Now(); + SleepForMilliseconds(estimate_time_ms); + return static_cast(cycleclock::Now() - start_ticks); +} + +std::vector GetLoadAvg() { +#if (defined BENCHMARK_OS_FREEBSD || defined(BENCHMARK_OS_LINUX) || \ + defined BENCHMARK_OS_MACOSX || defined BENCHMARK_OS_NETBSD || \ + defined BENCHMARK_OS_OPENBSD) && !defined(__ANDROID__) + constexpr int kMaxSamples = 3; + std::vector res(kMaxSamples, 0.0); + const int nelem = getloadavg(res.data(), kMaxSamples); + if (nelem < 1) { + res.clear(); + } else { + res.resize(nelem); + } + return res; +#else + return {}; +#endif +} + +} // end namespace + +const CPUInfo& CPUInfo::Get() { + static const CPUInfo* info = new CPUInfo(); + return *info; +} + +CPUInfo::CPUInfo() + : num_cpus(GetNumCPUs()), + cycles_per_second(GetCPUCyclesPerSecond()), + caches(GetCacheSizes()), + scaling_enabled(CpuScalingEnabled(num_cpus)), + load_avg(GetLoadAvg()) {} + + +const SystemInfo& SystemInfo::Get() { + static const SystemInfo* info = new SystemInfo(); + return *info; +} + +SystemInfo::SystemInfo() : name(GetSystemName()) {} +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_manager.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_manager.h new file mode 100644 index 000000000..1720281f0 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_manager.h @@ -0,0 +1,64 @@ +#ifndef BENCHMARK_THREAD_MANAGER_H +#define BENCHMARK_THREAD_MANAGER_H + +#include + +#include "benchmark/benchmark.h" +#include "mutex.h" + +namespace benchmark { +namespace internal { + +class ThreadManager { + public: + ThreadManager(int num_threads) + : alive_threads_(num_threads), start_stop_barrier_(num_threads) {} + + Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) { + return benchmark_mutex_; + } + + bool StartStopBarrier() EXCLUDES(end_cond_mutex_) { + return start_stop_barrier_.wait(); + } + + void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) { + start_stop_barrier_.removeThread(); + if (--alive_threads_ == 0) { + MutexLock lock(end_cond_mutex_); + end_condition_.notify_all(); + } + } + + void WaitForAllThreads() EXCLUDES(end_cond_mutex_) { + MutexLock lock(end_cond_mutex_); + end_condition_.wait(lock.native_handle(), + [this]() { return alive_threads_ == 0; }); + } + + public: + struct Result { + IterationCount iterations = 0; + double real_time_used = 0; + double cpu_time_used = 0; + double manual_time_used = 0; + int64_t complexity_n = 0; + std::string report_label_; + std::string error_message_; + bool has_error_ = false; + UserCounters counters; + }; + GUARDED_BY(GetBenchmarkMutex()) Result results; + + private: + mutable Mutex benchmark_mutex_; + std::atomic alive_threads_; + Barrier start_stop_barrier_; + Mutex end_cond_mutex_; + Condition end_condition_; +}; + +} // namespace internal +} // namespace benchmark + +#endif // BENCHMARK_THREAD_MANAGER_H diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_timer.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_timer.h new file mode 100644 index 000000000..fbd298d3b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/thread_timer.h @@ -0,0 +1,86 @@ +#ifndef BENCHMARK_THREAD_TIMER_H +#define BENCHMARK_THREAD_TIMER_H + +#include "check.h" +#include "timers.h" + +namespace benchmark { +namespace internal { + +class ThreadTimer { + explicit ThreadTimer(bool measure_process_cpu_time_) + : measure_process_cpu_time(measure_process_cpu_time_) {} + + public: + static ThreadTimer Create() { + return ThreadTimer(/*measure_process_cpu_time_=*/false); + } + static ThreadTimer CreateProcessCpuTime() { + return ThreadTimer(/*measure_process_cpu_time_=*/true); + } + + // Called by each thread + void StartTimer() { + running_ = true; + start_real_time_ = ChronoClockNow(); + start_cpu_time_ = ReadCpuTimerOfChoice(); + } + + // Called by each thread + void StopTimer() { + CHECK(running_); + running_ = false; + real_time_used_ += ChronoClockNow() - start_real_time_; + // Floating point error can result in the subtraction producing a negative + // time. Guard against that. + cpu_time_used_ += + std::max(ReadCpuTimerOfChoice() - start_cpu_time_, 0); + } + + // Called by each thread + void SetIterationTime(double seconds) { manual_time_used_ += seconds; } + + bool running() const { return running_; } + + // REQUIRES: timer is not running + double real_time_used() { + CHECK(!running_); + return real_time_used_; + } + + // REQUIRES: timer is not running + double cpu_time_used() { + CHECK(!running_); + return cpu_time_used_; + } + + // REQUIRES: timer is not running + double manual_time_used() { + CHECK(!running_); + return manual_time_used_; + } + + private: + double ReadCpuTimerOfChoice() const { + if (measure_process_cpu_time) return ProcessCPUUsage(); + return ThreadCPUUsage(); + } + + // should the thread, or the process, time be measured? + const bool measure_process_cpu_time; + + bool running_ = false; // Is the timer running + double start_real_time_ = 0; // If running_ + double start_cpu_time_ = 0; // If running_ + + // Accumulated time so far (does not contain current slice if running_) + double real_time_used_ = 0; + double cpu_time_used_ = 0; + // Manually set iteration time. User sets this with SetIterationTime(seconds). + double manual_time_used_ = 0; +}; + +} // namespace internal +} // namespace benchmark + +#endif // BENCHMARK_THREAD_TIMER_H diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.cc new file mode 100644 index 000000000..7613ff92c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.cc @@ -0,0 +1,217 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "timers.h" +#include "internal_macros.h" + +#ifdef BENCHMARK_OS_WINDOWS +#include +#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA +#include +#include +#else +#include +#ifndef BENCHMARK_OS_FUCHSIA +#include +#endif +#include +#include // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD +#include +#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX +#include +#endif +#if defined(BENCHMARK_OS_MACOSX) +#include +#include +#include +#endif +#endif + +#ifdef BENCHMARK_OS_EMSCRIPTEN +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "log.h" +#include "sleep.h" +#include "string_util.h" + +namespace benchmark { + +// Suppress unused warnings on helper functions. +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + +namespace { +#if defined(BENCHMARK_OS_WINDOWS) +double MakeTime(FILETIME const& kernel_time, FILETIME const& user_time) { + ULARGE_INTEGER kernel; + ULARGE_INTEGER user; + kernel.HighPart = kernel_time.dwHighDateTime; + kernel.LowPart = kernel_time.dwLowDateTime; + user.HighPart = user_time.dwHighDateTime; + user.LowPart = user_time.dwLowDateTime; + return (static_cast(kernel.QuadPart) + + static_cast(user.QuadPart)) * + 1e-7; +} +#elif !defined(BENCHMARK_OS_FUCHSIA) +double MakeTime(struct rusage const& ru) { + return (static_cast(ru.ru_utime.tv_sec) + + static_cast(ru.ru_utime.tv_usec) * 1e-6 + + static_cast(ru.ru_stime.tv_sec) + + static_cast(ru.ru_stime.tv_usec) * 1e-6); +} +#endif +#if defined(BENCHMARK_OS_MACOSX) +double MakeTime(thread_basic_info_data_t const& info) { + return (static_cast(info.user_time.seconds) + + static_cast(info.user_time.microseconds) * 1e-6 + + static_cast(info.system_time.seconds) + + static_cast(info.system_time.microseconds) * 1e-6); +} +#endif +#if defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_THREAD_CPUTIME_ID) +double MakeTime(struct timespec const& ts) { + return ts.tv_sec + (static_cast(ts.tv_nsec) * 1e-9); +} +#endif + +BENCHMARK_NORETURN static void DiagnoseAndExit(const char* msg) { + std::cerr << "ERROR: " << msg << std::endl; + std::exit(EXIT_FAILURE); +} + +} // end namespace + +double ProcessCPUUsage() { +#if defined(BENCHMARK_OS_WINDOWS) + HANDLE proc = GetCurrentProcess(); + FILETIME creation_time; + FILETIME exit_time; + FILETIME kernel_time; + FILETIME user_time; + if (GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time, + &user_time)) + return MakeTime(kernel_time, user_time); + DiagnoseAndExit("GetProccessTimes() failed"); +#elif defined(BENCHMARK_OS_EMSCRIPTEN) + // clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) returns 0 on Emscripten. + // Use Emscripten-specific API. Reported CPU time would be exactly the + // same as total time, but this is ok because there aren't long-latency + // syncronous system calls in Emscripten. + return emscripten_get_now() * 1e-3; +#elif defined(CLOCK_PROCESS_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX) + // FIXME We want to use clock_gettime, but its not available in MacOS 10.11. See + // https://github.com/google/benchmark/pull/292 + struct timespec spec; + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0) + return MakeTime(spec); + DiagnoseAndExit("clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) failed"); +#else + struct rusage ru; + if (getrusage(RUSAGE_SELF, &ru) == 0) return MakeTime(ru); + DiagnoseAndExit("getrusage(RUSAGE_SELF, ...) failed"); +#endif +} + +double ThreadCPUUsage() { +#if defined(BENCHMARK_OS_WINDOWS) + HANDLE this_thread = GetCurrentThread(); + FILETIME creation_time; + FILETIME exit_time; + FILETIME kernel_time; + FILETIME user_time; + GetThreadTimes(this_thread, &creation_time, &exit_time, &kernel_time, + &user_time); + return MakeTime(kernel_time, user_time); +#elif defined(BENCHMARK_OS_MACOSX) + // FIXME We want to use clock_gettime, but its not available in MacOS 10.11. See + // https://github.com/google/benchmark/pull/292 + mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; + thread_basic_info_data_t info; + mach_port_t thread = pthread_mach_thread_np(pthread_self()); + if (thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &count) == + KERN_SUCCESS) { + return MakeTime(info); + } + DiagnoseAndExit("ThreadCPUUsage() failed when evaluating thread_info"); +#elif defined(BENCHMARK_OS_EMSCRIPTEN) + // Emscripten doesn't support traditional threads + return ProcessCPUUsage(); +#elif defined(BENCHMARK_OS_RTEMS) + // RTEMS doesn't support CLOCK_THREAD_CPUTIME_ID. See + // https://github.com/RTEMS/rtems/blob/master/cpukit/posix/src/clockgettime.c + return ProcessCPUUsage(); +#elif defined(BENCHMARK_OS_SOLARIS) + struct rusage ru; + if (getrusage(RUSAGE_LWP, &ru) == 0) return MakeTime(ru); + DiagnoseAndExit("getrusage(RUSAGE_LWP, ...) failed"); +#elif defined(CLOCK_THREAD_CPUTIME_ID) + struct timespec ts; + if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts); + DiagnoseAndExit("clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) failed"); +#else +#error Per-thread timing is not available on your system. +#endif +} + +namespace { + +std::string DateTimeString(bool local) { + typedef std::chrono::system_clock Clock; + std::time_t now = Clock::to_time_t(Clock::now()); + const std::size_t kStorageSize = 128; + char storage[kStorageSize]; + std::size_t written; + + if (local) { +#if defined(BENCHMARK_OS_WINDOWS) + written = + std::strftime(storage, sizeof(storage), "%x %X", ::localtime(&now)); +#else + std::tm timeinfo; + ::localtime_r(&now, &timeinfo); + written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo); +#endif + } else { +#if defined(BENCHMARK_OS_WINDOWS) + written = std::strftime(storage, sizeof(storage), "%x %X", ::gmtime(&now)); +#else + std::tm timeinfo; + ::gmtime_r(&now, &timeinfo); + written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo); +#endif + } + CHECK(written < kStorageSize); + ((void)written); // prevent unused variable in optimized mode. + return std::string(storage); +} + +} // end namespace + +std::string LocalDateTimeString() { return DateTimeString(true); } + +} // end namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.h new file mode 100644 index 000000000..65606ccd9 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/src/timers.h @@ -0,0 +1,48 @@ +#ifndef BENCHMARK_TIMERS_H +#define BENCHMARK_TIMERS_H + +#include +#include + +namespace benchmark { + +// Return the CPU usage of the current process +double ProcessCPUUsage(); + +// Return the CPU usage of the children of the current process +double ChildrenCPUUsage(); + +// Return the CPU usage of the current thread +double ThreadCPUUsage(); + +#if defined(HAVE_STEADY_CLOCK) +template +struct ChooseSteadyClock { + typedef std::chrono::high_resolution_clock type; +}; + +template <> +struct ChooseSteadyClock { + typedef std::chrono::steady_clock type; +}; +#endif + +struct ChooseClockType { +#if defined(HAVE_STEADY_CLOCK) + typedef ChooseSteadyClock<>::type type; +#else + typedef std::chrono::high_resolution_clock type; +#endif +}; + +inline double ChronoClockNow() { + typedef ChooseClockType::type ClockType; + using FpSeconds = std::chrono::duration; + return FpSeconds(ClockType::now().time_since_epoch()).count(); +} + +std::string LocalDateTimeString(); + +} // end namespace benchmark + +#endif // BENCHMARK_TIMERS_H diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/AssemblyTests.cmake b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/AssemblyTests.cmake new file mode 100644 index 000000000..3d078586f --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/AssemblyTests.cmake @@ -0,0 +1,46 @@ + +include(split_list) + +set(ASM_TEST_FLAGS "") +check_cxx_compiler_flag(-O3 BENCHMARK_HAS_O3_FLAG) +if (BENCHMARK_HAS_O3_FLAG) + list(APPEND ASM_TEST_FLAGS -O3) +endif() + +check_cxx_compiler_flag(-g0 BENCHMARK_HAS_G0_FLAG) +if (BENCHMARK_HAS_G0_FLAG) + list(APPEND ASM_TEST_FLAGS -g0) +endif() + +check_cxx_compiler_flag(-fno-stack-protector BENCHMARK_HAS_FNO_STACK_PROTECTOR_FLAG) +if (BENCHMARK_HAS_FNO_STACK_PROTECTOR_FLAG) + list(APPEND ASM_TEST_FLAGS -fno-stack-protector) +endif() + +split_list(ASM_TEST_FLAGS) +string(TOUPPER "${CMAKE_CXX_COMPILER_ID}" ASM_TEST_COMPILER) + +macro(add_filecheck_test name) + cmake_parse_arguments(ARG "" "" "CHECK_PREFIXES" ${ARGV}) + add_library(${name} OBJECT ${name}.cc) + set_target_properties(${name} PROPERTIES COMPILE_FLAGS "-S ${ASM_TEST_FLAGS}") + set(ASM_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${name}.s") + add_custom_target(copy_${name} ALL + COMMAND ${PROJECT_SOURCE_DIR}/tools/strip_asm.py + $ + ${ASM_OUTPUT_FILE} + BYPRODUCTS ${ASM_OUTPUT_FILE}) + add_dependencies(copy_${name} ${name}) + if (NOT ARG_CHECK_PREFIXES) + set(ARG_CHECK_PREFIXES "CHECK") + endif() + foreach(prefix ${ARG_CHECK_PREFIXES}) + add_test(NAME run_${name}_${prefix} + COMMAND + ${LLVM_FILECHECK_EXE} ${name}.cc + --input-file=${ASM_OUTPUT_FILE} + --check-prefixes=CHECK,CHECK-${ASM_TEST_COMPILER} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + endforeach() +endmacro() + diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/BUILD b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/BUILD new file mode 100644 index 000000000..3f174c486 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/BUILD @@ -0,0 +1,65 @@ +TEST_COPTS = [ + "-pedantic", + "-pedantic-errors", + "-std=c++11", + "-Wall", + "-Wextra", + "-Wshadow", +# "-Wshorten-64-to-32", + "-Wfloat-equal", + "-fstrict-aliasing", +] + +PER_SRC_COPTS = ({ + "cxx03_test.cc": ["-std=c++03"], + # Some of the issues with DoNotOptimize only occur when optimization is enabled + "donotoptimize_test.cc": ["-O3"], +}) + + +TEST_ARGS = ["--benchmark_min_time=0.01"] + +PER_SRC_TEST_ARGS = ({ + "user_counters_tabular_test.cc": ["--benchmark_counters_tabular=true"], +}) + +cc_library( + name = "output_test_helper", + testonly = 1, + srcs = ["output_test_helper.cc"], + hdrs = ["output_test.h"], + copts = TEST_COPTS, + deps = [ + "//:benchmark", + "//:benchmark_internal_headers", + ], +) + +[ + cc_test( + name = test_src[:-len(".cc")], + size = "small", + srcs = [test_src], + args = TEST_ARGS + PER_SRC_TEST_ARGS.get(test_src, []), + copts = TEST_COPTS + PER_SRC_COPTS.get(test_src, []), + deps = [ + ":output_test_helper", + "//:benchmark", + "//:benchmark_internal_headers", + "@com_google_googletest//:gtest", + ] + ( + ["@com_google_googletest//:gtest_main"] if (test_src[-len("gtest.cc"):] == "gtest.cc") else [] + ), + # FIXME: Add support for assembly tests to bazel. + # See Issue #556 + # https://github.com/google/benchmark/issues/556 + ) for test_src in glob(["*test.cc"], exclude = ["*_assembly_test.cc", "link_main_test.cc"]) +] + +cc_test( + name = "link_main_test", + size = "small", + srcs = ["link_main_test.cc"], + copts = TEST_COPTS, + deps = ["//:benchmark_main"], +) diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/CMakeLists.txt new file mode 100644 index 000000000..030f35aae --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/CMakeLists.txt @@ -0,0 +1,259 @@ +# Enable the tests + +find_package(Threads REQUIRED) +include(CheckCXXCompilerFlag) + +# NOTE: Some tests use `` to perform the test. Therefore we must +# strip -DNDEBUG from the default CMake flags in DEBUG mode. +string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) +if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" ) + add_definitions( -UNDEBUG ) + add_definitions(-DTEST_BENCHMARK_LIBRARY_HAS_NO_ASSERTIONS) + # Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines. + foreach (flags_var_to_scrub + CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_C_FLAGS_MINSIZEREL) + string (REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " + "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") + endforeach() +endif() + +check_cxx_compiler_flag(-O3 BENCHMARK_HAS_O3_FLAG) +set(BENCHMARK_O3_FLAG "") +if (BENCHMARK_HAS_O3_FLAG) + set(BENCHMARK_O3_FLAG "-O3") +endif() + +# NOTE: These flags must be added after find_package(Threads REQUIRED) otherwise +# they will break the configuration check. +if (DEFINED BENCHMARK_CXX_LINKER_FLAGS) + list(APPEND CMAKE_EXE_LINKER_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}) +endif() + +add_library(output_test_helper STATIC output_test_helper.cc output_test.h) + +macro(compile_benchmark_test name) + add_executable(${name} "${name}.cc") + target_link_libraries(${name} benchmark ${CMAKE_THREAD_LIBS_INIT}) +endmacro(compile_benchmark_test) + +macro(compile_benchmark_test_with_main name) + add_executable(${name} "${name}.cc") + target_link_libraries(${name} benchmark_main) +endmacro(compile_benchmark_test_with_main) + +macro(compile_output_test name) + add_executable(${name} "${name}.cc" output_test.h) + target_link_libraries(${name} output_test_helper benchmark + ${BENCHMARK_CXX_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) +endmacro(compile_output_test) + +# Demonstration executable +compile_benchmark_test(benchmark_test) +add_test(benchmark benchmark_test --benchmark_min_time=0.01) + +compile_benchmark_test(filter_test) +macro(add_filter_test name filter expect) + add_test(${name} filter_test --benchmark_min_time=0.01 --benchmark_filter=${filter} ${expect}) + add_test(${name}_list_only filter_test --benchmark_list_tests --benchmark_filter=${filter} ${expect}) +endmacro(add_filter_test) + +add_filter_test(filter_simple "Foo" 3) +add_filter_test(filter_simple_negative "-Foo" 2) +add_filter_test(filter_suffix "BM_.*" 4) +add_filter_test(filter_suffix_negative "-BM_.*" 1) +add_filter_test(filter_regex_all ".*" 5) +add_filter_test(filter_regex_all_negative "-.*" 0) +add_filter_test(filter_regex_blank "" 5) +add_filter_test(filter_regex_blank_negative "-" 0) +add_filter_test(filter_regex_none "monkey" 0) +add_filter_test(filter_regex_none_negative "-monkey" 5) +add_filter_test(filter_regex_wildcard ".*Foo.*" 3) +add_filter_test(filter_regex_wildcard_negative "-.*Foo.*" 2) +add_filter_test(filter_regex_begin "^BM_.*" 4) +add_filter_test(filter_regex_begin_negative "-^BM_.*" 1) +add_filter_test(filter_regex_begin2 "^N" 1) +add_filter_test(filter_regex_begin2_negative "-^N" 4) +add_filter_test(filter_regex_end ".*Ba$" 1) +add_filter_test(filter_regex_end_negative "-.*Ba$" 4) + +compile_benchmark_test(options_test) +add_test(options_benchmarks options_test --benchmark_min_time=0.01) + +compile_benchmark_test(basic_test) +add_test(basic_benchmark basic_test --benchmark_min_time=0.01) + +compile_benchmark_test(diagnostics_test) +add_test(diagnostics_test diagnostics_test --benchmark_min_time=0.01) + +compile_benchmark_test(skip_with_error_test) +add_test(skip_with_error_test skip_with_error_test --benchmark_min_time=0.01) + +compile_benchmark_test(donotoptimize_test) +# Some of the issues with DoNotOptimize only occur when optimization is enabled +check_cxx_compiler_flag(-O3 BENCHMARK_HAS_O3_FLAG) +if (BENCHMARK_HAS_O3_FLAG) + set_target_properties(donotoptimize_test PROPERTIES COMPILE_FLAGS "-O3") +endif() +add_test(donotoptimize_test donotoptimize_test --benchmark_min_time=0.01) + +compile_benchmark_test(fixture_test) +add_test(fixture_test fixture_test --benchmark_min_time=0.01) + +compile_benchmark_test(register_benchmark_test) +add_test(register_benchmark_test register_benchmark_test --benchmark_min_time=0.01) + +compile_benchmark_test(map_test) +add_test(map_test map_test --benchmark_min_time=0.01) + +compile_benchmark_test(multiple_ranges_test) +add_test(multiple_ranges_test multiple_ranges_test --benchmark_min_time=0.01) + +compile_benchmark_test_with_main(link_main_test) +add_test(link_main_test link_main_test --benchmark_min_time=0.01) + +compile_output_test(reporter_output_test) +add_test(reporter_output_test reporter_output_test --benchmark_min_time=0.01) + +compile_output_test(templated_fixture_test) +add_test(templated_fixture_test templated_fixture_test --benchmark_min_time=0.01) + +compile_output_test(user_counters_test) +add_test(user_counters_test user_counters_test --benchmark_min_time=0.01) + +compile_output_test(internal_threading_test) +add_test(internal_threading_test internal_threading_test --benchmark_min_time=0.01) + +compile_output_test(report_aggregates_only_test) +add_test(report_aggregates_only_test report_aggregates_only_test --benchmark_min_time=0.01) + +compile_output_test(display_aggregates_only_test) +add_test(display_aggregates_only_test display_aggregates_only_test --benchmark_min_time=0.01) + +compile_output_test(user_counters_tabular_test) +add_test(user_counters_tabular_test user_counters_tabular_test --benchmark_counters_tabular=true --benchmark_min_time=0.01) + +compile_output_test(user_counters_thousands_test) +add_test(user_counters_thousands_test user_counters_thousands_test --benchmark_min_time=0.01) + +compile_output_test(memory_manager_test) +add_test(memory_manager_test memory_manager_test --benchmark_min_time=0.01) + +check_cxx_compiler_flag(-std=c++03 BENCHMARK_HAS_CXX03_FLAG) +if (BENCHMARK_HAS_CXX03_FLAG) + compile_benchmark_test(cxx03_test) + set_target_properties(cxx03_test + PROPERTIES + COMPILE_FLAGS "-std=c++03") + # libstdc++ provides different definitions within between dialects. When + # LTO is enabled and -Werror is specified GCC diagnoses this ODR violation + # causing the test to fail to compile. To prevent this we explicitly disable + # the warning. + check_cxx_compiler_flag(-Wno-odr BENCHMARK_HAS_WNO_ODR) + if (BENCHMARK_ENABLE_LTO AND BENCHMARK_HAS_WNO_ODR) + set_target_properties(cxx03_test + PROPERTIES + LINK_FLAGS "-Wno-odr") + endif() + add_test(cxx03 cxx03_test --benchmark_min_time=0.01) +endif() + +# Attempt to work around flaky test failures when running on Appveyor servers. +if (DEFINED ENV{APPVEYOR}) + set(COMPLEXITY_MIN_TIME "0.5") +else() + set(COMPLEXITY_MIN_TIME "0.01") +endif() +compile_output_test(complexity_test) +add_test(complexity_benchmark complexity_test --benchmark_min_time=${COMPLEXITY_MIN_TIME}) + +############################################################################### +# GoogleTest Unit Tests +############################################################################### + +if (BENCHMARK_ENABLE_GTEST_TESTS) + macro(compile_gtest name) + add_executable(${name} "${name}.cc") + target_link_libraries(${name} benchmark + gmock_main ${CMAKE_THREAD_LIBS_INIT}) + endmacro(compile_gtest) + + macro(add_gtest name) + compile_gtest(${name}) + add_test(${name} ${name}) + endmacro() + + add_gtest(benchmark_gtest) + add_gtest(benchmark_name_gtest) + add_gtest(commandlineflags_gtest) + add_gtest(statistics_gtest) + add_gtest(string_util_gtest) +endif(BENCHMARK_ENABLE_GTEST_TESTS) + +############################################################################### +# Assembly Unit Tests +############################################################################### + +if (BENCHMARK_ENABLE_ASSEMBLY_TESTS) + if (NOT LLVM_FILECHECK_EXE) + message(FATAL_ERROR "LLVM FileCheck is required when including this file") + endif() + include(AssemblyTests.cmake) + add_filecheck_test(donotoptimize_assembly_test) + add_filecheck_test(state_assembly_test) + add_filecheck_test(clobber_memory_assembly_test) +endif() + + + +############################################################################### +# Code Coverage Configuration +############################################################################### + +# Add the coverage command(s) +if(CMAKE_BUILD_TYPE) + string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) +endif() +if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage") + find_program(GCOV gcov) + find_program(LCOV lcov) + find_program(GENHTML genhtml) + find_program(CTEST ctest) + if (GCOV AND LCOV AND GENHTML AND CTEST AND HAVE_CXX_FLAG_COVERAGE) + add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/lcov/index.html + COMMAND ${LCOV} -q -z -d . + COMMAND ${LCOV} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o before.lcov -i + COMMAND ${CTEST} --force-new-ctest-process + COMMAND ${LCOV} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o after.lcov + COMMAND ${LCOV} -q -a before.lcov -a after.lcov --output-file final.lcov + COMMAND ${LCOV} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov + COMMAND ${GENHTML} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_BINARY_DIR}" -t benchmark + DEPENDS filter_test benchmark_test options_test basic_test fixture_test cxx03_test complexity_test + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Running LCOV" + ) + add_custom_target(coverage + DEPENDS ${CMAKE_BINARY_DIR}/lcov/index.html + COMMENT "LCOV report at lcov/index.html" + ) + message(STATUS "Coverage command added") + else() + if (HAVE_CXX_FLAG_COVERAGE) + set(CXX_FLAG_COVERAGE_MESSAGE supported) + else() + set(CXX_FLAG_COVERAGE_MESSAGE unavailable) + endif() + message(WARNING + "Coverage not available:\n" + " gcov: ${GCOV}\n" + " lcov: ${LCOV}\n" + " genhtml: ${GENHTML}\n" + " ctest: ${CTEST}\n" + " --coverage flag: ${CXX_FLAG_COVERAGE_MESSAGE}") + endif() +endif() diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/basic_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/basic_test.cc new file mode 100644 index 000000000..5f3dd1a3e --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/basic_test.cc @@ -0,0 +1,136 @@ + +#include "benchmark/benchmark.h" + +#define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192) + +void BM_empty(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(state.iterations()); + } +} +BENCHMARK(BM_empty); +BENCHMARK(BM_empty)->ThreadPerCpu(); + +void BM_spin_empty(benchmark::State& state) { + for (auto _ : state) { + for (int x = 0; x < state.range(0); ++x) { + benchmark::DoNotOptimize(x); + } + } +} +BASIC_BENCHMARK_TEST(BM_spin_empty); +BASIC_BENCHMARK_TEST(BM_spin_empty)->ThreadPerCpu(); + +void BM_spin_pause_before(benchmark::State& state) { + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } + } +} +BASIC_BENCHMARK_TEST(BM_spin_pause_before); +BASIC_BENCHMARK_TEST(BM_spin_pause_before)->ThreadPerCpu(); + +void BM_spin_pause_during(benchmark::State& state) { + for (auto _ : state) { + state.PauseTiming(); + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } + state.ResumeTiming(); + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } + } +} +BASIC_BENCHMARK_TEST(BM_spin_pause_during); +BASIC_BENCHMARK_TEST(BM_spin_pause_during)->ThreadPerCpu(); + +void BM_pause_during(benchmark::State& state) { + for (auto _ : state) { + state.PauseTiming(); + state.ResumeTiming(); + } +} +BENCHMARK(BM_pause_during); +BENCHMARK(BM_pause_during)->ThreadPerCpu(); +BENCHMARK(BM_pause_during)->UseRealTime(); +BENCHMARK(BM_pause_during)->UseRealTime()->ThreadPerCpu(); + +void BM_spin_pause_after(benchmark::State& state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } + } + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } +} +BASIC_BENCHMARK_TEST(BM_spin_pause_after); +BASIC_BENCHMARK_TEST(BM_spin_pause_after)->ThreadPerCpu(); + +void BM_spin_pause_before_and_after(benchmark::State& state) { + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } + } + for (int i = 0; i < state.range(0); ++i) { + benchmark::DoNotOptimize(i); + } +} +BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after); +BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after)->ThreadPerCpu(); + +void BM_empty_stop_start(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_empty_stop_start); +BENCHMARK(BM_empty_stop_start)->ThreadPerCpu(); + + +void BM_KeepRunning(benchmark::State& state) { + benchmark::IterationCount iter_count = 0; + assert(iter_count == state.iterations()); + while (state.KeepRunning()) { + ++iter_count; + } + assert(iter_count == state.iterations()); +} +BENCHMARK(BM_KeepRunning); + +void BM_KeepRunningBatch(benchmark::State& state) { + // Choose a prime batch size to avoid evenly dividing max_iterations. + const benchmark::IterationCount batch_size = 101; + benchmark::IterationCount iter_count = 0; + while (state.KeepRunningBatch(batch_size)) { + iter_count += batch_size; + } + assert(state.iterations() == iter_count); +} +BENCHMARK(BM_KeepRunningBatch); + +void BM_RangedFor(benchmark::State& state) { + benchmark::IterationCount iter_count = 0; + for (auto _ : state) { + ++iter_count; + } + assert(iter_count == state.max_iterations); +} +BENCHMARK(BM_RangedFor); + +// Ensure that StateIterator provides all the necessary typedefs required to +// instantiate std::iterator_traits. +static_assert(std::is_same< + typename std::iterator_traits::value_type, + typename benchmark::State::StateIterator::value_type>::value, ""); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_gtest.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_gtest.cc new file mode 100644 index 000000000..9557b20ec --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_gtest.cc @@ -0,0 +1,128 @@ +#include + +#include "../src/benchmark_register.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace benchmark { +namespace internal { +namespace { + +TEST(AddRangeTest, Simple) { + std::vector dst; + AddRange(&dst, 1, 2, 2); + EXPECT_THAT(dst, testing::ElementsAre(1, 2)); +} + +TEST(AddRangeTest, Simple64) { + std::vector dst; + AddRange(&dst, static_cast(1), static_cast(2), 2); + EXPECT_THAT(dst, testing::ElementsAre(1, 2)); +} + +TEST(AddRangeTest, Advanced) { + std::vector dst; + AddRange(&dst, 5, 15, 2); + EXPECT_THAT(dst, testing::ElementsAre(5, 8, 15)); +} + +TEST(AddRangeTest, Advanced64) { + std::vector dst; + AddRange(&dst, static_cast(5), static_cast(15), 2); + EXPECT_THAT(dst, testing::ElementsAre(5, 8, 15)); +} + +TEST(AddRangeTest, FullRange8) { + std::vector dst; + AddRange(&dst, int8_t{1}, std::numeric_limits::max(), 8); + EXPECT_THAT(dst, testing::ElementsAre(1, 8, 64, 127)); +} + +TEST(AddRangeTest, FullRange64) { + std::vector dst; + AddRange(&dst, int64_t{1}, std::numeric_limits::max(), 1024); + EXPECT_THAT( + dst, testing::ElementsAre(1LL, 1024LL, 1048576LL, 1073741824LL, + 1099511627776LL, 1125899906842624LL, + 1152921504606846976LL, 9223372036854775807LL)); +} + +TEST(AddRangeTest, NegativeRanges) { + std::vector dst; + AddRange(&dst, -8, 0, 2); + EXPECT_THAT(dst, testing::ElementsAre(-8, -4, -2, -1, 0)); +} + +TEST(AddRangeTest, StrictlyNegative) { + std::vector dst; + AddRange(&dst, -8, -1, 2); + EXPECT_THAT(dst, testing::ElementsAre(-8, -4, -2, -1)); +} + +TEST(AddRangeTest, SymmetricNegativeRanges) { + std::vector dst; + AddRange(&dst, -8, 8, 2); + EXPECT_THAT(dst, testing::ElementsAre(-8, -4, -2, -1, 0, 1, 2, 4, 8)); +} + +TEST(AddRangeTest, SymmetricNegativeRangesOddMult) { + std::vector dst; + AddRange(&dst, -30, 32, 5); + EXPECT_THAT(dst, testing::ElementsAre(-30, -25, -5, -1, 0, 1, 5, 25, 32)); +} + +TEST(AddRangeTest, NegativeRangesAsymmetric) { + std::vector dst; + AddRange(&dst, -3, 5, 2); + EXPECT_THAT(dst, testing::ElementsAre(-3, -2, -1, 0, 1, 2, 4, 5)); +} + +TEST(AddRangeTest, NegativeRangesLargeStep) { + // Always include -1, 0, 1 when crossing zero. + std::vector dst; + AddRange(&dst, -8, 8, 10); + EXPECT_THAT(dst, testing::ElementsAre(-8, -1, 0, 1, 8)); +} + +TEST(AddRangeTest, ZeroOnlyRange) { + std::vector dst; + AddRange(&dst, 0, 0, 2); + EXPECT_THAT(dst, testing::ElementsAre(0)); +} + +TEST(AddRangeTest, NegativeRange64) { + std::vector dst; + AddRange(&dst, -4, 4, 2); + EXPECT_THAT(dst, testing::ElementsAre(-4, -2, -1, 0, 1, 2, 4)); +} + +TEST(AddRangeTest, NegativeRangePreservesExistingOrder) { + // If elements already exist in the range, ensure we don't change + // their ordering by adding negative values. + std::vector dst = {1, 2, 3}; + AddRange(&dst, -2, 2, 2); + EXPECT_THAT(dst, testing::ElementsAre(1, 2, 3, -2, -1, 0, 1, 2)); +} + +TEST(AddRangeTest, FullNegativeRange64) { + std::vector dst; + const auto min = std::numeric_limits::min(); + const auto max = std::numeric_limits::max(); + AddRange(&dst, min, max, 1024); + EXPECT_THAT( + dst, testing::ElementsAreArray(std::vector{ + min, -1152921504606846976LL, -1125899906842624LL, + -1099511627776LL, -1073741824LL, -1048576LL, -1024LL, -1LL, 0LL, + 1LL, 1024LL, 1048576LL, 1073741824LL, 1099511627776LL, + 1125899906842624LL, 1152921504606846976LL, max})); +} + +TEST(AddRangeTest, Simple8) { + std::vector dst; + AddRange(&dst, 1, 8, 2); + EXPECT_THAT(dst, testing::ElementsAre(1, 2, 4, 8)); +} + +} // namespace +} // namespace internal +} // namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_name_gtest.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_name_gtest.cc new file mode 100644 index 000000000..afb401c1f --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_name_gtest.cc @@ -0,0 +1,74 @@ +#include "benchmark/benchmark.h" +#include "gtest/gtest.h" + +namespace { + +using namespace benchmark; +using namespace benchmark::internal; + +TEST(BenchmarkNameTest, Empty) { + const auto name = BenchmarkName(); + EXPECT_EQ(name.str(), std::string()); +} + +TEST(BenchmarkNameTest, FunctionName) { + auto name = BenchmarkName(); + name.function_name = "function_name"; + EXPECT_EQ(name.str(), "function_name"); +} + +TEST(BenchmarkNameTest, FunctionNameAndArgs) { + auto name = BenchmarkName(); + name.function_name = "function_name"; + name.args = "some_args:3/4/5"; + EXPECT_EQ(name.str(), "function_name/some_args:3/4/5"); +} + +TEST(BenchmarkNameTest, MinTime) { + auto name = BenchmarkName(); + name.function_name = "function_name"; + name.args = "some_args:3/4"; + name.min_time = "min_time:3.4s"; + EXPECT_EQ(name.str(), "function_name/some_args:3/4/min_time:3.4s"); +} + +TEST(BenchmarkNameTest, Iterations) { + auto name = BenchmarkName(); + name.function_name = "function_name"; + name.min_time = "min_time:3.4s"; + name.iterations = "iterations:42"; + EXPECT_EQ(name.str(), "function_name/min_time:3.4s/iterations:42"); +} + +TEST(BenchmarkNameTest, Repetitions) { + auto name = BenchmarkName(); + name.function_name = "function_name"; + name.min_time = "min_time:3.4s"; + name.repetitions = "repetitions:24"; + EXPECT_EQ(name.str(), "function_name/min_time:3.4s/repetitions:24"); +} + +TEST(BenchmarkNameTest, TimeType) { + auto name = BenchmarkName(); + name.function_name = "function_name"; + name.min_time = "min_time:3.4s"; + name.time_type = "hammer_time"; + EXPECT_EQ(name.str(), "function_name/min_time:3.4s/hammer_time"); +} + +TEST(BenchmarkNameTest, Threads) { + auto name = BenchmarkName(); + name.function_name = "function_name"; + name.min_time = "min_time:3.4s"; + name.threads = "threads:256"; + EXPECT_EQ(name.str(), "function_name/min_time:3.4s/threads:256"); +} + +TEST(BenchmarkNameTest, TestEmptyFunctionName) { + auto name = BenchmarkName(); + name.args = "first:3/second:4"; + name.threads = "threads:22"; + EXPECT_EQ(name.str(), "first:3/second:4/threads:22"); +} + +} // end namespace diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_test.cc new file mode 100644 index 000000000..3cd4f5565 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/benchmark_test.cc @@ -0,0 +1,245 @@ +#include "benchmark/benchmark.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) +#define BENCHMARK_NOINLINE __attribute__((noinline)) +#else +#define BENCHMARK_NOINLINE +#endif + +namespace { + +int BENCHMARK_NOINLINE Factorial(uint32_t n) { + return (n == 1) ? 1 : n * Factorial(n - 1); +} + +double CalculatePi(int depth) { + double pi = 0.0; + for (int i = 0; i < depth; ++i) { + double numerator = static_cast(((i % 2) * 2) - 1); + double denominator = static_cast((2 * i) - 1); + pi += numerator / denominator; + } + return (pi - 1.0) * 4; +} + +std::set ConstructRandomSet(int64_t size) { + std::set s; + for (int i = 0; i < size; ++i) s.insert(s.end(), i); + return s; +} + +std::mutex test_vector_mu; +std::vector* test_vector = nullptr; + +} // end namespace + +static void BM_Factorial(benchmark::State& state) { + int fac_42 = 0; + for (auto _ : state) fac_42 = Factorial(8); + // Prevent compiler optimizations + std::stringstream ss; + ss << fac_42; + state.SetLabel(ss.str()); +} +BENCHMARK(BM_Factorial); +BENCHMARK(BM_Factorial)->UseRealTime(); + +static void BM_CalculatePiRange(benchmark::State& state) { + double pi = 0.0; + for (auto _ : state) pi = CalculatePi(static_cast(state.range(0))); + std::stringstream ss; + ss << pi; + state.SetLabel(ss.str()); +} +BENCHMARK_RANGE(BM_CalculatePiRange, 1, 1024 * 1024); + +static void BM_CalculatePi(benchmark::State& state) { + static const int depth = 1024; + for (auto _ : state) { + benchmark::DoNotOptimize(CalculatePi(static_cast(depth))); + } +} +BENCHMARK(BM_CalculatePi)->Threads(8); +BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32); +BENCHMARK(BM_CalculatePi)->ThreadPerCpu(); + +static void BM_SetInsert(benchmark::State& state) { + std::set data; + for (auto _ : state) { + state.PauseTiming(); + data = ConstructRandomSet(state.range(0)); + state.ResumeTiming(); + for (int j = 0; j < state.range(1); ++j) data.insert(rand()); + } + state.SetItemsProcessed(state.iterations() * state.range(1)); + state.SetBytesProcessed(state.iterations() * state.range(1) * sizeof(int)); +} + +// Test many inserts at once to reduce the total iterations needed. Otherwise, the slower, +// non-timed part of each iteration will make the benchmark take forever. +BENCHMARK(BM_SetInsert)->Ranges({{1 << 10, 8 << 10}, {128, 512}}); + +template +static void BM_Sequential(benchmark::State& state) { + ValueType v = 42; + for (auto _ : state) { + Container c; + for (int64_t i = state.range(0); --i;) c.push_back(v); + } + const int64_t items_processed = state.iterations() * state.range(0); + state.SetItemsProcessed(items_processed); + state.SetBytesProcessed(items_processed * sizeof(v)); +} +BENCHMARK_TEMPLATE2(BM_Sequential, std::vector, int) + ->Range(1 << 0, 1 << 10); +BENCHMARK_TEMPLATE(BM_Sequential, std::list)->Range(1 << 0, 1 << 10); +// Test the variadic version of BENCHMARK_TEMPLATE in C++11 and beyond. +#ifdef BENCHMARK_HAS_CXX11 +BENCHMARK_TEMPLATE(BM_Sequential, std::vector, int)->Arg(512); +#endif + +static void BM_StringCompare(benchmark::State& state) { + size_t len = static_cast(state.range(0)); + std::string s1(len, '-'); + std::string s2(len, '-'); + for (auto _ : state) benchmark::DoNotOptimize(s1.compare(s2)); +} +BENCHMARK(BM_StringCompare)->Range(1, 1 << 20); + +static void BM_SetupTeardown(benchmark::State& state) { + if (state.thread_index == 0) { + // No need to lock test_vector_mu here as this is running single-threaded. + test_vector = new std::vector(); + } + int i = 0; + for (auto _ : state) { + std::lock_guard l(test_vector_mu); + if (i % 2 == 0) + test_vector->push_back(i); + else + test_vector->pop_back(); + ++i; + } + if (state.thread_index == 0) { + delete test_vector; + } +} +BENCHMARK(BM_SetupTeardown)->ThreadPerCpu(); + +static void BM_LongTest(benchmark::State& state) { + double tracker = 0.0; + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) + benchmark::DoNotOptimize(tracker += i); + } +} +BENCHMARK(BM_LongTest)->Range(1 << 16, 1 << 28); + +static void BM_ParallelMemset(benchmark::State& state) { + int64_t size = state.range(0) / static_cast(sizeof(int)); + int thread_size = static_cast(size) / state.threads; + int from = thread_size * state.thread_index; + int to = from + thread_size; + + if (state.thread_index == 0) { + test_vector = new std::vector(static_cast(size)); + } + + for (auto _ : state) { + for (int i = from; i < to; i++) { + // No need to lock test_vector_mu as ranges + // do not overlap between threads. + benchmark::DoNotOptimize(test_vector->at(i) = 1); + } + } + + if (state.thread_index == 0) { + delete test_vector; + } +} +BENCHMARK(BM_ParallelMemset)->Arg(10 << 20)->ThreadRange(1, 4); + +static void BM_ManualTiming(benchmark::State& state) { + int64_t slept_for = 0; + int64_t microseconds = state.range(0); + std::chrono::duration sleep_duration{ + static_cast(microseconds)}; + + for (auto _ : state) { + auto start = std::chrono::high_resolution_clock::now(); + // Simulate some useful workload with a sleep + std::this_thread::sleep_for( + std::chrono::duration_cast(sleep_duration)); + auto end = std::chrono::high_resolution_clock::now(); + + auto elapsed = + std::chrono::duration_cast>(end - start); + + state.SetIterationTime(elapsed.count()); + slept_for += microseconds; + } + state.SetItemsProcessed(slept_for); +} +BENCHMARK(BM_ManualTiming)->Range(1, 1 << 14)->UseRealTime(); +BENCHMARK(BM_ManualTiming)->Range(1, 1 << 14)->UseManualTime(); + +#ifdef BENCHMARK_HAS_CXX11 + +template +void BM_with_args(benchmark::State& state, Args&&...) { + for (auto _ : state) { + } +} +BENCHMARK_CAPTURE(BM_with_args, int_test, 42, 43, 44); +BENCHMARK_CAPTURE(BM_with_args, string_and_pair_test, std::string("abc"), + std::pair(42, 3.8)); + +void BM_non_template_args(benchmark::State& state, int, double) { + while(state.KeepRunning()) {} +} +BENCHMARK_CAPTURE(BM_non_template_args, basic_test, 0, 0); + +#endif // BENCHMARK_HAS_CXX11 + +static void BM_DenseThreadRanges(benchmark::State& st) { + switch (st.range(0)) { + case 1: + assert(st.threads == 1 || st.threads == 2 || st.threads == 3); + break; + case 2: + assert(st.threads == 1 || st.threads == 3 || st.threads == 4); + break; + case 3: + assert(st.threads == 5 || st.threads == 8 || st.threads == 11 || + st.threads == 14); + break; + default: + assert(false && "Invalid test case number"); + } + while (st.KeepRunning()) { + } +} +BENCHMARK(BM_DenseThreadRanges)->Arg(1)->DenseThreadRange(1, 3); +BENCHMARK(BM_DenseThreadRanges)->Arg(2)->DenseThreadRange(1, 4, 2); +BENCHMARK(BM_DenseThreadRanges)->Arg(3)->DenseThreadRange(5, 14, 3); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/clobber_memory_assembly_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/clobber_memory_assembly_test.cc new file mode 100644 index 000000000..f41911a39 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/clobber_memory_assembly_test.cc @@ -0,0 +1,64 @@ +#include + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wreturn-type" +#endif + +extern "C" { + +extern int ExternInt; +extern int ExternInt2; +extern int ExternInt3; + +} + +// CHECK-LABEL: test_basic: +extern "C" void test_basic() { + int x; + benchmark::DoNotOptimize(&x); + x = 101; + benchmark::ClobberMemory(); + // CHECK: leaq [[DEST:[^,]+]], %rax + // CHECK: movl $101, [[DEST]] + // CHECK: ret +} + +// CHECK-LABEL: test_redundant_store: +extern "C" void test_redundant_store() { + ExternInt = 3; + benchmark::ClobberMemory(); + ExternInt = 51; + // CHECK-DAG: ExternInt + // CHECK-DAG: movl $3 + // CHECK: movl $51 +} + +// CHECK-LABEL: test_redundant_read: +extern "C" void test_redundant_read() { + int x; + benchmark::DoNotOptimize(&x); + x = ExternInt; + benchmark::ClobberMemory(); + x = ExternInt2; + // CHECK: leaq [[DEST:[^,]+]], %rax + // CHECK: ExternInt(%rip) + // CHECK: movl %eax, [[DEST]] + // CHECK-NOT: ExternInt2 + // CHECK: ret +} + +// CHECK-LABEL: test_redundant_read2: +extern "C" void test_redundant_read2() { + int x; + benchmark::DoNotOptimize(&x); + x = ExternInt; + benchmark::ClobberMemory(); + x = ExternInt2; + benchmark::ClobberMemory(); + // CHECK: leaq [[DEST:[^,]+]], %rax + // CHECK: ExternInt(%rip) + // CHECK: movl %eax, [[DEST]] + // CHECK: ExternInt2(%rip) + // CHECK: movl %eax, [[DEST]] + // CHECK: ret +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/commandlineflags_gtest.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/commandlineflags_gtest.cc new file mode 100644 index 000000000..5460778c4 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/commandlineflags_gtest.cc @@ -0,0 +1,78 @@ +#include + +#include "../src/commandlineflags.h" +#include "../src/internal_macros.h" +#include "gtest/gtest.h" + +namespace benchmark { +namespace { + +#if defined(BENCHMARK_OS_WINDOWS) +int setenv(const char* name, const char* value, int overwrite) { + if (!overwrite) { + // NOTE: getenv_s is far superior but not available under mingw. + char* env_value = getenv(name); + if (env_value == nullptr) { + return -1; + } + } + return _putenv_s(name, value); +} + +int unsetenv(const char* name) { + return _putenv_s(name, ""); +} + +#endif // BENCHMARK_OS_WINDOWS + +TEST(BoolFromEnv, Default) { + ASSERT_EQ(unsetenv("BENCHMARK_NOT_IN_ENV"), 0); + EXPECT_EQ(BoolFromEnv("not_in_env", true), true); +} + +TEST(BoolFromEnv, False) { + ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "0", 1), 0); + EXPECT_EQ(BoolFromEnv("in_env", true), false); + unsetenv("BENCHMARK_IN_ENV"); +} + +TEST(BoolFromEnv, True) { + ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "1", 1), 0); + EXPECT_EQ(BoolFromEnv("in_env", false), true); + unsetenv("BENCHMARK_IN_ENV"); + + ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "foo", 1), 0); + EXPECT_EQ(BoolFromEnv("in_env", false), true); + unsetenv("BENCHMARK_IN_ENV"); +} + +TEST(Int32FromEnv, NotInEnv) { + ASSERT_EQ(unsetenv("BENCHMARK_NOT_IN_ENV"), 0); + EXPECT_EQ(Int32FromEnv("not_in_env", 42), 42); +} + +TEST(Int32FromEnv, InvalidInteger) { + ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "foo", 1), 0); + EXPECT_EQ(Int32FromEnv("in_env", 42), 42); + ASSERT_EQ(unsetenv("BENCHMARK_IN_ENV"), 0); +} + +TEST(Int32FromEnv, ValidInteger) { + ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "42", 1), 0); + EXPECT_EQ(Int32FromEnv("in_env", 64), 42); + unsetenv("BENCHMARK_IN_ENV"); +} + +TEST(StringFromEnv, Default) { + ASSERT_EQ(unsetenv("BENCHMARK_NOT_IN_ENV"), 0); + EXPECT_STREQ(StringFromEnv("not_in_env", "foo"), "foo"); +} + +TEST(StringFromEnv, Valid) { + ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "foo", 1), 0); + EXPECT_STREQ(StringFromEnv("in_env", "bar"), "foo"); + unsetenv("BENCHMARK_IN_ENV"); +} + +} // namespace +} // namespace benchmark diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/complexity_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/complexity_test.cc new file mode 100644 index 000000000..d4febbbc1 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/complexity_test.cc @@ -0,0 +1,211 @@ +#undef NDEBUG +#include +#include +#include +#include +#include +#include "benchmark/benchmark.h" +#include "output_test.h" + +namespace { + +#define ADD_COMPLEXITY_CASES(...) \ + int CONCAT(dummy, __LINE__) = AddComplexityTest(__VA_ARGS__) + +int AddComplexityTest(std::string test_name, std::string big_o_test_name, + std::string rms_test_name, std::string big_o) { + SetSubstitutions({{"%name", test_name}, + {"%bigo_name", big_o_test_name}, + {"%rms_name", rms_test_name}, + {"%bigo_str", "[ ]* %float " + big_o}, + {"%bigo", big_o}, + {"%rms", "[ ]*[0-9]+ %"}}); + AddCases( + TC_ConsoleOut, + {{"^%bigo_name %bigo_str %bigo_str[ ]*$"}, + {"^%bigo_name", MR_Not}, // Assert we we didn't only matched a name. + {"^%rms_name %rms %rms[ ]*$", MR_Next}}); + AddCases(TC_JSONOut, {{"\"name\": \"%bigo_name\",$"}, + {"\"run_name\": \"%name\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": %int,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"BigO\",$", MR_Next}, + {"\"cpu_coefficient\": %float,$", MR_Next}, + {"\"real_coefficient\": %float,$", MR_Next}, + {"\"big_o\": \"%bigo\",$", MR_Next}, + {"\"time_unit\": \"ns\"$", MR_Next}, + {"}", MR_Next}, + {"\"name\": \"%rms_name\",$"}, + {"\"run_name\": \"%name\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": %int,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"RMS\",$", MR_Next}, + {"\"rms\": %float$", MR_Next}, + {"}", MR_Next}}); + AddCases(TC_CSVOut, {{"^\"%bigo_name\",,%float,%float,%bigo,,,,,$"}, + {"^\"%bigo_name\"", MR_Not}, + {"^\"%rms_name\",,%float,%float,,,,,,$", MR_Next}}); + return 0; +} + +} // end namespace + +// ========================================================================= // +// --------------------------- Testing BigO O(1) --------------------------- // +// ========================================================================= // + +void BM_Complexity_O1(benchmark::State& state) { + for (auto _ : state) { + for (int i = 0; i < 1024; ++i) { + benchmark::DoNotOptimize(&i); + } + } + state.SetComplexityN(state.range(0)); +} +BENCHMARK(BM_Complexity_O1)->Range(1, 1 << 18)->Complexity(benchmark::o1); +BENCHMARK(BM_Complexity_O1)->Range(1, 1 << 18)->Complexity(); +BENCHMARK(BM_Complexity_O1) + ->Range(1, 1 << 18) + ->Complexity([](benchmark::IterationCount) { return 1.0; }); + +const char *one_test_name = "BM_Complexity_O1"; +const char *big_o_1_test_name = "BM_Complexity_O1_BigO"; +const char *rms_o_1_test_name = "BM_Complexity_O1_RMS"; +const char *enum_big_o_1 = "\\([0-9]+\\)"; +// FIXME: Tolerate both '(1)' and 'lgN' as output when the complexity is auto +// deduced. +// See https://github.com/google/benchmark/issues/272 +const char *auto_big_o_1 = "(\\([0-9]+\\))|(lgN)"; +const char *lambda_big_o_1 = "f\\(N\\)"; + +// Add enum tests +ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name, + enum_big_o_1); + +// Add auto enum tests +ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name, + auto_big_o_1); + +// Add lambda tests +ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name, + lambda_big_o_1); + +// ========================================================================= // +// --------------------------- Testing BigO O(N) --------------------------- // +// ========================================================================= // + +std::vector ConstructRandomVector(int64_t size) { + std::vector v; + v.reserve(static_cast(size)); + for (int i = 0; i < size; ++i) { + v.push_back(static_cast(std::rand() % size)); + } + return v; +} + +void BM_Complexity_O_N(benchmark::State& state) { + auto v = ConstructRandomVector(state.range(0)); + // Test worst case scenario (item not in vector) + const int64_t item_not_in_vector = state.range(0) * 2; + for (auto _ : state) { + benchmark::DoNotOptimize(std::find(v.begin(), v.end(), item_not_in_vector)); + } + state.SetComplexityN(state.range(0)); +} +BENCHMARK(BM_Complexity_O_N) + ->RangeMultiplier(2) + ->Range(1 << 10, 1 << 16) + ->Complexity(benchmark::oN); +BENCHMARK(BM_Complexity_O_N) + ->RangeMultiplier(2) + ->Range(1 << 10, 1 << 16) + ->Complexity([](benchmark::IterationCount n) -> double { + return static_cast(n); + }); +BENCHMARK(BM_Complexity_O_N) + ->RangeMultiplier(2) + ->Range(1 << 10, 1 << 16) + ->Complexity(); + +const char *n_test_name = "BM_Complexity_O_N"; +const char *big_o_n_test_name = "BM_Complexity_O_N_BigO"; +const char *rms_o_n_test_name = "BM_Complexity_O_N_RMS"; +const char *enum_auto_big_o_n = "N"; +const char *lambda_big_o_n = "f\\(N\\)"; + +// Add enum tests +ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name, + enum_auto_big_o_n); + +// Add lambda tests +ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name, + lambda_big_o_n); + +// ========================================================================= // +// ------------------------- Testing BigO O(N*lgN) ------------------------- // +// ========================================================================= // + +static void BM_Complexity_O_N_log_N(benchmark::State& state) { + auto v = ConstructRandomVector(state.range(0)); + for (auto _ : state) { + std::sort(v.begin(), v.end()); + } + state.SetComplexityN(state.range(0)); +} +static const double kLog2E = 1.44269504088896340736; +BENCHMARK(BM_Complexity_O_N_log_N) + ->RangeMultiplier(2) + ->Range(1 << 10, 1 << 16) + ->Complexity(benchmark::oNLogN); +BENCHMARK(BM_Complexity_O_N_log_N) + ->RangeMultiplier(2) + ->Range(1 << 10, 1 << 16) + ->Complexity([](benchmark::IterationCount n) { + return kLog2E * n * log(static_cast(n)); + }); +BENCHMARK(BM_Complexity_O_N_log_N) + ->RangeMultiplier(2) + ->Range(1 << 10, 1 << 16) + ->Complexity(); + +const char *n_lg_n_test_name = "BM_Complexity_O_N_log_N"; +const char *big_o_n_lg_n_test_name = "BM_Complexity_O_N_log_N_BigO"; +const char *rms_o_n_lg_n_test_name = "BM_Complexity_O_N_log_N_RMS"; +const char *enum_auto_big_o_n_lg_n = "NlgN"; +const char *lambda_big_o_n_lg_n = "f\\(N\\)"; + +// Add enum tests +ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name, + rms_o_n_lg_n_test_name, enum_auto_big_o_n_lg_n); + +// Add lambda tests +ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name, + rms_o_n_lg_n_test_name, lambda_big_o_n_lg_n); + +// ========================================================================= // +// -------- Testing formatting of Complexity with captured args ------------ // +// ========================================================================= // + +void BM_ComplexityCaptureArgs(benchmark::State& state, int n) { + for (auto _ : state) { + } + state.SetComplexityN(n); +} + +BENCHMARK_CAPTURE(BM_ComplexityCaptureArgs, capture_test, 100) + ->Complexity(benchmark::oN) + ->Ranges({{1, 2}, {3, 4}}); + +const std::string complexity_capture_name = + "BM_ComplexityCaptureArgs/capture_test"; + +ADD_COMPLEXITY_CASES(complexity_capture_name, complexity_capture_name + "_BigO", + complexity_capture_name + "_RMS", "N"); + +// ========================================================================= // +// --------------------------- TEST CASES END ------------------------------ // +// ========================================================================= // + +int main(int argc, char *argv[]) { RunOutputTests(argc, argv); } diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/cxx03_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/cxx03_test.cc new file mode 100644 index 000000000..c4c9a5227 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/cxx03_test.cc @@ -0,0 +1,63 @@ +#undef NDEBUG +#include +#include + +#include "benchmark/benchmark.h" + +#if __cplusplus >= 201103L +#error C++11 or greater detected. Should be C++03. +#endif + +#ifdef BENCHMARK_HAS_CXX11 +#error C++11 or greater detected by the library. BENCHMARK_HAS_CXX11 is defined. +#endif + +void BM_empty(benchmark::State& state) { + while (state.KeepRunning()) { + volatile benchmark::IterationCount x = state.iterations(); + ((void)x); + } +} +BENCHMARK(BM_empty); + +// The new C++11 interface for args/ranges requires initializer list support. +// Therefore we provide the old interface to support C++03. +void BM_old_arg_range_interface(benchmark::State& state) { + assert((state.range(0) == 1 && state.range(1) == 2) || + (state.range(0) == 5 && state.range(1) == 6)); + while (state.KeepRunning()) { + } +} +BENCHMARK(BM_old_arg_range_interface)->ArgPair(1, 2)->RangePair(5, 5, 6, 6); + +template +void BM_template2(benchmark::State& state) { + BM_empty(state); +} +BENCHMARK_TEMPLATE2(BM_template2, int, long); + +template +void BM_template1(benchmark::State& state) { + BM_empty(state); +} +BENCHMARK_TEMPLATE(BM_template1, long); +BENCHMARK_TEMPLATE1(BM_template1, int); + +template +struct BM_Fixture : public ::benchmark::Fixture { +}; + +BENCHMARK_TEMPLATE_F(BM_Fixture, BM_template1, long)(benchmark::State& state) { + BM_empty(state); +} +BENCHMARK_TEMPLATE1_F(BM_Fixture, BM_template2, int)(benchmark::State& state) { + BM_empty(state); +} + +void BM_counters(benchmark::State& state) { + BM_empty(state); + state.counters["Foo"] = 2; +} +BENCHMARK(BM_counters); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/diagnostics_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/diagnostics_test.cc new file mode 100644 index 000000000..dd64a3365 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/diagnostics_test.cc @@ -0,0 +1,80 @@ +// Testing: +// State::PauseTiming() +// State::ResumeTiming() +// Test that CHECK's within these function diagnose when they are called +// outside of the KeepRunning() loop. +// +// NOTE: Users should NOT include or use src/check.h. This is only done in +// order to test library internals. + +#include +#include + +#include "../src/check.h" +#include "benchmark/benchmark.h" + +#if defined(__GNUC__) && !defined(__EXCEPTIONS) +#define TEST_HAS_NO_EXCEPTIONS +#endif + +void TestHandler() { +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::logic_error(""); +#else + std::abort(); +#endif +} + +void try_invalid_pause_resume(benchmark::State& state) { +#if !defined(TEST_BENCHMARK_LIBRARY_HAS_NO_ASSERTIONS) && !defined(TEST_HAS_NO_EXCEPTIONS) + try { + state.PauseTiming(); + std::abort(); + } catch (std::logic_error const&) { + } + try { + state.ResumeTiming(); + std::abort(); + } catch (std::logic_error const&) { + } +#else + (void)state; // avoid unused warning +#endif +} + +void BM_diagnostic_test(benchmark::State& state) { + static bool called_once = false; + + if (called_once == false) try_invalid_pause_resume(state); + + for (auto _ : state) { + benchmark::DoNotOptimize(state.iterations()); + } + + if (called_once == false) try_invalid_pause_resume(state); + + called_once = true; +} +BENCHMARK(BM_diagnostic_test); + + +void BM_diagnostic_test_keep_running(benchmark::State& state) { + static bool called_once = false; + + if (called_once == false) try_invalid_pause_resume(state); + + while(state.KeepRunning()) { + benchmark::DoNotOptimize(state.iterations()); + } + + if (called_once == false) try_invalid_pause_resume(state); + + called_once = true; +} +BENCHMARK(BM_diagnostic_test_keep_running); + +int main(int argc, char* argv[]) { + benchmark::internal::GetAbortHandler() = &TestHandler; + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/display_aggregates_only_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/display_aggregates_only_test.cc new file mode 100644 index 000000000..3c36d3f03 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/display_aggregates_only_test.cc @@ -0,0 +1,43 @@ + +#undef NDEBUG +#include +#include + +#include "benchmark/benchmark.h" +#include "output_test.h" + +// Ok this test is super ugly. We want to check what happens with the file +// reporter in the presence of DisplayAggregatesOnly(). +// We do not care about console output, the normal tests check that already. + +void BM_SummaryRepeat(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->DisplayAggregatesOnly(); + +int main(int argc, char* argv[]) { + const std::string output = GetFileReporterOutput(argc, argv); + + if (SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3") != 6 || + SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3\"") != 3 || + SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_mean\"") != 1 || + SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_median\"") != + 1 || + SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"") != + 1) { + std::cout << "Precondition mismatch. Expected to only find 6 " + "occurrences of \"BM_SummaryRepeat/repeats:3\" substring:\n" + "\"name\": \"BM_SummaryRepeat/repeats:3\", " + "\"name\": \"BM_SummaryRepeat/repeats:3\", " + "\"name\": \"BM_SummaryRepeat/repeats:3\", " + "\"name\": \"BM_SummaryRepeat/repeats:3_mean\", " + "\"name\": \"BM_SummaryRepeat/repeats:3_median\", " + "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"\nThe entire " + "output:\n"; + std::cout << output; + return 1; + } + + return 0; +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_assembly_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_assembly_test.cc new file mode 100644 index 000000000..d4b0bab70 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_assembly_test.cc @@ -0,0 +1,163 @@ +#include + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wreturn-type" +#endif + +extern "C" { + +extern int ExternInt; +extern int ExternInt2; +extern int ExternInt3; + +inline int Add42(int x) { return x + 42; } + +struct NotTriviallyCopyable { + NotTriviallyCopyable(); + explicit NotTriviallyCopyable(int x) : value(x) {} + NotTriviallyCopyable(NotTriviallyCopyable const&); + int value; +}; + +struct Large { + int value; + int data[2]; +}; + +} +// CHECK-LABEL: test_with_rvalue: +extern "C" void test_with_rvalue() { + benchmark::DoNotOptimize(Add42(0)); + // CHECK: movl $42, %eax + // CHECK: ret +} + +// CHECK-LABEL: test_with_large_rvalue: +extern "C" void test_with_large_rvalue() { + benchmark::DoNotOptimize(Large{ExternInt, {ExternInt, ExternInt}}); + // CHECK: ExternInt(%rip) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]] + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) + // CHECK: ret +} + +// CHECK-LABEL: test_with_non_trivial_rvalue: +extern "C" void test_with_non_trivial_rvalue() { + benchmark::DoNotOptimize(NotTriviallyCopyable(ExternInt)); + // CHECK: mov{{l|q}} ExternInt(%rip) + // CHECK: ret +} + +// CHECK-LABEL: test_with_lvalue: +extern "C" void test_with_lvalue() { + int x = 101; + benchmark::DoNotOptimize(x); + // CHECK-GNU: movl $101, %eax + // CHECK-CLANG: movl $101, -{{[0-9]+}}(%[[REG:[a-z]+]]) + // CHECK: ret +} + +// CHECK-LABEL: test_with_large_lvalue: +extern "C" void test_with_large_lvalue() { + Large L{ExternInt, {ExternInt, ExternInt}}; + benchmark::DoNotOptimize(L); + // CHECK: ExternInt(%rip) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) + // CHECK: ret +} + +// CHECK-LABEL: test_with_non_trivial_lvalue: +extern "C" void test_with_non_trivial_lvalue() { + NotTriviallyCopyable NTC(ExternInt); + benchmark::DoNotOptimize(NTC); + // CHECK: ExternInt(%rip) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) + // CHECK: ret +} + +// CHECK-LABEL: test_with_const_lvalue: +extern "C" void test_with_const_lvalue() { + const int x = 123; + benchmark::DoNotOptimize(x); + // CHECK: movl $123, %eax + // CHECK: ret +} + +// CHECK-LABEL: test_with_large_const_lvalue: +extern "C" void test_with_large_const_lvalue() { + const Large L{ExternInt, {ExternInt, ExternInt}}; + benchmark::DoNotOptimize(L); + // CHECK: ExternInt(%rip) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) + // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) + // CHECK: ret +} + +// CHECK-LABEL: test_with_non_trivial_const_lvalue: +extern "C" void test_with_non_trivial_const_lvalue() { + const NotTriviallyCopyable Obj(ExternInt); + benchmark::DoNotOptimize(Obj); + // CHECK: mov{{q|l}} ExternInt(%rip) + // CHECK: ret +} + +// CHECK-LABEL: test_div_by_two: +extern "C" int test_div_by_two(int input) { + int divisor = 2; + benchmark::DoNotOptimize(divisor); + return input / divisor; + // CHECK: movl $2, [[DEST:.*]] + // CHECK: idivl [[DEST]] + // CHECK: ret +} + +// CHECK-LABEL: test_inc_integer: +extern "C" int test_inc_integer() { + int x = 0; + for (int i=0; i < 5; ++i) + benchmark::DoNotOptimize(++x); + // CHECK: movl $1, [[DEST:.*]] + // CHECK: {{(addl \$1,|incl)}} [[DEST]] + // CHECK: {{(addl \$1,|incl)}} [[DEST]] + // CHECK: {{(addl \$1,|incl)}} [[DEST]] + // CHECK: {{(addl \$1,|incl)}} [[DEST]] + // CHECK-CLANG: movl [[DEST]], %eax + // CHECK: ret + return x; +} + +// CHECK-LABEL: test_pointer_rvalue +extern "C" void test_pointer_rvalue() { + // CHECK: movl $42, [[DEST:.*]] + // CHECK: leaq [[DEST]], %rax + // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]]) + // CHECK: ret + int x = 42; + benchmark::DoNotOptimize(&x); +} + +// CHECK-LABEL: test_pointer_const_lvalue: +extern "C" void test_pointer_const_lvalue() { + // CHECK: movl $42, [[DEST:.*]] + // CHECK: leaq [[DEST]], %rax + // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]]) + // CHECK: ret + int x = 42; + int * const xp = &x; + benchmark::DoNotOptimize(xp); +} + +// CHECK-LABEL: test_pointer_lvalue: +extern "C" void test_pointer_lvalue() { + // CHECK: movl $42, [[DEST:.*]] + // CHECK: leaq [[DEST]], %rax + // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]]) + // CHECK: ret + int x = 42; + int *xp = &x; + benchmark::DoNotOptimize(xp); +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_test.cc new file mode 100644 index 000000000..2ce92d1c7 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/donotoptimize_test.cc @@ -0,0 +1,52 @@ +#include "benchmark/benchmark.h" + +#include + +namespace { +#if defined(__GNUC__) +std::uint64_t double_up(const std::uint64_t x) __attribute__((const)); +#endif +std::uint64_t double_up(const std::uint64_t x) { return x * 2; } +} + +// Using DoNotOptimize on types like BitRef seem to cause a lot of problems +// with the inline assembly on both GCC and Clang. +struct BitRef { + int index; + unsigned char &byte; + +public: + static BitRef Make() { + static unsigned char arr[2] = {}; + BitRef b(1, arr[0]); + return b; + } +private: + BitRef(int i, unsigned char& b) : index(i), byte(b) {} +}; + +int main(int, char*[]) { + // this test verifies compilation of DoNotOptimize() for some types + + char buffer8[8] = ""; + benchmark::DoNotOptimize(buffer8); + + char buffer20[20] = ""; + benchmark::DoNotOptimize(buffer20); + + char buffer1024[1024] = ""; + benchmark::DoNotOptimize(buffer1024); + benchmark::DoNotOptimize(&buffer1024[0]); + + int x = 123; + benchmark::DoNotOptimize(x); + benchmark::DoNotOptimize(&x); + benchmark::DoNotOptimize(x += 42); + + benchmark::DoNotOptimize(double_up(x)); + + // These tests are to e + benchmark::DoNotOptimize(BitRef::Make()); + BitRef lval = BitRef::Make(); + benchmark::DoNotOptimize(lval); +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/filter_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/filter_test.cc new file mode 100644 index 000000000..0e27065c1 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/filter_test.cc @@ -0,0 +1,104 @@ +#include "benchmark/benchmark.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace { + +class TestReporter : public benchmark::ConsoleReporter { + public: + virtual bool ReportContext(const Context& context) { + return ConsoleReporter::ReportContext(context); + }; + + virtual void ReportRuns(const std::vector& report) { + ++count_; + ConsoleReporter::ReportRuns(report); + }; + + TestReporter() : count_(0) {} + + virtual ~TestReporter() {} + + size_t GetCount() const { return count_; } + + private: + mutable size_t count_; +}; + +} // end namespace + +static void NoPrefix(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(NoPrefix); + +static void BM_Foo(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_Foo); + +static void BM_Bar(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_Bar); + +static void BM_FooBar(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_FooBar); + +static void BM_FooBa(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_FooBa); + +int main(int argc, char **argv) { + bool list_only = false; + for (int i = 0; i < argc; ++i) + list_only |= std::string(argv[i]).find("--benchmark_list_tests") != + std::string::npos; + + benchmark::Initialize(&argc, argv); + + TestReporter test_reporter; + const size_t returned_count = + benchmark::RunSpecifiedBenchmarks(&test_reporter); + + if (argc == 2) { + // Make sure we ran all of the tests + std::stringstream ss(argv[1]); + size_t expected_return; + ss >> expected_return; + + if (returned_count != expected_return) { + std::cerr << "ERROR: Expected " << expected_return + << " tests to match the filter but returned_count = " + << returned_count << std::endl; + return -1; + } + + const size_t expected_reports = list_only ? 0 : expected_return; + const size_t reports_count = test_reporter.GetCount(); + if (reports_count != expected_reports) { + std::cerr << "ERROR: Expected " << expected_reports + << " tests to be run but reported_count = " << reports_count + << std::endl; + return -1; + } + } + + return 0; +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/fixture_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/fixture_test.cc new file mode 100644 index 000000000..1462b10f0 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/fixture_test.cc @@ -0,0 +1,49 @@ + +#include "benchmark/benchmark.h" + +#include +#include + +class MyFixture : public ::benchmark::Fixture { + public: + void SetUp(const ::benchmark::State& state) { + if (state.thread_index == 0) { + assert(data.get() == nullptr); + data.reset(new int(42)); + } + } + + void TearDown(const ::benchmark::State& state) { + if (state.thread_index == 0) { + assert(data.get() != nullptr); + data.reset(); + } + } + + ~MyFixture() { assert(data == nullptr); } + + std::unique_ptr data; +}; + +BENCHMARK_F(MyFixture, Foo)(benchmark::State &st) { + assert(data.get() != nullptr); + assert(*data == 42); + for (auto _ : st) { + } +} + +BENCHMARK_DEFINE_F(MyFixture, Bar)(benchmark::State& st) { + if (st.thread_index == 0) { + assert(data.get() != nullptr); + assert(*data == 42); + } + for (auto _ : st) { + assert(data.get() != nullptr); + assert(*data == 42); + } + st.SetItemsProcessed(st.range(0)); +} +BENCHMARK_REGISTER_F(MyFixture, Bar)->Arg(42); +BENCHMARK_REGISTER_F(MyFixture, Bar)->Arg(42)->ThreadPerCpu(); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/internal_threading_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/internal_threading_test.cc new file mode 100644 index 000000000..039d7c14a --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/internal_threading_test.cc @@ -0,0 +1,184 @@ + +#undef NDEBUG + +#include +#include +#include "../src/timers.h" +#include "benchmark/benchmark.h" +#include "output_test.h" + +static const std::chrono::duration time_frame(50); +static const double time_frame_in_sec( + std::chrono::duration_cast>>( + time_frame) + .count()); + +void MyBusySpinwait() { + const auto start = benchmark::ChronoClockNow(); + + while (true) { + const auto now = benchmark::ChronoClockNow(); + const auto elapsed = now - start; + + if (std::chrono::duration(elapsed) >= + time_frame) + return; + } +} + +// ========================================================================= // +// --------------------------- TEST CASES BEGIN ---------------------------- // +// ========================================================================= // + +// ========================================================================= // +// BM_MainThread + +void BM_MainThread(benchmark::State& state) { + for (auto _ : state) { + MyBusySpinwait(); + state.SetIterationTime(time_frame_in_sec); + } + state.counters["invtime"] = + benchmark::Counter{1, benchmark::Counter::kIsRate}; +} + +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(1); +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(1)->UseRealTime(); +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(1)->UseManualTime(); +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(1)->MeasureProcessCPUTime(); +BENCHMARK(BM_MainThread) + ->Iterations(1) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_MainThread) + ->Iterations(1) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(2); +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(2)->UseRealTime(); +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(2)->UseManualTime(); +BENCHMARK(BM_MainThread)->Iterations(1)->Threads(2)->MeasureProcessCPUTime(); +BENCHMARK(BM_MainThread) + ->Iterations(1) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_MainThread) + ->Iterations(1) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +// ========================================================================= // +// BM_WorkerThread + +void BM_WorkerThread(benchmark::State& state) { + for (auto _ : state) { + std::thread Worker(&MyBusySpinwait); + Worker.join(); + state.SetIterationTime(time_frame_in_sec); + } + state.counters["invtime"] = + benchmark::Counter{1, benchmark::Counter::kIsRate}; +} + +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(1); +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(1)->UseRealTime(); +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(1)->UseManualTime(); +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(1)->MeasureProcessCPUTime(); +BENCHMARK(BM_WorkerThread) + ->Iterations(1) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_WorkerThread) + ->Iterations(1) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(2); +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(2)->UseRealTime(); +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(2)->UseManualTime(); +BENCHMARK(BM_WorkerThread)->Iterations(1)->Threads(2)->MeasureProcessCPUTime(); +BENCHMARK(BM_WorkerThread) + ->Iterations(1) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_WorkerThread) + ->Iterations(1) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +// ========================================================================= // +// BM_MainThreadAndWorkerThread + +void BM_MainThreadAndWorkerThread(benchmark::State& state) { + for (auto _ : state) { + std::thread Worker(&MyBusySpinwait); + MyBusySpinwait(); + Worker.join(); + state.SetIterationTime(time_frame_in_sec); + } + state.counters["invtime"] = + benchmark::Counter{1, benchmark::Counter::kIsRate}; +} + +BENCHMARK(BM_MainThreadAndWorkerThread)->Iterations(1)->Threads(1); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(1) + ->UseRealTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(1) + ->UseManualTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(1) + ->MeasureProcessCPUTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +BENCHMARK(BM_MainThreadAndWorkerThread)->Iterations(1)->Threads(2); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(2) + ->UseRealTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(2) + ->UseManualTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(2) + ->MeasureProcessCPUTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_MainThreadAndWorkerThread) + ->Iterations(1) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +// ========================================================================= // +// ---------------------------- TEST CASES END ----------------------------- // +// ========================================================================= // + +int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/link_main_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/link_main_test.cc new file mode 100644 index 000000000..241ad5c39 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/link_main_test.cc @@ -0,0 +1,8 @@ +#include "benchmark/benchmark.h" + +void BM_empty(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(state.iterations()); + } +} +BENCHMARK(BM_empty); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/map_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/map_test.cc new file mode 100644 index 000000000..dbf7982a3 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/map_test.cc @@ -0,0 +1,57 @@ +#include "benchmark/benchmark.h" + +#include +#include + +namespace { + +std::map ConstructRandomMap(int size) { + std::map m; + for (int i = 0; i < size; ++i) { + m.insert(std::make_pair(std::rand() % size, std::rand() % size)); + } + return m; +} + +} // namespace + +// Basic version. +static void BM_MapLookup(benchmark::State& state) { + const int size = static_cast(state.range(0)); + std::map m; + for (auto _ : state) { + state.PauseTiming(); + m = ConstructRandomMap(size); + state.ResumeTiming(); + for (int i = 0; i < size; ++i) { + benchmark::DoNotOptimize(m.find(std::rand() % size)); + } + } + state.SetItemsProcessed(state.iterations() * size); +} +BENCHMARK(BM_MapLookup)->Range(1 << 3, 1 << 12); + +// Using fixtures. +class MapFixture : public ::benchmark::Fixture { + public: + void SetUp(const ::benchmark::State& st) { + m = ConstructRandomMap(static_cast(st.range(0))); + } + + void TearDown(const ::benchmark::State&) { m.clear(); } + + std::map m; +}; + +BENCHMARK_DEFINE_F(MapFixture, Lookup)(benchmark::State& state) { + const int size = static_cast(state.range(0)); + for (auto _ : state) { + for (int i = 0; i < size; ++i) { + benchmark::DoNotOptimize(m.find(std::rand() % size)); + } + } + state.SetItemsProcessed(state.iterations() * size); +} +BENCHMARK_REGISTER_F(MapFixture, Lookup)->Range(1 << 3, 1 << 12); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/memory_manager_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/memory_manager_test.cc new file mode 100644 index 000000000..90bed16cf --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/memory_manager_test.cc @@ -0,0 +1,44 @@ +#include + +#include "../src/check.h" +#include "benchmark/benchmark.h" +#include "output_test.h" + +class TestMemoryManager : public benchmark::MemoryManager { + void Start() {} + void Stop(Result* result) { + result->num_allocs = 42; + result->max_bytes_used = 42000; + } +}; + +void BM_empty(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(state.iterations()); + } +} +BENCHMARK(BM_empty); + +ADD_CASES(TC_ConsoleOut, {{"^BM_empty %console_report$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"}, + {"\"run_name\": \"BM_empty\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"allocs_per_iter\": %float,$", MR_Next}, + {"\"max_bytes_used\": 42000$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_empty\",%csv_report$"}}); + +int main(int argc, char* argv[]) { + std::unique_ptr mm(new TestMemoryManager()); + + benchmark::RegisterMemoryManager(mm.get()); + RunOutputTests(argc, argv); + benchmark::RegisterMemoryManager(nullptr); +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/multiple_ranges_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/multiple_ranges_test.cc new file mode 100644 index 000000000..b25f40eb5 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/multiple_ranges_test.cc @@ -0,0 +1,96 @@ +#include "benchmark/benchmark.h" + +#include +#include +#include +#include + +class MultipleRangesFixture : public ::benchmark::Fixture { + public: + MultipleRangesFixture() + : expectedValues({{1, 3, 5}, + {1, 3, 8}, + {1, 3, 15}, + {2, 3, 5}, + {2, 3, 8}, + {2, 3, 15}, + {1, 4, 5}, + {1, 4, 8}, + {1, 4, 15}, + {2, 4, 5}, + {2, 4, 8}, + {2, 4, 15}, + {1, 7, 5}, + {1, 7, 8}, + {1, 7, 15}, + {2, 7, 5}, + {2, 7, 8}, + {2, 7, 15}, + {7, 6, 3}}) {} + + void SetUp(const ::benchmark::State& state) { + std::vector ranges = {state.range(0), state.range(1), + state.range(2)}; + + assert(expectedValues.find(ranges) != expectedValues.end()); + + actualValues.insert(ranges); + } + + // NOTE: This is not TearDown as we want to check after _all_ runs are + // complete. + virtual ~MultipleRangesFixture() { + if (actualValues != expectedValues) { + std::cout << "EXPECTED\n"; + for (auto v : expectedValues) { + std::cout << "{"; + for (int64_t iv : v) { + std::cout << iv << ", "; + } + std::cout << "}\n"; + } + std::cout << "ACTUAL\n"; + for (auto v : actualValues) { + std::cout << "{"; + for (int64_t iv : v) { + std::cout << iv << ", "; + } + std::cout << "}\n"; + } + } + } + + std::set> expectedValues; + std::set> actualValues; +}; + +BENCHMARK_DEFINE_F(MultipleRangesFixture, Empty)(benchmark::State& state) { + for (auto _ : state) { + int64_t product = state.range(0) * state.range(1) * state.range(2); + for (int64_t x = 0; x < product; x++) { + benchmark::DoNotOptimize(x); + } + } +} + +BENCHMARK_REGISTER_F(MultipleRangesFixture, Empty) + ->RangeMultiplier(2) + ->Ranges({{1, 2}, {3, 7}, {5, 15}}) + ->Args({7, 6, 3}); + +void BM_CheckDefaultArgument(benchmark::State& state) { + // Test that the 'range()' without an argument is the same as 'range(0)'. + assert(state.range() == state.range(0)); + assert(state.range() != state.range(1)); + for (auto _ : state) { + } +} +BENCHMARK(BM_CheckDefaultArgument)->Ranges({{1, 5}, {6, 10}}); + +static void BM_MultipleRanges(benchmark::State& st) { + for (auto _ : st) { + } +} +BENCHMARK(BM_MultipleRanges)->Ranges({{5, 5}, {6, 6}}); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/options_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/options_test.cc new file mode 100644 index 000000000..7bfc23546 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/options_test.cc @@ -0,0 +1,75 @@ +#include "benchmark/benchmark.h" +#include +#include + +#if defined(NDEBUG) +#undef NDEBUG +#endif +#include + +void BM_basic(benchmark::State& state) { + for (auto _ : state) { + } +} + +void BM_basic_slow(benchmark::State& state) { + std::chrono::milliseconds sleep_duration(state.range(0)); + for (auto _ : state) { + std::this_thread::sleep_for( + std::chrono::duration_cast(sleep_duration)); + } +} + +BENCHMARK(BM_basic); +BENCHMARK(BM_basic)->Arg(42); +BENCHMARK(BM_basic_slow)->Arg(10)->Unit(benchmark::kNanosecond); +BENCHMARK(BM_basic_slow)->Arg(100)->Unit(benchmark::kMicrosecond); +BENCHMARK(BM_basic_slow)->Arg(1000)->Unit(benchmark::kMillisecond); +BENCHMARK(BM_basic)->Range(1, 8); +BENCHMARK(BM_basic)->RangeMultiplier(2)->Range(1, 8); +BENCHMARK(BM_basic)->DenseRange(10, 15); +BENCHMARK(BM_basic)->Args({42, 42}); +BENCHMARK(BM_basic)->Ranges({{64, 512}, {64, 512}}); +BENCHMARK(BM_basic)->MinTime(0.7); +BENCHMARK(BM_basic)->UseRealTime(); +BENCHMARK(BM_basic)->ThreadRange(2, 4); +BENCHMARK(BM_basic)->ThreadPerCpu(); +BENCHMARK(BM_basic)->Repetitions(3); +BENCHMARK(BM_basic) + ->RangeMultiplier(std::numeric_limits::max()) + ->Range(std::numeric_limits::min(), + std::numeric_limits::max()); + +// Negative ranges +BENCHMARK(BM_basic)->Range(-64, -1); +BENCHMARK(BM_basic)->RangeMultiplier(4)->Range(-8, 8); +BENCHMARK(BM_basic)->DenseRange(-2, 2, 1); +BENCHMARK(BM_basic)->Ranges({{-64, 1}, {-8, -1}}); + +void CustomArgs(benchmark::internal::Benchmark* b) { + for (int i = 0; i < 10; ++i) { + b->Arg(i); + } +} + +BENCHMARK(BM_basic)->Apply(CustomArgs); + +void BM_explicit_iteration_count(benchmark::State& state) { + // Test that benchmarks specified with an explicit iteration count are + // only run once. + static bool invoked_before = false; + assert(!invoked_before); + invoked_before = true; + + // Test that the requested iteration count is respected. + assert(state.max_iterations == 42); + size_t actual_iterations = 0; + for (auto _ : state) + ++actual_iterations; + assert(state.iterations() == state.max_iterations); + assert(state.iterations() == 42); + +} +BENCHMARK(BM_explicit_iteration_count)->Iterations(42); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test.h b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test.h new file mode 100644 index 000000000..9385761b2 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test.h @@ -0,0 +1,213 @@ +#ifndef TEST_OUTPUT_TEST_H +#define TEST_OUTPUT_TEST_H + +#undef NDEBUG +#include +#include +#include +#include +#include +#include +#include + +#include "../src/re.h" +#include "benchmark/benchmark.h" + +#define CONCAT2(x, y) x##y +#define CONCAT(x, y) CONCAT2(x, y) + +#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = ::AddCases(__VA_ARGS__) + +#define SET_SUBSTITUTIONS(...) \ + int CONCAT(dummy, __LINE__) = ::SetSubstitutions(__VA_ARGS__) + +enum MatchRules { + MR_Default, // Skip non-matching lines until a match is found. + MR_Next, // Match must occur on the next line. + MR_Not // No line between the current position and the next match matches + // the regex +}; + +struct TestCase { + TestCase(std::string re, int rule = MR_Default); + + std::string regex_str; + int match_rule; + std::string substituted_regex; + std::shared_ptr regex; +}; + +enum TestCaseID { + TC_ConsoleOut, + TC_ConsoleErr, + TC_JSONOut, + TC_JSONErr, + TC_CSVOut, + TC_CSVErr, + + TC_NumID // PRIVATE +}; + +// Add a list of test cases to be run against the output specified by +// 'ID' +int AddCases(TestCaseID ID, std::initializer_list il); + +// Add or set a list of substitutions to be performed on constructed regex's +// See 'output_test_helper.cc' for a list of default substitutions. +int SetSubstitutions( + std::initializer_list> il); + +// Run all output tests. +void RunOutputTests(int argc, char* argv[]); + +// Count the number of 'pat' substrings in the 'haystack' string. +int SubstrCnt(const std::string& haystack, const std::string& pat); + +// Run registered benchmarks with file reporter enabled, and return the content +// outputted by the file reporter. +std::string GetFileReporterOutput(int argc, char* argv[]); + +// ========================================================================= // +// ------------------------- Results checking ------------------------------ // +// ========================================================================= // + +// Call this macro to register a benchmark for checking its results. This +// should be all that's needed. It subscribes a function to check the (CSV) +// results of a benchmark. This is done only after verifying that the output +// strings are really as expected. +// bm_name_pattern: a name or a regex pattern which will be matched against +// all the benchmark names. Matching benchmarks +// will be the subject of a call to checker_function +// checker_function: should be of type ResultsCheckFn (see below) +#define CHECK_BENCHMARK_RESULTS(bm_name_pattern, checker_function) \ + size_t CONCAT(dummy, __LINE__) = AddChecker(bm_name_pattern, checker_function) + +struct Results; +typedef std::function ResultsCheckFn; + +size_t AddChecker(const char* bm_name_pattern, ResultsCheckFn fn); + +// Class holding the results of a benchmark. +// It is passed in calls to checker functions. +struct Results { + // the benchmark name + std::string name; + // the benchmark fields + std::map values; + + Results(const std::string& n) : name(n) {} + + int NumThreads() const; + + double NumIterations() const; + + typedef enum { kCpuTime, kRealTime } BenchmarkTime; + + // get cpu_time or real_time in seconds + double GetTime(BenchmarkTime which) const; + + // get the real_time duration of the benchmark in seconds. + // it is better to use fuzzy float checks for this, as the float + // ASCII formatting is lossy. + double DurationRealTime() const { + return NumIterations() * GetTime(kRealTime); + } + // get the cpu_time duration of the benchmark in seconds + double DurationCPUTime() const { + return NumIterations() * GetTime(kCpuTime); + } + + // get the string for a result by name, or nullptr if the name + // is not found + const std::string* Get(const char* entry_name) const { + auto it = values.find(entry_name); + if (it == values.end()) return nullptr; + return &it->second; + } + + // get a result by name, parsed as a specific type. + // NOTE: for counters, use GetCounterAs instead. + template + T GetAs(const char* entry_name) const; + + // counters are written as doubles, so they have to be read first + // as a double, and only then converted to the asked type. + template + T GetCounterAs(const char* entry_name) const { + double dval = GetAs(entry_name); + T tval = static_cast(dval); + return tval; + } +}; + +template +T Results::GetAs(const char* entry_name) const { + auto* sv = Get(entry_name); + CHECK(sv != nullptr && !sv->empty()); + std::stringstream ss; + ss << *sv; + T out; + ss >> out; + CHECK(!ss.fail()); + return out; +} + +//---------------------------------- +// Macros to help in result checking. Do not use them with arguments causing +// side-effects. + +// clang-format off + +#define _CHECK_RESULT_VALUE(entry, getfn, var_type, var_name, relationship, value) \ + CONCAT(CHECK_, relationship) \ + (entry.getfn< var_type >(var_name), (value)) << "\n" \ + << __FILE__ << ":" << __LINE__ << ": " << (entry).name << ":\n" \ + << __FILE__ << ":" << __LINE__ << ": " \ + << "expected (" << #var_type << ")" << (var_name) \ + << "=" << (entry).getfn< var_type >(var_name) \ + << " to be " #relationship " to " << (value) << "\n" + +// check with tolerance. eps_factor is the tolerance window, which is +// interpreted relative to value (eg, 0.1 means 10% of value). +#define _CHECK_FLOAT_RESULT_VALUE(entry, getfn, var_type, var_name, relationship, value, eps_factor) \ + CONCAT(CHECK_FLOAT_, relationship) \ + (entry.getfn< var_type >(var_name), (value), (eps_factor) * (value)) << "\n" \ + << __FILE__ << ":" << __LINE__ << ": " << (entry).name << ":\n" \ + << __FILE__ << ":" << __LINE__ << ": " \ + << "expected (" << #var_type << ")" << (var_name) \ + << "=" << (entry).getfn< var_type >(var_name) \ + << " to be " #relationship " to " << (value) << "\n" \ + << __FILE__ << ":" << __LINE__ << ": " \ + << "with tolerance of " << (eps_factor) * (value) \ + << " (" << (eps_factor)*100. << "%), " \ + << "but delta was " << ((entry).getfn< var_type >(var_name) - (value)) \ + << " (" << (((entry).getfn< var_type >(var_name) - (value)) \ + / \ + ((value) > 1.e-5 || value < -1.e-5 ? value : 1.e-5)*100.) \ + << "%)" + +#define CHECK_RESULT_VALUE(entry, var_type, var_name, relationship, value) \ + _CHECK_RESULT_VALUE(entry, GetAs, var_type, var_name, relationship, value) + +#define CHECK_COUNTER_VALUE(entry, var_type, var_name, relationship, value) \ + _CHECK_RESULT_VALUE(entry, GetCounterAs, var_type, var_name, relationship, value) + +#define CHECK_FLOAT_RESULT_VALUE(entry, var_name, relationship, value, eps_factor) \ + _CHECK_FLOAT_RESULT_VALUE(entry, GetAs, double, var_name, relationship, value, eps_factor) + +#define CHECK_FLOAT_COUNTER_VALUE(entry, var_name, relationship, value, eps_factor) \ + _CHECK_FLOAT_RESULT_VALUE(entry, GetCounterAs, double, var_name, relationship, value, eps_factor) + +// clang-format on + +// ========================================================================= // +// --------------------------- Misc Utilities ------------------------------ // +// ========================================================================= // + +namespace { + +const char* const dec_re = "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"; + +} // end namespace + +#endif // TEST_OUTPUT_TEST_H diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test_helper.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test_helper.cc new file mode 100644 index 000000000..5dc951d2b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/output_test_helper.cc @@ -0,0 +1,505 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../src/benchmark_api_internal.h" +#include "../src/check.h" // NOTE: check.h is for internal use only! +#include "../src/re.h" // NOTE: re.h is for internal use only +#include "output_test.h" + +// ========================================================================= // +// ------------------------------ Internals -------------------------------- // +// ========================================================================= // +namespace internal { +namespace { + +using TestCaseList = std::vector; + +// Use a vector because the order elements are added matters during iteration. +// std::map/unordered_map don't guarantee that. +// For example: +// SetSubstitutions({{"%HelloWorld", "Hello"}, {"%Hello", "Hi"}}); +// Substitute("%HelloWorld") // Always expands to Hello. +using SubMap = std::vector>; + +TestCaseList& GetTestCaseList(TestCaseID ID) { + // Uses function-local statics to ensure initialization occurs + // before first use. + static TestCaseList lists[TC_NumID]; + return lists[ID]; +} + +SubMap& GetSubstitutions() { + // Don't use 'dec_re' from header because it may not yet be initialized. + // clang-format off + static std::string safe_dec_re = "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"; + static std::string time_re = "([0-9]+[.])?[0-9]+"; + static SubMap map = { + {"%float", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"}, + // human-readable float + {"%hrfloat", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?[kMGTPEZYmunpfazy]?"}, + {"%int", "[ ]*[0-9]+"}, + {" %s ", "[ ]+"}, + {"%time", "[ ]*" + time_re + "[ ]+ns"}, + {"%console_report", "[ ]*" + time_re + "[ ]+ns [ ]*" + time_re + "[ ]+ns [ ]*[0-9]+"}, + {"%console_time_only_report", "[ ]*" + time_re + "[ ]+ns [ ]*" + time_re + "[ ]+ns"}, + {"%console_us_report", "[ ]*" + time_re + "[ ]+us [ ]*" + time_re + "[ ]+us [ ]*[0-9]+"}, + {"%console_us_time_only_report", "[ ]*" + time_re + "[ ]+us [ ]*" + time_re + "[ ]+us"}, + {"%csv_header", + "name,iterations,real_time,cpu_time,time_unit,bytes_per_second," + "items_per_second,label,error_occurred,error_message"}, + {"%csv_report", "[0-9]+," + safe_dec_re + "," + safe_dec_re + ",ns,,,,,"}, + {"%csv_us_report", "[0-9]+," + safe_dec_re + "," + safe_dec_re + ",us,,,,,"}, + {"%csv_bytes_report", + "[0-9]+," + safe_dec_re + "," + safe_dec_re + ",ns," + safe_dec_re + ",,,,"}, + {"%csv_items_report", + "[0-9]+," + safe_dec_re + "," + safe_dec_re + ",ns,," + safe_dec_re + ",,,"}, + {"%csv_bytes_items_report", + "[0-9]+," + safe_dec_re + "," + safe_dec_re + ",ns," + safe_dec_re + + "," + safe_dec_re + ",,,"}, + {"%csv_label_report_begin", "[0-9]+," + safe_dec_re + "," + safe_dec_re + ",ns,,,"}, + {"%csv_label_report_end", ",,"}}; + // clang-format on + return map; +} + +std::string PerformSubstitutions(std::string source) { + SubMap const& subs = GetSubstitutions(); + using SizeT = std::string::size_type; + for (auto const& KV : subs) { + SizeT pos; + SizeT next_start = 0; + while ((pos = source.find(KV.first, next_start)) != std::string::npos) { + next_start = pos + KV.second.size(); + source.replace(pos, KV.first.size(), KV.second); + } + } + return source; +} + +void CheckCase(std::stringstream& remaining_output, TestCase const& TC, + TestCaseList const& not_checks) { + std::string first_line; + bool on_first = true; + std::string line; + while (remaining_output.eof() == false) { + CHECK(remaining_output.good()); + std::getline(remaining_output, line); + if (on_first) { + first_line = line; + on_first = false; + } + for (const auto& NC : not_checks) { + CHECK(!NC.regex->Match(line)) + << "Unexpected match for line \"" << line << "\" for MR_Not regex \"" + << NC.regex_str << "\"" + << "\n actual regex string \"" << TC.substituted_regex << "\"" + << "\n started matching near: " << first_line; + } + if (TC.regex->Match(line)) return; + CHECK(TC.match_rule != MR_Next) + << "Expected line \"" << line << "\" to match regex \"" << TC.regex_str + << "\"" + << "\n actual regex string \"" << TC.substituted_regex << "\"" + << "\n started matching near: " << first_line; + } + CHECK(remaining_output.eof() == false) + << "End of output reached before match for regex \"" << TC.regex_str + << "\" was found" + << "\n actual regex string \"" << TC.substituted_regex << "\"" + << "\n started matching near: " << first_line; +} + +void CheckCases(TestCaseList const& checks, std::stringstream& output) { + std::vector not_checks; + for (size_t i = 0; i < checks.size(); ++i) { + const auto& TC = checks[i]; + if (TC.match_rule == MR_Not) { + not_checks.push_back(TC); + continue; + } + CheckCase(output, TC, not_checks); + not_checks.clear(); + } +} + +class TestReporter : public benchmark::BenchmarkReporter { + public: + TestReporter(std::vector reps) + : reporters_(reps) {} + + virtual bool ReportContext(const Context& context) { + bool last_ret = false; + bool first = true; + for (auto rep : reporters_) { + bool new_ret = rep->ReportContext(context); + CHECK(first || new_ret == last_ret) + << "Reports return different values for ReportContext"; + first = false; + last_ret = new_ret; + } + (void)first; + return last_ret; + } + + void ReportRuns(const std::vector& report) { + for (auto rep : reporters_) rep->ReportRuns(report); + } + void Finalize() { + for (auto rep : reporters_) rep->Finalize(); + } + + private: + std::vector reporters_; +}; +} // namespace + +} // end namespace internal + +// ========================================================================= // +// -------------------------- Results checking ----------------------------- // +// ========================================================================= // + +namespace internal { + +// Utility class to manage subscribers for checking benchmark results. +// It works by parsing the CSV output to read the results. +class ResultsChecker { + public: + struct PatternAndFn : public TestCase { // reusing TestCase for its regexes + PatternAndFn(const std::string& rx, ResultsCheckFn fn_) + : TestCase(rx), fn(fn_) {} + ResultsCheckFn fn; + }; + + std::vector check_patterns; + std::vector results; + std::vector field_names; + + void Add(const std::string& entry_pattern, ResultsCheckFn fn); + + void CheckResults(std::stringstream& output); + + private: + void SetHeader_(const std::string& csv_header); + void SetValues_(const std::string& entry_csv_line); + + std::vector SplitCsv_(const std::string& line); +}; + +// store the static ResultsChecker in a function to prevent initialization +// order problems +ResultsChecker& GetResultsChecker() { + static ResultsChecker rc; + return rc; +} + +// add a results checker for a benchmark +void ResultsChecker::Add(const std::string& entry_pattern, ResultsCheckFn fn) { + check_patterns.emplace_back(entry_pattern, fn); +} + +// check the results of all subscribed benchmarks +void ResultsChecker::CheckResults(std::stringstream& output) { + // first reset the stream to the start + { + auto start = std::stringstream::pos_type(0); + // clear before calling tellg() + output.clear(); + // seek to zero only when needed + if (output.tellg() > start) output.seekg(start); + // and just in case + output.clear(); + } + // now go over every line and publish it to the ResultsChecker + std::string line; + bool on_first = true; + while (output.eof() == false) { + CHECK(output.good()); + std::getline(output, line); + if (on_first) { + SetHeader_(line); // this is important + on_first = false; + continue; + } + SetValues_(line); + } + // finally we can call the subscribed check functions + for (const auto& p : check_patterns) { + VLOG(2) << "--------------------------------\n"; + VLOG(2) << "checking for benchmarks matching " << p.regex_str << "...\n"; + for (const auto& r : results) { + if (!p.regex->Match(r.name)) { + VLOG(2) << p.regex_str << " is not matched by " << r.name << "\n"; + continue; + } else { + VLOG(2) << p.regex_str << " is matched by " << r.name << "\n"; + } + VLOG(1) << "Checking results of " << r.name << ": ... \n"; + p.fn(r); + VLOG(1) << "Checking results of " << r.name << ": OK.\n"; + } + } +} + +// prepare for the names in this header +void ResultsChecker::SetHeader_(const std::string& csv_header) { + field_names = SplitCsv_(csv_header); +} + +// set the values for a benchmark +void ResultsChecker::SetValues_(const std::string& entry_csv_line) { + if (entry_csv_line.empty()) return; // some lines are empty + CHECK(!field_names.empty()); + auto vals = SplitCsv_(entry_csv_line); + CHECK_EQ(vals.size(), field_names.size()); + results.emplace_back(vals[0]); // vals[0] is the benchmark name + auto& entry = results.back(); + for (size_t i = 1, e = vals.size(); i < e; ++i) { + entry.values[field_names[i]] = vals[i]; + } +} + +// a quick'n'dirty csv splitter (eliminating quotes) +std::vector ResultsChecker::SplitCsv_(const std::string& line) { + std::vector out; + if (line.empty()) return out; + if (!field_names.empty()) out.reserve(field_names.size()); + size_t prev = 0, pos = line.find_first_of(','), curr = pos; + while (pos != line.npos) { + CHECK(curr > 0); + if (line[prev] == '"') ++prev; + if (line[curr - 1] == '"') --curr; + out.push_back(line.substr(prev, curr - prev)); + prev = pos + 1; + pos = line.find_first_of(',', pos + 1); + curr = pos; + } + curr = line.size(); + if (line[prev] == '"') ++prev; + if (line[curr - 1] == '"') --curr; + out.push_back(line.substr(prev, curr - prev)); + return out; +} + +} // end namespace internal + +size_t AddChecker(const char* bm_name, ResultsCheckFn fn) { + auto& rc = internal::GetResultsChecker(); + rc.Add(bm_name, fn); + return rc.results.size(); +} + +int Results::NumThreads() const { + auto pos = name.find("/threads:"); + if (pos == name.npos) return 1; + auto end = name.find('/', pos + 9); + std::stringstream ss; + ss << name.substr(pos + 9, end); + int num = 1; + ss >> num; + CHECK(!ss.fail()); + return num; +} + +double Results::NumIterations() const { + return GetAs("iterations"); +} + +double Results::GetTime(BenchmarkTime which) const { + CHECK(which == kCpuTime || which == kRealTime); + const char* which_str = which == kCpuTime ? "cpu_time" : "real_time"; + double val = GetAs(which_str); + auto unit = Get("time_unit"); + CHECK(unit); + if (*unit == "ns") { + return val * 1.e-9; + } else if (*unit == "us") { + return val * 1.e-6; + } else if (*unit == "ms") { + return val * 1.e-3; + } else if (*unit == "s") { + return val; + } else { + CHECK(1 == 0) << "unknown time unit: " << *unit; + return 0; + } +} + +// ========================================================================= // +// -------------------------- Public API Definitions------------------------ // +// ========================================================================= // + +TestCase::TestCase(std::string re, int rule) + : regex_str(std::move(re)), + match_rule(rule), + substituted_regex(internal::PerformSubstitutions(regex_str)), + regex(std::make_shared()) { + std::string err_str; + regex->Init(substituted_regex, &err_str); + CHECK(err_str.empty()) << "Could not construct regex \"" << substituted_regex + << "\"" + << "\n originally \"" << regex_str << "\"" + << "\n got error: " << err_str; +} + +int AddCases(TestCaseID ID, std::initializer_list il) { + auto& L = internal::GetTestCaseList(ID); + L.insert(L.end(), il); + return 0; +} + +int SetSubstitutions( + std::initializer_list> il) { + auto& subs = internal::GetSubstitutions(); + for (auto KV : il) { + bool exists = false; + KV.second = internal::PerformSubstitutions(KV.second); + for (auto& EKV : subs) { + if (EKV.first == KV.first) { + EKV.second = std::move(KV.second); + exists = true; + break; + } + } + if (!exists) subs.push_back(std::move(KV)); + } + return 0; +} + +void RunOutputTests(int argc, char* argv[]) { + using internal::GetTestCaseList; + benchmark::Initialize(&argc, argv); + auto options = benchmark::internal::GetOutputOptions(/*force_no_color*/ true); + benchmark::ConsoleReporter CR(options); + benchmark::JSONReporter JR; + benchmark::CSVReporter CSVR; + struct ReporterTest { + const char* name; + std::vector& output_cases; + std::vector& error_cases; + benchmark::BenchmarkReporter& reporter; + std::stringstream out_stream; + std::stringstream err_stream; + + ReporterTest(const char* n, std::vector& out_tc, + std::vector& err_tc, + benchmark::BenchmarkReporter& br) + : name(n), output_cases(out_tc), error_cases(err_tc), reporter(br) { + reporter.SetOutputStream(&out_stream); + reporter.SetErrorStream(&err_stream); + } + } TestCases[] = { + {"ConsoleReporter", GetTestCaseList(TC_ConsoleOut), + GetTestCaseList(TC_ConsoleErr), CR}, + {"JSONReporter", GetTestCaseList(TC_JSONOut), GetTestCaseList(TC_JSONErr), + JR}, + {"CSVReporter", GetTestCaseList(TC_CSVOut), GetTestCaseList(TC_CSVErr), + CSVR}, + }; + + // Create the test reporter and run the benchmarks. + std::cout << "Running benchmarks...\n"; + internal::TestReporter test_rep({&CR, &JR, &CSVR}); + benchmark::RunSpecifiedBenchmarks(&test_rep); + + for (auto& rep_test : TestCases) { + std::string msg = std::string("\nTesting ") + rep_test.name + " Output\n"; + std::string banner(msg.size() - 1, '-'); + std::cout << banner << msg << banner << "\n"; + + std::cerr << rep_test.err_stream.str(); + std::cout << rep_test.out_stream.str(); + + internal::CheckCases(rep_test.error_cases, rep_test.err_stream); + internal::CheckCases(rep_test.output_cases, rep_test.out_stream); + + std::cout << "\n"; + } + + // now that we know the output is as expected, we can dispatch + // the checks to subscribees. + auto& csv = TestCases[2]; + // would use == but gcc spits a warning + CHECK(std::strcmp(csv.name, "CSVReporter") == 0); + internal::GetResultsChecker().CheckResults(csv.out_stream); +} + +int SubstrCnt(const std::string& haystack, const std::string& pat) { + if (pat.length() == 0) return 0; + int count = 0; + for (size_t offset = haystack.find(pat); offset != std::string::npos; + offset = haystack.find(pat, offset + pat.length())) + ++count; + return count; +} + +static char ToHex(int ch) { + return ch < 10 ? static_cast('0' + ch) + : static_cast('a' + (ch - 10)); +} + +static char RandomHexChar() { + static std::mt19937 rd{std::random_device{}()}; + static std::uniform_int_distribution mrand{0, 15}; + return ToHex(mrand(rd)); +} + +static std::string GetRandomFileName() { + std::string model = "test.%%%%%%"; + for (auto & ch : model) { + if (ch == '%') + ch = RandomHexChar(); + } + return model; +} + +static bool FileExists(std::string const& name) { + std::ifstream in(name.c_str()); + return in.good(); +} + +static std::string GetTempFileName() { + // This function attempts to avoid race conditions where two tests + // create the same file at the same time. However, it still introduces races + // similar to tmpnam. + int retries = 3; + while (--retries) { + std::string name = GetRandomFileName(); + if (!FileExists(name)) + return name; + } + std::cerr << "Failed to create unique temporary file name" << std::endl; + std::abort(); +} + +std::string GetFileReporterOutput(int argc, char* argv[]) { + std::vector new_argv(argv, argv + argc); + assert(static_cast(argc) == new_argv.size()); + + std::string tmp_file_name = GetTempFileName(); + std::cout << "Will be using this as the tmp file: " << tmp_file_name << '\n'; + + std::string tmp = "--benchmark_out="; + tmp += tmp_file_name; + new_argv.emplace_back(const_cast(tmp.c_str())); + + argc = int(new_argv.size()); + + benchmark::Initialize(&argc, new_argv.data()); + benchmark::RunSpecifiedBenchmarks(); + + // Read the output back from the file, and delete the file. + std::ifstream tmp_stream(tmp_file_name); + std::string output = std::string((std::istreambuf_iterator(tmp_stream)), + std::istreambuf_iterator()); + std::remove(tmp_file_name.c_str()); + + return output; +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/register_benchmark_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/register_benchmark_test.cc new file mode 100644 index 000000000..3ac5b21fb --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/register_benchmark_test.cc @@ -0,0 +1,184 @@ + +#undef NDEBUG +#include +#include + +#include "../src/check.h" // NOTE: check.h is for internal use only! +#include "benchmark/benchmark.h" + +namespace { + +class TestReporter : public benchmark::ConsoleReporter { + public: + virtual void ReportRuns(const std::vector& report) { + all_runs_.insert(all_runs_.end(), begin(report), end(report)); + ConsoleReporter::ReportRuns(report); + } + + std::vector all_runs_; +}; + +struct TestCase { + std::string name; + const char* label; + // Note: not explicit as we rely on it being converted through ADD_CASES. + TestCase(const char* xname) : TestCase(xname, nullptr) {} + TestCase(const char* xname, const char* xlabel) + : name(xname), label(xlabel) {} + + typedef benchmark::BenchmarkReporter::Run Run; + + void CheckRun(Run const& run) const { + // clang-format off + CHECK(name == run.benchmark_name()) << "expected " << name << " got " + << run.benchmark_name(); + if (label) { + CHECK(run.report_label == label) << "expected " << label << " got " + << run.report_label; + } else { + CHECK(run.report_label == ""); + } + // clang-format on + } +}; + +std::vector ExpectedResults; + +int AddCases(std::initializer_list const& v) { + for (auto N : v) { + ExpectedResults.push_back(N); + } + return 0; +} + +#define CONCAT(x, y) CONCAT2(x, y) +#define CONCAT2(x, y) x##y +#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__}) + +} // end namespace + +typedef benchmark::internal::Benchmark* ReturnVal; + +//----------------------------------------------------------------------------// +// Test RegisterBenchmark with no additional arguments +//----------------------------------------------------------------------------// +void BM_function(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_function); +ReturnVal dummy = benchmark::RegisterBenchmark( + "BM_function_manual_registration", BM_function); +ADD_CASES({"BM_function"}, {"BM_function_manual_registration"}); + +//----------------------------------------------------------------------------// +// Test RegisterBenchmark with additional arguments +// Note: GCC <= 4.8 do not support this form of RegisterBenchmark because they +// reject the variadic pack expansion of lambda captures. +//----------------------------------------------------------------------------// +#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK + +void BM_extra_args(benchmark::State& st, const char* label) { + for (auto _ : st) { + } + st.SetLabel(label); +} +int RegisterFromFunction() { + std::pair cases[] = { + {"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}}; + for (auto const& c : cases) + benchmark::RegisterBenchmark(c.first, &BM_extra_args, c.second); + return 0; +} +int dummy2 = RegisterFromFunction(); +ADD_CASES({"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}); + +#endif // BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK + +//----------------------------------------------------------------------------// +// Test RegisterBenchmark with different callable types +//----------------------------------------------------------------------------// + +struct CustomFixture { + void operator()(benchmark::State& st) { + for (auto _ : st) { + } + } +}; + +void TestRegistrationAtRuntime() { +#ifdef BENCHMARK_HAS_CXX11 + { + CustomFixture fx; + benchmark::RegisterBenchmark("custom_fixture", fx); + AddCases({"custom_fixture"}); + } +#endif +#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK + { + const char* x = "42"; + auto capturing_lam = [=](benchmark::State& st) { + for (auto _ : st) { + } + st.SetLabel(x); + }; + benchmark::RegisterBenchmark("lambda_benchmark", capturing_lam); + AddCases({{"lambda_benchmark", x}}); + } +#endif +} + +// Test that all benchmarks, registered at either during static init or runtime, +// are run and the results are passed to the reported. +void RunTestOne() { + TestRegistrationAtRuntime(); + + TestReporter test_reporter; + benchmark::RunSpecifiedBenchmarks(&test_reporter); + + typedef benchmark::BenchmarkReporter::Run Run; + auto EB = ExpectedResults.begin(); + + for (Run const& run : test_reporter.all_runs_) { + assert(EB != ExpectedResults.end()); + EB->CheckRun(run); + ++EB; + } + assert(EB == ExpectedResults.end()); +} + +// Test that ClearRegisteredBenchmarks() clears all previously registered +// benchmarks. +// Also test that new benchmarks can be registered and ran afterwards. +void RunTestTwo() { + assert(ExpectedResults.size() != 0 && + "must have at least one registered benchmark"); + ExpectedResults.clear(); + benchmark::ClearRegisteredBenchmarks(); + + TestReporter test_reporter; + size_t num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter); + assert(num_ran == 0); + assert(test_reporter.all_runs_.begin() == test_reporter.all_runs_.end()); + + TestRegistrationAtRuntime(); + num_ran = benchmark::RunSpecifiedBenchmarks(&test_reporter); + assert(num_ran == ExpectedResults.size()); + + typedef benchmark::BenchmarkReporter::Run Run; + auto EB = ExpectedResults.begin(); + + for (Run const& run : test_reporter.all_runs_) { + assert(EB != ExpectedResults.end()); + EB->CheckRun(run); + ++EB; + } + assert(EB == ExpectedResults.end()); +} + +int main(int argc, char* argv[]) { + benchmark::Initialize(&argc, argv); + + RunTestOne(); + RunTestTwo(); +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/report_aggregates_only_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/report_aggregates_only_test.cc new file mode 100644 index 000000000..9646b9be5 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/report_aggregates_only_test.cc @@ -0,0 +1,39 @@ + +#undef NDEBUG +#include +#include + +#include "benchmark/benchmark.h" +#include "output_test.h" + +// Ok this test is super ugly. We want to check what happens with the file +// reporter in the presence of ReportAggregatesOnly(). +// We do not care about console output, the normal tests check that already. + +void BM_SummaryRepeat(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->ReportAggregatesOnly(); + +int main(int argc, char* argv[]) { + const std::string output = GetFileReporterOutput(argc, argv); + + if (SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3") != 3 || + SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_mean\"") != 1 || + SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_median\"") != + 1 || + SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"") != + 1) { + std::cout << "Precondition mismatch. Expected to only find three " + "occurrences of \"BM_SummaryRepeat/repeats:3\" substring:\n" + "\"name\": \"BM_SummaryRepeat/repeats:3_mean\", " + "\"name\": \"BM_SummaryRepeat/repeats:3_median\", " + "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"\nThe entire " + "output:\n"; + std::cout << output; + return 1; + } + + return 0; +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/reporter_output_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/reporter_output_test.cc new file mode 100644 index 000000000..c8090d4ac --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/reporter_output_test.cc @@ -0,0 +1,742 @@ + +#undef NDEBUG +#include + +#include "benchmark/benchmark.h" +#include "output_test.h" + +// ========================================================================= // +// ---------------------- Testing Prologue Output -------------------------- // +// ========================================================================= // + +ADD_CASES(TC_ConsoleOut, {{"^[-]+$", MR_Next}, + {"^Benchmark %s Time %s CPU %s Iterations$", MR_Next}, + {"^[-]+$", MR_Next}}); +static int AddContextCases() { + AddCases(TC_ConsoleErr, + { + {"%int[-/]%int[-/]%int %int:%int:%int$", MR_Default}, + {"Running .*/reporter_output_test(\\.exe)?$", MR_Next}, + {"Run on \\(%int X %float MHz CPU s?\\)", MR_Next}, + }); + AddCases(TC_JSONOut, + {{"^\\{", MR_Default}, + {"\"context\":", MR_Next}, + {"\"date\": \"", MR_Next}, + {"\"host_name\":", MR_Next}, + {"\"executable\": \".*(/|\\\\)reporter_output_test(\\.exe)?\",", + MR_Next}, + {"\"num_cpus\": %int,$", MR_Next}, + {"\"mhz_per_cpu\": %float,$", MR_Next}, + {"\"cpu_scaling_enabled\": ", MR_Next}, + {"\"caches\": \\[$", MR_Next}}); + auto const& Info = benchmark::CPUInfo::Get(); + auto const& Caches = Info.caches; + if (!Caches.empty()) { + AddCases(TC_ConsoleErr, {{"CPU Caches:$", MR_Next}}); + } + for (size_t I = 0; I < Caches.size(); ++I) { + std::string num_caches_str = + Caches[I].num_sharing != 0 ? " \\(x%int\\)$" : "$"; + AddCases( + TC_ConsoleErr, + {{"L%int (Data|Instruction|Unified) %intK" + num_caches_str, MR_Next}}); + AddCases(TC_JSONOut, {{"\\{$", MR_Next}, + {"\"type\": \"", MR_Next}, + {"\"level\": %int,$", MR_Next}, + {"\"size\": %int,$", MR_Next}, + {"\"num_sharing\": %int$", MR_Next}, + {"}[,]{0,1}$", MR_Next}}); + } + AddCases(TC_JSONOut, {{"],$"}}); + auto const& LoadAvg = Info.load_avg; + if (!LoadAvg.empty()) { + AddCases(TC_ConsoleErr, + {{"Load Average: (%float, ){0,2}%float$", MR_Next}}); + } + AddCases(TC_JSONOut, {{"\"load_avg\": \\[(%float,?){0,3}],$", MR_Next}}); + return 0; +} +int dummy_register = AddContextCases(); +ADD_CASES(TC_CSVOut, {{"%csv_header"}}); + +// ========================================================================= // +// ------------------------ Testing Basic Output --------------------------- // +// ========================================================================= // + +void BM_basic(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_basic); + +ADD_CASES(TC_ConsoleOut, {{"^BM_basic %console_report$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_basic\",$"}, + {"\"run_name\": \"BM_basic\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\"$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_basic\",%csv_report$"}}); + +// ========================================================================= // +// ------------------------ Testing Bytes per Second Output ---------------- // +// ========================================================================= // + +void BM_bytes_per_second(benchmark::State& state) { + for (auto _ : state) { + } + state.SetBytesProcessed(1); +} +BENCHMARK(BM_bytes_per_second); + +ADD_CASES(TC_ConsoleOut, {{"^BM_bytes_per_second %console_report " + "bytes_per_second=%float[kM]{0,1}/s$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_bytes_per_second\",$"}, + {"\"run_name\": \"BM_bytes_per_second\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bytes_per_second\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_bytes_per_second\",%csv_bytes_report$"}}); + +// ========================================================================= // +// ------------------------ Testing Items per Second Output ---------------- // +// ========================================================================= // + +void BM_items_per_second(benchmark::State& state) { + for (auto _ : state) { + } + state.SetItemsProcessed(1); +} +BENCHMARK(BM_items_per_second); + +ADD_CASES(TC_ConsoleOut, {{"^BM_items_per_second %console_report " + "items_per_second=%float[kM]{0,1}/s$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_items_per_second\",$"}, + {"\"run_name\": \"BM_items_per_second\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"items_per_second\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_items_per_second\",%csv_items_report$"}}); + +// ========================================================================= // +// ------------------------ Testing Label Output --------------------------- // +// ========================================================================= // + +void BM_label(benchmark::State& state) { + for (auto _ : state) { + } + state.SetLabel("some label"); +} +BENCHMARK(BM_label); + +ADD_CASES(TC_ConsoleOut, {{"^BM_label %console_report some label$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_label\",$"}, + {"\"run_name\": \"BM_label\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"label\": \"some label\"$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_label\",%csv_label_report_begin\"some " + "label\"%csv_label_report_end$"}}); + +// ========================================================================= // +// ------------------------ Testing Error Output --------------------------- // +// ========================================================================= // + +void BM_error(benchmark::State& state) { + state.SkipWithError("message"); + for (auto _ : state) { + } +} +BENCHMARK(BM_error); +ADD_CASES(TC_ConsoleOut, {{"^BM_error[ ]+ERROR OCCURRED: 'message'$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_error\",$"}, + {"\"run_name\": \"BM_error\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"error_occurred\": true,$", MR_Next}, + {"\"error_message\": \"message\",$", MR_Next}}); + +ADD_CASES(TC_CSVOut, {{"^\"BM_error\",,,,,,,,true,\"message\"$"}}); + +// ========================================================================= // +// ------------------------ Testing No Arg Name Output ----------------------- +// // +// ========================================================================= // + +void BM_no_arg_name(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_no_arg_name)->Arg(3); +ADD_CASES(TC_ConsoleOut, {{"^BM_no_arg_name/3 %console_report$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_no_arg_name/3\",$"}, + {"\"run_name\": \"BM_no_arg_name/3\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_no_arg_name/3\",%csv_report$"}}); + +// ========================================================================= // +// ------------------------ Testing Arg Name Output ----------------------- // +// ========================================================================= // + +void BM_arg_name(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_arg_name)->ArgName("first")->Arg(3); +ADD_CASES(TC_ConsoleOut, {{"^BM_arg_name/first:3 %console_report$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_arg_name/first:3\",$"}, + {"\"run_name\": \"BM_arg_name/first:3\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_arg_name/first:3\",%csv_report$"}}); + +// ========================================================================= // +// ------------------------ Testing Arg Names Output ----------------------- // +// ========================================================================= // + +void BM_arg_names(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_arg_names)->Args({2, 5, 4})->ArgNames({"first", "", "third"}); +ADD_CASES(TC_ConsoleOut, + {{"^BM_arg_names/first:2/5/third:4 %console_report$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_arg_names/first:2/5/third:4\",$"}, + {"\"run_name\": \"BM_arg_names/first:2/5/third:4\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_arg_names/first:2/5/third:4\",%csv_report$"}}); + +// ========================================================================= // +// ------------------------ Testing Big Args Output ------------------------ // +// ========================================================================= // + +void BM_BigArgs(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_BigArgs)->RangeMultiplier(2)->Range(1U << 30U, 1U << 31U); +ADD_CASES(TC_ConsoleOut, {{"^BM_BigArgs/1073741824 %console_report$"}, + {"^BM_BigArgs/2147483648 %console_report$"}}); + +// ========================================================================= // +// ----------------------- Testing Complexity Output ----------------------- // +// ========================================================================= // + +void BM_Complexity_O1(benchmark::State& state) { + for (auto _ : state) { + } + state.SetComplexityN(state.range(0)); +} +BENCHMARK(BM_Complexity_O1)->Range(1, 1 << 18)->Complexity(benchmark::o1); +SET_SUBSTITUTIONS({{"%bigOStr", "[ ]* %float \\([0-9]+\\)"}, + {"%RMS", "[ ]*[0-9]+ %"}}); +ADD_CASES(TC_ConsoleOut, {{"^BM_Complexity_O1_BigO %bigOStr %bigOStr[ ]*$"}, + {"^BM_Complexity_O1_RMS %RMS %RMS[ ]*$"}}); + +// ========================================================================= // +// ----------------------- Testing Aggregate Output ------------------------ // +// ========================================================================= // + +// Test that non-aggregate data is printed by default +void BM_Repeat(benchmark::State& state) { + for (auto _ : state) { + } +} +// need two repetitions min to be able to output any aggregate output +BENCHMARK(BM_Repeat)->Repetitions(2); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Repeat/repeats:2 %console_report$"}, + {"^BM_Repeat/repeats:2 %console_report$"}, + {"^BM_Repeat/repeats:2_mean %console_time_only_report [ ]*2$"}, + {"^BM_Repeat/repeats:2_median %console_time_only_report [ ]*2$"}, + {"^BM_Repeat/repeats:2_stddev %console_time_only_report [ ]*2$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Repeat/repeats:2\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:2\"", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:2\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"repetition_index\": 1,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:2_mean\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:2_median\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:2_stddev\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:2\",%csv_report$"}, + {"^\"BM_Repeat/repeats:2\",%csv_report$"}, + {"^\"BM_Repeat/repeats:2_mean\",%csv_report$"}, + {"^\"BM_Repeat/repeats:2_median\",%csv_report$"}, + {"^\"BM_Repeat/repeats:2_stddev\",%csv_report$"}}); +// but for two repetitions, mean and median is the same, so let's repeat.. +BENCHMARK(BM_Repeat)->Repetitions(3); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Repeat/repeats:3 %console_report$"}, + {"^BM_Repeat/repeats:3 %console_report$"}, + {"^BM_Repeat/repeats:3 %console_report$"}, + {"^BM_Repeat/repeats:3_mean %console_time_only_report [ ]*3$"}, + {"^BM_Repeat/repeats:3_median %console_time_only_report [ ]*3$"}, + {"^BM_Repeat/repeats:3_stddev %console_time_only_report [ ]*3$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Repeat/repeats:3\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:3\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"repetition_index\": 1,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:3\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"repetition_index\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:3_mean\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:3_median\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:3_stddev\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:3\",%csv_report$"}, + {"^\"BM_Repeat/repeats:3\",%csv_report$"}, + {"^\"BM_Repeat/repeats:3\",%csv_report$"}, + {"^\"BM_Repeat/repeats:3_mean\",%csv_report$"}, + {"^\"BM_Repeat/repeats:3_median\",%csv_report$"}, + {"^\"BM_Repeat/repeats:3_stddev\",%csv_report$"}}); +// median differs between even/odd number of repetitions, so just to be sure +BENCHMARK(BM_Repeat)->Repetitions(4); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Repeat/repeats:4 %console_report$"}, + {"^BM_Repeat/repeats:4 %console_report$"}, + {"^BM_Repeat/repeats:4 %console_report$"}, + {"^BM_Repeat/repeats:4 %console_report$"}, + {"^BM_Repeat/repeats:4_mean %console_time_only_report [ ]*4$"}, + {"^BM_Repeat/repeats:4_median %console_time_only_report [ ]*4$"}, + {"^BM_Repeat/repeats:4_stddev %console_time_only_report [ ]*4$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Repeat/repeats:4\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 4,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:4\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 4,$", MR_Next}, + {"\"repetition_index\": 1,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:4\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 4,$", MR_Next}, + {"\"repetition_index\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:4\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 4,$", MR_Next}, + {"\"repetition_index\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:4_mean\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 4,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 4,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:4_median\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 4,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 4,$", MR_Next}, + {"\"name\": \"BM_Repeat/repeats:4_stddev\",$"}, + {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 4,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 4,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:4\",%csv_report$"}, + {"^\"BM_Repeat/repeats:4\",%csv_report$"}, + {"^\"BM_Repeat/repeats:4\",%csv_report$"}, + {"^\"BM_Repeat/repeats:4\",%csv_report$"}, + {"^\"BM_Repeat/repeats:4_mean\",%csv_report$"}, + {"^\"BM_Repeat/repeats:4_median\",%csv_report$"}, + {"^\"BM_Repeat/repeats:4_stddev\",%csv_report$"}}); + +// Test that a non-repeated test still prints non-aggregate results even when +// only-aggregate reports have been requested +void BM_RepeatOnce(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_RepeatOnce)->Repetitions(1)->ReportAggregatesOnly(); +ADD_CASES(TC_ConsoleOut, {{"^BM_RepeatOnce/repeats:1 %console_report$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_RepeatOnce/repeats:1\",$"}, + {"\"run_name\": \"BM_RepeatOnce/repeats:1\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_RepeatOnce/repeats:1\",%csv_report$"}}); + +// Test that non-aggregate data is not reported +void BM_SummaryRepeat(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->ReportAggregatesOnly(); +ADD_CASES( + TC_ConsoleOut, + {{".*BM_SummaryRepeat/repeats:3 ", MR_Not}, + {"^BM_SummaryRepeat/repeats:3_mean %console_time_only_report [ ]*3$"}, + {"^BM_SummaryRepeat/repeats:3_median %console_time_only_report [ ]*3$"}, + {"^BM_SummaryRepeat/repeats:3_stddev %console_time_only_report [ ]*3$"}}); +ADD_CASES(TC_JSONOut, + {{".*BM_SummaryRepeat/repeats:3 ", MR_Not}, + {"\"name\": \"BM_SummaryRepeat/repeats:3_mean\",$"}, + {"\"run_name\": \"BM_SummaryRepeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"name\": \"BM_SummaryRepeat/repeats:3_median\",$"}, + {"\"run_name\": \"BM_SummaryRepeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"name\": \"BM_SummaryRepeat/repeats:3_stddev\",$"}, + {"\"run_name\": \"BM_SummaryRepeat/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{".*BM_SummaryRepeat/repeats:3 ", MR_Not}, + {"^\"BM_SummaryRepeat/repeats:3_mean\",%csv_report$"}, + {"^\"BM_SummaryRepeat/repeats:3_median\",%csv_report$"}, + {"^\"BM_SummaryRepeat/repeats:3_stddev\",%csv_report$"}}); + +// Test that non-aggregate data is not displayed. +// NOTE: this test is kinda bad. we are only testing the display output. +// But we don't check that the file output still contains everything... +void BM_SummaryDisplay(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_SummaryDisplay)->Repetitions(2)->DisplayAggregatesOnly(); +ADD_CASES( + TC_ConsoleOut, + {{".*BM_SummaryDisplay/repeats:2 ", MR_Not}, + {"^BM_SummaryDisplay/repeats:2_mean %console_time_only_report [ ]*2$"}, + {"^BM_SummaryDisplay/repeats:2_median %console_time_only_report [ ]*2$"}, + {"^BM_SummaryDisplay/repeats:2_stddev %console_time_only_report [ ]*2$"}}); +ADD_CASES(TC_JSONOut, + {{".*BM_SummaryDisplay/repeats:2 ", MR_Not}, + {"\"name\": \"BM_SummaryDisplay/repeats:2_mean\",$"}, + {"\"run_name\": \"BM_SummaryDisplay/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}, + {"\"name\": \"BM_SummaryDisplay/repeats:2_median\",$"}, + {"\"run_name\": \"BM_SummaryDisplay/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}, + {"\"name\": \"BM_SummaryDisplay/repeats:2_stddev\",$"}, + {"\"run_name\": \"BM_SummaryDisplay/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}}); +ADD_CASES(TC_CSVOut, + {{".*BM_SummaryDisplay/repeats:2 ", MR_Not}, + {"^\"BM_SummaryDisplay/repeats:2_mean\",%csv_report$"}, + {"^\"BM_SummaryDisplay/repeats:2_median\",%csv_report$"}, + {"^\"BM_SummaryDisplay/repeats:2_stddev\",%csv_report$"}}); + +// Test repeats with custom time unit. +void BM_RepeatTimeUnit(benchmark::State& state) { + for (auto _ : state) { + } +} +BENCHMARK(BM_RepeatTimeUnit) + ->Repetitions(3) + ->ReportAggregatesOnly() + ->Unit(benchmark::kMicrosecond); +ADD_CASES( + TC_ConsoleOut, + {{".*BM_RepeatTimeUnit/repeats:3 ", MR_Not}, + {"^BM_RepeatTimeUnit/repeats:3_mean %console_us_time_only_report [ ]*3$"}, + {"^BM_RepeatTimeUnit/repeats:3_median %console_us_time_only_report [ " + "]*3$"}, + {"^BM_RepeatTimeUnit/repeats:3_stddev %console_us_time_only_report [ " + "]*3$"}}); +ADD_CASES(TC_JSONOut, + {{".*BM_RepeatTimeUnit/repeats:3 ", MR_Not}, + {"\"name\": \"BM_RepeatTimeUnit/repeats:3_mean\",$"}, + {"\"run_name\": \"BM_RepeatTimeUnit/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"time_unit\": \"us\",?$"}, + {"\"name\": \"BM_RepeatTimeUnit/repeats:3_median\",$"}, + {"\"run_name\": \"BM_RepeatTimeUnit/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"time_unit\": \"us\",?$"}, + {"\"name\": \"BM_RepeatTimeUnit/repeats:3_stddev\",$"}, + {"\"run_name\": \"BM_RepeatTimeUnit/repeats:3\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"time_unit\": \"us\",?$"}}); +ADD_CASES(TC_CSVOut, + {{".*BM_RepeatTimeUnit/repeats:3 ", MR_Not}, + {"^\"BM_RepeatTimeUnit/repeats:3_mean\",%csv_us_report$"}, + {"^\"BM_RepeatTimeUnit/repeats:3_median\",%csv_us_report$"}, + {"^\"BM_RepeatTimeUnit/repeats:3_stddev\",%csv_us_report$"}}); + +// ========================================================================= // +// -------------------- Testing user-provided statistics ------------------- // +// ========================================================================= // + +const auto UserStatistics = [](const std::vector& v) { + return v.back(); +}; +void BM_UserStats(benchmark::State& state) { + for (auto _ : state) { + state.SetIterationTime(150 / 10e8); + } +} +// clang-format off +BENCHMARK(BM_UserStats) + ->Repetitions(3) + ->Iterations(5) + ->UseManualTime() + ->ComputeStatistics("", UserStatistics); +// clang-format on + +// check that user-provided stats is calculated, and is after the default-ones +// empty string as name is intentional, it would sort before anything else +ADD_CASES(TC_ConsoleOut, {{"^BM_UserStats/iterations:5/repeats:3/manual_time [ " + "]* 150 ns %time [ ]*5$"}, + {"^BM_UserStats/iterations:5/repeats:3/manual_time [ " + "]* 150 ns %time [ ]*5$"}, + {"^BM_UserStats/iterations:5/repeats:3/manual_time [ " + "]* 150 ns %time [ ]*5$"}, + {"^BM_UserStats/iterations:5/repeats:3/" + "manual_time_mean [ ]* 150 ns %time [ ]*3$"}, + {"^BM_UserStats/iterations:5/repeats:3/" + "manual_time_median [ ]* 150 ns %time [ ]*3$"}, + {"^BM_UserStats/iterations:5/repeats:3/" + "manual_time_stddev [ ]* 0.000 ns %time [ ]*3$"}, + {"^BM_UserStats/iterations:5/repeats:3/manual_time_ " + "[ ]* 150 ns %time [ ]*3$"}}); +ADD_CASES( + TC_JSONOut, + {{"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$"}, + {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": 5,$", MR_Next}, + {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next}, + {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$"}, + {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"repetition_index\": 1,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": 5,$", MR_Next}, + {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next}, + {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$"}, + {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"repetition_index\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": 5,$", MR_Next}, + {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next}, + {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_mean\",$"}, + {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$", + MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next}, + {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_median\",$"}, + {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$", + MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next}, + {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_stddev\",$"}, + {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$", + MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_\",$"}, + {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$", + MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 3,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"\",$", MR_Next}, + {"\"iterations\": 3,$", MR_Next}, + {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next}}); +ADD_CASES( + TC_CSVOut, + {{"^\"BM_UserStats/iterations:5/repeats:3/manual_time\",%csv_report$"}, + {"^\"BM_UserStats/iterations:5/repeats:3/manual_time\",%csv_report$"}, + {"^\"BM_UserStats/iterations:5/repeats:3/manual_time\",%csv_report$"}, + {"^\"BM_UserStats/iterations:5/repeats:3/manual_time_mean\",%csv_report$"}, + {"^\"BM_UserStats/iterations:5/repeats:3/" + "manual_time_median\",%csv_report$"}, + {"^\"BM_UserStats/iterations:5/repeats:3/" + "manual_time_stddev\",%csv_report$"}, + {"^\"BM_UserStats/iterations:5/repeats:3/manual_time_\",%csv_report$"}}); + +// ========================================================================= // +// ------------------------- Testing StrEscape JSON ------------------------ // +// ========================================================================= // +#if 0 // enable when csv testing code correctly handles multi-line fields +void BM_JSON_Format(benchmark::State& state) { + state.SkipWithError("val\b\f\n\r\t\\\"with\"es,capes"); + for (auto _ : state) { + } +} +BENCHMARK(BM_JSON_Format); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_JSON_Format\",$"}, + {"\"run_name\": \"BM_JSON_Format\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"error_occurred\": true,$", MR_Next}, + {R"("error_message": "val\\b\\f\\n\\r\\t\\\\\\"with\\"es,capes",$)", MR_Next}}); +#endif +// ========================================================================= // +// -------------------------- Testing CsvEscape ---------------------------- // +// ========================================================================= // + +void BM_CSV_Format(benchmark::State& state) { + state.SkipWithError("\"freedom\""); + for (auto _ : state) { + } +} +BENCHMARK(BM_CSV_Format); +ADD_CASES(TC_CSVOut, {{"^\"BM_CSV_Format\",,,,,,,,true,\"\"\"freedom\"\"\"$"}}); + +// ========================================================================= // +// --------------------------- TEST CASES END ------------------------------ // +// ========================================================================= // + +int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/skip_with_error_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/skip_with_error_test.cc new file mode 100644 index 000000000..06579772f --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/skip_with_error_test.cc @@ -0,0 +1,189 @@ + +#undef NDEBUG +#include +#include + +#include "../src/check.h" // NOTE: check.h is for internal use only! +#include "benchmark/benchmark.h" + +namespace { + +class TestReporter : public benchmark::ConsoleReporter { + public: + virtual bool ReportContext(const Context& context) { + return ConsoleReporter::ReportContext(context); + }; + + virtual void ReportRuns(const std::vector& report) { + all_runs_.insert(all_runs_.end(), begin(report), end(report)); + ConsoleReporter::ReportRuns(report); + } + + TestReporter() {} + virtual ~TestReporter() {} + + mutable std::vector all_runs_; +}; + +struct TestCase { + std::string name; + bool error_occurred; + std::string error_message; + + typedef benchmark::BenchmarkReporter::Run Run; + + void CheckRun(Run const& run) const { + CHECK(name == run.benchmark_name()) + << "expected " << name << " got " << run.benchmark_name(); + CHECK(error_occurred == run.error_occurred); + CHECK(error_message == run.error_message); + if (error_occurred) { + // CHECK(run.iterations == 0); + } else { + CHECK(run.iterations != 0); + } + } +}; + +std::vector ExpectedResults; + +int AddCases(const char* base_name, std::initializer_list const& v) { + for (auto TC : v) { + TC.name = base_name + TC.name; + ExpectedResults.push_back(std::move(TC)); + } + return 0; +} + +#define CONCAT(x, y) CONCAT2(x, y) +#define CONCAT2(x, y) x##y +#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__) + +} // end namespace + +void BM_error_before_running(benchmark::State& state) { + state.SkipWithError("error message"); + while (state.KeepRunning()) { + assert(false); + } +} +BENCHMARK(BM_error_before_running); +ADD_CASES("BM_error_before_running", {{"", true, "error message"}}); + +void BM_error_before_running_batch(benchmark::State& state) { + state.SkipWithError("error message"); + while (state.KeepRunningBatch(17)) { + assert(false); + } +} +BENCHMARK(BM_error_before_running_batch); +ADD_CASES("BM_error_before_running_batch", {{"", true, "error message"}}); + +void BM_error_before_running_range_for(benchmark::State& state) { + state.SkipWithError("error message"); + for (auto _ : state) { + assert(false); + } +} +BENCHMARK(BM_error_before_running_range_for); +ADD_CASES("BM_error_before_running_range_for", {{"", true, "error message"}}); + +void BM_error_during_running(benchmark::State& state) { + int first_iter = true; + while (state.KeepRunning()) { + if (state.range(0) == 1 && state.thread_index <= (state.threads / 2)) { + assert(first_iter); + first_iter = false; + state.SkipWithError("error message"); + } else { + state.PauseTiming(); + state.ResumeTiming(); + } + } +} +BENCHMARK(BM_error_during_running)->Arg(1)->Arg(2)->ThreadRange(1, 8); +ADD_CASES("BM_error_during_running", {{"/1/threads:1", true, "error message"}, + {"/1/threads:2", true, "error message"}, + {"/1/threads:4", true, "error message"}, + {"/1/threads:8", true, "error message"}, + {"/2/threads:1", false, ""}, + {"/2/threads:2", false, ""}, + {"/2/threads:4", false, ""}, + {"/2/threads:8", false, ""}}); + +void BM_error_during_running_ranged_for(benchmark::State& state) { + assert(state.max_iterations > 3 && "test requires at least a few iterations"); + int first_iter = true; + // NOTE: Users should not write the for loop explicitly. + for (auto It = state.begin(), End = state.end(); It != End; ++It) { + if (state.range(0) == 1) { + assert(first_iter); + first_iter = false; + state.SkipWithError("error message"); + // Test the unfortunate but documented behavior that the ranged-for loop + // doesn't automatically terminate when SkipWithError is set. + assert(++It != End); + break; // Required behavior + } + } +} +BENCHMARK(BM_error_during_running_ranged_for)->Arg(1)->Arg(2)->Iterations(5); +ADD_CASES("BM_error_during_running_ranged_for", + {{"/1/iterations:5", true, "error message"}, + {"/2/iterations:5", false, ""}}); + +void BM_error_after_running(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(state.iterations()); + } + if (state.thread_index <= (state.threads / 2)) + state.SkipWithError("error message"); +} +BENCHMARK(BM_error_after_running)->ThreadRange(1, 8); +ADD_CASES("BM_error_after_running", {{"/threads:1", true, "error message"}, + {"/threads:2", true, "error message"}, + {"/threads:4", true, "error message"}, + {"/threads:8", true, "error message"}}); + +void BM_error_while_paused(benchmark::State& state) { + bool first_iter = true; + while (state.KeepRunning()) { + if (state.range(0) == 1 && state.thread_index <= (state.threads / 2)) { + assert(first_iter); + first_iter = false; + state.PauseTiming(); + state.SkipWithError("error message"); + } else { + state.PauseTiming(); + state.ResumeTiming(); + } + } +} +BENCHMARK(BM_error_while_paused)->Arg(1)->Arg(2)->ThreadRange(1, 8); +ADD_CASES("BM_error_while_paused", {{"/1/threads:1", true, "error message"}, + {"/1/threads:2", true, "error message"}, + {"/1/threads:4", true, "error message"}, + {"/1/threads:8", true, "error message"}, + {"/2/threads:1", false, ""}, + {"/2/threads:2", false, ""}, + {"/2/threads:4", false, ""}, + {"/2/threads:8", false, ""}}); + +int main(int argc, char* argv[]) { + benchmark::Initialize(&argc, argv); + + TestReporter test_reporter; + benchmark::RunSpecifiedBenchmarks(&test_reporter); + + typedef benchmark::BenchmarkReporter::Run Run; + auto EB = ExpectedResults.begin(); + + for (Run const& run : test_reporter.all_runs_) { + assert(EB != ExpectedResults.end()); + EB->CheckRun(run); + ++EB; + } + assert(EB == ExpectedResults.end()); + + return 0; +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/state_assembly_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/state_assembly_test.cc new file mode 100644 index 000000000..7ddbb3b2a --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/state_assembly_test.cc @@ -0,0 +1,68 @@ +#include + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wreturn-type" +#endif + +// clang-format off +extern "C" { + extern int ExternInt; + benchmark::State& GetState(); + void Fn(); +} +// clang-format on + +using benchmark::State; + +// CHECK-LABEL: test_for_auto_loop: +extern "C" int test_for_auto_loop() { + State& S = GetState(); + int x = 42; + // CHECK: [[CALL:call(q)*]] _ZN9benchmark5State16StartKeepRunningEv + // CHECK-NEXT: testq %rbx, %rbx + // CHECK-NEXT: je [[LOOP_END:.*]] + + for (auto _ : S) { + // CHECK: .L[[LOOP_HEAD:[a-zA-Z0-9_]+]]: + // CHECK-GNU-NEXT: subq $1, %rbx + // CHECK-CLANG-NEXT: {{(addq \$1, %rax|incq %rax|addq \$-1, %rbx)}} + // CHECK-NEXT: jne .L[[LOOP_HEAD]] + benchmark::DoNotOptimize(x); + } + // CHECK: [[LOOP_END]]: + // CHECK: [[CALL]] _ZN9benchmark5State17FinishKeepRunningEv + + // CHECK: movl $101, %eax + // CHECK: ret + return 101; +} + +// CHECK-LABEL: test_while_loop: +extern "C" int test_while_loop() { + State& S = GetState(); + int x = 42; + + // CHECK: j{{(e|mp)}} .L[[LOOP_HEADER:[a-zA-Z0-9_]+]] + // CHECK-NEXT: .L[[LOOP_BODY:[a-zA-Z0-9_]+]]: + while (S.KeepRunning()) { + // CHECK-GNU-NEXT: subq $1, %[[IREG:[a-z]+]] + // CHECK-CLANG-NEXT: {{(addq \$-1,|decq)}} %[[IREG:[a-z]+]] + // CHECK: movq %[[IREG]], [[DEST:.*]] + benchmark::DoNotOptimize(x); + } + // CHECK-DAG: movq [[DEST]], %[[IREG]] + // CHECK-DAG: testq %[[IREG]], %[[IREG]] + // CHECK-DAG: jne .L[[LOOP_BODY]] + // CHECK-DAG: .L[[LOOP_HEADER]]: + + // CHECK: cmpb $0 + // CHECK-NEXT: jne .L[[LOOP_END:[a-zA-Z0-9_]+]] + // CHECK: [[CALL:call(q)*]] _ZN9benchmark5State16StartKeepRunningEv + + // CHECK: .L[[LOOP_END]]: + // CHECK: [[CALL]] _ZN9benchmark5State17FinishKeepRunningEv + + // CHECK: movl $101, %eax + // CHECK: ret + return 101; +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/statistics_gtest.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/statistics_gtest.cc new file mode 100644 index 000000000..99e314920 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/statistics_gtest.cc @@ -0,0 +1,28 @@ +//===---------------------------------------------------------------------===// +// statistics_test - Unit tests for src/statistics.cc +//===---------------------------------------------------------------------===// + +#include "../src/statistics.h" +#include "gtest/gtest.h" + +namespace { +TEST(StatisticsTest, Mean) { + EXPECT_DOUBLE_EQ(benchmark::StatisticsMean({42, 42, 42, 42}), 42.0); + EXPECT_DOUBLE_EQ(benchmark::StatisticsMean({1, 2, 3, 4}), 2.5); + EXPECT_DOUBLE_EQ(benchmark::StatisticsMean({1, 2, 5, 10, 10, 14}), 7.0); +} + +TEST(StatisticsTest, Median) { + EXPECT_DOUBLE_EQ(benchmark::StatisticsMedian({42, 42, 42, 42}), 42.0); + EXPECT_DOUBLE_EQ(benchmark::StatisticsMedian({1, 2, 3, 4}), 2.5); + EXPECT_DOUBLE_EQ(benchmark::StatisticsMedian({1, 2, 5, 10, 10}), 5.0); +} + +TEST(StatisticsTest, StdDev) { + EXPECT_DOUBLE_EQ(benchmark::StatisticsStdDev({101, 101, 101, 101}), 0.0); + EXPECT_DOUBLE_EQ(benchmark::StatisticsStdDev({1, 2, 3}), 1.0); + EXPECT_FLOAT_EQ(benchmark::StatisticsStdDev({1.5, 2.4, 3.3, 4.2, 5.1}), + 1.42302495); +} + +} // end namespace diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/string_util_gtest.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/string_util_gtest.cc new file mode 100644 index 000000000..2c5d073f6 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/string_util_gtest.cc @@ -0,0 +1,146 @@ +//===---------------------------------------------------------------------===// +// statistics_test - Unit tests for src/statistics.cc +//===---------------------------------------------------------------------===// + +#include "../src/string_util.h" +#include "gtest/gtest.h" + +namespace { +TEST(StringUtilTest, stoul) { + { + size_t pos = 0; + EXPECT_EQ(0ul, benchmark::stoul("0", &pos)); + EXPECT_EQ(1ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(7ul, benchmark::stoul("7", &pos)); + EXPECT_EQ(1ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(135ul, benchmark::stoul("135", &pos)); + EXPECT_EQ(3ul, pos); + } +#if ULONG_MAX == 0xFFFFFFFFul + { + size_t pos = 0; + EXPECT_EQ(0xFFFFFFFFul, benchmark::stoul("4294967295", &pos)); + EXPECT_EQ(10ul, pos); + } +#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFFul + { + size_t pos = 0; + EXPECT_EQ(0xFFFFFFFFFFFFFFFFul, benchmark::stoul("18446744073709551615", &pos)); + EXPECT_EQ(20ul, pos); + } +#endif + { + size_t pos = 0; + EXPECT_EQ(10ul, benchmark::stoul("1010", &pos, 2)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(520ul, benchmark::stoul("1010", &pos, 8)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1010ul, benchmark::stoul("1010", &pos, 10)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(4112ul, benchmark::stoul("1010", &pos, 16)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(0xBEEFul, benchmark::stoul("BEEF", &pos, 16)); + EXPECT_EQ(4ul, pos); + } + { + ASSERT_THROW(benchmark::stoul("this is a test"), std::invalid_argument); + } +} + +TEST(StringUtilTest, stoi) { + { + size_t pos = 0; + EXPECT_EQ(0, benchmark::stoi("0", &pos)); + EXPECT_EQ(1ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(-17, benchmark::stoi("-17", &pos)); + EXPECT_EQ(3ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1357, benchmark::stoi("1357", &pos)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(10, benchmark::stoi("1010", &pos, 2)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(520, benchmark::stoi("1010", &pos, 8)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1010, benchmark::stoi("1010", &pos, 10)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(4112, benchmark::stoi("1010", &pos, 16)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(0xBEEF, benchmark::stoi("BEEF", &pos, 16)); + EXPECT_EQ(4ul, pos); + } + { + ASSERT_THROW(benchmark::stoi("this is a test"), std::invalid_argument); + } +} + +TEST(StringUtilTest, stod) { + { + size_t pos = 0; + EXPECT_EQ(0.0, benchmark::stod("0", &pos)); + EXPECT_EQ(1ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(-84.0, benchmark::stod("-84", &pos)); + EXPECT_EQ(3ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1234.0, benchmark::stod("1234", &pos)); + EXPECT_EQ(4ul, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1.5, benchmark::stod("1.5", &pos)); + EXPECT_EQ(3ul, pos); + } + { + size_t pos = 0; + /* Note: exactly representable as double */ + EXPECT_EQ(-1.25e+9, benchmark::stod("-1.25e+9", &pos)); + EXPECT_EQ(8ul, pos); + } + { + ASSERT_THROW(benchmark::stod("this is a test"), std::invalid_argument); + } +} + +} // end namespace diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/templated_fixture_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/templated_fixture_test.cc new file mode 100644 index 000000000..fe9865cc7 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/templated_fixture_test.cc @@ -0,0 +1,28 @@ + +#include "benchmark/benchmark.h" + +#include +#include + +template +class MyFixture : public ::benchmark::Fixture { + public: + MyFixture() : data(0) {} + + T data; +}; + +BENCHMARK_TEMPLATE_F(MyFixture, Foo, int)(benchmark::State& st) { + for (auto _ : st) { + data += 1; + } +} + +BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, Bar, double)(benchmark::State& st) { + for (auto _ : st) { + data += 1.0; + } +} +BENCHMARK_REGISTER_F(MyFixture, Bar); + +BENCHMARK_MAIN(); diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_tabular_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_tabular_test.cc new file mode 100644 index 000000000..099464ef9 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_tabular_test.cc @@ -0,0 +1,283 @@ + +#undef NDEBUG + +#include "benchmark/benchmark.h" +#include "output_test.h" + +// @todo: this checks the full output at once; the rule for +// CounterSet1 was failing because it was not matching "^[-]+$". +// @todo: check that the counters are vertically aligned. +ADD_CASES( + TC_ConsoleOut, + { + // keeping these lines long improves readability, so: + // clang-format off + {"^[-]+$", MR_Next}, + {"^Benchmark %s Time %s CPU %s Iterations %s Bar %s Bat %s Baz %s Foo %s Frob %s Lob$", MR_Next}, + {"^[-]+$", MR_Next}, + {"^BM_Counters_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_Counters_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_Counters_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_Counters_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_Counters_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterRates_Tabular/threads:%int %console_report [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s$", MR_Next}, + {"^BM_CounterRates_Tabular/threads:%int %console_report [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s$", MR_Next}, + {"^BM_CounterRates_Tabular/threads:%int %console_report [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s$", MR_Next}, + {"^BM_CounterRates_Tabular/threads:%int %console_report [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s$", MR_Next}, + {"^BM_CounterRates_Tabular/threads:%int %console_report [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s [ ]*%hrfloat/s$", MR_Next}, + {"^[-]+$", MR_Next}, + {"^Benchmark %s Time %s CPU %s Iterations %s Bar %s Baz %s Foo$", MR_Next}, + {"^[-]+$", MR_Next}, + {"^BM_CounterSet0_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet0_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet0_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet0_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet0_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet1_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet1_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet1_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet1_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet1_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^[-]+$", MR_Next}, + {"^Benchmark %s Time %s CPU %s Iterations %s Bat %s Baz %s Foo$", MR_Next}, + {"^[-]+$", MR_Next}, + {"^BM_CounterSet2_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet2_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet2_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet2_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$", MR_Next}, + {"^BM_CounterSet2_Tabular/threads:%int %console_report [ ]*%hrfloat [ ]*%hrfloat [ ]*%hrfloat$"}, + // clang-format on + }); +ADD_CASES(TC_CSVOut, {{"%csv_header," + "\"Bar\",\"Bat\",\"Baz\",\"Foo\",\"Frob\",\"Lob\""}}); + +// ========================================================================= // +// ------------------------- Tabular Counters Output ----------------------- // +// ========================================================================= // + +void BM_Counters_Tabular(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters.insert({ + {"Foo", {1, bm::Counter::kAvgThreads}}, + {"Bar", {2, bm::Counter::kAvgThreads}}, + {"Baz", {4, bm::Counter::kAvgThreads}}, + {"Bat", {8, bm::Counter::kAvgThreads}}, + {"Frob", {16, bm::Counter::kAvgThreads}}, + {"Lob", {32, bm::Counter::kAvgThreads}}, + }); +} +BENCHMARK(BM_Counters_Tabular)->ThreadRange(1, 16); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Tabular/threads:%int\",$"}, + {"\"run_name\": \"BM_Counters_Tabular/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"Bar\": %float,$", MR_Next}, + {"\"Bat\": %float,$", MR_Next}, + {"\"Baz\": %float,$", MR_Next}, + {"\"Foo\": %float,$", MR_Next}, + {"\"Frob\": %float,$", MR_Next}, + {"\"Lob\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Tabular/threads:%int\",%csv_report," + "%float,%float,%float,%float,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckTabular(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "Foo", EQ, 1); + CHECK_COUNTER_VALUE(e, int, "Bar", EQ, 2); + CHECK_COUNTER_VALUE(e, int, "Baz", EQ, 4); + CHECK_COUNTER_VALUE(e, int, "Bat", EQ, 8); + CHECK_COUNTER_VALUE(e, int, "Frob", EQ, 16); + CHECK_COUNTER_VALUE(e, int, "Lob", EQ, 32); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Tabular/threads:%int", &CheckTabular); + +// ========================================================================= // +// -------------------- Tabular+Rate Counters Output ----------------------- // +// ========================================================================= // + +void BM_CounterRates_Tabular(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters.insert({ + {"Foo", {1, bm::Counter::kAvgThreadsRate}}, + {"Bar", {2, bm::Counter::kAvgThreadsRate}}, + {"Baz", {4, bm::Counter::kAvgThreadsRate}}, + {"Bat", {8, bm::Counter::kAvgThreadsRate}}, + {"Frob", {16, bm::Counter::kAvgThreadsRate}}, + {"Lob", {32, bm::Counter::kAvgThreadsRate}}, + }); +} +BENCHMARK(BM_CounterRates_Tabular)->ThreadRange(1, 16); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_CounterRates_Tabular/threads:%int\",$"}, + {"\"run_name\": \"BM_CounterRates_Tabular/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"Bar\": %float,$", MR_Next}, + {"\"Bat\": %float,$", MR_Next}, + {"\"Baz\": %float,$", MR_Next}, + {"\"Foo\": %float,$", MR_Next}, + {"\"Frob\": %float,$", MR_Next}, + {"\"Lob\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_CounterRates_Tabular/threads:%int\",%csv_report," + "%float,%float,%float,%float,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckTabularRate(Results const& e) { + double t = e.DurationCPUTime(); + CHECK_FLOAT_COUNTER_VALUE(e, "Foo", EQ, 1. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "Bar", EQ, 2. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "Baz", EQ, 4. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "Bat", EQ, 8. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "Frob", EQ, 16. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "Lob", EQ, 32. / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_CounterRates_Tabular/threads:%int", + &CheckTabularRate); + +// ========================================================================= // +// ------------------------- Tabular Counters Output ----------------------- // +// ========================================================================= // + +// set only some of the counters +void BM_CounterSet0_Tabular(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters.insert({ + {"Foo", {10, bm::Counter::kAvgThreads}}, + {"Bar", {20, bm::Counter::kAvgThreads}}, + {"Baz", {40, bm::Counter::kAvgThreads}}, + }); +} +BENCHMARK(BM_CounterSet0_Tabular)->ThreadRange(1, 16); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_CounterSet0_Tabular/threads:%int\",$"}, + {"\"run_name\": \"BM_CounterSet0_Tabular/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"Bar\": %float,$", MR_Next}, + {"\"Baz\": %float,$", MR_Next}, + {"\"Foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_CounterSet0_Tabular/threads:%int\",%csv_report," + "%float,,%float,%float,,"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckSet0(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "Foo", EQ, 10); + CHECK_COUNTER_VALUE(e, int, "Bar", EQ, 20); + CHECK_COUNTER_VALUE(e, int, "Baz", EQ, 40); +} +CHECK_BENCHMARK_RESULTS("BM_CounterSet0_Tabular", &CheckSet0); + +// again. +void BM_CounterSet1_Tabular(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters.insert({ + {"Foo", {15, bm::Counter::kAvgThreads}}, + {"Bar", {25, bm::Counter::kAvgThreads}}, + {"Baz", {45, bm::Counter::kAvgThreads}}, + }); +} +BENCHMARK(BM_CounterSet1_Tabular)->ThreadRange(1, 16); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_CounterSet1_Tabular/threads:%int\",$"}, + {"\"run_name\": \"BM_CounterSet1_Tabular/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"Bar\": %float,$", MR_Next}, + {"\"Baz\": %float,$", MR_Next}, + {"\"Foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_CounterSet1_Tabular/threads:%int\",%csv_report," + "%float,,%float,%float,,"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckSet1(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "Foo", EQ, 15); + CHECK_COUNTER_VALUE(e, int, "Bar", EQ, 25); + CHECK_COUNTER_VALUE(e, int, "Baz", EQ, 45); +} +CHECK_BENCHMARK_RESULTS("BM_CounterSet1_Tabular/threads:%int", &CheckSet1); + +// ========================================================================= // +// ------------------------- Tabular Counters Output ----------------------- // +// ========================================================================= // + +// set only some of the counters, different set now. +void BM_CounterSet2_Tabular(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters.insert({ + {"Foo", {10, bm::Counter::kAvgThreads}}, + {"Bat", {30, bm::Counter::kAvgThreads}}, + {"Baz", {40, bm::Counter::kAvgThreads}}, + }); +} +BENCHMARK(BM_CounterSet2_Tabular)->ThreadRange(1, 16); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_CounterSet2_Tabular/threads:%int\",$"}, + {"\"run_name\": \"BM_CounterSet2_Tabular/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"Bat\": %float,$", MR_Next}, + {"\"Baz\": %float,$", MR_Next}, + {"\"Foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_CounterSet2_Tabular/threads:%int\",%csv_report," + ",%float,%float,%float,,"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckSet2(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "Foo", EQ, 10); + CHECK_COUNTER_VALUE(e, int, "Bat", EQ, 30); + CHECK_COUNTER_VALUE(e, int, "Baz", EQ, 40); +} +CHECK_BENCHMARK_RESULTS("BM_CounterSet2_Tabular", &CheckSet2); + +// ========================================================================= // +// --------------------------- TEST CASES END ------------------------------ // +// ========================================================================= // + +int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_test.cc new file mode 100644 index 000000000..0775bc01f --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_test.cc @@ -0,0 +1,438 @@ + +#undef NDEBUG + +#include "benchmark/benchmark.h" +#include "output_test.h" + +// ========================================================================= // +// ---------------------- Testing Prologue Output -------------------------- // +// ========================================================================= // + +// clang-format off + +ADD_CASES(TC_ConsoleOut, + {{"^[-]+$", MR_Next}, + {"^Benchmark %s Time %s CPU %s Iterations UserCounters...$", MR_Next}, + {"^[-]+$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"%csv_header,\"bar\",\"foo\""}}); + +// clang-format on + +// ========================================================================= // +// ------------------------- Simple Counters Output ------------------------ // +// ========================================================================= // + +void BM_Counters_Simple(benchmark::State& state) { + for (auto _ : state) { + } + state.counters["foo"] = 1; + state.counters["bar"] = 2 * (double)state.iterations(); +} +BENCHMARK(BM_Counters_Simple); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Counters_Simple %console_report bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Simple\",$"}, + {"\"run_name\": \"BM_Counters_Simple\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Simple\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckSimple(Results const& e) { + double its = e.NumIterations(); + CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1); + // check that the value of bar is within 0.1% of the expected value + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", &CheckSimple); + +// ========================================================================= // +// --------------------- Counters+Items+Bytes/s Output --------------------- // +// ========================================================================= // + +namespace { +int num_calls1 = 0; +} +void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) { + for (auto _ : state) { + } + state.counters["foo"] = 1; + state.counters["bar"] = ++num_calls1; + state.SetBytesProcessed(364); + state.SetItemsProcessed(150); +} +BENCHMARK(BM_Counters_WithBytesAndItemsPSec); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_WithBytesAndItemsPSec %console_report " + "bar=%hrfloat bytes_per_second=%hrfloat/s " + "foo=%hrfloat items_per_second=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec\",$"}, + {"\"run_name\": \"BM_Counters_WithBytesAndItemsPSec\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"bytes_per_second\": %float,$", MR_Next}, + {"\"foo\": %float,$", MR_Next}, + {"\"items_per_second\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec\"," + "%csv_bytes_items_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckBytesAndItemsPSec(Results const& e) { + double t = e.DurationCPUTime(); // this (and not real time) is the time used + CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1); + CHECK_COUNTER_VALUE(e, int, "bar", EQ, num_calls1); + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_RESULT_VALUE(e, "bytes_per_second", EQ, 364. / t, 0.001); + CHECK_FLOAT_RESULT_VALUE(e, "items_per_second", EQ, 150. / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec", + &CheckBytesAndItemsPSec); + +// ========================================================================= // +// ------------------------- Rate Counters Output -------------------------- // +// ========================================================================= // + +void BM_Counters_Rate(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kIsRate}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kIsRate}; +} +BENCHMARK(BM_Counters_Rate); +ADD_CASES( + TC_ConsoleOut, + {{"^BM_Counters_Rate %console_report bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Rate\",$"}, + {"\"run_name\": \"BM_Counters_Rate\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Rate\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckRate(Results const& e) { + double t = e.DurationCPUTime(); // this (and not real time) is the time used + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Rate", &CheckRate); + +// ========================================================================= // +// ------------------------- Thread Counters Output ------------------------ // +// ========================================================================= // + +void BM_Counters_Threads(benchmark::State& state) { + for (auto _ : state) { + } + state.counters["foo"] = 1; + state.counters["bar"] = 2; +} +BENCHMARK(BM_Counters_Threads)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Threads/threads:%int %console_report " + "bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"}, + {"\"run_name\": \"BM_Counters_Threads/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES( + TC_CSVOut, + {{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckThreads(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "foo", EQ, e.NumThreads()); + CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads()); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads); + +// ========================================================================= // +// ---------------------- ThreadAvg Counters Output ------------------------ // +// ========================================================================= // + +void BM_Counters_AvgThreads(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreads}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreads}; +} +BENCHMARK(BM_Counters_AvgThreads)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreads/threads:%int " + "%console_report bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"}, + {"\"run_name\": \"BM_Counters_AvgThreads/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES( + TC_CSVOut, + {{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgThreads(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1); + CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int", + &CheckAvgThreads); + +// ========================================================================= // +// ---------------------- ThreadAvg Counters Output ------------------------ // +// ========================================================================= // + +void BM_Counters_AvgThreadsRate(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreadsRate}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreadsRate}; +} +BENCHMARK(BM_Counters_AvgThreadsRate)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreadsRate/threads:%int " + "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$"}, + {"\"run_name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/" + "threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgThreadsRate(Results const& e) { + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / e.DurationCPUTime(), 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / e.DurationCPUTime(), 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int", + &CheckAvgThreadsRate); + +// ========================================================================= // +// ------------------- IterationInvariant Counters Output ------------------ // +// ========================================================================= // + +void BM_Counters_IterationInvariant(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kIsIterationInvariant}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kIsIterationInvariant}; +} +BENCHMARK(BM_Counters_IterationInvariant); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_IterationInvariant %console_report " + "bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_IterationInvariant\",$"}, + {"\"run_name\": \"BM_Counters_IterationInvariant\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, + {{"^\"BM_Counters_IterationInvariant\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckIterationInvariant(Results const& e) { + double its = e.NumIterations(); + // check that the values are within 0.1% of the expected value + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant", + &CheckIterationInvariant); + +// ========================================================================= // +// ----------------- IterationInvariantRate Counters Output ---------------- // +// ========================================================================= // + +void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = + bm::Counter{1, bm::Counter::kIsIterationInvariantRate}; + state.counters["bar"] = + bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kIsIterationInvariant}; +} +BENCHMARK(BM_Counters_kIsIterationInvariantRate); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kIsIterationInvariantRate " + "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_kIsIterationInvariantRate\",$"}, + {"\"run_name\": \"BM_Counters_kIsIterationInvariantRate\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_kIsIterationInvariantRate\",%csv_report," + "%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckIsIterationInvariantRate(Results const& e) { + double its = e.NumIterations(); + double t = e.DurationCPUTime(); // this (and not real time) is the time used + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * 1. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, its * 2. / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate", + &CheckIsIterationInvariantRate); + +// ========================================================================= // +// ------------------- AvgIterations Counters Output ------------------ // +// ========================================================================= // + +void BM_Counters_AvgIterations(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterations}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgIterations}; +} +BENCHMARK(BM_Counters_AvgIterations); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgIterations %console_report " + "bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_AvgIterations\",$"}, + {"\"run_name\": \"BM_Counters_AvgIterations\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, + {{"^\"BM_Counters_AvgIterations\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgIterations(Results const& e) { + double its = e.NumIterations(); + // check that the values are within 0.1% of the expected value + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / its, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / its, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations", &CheckAvgIterations); + +// ========================================================================= // +// ----------------- AvgIterationsRate Counters Output ---------------- // +// ========================================================================= // + +void BM_Counters_kAvgIterationsRate(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterationsRate}; + state.counters["bar"] = + bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kAvgIterations}; +} +BENCHMARK(BM_Counters_kAvgIterationsRate); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kAvgIterationsRate " + "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_kAvgIterationsRate\",$"}, + {"\"run_name\": \"BM_Counters_kAvgIterationsRate\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 0,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_kAvgIterationsRate\",%csv_report," + "%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgIterationsRate(Results const& e) { + double its = e.NumIterations(); + double t = e.DurationCPUTime(); // this (and not real time) is the time used + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / its / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / its / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate", + &CheckAvgIterationsRate); + +// ========================================================================= // +// --------------------------- TEST CASES END ------------------------------ // +// ========================================================================= // + +int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_thousands_test.cc b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_thousands_test.cc new file mode 100644 index 000000000..21d8285de --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/test/user_counters_thousands_test.cc @@ -0,0 +1,173 @@ + +#undef NDEBUG + +#include "benchmark/benchmark.h" +#include "output_test.h" + +// ========================================================================= // +// ------------------------ Thousands Customisation ------------------------ // +// ========================================================================= // + +void BM_Counters_Thousands(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters.insert({ + {"t0_1000000DefaultBase", + bm::Counter(1000 * 1000, bm::Counter::kDefaults)}, + {"t1_1000000Base1000", bm::Counter(1000 * 1000, bm::Counter::kDefaults, + benchmark::Counter::OneK::kIs1000)}, + {"t2_1000000Base1024", bm::Counter(1000 * 1000, bm::Counter::kDefaults, + benchmark::Counter::OneK::kIs1024)}, + {"t3_1048576Base1000", bm::Counter(1024 * 1024, bm::Counter::kDefaults, + benchmark::Counter::OneK::kIs1000)}, + {"t4_1048576Base1024", bm::Counter(1024 * 1024, bm::Counter::kDefaults, + benchmark::Counter::OneK::kIs1024)}, + }); +} +BENCHMARK(BM_Counters_Thousands)->Repetitions(2); +ADD_CASES( + TC_ConsoleOut, + { + {"^BM_Counters_Thousands/repeats:2 %console_report " + "t0_1000000DefaultBase=1000k " + "t1_1000000Base1000=1000k t2_1000000Base1024=976.56[23]k " + "t3_1048576Base1000=1048.58k t4_1048576Base1024=1024k$"}, + {"^BM_Counters_Thousands/repeats:2 %console_report " + "t0_1000000DefaultBase=1000k " + "t1_1000000Base1000=1000k t2_1000000Base1024=976.56[23]k " + "t3_1048576Base1000=1048.58k t4_1048576Base1024=1024k$"}, + {"^BM_Counters_Thousands/repeats:2_mean %console_report " + "t0_1000000DefaultBase=1000k t1_1000000Base1000=1000k " + "t2_1000000Base1024=976.56[23]k t3_1048576Base1000=1048.58k " + "t4_1048576Base1024=1024k$"}, + {"^BM_Counters_Thousands/repeats:2_median %console_report " + "t0_1000000DefaultBase=1000k t1_1000000Base1000=1000k " + "t2_1000000Base1024=976.56[23]k t3_1048576Base1000=1048.58k " + "t4_1048576Base1024=1024k$"}, + {"^BM_Counters_Thousands/repeats:2_stddev %console_time_only_report [ " + "]*2 t0_1000000DefaultBase=0 t1_1000000Base1000=0 " + "t2_1000000Base1024=0 t3_1048576Base1000=0 t4_1048576Base1024=0$"}, + }); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Thousands/repeats:2\",$"}, + {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next}, + {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Thousands/repeats:2\",$"}, + {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"repetition_index\": 1,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next}, + {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Thousands/repeats:2_mean\",$"}, + {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"mean\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next}, + {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Thousands/repeats:2_median\",$"}, + {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"median\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next}, + {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next}, + {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Thousands/repeats:2_stddev\",$"}, + {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next}, + {"\"run_type\": \"aggregate\",$", MR_Next}, + {"\"repetitions\": 2,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"aggregate_name\": \"stddev\",$", MR_Next}, + {"\"iterations\": 2,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"t0_1000000DefaultBase\": 0\\.(0)*e\\+(0)*,$", MR_Next}, + {"\"t1_1000000Base1000\": 0\\.(0)*e\\+(0)*,$", MR_Next}, + {"\"t2_1000000Base1024\": 0\\.(0)*e\\+(0)*,$", MR_Next}, + {"\"t3_1048576Base1000\": 0\\.(0)*e\\+(0)*,$", MR_Next}, + {"\"t4_1048576Base1024\": 0\\.(0)*e\\+(0)*$", MR_Next}, + {"}", MR_Next}}); + +ADD_CASES( + TC_CSVOut, + {{"^\"BM_Counters_Thousands/" + "repeats:2\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\.04858e\\+(" + "0)*6,1\\.04858e\\+(0)*6$"}, + {"^\"BM_Counters_Thousands/" + "repeats:2\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\.04858e\\+(" + "0)*6,1\\.04858e\\+(0)*6$"}, + {"^\"BM_Counters_Thousands/" + "repeats:2_mean\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\." + "04858e\\+(0)*6,1\\.04858e\\+(0)*6$"}, + {"^\"BM_Counters_Thousands/" + "repeats:2_median\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\." + "04858e\\+(0)*6,1\\.04858e\\+(0)*6$"}, + {"^\"BM_Counters_Thousands/repeats:2_stddev\",%csv_report,0,0,0,0,0$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckThousands(Results const& e) { + if (e.name != "BM_Counters_Thousands/repeats:2") + return; // Do not check the aggregates! + + // check that the values are within 0.01% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "t0_1000000DefaultBase", EQ, 1000 * 1000, + 0.0001); + CHECK_FLOAT_COUNTER_VALUE(e, "t1_1000000Base1000", EQ, 1000 * 1000, 0.0001); + CHECK_FLOAT_COUNTER_VALUE(e, "t2_1000000Base1024", EQ, 1000 * 1000, 0.0001); + CHECK_FLOAT_COUNTER_VALUE(e, "t3_1048576Base1000", EQ, 1024 * 1024, 0.0001); + CHECK_FLOAT_COUNTER_VALUE(e, "t4_1048576Base1024", EQ, 1024 * 1024, 0.0001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Thousands", &CheckThousands); + +// ========================================================================= // +// --------------------------- TEST CASES END ------------------------------ // +// ========================================================================= // + +int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/compare.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/compare.py new file mode 100755 index 000000000..539ace6fb --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/compare.py @@ -0,0 +1,408 @@ +#!/usr/bin/env python + +import unittest +""" +compare.py - versatile benchmark output compare tool +""" + +import argparse +from argparse import ArgumentParser +import sys +import gbench +from gbench import util, report +from gbench.util import * + + +def check_inputs(in1, in2, flags): + """ + Perform checking on the user provided inputs and diagnose any abnormalities + """ + in1_kind, in1_err = classify_input_file(in1) + in2_kind, in2_err = classify_input_file(in2) + output_file = find_benchmark_flag('--benchmark_out=', flags) + output_type = find_benchmark_flag('--benchmark_out_format=', flags) + if in1_kind == IT_Executable and in2_kind == IT_Executable and output_file: + print(("WARNING: '--benchmark_out=%s' will be passed to both " + "benchmarks causing it to be overwritten") % output_file) + if in1_kind == IT_JSON and in2_kind == IT_JSON and len(flags) > 0: + print("WARNING: passing optional flags has no effect since both " + "inputs are JSON") + if output_type is not None and output_type != 'json': + print(("ERROR: passing '--benchmark_out_format=%s' to 'compare.py`" + " is not supported.") % output_type) + sys.exit(1) + + +def create_parser(): + parser = ArgumentParser( + description='versatile benchmark output compare tool') + + parser.add_argument( + '-a', + '--display_aggregates_only', + dest='display_aggregates_only', + action="store_true", + help="If there are repetitions, by default, we display everything - the" + " actual runs, and the aggregates computed. Sometimes, it is " + "desirable to only view the aggregates. E.g. when there are a lot " + "of repetitions. Do note that only the display is affected. " + "Internally, all the actual runs are still used, e.g. for U test.") + + utest = parser.add_argument_group() + utest.add_argument( + '--no-utest', + dest='utest', + default=True, + action="store_false", + help="The tool can do a two-tailed Mann-Whitney U test with the null hypothesis that it is equally likely that a randomly selected value from one sample will be less than or greater than a randomly selected value from a second sample.\nWARNING: requires **LARGE** (no less than {}) number of repetitions to be meaningful!\nThe test is being done by default, if at least {} repetitions were done.\nThis option can disable the U Test.".format(report.UTEST_OPTIMAL_REPETITIONS, report.UTEST_MIN_REPETITIONS)) + alpha_default = 0.05 + utest.add_argument( + "--alpha", + dest='utest_alpha', + default=alpha_default, + type=float, + help=("significance level alpha. if the calculated p-value is below this value, then the result is said to be statistically significant and the null hypothesis is rejected.\n(default: %0.4f)") % + alpha_default) + + subparsers = parser.add_subparsers( + help='This tool has multiple modes of operation:', + dest='mode') + + parser_a = subparsers.add_parser( + 'benchmarks', + help='The most simple use-case, compare all the output of these two benchmarks') + baseline = parser_a.add_argument_group( + 'baseline', 'The benchmark baseline') + baseline.add_argument( + 'test_baseline', + metavar='test_baseline', + type=argparse.FileType('r'), + nargs=1, + help='A benchmark executable or JSON output file') + contender = parser_a.add_argument_group( + 'contender', 'The benchmark that will be compared against the baseline') + contender.add_argument( + 'test_contender', + metavar='test_contender', + type=argparse.FileType('r'), + nargs=1, + help='A benchmark executable or JSON output file') + parser_a.add_argument( + 'benchmark_options', + metavar='benchmark_options', + nargs=argparse.REMAINDER, + help='Arguments to pass when running benchmark executables') + + parser_b = subparsers.add_parser( + 'filters', help='Compare filter one with the filter two of benchmark') + baseline = parser_b.add_argument_group( + 'baseline', 'The benchmark baseline') + baseline.add_argument( + 'test', + metavar='test', + type=argparse.FileType('r'), + nargs=1, + help='A benchmark executable or JSON output file') + baseline.add_argument( + 'filter_baseline', + metavar='filter_baseline', + type=str, + nargs=1, + help='The first filter, that will be used as baseline') + contender = parser_b.add_argument_group( + 'contender', 'The benchmark that will be compared against the baseline') + contender.add_argument( + 'filter_contender', + metavar='filter_contender', + type=str, + nargs=1, + help='The second filter, that will be compared against the baseline') + parser_b.add_argument( + 'benchmark_options', + metavar='benchmark_options', + nargs=argparse.REMAINDER, + help='Arguments to pass when running benchmark executables') + + parser_c = subparsers.add_parser( + 'benchmarksfiltered', + help='Compare filter one of first benchmark with filter two of the second benchmark') + baseline = parser_c.add_argument_group( + 'baseline', 'The benchmark baseline') + baseline.add_argument( + 'test_baseline', + metavar='test_baseline', + type=argparse.FileType('r'), + nargs=1, + help='A benchmark executable or JSON output file') + baseline.add_argument( + 'filter_baseline', + metavar='filter_baseline', + type=str, + nargs=1, + help='The first filter, that will be used as baseline') + contender = parser_c.add_argument_group( + 'contender', 'The benchmark that will be compared against the baseline') + contender.add_argument( + 'test_contender', + metavar='test_contender', + type=argparse.FileType('r'), + nargs=1, + help='The second benchmark executable or JSON output file, that will be compared against the baseline') + contender.add_argument( + 'filter_contender', + metavar='filter_contender', + type=str, + nargs=1, + help='The second filter, that will be compared against the baseline') + parser_c.add_argument( + 'benchmark_options', + metavar='benchmark_options', + nargs=argparse.REMAINDER, + help='Arguments to pass when running benchmark executables') + + return parser + + +def main(): + # Parse the command line flags + parser = create_parser() + args, unknown_args = parser.parse_known_args() + if args.mode is None: + parser.print_help() + exit(1) + assert not unknown_args + benchmark_options = args.benchmark_options + + if args.mode == 'benchmarks': + test_baseline = args.test_baseline[0].name + test_contender = args.test_contender[0].name + filter_baseline = '' + filter_contender = '' + + # NOTE: if test_baseline == test_contender, you are analyzing the stdev + + description = 'Comparing %s to %s' % (test_baseline, test_contender) + elif args.mode == 'filters': + test_baseline = args.test[0].name + test_contender = args.test[0].name + filter_baseline = args.filter_baseline[0] + filter_contender = args.filter_contender[0] + + # NOTE: if filter_baseline == filter_contender, you are analyzing the + # stdev + + description = 'Comparing %s to %s (from %s)' % ( + filter_baseline, filter_contender, args.test[0].name) + elif args.mode == 'benchmarksfiltered': + test_baseline = args.test_baseline[0].name + test_contender = args.test_contender[0].name + filter_baseline = args.filter_baseline[0] + filter_contender = args.filter_contender[0] + + # NOTE: if test_baseline == test_contender and + # filter_baseline == filter_contender, you are analyzing the stdev + + description = 'Comparing %s (from %s) to %s (from %s)' % ( + filter_baseline, test_baseline, filter_contender, test_contender) + else: + # should never happen + print("Unrecognized mode of operation: '%s'" % args.mode) + parser.print_help() + exit(1) + + check_inputs(test_baseline, test_contender, benchmark_options) + + if args.display_aggregates_only: + benchmark_options += ['--benchmark_display_aggregates_only=true'] + + options_baseline = [] + options_contender = [] + + if filter_baseline and filter_contender: + options_baseline = ['--benchmark_filter=%s' % filter_baseline] + options_contender = ['--benchmark_filter=%s' % filter_contender] + + # Run the benchmarks and report the results + json1 = json1_orig = gbench.util.run_or_load_benchmark( + test_baseline, benchmark_options + options_baseline) + json2 = json2_orig = gbench.util.run_or_load_benchmark( + test_contender, benchmark_options + options_contender) + + # Now, filter the benchmarks so that the difference report can work + if filter_baseline and filter_contender: + replacement = '[%s vs. %s]' % (filter_baseline, filter_contender) + json1 = gbench.report.filter_benchmark( + json1_orig, filter_baseline, replacement) + json2 = gbench.report.filter_benchmark( + json2_orig, filter_contender, replacement) + + # Diff and output + output_lines = gbench.report.generate_difference_report( + json1, json2, args.display_aggregates_only, + args.utest, args.utest_alpha) + print(description) + for ln in output_lines: + print(ln) + + +class TestParser(unittest.TestCase): + def setUp(self): + self.parser = create_parser() + testInputs = os.path.join( + os.path.dirname( + os.path.realpath(__file__)), + 'gbench', + 'Inputs') + self.testInput0 = os.path.join(testInputs, 'test1_run1.json') + self.testInput1 = os.path.join(testInputs, 'test1_run2.json') + + def test_benchmarks_basic(self): + parsed = self.parser.parse_args( + ['benchmarks', self.testInput0, self.testInput1]) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'benchmarks') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertFalse(parsed.benchmark_options) + + def test_benchmarks_basic_without_utest(self): + parsed = self.parser.parse_args( + ['--no-utest', 'benchmarks', self.testInput0, self.testInput1]) + self.assertFalse(parsed.display_aggregates_only) + self.assertFalse(parsed.utest) + self.assertEqual(parsed.utest_alpha, 0.05) + self.assertEqual(parsed.mode, 'benchmarks') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertFalse(parsed.benchmark_options) + + def test_benchmarks_basic_display_aggregates_only(self): + parsed = self.parser.parse_args( + ['-a', 'benchmarks', self.testInput0, self.testInput1]) + self.assertTrue(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'benchmarks') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertFalse(parsed.benchmark_options) + + def test_benchmarks_basic_with_utest_alpha(self): + parsed = self.parser.parse_args( + ['--alpha=0.314', 'benchmarks', self.testInput0, self.testInput1]) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.utest_alpha, 0.314) + self.assertEqual(parsed.mode, 'benchmarks') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertFalse(parsed.benchmark_options) + + def test_benchmarks_basic_without_utest_with_utest_alpha(self): + parsed = self.parser.parse_args( + ['--no-utest', '--alpha=0.314', 'benchmarks', self.testInput0, self.testInput1]) + self.assertFalse(parsed.display_aggregates_only) + self.assertFalse(parsed.utest) + self.assertEqual(parsed.utest_alpha, 0.314) + self.assertEqual(parsed.mode, 'benchmarks') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertFalse(parsed.benchmark_options) + + def test_benchmarks_with_remainder(self): + parsed = self.parser.parse_args( + ['benchmarks', self.testInput0, self.testInput1, 'd']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'benchmarks') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertEqual(parsed.benchmark_options, ['d']) + + def test_benchmarks_with_remainder_after_doubleminus(self): + parsed = self.parser.parse_args( + ['benchmarks', self.testInput0, self.testInput1, '--', 'e']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'benchmarks') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertEqual(parsed.benchmark_options, ['e']) + + def test_filters_basic(self): + parsed = self.parser.parse_args( + ['filters', self.testInput0, 'c', 'd']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'filters') + self.assertEqual(parsed.test[0].name, self.testInput0) + self.assertEqual(parsed.filter_baseline[0], 'c') + self.assertEqual(parsed.filter_contender[0], 'd') + self.assertFalse(parsed.benchmark_options) + + def test_filters_with_remainder(self): + parsed = self.parser.parse_args( + ['filters', self.testInput0, 'c', 'd', 'e']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'filters') + self.assertEqual(parsed.test[0].name, self.testInput0) + self.assertEqual(parsed.filter_baseline[0], 'c') + self.assertEqual(parsed.filter_contender[0], 'd') + self.assertEqual(parsed.benchmark_options, ['e']) + + def test_filters_with_remainder_after_doubleminus(self): + parsed = self.parser.parse_args( + ['filters', self.testInput0, 'c', 'd', '--', 'f']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'filters') + self.assertEqual(parsed.test[0].name, self.testInput0) + self.assertEqual(parsed.filter_baseline[0], 'c') + self.assertEqual(parsed.filter_contender[0], 'd') + self.assertEqual(parsed.benchmark_options, ['f']) + + def test_benchmarksfiltered_basic(self): + parsed = self.parser.parse_args( + ['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'benchmarksfiltered') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.filter_baseline[0], 'c') + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertEqual(parsed.filter_contender[0], 'e') + self.assertFalse(parsed.benchmark_options) + + def test_benchmarksfiltered_with_remainder(self): + parsed = self.parser.parse_args( + ['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e', 'f']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'benchmarksfiltered') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.filter_baseline[0], 'c') + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertEqual(parsed.filter_contender[0], 'e') + self.assertEqual(parsed.benchmark_options[0], 'f') + + def test_benchmarksfiltered_with_remainder_after_doubleminus(self): + parsed = self.parser.parse_args( + ['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e', '--', 'g']) + self.assertFalse(parsed.display_aggregates_only) + self.assertTrue(parsed.utest) + self.assertEqual(parsed.mode, 'benchmarksfiltered') + self.assertEqual(parsed.test_baseline[0].name, self.testInput0) + self.assertEqual(parsed.filter_baseline[0], 'c') + self.assertEqual(parsed.test_contender[0].name, self.testInput1) + self.assertEqual(parsed.filter_contender[0], 'e') + self.assertEqual(parsed.benchmark_options[0], 'g') + + +if __name__ == '__main__': + # unittest.main() + main() + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off; +# kate: indent-mode python; remove-trailing-spaces modified; diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run1.json b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run1.json new file mode 100644 index 000000000..601e327ae --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run1.json @@ -0,0 +1,119 @@ +{ + "context": { + "date": "2016-08-02 17:44:46", + "num_cpus": 4, + "mhz_per_cpu": 4228, + "cpu_scaling_enabled": false, + "library_build_type": "release" + }, + "benchmarks": [ + { + "name": "BM_SameTimes", + "iterations": 1000, + "real_time": 10, + "cpu_time": 10, + "time_unit": "ns" + }, + { + "name": "BM_2xFaster", + "iterations": 1000, + "real_time": 50, + "cpu_time": 50, + "time_unit": "ns" + }, + { + "name": "BM_2xSlower", + "iterations": 1000, + "real_time": 50, + "cpu_time": 50, + "time_unit": "ns" + }, + { + "name": "BM_1PercentFaster", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_1PercentSlower", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_10PercentFaster", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_10PercentSlower", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_100xSlower", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_100xFaster", + "iterations": 1000, + "real_time": 10000, + "cpu_time": 10000, + "time_unit": "ns" + }, + { + "name": "BM_10PercentCPUToTime", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_ThirdFaster", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "MyComplexityTest_BigO", + "run_name": "MyComplexityTest", + "run_type": "aggregate", + "aggregate_name": "BigO", + "cpu_coefficient": 4.2749856294592886e+00, + "real_coefficient": 6.4789275289789780e+00, + "big_o": "N", + "time_unit": "ns" + }, + { + "name": "MyComplexityTest_RMS", + "run_name": "MyComplexityTest", + "run_type": "aggregate", + "aggregate_name": "RMS", + "rms": 4.5097802512472874e-03 + }, + { + "name": "BM_NotBadTimeUnit", + "iterations": 1000, + "real_time": 0.4, + "cpu_time": 0.5, + "time_unit": "s" + }, + { + "name": "BM_DifferentTimeUnit", + "iterations": 1, + "real_time": 1, + "cpu_time": 1, + "time_unit": "s" + } + ] +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run2.json b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run2.json new file mode 100644 index 000000000..3cbcf39b0 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test1_run2.json @@ -0,0 +1,119 @@ +{ + "context": { + "date": "2016-08-02 17:44:46", + "num_cpus": 4, + "mhz_per_cpu": 4228, + "cpu_scaling_enabled": false, + "library_build_type": "release" + }, + "benchmarks": [ + { + "name": "BM_SameTimes", + "iterations": 1000, + "real_time": 10, + "cpu_time": 10, + "time_unit": "ns" + }, + { + "name": "BM_2xFaster", + "iterations": 1000, + "real_time": 25, + "cpu_time": 25, + "time_unit": "ns" + }, + { + "name": "BM_2xSlower", + "iterations": 20833333, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_1PercentFaster", + "iterations": 1000, + "real_time": 98.9999999, + "cpu_time": 98.9999999, + "time_unit": "ns" + }, + { + "name": "BM_1PercentSlower", + "iterations": 1000, + "real_time": 100.9999999, + "cpu_time": 100.9999999, + "time_unit": "ns" + }, + { + "name": "BM_10PercentFaster", + "iterations": 1000, + "real_time": 90, + "cpu_time": 90, + "time_unit": "ns" + }, + { + "name": "BM_10PercentSlower", + "iterations": 1000, + "real_time": 110, + "cpu_time": 110, + "time_unit": "ns" + }, + { + "name": "BM_100xSlower", + "iterations": 1000, + "real_time": 1.0000e+04, + "cpu_time": 1.0000e+04, + "time_unit": "ns" + }, + { + "name": "BM_100xFaster", + "iterations": 1000, + "real_time": 100, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_10PercentCPUToTime", + "iterations": 1000, + "real_time": 110, + "cpu_time": 90, + "time_unit": "ns" + }, + { + "name": "BM_ThirdFaster", + "iterations": 1000, + "real_time": 66.665, + "cpu_time": 66.664, + "time_unit": "ns" + }, + { + "name": "MyComplexityTest_BigO", + "run_name": "MyComplexityTest", + "run_type": "aggregate", + "aggregate_name": "BigO", + "cpu_coefficient": 5.6215779594361486e+00, + "real_coefficient": 5.6288314793554610e+00, + "big_o": "N", + "time_unit": "ns" + }, + { + "name": "MyComplexityTest_RMS", + "run_name": "MyComplexityTest", + "run_type": "aggregate", + "aggregate_name": "RMS", + "rms": 3.3128901852342174e-03 + }, + { + "name": "BM_NotBadTimeUnit", + "iterations": 1000, + "real_time": 0.04, + "cpu_time": 0.6, + "time_unit": "s" + }, + { + "name": "BM_DifferentTimeUnit", + "iterations": 1, + "real_time": 1, + "cpu_time": 1, + "time_unit": "ns" + } + ] +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test2_run.json b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test2_run.json new file mode 100644 index 000000000..15bc69803 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test2_run.json @@ -0,0 +1,81 @@ +{ + "context": { + "date": "2016-08-02 17:44:46", + "num_cpus": 4, + "mhz_per_cpu": 4228, + "cpu_scaling_enabled": false, + "library_build_type": "release" + }, + "benchmarks": [ + { + "name": "BM_Hi", + "iterations": 1234, + "real_time": 42, + "cpu_time": 24, + "time_unit": "ms" + }, + { + "name": "BM_Zero", + "iterations": 1000, + "real_time": 10, + "cpu_time": 10, + "time_unit": "ns" + }, + { + "name": "BM_Zero/4", + "iterations": 4000, + "real_time": 40, + "cpu_time": 40, + "time_unit": "ns" + }, + { + "name": "Prefix/BM_Zero", + "iterations": 2000, + "real_time": 20, + "cpu_time": 20, + "time_unit": "ns" + }, + { + "name": "Prefix/BM_Zero/3", + "iterations": 3000, + "real_time": 30, + "cpu_time": 30, + "time_unit": "ns" + }, + { + "name": "BM_One", + "iterations": 5000, + "real_time": 5, + "cpu_time": 5, + "time_unit": "ns" + }, + { + "name": "BM_One/4", + "iterations": 2000, + "real_time": 20, + "cpu_time": 20, + "time_unit": "ns" + }, + { + "name": "Prefix/BM_One", + "iterations": 1000, + "real_time": 10, + "cpu_time": 10, + "time_unit": "ns" + }, + { + "name": "Prefix/BM_One/3", + "iterations": 1500, + "real_time": 15, + "cpu_time": 15, + "time_unit": "ns" + }, + { + "name": "BM_Bye", + "iterations": 5321, + "real_time": 11, + "cpu_time": 63, + "time_unit": "ns" + } + ] +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run0.json b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run0.json new file mode 100644 index 000000000..49f8b0614 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run0.json @@ -0,0 +1,65 @@ +{ + "context": { + "date": "2016-08-02 17:44:46", + "num_cpus": 4, + "mhz_per_cpu": 4228, + "cpu_scaling_enabled": false, + "library_build_type": "release" + }, + "benchmarks": [ + { + "name": "BM_One", + "run_type": "aggregate", + "iterations": 1000, + "real_time": 10, + "cpu_time": 100, + "time_unit": "ns" + }, + { + "name": "BM_Two", + "iterations": 1000, + "real_time": 9, + "cpu_time": 90, + "time_unit": "ns" + }, + { + "name": "BM_Two", + "iterations": 1000, + "real_time": 8, + "cpu_time": 86, + "time_unit": "ns" + }, + { + "name": "short", + "run_type": "aggregate", + "iterations": 1000, + "real_time": 8, + "cpu_time": 80, + "time_unit": "ns" + }, + { + "name": "short", + "run_type": "aggregate", + "iterations": 1000, + "real_time": 8, + "cpu_time": 77, + "time_unit": "ns" + }, + { + "name": "medium", + "run_type": "iteration", + "iterations": 1000, + "real_time": 8, + "cpu_time": 80, + "time_unit": "ns" + }, + { + "name": "medium", + "run_type": "iteration", + "iterations": 1000, + "real_time": 9, + "cpu_time": 82, + "time_unit": "ns" + } + ] +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run1.json b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run1.json new file mode 100644 index 000000000..acc5ba17a --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/Inputs/test3_run1.json @@ -0,0 +1,65 @@ +{ + "context": { + "date": "2016-08-02 17:44:46", + "num_cpus": 4, + "mhz_per_cpu": 4228, + "cpu_scaling_enabled": false, + "library_build_type": "release" + }, + "benchmarks": [ + { + "name": "BM_One", + "iterations": 1000, + "real_time": 9, + "cpu_time": 110, + "time_unit": "ns" + }, + { + "name": "BM_Two", + "run_type": "aggregate", + "iterations": 1000, + "real_time": 10, + "cpu_time": 89, + "time_unit": "ns" + }, + { + "name": "BM_Two", + "iterations": 1000, + "real_time": 7, + "cpu_time": 72, + "time_unit": "ns" + }, + { + "name": "short", + "run_type": "aggregate", + "iterations": 1000, + "real_time": 7, + "cpu_time": 75, + "time_unit": "ns" + }, + { + "name": "short", + "run_type": "aggregate", + "iterations": 762, + "real_time": 4.54, + "cpu_time": 66.6, + "time_unit": "ns" + }, + { + "name": "short", + "run_type": "iteration", + "iterations": 1000, + "real_time": 800, + "cpu_time": 1, + "time_unit": "ns" + }, + { + "name": "medium", + "run_type": "iteration", + "iterations": 1200, + "real_time": 5, + "cpu_time": 53, + "time_unit": "ns" + } + ] +} diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/__init__.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/__init__.py new file mode 100644 index 000000000..fce1a1acf --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/__init__.py @@ -0,0 +1,8 @@ +"""Google Benchmark tooling""" + +__author__ = 'Eric Fiselier' +__email__ = 'eric@efcs.ca' +__versioninfo__ = (0, 5, 0) +__version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev' + +__all__ = [] diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/report.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/report.py new file mode 100644 index 000000000..5bd3a8d85 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/report.py @@ -0,0 +1,541 @@ +import unittest +"""report.py - Utilities for reporting statistics about benchmark results +""" +import os +import re +import copy + +from scipy.stats import mannwhitneyu + + +class BenchmarkColor(object): + def __init__(self, name, code): + self.name = name + self.code = code + + def __repr__(self): + return '%s%r' % (self.__class__.__name__, + (self.name, self.code)) + + def __format__(self, format): + return self.code + + +# Benchmark Colors Enumeration +BC_NONE = BenchmarkColor('NONE', '') +BC_MAGENTA = BenchmarkColor('MAGENTA', '\033[95m') +BC_CYAN = BenchmarkColor('CYAN', '\033[96m') +BC_OKBLUE = BenchmarkColor('OKBLUE', '\033[94m') +BC_OKGREEN = BenchmarkColor('OKGREEN', '\033[32m') +BC_HEADER = BenchmarkColor('HEADER', '\033[92m') +BC_WARNING = BenchmarkColor('WARNING', '\033[93m') +BC_WHITE = BenchmarkColor('WHITE', '\033[97m') +BC_FAIL = BenchmarkColor('FAIL', '\033[91m') +BC_ENDC = BenchmarkColor('ENDC', '\033[0m') +BC_BOLD = BenchmarkColor('BOLD', '\033[1m') +BC_UNDERLINE = BenchmarkColor('UNDERLINE', '\033[4m') + +UTEST_MIN_REPETITIONS = 2 +UTEST_OPTIMAL_REPETITIONS = 9 # Lowest reasonable number, More is better. +UTEST_COL_NAME = "_pvalue" + + +def color_format(use_color, fmt_str, *args, **kwargs): + """ + Return the result of 'fmt_str.format(*args, **kwargs)' after transforming + 'args' and 'kwargs' according to the value of 'use_color'. If 'use_color' + is False then all color codes in 'args' and 'kwargs' are replaced with + the empty string. + """ + assert use_color is True or use_color is False + if not use_color: + args = [arg if not isinstance(arg, BenchmarkColor) else BC_NONE + for arg in args] + kwargs = {key: arg if not isinstance(arg, BenchmarkColor) else BC_NONE + for key, arg in kwargs.items()} + return fmt_str.format(*args, **kwargs) + + +def find_longest_name(benchmark_list): + """ + Return the length of the longest benchmark name in a given list of + benchmark JSON objects + """ + longest_name = 1 + for bc in benchmark_list: + if len(bc['name']) > longest_name: + longest_name = len(bc['name']) + return longest_name + + +def calculate_change(old_val, new_val): + """ + Return a float representing the decimal change between old_val and new_val. + """ + if old_val == 0 and new_val == 0: + return 0.0 + if old_val == 0: + return float(new_val - old_val) / (float(old_val + new_val) / 2) + return float(new_val - old_val) / abs(old_val) + + +def filter_benchmark(json_orig, family, replacement=""): + """ + Apply a filter to the json, and only leave the 'family' of benchmarks. + """ + regex = re.compile(family) + filtered = {} + filtered['benchmarks'] = [] + for be in json_orig['benchmarks']: + if not regex.search(be['name']): + continue + filteredbench = copy.deepcopy(be) # Do NOT modify the old name! + filteredbench['name'] = regex.sub(replacement, filteredbench['name']) + filtered['benchmarks'].append(filteredbench) + return filtered + + +def get_unique_benchmark_names(json): + """ + While *keeping* the order, give all the unique 'names' used for benchmarks. + """ + seen = set() + uniqued = [x['name'] for x in json['benchmarks'] + if x['name'] not in seen and + (seen.add(x['name']) or True)] + return uniqued + + +def intersect(list1, list2): + """ + Given two lists, get a new list consisting of the elements only contained + in *both of the input lists*, while preserving the ordering. + """ + return [x for x in list1 if x in list2] + + +def is_potentially_comparable_benchmark(x): + return ('time_unit' in x and 'real_time' in x and 'cpu_time' in x) + + +def partition_benchmarks(json1, json2): + """ + While preserving the ordering, find benchmarks with the same names in + both of the inputs, and group them. + (i.e. partition/filter into groups with common name) + """ + json1_unique_names = get_unique_benchmark_names(json1) + json2_unique_names = get_unique_benchmark_names(json2) + names = intersect(json1_unique_names, json2_unique_names) + partitions = [] + for name in names: + time_unit = None + # Pick the time unit from the first entry of the lhs benchmark. + # We should be careful not to crash with unexpected input. + for x in json1['benchmarks']: + if (x['name'] == name and is_potentially_comparable_benchmark(x)): + time_unit = x['time_unit'] + break + if time_unit is None: + continue + # Filter by name and time unit. + # All the repetitions are assumed to be comparable. + lhs = [x for x in json1['benchmarks'] if x['name'] == name and + x['time_unit'] == time_unit] + rhs = [x for x in json2['benchmarks'] if x['name'] == name and + x['time_unit'] == time_unit] + partitions.append([lhs, rhs]) + return partitions + + +def extract_field(partition, field_name): + # The count of elements may be different. We want *all* of them. + lhs = [x[field_name] for x in partition[0]] + rhs = [x[field_name] for x in partition[1]] + return [lhs, rhs] + +def calc_utest(timings_cpu, timings_time): + min_rep_cnt = min(len(timings_time[0]), + len(timings_time[1]), + len(timings_cpu[0]), + len(timings_cpu[1])) + + # Does *everything* has at least UTEST_MIN_REPETITIONS repetitions? + if min_rep_cnt < UTEST_MIN_REPETITIONS: + return False, None, None + + time_pvalue = mannwhitneyu( + timings_time[0], timings_time[1], alternative='two-sided').pvalue + cpu_pvalue = mannwhitneyu( + timings_cpu[0], timings_cpu[1], alternative='two-sided').pvalue + + return (min_rep_cnt >= UTEST_OPTIMAL_REPETITIONS), cpu_pvalue, time_pvalue + +def print_utest(partition, utest_alpha, first_col_width, use_color=True): + def get_utest_color(pval): + return BC_FAIL if pval >= utest_alpha else BC_OKGREEN + + timings_time = extract_field(partition, 'real_time') + timings_cpu = extract_field(partition, 'cpu_time') + have_optimal_repetitions, cpu_pvalue, time_pvalue = calc_utest(timings_cpu, timings_time) + + # Check if we failed miserably with minimum required repetitions for utest + if not have_optimal_repetitions and cpu_pvalue is None and time_pvalue is None: + return [] + + dsc = "U Test, Repetitions: {} vs {}".format( + len(timings_cpu[0]), len(timings_cpu[1])) + dsc_color = BC_OKGREEN + + # We still got some results to show but issue a warning about it. + if not have_optimal_repetitions: + dsc_color = BC_WARNING + dsc += ". WARNING: Results unreliable! {}+ repetitions recommended.".format( + UTEST_OPTIMAL_REPETITIONS) + + special_str = "{}{:<{}s}{endc}{}{:16.4f}{endc}{}{:16.4f}{endc}{} {}" + + last_name = partition[0][0]['name'] + return [color_format(use_color, + special_str, + BC_HEADER, + "{}{}".format(last_name, UTEST_COL_NAME), + first_col_width, + get_utest_color(time_pvalue), time_pvalue, + get_utest_color(cpu_pvalue), cpu_pvalue, + dsc_color, dsc, + endc=BC_ENDC)] + + +def generate_difference_report( + json1, + json2, + display_aggregates_only=False, + utest=False, + utest_alpha=0.05, + use_color=True): + """ + Calculate and report the difference between each test of two benchmarks + runs specified as 'json1' and 'json2'. + """ + assert utest is True or utest is False + first_col_width = find_longest_name(json1['benchmarks']) + + def find_test(name): + for b in json2['benchmarks']: + if b['name'] == name: + return b + return None + + first_col_width = max( + first_col_width, + len('Benchmark')) + first_col_width += len(UTEST_COL_NAME) + first_line = "{:<{}s}Time CPU Time Old Time New CPU Old CPU New".format( + 'Benchmark', 12 + first_col_width) + output_strs = [first_line, '-' * len(first_line)] + + partitions = partition_benchmarks(json1, json2) + for partition in partitions: + # Careful, we may have different repetition count. + for i in range(min(len(partition[0]), len(partition[1]))): + bn = partition[0][i] + other_bench = partition[1][i] + + # *If* we were asked to only display aggregates, + # and if it is non-aggregate, then skip it. + if display_aggregates_only and 'run_type' in bn and 'run_type' in other_bench: + assert bn['run_type'] == other_bench['run_type'] + if bn['run_type'] != 'aggregate': + continue + + fmt_str = "{}{:<{}s}{endc}{}{:+16.4f}{endc}{}{:+16.4f}{endc}{:14.0f}{:14.0f}{endc}{:14.0f}{:14.0f}" + + def get_color(res): + if res > 0.05: + return BC_FAIL + elif res > -0.07: + return BC_WHITE + else: + return BC_CYAN + + tres = calculate_change(bn['real_time'], other_bench['real_time']) + cpures = calculate_change(bn['cpu_time'], other_bench['cpu_time']) + output_strs += [color_format(use_color, + fmt_str, + BC_HEADER, + bn['name'], + first_col_width, + get_color(tres), + tres, + get_color(cpures), + cpures, + bn['real_time'], + other_bench['real_time'], + bn['cpu_time'], + other_bench['cpu_time'], + endc=BC_ENDC)] + + # After processing the whole partition, if requested, do the U test. + if utest: + output_strs += print_utest(partition, + utest_alpha=utest_alpha, + first_col_width=first_col_width, + use_color=use_color) + + return output_strs + + +############################################################################### +# Unit tests + + +class TestGetUniqueBenchmarkNames(unittest.TestCase): + def load_results(self): + import json + testInputs = os.path.join( + os.path.dirname( + os.path.realpath(__file__)), + 'Inputs') + testOutput = os.path.join(testInputs, 'test3_run0.json') + with open(testOutput, 'r') as f: + json = json.load(f) + return json + + def test_basic(self): + expect_lines = [ + 'BM_One', + 'BM_Two', + 'short', # These two are not sorted + 'medium', # These two are not sorted + ] + json = self.load_results() + output_lines = get_unique_benchmark_names(json) + print("\n") + print("\n".join(output_lines)) + self.assertEqual(len(output_lines), len(expect_lines)) + for i in range(0, len(output_lines)): + self.assertEqual(expect_lines[i], output_lines[i]) + + +class TestReportDifference(unittest.TestCase): + def load_results(self): + import json + testInputs = os.path.join( + os.path.dirname( + os.path.realpath(__file__)), + 'Inputs') + testOutput1 = os.path.join(testInputs, 'test1_run1.json') + testOutput2 = os.path.join(testInputs, 'test1_run2.json') + with open(testOutput1, 'r') as f: + json1 = json.load(f) + with open(testOutput2, 'r') as f: + json2 = json.load(f) + return json1, json2 + + def test_basic(self): + expect_lines = [ + ['BM_SameTimes', '+0.0000', '+0.0000', '10', '10', '10', '10'], + ['BM_2xFaster', '-0.5000', '-0.5000', '50', '25', '50', '25'], + ['BM_2xSlower', '+1.0000', '+1.0000', '50', '100', '50', '100'], + ['BM_1PercentFaster', '-0.0100', '-0.0100', '100', '99', '100', '99'], + ['BM_1PercentSlower', '+0.0100', '+0.0100', '100', '101', '100', '101'], + ['BM_10PercentFaster', '-0.1000', '-0.1000', '100', '90', '100', '90'], + ['BM_10PercentSlower', '+0.1000', '+0.1000', '100', '110', '100', '110'], + ['BM_100xSlower', '+99.0000', '+99.0000', + '100', '10000', '100', '10000'], + ['BM_100xFaster', '-0.9900', '-0.9900', + '10000', '100', '10000', '100'], + ['BM_10PercentCPUToTime', '+0.1000', + '-0.1000', '100', '110', '100', '90'], + ['BM_ThirdFaster', '-0.3333', '-0.3334', '100', '67', '100', '67'], + ['BM_NotBadTimeUnit', '-0.9000', '+0.2000', '0', '0', '0', '1'], + ] + json1, json2 = self.load_results() + output_lines_with_header = generate_difference_report( + json1, json2, use_color=False) + output_lines = output_lines_with_header[2:] + print("\n") + print("\n".join(output_lines_with_header)) + self.assertEqual(len(output_lines), len(expect_lines)) + for i in range(0, len(output_lines)): + parts = [x for x in output_lines[i].split(' ') if x] + self.assertEqual(len(parts), 7) + self.assertEqual(expect_lines[i], parts) + + +class TestReportDifferenceBetweenFamilies(unittest.TestCase): + def load_result(self): + import json + testInputs = os.path.join( + os.path.dirname( + os.path.realpath(__file__)), + 'Inputs') + testOutput = os.path.join(testInputs, 'test2_run.json') + with open(testOutput, 'r') as f: + json = json.load(f) + return json + + def test_basic(self): + expect_lines = [ + ['.', '-0.5000', '-0.5000', '10', '5', '10', '5'], + ['./4', '-0.5000', '-0.5000', '40', '20', '40', '20'], + ['Prefix/.', '-0.5000', '-0.5000', '20', '10', '20', '10'], + ['Prefix/./3', '-0.5000', '-0.5000', '30', '15', '30', '15'], + ] + json = self.load_result() + json1 = filter_benchmark(json, "BM_Z.ro", ".") + json2 = filter_benchmark(json, "BM_O.e", ".") + output_lines_with_header = generate_difference_report( + json1, json2, use_color=False) + output_lines = output_lines_with_header[2:] + print("\n") + print("\n".join(output_lines_with_header)) + self.assertEqual(len(output_lines), len(expect_lines)) + for i in range(0, len(output_lines)): + parts = [x for x in output_lines[i].split(' ') if x] + self.assertEqual(len(parts), 7) + self.assertEqual(expect_lines[i], parts) + + +class TestReportDifferenceWithUTest(unittest.TestCase): + def load_results(self): + import json + testInputs = os.path.join( + os.path.dirname( + os.path.realpath(__file__)), + 'Inputs') + testOutput1 = os.path.join(testInputs, 'test3_run0.json') + testOutput2 = os.path.join(testInputs, 'test3_run1.json') + with open(testOutput1, 'r') as f: + json1 = json.load(f) + with open(testOutput2, 'r') as f: + json2 = json.load(f) + return json1, json2 + + def test_utest(self): + expect_lines = [] + expect_lines = [ + ['BM_One', '-0.1000', '+0.1000', '10', '9', '100', '110'], + ['BM_Two', '+0.1111', '-0.0111', '9', '10', '90', '89'], + ['BM_Two', '-0.1250', '-0.1628', '8', '7', '86', '72'], + ['BM_Two_pvalue', + '0.6985', + '0.6985', + 'U', + 'Test,', + 'Repetitions:', + '2', + 'vs', + '2.', + 'WARNING:', + 'Results', + 'unreliable!', + '9+', + 'repetitions', + 'recommended.'], + ['short', '-0.1250', '-0.0625', '8', '7', '80', '75'], + ['short', '-0.4325', '-0.1351', '8', '5', '77', '67'], + ['short_pvalue', + '0.7671', + '0.1489', + 'U', + 'Test,', + 'Repetitions:', + '2', + 'vs', + '3.', + 'WARNING:', + 'Results', + 'unreliable!', + '9+', + 'repetitions', + 'recommended.'], + ['medium', '-0.3750', '-0.3375', '8', '5', '80', '53'], + ] + json1, json2 = self.load_results() + output_lines_with_header = generate_difference_report( + json1, json2, utest=True, utest_alpha=0.05, use_color=False) + output_lines = output_lines_with_header[2:] + print("\n") + print("\n".join(output_lines_with_header)) + self.assertEqual(len(output_lines), len(expect_lines)) + for i in range(0, len(output_lines)): + parts = [x for x in output_lines[i].split(' ') if x] + self.assertEqual(expect_lines[i], parts) + + +class TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly( + unittest.TestCase): + def load_results(self): + import json + testInputs = os.path.join( + os.path.dirname( + os.path.realpath(__file__)), + 'Inputs') + testOutput1 = os.path.join(testInputs, 'test3_run0.json') + testOutput2 = os.path.join(testInputs, 'test3_run1.json') + with open(testOutput1, 'r') as f: + json1 = json.load(f) + with open(testOutput2, 'r') as f: + json2 = json.load(f) + return json1, json2 + + def test_utest(self): + expect_lines = [] + expect_lines = [ + ['BM_One', '-0.1000', '+0.1000', '10', '9', '100', '110'], + ['BM_Two', '+0.1111', '-0.0111', '9', '10', '90', '89'], + ['BM_Two', '-0.1250', '-0.1628', '8', '7', '86', '72'], + ['BM_Two_pvalue', + '0.6985', + '0.6985', + 'U', + 'Test,', + 'Repetitions:', + '2', + 'vs', + '2.', + 'WARNING:', + 'Results', + 'unreliable!', + '9+', + 'repetitions', + 'recommended.'], + ['short', '-0.1250', '-0.0625', '8', '7', '80', '75'], + ['short', '-0.4325', '-0.1351', '8', '5', '77', '67'], + ['short_pvalue', + '0.7671', + '0.1489', + 'U', + 'Test,', + 'Repetitions:', + '2', + 'vs', + '3.', + 'WARNING:', + 'Results', + 'unreliable!', + '9+', + 'repetitions', + 'recommended.'], + ] + json1, json2 = self.load_results() + output_lines_with_header = generate_difference_report( + json1, json2, display_aggregates_only=True, + utest=True, utest_alpha=0.05, use_color=False) + output_lines = output_lines_with_header[2:] + print("\n") + print("\n".join(output_lines_with_header)) + self.assertEqual(len(output_lines), len(expect_lines)) + for i in range(0, len(output_lines)): + parts = [x for x in output_lines[i].split(' ') if x] + self.assertEqual(expect_lines[i], parts) + + +if __name__ == '__main__': + unittest.main() + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off; +# kate: indent-mode python; remove-trailing-spaces modified; diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/util.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/util.py new file mode 100644 index 000000000..1f8e8e2c4 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/gbench/util.py @@ -0,0 +1,164 @@ +"""util.py - General utilities for running, loading, and processing benchmarks +""" +import json +import os +import tempfile +import subprocess +import sys + +# Input file type enumeration +IT_Invalid = 0 +IT_JSON = 1 +IT_Executable = 2 + +_num_magic_bytes = 2 if sys.platform.startswith('win') else 4 + + +def is_executable_file(filename): + """ + Return 'True' if 'filename' names a valid file which is likely + an executable. A file is considered an executable if it starts with the + magic bytes for a EXE, Mach O, or ELF file. + """ + if not os.path.isfile(filename): + return False + with open(filename, mode='rb') as f: + magic_bytes = f.read(_num_magic_bytes) + if sys.platform == 'darwin': + return magic_bytes in [ + b'\xfe\xed\xfa\xce', # MH_MAGIC + b'\xce\xfa\xed\xfe', # MH_CIGAM + b'\xfe\xed\xfa\xcf', # MH_MAGIC_64 + b'\xcf\xfa\xed\xfe', # MH_CIGAM_64 + b'\xca\xfe\xba\xbe', # FAT_MAGIC + b'\xbe\xba\xfe\xca' # FAT_CIGAM + ] + elif sys.platform.startswith('win'): + return magic_bytes == b'MZ' + else: + return magic_bytes == b'\x7FELF' + + +def is_json_file(filename): + """ + Returns 'True' if 'filename' names a valid JSON output file. + 'False' otherwise. + """ + try: + with open(filename, 'r') as f: + json.load(f) + return True + except BaseException: + pass + return False + + +def classify_input_file(filename): + """ + Return a tuple (type, msg) where 'type' specifies the classified type + of 'filename'. If 'type' is 'IT_Invalid' then 'msg' is a human readable + string represeting the error. + """ + ftype = IT_Invalid + err_msg = None + if not os.path.exists(filename): + err_msg = "'%s' does not exist" % filename + elif not os.path.isfile(filename): + err_msg = "'%s' does not name a file" % filename + elif is_executable_file(filename): + ftype = IT_Executable + elif is_json_file(filename): + ftype = IT_JSON + else: + err_msg = "'%s' does not name a valid benchmark executable or JSON file" % filename + return ftype, err_msg + + +def check_input_file(filename): + """ + Classify the file named by 'filename' and return the classification. + If the file is classified as 'IT_Invalid' print an error message and exit + the program. + """ + ftype, msg = classify_input_file(filename) + if ftype == IT_Invalid: + print("Invalid input file: %s" % msg) + sys.exit(1) + return ftype + + +def find_benchmark_flag(prefix, benchmark_flags): + """ + Search the specified list of flags for a flag matching `` and + if it is found return the arg it specifies. If specified more than once the + last value is returned. If the flag is not found None is returned. + """ + assert prefix.startswith('--') and prefix.endswith('=') + result = None + for f in benchmark_flags: + if f.startswith(prefix): + result = f[len(prefix):] + return result + + +def remove_benchmark_flags(prefix, benchmark_flags): + """ + Return a new list containing the specified benchmark_flags except those + with the specified prefix. + """ + assert prefix.startswith('--') and prefix.endswith('=') + return [f for f in benchmark_flags if not f.startswith(prefix)] + + +def load_benchmark_results(fname): + """ + Read benchmark output from a file and return the JSON object. + REQUIRES: 'fname' names a file containing JSON benchmark output. + """ + with open(fname, 'r') as f: + return json.load(f) + + +def run_benchmark(exe_name, benchmark_flags): + """ + Run a benchmark specified by 'exe_name' with the specified + 'benchmark_flags'. The benchmark is run directly as a subprocess to preserve + real time console output. + RETURNS: A JSON object representing the benchmark output + """ + output_name = find_benchmark_flag('--benchmark_out=', + benchmark_flags) + is_temp_output = False + if output_name is None: + is_temp_output = True + thandle, output_name = tempfile.mkstemp() + os.close(thandle) + benchmark_flags = list(benchmark_flags) + \ + ['--benchmark_out=%s' % output_name] + + cmd = [exe_name] + benchmark_flags + print("RUNNING: %s" % ' '.join(cmd)) + exitCode = subprocess.call(cmd) + if exitCode != 0: + print('TEST FAILED...') + sys.exit(exitCode) + json_res = load_benchmark_results(output_name) + if is_temp_output: + os.unlink(output_name) + return json_res + + +def run_or_load_benchmark(filename, benchmark_flags): + """ + Get the results for a specified benchmark. If 'filename' specifies + an executable benchmark then the results are generated by running the + benchmark. Otherwise 'filename' must name a valid JSON output file, + which is loaded and the result returned. + """ + ftype = check_input_file(filename) + if ftype == IT_JSON: + return load_benchmark_results(filename) + elif ftype == IT_Executable: + return run_benchmark(filename, benchmark_flags) + else: + assert False # This branch is unreachable diff --git a/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/strip_asm.py b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/strip_asm.py new file mode 100755 index 000000000..9030550b4 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/benchmark-1.5.0/tools/strip_asm.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python + +""" +strip_asm.py - Cleanup ASM output for the specified file +""" + +from argparse import ArgumentParser +import sys +import os +import re + +def find_used_labels(asm): + found = set() + label_re = re.compile("\s*j[a-z]+\s+\.L([a-zA-Z0-9][a-zA-Z0-9_]*)") + for l in asm.splitlines(): + m = label_re.match(l) + if m: + found.add('.L%s' % m.group(1)) + return found + + +def normalize_labels(asm): + decls = set() + label_decl = re.compile("^[.]{0,1}L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)") + for l in asm.splitlines(): + m = label_decl.match(l) + if m: + decls.add(m.group(0)) + if len(decls) == 0: + return asm + needs_dot = next(iter(decls))[0] != '.' + if not needs_dot: + return asm + for ld in decls: + asm = re.sub("(^|\s+)" + ld + "(?=:|\s)", '\\1.' + ld, asm) + return asm + + +def transform_labels(asm): + asm = normalize_labels(asm) + used_decls = find_used_labels(asm) + new_asm = '' + label_decl = re.compile("^\.L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)") + for l in asm.splitlines(): + m = label_decl.match(l) + if not m or m.group(0) in used_decls: + new_asm += l + new_asm += '\n' + return new_asm + + +def is_identifier(tk): + if len(tk) == 0: + return False + first = tk[0] + if not first.isalpha() and first != '_': + return False + for i in range(1, len(tk)): + c = tk[i] + if not c.isalnum() and c != '_': + return False + return True + +def process_identifiers(l): + """ + process_identifiers - process all identifiers and modify them to have + consistent names across all platforms; specifically across ELF and MachO. + For example, MachO inserts an additional understore at the beginning of + names. This function removes that. + """ + parts = re.split(r'([a-zA-Z0-9_]+)', l) + new_line = '' + for tk in parts: + if is_identifier(tk): + if tk.startswith('__Z'): + tk = tk[1:] + elif tk.startswith('_') and len(tk) > 1 and \ + tk[1].isalpha() and tk[1] != 'Z': + tk = tk[1:] + new_line += tk + return new_line + + +def process_asm(asm): + """ + Strip the ASM of unwanted directives and lines + """ + new_contents = '' + asm = transform_labels(asm) + + # TODO: Add more things we want to remove + discard_regexes = [ + re.compile("\s+\..*$"), # directive + re.compile("\s*#(NO_APP|APP)$"), #inline ASM + re.compile("\s*#.*$"), # comment line + re.compile("\s*\.globa?l\s*([.a-zA-Z_][a-zA-Z0-9$_.]*)"), #global directive + re.compile("\s*\.(string|asciz|ascii|[1248]?byte|short|word|long|quad|value|zero)"), + ] + keep_regexes = [ + + ] + fn_label_def = re.compile("^[a-zA-Z_][a-zA-Z0-9_.]*:") + for l in asm.splitlines(): + # Remove Mach-O attribute + l = l.replace('@GOTPCREL', '') + add_line = True + for reg in discard_regexes: + if reg.match(l) is not None: + add_line = False + break + for reg in keep_regexes: + if reg.match(l) is not None: + add_line = True + break + if add_line: + if fn_label_def.match(l) and len(new_contents) != 0: + new_contents += '\n' + l = process_identifiers(l) + new_contents += l + new_contents += '\n' + return new_contents + +def main(): + parser = ArgumentParser( + description='generate a stripped assembly file') + parser.add_argument( + 'input', metavar='input', type=str, nargs=1, + help='An input assembly file') + parser.add_argument( + 'out', metavar='output', type=str, nargs=1, + help='The output file') + args, unknown_args = parser.parse_known_args() + input = args.input[0] + output = args.out[0] + if not os.path.isfile(input): + print(("ERROR: input file '%s' does not exist") % input) + sys.exit(1) + contents = None + with open(input, 'r') as f: + contents = f.read() + new_contents = process_asm(contents) + with open(output, 'w') as f: + f.write(new_contents) + + +if __name__ == '__main__': + main() + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off; +# kate: indent-mode python; remove-trailing-spaces modified; diff --git a/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CHANGES.txt b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CHANGES.txt new file mode 100644 index 000000000..b01c880dd --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CHANGES.txt @@ -0,0 +1,551 @@ +----------- +FRUIT 3.4.1 +----------- + +Maximum number of failed assertations was limited to 2000. +This limitation is removed. + + +----------- +FRUIT 3.4.0 +----------- + +A sample of calling assertations from multi-thread code +using OpenMP is added as sample_openmp. +No changes in fruit_processor in this version. +Version number of fruit_processor remains 3.3.8. + + +----------- +FRUIT 3.3.9 +----------- + +Content of fruit_util.f90 is added into fruit.f90. +No changes in fruit_processor in this version. +Version number of fruit_processor remains 3.3.8. + + +----------- +FRUIT 3.3.8 +----------- + +Fruit_processor failed to recognize the subroutine +when "!" appears on the line tester subroutine name declared. + +For example, on this code + subroutine test_some_routine !comment + ... + end subroutine +tester "test_some_routine" was ignored. +This behavior of fruit_processor is fixed now. + + +----------- +FRUIT 3.3.7 +----------- + +Samples added: + sample_using_make + This sample uses not rake but make. + Works only for gfortran + make. + + sample_exit_at_fail + Sample of exitting a test case when assertion fails. + User has to add a line + if (fruit_if_case_failed()) return + in the tester code. + +Subroutines to surppress output of "." added. + After + call fruit_hide_dots + dots are not written. + To output dots again, + call fruit_show_dots + can be used. + These calls are tested in a sample "sample_selective". + +No changes in fruit_processor in this version. +Version number of fruit_processor remains 3.3.6. + + +----------- +FRUIT 3.3.6 +----------- + +Previous version (3.3.5) could not compile +external subroutines having circular dependencies. +See + sample_circular_dep +. +Fruit 3.3.6 tries to build it +through considering some dependencies +not while compiling but while linking. + + + +----------- +FRUIT 3.3.5 +----------- + +Samples of testing external subroutine and +external functions are is at + sample_exteranl_sub/ + sample_exteranl_func/ + +External functions tested must be +specified in interface block or external statement of +tester code. +Otherwise FRUIT cannot estimate dependencies +for compile. + + +----------- +FRUIT 3.3.4 +----------- + +When tester routines are added to *_test.f90, +fruit_basket_gen.f90 is updated. +But when tester routine(s) were removed, +fruit_basket_gen.f90 was not updated. +This problem is fixed in FRUIT 3.3.4. + + +----------- +FRUIT 3.3.3 +----------- + +Time stamp of fruit_basket_gen.f90 and fruit_driver_gen.f90 +are kept when their content does not change. +This behavior surpresses unnecessary re-compile and saves your time. + + +----------- +FRUIT 3.3.2 +----------- + +In assert_not_equals subroutines, +inequality comparison for real numbers + if (real_number_1 /= real_number_2) then ... +was used. +(gfortran 4.8.2 with -Wextra option warns about it.) +The inequality is replaced by inequalities + if (real_1 < real_2 .or. real_1 > real_2) then... + + +----------- +FRUIT 3.3.1 +----------- + +Unnecessary mpi_machine_file were included in fruit_3.3.0.zip. +Removed them. + + +----------- +FRUIT 3.3.0 +----------- + +FRUIT 3.3.0 can test codes using MPI. +Sample is in directry sample_mpi. +Test code is in self_test_mpi. + +Tested on + Ubuntu 12.04 + OpenMPI + Windows 7 + MPICH2 (mpich2-1.4.1p1-win-ia32) + + +----------- +FRUIT 3.2.6 +----------- + +assert_false added. + +When execution of test stops before regular exit, +"result.xml" that reports one failure is generated. +(So far, "result.xml" of previous run remained + that usually reports no error.) + + +----------- +FRUIT 3.2.5 +----------- + +Description of samples are added to README. + +doc/changes.txt is moved to CHANGES.txt + +sample_selective/rakefile directly reads src/fruit.f90, src/fruit_util.f90. + + +----------- +FRUIT 3.2.4 +----------- + +On FTN95 output to "result.xml" become available. + +Prefix for "classname" within result.xml can be +specified by writing + + fp.xml_prefix = "some_string. " + +within rakefile. +See self_test/rakefile for example. +When Jenkins ( http://jenkins-ci.org/ ) reads this "result.xml" as JUnit result, +the prefix until period is treated as package name. + +rakefile is modified to generate ROOT_ANCHOR and fruit.f90 before running samples. + + +----------- +FRUIT 3.2.3 +----------- + +There was problem in rake_estimate.rb that +module names with upper case characters are not +processed correctly. +Fixed in this version. + + +----------- +FRUIT 3.2.2 +----------- + +On gfortran and ifort, coverage reports can be generated for samples + self_test + sample_multi_dir/build + sample_build_dir + sample_selecive. +In these directries, do "rake coverage" for generate reports such as + *.f90.gcov (gfortran) + CODE_COVERAGE.HTML (ifort) + + +FruitProcessor warns if user-specifiled filenames given in + fp.process_only = [ (filenames) ] +line not match with *_test.f(90|95|03|07) +or any of the corresponding files is absent. + + +rake_estimate.rb warns if two fortran source files +define the same module name. + + +Fixed a problem that fruit_basket_gen.f90 and fruit_driver_gen.f90 +are compiled twice when rake_estimate.rb is used. + + +----------- +FRUIT 3.2.1 +----------- + +Order of test methods can be made random by setting + fp.shuffle = true +in rakefile. For example, see self_test/rakefile. + +Fruit processor checks if test module name and its file name are consistent. +A method "module_name_consistent?" in fruit_processor_gem/lib/fruit_processor.rb +does it. + +Log output from rake_estimate.rb on file dependencies is reduced. +To see extra info on dependencies, set + $show_info = true +in rakefile. See sample_multi_dir/build/rakefile for example. + +Unnecessary dependencies given in rake_base_deps.rb are removed. + +Sample of rakefile for building main program using rake_estimate.rb is added. +See sample_selective/rakefile_main. +It estimates dependencies between modules. + + +----------- +FRUIT 3.2.0 +----------- + ++ Works on FTN95. + FTN95 is Fortran compiler for Windows. + http://www.silverfrost.com + ++ Works on gfortran of TDM-GCC on Windows. + http://tdm-gcc.tdragon.net/ + ++ To support extension .obj and backslash path, + rake_base.rb is divided into + compiler definition part (rake_base.rb) and + dependencies part (rake_base_deps.rb). + + +----------- +FRUIT 3.1.0 +----------- + ++ LICENSE.txt added + ++ Comment on copyright added to each file + ++ Samples added or changed + + + sample_build_dir + This sample puts *.o, *.mod, *_gen.f90, and executable to a sub directry. + + + sample + rakefile "rakefile_mingw" added that works with MinGW. + It does not use library. Instead fruit.f90 and fruit_util.f90 are compiled. + + + sample_multi_dir + Source files in multiple directries are compiled within single rakefile. + This sample puts *.o, *.mod, *_gen.f90, and executable to a sub directry. + Source directries are kept unchanged. + ++ FruitProcessor and rake_estimate.rb may process multiple source directries. + See sample sample_multi_dir. + + +----------- +FRUIT 3.0.2 +----------- + ++ fruit_processor_gem/rakefile + + Changed to work with rake 10.0.x + + +----------- +FRUIT 3.0.1 +----------- + ++ rake_estimate.rb + + A problem that rake_estimate.rb failed to read + lines ending in CR+LF is fixed. + + ++ setup and teardown + + When tester file (*_test.f90 etc.) did not have setup subroutine, + its teardown subroutine was not called. + Corresponding error in fruit_processor.rb is fixed. + + +----------- +FRUIT 3.0 +----------- + ++ Test runner GUI gui_fruit.rb is added. + + To use "gui_fruit.rb", other two ruby scripts + "rake_base.rb" and "rake_estimate.rb" must be in the same directory. + Before starting GUI, Fortran compiler setting in "rake_base_db" + should be edited. + + Works both for single directory projects and multiple directry projects. + Here multiple directry project means project consist of + one source directry (contains tested fortran files) and + one tester directry (contains tester fortran files *_test.f90). + For example, within fruit distribution tests + "self_test", "sample_selective", "sample_single_dir", + "in_3_minutes" and + "sample" + can be run using GUI. + + +----------- +FRUIT 2.9.2 +----------- + ++ Test of rake_estimate.rb + +A tester of rake_estimate.rb is added as ruby_test/rake_estimate_test.rb. + + ++ Change in rake_estimate.rb + +rake_estimate.rb is rewritten as a class FruitRakeEstimate. + + ++ Not copy but make symbolic links + +In the previous version, rakefile copies +fortran files (fruit.f90, fruit_util.f90) and +ruby files (rake_base.rb, rake_estimate.rb) to directries +"sample_single_dir", "sample_selective" and "in_3_minutes". +Now symbolic links are made instead of copying files. + + + +----------- +FRUIT 2.9.1 +----------- + ++ Selective build + +When there are several *_test.f90 files in a directry, +all these tester files were compiled to build fruit driver. +One may want to run only few of the tester files. +To compile only selected tester files, +method "process_only" is added to fruit_processor. +New sample "sample_selective" demonstrates it. +File(s) to compile is given in + + fp.process_only = FileList["mydict_test.f90"] + +line of sample_selective/rakefile. + + ++ When main file exists in directry + +Building fruit driver used to be failed when there was a main program +(.f90 file with "program" ... "end program" statements). +Build becomes possible by adding a line + +$main = "fruit_driver_gen.f90" + +to rakefile. It's demonstrated in samples + * sample_single_dir + * sample_selective +In these samples main file (dummy_main.f90) is +successfully ignored. + + ++ Estimation of dependencies + +When there was dependency between fortran files, +it had to be written it in rakefile. +In this release, a new script "rake_estimate.rb" is added. +It scans "module ..." lines and "use ..." lines +and estimates dependencies between Fortran files. +To use it, include it from rakefile. +Examples are + * sample/test/rakefile + * sample_selective/rakefile + * sample_single_dir/rakefile + + ++ descriptions of rake target + +Descriptions of rake target is added to rakefile. +Try "rake -T" to see the list of descriptios. + + ++ Self-tests + +A number of self-tests for fruit.f90 are added as + self_test/various_asserts_test.f90 + + ++ Generator of fruit.f90 + +To support various assertions for various types +(logical, real, double, complex-double, integer), +dimensions (0d, 1d, 2d) and equals/not-equals, +fruit.f90 is now generated using +src/fruit_f90_generator.rb and src/fruit_f90_source.txt. + + ++ Deallocate + +Array for messages used in fruit.f90 was allocated but +not deallocated. Some compiler report it as memory error. +For deallocation of it, subroutine "fruit_finalize" is added to fruit.f90. +It deallocate the array for messages. +Corresponding memory leak while running self-test is fixed. + + ++ Error fixed + +There was regression in FRUIT 2.9. +When Fortran source is updated and older corresponding +object file exists, rake did not recompile the source. +To fix it, relation between Fortran files and object files +are confirmed in rake_base.rb. + + ++ ruby 1.9.3 + +In addition to ruby 1.8.7, FRUIT works on ruby 1.9.3. + + + + +--------- +FRUIT 2.9 +--------- + ++ Extensions .f95 + +fruit_processor was processing only files with extension .f90. +Now extension .f95 is also recognized. +These extensions are hard-coded in + "fruit_processor_gem/lib/fruit_processor.rb" (around line 12) +and + "rake_base.rb" (around line 13). + + ++ Additional sample + +New sample is added to "sample_single_dir/". +It is single directory project. Before compiling, + fruit.f90, + fruit_util.f90, and + rake_base.rb +must be copied to this directory. Fruit_processor generates +fruit_driver and fruit_basket and builds driver executable. +File extension .f95 is used for testing code and tested code. +If your fortran compiler does not recognize .f95 extension, +rename the files to have .f90 extension. + + ++ Self-testing + +Test of "fruit_processor.rb" is done by +"fruit_processor_gem/test/fruit_processor_test.rb". +This test is included to default rake target of +"(tarball base dir)/rakefile" and +"(tarball base dir)/fruit_processor_gem/rakefile". + +Self tests of "src/fruit.f90" and "src/fruit_util.f90" are in +"self_test" directry. +These test are originally in "test/" directry and rewritten +as automated tests. + + ++ Spec string + +There was regression in FRUIT 2.8. +Spec string written using Fortran's continuous line did not processed. + +Now spec string specification such as + character(len=*), parameter :: spec = 'calculation should produce 4.0& + & when 2.0 & + and 2.0 & + are inputs' +is processed. Also, spec specification as Fortran's comment line + + !FRUIT_SPEC Spec string may given as Fortran's "comment" line. + +is available. + + + +--------- +FRUIT 2.8 +--------- + +1. FRUIT outputs test report in XML. + It can be read by Jenkins( http://jenkins-ci.org/ ). + A sample report appears as sample/test/result.xml + in FRUIT 2.8 release. + +2. Case names are shown in failed assertion messages + even when fruit_processor is used. + Previously __unnamed__ was shown in place of case names. + +3. Sample without rake nor rake was in "sample/taste" directry of FRUIT 2.7. + It is moved to "in_3_minutes" directry. + +4. Works both with rake 0.9.2.2 and rake 0.8.7. + +5. Debug option of fortran compiler is turned on by default. + +For example of 1. and 2. above, see fruit2.8_with_jenkins.png + + diff --git a/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CMakeLists.txt new file mode 100644 index 000000000..6d06a9f99 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/CMakeLists.txt @@ -0,0 +1,17 @@ +# Fortran unit test framework +# +# http://sourceforge.net/projects/fortranxunit +# http://www.software.ac.uk/blog/2014-07-22-look-fortran-unit-test-frameworks +# +# Modules will be installed into CMAKE_Fortran_MODULE_DIRECTORY +# defined in CMakeBasics.cmake + +blt_add_library( + NAME fruit + SOURCES fruit.f90 +) +blt_register_library( NAME fruit + FORTRAN_MODULES ${CMAKE_Fortran_MODULE_DIRECTORY} + INCLUDES ${CMAKE_Fortran_MODULE_DIRECTORY} + LIBRARIES fruit +) diff --git a/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/LICENSE.txt b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/LICENSE.txt new file mode 100644 index 000000000..86b8b8de1 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/LICENSE.txt @@ -0,0 +1,43 @@ + +License: + +Copyright (c) 2005-2010, 2012-2013, Andrew Hang Chen and contributors, +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Westinghouse Electric Company nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ANDREW HANG CHEN AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Note: +The orignal work of FRUIT was +created by Andrew Hang Chen while working at Westinghouse Electric +Company. The package was donated by Westinghouse Electric Company as +an open source project. + + +Contributors: +Andrew Hang Chen +sgould +istomoya +If you feel you should be listed here and aren't, please let us know. + + diff --git a/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/fruit.f90 b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/fruit.f90 new file mode 100644 index 000000000..be7a47a13 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/fruit-3.4.1/fruit.f90 @@ -0,0 +1,2562 @@ + +! Copyright (c) 2005-2010, 2012-2013, Andrew Hang Chen and contributors, +! All rights reserved. +! Licensed under the 3-clause BSD license. + +!------------------------ +! FORTRAN unit test utility +! +! Author: Andrew H. Chen meihome @at@ gmail.com +!------------------------ +! +! Unit test framework for FORTRAN. (FoRtran UnIT) +! +! This package is to perform unit test for FORTRAN subroutines +! +! The method used most are: assert_true, assert_equals +! +! Coding convention: +! 1) All methods must be exposed by interface. i.e. interface init_fruit +! 2) Variable and methods are lower case connected with underscores. i.e. init_fruit, and +! failed_assert_count +! + + +module fruit_util + private + + public :: equals, to_s, strip + + interface equals + module procedure equalEpsilon + module procedure floatEqual + module procedure integerEqual + module procedure doublePrecisionEqual + module procedure stringEqual + module procedure logicalEqual + end interface + + interface to_s + module procedure to_s_int_ + module procedure to_s_real_ + module procedure to_s_logical_ + module procedure to_s_double_ + module procedure to_s_complex_ + module procedure to_s_double_complex_ + module procedure to_s_string_ + end interface + + interface strip + module procedure strip_ + module procedure strip_length_ + end interface +contains + + function to_s_int_ (value) + implicit none + character(len=500):: to_s_int_ + integer, intent(in) :: value + character(len=500) :: result + write (result, *) value + to_s_int_ = adjustl(trim(result)) + end function to_s_int_ + + function to_s_real_ (value) + implicit none + character(len=500):: to_s_real_ + real, intent(in) :: value + character(len=500) :: result + write (result, *) value + to_s_real_ = adjustl(trim(result)) + end function to_s_real_ + + function to_s_double_ (value) + implicit none + character(len=500):: to_s_double_ + double precision, intent(in) :: value + character(len=500) :: result + write (result, *) value + to_s_double_ = adjustl(trim(result)) + end function to_s_double_ + + function to_s_complex_ (value) + implicit none + character(len=500):: to_s_complex_ + complex, intent(in) :: value + character(len=500) :: result + write (result, *) value + to_s_complex_ = adjustl(trim(result)) + end function to_s_complex_ + + function to_s_double_complex_ (value) + implicit none + character(len=500):: to_s_double_complex_ + complex(kind=kind(1.0D0)), intent(in) :: value + character(len=500) :: result + write (result, *) value + to_s_double_complex_ = adjustl(trim(result)) + end function to_s_double_complex_ + + function to_s_logical_ (value) + implicit none + character(len=500):: to_s_logical_ + logical, intent(in) :: value + character(len=500) :: result + write (result, *) value + to_s_logical_ = adjustl(trim(result)) + end function to_s_logical_ + + function to_s_string_ (value) + implicit none + character(len=500):: to_s_string_ + character(len=*), intent(in) :: value + to_s_string_ = value + end function to_s_string_ + + function strip_(value) + implicit none + character(len=500):: strip_ + character(len=*), intent(in) :: value + strip_ = trim(adjustl(value)) + end function strip_ + + function strip_length_(value, length) + implicit none + character(len=*), intent(in) :: value + integer, intent(in) :: length + character(len= length):: strip_length_ + strip_length_ = trim(adjustl(value)) + end function strip_length_ + + !------------------------ + ! test if 2 values are close + !------------------------ + !logical function equals (number1, number2) + ! real, intent (in) :: number1, number2 + ! + ! return equalEpsilon (number1, number2, epsilon(number1)) + ! + !end function equals + + + function equalEpsilon (number1, number2, epsilon ) result (resultValue) + real , intent (in) :: number1, number2, epsilon + logical :: resultValue + + resultValue = .false. + + ! test very small number1 + if ( abs(number1) < epsilon .and. abs(number1 - number2) < epsilon ) then + resultValue = .true. + else + if ((abs(( number1 - number2)) / number1) < epsilon ) then + resultValue = .true. + else + resultValue = .false. + end if + end if + + end function equalEpsilon + + function floatEqual (number1, number2 ) result (resultValue) + real , intent (in) :: number1, number2 + real :: epsilon + logical :: resultValue + + resultValue = .false. + epsilon = 1E-6 + + ! test very small number1 + if ( abs(number1) < epsilon .and. abs(number1 - number2) < epsilon ) then + resultValue = .true. + else + if ((abs(( number1 - number2)) / number1) < epsilon ) then + resultValue = .true. + else + resultValue = .false. + end if + end if + end function floatEqual + + function doublePrecisionEqual (number1, number2 ) result (resultValue) + double precision , intent (in) :: number1, number2 + real :: epsilon + logical :: resultValue + + resultValue = .false. + epsilon = 1E-6 + !epsilon = epsilon (number1) + + ! test very small number1 + if ( abs(number1) < epsilon .and. abs(number1 - number2) < epsilon ) then + resultValue = .true. + else + if ((abs(( number1 - number2)) / number1) < epsilon ) then + resultValue = .true. + else + resultValue = .false. + end if + end if + end function doublePrecisionEqual + + function integerEqual (number1, number2 ) result (resultValue) + integer , intent (in) :: number1, number2 + logical :: resultValue + + resultValue = .false. + + if ( number1 .eq. number2 ) then + resultValue = .true. + else + resultValue = .false. + end if + end function integerEqual + + function stringEqual (str1, str2 ) result (resultValue) + character(*) , intent (in) :: str1, str2 + logical :: resultValue + + resultValue = .false. + + if ( str1 .eq. str2 ) then + resultValue = .true. + end if + end function stringEqual + + function logicalEqual (l1, l2 ) result (resultValue) + logical, intent (in) :: l1, l2 + logical :: resultValue + + resultValue = .false. + + if ( l1 .eqv. l2 ) then + resultValue = .true. + end if + end function logicalEqual +end module fruit_util + + +module fruit + use fruit_util + implicit none + private + + integer, parameter :: STDOUT_DEFAULT = 6 + integer :: stdout = STDOUT_DEFAULT + + integer, parameter :: XML_OPEN = 20 + integer, parameter :: XML_WORK_DEFAULT = 21 + integer :: xml_work = XML_WORK_DEFAULT + character (len = *), parameter :: xml_filename = "result.xml" + character (len = *), parameter :: XML_FN_WORK_DEF = "result_tmp.xml" + character (len = 50) :: xml_filename_work = XML_FN_WORK_DEF + + integer, parameter :: MAX_NUM_FAILURES_IN_XML = 10 + integer, parameter :: XML_LINE_LENGTH = 2670 + !! xml_line_length >= max_num_failures_in_xml * (msg_length + 1) + 50 + + integer, parameter :: STRLEN_T = 12 + + integer, parameter :: NUMBER_LENGTH = 10 + + integer, parameter :: MSG_LENGTH = 256 + integer, parameter :: MAX_MSG_STACK_SIZE = 2000 + integer, parameter :: MSG_ARRAY_INCREMENT = 50 + integer, parameter :: MAX_MARKS_PER_LINE = 78 + + character(*), parameter :: DEFAULT_CASE_NAME = '_not_set_' + logical, private, parameter :: DEFAULT_CASE_PASSED = .true. + + !---------- save ---------- + integer, private, save :: successful_assert_count = 0 + integer, private, save :: failed_assert_count = 0 + + integer, private, save :: message_index = 1 + integer, private, save :: message_index_from = 1 + integer, private, save :: current_max = 50 + + character (len = MSG_LENGTH), private, allocatable :: message_array(:) + character (len = MSG_LENGTH), private, save :: msg = '[unit name not set from set_name]: ' + character (len = MSG_LENGTH), private, save :: case_name = DEFAULT_CASE_NAME + + integer, private, save :: successful_case_count = 0 + integer, private, save :: failed_case_count = 0 + integer, private, save :: testCaseIndex = 1 + logical, private, save :: last_passed = .false. + logical, private, save :: case_passed = DEFAULT_CASE_PASSED + integer, private, save :: case_time_from = 0 + integer, private, save :: linechar_count = 0 + logical, private, save :: if_show_dots = .true. + + integer, parameter :: FRUIT_PREFIX_LEN_MAX = 50 + character(len = FRUIT_PREFIX_LEN_MAX) :: prefix = "" + !---------- save ---------- + + type ty_stack + integer :: successful_assert_count + integer :: failed_assert_count + + integer :: message_index + integer :: message_index_from + integer :: current_max + + character (len = MSG_LENGTH), pointer :: message_array(:) + character (len = MSG_LENGTH) :: case_name ! = DEFAULT_CASE_NAME + + integer :: successful_case_count + integer :: failed_case_count + integer :: testCaseIndex + logical :: last_passed + logical :: case_passed = DEFAULT_CASE_PASSED + integer :: case_time_from + integer :: linechar_count + logical :: if_show_dots + end type ty_stack + + type(ty_stack), save :: stashed_suite + + public :: & + init_fruit + public :: & + get_last_message, & + is_last_passed, & + is_case_passed, & + add_success, addSuccess, & + set_unit_name, get_unit_name, & + set_case_name, get_case_name, & + failed_assert_action, get_total_count, getTotalCount, & + get_failed_count, getFailedCount, is_all_successful, isAllSuccessful, & + run_test_case, runTestCase + public :: assert_equals, assertEquals + public :: assert_not_equals, assertNotEquals + public :: assert_true, assertTrue + public :: stash_test_suite, restore_test_suite + public :: FRUIT_PREFIX_LEN_MAX + public :: override_xml_work, end_override_xml_work + public :: get_assert_and_case_count + + public :: initializeFruit + interface initializeFruit + module procedure obsolete_initializeFruit_ + end interface + + public :: getTestSummary + interface getTestSummary + module procedure obsolete_getTestSummary_ + end interface + + interface assertTrue + module procedure obsolete_assert_true_logical_ + end interface + + public :: assert_false + interface assert_false + module procedure assert_false_ + end interface + + interface assert_equals + !====== begin of generated interface ====== + module procedure assert_eq_logical_ + module procedure assert_eq_1d_logical_ + module procedure assert_eq_2d_logical_ + module procedure assert_eq_string_ + module procedure assert_eq_1d_string_ + module procedure assert_eq_2d_string_ + module procedure assert_eq_int_ + module procedure assert_eq_1d_int_ + module procedure assert_eq_2d_int_ + module procedure assert_eq_real_ + module procedure assert_eq_real_in_range_ + module procedure assert_eq_1d_real_ + module procedure assert_eq_1d_real_in_range_ + module procedure assert_eq_2d_real_ + module procedure assert_eq_2d_real_in_range_ + module procedure assert_eq_double_ + module procedure assert_eq_double_in_range_ + module procedure assert_eq_1d_double_ + module procedure assert_eq_1d_double_in_range_ + module procedure assert_eq_2d_double_ + module procedure assert_eq_2d_double_in_range_ + module procedure assert_eq_complex_ + module procedure assert_eq_complex_in_range_ + module procedure assert_eq_1d_complex_ + module procedure assert_eq_1d_complex_in_range_ + module procedure assert_eq_2d_complex_ + module procedure assert_eq_2d_complex_in_range_ + !====== end of generated inteface ====== + end interface + + interface assertEquals + !====== begin of generated interface ====== + module procedure assert_eq_logical_ + module procedure assert_eq_1d_logical_ + module procedure assert_eq_2d_logical_ + module procedure assert_eq_string_ + module procedure assert_eq_1d_string_ + module procedure assert_eq_2d_string_ + module procedure assert_eq_int_ + module procedure assert_eq_1d_int_ + module procedure assert_eq_2d_int_ + module procedure assert_eq_real_ + module procedure assert_eq_real_in_range_ + module procedure assert_eq_1d_real_ + module procedure assert_eq_1d_real_in_range_ + module procedure assert_eq_2d_real_ + module procedure assert_eq_2d_real_in_range_ + module procedure assert_eq_double_ + module procedure assert_eq_double_in_range_ + module procedure assert_eq_1d_double_ + module procedure assert_eq_1d_double_in_range_ + module procedure assert_eq_2d_double_ + module procedure assert_eq_2d_double_in_range_ + module procedure assert_eq_complex_ + module procedure assert_eq_complex_in_range_ + module procedure assert_eq_1d_complex_ + module procedure assert_eq_1d_complex_in_range_ + module procedure assert_eq_2d_complex_ + module procedure assert_eq_2d_complex_in_range_ + !====== end of generated inteface ====== + end interface + + interface assert_not_equals + !====== begin of generated interface ====== + module procedure assert_not_equals_logical_ + module procedure assert_not_equals_1d_logical_ + module procedure assert_not_equals_2d_logical_ + module procedure assert_not_equals_string_ + module procedure assert_not_equals_1d_string_ + module procedure assert_not_equals_2d_string_ + module procedure assert_not_equals_int_ + module procedure assert_not_equals_1d_int_ + module procedure assert_not_equals_2d_int_ + module procedure assert_not_equals_real_ + module procedure assert_not_equals_real_in_range_ + module procedure assert_not_equals_1d_real_ + module procedure assert_not_equals_1d_real_in_range_ + module procedure assert_not_equals_2d_real_ + module procedure assert_not_equals_2d_real_in_range_ + module procedure assert_not_equals_double_ + module procedure assert_not_equals_double_in_range_ + module procedure assert_not_equals_1d_double_ + module procedure assert_not_equals_1d_double_in_range_ + module procedure assert_not_equals_2d_double_ + module procedure assert_not_equals_2d_double_in_range_ + module procedure assert_not_equals_complex_ + module procedure assert_not_equals_complex_in_range_ + module procedure assert_not_equals_1d_complex_ + module procedure assert_not_equals_1d_complex_in_range_ + module procedure assert_not_equals_2d_complex_ + module procedure assert_not_equals_2d_complex_in_range_ + !====== end of generated inteface ====== + + end interface + + interface assertNotEquals + !====== begin of generated interface ====== + module procedure assert_not_equals_logical_ + module procedure assert_not_equals_1d_logical_ + module procedure assert_not_equals_2d_logical_ + module procedure assert_not_equals_string_ + module procedure assert_not_equals_1d_string_ + module procedure assert_not_equals_2d_string_ + module procedure assert_not_equals_int_ + module procedure assert_not_equals_1d_int_ + module procedure assert_not_equals_2d_int_ + module procedure assert_not_equals_real_ + module procedure assert_not_equals_real_in_range_ + module procedure assert_not_equals_1d_real_ + module procedure assert_not_equals_1d_real_in_range_ + module procedure assert_not_equals_2d_real_ + module procedure assert_not_equals_2d_real_in_range_ + module procedure assert_not_equals_double_ + module procedure assert_not_equals_double_in_range_ + module procedure assert_not_equals_1d_double_ + module procedure assert_not_equals_1d_double_in_range_ + module procedure assert_not_equals_2d_double_ + module procedure assert_not_equals_2d_double_in_range_ + module procedure assert_not_equals_complex_ + module procedure assert_not_equals_complex_in_range_ + module procedure assert_not_equals_1d_complex_ + module procedure assert_not_equals_1d_complex_in_range_ + module procedure assert_not_equals_2d_complex_ + module procedure assert_not_equals_2d_complex_in_range_ + !====== end of generated inteface ====== + + end interface + + interface addSuccess + module procedure obsolete_addSuccess_ + end interface + + public :: add_fail + interface add_fail + module procedure add_fail_ + module procedure add_fail_unit_ + end interface + + public :: addFail + interface addFail + module procedure add_fail_ + module procedure add_fail_unit_ + end interface + + interface getTotalCount + module procedure obsolete_getTotalCount_ + end interface + + interface getFailedCount + module procedure obsolete_getFailedCount_ + end interface + + interface isAllSuccessful + module procedure obsolete_isAllSuccessful_ + end interface + + interface run_test_case + module procedure run_test_case_ + module procedure run_test_case_named_ + end interface + + interface runTestCase + module procedure run_test_case_ + module procedure run_test_case_named_ + end interface + + public :: init_fruit_xml + interface init_fruit_xml + module procedure init_fruit_xml_ + end interface + + public :: fruit_summary + interface fruit_summary + module procedure fruit_summary_ + end interface + + public :: fruit_summary_xml + interface fruit_summary_xml + module procedure fruit_summary_xml_ + end interface + + public :: case_passed_xml + interface case_passed_xml + module procedure case_passed_xml_ + end interface + + public :: case_failed_xml + interface case_failed_xml + module procedure case_failed_xml_ + end interface + + public :: override_stdout + interface override_stdout + module procedure override_stdout_ + end interface + + public :: end_override_stdout + interface end_override_stdout + module procedure end_override_stdout_ + end interface + + interface override_xml_work + module procedure override_xml_work_ + end interface + + interface end_override_xml_work + module procedure end_override_xml_work_ + end interface + + public :: get_xml_filename_work + interface get_xml_filename_work + module procedure get_xml_filename_work_ + end interface + + public :: set_xml_filename_work + interface set_xml_filename_work + module procedure set_xml_filename_work_ + end interface + + public :: get_message_index + interface get_message_index + module procedure get_message_index_ + end interface + + public :: get_messages + interface get_messages + module procedure get_messages_ + end interface + + public :: get_message_array + interface get_message_array + module procedure get_message_array_ + end interface + + interface set_unit_name + module procedure set_case_name_ + end interface + interface set_case_name + module procedure set_case_name_ + end interface + + interface get_unit_name + module procedure get_case_name_ + end interface + interface get_case_name + module procedure get_case_name_ + end interface + + public :: fruit_finalize + interface fruit_finalize + module procedure fruit_finalize_ + end interface + + public :: set_prefix + interface set_prefix + module procedure set_prefix_ + end interface + + public :: get_prefix + interface get_prefix + module procedure get_prefix_ + end interface + + interface get_assert_and_case_count + module procedure get_assert_and_case_count_ + end interface + + public :: fruit_summary_table + interface fruit_summary_table + module procedure fruit_summary_table_ + end interface + + public :: fruit_if_case_failed + interface fruit_if_case_failed + module procedure fruit_if_case_failed_ + end interface + + public :: fruit_hide_dots + interface fruit_hide_dots + module procedure fruit_hide_dots_ + end interface + + public :: fruit_show_dots + interface fruit_show_dots + module procedure fruit_show_dots_ + end interface +contains + subroutine init_fruit(rank) + integer, intent(in), optional :: rank + logical :: if_write + + successful_assert_count = 0 + failed_assert_count = 0 + message_index = 1 + message_index_from = 1 + + if_write = .true. + if (present(rank)) then + if (rank /= 0) if_write = .false. + endif + + if (if_write) then + write (stdout,*) + write (stdout,*) "Test module initialized" + write (stdout,*) + write (stdout,*) " . : successful assert, F : failed assert " + write (stdout,*) + endif +!$omp critical (FRUIT_OMP_ALLOCATE_MESSAGE_ARRAY) + if ( .not. allocated(message_array) ) then + allocate(message_array(MSG_ARRAY_INCREMENT)) + end if +!$omp end critical (FRUIT_OMP_ALLOCATE_MESSAGE_ARRAY) + end subroutine init_fruit + + subroutine fruit_finalize_ +!$omp critical (FRUIT_OMP_DEALLOCATE_MESSAGE_ARRAY) + if (allocated(message_array)) then + deallocate(message_array) + endif +!$omp end critical (FRUIT_OMP_DEALLOCATE_MESSAGE_ARRAY) + end subroutine fruit_finalize_ + + subroutine init_fruit_xml_(rank) + integer, optional, intent(in) :: rank + logical :: rank_zero_or_single + + rank_zero_or_single = .true. + if (present(rank)) then + if (rank /= 0) then + rank_zero_or_single = .false. + endif + endif + + + if (rank_zero_or_single) then + open (XML_OPEN, file = xml_filename, action ="write", status = "replace") + write(XML_OPEN, '("")') + write(XML_OPEN, '("")') + write(XML_OPEN, '(" ")') + + write(XML_OPEN, & + & '(" ")') & + & "dummy_testcase", "dummy_classname", "0" + + write(XML_OPEN, '(a)', advance = "no") " " + write(XML_OPEN, '(" ")') + + write(XML_OPEN, '(" ")') + write(XML_OPEN, '("")') + close(XML_OPEN) + endif + + open (xml_work, FILE = xml_filename_work, action ="write", status='replace') + close(xml_work) + end subroutine init_fruit_xml_ + + function case_delta_t() + character(len = STRLEN_T) :: case_delta_t + real :: delta_t + integer :: case_time_to, time_rate, time_max + + call system_clock(case_time_to, time_rate, time_max) + if (time_rate > 0) then + delta_t = real(case_time_to - case_time_from) / real(time_rate) + if (delta_t < 0) then + delta_t = delta_t + real(time_max) / real(time_rate) + endif + else + delta_t = 0 + endif + + write(case_delta_t, '(g12.4)') delta_t + case_delta_t = adjustl(case_delta_t) + end function case_delta_t + + subroutine case_passed_xml_(tc_name, classname) + character(*), intent(in) :: tc_name + character(*), intent(in) :: classname + character(len = STRLEN_T) :: case_time + + case_time = case_delta_t() + + open (xml_work, FILE = xml_filename_work, position='append') + write(xml_work, & + & '(" ")') & + & trim(tc_name), trim(prefix), trim(classname), trim(case_time) + close(xml_work) + end subroutine case_passed_xml_ + + + subroutine case_failed_xml_(tc_name, classname) + character(*), intent(in) :: tc_name + character(*), intent(in) :: classname + integer :: i, j + character(len = STRLEN_T) :: case_time + + case_time = case_delta_t() + + open (xml_work, FILE = xml_filename_work, position='append') + write(xml_work, & + & '(" ")') & + & trim(tc_name), trim(prefix), trim(classname), trim(case_time) + + write(xml_work, '(" MAX_NUM_FAILURES_IN_XML) then + write(xml_work, '("(omit the rest)")', advance="no") + exit + endif + + write(xml_work, '(a)', advance = "no") trim(strip(message_array(i))) + + if (i == message_index - 1) then + continue + else + write(xml_work, '(" ")', advance="no") + endif + enddo + write(xml_work, '("""/>")') + + write(xml_work, & + & '(" ")') + close(xml_work) + end subroutine case_failed_xml_ + + subroutine fruit_summary_xml_ + character(len = XML_LINE_LENGTH) :: whole_line + character(len = 100) :: full_count + character(len = 100) :: fail_count + + full_count = int_to_str(successful_case_count + failed_case_count) + fail_count = int_to_str(failed_case_count) + + open (XML_OPEN, file = xml_filename, action ="write", status = "replace") + write(XML_OPEN, '("")') + write(XML_OPEN, '("")') + write(XML_OPEN, '(" ")') + + open (xml_work, FILE = xml_filename_work) + do + read(xml_work, '(a)', end = 999) whole_line + write(XML_OPEN, '(a)') trim(whole_line) + enddo +999 continue + close(xml_work) + + write(XML_OPEN, '(" ")') + write(XML_OPEN, '("")') + close(XML_OPEN) + end subroutine fruit_summary_xml_ + + function int_to_str(i) + integer, intent(in) :: i + character(LEN = NUMBER_LENGTH) :: int_to_str + + write(int_to_str, '(i10)') i + int_to_str = adjustl(int_to_str) + end function int_to_str + + subroutine obsolete_initializeFruit_ + call obsolete_ ("initializeFruit is OBSOLETE. replaced by init_fruit") + call init_fruit + end subroutine obsolete_initializeFruit_ + + subroutine obsolete_getTestSummary_ + call obsolete_ ( "getTestSummary is OBSOLETE. replaced by fruit_summary") + call fruit_summary_ + end subroutine obsolete_getTestSummary_ + + + logical function fruit_if_case_failed_() + if (failed_assert_count == 0) then + fruit_if_case_failed_ = .false. + return + endif + + if (case_passed) then + fruit_if_case_failed_ = .false. + else + fruit_if_case_failed_ = .true. + endif + end function fruit_if_case_failed_ + + + subroutine fruit_show_dots_ + if_show_dots = .true. + end subroutine fruit_show_dots_ + + + subroutine fruit_hide_dots_ + if_show_dots = .false. + end subroutine fruit_hide_dots_ + + + ! Run a named test case + subroutine run_test_case_named_( tc, tc_name ) + interface + subroutine tc() + end subroutine + end interface + character(*), intent(in) :: tc_name + + integer :: initial_failed_assert_count + + initial_failed_assert_count = failed_assert_count + + ! Set the name of the unit test + call set_case_name( tc_name ) + + last_passed = .true. + case_passed = .true. + linechar_count = 0 !! reset linechar_count for each test case. + message_index_from = message_index + call system_clock(case_time_from) + + !$OMP BARRIER + + !!! "case_passed" is true here. + !!! "case_passed" becomes .false. at the first fail of assertion + call tc() + + !$OMP BARRIER + + if ( initial_failed_assert_count .eq. failed_assert_count ) then + ! If no additional assertions failed during the run of this test case + ! then the test case was successful + successful_case_count = successful_case_count+1 + else + failed_case_count = failed_case_count+1 + end if + + testCaseIndex = testCaseIndex+1 + + ! Reset the name of the unit test back to the default + call set_case_name( DEFAULT_CASE_NAME ) + + end subroutine run_test_case_named_ + + ! Run an 'unnamed' test case + subroutine run_test_case_( tc ) + interface + subroutine tc() + end subroutine + end interface + + call run_test_case_named_( tc, '_unnamed_' ) + + end subroutine run_test_case_ + + + subroutine fruit_summary_ + integer :: i + + + write (stdout,*) + write (stdout,*) + write (stdout,*) ' Start of FRUIT summary: ' + write (stdout,*) + + if (failed_assert_count > 0) then + write (stdout,*) 'Some tests failed!' + else + write (stdout,*) 'SUCCESSFUL!' + end if + + write (stdout,*) + if ( message_index > 1) then + write (stdout,*) ' -- Failed assertion messages:' + + do i = 1, message_index - 1 + write (stdout,"(A)") ' '//trim(strip(message_array(i))) + end do + + write (stdout,*) ' -- end of failed assertion messages.' + write (stdout,*) + else + write (stdout,*) ' No messages ' + end if + + if (successful_assert_count + failed_assert_count /= 0) then + call fruit_summary_table_(& + & successful_assert_count, failed_assert_count, & + & successful_case_count, failed_case_count & + &) + end if + write (stdout, *) ' -- end of FRUIT summary' + end subroutine fruit_summary_ + + subroutine fruit_summary_table_(& + & succ_assert, fail_assert, & + & succ_case , fail_case & + &) + integer, intent(in) :: succ_assert, fail_assert + integer, intent(in) :: succ_case , fail_case + + write (stdout,*) 'Total asserts : ', succ_assert + fail_assert + write (stdout,*) 'Successful : ', succ_assert + write (stdout,*) 'Failed : ', fail_assert + write (stdout,'("Successful rate: ",f6.2,"%")') real(succ_assert) * 100.0 / & + real (succ_assert + fail_assert) + write (stdout, *) + write (stdout,*) 'Successful asserts / total asserts : [ ',& + succ_assert, '/', succ_assert + fail_assert, ' ]' + write (stdout,*) 'Successful cases / total cases : [ ', succ_case, '/', & + succ_case + fail_case, ' ]' + end subroutine fruit_summary_table_ + + subroutine obsolete_addSuccess_ + call obsolete_ ("addSuccess is OBSOLETE. replaced by add_success") + call add_success + end subroutine obsolete_addSuccess_ + + subroutine add_fail_ (message) + character (*), intent (in), optional :: message + call failed_assert_action('none', 'none', message, if_is = .true.) + end subroutine add_fail_ + + subroutine add_fail_unit_ (unitName, message) + character (*), intent (in) :: unitName + character (*), intent (in) :: message + + call add_fail_ ("[in " // unitName // "(fail)]: " // message) + end subroutine add_fail_unit_ + + subroutine obsolete_isAllSuccessful_(result) + logical, intent(out) :: result + call obsolete_ ('subroutine isAllSuccessful is changed to function is_all_successful.') + result = (failed_assert_count .eq. 0 ) + end subroutine obsolete_isAllSuccessful_ + + subroutine is_all_successful(result) + logical, intent(out) :: result + result= (failed_assert_count .eq. 0 ) + end subroutine is_all_successful + + ! Private, helper routine to wrap lines of success/failed marks + subroutine output_mark_( chr ) + character(1), intent(in) :: chr + !! integer, save :: linechar_count = 0 + !! Definition of linechar_count is moved to module, + !! so that it can be stashed and restored. + + !$omp critical (FRUIT_OMP_ADD_OUTPUT_MARK) + linechar_count = linechar_count + 1 + if ( linechar_count .lt. MAX_MARKS_PER_LINE ) then + write(stdout,"(A1)",ADVANCE='NO') chr + else + write(stdout,"(A1)",ADVANCE='YES') chr + linechar_count = 0 + endif + !$omp end critical (FRUIT_OMP_ADD_OUTPUT_MARK) + end subroutine output_mark_ + + subroutine success_mark_ + call output_mark_( '.' ) + end subroutine success_mark_ + + subroutine failed_mark_ + call output_mark_( 'F' ) + end subroutine failed_mark_ + + subroutine increase_message_stack_ + character(len=MSG_LENGTH) :: msg_swap_holder(current_max) + + if (message_index > MAX_MSG_STACK_SIZE) then + return + end if + + if (message_index > current_max) then + msg_swap_holder(1:current_max) = message_array(1:current_max) + deallocate(message_array) + current_max = current_max + MSG_ARRAY_INCREMENT + allocate(message_array(current_max)) + message_array(1:current_max - MSG_ARRAY_INCREMENT) & + = msg_swap_holder(1: current_max - MSG_ARRAY_INCREMENT) + end if + + message_array (message_index) = msg + if (message_index == MAX_MSG_STACK_SIZE) then + message_array(message_index) = "Max number of messages reached. Further messages suppressed." + endif + + message_index = message_index + 1 + + if (message_index > MAX_MSG_STACK_SIZE) then + write(stdout,*) "Stop because there are too many error messages to put into stack." + write(stdout,*) "Try to increase MAX_MSG_STACK_SIZE if you really need so." + end if + end subroutine increase_message_stack_ + + + subroutine get_xml_filename_work_(string) + character(len = *), intent(out) :: string + string = trim(xml_filename_work) + end subroutine get_xml_filename_work_ + + subroutine set_xml_filename_work_(string) + character(len = *), intent(in) :: string + xml_filename_work = trim(string) + end subroutine set_xml_filename_work_ + + + function get_last_message() + character(len=MSG_LENGTH) :: get_last_message + if (message_index > 1) then + get_last_message = strip(message_array(message_index-1), MSG_LENGTH) + else + get_last_message = '' + end if + end function get_last_message + + subroutine get_message_index_(index) + integer, intent(out) :: index + + index = message_index + end subroutine get_message_index_ + + + subroutine get_message_array_(msgs) + character(len = *), intent(out) :: msgs(:) + integer :: i + msgs(:) = "" + + do i = 1, message_index - 1 + msgs(i) = trim(strip(message_array(i))) + enddo + end subroutine get_message_array_ + + + subroutine get_messages_(msgs) + character(len = *), intent(out) :: msgs(:) + integer :: i, j + + msgs(:) = "" + do i = message_index_from, message_index - 1 + j = i - message_index_from + 1 + if (j > ubound(msgs, 1)) exit + msgs(j) = trim(strip(message_array(i))) + enddo + end subroutine get_messages_ + + subroutine obsolete_getTotalCount_ (count) + integer, intent (out) :: count + call obsolete_ (' getTotalCount subroutine is replaced by function get_total_count') + call get_total_count(count) + end subroutine obsolete_getTotalCount_ + + subroutine get_total_count(count) + integer, intent(out) :: count + + count = successful_assert_count + failed_assert_count + end subroutine get_total_count + + subroutine obsolete_getFailedCount_ (count) + integer, intent (out) :: count + + call obsolete_ (' getFailedCount subroutine is replaced by function get_failed_count') + call get_failed_count (count) + + end subroutine obsolete_getFailedCount_ + + subroutine get_failed_count (count) + integer, intent(out) :: count + count = failed_assert_count + end subroutine get_failed_count + + subroutine obsolete_ (message) + character (*), intent (in), optional :: message + write (stdout,*) + write (stdout,*) "<<<<<<<<<<<<<<<<<<<<<<<<<< WARNING from FRUIT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + write (stdout,*) message + write (stdout,*) + write (stdout,*) " old calls will be replaced in the next release in Jan 2009" + write (stdout,*) " Naming convention for all the method calls are changed to: first_name from" + write (stdout,*) " firstName. Subroutines that will be deleted: assertEquals, assertNotEquals," + write (stdout,*) " assertTrue, addSuccessful, addFail, etc." + write (stdout,*) "<<<<<<<<<<<<<<<<<<<<<<<<<< WARNING from FRUIT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + write (stdout,*) + end subroutine obsolete_ + + subroutine add_success + !$omp critical (FRUIT_OMP_ADD_SUCCESS) + successful_assert_count = successful_assert_count + 1 + last_passed = .true. + !$omp end critical (FRUIT_OMP_ADD_SUCCESS) + + if (if_show_dots) then + call success_mark_ + endif + end subroutine add_success + + subroutine failed_assert_action (expected, got, message, if_is) + character(*), intent(in) :: expected, got + character(*), intent(in), optional :: message + logical, intent(in), optional :: if_is + + !$omp critical (FRUIT_OMP_ADD_FAIL) + if (present(if_is)) then + call make_error_msg_ (expected, got, if_is, message) + else + call make_error_msg_ (expected, got, .true., message) + endif + call increase_message_stack_ + failed_assert_count = failed_assert_count + 1 + last_passed = .false. + case_passed = .false. + !$omp end critical (FRUIT_OMP_ADD_FAIL) + call failed_mark_ + end subroutine failed_assert_action + + subroutine set_case_name_(value) + character(*), intent(in) :: value + case_name = strip(value, MSG_LENGTH) + end subroutine set_case_name_ + + subroutine get_case_name_(value) + character(*), intent(out) :: value + value = strip(case_name) + end subroutine get_case_name_ + + subroutine make_error_msg_ (var1, var2, if_is, message) + character(*), intent(in) :: var1, var2 + logical, intent(in) :: if_is + character(*), intent(in), optional :: message + + msg = '[' // trim(strip(case_name)) // ']: ' + if (if_is) then + msg = trim(msg) // 'Expected' + else + msg = trim(msg) // 'Expected Not' + endif + msg = trim(msg) // " " // '[' // trim(strip(var1)) // '], ' + msg = trim(msg) // " " // 'Got' + msg = trim(msg) // " " // '[' // trim(strip(var2)) // ']' + + if (present(message)) then + msg = trim(msg) // '; User message: [' // trim(message) // ']' + endif + end subroutine make_error_msg_ + + function is_last_passed() + logical:: is_last_passed + is_last_passed = last_passed + end function is_last_passed + + function is_case_passed() + logical:: is_case_passed + is_case_passed = case_passed + end function is_case_passed + + subroutine override_stdout_(write_unit, filename) + integer, intent(in) :: write_unit + character(len = *), intent(in) :: filename + + stdout = write_unit + open(stdout, file = filename, action = "write", status = "replace") + end subroutine override_stdout_ + + subroutine override_xml_work_(new_unit, filename) + integer, intent(in) :: new_unit + character(len = *), intent(in) :: filename + + xml_work = new_unit + xml_filename_work = filename + open(xml_work, file = filename, action = "write", status = "replace") + end subroutine override_xml_work_ + + subroutine stash_test_suite + stashed_suite%successful_assert_count = successful_assert_count + successful_assert_count = 0 + + stashed_suite%failed_assert_count = failed_assert_count + failed_assert_count = 0 + + allocate(stashed_suite%message_array(current_max)) + stashed_suite%message_array(1:message_index) = & + & message_array(1:message_index) + deallocate(message_array) + allocate(message_array(MSG_ARRAY_INCREMENT)) + + stashed_suite%message_index = message_index + message_index = 1 + stashed_suite%message_index_from = message_index_from + message_index_from = 1 + + stashed_suite%current_max = current_max + current_max = 50 + stashed_suite%successful_case_count = successful_case_count + successful_case_count = 0 + stashed_suite%failed_case_count = failed_case_count + failed_case_count = 0 + stashed_suite%testCaseIndex = testCaseIndex + testCaseIndex = 1 + stashed_suite%case_name = case_name + case_name = DEFAULT_CASE_NAME + + stashed_suite%last_passed = last_passed + last_passed = .false. + stashed_suite%case_passed = case_passed + case_passed = DEFAULT_CASE_PASSED + stashed_suite%case_time_from = case_time_from + case_time_from = 0 + stashed_suite%linechar_count = linechar_count + linechar_count = 0 + stashed_suite%if_show_dots = if_show_dots + if_show_dots = .true. + end subroutine stash_test_suite + + subroutine restore_test_suite + successful_assert_count = stashed_suite%successful_assert_count + failed_assert_count = stashed_suite%failed_assert_count + + message_index = stashed_suite%message_index + message_index_from = stashed_suite%message_index_from + current_max = stashed_suite%current_max + + deallocate(message_array) + allocate( message_array(current_max)) + message_array(1:message_index) = & + & stashed_suite%message_array(1:message_index) + deallocate(stashed_suite%message_array) + + successful_case_count = stashed_suite%successful_case_count + failed_case_count = stashed_suite%failed_case_count + testCaseIndex = stashed_suite%testCaseIndex + + case_name = stashed_suite%case_name + last_passed = stashed_suite%last_passed + case_passed = stashed_suite%case_passed + case_time_from = stashed_suite%case_time_from + linechar_count = stashed_suite%linechar_count + if_show_dots = stashed_suite%if_show_dots + end subroutine restore_test_suite + + subroutine end_override_stdout_ + close(stdout) + stdout = STDOUT_DEFAULT + end subroutine end_override_stdout_ + + subroutine end_override_xml_work_ + close(xml_work) + xml_work = XML_WORK_DEFAULT + xml_filename_work = XML_FN_WORK_DEF + end subroutine end_override_xml_work_ + + subroutine set_prefix_(str) + character (len = *), intent(in) :: str + character (len = len_trim(str)) :: str2 + + str2 = trim(adjustl(str)) + if (len_trim(str2) <= FRUIT_PREFIX_LEN_MAX) then + prefix = str2 + else + prefix = str2(1:FRUIT_PREFIX_LEN_MAX) + endif + end subroutine set_prefix_ + + subroutine get_prefix_(str) + character (len = *), intent(out) :: str + + if (len(str) <= len(prefix)) then + str = trim(prefix) + else + str = prefix + endif + end subroutine get_prefix_ + + subroutine get_assert_and_case_count_(fail_assert, suc_assert, fail_case, suc_case) + integer, intent(out) :: fail_assert, suc_assert, fail_case, suc_case + + fail_assert = failed_assert_count + suc_assert = successful_assert_count + fail_case = failed_case_count + suc_case = successful_case_count + end subroutine get_assert_and_case_count_ + + + !-------------------------------------------------------------------------------- + ! all assertions + !-------------------------------------------------------------------------------- + subroutine obsolete_assert_true_logical_(var1, message) + logical, intent (in) :: var1 + character (*), intent (in), optional :: message + + call obsolete_ ('assertTrue subroutine is replaced by function assert_true') + call assert_true(var1, message) + end subroutine obsolete_assert_true_logical_ + + subroutine assert_true (var1, message) + logical, intent (in) :: var1 + character (*), intent (in), optional :: message + + if ( var1 .eqv. .true.) then + call add_success + else + call failed_assert_action(to_s(.true.), to_s(var1), message, if_is = .true.) + end if + end subroutine assert_true + + + subroutine assert_false_(var1, message) + logical, intent(in) :: var1 + character(len = *), intent(in), optional :: message + + if (var1 .eqv. .false.) then + call add_success + else + call failed_assert_action(to_s(.true.), to_s(var1), message, if_is = .false.) + endif + end subroutine assert_false_ + + !====== begin of generated code ====== + !------ 0d_logical ------ + subroutine assert_eq_logical_(var1, var2, message) + + logical, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + + if (var1 .neqv. var2) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_logical_ + + !------ 1d_logical ------ + subroutine assert_eq_1d_logical_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + logical, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + do i = 1, n + if (var1(i) .neqv. var2(i)) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_logical_ + + !------ 2d_logical ------ + subroutine assert_eq_2d_logical_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + logical, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if (var1(i, j) .neqv. var2(i, j)) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_logical_ + + !------ 0d_string ------ + subroutine assert_eq_string_(var1, var2, message) + + character (len = *), intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + + if (trim(strip(var1)) /= trim(strip(var2))) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_string_ + + !------ 1d_string ------ + subroutine assert_eq_1d_string_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + character (len = *), intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + do i = 1, n + if (trim(strip(var1(i))) /= trim(strip(var2(i)))) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_string_ + + !------ 2d_string ------ + subroutine assert_eq_2d_string_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + character (len = *), intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if (trim(strip(var1(i, j))) /= trim(strip(var2(i, j)))) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_string_ + + !------ 0d_int ------ + subroutine assert_eq_int_(var1, var2, message) + + integer, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + + if (var1 /= var2) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_int_ + + !------ 1d_int ------ + subroutine assert_eq_1d_int_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + integer, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + do i = 1, n + if (var1(i) /= var2(i)) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_int_ + + !------ 2d_int ------ + subroutine assert_eq_2d_int_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + integer, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if (var1(i, j) /= var2(i, j)) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_int_ + + !------ 0d_real ------ + subroutine assert_eq_real_(var1, var2, message) + + real, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + + if ((var1 < var2) .or. (var1 > var2)) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_real_ + + !------ 0d_real ------ + subroutine assert_eq_real_in_range_(var1, var2, delta, message) + + real, intent (in) :: var1, var2 + real, intent (in) :: delta + character(len = *), intent (in), optional :: message + + if (abs(var1 - var2) > delta) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_real_in_range_ + + !------ 1d_real ------ + subroutine assert_eq_1d_real_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + real, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + do i = 1, n + if ((var1(i) < var2(i)) .or. (var1(i) > var2(i))) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_real_ + + !------ 1d_real ------ + subroutine assert_eq_1d_real_in_range_(var1, var2, n, delta, message) + integer, intent (in) :: n + integer :: i + real, intent (in) :: var1(n), var2(n) + real, intent (in) :: delta + character(len = *), intent (in), optional :: message + do i = 1, n + if (abs(var1(i) - var2(i)) > delta) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_real_in_range_ + + !------ 2d_real ------ + subroutine assert_eq_2d_real_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + real, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if ((var1(i, j) < var2(i, j)) .or. (var1(i, j) > var2(i, j))) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_real_ + + !------ 2d_real ------ + subroutine assert_eq_2d_real_in_range_(var1, var2, n, m, delta, message) + integer, intent (in) :: n, m + integer :: i, j + real, intent (in) :: var1(n, m), var2(n, m) + real, intent (in) :: delta + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if (abs(var1(i, j) - var2(i, j)) > delta) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_real_in_range_ + + !------ 0d_double ------ + subroutine assert_eq_double_(var1, var2, message) + + double precision, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + + if ((var1 < var2) .or. (var1 > var2)) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_double_ + + !------ 0d_double ------ + subroutine assert_eq_double_in_range_(var1, var2, delta, message) + + double precision, intent (in) :: var1, var2 + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + + if (abs(var1 - var2) > delta) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_double_in_range_ + + !------ 1d_double ------ + subroutine assert_eq_1d_double_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + double precision, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + do i = 1, n + if ((var1(i) < var2(i)) .or. (var1(i) > var2(i))) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_double_ + + !------ 1d_double ------ + subroutine assert_eq_1d_double_in_range_(var1, var2, n, delta, message) + integer, intent (in) :: n + integer :: i + double precision, intent (in) :: var1(n), var2(n) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + do i = 1, n + if (abs(var1(i) - var2(i)) > delta) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_double_in_range_ + + !------ 2d_double ------ + subroutine assert_eq_2d_double_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + double precision, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if ((var1(i, j) < var2(i, j)) .or. (var1(i, j) > var2(i, j))) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_double_ + + !------ 2d_double ------ + subroutine assert_eq_2d_double_in_range_(var1, var2, n, m, delta, message) + integer, intent (in) :: n, m + integer :: i, j + double precision, intent (in) :: var1(n, m), var2(n, m) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if (abs(var1(i, j) - var2(i, j)) > delta) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_double_in_range_ + + !------ 0d_complex ------ + subroutine assert_eq_complex_(var1, var2, message) + + complex(kind=kind(1.0D0)), intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + + if ((real (var1) < real (var2)) .or. & +&(real (var1) > real (var2)) .or. & +&(aimag(var1) < aimag(var2)) .or. & +&(aimag(var1) > aimag(var2))) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_complex_ + + !------ 0d_complex ------ + subroutine assert_eq_complex_in_range_(var1, var2, delta, message) + + complex(kind=kind(1.0D0)), intent (in) :: var1, var2 + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + + if (abs(var1 - var2) > delta) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .true.) + return + endif + + call add_success + end subroutine assert_eq_complex_in_range_ + + !------ 1d_complex ------ + subroutine assert_eq_1d_complex_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + complex(kind=kind(1.0D0)), intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + do i = 1, n + if ((real (var1(i)) < real (var2(i))) .or. & +&(real (var1(i)) > real (var2(i))) .or. & +&(aimag(var1(i)) < aimag(var2(i))) .or. & +&(aimag(var1(i)) > aimag(var2(i)))) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_complex_ + + !------ 1d_complex ------ + subroutine assert_eq_1d_complex_in_range_(var1, var2, n, delta, message) + integer, intent (in) :: n + integer :: i + complex(kind=kind(1.0D0)), intent (in) :: var1(n), var2(n) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + do i = 1, n + if (abs(var1(i) - var2(i)) > delta) then + call failed_assert_action(& + & to_s(var1(i)), & + & to_s(var2(i)), '1d array has difference, ' // message, if_is = .true.) + return + endif + enddo + call add_success + end subroutine assert_eq_1d_complex_in_range_ + + !------ 2d_complex ------ + subroutine assert_eq_2d_complex_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + complex(kind=kind(1.0D0)), intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if ((real (var1(i, j)) < real (var2(i, j))) .or. & +&(real (var1(i, j)) > real (var2(i, j))) .or. & +&(aimag(var1(i, j)) < aimag(var2(i, j))) .or. & +&(aimag(var1(i, j)) > aimag(var2(i, j)))) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_complex_ + + !------ 2d_complex ------ + subroutine assert_eq_2d_complex_in_range_(var1, var2, n, m, delta, message) + integer, intent (in) :: n, m + integer :: i, j + complex(kind=kind(1.0D0)), intent (in) :: var1(n, m), var2(n, m) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + do j = 1, m + do i = 1, n + if (abs(var1(i, j) - var2(i, j)) > delta) then + call failed_assert_action(& + & to_s(var1(i, j)), & + & to_s(var2(i, j)), '2d array has difference, ' // message, if_is = .true.) + return + endif + enddo + enddo + call add_success + end subroutine assert_eq_2d_complex_in_range_ + + !------ 0d_logical ------ + subroutine assert_not_equals_logical_(var1, var2, message) + + logical, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if (var1 .neqv. var2) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_logical_ + + !------ 1d_logical ------ + subroutine assert_not_equals_1d_logical_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + logical, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if (var1(i) .neqv. var2(i)) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_logical_ + + !------ 2d_logical ------ + subroutine assert_not_equals_2d_logical_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + logical, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if (var1(i, j) .neqv. var2(i, j)) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_logical_ + + !------ 0d_string ------ + subroutine assert_not_equals_string_(var1, var2, message) + + character (len = *), intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if (trim(strip(var1)) /= trim(strip(var2))) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_string_ + + !------ 1d_string ------ + subroutine assert_not_equals_1d_string_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + character (len = *), intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if (trim(strip(var1(i))) /= trim(strip(var2(i)))) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_string_ + + !------ 2d_string ------ + subroutine assert_not_equals_2d_string_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + character (len = *), intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if (trim(strip(var1(i, j))) /= trim(strip(var2(i, j)))) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_string_ + + !------ 0d_int ------ + subroutine assert_not_equals_int_(var1, var2, message) + + integer, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if (var1 /= var2) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_int_ + + !------ 1d_int ------ + subroutine assert_not_equals_1d_int_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + integer, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if (var1(i) /= var2(i)) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_int_ + + !------ 2d_int ------ + subroutine assert_not_equals_2d_int_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + integer, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if (var1(i, j) /= var2(i, j)) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_int_ + + !------ 0d_real ------ + subroutine assert_not_equals_real_(var1, var2, message) + + real, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if ((var1 < var2) .or. (var1 > var2)) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_real_ + + !------ 0d_real ------ + subroutine assert_not_equals_real_in_range_(var1, var2, delta, message) + + real, intent (in) :: var1, var2 + real, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if (abs(var1 - var2) > delta) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_real_in_range_ + + !------ 1d_real ------ + subroutine assert_not_equals_1d_real_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + real, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if ((var1(i) < var2(i)) .or. (var1(i) > var2(i))) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_real_ + + !------ 1d_real ------ + subroutine assert_not_equals_1d_real_in_range_(var1, var2, n, delta, message) + integer, intent (in) :: n + integer :: i + real, intent (in) :: var1(n), var2(n) + real, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if (abs(var1(i) - var2(i)) > delta) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_real_in_range_ + + !------ 2d_real ------ + subroutine assert_not_equals_2d_real_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + real, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if ((var1(i, j) < var2(i, j)) .or. (var1(i, j) > var2(i, j))) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_real_ + + !------ 2d_real ------ + subroutine assert_not_equals_2d_real_in_range_(var1, var2, n, m, delta, message) + integer, intent (in) :: n, m + integer :: i, j + real, intent (in) :: var1(n, m), var2(n, m) + real, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if (abs(var1(i, j) - var2(i, j)) > delta) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_real_in_range_ + + !------ 0d_double ------ + subroutine assert_not_equals_double_(var1, var2, message) + + double precision, intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if ((var1 < var2) .or. (var1 > var2)) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_double_ + + !------ 0d_double ------ + subroutine assert_not_equals_double_in_range_(var1, var2, delta, message) + + double precision, intent (in) :: var1, var2 + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if (abs(var1 - var2) > delta) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_double_in_range_ + + !------ 1d_double ------ + subroutine assert_not_equals_1d_double_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + double precision, intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if ((var1(i) < var2(i)) .or. (var1(i) > var2(i))) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_double_ + + !------ 1d_double ------ + subroutine assert_not_equals_1d_double_in_range_(var1, var2, n, delta, message) + integer, intent (in) :: n + integer :: i + double precision, intent (in) :: var1(n), var2(n) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if (abs(var1(i) - var2(i)) > delta) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_double_in_range_ + + !------ 2d_double ------ + subroutine assert_not_equals_2d_double_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + double precision, intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if ((var1(i, j) < var2(i, j)) .or. (var1(i, j) > var2(i, j))) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_double_ + + !------ 2d_double ------ + subroutine assert_not_equals_2d_double_in_range_(var1, var2, n, m, delta, message) + integer, intent (in) :: n, m + integer :: i, j + double precision, intent (in) :: var1(n, m), var2(n, m) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if (abs(var1(i, j) - var2(i, j)) > delta) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_double_in_range_ + + !------ 0d_complex ------ + subroutine assert_not_equals_complex_(var1, var2, message) + + complex(kind=kind(1.0D0)), intent (in) :: var1, var2 + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if ((real (var1) < real (var2)) .or. & +&(real (var1) > real (var2)) .or. & +&(aimag(var1) < aimag(var2)) .or. & +&(aimag(var1) > aimag(var2))) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_complex_ + + !------ 0d_complex ------ + subroutine assert_not_equals_complex_in_range_(var1, var2, delta, message) + + complex(kind=kind(1.0D0)), intent (in) :: var1, var2 + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + + if (abs(var1 - var2) > delta) then + same_so_far = .false. + endif + + if (same_so_far) then + call failed_assert_action(& + & to_s(var1), & + & to_s(var2), message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_complex_in_range_ + + !------ 1d_complex ------ + subroutine assert_not_equals_1d_complex_(var1, var2, n, message) + integer, intent (in) :: n + integer :: i + complex(kind=kind(1.0D0)), intent (in) :: var1(n), var2(n) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if ((real (var1(i)) < real (var2(i))) .or. & +&(real (var1(i)) > real (var2(i))) .or. & +&(aimag(var1(i)) < aimag(var2(i))) .or. & +&(aimag(var1(i)) > aimag(var2(i)))) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_complex_ + + !------ 1d_complex ------ + subroutine assert_not_equals_1d_complex_in_range_(var1, var2, n, delta, message) + integer, intent (in) :: n + integer :: i + complex(kind=kind(1.0D0)), intent (in) :: var1(n), var2(n) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do i = 1, n + if (abs(var1(i) - var2(i)) > delta) then + same_so_far = .false. + endif + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1)), & + & to_s(var2(1)), '1d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_1d_complex_in_range_ + + !------ 2d_complex ------ + subroutine assert_not_equals_2d_complex_(var1, var2, n, m, message) + integer, intent (in) :: n, m + integer :: i, j + complex(kind=kind(1.0D0)), intent (in) :: var1(n, m), var2(n, m) + + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if ((real (var1(i, j)) < real (var2(i, j))) .or. & +&(real (var1(i, j)) > real (var2(i, j))) .or. & +&(aimag(var1(i, j)) < aimag(var2(i, j))) .or. & +&(aimag(var1(i, j)) > aimag(var2(i, j)))) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_complex_ + + !------ 2d_complex ------ + subroutine assert_not_equals_2d_complex_in_range_(var1, var2, n, m, delta, message) + integer, intent (in) :: n, m + integer :: i, j + complex(kind=kind(1.0D0)), intent (in) :: var1(n, m), var2(n, m) + double precision, intent (in) :: delta + character(len = *), intent (in), optional :: message + logical :: same_so_far + + same_so_far = .true. + do j = 1, m + do i = 1, n + if (abs(var1(i, j) - var2(i, j)) > delta) then + same_so_far = .false. + endif + enddo + enddo + if (same_so_far) then + call failed_assert_action(& + & to_s(var1(1, 1)), & + & to_s(var2(1, 1)), '2d array has no difference, ' // message, if_is = .false.) + return + endif + call add_success + end subroutine assert_not_equals_2d_complex_in_range_ + + !====== end of generated code ====== + +end module fruit + + diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.gitignore b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.gitignore new file mode 100755 index 000000000..ce310bc35 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.gitignore @@ -0,0 +1,2 @@ +# Ignore CI build directory +build/ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.travis.yml b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.travis.yml new file mode 100755 index 000000000..3204dfac1 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/.travis.yml @@ -0,0 +1,46 @@ +# Build matrix / environment variable are explained on: +# http://about.travis-ci.org/docs/user/build-configuration/ +# This file can be validated on: +# http://lint.travis-ci.org/ + +install: +# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available. +- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi +# /usr/bin/clang is 3.4, lets override with modern one. +- if [ "$CXX" = "clang++" ] && [ "$TRAVIS_OS_NAME" = "linux" ]; then export CXX="clang++-3.7" CC="clang-3.7"; fi +- echo ${PATH} +- echo ${CXX} +- ${CXX} --version +- ${CXX} -v +addons: + apt: + # List of whitelisted in travis packages for ubuntu-precise can be found here: + # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise + # List of whitelisted in travis apt-sources: + # https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.7 + packages: + - gcc-4.9 + - g++-4.9 + - clang-3.7 + - valgrind +os: + - linux + - osx +language: cpp +compiler: + - gcc + - clang +script: ./travis.sh +env: + matrix: + - GTEST_TARGET=googletest SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE + - GTEST_TARGET=googlemock SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE + - GTEST_TARGET=googlemock SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug CXX_FLAGS=-std=c++11 VERBOSE_MAKE=true VERBOSE +# - GTEST_TARGET=googletest SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false +# - GTEST_TARGET=googlemock SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false +notifications: + email: false +sudo: false diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/BUILD.bazel b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/BUILD.bazel new file mode 100644 index 000000000..9b48aee53 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/BUILD.bazel @@ -0,0 +1,179 @@ +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Bazel Build for Google C++ Testing Framework(Google Test) + +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +config_setting( + name = "windows", + constraint_values = ["@bazel_tools//platforms:windows"], +) + +config_setting( + name = "has_absl", + values = {"define": "absl=1"}, +) + +# Library that defines the FRIEND_TEST macro. +cc_library( + name = "gtest_prod", + hdrs = ["googletest/include/gtest/gtest_prod.h"], + includes = ["googletest/include"], +) + +# Google Test including Google Mock +cc_library( + name = "gtest", + srcs = glob( + include = [ + "googletest/src/*.cc", + "googletest/src/*.h", + "googletest/include/gtest/**/*.h", + "googlemock/src/*.cc", + "googlemock/include/gmock/**/*.h", + ], + exclude = [ + "googletest/src/gtest-all.cc", + "googletest/src/gtest_main.cc", + "googlemock/src/gmock-all.cc", + "googlemock/src/gmock_main.cc", + ], + ), + hdrs = glob([ + "googletest/include/gtest/*.h", + "googlemock/include/gmock/*.h", + ]), + copts = select({ + ":windows": [], + "//conditions:default": ["-pthread"], + }), + defines = select({ + ":has_absl": ["GTEST_HAS_ABSL=1"], + "//conditions:default": [], + }), + features = select({ + ":windows": ["windows_export_all_symbols"], + "//conditions:default": [], + }), + includes = [ + "googlemock", + "googlemock/include", + "googletest", + "googletest/include", + ], + linkopts = select({ + ":windows": [], + "//conditions:default": ["-pthread"], + }), + deps = select({ + ":has_absl": [ + "@com_google_absl//absl/debugging:failure_signal_handler", + "@com_google_absl//absl/debugging:stacktrace", + "@com_google_absl//absl/debugging:symbolize", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/types:optional", + "@com_google_absl//absl/types:variant", + ], + "//conditions:default": [], + }), +) + +cc_library( + name = "gtest_main", + srcs = ["googlemock/src/gmock_main.cc"], + features = select({ + ":windows": ["windows_export_all_symbols"], + "//conditions:default": [], + }), + deps = [":gtest"], +) + +# The following rules build samples of how to use gTest. +cc_library( + name = "gtest_sample_lib", + srcs = [ + "googletest/samples/sample1.cc", + "googletest/samples/sample2.cc", + "googletest/samples/sample4.cc", + ], + hdrs = [ + "googletest/samples/prime_tables.h", + "googletest/samples/sample1.h", + "googletest/samples/sample2.h", + "googletest/samples/sample3-inl.h", + "googletest/samples/sample4.h", + ], + features = select({ + ":windows": ["windows_export_all_symbols"], + "//conditions:default": [], + }), +) + +cc_test( + name = "gtest_samples", + size = "small", + # All Samples except: + # sample9 (main) + # sample10 (main and takes a command line option and needs to be separate) + srcs = [ + "googletest/samples/sample1_unittest.cc", + "googletest/samples/sample2_unittest.cc", + "googletest/samples/sample3_unittest.cc", + "googletest/samples/sample4_unittest.cc", + "googletest/samples/sample5_unittest.cc", + "googletest/samples/sample6_unittest.cc", + "googletest/samples/sample7_unittest.cc", + "googletest/samples/sample8_unittest.cc", + ], + linkstatic = 0, + deps = [ + "gtest_sample_lib", + ":gtest_main", + ], +) + +cc_test( + name = "sample9_unittest", + size = "small", + srcs = ["googletest/samples/sample9_unittest.cc"], + deps = [":gtest"], +) + +cc_test( + name = "sample10_unittest", + size = "small", + srcs = ["googletest/samples/sample10_unittest.cc"], + deps = [":gtest"], +) diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CMakeLists.txt new file mode 100644 index 000000000..30b8f9e4c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CMakeLists.txt @@ -0,0 +1,24 @@ +# Note: CMake support is community-based. The maintainers do not use CMake +# internally. + +if (POLICY CMP0048) + cmake_policy(SET CMP0048 NEW) +endif (POLICY CMP0048) + +project(googletest-distribution) +set(GOOGLETEST_VERSION 1.10.0) + +enable_testing() + +include(CMakeDependentOption) +include(GNUInstallDirs) + +#Note that googlemock target already builds googletest +option(BUILD_GMOCK "Builds the googlemock subproject" ON) +option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON) + +if(BUILD_GMOCK) + add_subdirectory( googlemock ) +elseif(BUILD_GTEST) + add_subdirectory( googletest ) +endif() diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CONTRIBUTING.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CONTRIBUTING.md new file mode 100644 index 000000000..bd1843eb4 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/CONTRIBUTING.md @@ -0,0 +1,142 @@ +# How to become a contributor and submit your own code + +## Contributor License Agreements + +We'd love to accept your patches! Before we can take them, we have to jump a +couple of legal hurdles. + +Please fill out either the individual or corporate Contributor License Agreement +(CLA). + +* If you are an individual writing original source code and you're sure you + own the intellectual property, then you'll need to sign an + [individual CLA](https://developers.google.com/open-source/cla/individual). +* If you work for a company that wants to allow you to contribute your work, + then you'll need to sign a + [corporate CLA](https://developers.google.com/open-source/cla/corporate). + +Follow either of the two links above to access the appropriate CLA and +instructions for how to sign and return it. Once we receive it, we'll be able to +accept your pull requests. + +## Are you a Googler? + +If you are a Googler, please make an attempt to submit an internal change rather +than a GitHub Pull Request. If you are not able to submit an internal change a +PR is acceptable as an alternative. + +## Contributing A Patch + +1. Submit an issue describing your proposed change to the + [issue tracker](https://github.com/google/googletest). +2. Please don't mix more than one logical change per submittal, because it + makes the history hard to follow. If you want to make a change that doesn't + have a corresponding issue in the issue tracker, please create one. +3. Also, coordinate with team members that are listed on the issue in question. + This ensures that work isn't being duplicated and communicating your plan + early also generally leads to better patches. +4. If your proposed change is accepted, and you haven't already done so, sign a + Contributor License Agreement (see details above). +5. Fork the desired repo, develop and test your code changes. +6. Ensure that your code adheres to the existing style in the sample to which + you are contributing. +7. Ensure that your code has an appropriate set of unit tests which all pass. +8. Submit a pull request. + +## The Google Test and Google Mock Communities + +The Google Test community exists primarily through the +[discussion group](http://groups.google.com/group/googletestframework) and the +GitHub repository. Likewise, the Google Mock community exists primarily through +their own [discussion group](http://groups.google.com/group/googlemock). You are +definitely encouraged to contribute to the discussion and you can also help us +to keep the effectiveness of the group high by following and promoting the +guidelines listed here. + +### Please Be Friendly + +Showing courtesy and respect to others is a vital part of the Google culture, +and we strongly encourage everyone participating in Google Test development to +join us in accepting nothing less. Of course, being courteous is not the same as +failing to constructively disagree with each other, but it does mean that we +should be respectful of each other when enumerating the 42 technical reasons +that a particular proposal may not be the best choice. There's never a reason to +be antagonistic or dismissive toward anyone who is sincerely trying to +contribute to a discussion. + +Sure, C++ testing is serious business and all that, but it's also a lot of fun. +Let's keep it that way. Let's strive to be one of the friendliest communities in +all of open source. + +As always, discuss Google Test in the official GoogleTest discussion group. You +don't have to actually submit code in order to sign up. Your participation +itself is a valuable contribution. + +## Style + +To keep the source consistent, readable, diffable and easy to merge, we use a +fairly rigid coding style, as defined by the +[google-styleguide](https://github.com/google/styleguide) project. All patches +will be expected to conform to the style outlined +[here](https://google.github.io/styleguide/cppguide.html). Use +[.clang-format](https://github.com/google/googletest/blob/master/.clang-format) +to check your formatting. + +## Requirements for Contributors + +If you plan to contribute a patch, you need to build Google Test, Google Mock, +and their own tests from a git checkout, which has further requirements: + +* [Python](https://www.python.org/) v2.3 or newer (for running some of the + tests and re-generating certain source files from templates) +* [CMake](https://cmake.org/) v2.6.4 or newer + +## Developing Google Test and Google Mock + +This section discusses how to make your own changes to the Google Test project. + +### Testing Google Test and Google Mock Themselves + +To make sure your changes work as intended and don't break existing +functionality, you'll want to compile and run Google Test and GoogleMock's own +tests. For that you can use CMake: + + mkdir mybuild + cd mybuild + cmake -Dgtest_build_tests=ON -Dgmock_build_tests=ON ${GTEST_REPO_DIR} + +To choose between building only Google Test or Google Mock, you may modify your +cmake command to be one of each + + cmake -Dgtest_build_tests=ON ${GTEST_DIR} # sets up Google Test tests + cmake -Dgmock_build_tests=ON ${GMOCK_DIR} # sets up Google Mock tests + +Make sure you have Python installed, as some of Google Test's tests are written +in Python. If the cmake command complains about not being able to find Python +(`Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)`), try telling it +explicitly where your Python executable can be found: + + cmake -DPYTHON_EXECUTABLE=path/to/python ... + +Next, you can build Google Test and / or Google Mock and all desired tests. On +\*nix, this is usually done by + + make + +To run the tests, do + + make test + +All tests should pass. + +### Regenerating Source Files + +Some of Google Test's source files are generated from templates (not in the C++ +sense) using a script. For example, the file +*googlemock/include/gmock/gmock-generated-actions.h.pump* is used to generate +*gmock-generated-actions.h* in the same directory. + +You don't need to worry about regenerating the source files unless you need to +modify them. You would then modify the corresponding `.pump` files and run the +'[pump.py](googlemock/scripts/pump.py)' generator script. See the +[Pump Manual](googlemock/docs/pump_manual.md). diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/LICENSE b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/LICENSE new file mode 100644 index 000000000..1941a11f8 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/LICENSE @@ -0,0 +1,28 @@ +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/README.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/README.md new file mode 100644 index 000000000..e332e9a21 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/README.md @@ -0,0 +1,136 @@ +# Google Test + +#### OSS Builds Status: + +[![Build Status](https://api.travis-ci.org/google/googletest.svg?branch=master)](https://travis-ci.org/google/googletest) +[![Build status](https://ci.appveyor.com/api/projects/status/4o38plt0xbo1ubc8/branch/master?svg=true)](https://ci.appveyor.com/project/GoogleTestAppVeyor/googletest/branch/master) + +### Announcements: + +#### Release 1.10.x + +[Release 1.10.x](https://github.com/google/googletest/releases/tag/release-1.10.0) +is now available. + +#### Coming Soon + +* Post 1.10.x googletest will follow + [Abseil Live at Head philosophy](https://abseil.io/about/philosophy) +* We are also planning to take a dependency on + [Abseil](https://github.com/abseil/abseil-cpp). + +## Welcome to **Google Test**, Google's C++ test framework! + +This repository is a merger of the formerly separate GoogleTest and GoogleMock +projects. These were so closely related that it makes sense to maintain and +release them together. + +Please subscribe to the mailing list at googletestframework@googlegroups.com for +questions, discussions, and development. + +### Getting started: + +The information for **Google Test** is available in the +[Google Test Primer](googletest/docs/primer.md) documentation. + +**Google Mock** is an extension to Google Test for writing and using C++ mock +classes. See the separate [Google Mock documentation](googlemock/README.md). + +More detailed documentation for googletest is in its interior +[googletest/README.md](googletest/README.md) file. + +## Features + +* An [xUnit](https://en.wikipedia.org/wiki/XUnit) test framework. +* Test discovery. +* A rich set of assertions. +* User-defined assertions. +* Death tests. +* Fatal and non-fatal failures. +* Value-parameterized tests. +* Type-parameterized tests. +* Various options for running the tests. +* XML test report generation. + +## Platforms + +Google test has been used on a variety of platforms: + +* Linux +* Mac OS X +* Windows +* Cygwin +* MinGW +* Windows Mobile +* Symbian +* PlatformIO + +## Who Is Using Google Test? + +In addition to many internal projects at Google, Google Test is also used by the +following notable projects: + +* The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser + and Chrome OS). +* The [LLVM](http://llvm.org/) compiler. +* [Protocol Buffers](https://github.com/google/protobuf), Google's data + interchange format. +* The [OpenCV](http://opencv.org/) computer vision library. +* [tiny-dnn](https://github.com/tiny-dnn/tiny-dnn): header only, + dependency-free deep learning framework in C++11. + +## Related Open Source Projects + +[GTest Runner](https://github.com/nholthaus/gtest-runner) is a Qt5 based +automated test-runner and Graphical User Interface with powerful features for +Windows and Linux platforms. + +[Google Test UI](https://github.com/ospector/gtest-gbar) is test runner that +runs your test binary, allows you to track its progress via a progress bar, and +displays a list of test failures. Clicking on one shows failure text. Google +Test UI is written in C#. + +[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event +listener for Google Test that implements the +[TAP protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) for test +result output. If your test runner understands TAP, you may find it useful. + +[gtest-parallel](https://github.com/google/gtest-parallel) is a test runner that +runs tests from your binary in parallel to provide significant speed-up. + +[GoogleTest Adapter](https://marketplace.visualstudio.com/items?itemName=DavidSchuldenfrei.gtest-adapter) +is a VS Code extension allowing to view Google Tests in a tree view, and +run/debug your tests. + +[Catch2 and Google Test Explorer](https://github.com/matepek/vscode-catch2-test-adapter) +is a VS Code extension allowing to view Google Tests in a tree view, and +run/debug your tests. + +[Cornichon](https://pypi.org/project/cornichon/) is a small Gherkin DSL parser +that generates stub code for Google Test. + +## Requirements + +Google Test is designed to have fairly minimal requirements to build and use +with your projects, but there are some. If you notice any problems on your +platform, please notify +[googletestframework@googlegroups.com](https://groups.google.com/forum/#!forum/googletestframework). +Patches for fixing them are welcome! + +### Build Requirements + +These are the base requirements to build and use Google Test from a source +package: + +* [Bazel](https://bazel.build/) or [CMake](https://cmake.org/). NOTE: Bazel is + the build system that googletest is using internally and tests against. + CMake is community-supported. + +* a C++11-standard-compliant compiler + +## Contributing change + +Please read the [`CONTRIBUTING.md`](CONTRIBUTING.md) for details on how to +contribute to this project. + +Happy testing! diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/WORKSPACE b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/WORKSPACE new file mode 100644 index 000000000..2289bdb7e --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/WORKSPACE @@ -0,0 +1,23 @@ +workspace(name = "com_google_googletest") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +# Abseil +http_archive( + name = "com_google_absl", + urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"], + strip_prefix = "abseil-cpp-master", +) + +http_archive( + name = "rules_cc", + strip_prefix = "rules_cc-master", + urls = ["https://github.com/bazelbuild/rules_cc/archive/master.zip"], +) + +http_archive( + name = "rules_python", + strip_prefix = "rules_python-master", + urls = ["https://github.com/bazelbuild/rules_python/archive/master.zip"], +) + diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/appveyor.yml b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/appveyor.yml new file mode 100644 index 000000000..ec155a76a --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/appveyor.yml @@ -0,0 +1,156 @@ +version: '{build}' + +os: Visual Studio 2015 + +environment: + matrix: + - compiler: msvc-15-seh + generator: "Visual Studio 15 2017" + build_system: cmake + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + enabled_on_pr: yes + + - compiler: msvc-15-seh + generator: "Visual Studio 15 2017 Win64" + build_system: cmake + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + enabled_on_pr: yes + + - compiler: msvc-15-seh + build_system: bazel + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + enabled_on_pr: yes + + - compiler: msvc-14-seh + build_system: cmake + generator: "Visual Studio 14 2015" + enabled_on_pr: yes + + - compiler: msvc-14-seh + build_system: cmake + generator: "Visual Studio 14 2015 Win64" + enabled_on_pr: yes + + - compiler: gcc-6.3.0-posix + build_system: cmake + generator: "MinGW Makefiles" + cxx_path: 'C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin' + enabled_on_pr: yes + +configuration: + - Debug + +build: + verbosity: minimal + +install: +- ps: | + Write-Output "Compiler: $env:compiler" + Write-Output "Generator: $env:generator" + Write-Output "Env:Configuation: $env:configuration" + Write-Output "Env: $env" + if (-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) { + Write-Output "This is *NOT* a pull request build" + } else { + Write-Output "This is a pull request build" + if (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes") { + Write-Output "PR builds are *NOT* explicitly enabled" + } + } + + # install Bazel + if ($env:build_system -eq "bazel") { + appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/0.28.1/bazel-0.28.1-windows-x86_64.exe -FileName bazel.exe + } + + if ($env:build_system -eq "cmake") { + # git bash conflicts with MinGW makefiles + if ($env:generator -eq "MinGW Makefiles") { + $env:path = $env:path.replace("C:\Program Files\Git\usr\bin;", "") + if ($env:cxx_path -ne "") { + $env:path += ";$env:cxx_path" + } + } + } + +before_build: +- ps: | + $env:root=$env:APPVEYOR_BUILD_FOLDER + Write-Output "env:root: $env:root" + +build_script: +- ps: | + # Only enable some builds for pull requests, the AppVeyor queue is too long. + if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) { + return + } else { + # special case - build with Bazel + if ($env:build_system -eq "bazel") { + & $env:root\bazel.exe build -c opt //:gtest_samples + if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error + $host.SetShouldExit(0) + } else { # a real error + throw "Exec: $ErrorMessage" + } + return + } + } + # by default build with CMake + md _build -Force | Out-Null + cd _build + + $conf = if ($env:generator -eq "MinGW Makefiles") {"-DCMAKE_BUILD_TYPE=$env:configuration"} else {"-DCMAKE_CONFIGURATION_TYPES=Debug;Release"} + # Disable test for MinGW (gtest tests fail, gmock tests can not build) + $gtest_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgtest_build_tests=OFF"} else {"-Dgtest_build_tests=ON"} + $gmock_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgmock_build_tests=OFF"} else {"-Dgmock_build_tests=ON"} + & cmake -G "$env:generator" $conf -Dgtest_build_samples=ON $gtest_build_tests $gmock_build_tests .. + if ($LastExitCode -ne 0) { + throw "Exec: $ErrorMessage" + } + $cmake_parallel = if ($env:generator -eq "MinGW Makefiles") {"-j2"} else {"/m"} + & cmake --build . --config $env:configuration -- $cmake_parallel + if ($LastExitCode -ne 0) { + throw "Exec: $ErrorMessage" + } + + +skip_commits: + files: + - '**/*.md' + +test_script: +- ps: | + # Only enable some builds for pull requests, the AppVeyor queue is too long. + if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) { + return + } + if ($env:build_system -eq "bazel") { + # special case - testing with Bazel + & $env:root\bazel.exe test //:gtest_samples + if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error + $host.SetShouldExit(0) + } else { # a real error + throw "Exec: $ErrorMessage" + } + } + if ($env:build_system -eq "cmake") { + # built with CMake - test with CTest + if ($env:generator -eq "MinGW Makefiles") { + return # No test available for MinGW + } + + & ctest -C $env:configuration --timeout 600 --output-on-failure + if ($LastExitCode -ne 0) { + throw "Exec: $ErrorMessage" + } + } + +artifacts: + - path: '_build/CMakeFiles/*.log' + name: logs + - path: '_build/Testing/**/*.xml' + name: test_results + - path: 'bazel-testlogs/**/test.log' + name: test_logs + - path: 'bazel-testlogs/**/test.xml' + name: test_results diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CMakeLists.txt b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CMakeLists.txt new file mode 100644 index 000000000..d32b70b5b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CMakeLists.txt @@ -0,0 +1,233 @@ +######################################################################## +# Note: CMake support is community-based. The maintainers do not use CMake +# internally. +# +# CMake build script for Google Mock. +# +# To run the tests for Google Mock itself on Linux, use 'make test' or +# ctest. You can select which tests to run using 'ctest -R regex'. +# For more options, run 'ctest --help'. + +option(gmock_build_tests "Build all of Google Mock's own tests." OFF) + +# A directory to find Google Test sources. +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt") + set(gtest_dir gtest) +else() + set(gtest_dir ../googletest) +endif() + +# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). +include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL) + +if (COMMAND pre_project_set_up_hermetic_build) + # Google Test also calls hermetic setup functions from add_subdirectory, + # although its changes will not affect things at the current scope. + pre_project_set_up_hermetic_build() +endif() + +######################################################################## +# +# Project-wide settings + +# Name of the project. +# +# CMake files in this project can refer to the root source directory +# as ${gmock_SOURCE_DIR} and to the root binary directory as +# ${gmock_BINARY_DIR}. +# Language "C" is required for find_package(Threads). +if (CMAKE_VERSION VERSION_LESS 3.0) + project(gmock CXX C) +else() + cmake_policy(SET CMP0048 NEW) + project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) +endif() +cmake_minimum_required(VERSION 2.6.4) + +if (COMMAND set_up_hermetic_build) + set_up_hermetic_build() +endif() + +# Instructs CMake to process Google Test's CMakeLists.txt and add its +# targets to the current scope. We are placing Google Test's binary +# directory in a subdirectory of our own as VC compilation may break +# if they are the same (the default). +add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}") + + +# These commands only run if this is the main project +if(CMAKE_PROJECT_NAME STREQUAL "gmock" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution") + # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to + # make it prominent in the GUI. + option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) +else() + mark_as_advanced(gmock_build_tests) +endif() + +# Although Google Test's CMakeLists.txt calls this function, the +# changes there don't affect the current scope. Therefore we have to +# call it again here. +config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake + +# Adds Google Mock's and Google Test's header directories to the search path. +set(gmock_build_include_dirs + "${gmock_SOURCE_DIR}/include" + "${gmock_SOURCE_DIR}" + "${gtest_SOURCE_DIR}/include" + # This directory is needed to build directly from Google Test sources. + "${gtest_SOURCE_DIR}") +include_directories(${gmock_build_include_dirs}) + +######################################################################## +# +# Defines the gmock & gmock_main libraries. User tests should link +# with one of them. + +# Google Mock libraries. We build them using more strict warnings than what +# are used for other targets, to ensure that Google Mock can be compiled by +# a user aggressive about warnings. +if (MSVC) + cxx_library(gmock + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc) + + cxx_library(gmock_main + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc + src/gmock_main.cc) +else() + cxx_library(gmock "${cxx_strict}" src/gmock-all.cc) + target_link_libraries(gmock PUBLIC gtest) + cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc) + target_link_libraries(gmock_main PUBLIC gmock) +endif() +# If the CMake version supports it, attach header directory information +# to the targets for when we are part of a parent build (ie being pulled +# in via add_subdirectory() rather than being a standalone build). +if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + target_include_directories(gmock SYSTEM INTERFACE + "$" + "$/${CMAKE_INSTALL_INCLUDEDIR}>") + target_include_directories(gmock_main SYSTEM INTERFACE + "$" + "$/${CMAKE_INSTALL_INCLUDEDIR}>") +endif() + +######################################################################## +# +# Install rules +install_project(gmock gmock_main) + +######################################################################## +# +# Google Mock's own tests. +# +# You can skip this section if you aren't interested in testing +# Google Mock itself. +# +# The tests are not built by default. To build them, set the +# gmock_build_tests option to ON. You can do it by running ccmake +# or specifying the -Dgmock_build_tests=ON flag when running cmake. + +if (gmock_build_tests) + # This must be set in the root directory for the tests to be run by + # 'make test' or ctest. + enable_testing() + + if (WIN32) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$/RunTest.ps1" + CONTENT +"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$\" +$env:Path = \"$project_bin;$env:Path\" +& $args") + elseif (MINGW OR CYGWIN) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1" + CONTENT +"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin) +$env:Path = \"$project_bin;$env:Path\" +& $args") + endif() + + if (MINGW OR CYGWIN) + if (CMAKE_VERSION VERSION_LESS "2.8.12") + add_compile_options("-Wa,-mbig-obj") + else() + add_definitions("-Wa,-mbig-obj") + endif() + endif() + + ############################################################ + # C++ tests built with standard compiler flags. + + cxx_test(gmock-actions_test gmock_main) + cxx_test(gmock-cardinalities_test gmock_main) + cxx_test(gmock_ex_test gmock_main) + cxx_test(gmock-function-mocker_test gmock_main) + cxx_test(gmock-generated-actions_test gmock_main) + cxx_test(gmock-generated-function-mockers_test gmock_main) + cxx_test(gmock-generated-matchers_test gmock_main) + cxx_test(gmock-internal-utils_test gmock_main) + cxx_test(gmock-matchers_test gmock_main) + cxx_test(gmock-more-actions_test gmock_main) + cxx_test(gmock-nice-strict_test gmock_main) + cxx_test(gmock-port_test gmock_main) + cxx_test(gmock-spec-builders_test gmock_main) + cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc) + cxx_test(gmock_test gmock_main) + + if (DEFINED GTEST_HAS_PTHREAD) + cxx_test(gmock_stress_test gmock) + endif() + + # gmock_all_test is commented to save time building and running tests. + # Uncomment if necessary. + # cxx_test(gmock_all_test gmock_main) + + ############################################################ + # C++ tests built with non-standard compiler flags. + + if (MSVC) + cxx_library(gmock_main_no_exception "${cxx_no_exception}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + else() + cxx_library(gmock_main_no_exception "${cxx_no_exception}" src/gmock_main.cc) + target_link_libraries(gmock_main_no_exception PUBLIC gmock) + + cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" src/gmock_main.cc) + target_link_libraries(gmock_main_no_rtti PUBLIC gmock) + endif() + cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}" + gmock_main_no_exception test/gmock-more-actions_test.cc) + + cxx_test_with_flags(gmock_no_rtti_test "${cxx_no_rtti}" + gmock_main_no_rtti test/gmock-spec-builders_test.cc) + + cxx_shared_library(shared_gmock_main "${cxx_default}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + # Tests that a binary can be built with Google Mock as a shared library. On + # some system configurations, it may not possible to run the binary without + # knowing more details about the system configurations. We do not try to run + # this binary. To get a more robust shared library coverage, configure with + # -DBUILD_SHARED_LIBS=ON. + cxx_executable_with_flags(shared_gmock_test_ "${cxx_default}" + shared_gmock_main test/gmock-spec-builders_test.cc) + set_target_properties(shared_gmock_test_ + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + + ############################################################ + # Python tests. + + cxx_executable(gmock_leak_test_ test gmock_main) + py_test(gmock_leak_test) + + cxx_executable(gmock_output_test_ test gmock) + py_test(gmock_output_test) +endif() diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CONTRIBUTORS b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CONTRIBUTORS new file mode 100644 index 000000000..6e9ae362b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/CONTRIBUTORS @@ -0,0 +1,40 @@ +# This file contains a list of people who've made non-trivial +# contribution to the Google C++ Mocking Framework project. People +# who commit code to the project are encouraged to add their names +# here. Please keep the list sorted by first names. + +Benoit Sigoure +Bogdan Piloca +Chandler Carruth +Dave MacLachlan +David Anderson +Dean Sturtevant +Gene Volovich +Hal Burch +Jeffrey Yasskin +Jim Keller +Joe Walnes +Jon Wray +Keir Mierle +Keith Ray +Kostya Serebryany +Lev Makhlis +Manuel Klimek +Mario Tanev +Mark Paskin +Markus Heule +Matthew Simmons +Mike Bland +Neal Norwitz +Nermin Ozkiranartli +Owen Carlsen +Paneendra Ba +Paul Menage +Piotr Kaminski +Russ Rufer +Sverre Sundsdal +Takeshi Yoshino +Vadim Berman +Vlad Losev +Wolfgang Klier +Zhanyong Wan diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/LICENSE b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/LICENSE new file mode 100644 index 000000000..1941a11f8 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/LICENSE @@ -0,0 +1,28 @@ +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/README.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/README.md new file mode 100644 index 000000000..183fdb81d --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/README.md @@ -0,0 +1,44 @@ +# Googletest Mocking (gMock) Framework + +### Overview + +Google's framework for writing and using C++ mock classes. It can help you +derive better designs of your system and write better tests. + +It is inspired by: + +* [jMock](http://www.jmock.org/), +* [EasyMock](http://www.easymock.org/), and +* [Hamcrest](http://code.google.com/p/hamcrest/), + +and designed with C++'s specifics in mind. + +gMock: + +- provides a declarative syntax for defining mocks, +- can define partial (hybrid) mocks, which are a cross of real and mock + objects, +- handles functions of arbitrary types and overloaded functions, +- comes with a rich set of matchers for validating function arguments, +- uses an intuitive syntax for controlling the behavior of a mock, +- does automatic verification of expectations (no record-and-replay needed), +- allows arbitrary (partial) ordering constraints on function calls to be + expressed, +- lets a user extend it by defining new matchers and actions. +- does not use exceptions, and +- is easy to learn and use. + +Details and examples can be found here: + +* [gMock for Dummies](docs/for_dummies.md) +* [Legacy gMock FAQ](docs/gmock_faq.md) +* [gMock Cookbook](docs/cook_book.md) +* [gMock Cheat Sheet](docs/cheat_sheet.md) + +Please note that code under scripts/generator/ is from the [cppclean +project](http://code.google.com/p/cppclean/) and under the Apache +License, which is different from Google Mock's license. + +Google Mock is a part of +[Google Test C++ testing framework](http://github.com/google/googletest/) and a +subject to the same requirements. diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock.pc.in b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock.pc.in new file mode 100644 index 000000000..5780fcaa5 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock.pc.in @@ -0,0 +1,10 @@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ + +Name: gmock +Description: GoogleMock (without main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Requires: gtest +Libs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock_main.pc.in b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock_main.pc.in new file mode 100644 index 000000000..f2dfe69e0 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/cmake/gmock_main.pc.in @@ -0,0 +1,10 @@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ + +Name: gmock_main +Description: GoogleMock (with main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Requires: gmock +Libs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cheat_sheet.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cheat_sheet.md new file mode 100644 index 000000000..b425e0a0e --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cheat_sheet.md @@ -0,0 +1,776 @@ +## gMock Cheat Sheet + + + + + +### Defining a Mock Class + +#### Mocking a Normal Class {#MockClass} + +Given + +```cpp +class Foo { + ... + virtual ~Foo(); + virtual int GetSize() const = 0; + virtual string Describe(const char* name) = 0; + virtual string Describe(int type) = 0; + virtual bool Process(Bar elem, int count) = 0; +}; +``` + +(note that `~Foo()` **must** be virtual) we can define its mock as + +```cpp +#include "gmock/gmock.h" + +class MockFoo : public Foo { + ... + MOCK_METHOD(int, GetSize, (), (const, override)); + MOCK_METHOD(string, Describe, (const char* name), (override)); + MOCK_METHOD(string, Describe, (int type), (override)); + MOCK_METHOD(bool, Process, (Bar elem, int count), (override)); +}; +``` + +To create a "nice" mock, which ignores all uninteresting calls, a "naggy" mock, +which warns on all uninteresting calls, or a "strict" mock, which treats them as +failures: + +```cpp +using ::testing::NiceMock; +using ::testing::NaggyMock; +using ::testing::StrictMock; + +NiceMock nice_foo; // The type is a subclass of MockFoo. +NaggyMock naggy_foo; // The type is a subclass of MockFoo. +StrictMock strict_foo; // The type is a subclass of MockFoo. +``` + +**Note:** A mock object is currently naggy by default. We may make it nice by +default in the future. + +#### Mocking a Class Template {#MockTemplate} + +Class templates can be mocked just like any class. + +To mock + +```cpp +template +class StackInterface { + ... + virtual ~StackInterface(); + virtual int GetSize() const = 0; + virtual void Push(const Elem& x) = 0; +}; +``` + +(note that all member functions that are mocked, including `~StackInterface()` +**must** be virtual). + +```cpp +template +class MockStack : public StackInterface { + ... + MOCK_METHOD(int, GetSize, (), (const, override)); + MOCK_METHOD(void, Push, (const Elem& x), (override)); +}; +``` + +#### Specifying Calling Conventions for Mock Functions + +If your mock function doesn't use the default calling convention, you can +specify it by adding `Calltype(convention)` to `MOCK_METHOD`'s 4th parameter. +For example, + +```cpp + MOCK_METHOD(bool, Foo, (int n), (Calltype(STDMETHODCALLTYPE))); + MOCK_METHOD(int, Bar, (double x, double y), + (const, Calltype(STDMETHODCALLTYPE))); +``` + +where `STDMETHODCALLTYPE` is defined by `` on Windows. + +### Using Mocks in Tests {#UsingMocks} + +The typical work flow is: + +1. Import the gMock names you need to use. All gMock symbols are in the + `testing` namespace unless they are macros or otherwise noted. +2. Create the mock objects. +3. Optionally, set the default actions of the mock objects. +4. Set your expectations on the mock objects (How will they be called? What + will they do?). +5. Exercise code that uses the mock objects; if necessary, check the result + using googletest assertions. +6. When a mock object is destructed, gMock automatically verifies that all + expectations on it have been satisfied. + +Here's an example: + +```cpp +using ::testing::Return; // #1 + +TEST(BarTest, DoesThis) { + MockFoo foo; // #2 + + ON_CALL(foo, GetSize()) // #3 + .WillByDefault(Return(1)); + // ... other default actions ... + + EXPECT_CALL(foo, Describe(5)) // #4 + .Times(3) + .WillRepeatedly(Return("Category 5")); + // ... other expectations ... + + EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 +} // #6 +``` + +### Setting Default Actions {#OnCall} + +gMock has a **built-in default action** for any function that returns `void`, +`bool`, a numeric value, or a pointer. In C++11, it will additionally returns +the default-constructed value, if one exists for the given type. + +To customize the default action for functions with return type *`T`*: + +```cpp +using ::testing::DefaultValue; + +// Sets the default value to be returned. T must be CopyConstructible. +DefaultValue::Set(value); +// Sets a factory. Will be invoked on demand. T must be MoveConstructible. +// T MakeT(); +DefaultValue::SetFactory(&MakeT); +// ... use the mocks ... +// Resets the default value. +DefaultValue::Clear(); +``` + +Example usage: + +```cpp + // Sets the default action for return type std::unique_ptr to + // creating a new Buzz every time. + DefaultValue>::SetFactory( + [] { return MakeUnique(AccessLevel::kInternal); }); + + // When this fires, the default action of MakeBuzz() will run, which + // will return a new Buzz object. + EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber()); + + auto buzz1 = mock_buzzer_.MakeBuzz("hello"); + auto buzz2 = mock_buzzer_.MakeBuzz("hello"); + EXPECT_NE(nullptr, buzz1); + EXPECT_NE(nullptr, buzz2); + EXPECT_NE(buzz1, buzz2); + + // Resets the default action for return type std::unique_ptr, + // to avoid interfere with other tests. + DefaultValue>::Clear(); +``` + +To customize the default action for a particular method of a specific mock +object, use `ON_CALL()`. `ON_CALL()` has a similar syntax to `EXPECT_CALL()`, +but it is used for setting default behaviors (when you do not require that the +mock method is called). See [here](cook_book.md#UseOnCall) for a more detailed +discussion. + +```cpp +ON_CALL(mock-object, method(matchers)) + .With(multi-argument-matcher) ? + .WillByDefault(action); +``` + +### Setting Expectations {#ExpectCall} + +`EXPECT_CALL()` sets **expectations** on a mock method (How will it be called? +What will it do?): + +```cpp +EXPECT_CALL(mock-object, method (matchers)?) + .With(multi-argument-matcher) ? + .Times(cardinality) ? + .InSequence(sequences) * + .After(expectations) * + .WillOnce(action) * + .WillRepeatedly(action) ? + .RetiresOnSaturation(); ? +``` + +For each item above, `?` means it can be used at most once, while `*` means it +can be used any number of times. + +In order to pass, `EXPECT_CALL` must be used before the calls are actually made. + +The `(matchers)` is a comma-separated list of matchers that correspond to each +of the arguments of `method`, and sets the expectation only for calls of +`method` that matches all of the matchers. + +If `(matchers)` is omitted, the expectation is the same as if the matchers were +set to anything matchers (for example, `(_, _, _, _)` for a four-arg method). + +If `Times()` is omitted, the cardinality is assumed to be: + +* `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`; +* `Times(n)` when there are `n` `WillOnce()`s but no `WillRepeatedly()`, where + `n` >= 1; or +* `Times(AtLeast(n))` when there are `n` `WillOnce()`s and a + `WillRepeatedly()`, where `n` >= 0. + +A method with no `EXPECT_CALL()` is free to be invoked *any number of times*, +and the default action will be taken each time. + +### Matchers {#MatcherList} + + + +A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or +`EXPECT_CALL()`, or use it to validate a value directly using two macros: + + +| Macro | Description | +| :----------------------------------- | :------------------------------------ | +| `EXPECT_THAT(actual_value, matcher)` | Asserts that `actual_value` matches `matcher`. | +| `ASSERT_THAT(actual_value, matcher)` | The same as `EXPECT_THAT(actual_value, matcher)`, except that it generates a **fatal** failure. | + + +Built-in matchers (where `argument` is the function argument, e.g. +`actual_value` in the example above, or when used in the context of +`EXPECT_CALL(mock_object, method(matchers))`, the arguments of `method`) are +divided into several categories: + +#### Wildcard + +Matcher | Description +:-------------------------- | :----------------------------------------------- +`_` | `argument` can be any value of the correct type. +`A()` or `An()` | `argument` can be any value of type `type`. + +#### Generic Comparison + + +| Matcher | Description | +| :--------------------- | :-------------------------------------------------- | +| `Eq(value)` or `value` | `argument == value` | +| `Ge(value)` | `argument >= value` | +| `Gt(value)` | `argument > value` | +| `Le(value)` | `argument <= value` | +| `Lt(value)` | `argument < value` | +| `Ne(value)` | `argument != value` | +| `IsFalse()` | `argument` evaluates to `false` in a Boolean context. | +| `IsTrue()` | `argument` evaluates to `true` in a Boolean context. | +| `IsNull()` | `argument` is a `NULL` pointer (raw or smart). | +| `NotNull()` | `argument` is a non-null pointer (raw or smart). | +| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)| +| `VariantWith(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. | +| `Ref(variable)` | `argument` is a reference to `variable`. | +| `TypedEq(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. | + + +Except `Ref()`, these matchers make a *copy* of `value` in case it's modified or +destructed later. If the compiler complains that `value` doesn't have a public +copy constructor, try wrap it in `ByRef()`, e.g. +`Eq(ByRef(non_copyable_value))`. If you do that, make sure `non_copyable_value` +is not changed afterwards, or the meaning of your matcher will be changed. + +`IsTrue` and `IsFalse` are useful when you need to use a matcher, or for types +that can be explicitly converted to Boolean, but are not implicitly converted to +Boolean. In other cases, you can use the basic +[`EXPECT_TRUE` and `EXPECT_FALSE`](../../googletest/docs/primer#basic-assertions) +assertions. + +#### Floating-Point Matchers {#FpMatchers} + + +| Matcher | Description | +| :------------------------------- | :--------------------------------- | +| `DoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal. | +| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. | +| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. | +| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. | +| `IsNan()` | `argument` is any floating-point type with a NaN value. | + + +The above matchers use ULP-based comparison (the same as used in googletest). +They automatically pick a reasonable error bound based on the absolute value of +the expected value. `DoubleEq()` and `FloatEq()` conform to the IEEE standard, +which requires comparing two NaNs for equality to return false. The +`NanSensitive*` version instead treats two NaNs as equal, which is often what a +user wants. + + +| Matcher | Description | +| :------------------------------------------------ | :----------------------- | +| `DoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | +| `FloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | +| `NanSensitiveDoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. | +| `NanSensitiveFloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. | + + +#### String Matchers + +The `argument` can be either a C string or a C++ string object: + + +| Matcher | Description | +| :---------------------- | :------------------------------------------------- | +| `ContainsRegex(string)` | `argument` matches the given regular expression. | +| `EndsWith(suffix)` | `argument` ends with string `suffix`. | +| `HasSubstr(string)` | `argument` contains `string` as a sub-string. | +| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. | +| `StartsWith(prefix)` | `argument` starts with string `prefix`. | +| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. | +| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. | +| `StrEq(string)` | `argument` is equal to `string`. | +| `StrNe(string)` | `argument` is not equal to `string`. | + + +`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They +use the regular expression syntax defined +[here](../../googletest/docs/advanced.md#regular-expression-syntax). All of +these matchers, except `ContainsRegex()` and `MatchesRegex()` work for wide +strings as well. + +#### Container Matchers + +Most STL-style containers support `==`, so you can use `Eq(expected_container)` +or simply `expected_container` to match a container exactly. If you want to +write the elements in-line, match them more flexibly, or get more informative +messages, you can use: + + +| Matcher | Description | +| :---------------------------------------- | :------------------------------- | +| `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. | +| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | +| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | +| `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. | +| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. | +| `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `IsEmpty()` | `argument` is an empty container (`container.empty()`). | +| `IsSubsetOf({e0, e1, ..., en})`, `IsSubsetOf(a_container)`, `IsSubsetOf(begin, end)`, `IsSubsetOf(array)`, or `IsSubsetOf(array, count)` | `argument` matches `UnorderedElementsAre(x0, x1, ..., xk)` for some subset `{x0, x1, ..., xk}` of the expected matchers. | +| `IsSupersetOf({e0, e1, ..., en})`, `IsSupersetOf(a_container)`, `IsSupersetOf(begin, end)`, `IsSupersetOf(array)`, or `IsSupersetOf(array, count)` | Some subset of `argument` matches `UnorderedElementsAre(`expected matchers`)`. | +| `Pointwise(m, container)`, `Pointwise(m, {e0, e1, ..., en})` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. See more detail below. | +| `SizeIs(m)` | `argument` is a container whose size matches `m`. E.g. `SizeIs(2)` or `SizeIs(Lt(2))`. | +| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, and under *some* permutation of the elements, each element matches an `ei` (for a different `i`), which can be a value or a matcher. | +| `UnorderedElementsAreArray({e0, e1, ..., en})`, `UnorderedElementsAreArray(a_container)`, `UnorderedElementsAreArray(begin, end)`, `UnorderedElementsAreArray(array)`, or `UnorderedElementsAreArray(array, count)` | The same as `UnorderedElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `UnorderedPointwise(m, container)`, `UnorderedPointwise(m, {e0, e1, ..., en})` | Like `Pointwise(m, container)`, but ignores the order of elements. | +| `WhenSorted(m)` | When `argument` is sorted using the `<` operator, it matches container matcher `m`. E.g. `WhenSorted(ElementsAre(1, 2, 3))` verifies that `argument` contains elements 1, 2, and 3, ignoring order. | +| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except that the given comparator instead of `<` is used to sort `argument`. E.g. `WhenSortedBy(std::greater(), ElementsAre(3, 2, 1))`. | + + +**Notes:** + +* These matchers can also match: + 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), + and + 2. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, + int len)` -- see [Multi-argument Matchers](#MultiArgMatchers)). +* The array being matched may be multi-dimensional (i.e. its elements can be + arrays). +* `m` in `Pointwise(m, ...)` should be a matcher for `::std::tuple` + where `T` and `U` are the element type of the actual container and the + expected container, respectively. For example, to compare two `Foo` + containers where `Foo` doesn't support `operator==`, one might write: + + ```cpp + using ::std::get; + MATCHER(FooEq, "") { + return std::get<0>(arg).Equals(std::get<1>(arg)); + } + ... + EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos)); + ``` + +#### Member Matchers + + +| Matcher | Description | +| :------------------------------ | :----------------------------------------- | +| `Field(&class::field, m)` | `argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. | +| `Key(e)` | `argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`. | +| `Pair(m1, m2)` | `argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | +| `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. | + + +#### Matching the Result of a Function, Functor, or Callback + + +| Matcher | Description | +| :--------------- | :------------------------------------------------ | +| `ResultOf(f, m)` | `f(argument)` matches matcher `m`, where `f` is a function or functor. | + + +#### Pointer Matchers + + +| Matcher | Description | +| :------------------------ | :---------------------------------------------- | +| `Pointee(m)` | `argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`. | +| `WhenDynamicCastTo(m)` | when `argument` is passed through `dynamic_cast()`, it matches matcher `m`. | + + + + + + +#### Multi-argument Matchers {#MultiArgMatchers} + +Technically, all matchers match a *single* value. A "multi-argument" matcher is +just one that matches a *tuple*. The following matchers can be used to match a +tuple `(x, y)`: + +Matcher | Description +:------ | :---------- +`Eq()` | `x == y` +`Ge()` | `x >= y` +`Gt()` | `x > y` +`Le()` | `x <= y` +`Lt()` | `x < y` +`Ne()` | `x != y` + +You can use the following selectors to pick a subset of the arguments (or +reorder them) to participate in the matching: + + +| Matcher | Description | +| :------------------------- | :---------------------------------------------- | +| `AllArgs(m)` | Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`. | +| `Args(m)` | The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`. | + + +#### Composite Matchers + +You can make a matcher from one or more other matchers: + + +| Matcher | Description | +| :------------------------------- | :-------------------------------------- | +| `AllOf(m1, m2, ..., mn)` | `argument` matches all of the matchers `m1` to `mn`. | +| `AllOfArray({m0, m1, ..., mn})`, `AllOfArray(a_container)`, `AllOfArray(begin, end)`, `AllOfArray(array)`, or `AllOfArray(array, count)` | The same as `AllOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. | +| `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `Not(m)` | `argument` doesn't match matcher `m`. | + + + + +#### Adapters for Matchers + + +| Matcher | Description | +| :---------------------- | :------------------------------------ | +| `MatcherCast(m)` | casts matcher `m` to type `Matcher`. | +| `SafeMatcherCast(m)` | [safely casts](cook_book.md#casting-matchers) matcher `m` to type `Matcher`. | +| `Truly(predicate)` | `predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor. | + + +`AddressSatisfies(callback)` and `Truly(callback)` take ownership of `callback`, +which must be a permanent callback. + +#### Using Matchers as Predicates {#MatchersAsPredicatesCheat} + + +| Matcher | Description | +| :---------------------------- | :------------------------------------------ | +| `Matches(m)(value)` | evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor. | +| `ExplainMatchResult(m, value, result_listener)` | evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. | +| `Value(value, m)` | evaluates to `true` if `value` matches `m`. | + + +#### Defining Matchers + + +| Matcher | Description | +| :----------------------------------- | :------------------------------------ | +| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | +| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a macher `IsDivisibleBy(n)` to match a number divisible by `n`. | +| `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | + + +**Notes:** + +1. The `MATCHER*` macros cannot be used inside a function or class. +2. The matcher body must be *purely functional* (i.e. it cannot have any side + effect, and the result must not depend on anything other than the value + being matched and the matcher parameters). +3. You can use `PrintToString(x)` to convert a value `x` of any type to a + string. + +### Actions {#ActionList} + +**Actions** specify what a mock function should do when invoked. + +#### Returning a Value + + +| | | +| :-------------------------------- | :-------------------------------------------- | +| `Return()` | Return from a `void` mock function. | +| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type at the time the expectation is set, not when the action is executed. | +| `ReturnArg()` | Return the `N`-th (0-based) argument. | +| `ReturnNew(a1, ..., ak)` | Return `new T(a1, ..., ak)`; a different object is created each time. | +| `ReturnNull()` | Return a null pointer. | +| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. | +| `ReturnRef(variable)` | Return a reference to `variable`. | +| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. | +| `ReturnRoundRobin({a1, ..., ak})` | Each call will return the next `ai` in the list, starting at the beginning when the end of the list is reached. | + + +#### Side Effects + + +| | | +| :--------------------------------- | :-------------------------------------- | +| `Assign(&variable, value)` | Assign `value` to variable. | +| `DeleteArg()` | Delete the `N`-th (0-based) argument, which must be a pointer. | +| `SaveArg(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. | +| `SaveArgPointee(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. | +| `SetArgReferee(value)` | Assign value to the variable referenced by the `N`-th (0-based) argument. | +| `SetArgPointee(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. | +| `SetArgumentPointee(value)` | Same as `SetArgPointee(value)`. Deprecated. Will be removed in v1.7.0. | +| `SetArrayArgument(first, last)` | Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range. | +| `SetErrnoAndReturn(error, value)` | Set `errno` to `error` and return `value`. | +| `Throw(exception)` | Throws the given exception, which can be any copyable value. Available since v1.1.0. | + + +#### Using a Function, Functor, or Lambda as an Action + +In the following, by "callable" we mean a free function, `std::function`, +functor, or lambda. + + +| | | +| :---------------------------------- | :------------------------------------- | +| `f` | Invoke f with the arguments passed to the mock function, where f is a callable. | +| `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. | +| `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. | +| `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | +| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. | +| `InvokeArgument(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. | + + +The return value of the invoked function is used as the return value of the +action. + +When defining a callable to be used with `Invoke*()`, you can declare any unused +parameters as `Unused`: + +```cpp +using ::testing::Invoke; +double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } +... +EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); +``` + +`Invoke(callback)` and `InvokeWithoutArgs(callback)` take ownership of +`callback`, which must be permanent. The type of `callback` must be a base +callback type instead of a derived one, e.g. + +```cpp + BlockingClosure* done = new BlockingClosure; + ... Invoke(done) ...; // This won't compile! + + Closure* done2 = new BlockingClosure; + ... Invoke(done2) ...; // This works. +``` + +In `InvokeArgument(...)`, if an argument needs to be passed by reference, +wrap it inside `ByRef()`. For example, + +```cpp +using ::testing::ByRef; +using ::testing::InvokeArgument; +... +InvokeArgument<2>(5, string("Hi"), ByRef(foo)) +``` + +calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by +value, and `foo` by reference. + +#### Default Action + + +| Matcher | Description | +| :------------ | :----------------------------------------------------- | +| `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). | + + +**Note:** due to technical reasons, `DoDefault()` cannot be used inside a +composite action - trying to do so will result in a run-time error. + + + +#### Composite Actions + + +| | | +| :----------------------------- | :------------------------------------------ | +| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. | +| `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. | +| `WithArg(a)` | Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. | +| `WithArgs(a)` | Pass the selected (0-based) arguments of the mock function to action `a` and perform it. | +| `WithoutArgs(a)` | Perform action `a` without any arguments. | + + +#### Defining Actions + + +| | | +| :--------------------------------- | :-------------------------------------- | +| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | +| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | +| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. | + + +The `ACTION*` macros cannot be used inside a function or class. + +### Cardinalities {#CardinalityList} + +These are used in `Times()` to specify how many times a mock function will be +called: + + +| | | +| :---------------- | :----------------------------------------------------- | +| `AnyNumber()` | The function can be called any number of times. | +| `AtLeast(n)` | The call is expected at least `n` times. | +| `AtMost(n)` | The call is expected at most `n` times. | +| `Between(m, n)` | The call is expected between `m` and `n` (inclusive) times. | +| `Exactly(n) or n` | The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0. | + + +### Expectation Order + +By default, the expectations can be matched in *any* order. If some or all +expectations must be matched in a given order, there are two ways to specify it. +They can be used either independently or together. + +#### The After Clause {#AfterClause} + +```cpp +using ::testing::Expectation; +... +Expectation init_x = EXPECT_CALL(foo, InitX()); +Expectation init_y = EXPECT_CALL(foo, InitY()); +EXPECT_CALL(foo, Bar()) + .After(init_x, init_y); +``` + +says that `Bar()` can be called only after both `InitX()` and `InitY()` have +been called. + +If you don't know how many pre-requisites an expectation has when you write it, +you can use an `ExpectationSet` to collect them: + +```cpp +using ::testing::ExpectationSet; +... +ExpectationSet all_inits; +for (int i = 0; i < element_count; i++) { + all_inits += EXPECT_CALL(foo, InitElement(i)); +} +EXPECT_CALL(foo, Bar()) + .After(all_inits); +``` + +says that `Bar()` can be called only after all elements have been initialized +(but we don't care about which elements get initialized before the others). + +Modifying an `ExpectationSet` after using it in an `.After()` doesn't affect the +meaning of the `.After()`. + +#### Sequences {#UsingSequences} + +When you have a long chain of sequential expectations, it's easier to specify +the order using **sequences**, which don't require you to given each expectation +in the chain a different name. *All expected calls* in the same sequence must +occur in the order they are specified. + +```cpp +using ::testing::Return; +using ::testing::Sequence; +Sequence s1, s2; +... +EXPECT_CALL(foo, Reset()) + .InSequence(s1, s2) + .WillOnce(Return(true)); +EXPECT_CALL(foo, GetSize()) + .InSequence(s1) + .WillOnce(Return(1)); +EXPECT_CALL(foo, Describe(A())) + .InSequence(s2) + .WillOnce(Return("dummy")); +``` + +says that `Reset()` must be called before *both* `GetSize()` *and* `Describe()`, +and the latter two can occur in any order. + +To put many expectations in a sequence conveniently: + +```cpp +using ::testing::InSequence; +{ + InSequence seq; + + EXPECT_CALL(...)...; + EXPECT_CALL(...)...; + ... + EXPECT_CALL(...)...; +} +``` + +says that all expected calls in the scope of `seq` must occur in strict order. +The name `seq` is irrelevant. + +### Verifying and Resetting a Mock + +gMock will verify the expectations on a mock object when it is destructed, or +you can do it earlier: + +```cpp +using ::testing::Mock; +... +// Verifies and removes the expectations on mock_obj; +// returns true if and only if successful. +Mock::VerifyAndClearExpectations(&mock_obj); +... +// Verifies and removes the expectations on mock_obj; +// also removes the default actions set by ON_CALL(); +// returns true if and only if successful. +Mock::VerifyAndClear(&mock_obj); +``` + +You can also tell gMock that a mock object can be leaked and doesn't need to be +verified: + +```cpp +Mock::AllowLeak(&mock_obj); +``` + +### Mock Classes + +gMock defines a convenient mock class template + +```cpp +class MockFunction { + public: + MOCK_METHOD(R, Call, (A1, ..., An)); +}; +``` + +See this [recipe](cook_book.md#using-check-points) for one application of it. + +### Flags + + +| Flag | Description | +| :----------------------------- | :---------------------------------------- | +| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. | +| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. | + diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cook_book.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cook_book.md new file mode 100644 index 000000000..a49352148 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/cook_book.md @@ -0,0 +1,4269 @@ +# gMock Cookbook + + + +You can find recipes for using gMock here. If you haven't yet, please read +[this](for_dummies.md) first to make sure you understand the basics. + +**Note:** gMock lives in the `testing` name space. For readability, it is +recommended to write `using ::testing::Foo;` once in your file before using the +name `Foo` defined by gMock. We omit such `using` statements in this section for +brevity, but you should do it in your own code. + +## Creating Mock Classes + +Mock classes are defined as normal classes, using the `MOCK_METHOD` macro to +generate mocked methods. The macro gets 3 or 4 parameters: + +```cpp +class MyMock { + public: + MOCK_METHOD(ReturnType, MethodName, (Args...)); + MOCK_METHOD(ReturnType, MethodName, (Args...), (Specs...)); +}; +``` + +The first 3 parameters are simply the method declaration, split into 3 parts. +The 4th parameter accepts a closed list of qualifiers, which affect the +generated method: + +* **`const`** - Makes the mocked method a `const` method. Required if + overriding a `const` method. +* **`override`** - Marks the method with `override`. Recommended if overriding + a `virtual` method. +* **`noexcept`** - Marks the method with `noexcept`. Required if overriding a + `noexcept` method. +* **`Calltype(...)`** - Sets the call type for the method (e.g. to + `STDMETHODCALLTYPE`), useful in Windows. + +### Dealing with unprotected commas + +Unprotected commas, i.e. commas which are not surrounded by parentheses, prevent +`MOCK_METHOD` from parsing its arguments correctly: + +```cpp {.bad} +class MockFoo { + public: + MOCK_METHOD(std::pair, GetPair, ()); // Won't compile! + MOCK_METHOD(bool, CheckMap, (std::map, bool)); // Won't compile! +}; +``` + +Solution 1 - wrap with parentheses: + +```cpp {.good} +class MockFoo { + public: + MOCK_METHOD((std::pair), GetPair, ()); + MOCK_METHOD(bool, CheckMap, ((std::map), bool)); +}; +``` + +Note that wrapping a return or argument type with parentheses is, in general, +invalid C++. `MOCK_METHOD` removes the parentheses. + +Solution 2 - define an alias: + +```cpp {.good} +class MockFoo { + public: + using BoolAndInt = std::pair; + MOCK_METHOD(BoolAndInt, GetPair, ()); + using MapIntDouble = std::map; + MOCK_METHOD(bool, CheckMap, (MapIntDouble, bool)); +}; +``` + +### Mocking Private or Protected Methods + +You must always put a mock method definition (`MOCK_METHOD`) in a `public:` +section of the mock class, regardless of the method being mocked being `public`, +`protected`, or `private` in the base class. This allows `ON_CALL` and +`EXPECT_CALL` to reference the mock function from outside of the mock class. +(Yes, C++ allows a subclass to change the access level of a virtual function in +the base class.) Example: + +```cpp +class Foo { + public: + ... + virtual bool Transform(Gadget* g) = 0; + + protected: + virtual void Resume(); + + private: + virtual int GetTimeOut(); +}; + +class MockFoo : public Foo { + public: + ... + MOCK_METHOD(bool, Transform, (Gadget* g), (override)); + + // The following must be in the public section, even though the + // methods are protected or private in the base class. + MOCK_METHOD(void, Resume, (), (override)); + MOCK_METHOD(int, GetTimeOut, (), (override)); +}; +``` + +### Mocking Overloaded Methods + +You can mock overloaded functions as usual. No special attention is required: + +```cpp +class Foo { + ... + + // Must be virtual as we'll inherit from Foo. + virtual ~Foo(); + + // Overloaded on the types and/or numbers of arguments. + virtual int Add(Element x); + virtual int Add(int times, Element x); + + // Overloaded on the const-ness of this object. + virtual Bar& GetBar(); + virtual const Bar& GetBar() const; +}; + +class MockFoo : public Foo { + ... + MOCK_METHOD(int, Add, (Element x), (override)); + MOCK_METHOD(int, Add, (int times, Element x), (override)); + + MOCK_METHOD(Bar&, GetBar, (), (override)); + MOCK_METHOD(const Bar&, GetBar, (), (const, override)); +}; +``` + +**Note:** if you don't mock all versions of the overloaded method, the compiler +will give you a warning about some methods in the base class being hidden. To +fix that, use `using` to bring them in scope: + +```cpp +class MockFoo : public Foo { + ... + using Foo::Add; + MOCK_METHOD(int, Add, (Element x), (override)); + // We don't want to mock int Add(int times, Element x); + ... +}; +``` + +### Mocking Class Templates + +You can mock class templates just like any class. + +```cpp +template +class StackInterface { + ... + // Must be virtual as we'll inherit from StackInterface. + virtual ~StackInterface(); + + virtual int GetSize() const = 0; + virtual void Push(const Elem& x) = 0; +}; + +template +class MockStack : public StackInterface { + ... + MOCK_METHOD(int, GetSize, (), (override)); + MOCK_METHOD(void, Push, (const Elem& x), (override)); +}; +``` + +### Mocking Non-virtual Methods {#MockingNonVirtualMethods} + +gMock can mock non-virtual functions to be used in Hi-perf dependency +injection. + +In this case, instead of sharing a common base class with the real class, your +mock class will be *unrelated* to the real class, but contain methods with the +same signatures. The syntax for mocking non-virtual methods is the *same* as +mocking virtual methods (just don't add `override`): + +```cpp +// A simple packet stream class. None of its members is virtual. +class ConcretePacketStream { + public: + void AppendPacket(Packet* new_packet); + const Packet* GetPacket(size_t packet_number) const; + size_t NumberOfPackets() const; + ... +}; + +// A mock packet stream class. It inherits from no other, but defines +// GetPacket() and NumberOfPackets(). +class MockPacketStream { + public: + MOCK_METHOD(const Packet*, GetPacket, (size_t packet_number), (const)); + MOCK_METHOD(size_t, NumberOfPackets, (), (const)); + ... +}; +``` + +Note that the mock class doesn't define `AppendPacket()`, unlike the real class. +That's fine as long as the test doesn't need to call it. + +Next, you need a way to say that you want to use `ConcretePacketStream` in +production code, and use `MockPacketStream` in tests. Since the functions are +not virtual and the two classes are unrelated, you must specify your choice at +*compile time* (as opposed to run time). + +One way to do it is to templatize your code that needs to use a packet stream. +More specifically, you will give your code a template type argument for the type +of the packet stream. In production, you will instantiate your template with +`ConcretePacketStream` as the type argument. In tests, you will instantiate the +same template with `MockPacketStream`. For example, you may write: + +```cpp +template +void CreateConnection(PacketStream* stream) { ... } + +template +class PacketReader { + public: + void ReadPackets(PacketStream* stream, size_t packet_num); +}; +``` + +Then you can use `CreateConnection()` and +`PacketReader` in production code, and use +`CreateConnection()` and `PacketReader` in +tests. + +```cpp + MockPacketStream mock_stream; + EXPECT_CALL(mock_stream, ...)...; + .. set more expectations on mock_stream ... + PacketReader reader(&mock_stream); + ... exercise reader ... +``` + +### Mocking Free Functions + +It's possible to use gMock to mock a free function (i.e. a C-style function or a +static method). You just need to rewrite your code to use an interface (abstract +class). + +Instead of calling a free function (say, `OpenFile`) directly, introduce an +interface for it and have a concrete subclass that calls the free function: + +```cpp +class FileInterface { + public: + ... + virtual bool Open(const char* path, const char* mode) = 0; +}; + +class File : public FileInterface { + public: + ... + virtual bool Open(const char* path, const char* mode) { + return OpenFile(path, mode); + } +}; +``` + +Your code should talk to `FileInterface` to open a file. Now it's easy to mock +out the function. + +This may seem like a lot of hassle, but in practice you often have multiple +related functions that you can put in the same interface, so the per-function +syntactic overhead will be much lower. + +If you are concerned about the performance overhead incurred by virtual +functions, and profiling confirms your concern, you can combine this with the +recipe for [mocking non-virtual methods](#MockingNonVirtualMethods). + +### Old-Style `MOCK_METHODn` Macros + +Before the generic `MOCK_METHOD` macro was introduced, mocks where created using +a family of macros collectively called `MOCK_METHODn`. These macros are still +supported, though migration to the new `MOCK_METHOD` is recommended. + +The macros in the `MOCK_METHODn` family differ from `MOCK_METHOD`: + +* The general structure is `MOCK_METHODn(MethodName, ReturnType(Args))`, + instead of `MOCK_METHOD(ReturnType, MethodName, (Args))`. +* The number `n` must equal the number of arguments. +* When mocking a const method, one must use `MOCK_CONST_METHODn`. +* When mocking a class template, the macro name must be suffixed with `_T`. +* In order to specify the call type, the macro name must be suffixed with + `_WITH_CALLTYPE`, and the call type is the first macro argument. + +Old macros and their new equivalents: + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Simple
Old `MOCK_METHOD1(Foo, bool(int))`
New `MOCK_METHOD(bool, Foo, (int))`
Const Method
Old +`MOCK_CONST_METHOD1(Foo, bool(int))`
New +`MOCK_METHOD(bool, Foo, (int), (const))`
Method in a Class Template
Old `MOCK_METHOD1_T(Foo, bool(int))`
New +`MOCK_METHOD(bool, Foo, (int))`
Const Method in a Class Template
Old + `MOCK_CONST_METHOD1_T(Foo, bool(int))`
New + `MOCK_METHOD(bool, Foo, (int), (const))`
Method with Call Type
Old +`MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))`
New `MOCK_METHOD(bool, Foo, (int), +(Calltype(STDMETHODCALLTYPE)))`
Const Method with Call Type
Old `MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))`
New `MOCK_METHOD(bool, Foo, (int), (const, +Calltype(STDMETHODCALLTYPE)))`
Method with Call Type in a Class Template
Old `MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, +bool(int))`
New `MOCK_METHOD(bool, Foo, (int), +(Calltype(STDMETHODCALLTYPE)))`
Const Method with Call Type in a Class Template
Old `MOCK_CONST_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, +Foo, bool(int))`
New `MOCK_METHOD(bool, Foo, +(int), (const, Calltype(STDMETHODCALLTYPE)))`
+ +### The Nice, the Strict, and the Naggy {#NiceStrictNaggy} + +If a mock method has no `EXPECT_CALL` spec but is called, we say that it's an +"uninteresting call", and the default action (which can be specified using +`ON_CALL()`) of the method will be taken. Currently, an uninteresting call will +also by default cause gMock to print a warning. (In the future, we might remove +this warning by default.) + +However, sometimes you may want to ignore these uninteresting calls, and +sometimes you may want to treat them as errors. gMock lets you make the decision +on a per-mock-object basis. + +Suppose your test uses a mock class `MockFoo`: + +```cpp +TEST(...) { + MockFoo mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +If a method of `mock_foo` other than `DoThis()` is called, you will get a +warning. However, if you rewrite your test to use `NiceMock` instead, +you can suppress the warning: + +```cpp +using ::testing::NiceMock; + +TEST(...) { + NiceMock mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +`NiceMock` is a subclass of `MockFoo`, so it can be used wherever +`MockFoo` is accepted. + +It also works if `MockFoo`'s constructor takes some arguments, as +`NiceMock` "inherits" `MockFoo`'s constructors: + +```cpp +using ::testing::NiceMock; + +TEST(...) { + NiceMock mock_foo(5, "hi"); // Calls MockFoo(5, "hi"). + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +The usage of `StrictMock` is similar, except that it makes all uninteresting +calls failures: + +```cpp +using ::testing::StrictMock; + +TEST(...) { + StrictMock mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... + + // The test will fail if a method of mock_foo other than DoThis() + // is called. +} +``` + +NOTE: `NiceMock` and `StrictMock` only affects *uninteresting* calls (calls of +*methods* with no expectations); they do not affect *unexpected* calls (calls of +methods with expectations, but they don't match). See +[Understanding Uninteresting vs Unexpected Calls](#uninteresting-vs-unexpected). + +There are some caveats though (I dislike them just as much as the next guy, but +sadly they are side effects of C++'s limitations): + +1. `NiceMock` and `StrictMock` only work for mock methods + defined using the `MOCK_METHOD` macro **directly** in the `MockFoo` class. + If a mock method is defined in a **base class** of `MockFoo`, the "nice" or + "strict" modifier may not affect it, depending on the compiler. In + particular, nesting `NiceMock` and `StrictMock` (e.g. + `NiceMock >`) is **not** supported. +2. `NiceMock` and `StrictMock` may not work correctly if the + destructor of `MockFoo` is not virtual. We would like to fix this, but it + requires cleaning up existing tests. http://b/28934720 tracks the issue. +3. During the constructor or destructor of `MockFoo`, the mock object is *not* + nice or strict. This may cause surprises if the constructor or destructor + calls a mock method on `this` object. (This behavior, however, is consistent + with C++'s general rule: if a constructor or destructor calls a virtual + method of `this` object, that method is treated as non-virtual. In other + words, to the base class's constructor or destructor, `this` object behaves + like an instance of the base class, not the derived class. This rule is + required for safety. Otherwise a base constructor may use members of a + derived class before they are initialized, or a base destructor may use + members of a derived class after they have been destroyed.) + +Finally, you should be **very cautious** about when to use naggy or strict +mocks, as they tend to make tests more brittle and harder to maintain. When you +refactor your code without changing its externally visible behavior, ideally you +shouldn't need to update any tests. If your code interacts with a naggy mock, +however, you may start to get spammed with warnings as the result of your +change. Worse, if your code interacts with a strict mock, your tests may start +to fail and you'll be forced to fix them. Our general recommendation is to use +nice mocks (not yet the default) most of the time, use naggy mocks (the current +default) when developing or debugging tests, and use strict mocks only as the +last resort. + +### Simplifying the Interface without Breaking Existing Code {#SimplerInterfaces} + +Sometimes a method has a long list of arguments that is mostly uninteresting. +For example: + +```cpp +class LogSink { + public: + ... + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const struct tm* tm_time, + const char* message, size_t message_len) = 0; +}; +``` + +This method's argument list is lengthy and hard to work with (the `message` +argument is not even 0-terminated). If we mock it as is, using the mock will be +awkward. If, however, we try to simplify this interface, we'll need to fix all +clients depending on it, which is often infeasible. + +The trick is to redispatch the method in the mock class: + +```cpp +class ScopedMockLog : public LogSink { + public: + ... + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, const tm* tm_time, + const char* message, size_t message_len) { + // We are only interested in the log severity, full file name, and + // log message. + Log(severity, full_filename, std::string(message, message_len)); + } + + // Implements the mock method: + // + // void Log(LogSeverity severity, + // const string& file_path, + // const string& message); + MOCK_METHOD(void, Log, + (LogSeverity severity, const string& file_path, + const string& message)); +}; +``` + +By defining a new mock method with a trimmed argument list, we make the mock +class more user-friendly. + +This technique may also be applied to make overloaded methods more amenable to +mocking. For example, when overloads have been used to implement default +arguments: + +```cpp +class MockTurtleFactory : public TurtleFactory { + public: + Turtle* MakeTurtle(int length, int weight) override { ... } + Turtle* MakeTurtle(int length, int weight, int speed) override { ... } + + // the above methods delegate to this one: + MOCK_METHOD(Turtle*, DoMakeTurtle, ()); +}; +``` + +This allows tests that don't care which overload was invoked to avoid specifying +argument matchers: + +```cpp +ON_CALL(factory, DoMakeTurtle) + .WillByDefault(MakeMockTurtle()); +``` + +### Alternative to Mocking Concrete Classes + +Often you may find yourself using classes that don't implement interfaces. In +order to test your code that uses such a class (let's call it `Concrete`), you +may be tempted to make the methods of `Concrete` virtual and then mock it. + +Try not to do that. + +Making a non-virtual function virtual is a big decision. It creates an extension +point where subclasses can tweak your class' behavior. This weakens your control +on the class because now it's harder to maintain the class invariants. You +should make a function virtual only when there is a valid reason for a subclass +to override it. + +Mocking concrete classes directly is problematic as it creates a tight coupling +between the class and the tests - any small change in the class may invalidate +your tests and make test maintenance a pain. + +To avoid such problems, many programmers have been practicing "coding to +interfaces": instead of talking to the `Concrete` class, your code would define +an interface and talk to it. Then you implement that interface as an adaptor on +top of `Concrete`. In tests, you can easily mock that interface to observe how +your code is doing. + +This technique incurs some overhead: + +* You pay the cost of virtual function calls (usually not a problem). +* There is more abstraction for the programmers to learn. + +However, it can also bring significant benefits in addition to better +testability: + +* `Concrete`'s API may not fit your problem domain very well, as you may not + be the only client it tries to serve. By designing your own interface, you + have a chance to tailor it to your need - you may add higher-level + functionalities, rename stuff, etc instead of just trimming the class. This + allows you to write your code (user of the interface) in a more natural way, + which means it will be more readable, more maintainable, and you'll be more + productive. +* If `Concrete`'s implementation ever has to change, you don't have to rewrite + everywhere it is used. Instead, you can absorb the change in your + implementation of the interface, and your other code and tests will be + insulated from this change. + +Some people worry that if everyone is practicing this technique, they will end +up writing lots of redundant code. This concern is totally understandable. +However, there are two reasons why it may not be the case: + +* Different projects may need to use `Concrete` in different ways, so the best + interfaces for them will be different. Therefore, each of them will have its + own domain-specific interface on top of `Concrete`, and they will not be the + same code. +* If enough projects want to use the same interface, they can always share it, + just like they have been sharing `Concrete`. You can check in the interface + and the adaptor somewhere near `Concrete` (perhaps in a `contrib` + sub-directory) and let many projects use it. + +You need to weigh the pros and cons carefully for your particular problem, but +I'd like to assure you that the Java community has been practicing this for a +long time and it's a proven effective technique applicable in a wide variety of +situations. :-) + +### Delegating Calls to a Fake {#DelegatingToFake} + +Some times you have a non-trivial fake implementation of an interface. For +example: + +```cpp +class Foo { + public: + virtual ~Foo() {} + virtual char DoThis(int n) = 0; + virtual void DoThat(const char* s, int* p) = 0; +}; + +class FakeFoo : public Foo { + public: + char DoThis(int n) override { + return (n > 0) ? '+' : + (n < 0) ? '-' : '0'; + } + + void DoThat(const char* s, int* p) override { + *p = strlen(s); + } +}; +``` + +Now you want to mock this interface such that you can set expectations on it. +However, you also want to use `FakeFoo` for the default behavior, as duplicating +it in the mock object is, well, a lot of work. + +When you define the mock class using gMock, you can have it delegate its default +action to a fake class you already have, using this pattern: + +```cpp +class MockFoo : public Foo { + public: + // Normal mock method definitions using gMock. + MOCK_METHOD(char, DoThis, (int n), (override)); + MOCK_METHOD(void, DoThat, (const char* s, int* p), (override)); + + // Delegates the default actions of the methods to a FakeFoo object. + // This must be called *before* the custom ON_CALL() statements. + void DelegateToFake() { + ON_CALL(*this, DoThis).WillByDefault([this](int n) { + return fake_.DoThis(n); + }); + ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) { + fake_.DoThat(s, p); + }); + } + + private: + FakeFoo fake_; // Keeps an instance of the fake in the mock. +}; +``` + +With that, you can use `MockFoo` in your tests as usual. Just remember that if +you don't explicitly set an action in an `ON_CALL()` or `EXPECT_CALL()`, the +fake will be called upon to do it.: + +```cpp +using ::testing::_; + +TEST(AbcTest, Xyz) { + MockFoo foo; + + foo.DelegateToFake(); // Enables the fake for delegation. + + // Put your ON_CALL(foo, ...)s here, if any. + + // No action specified, meaning to use the default action. + EXPECT_CALL(foo, DoThis(5)); + EXPECT_CALL(foo, DoThat(_, _)); + + int n = 0; + EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked. + foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked. + EXPECT_EQ(2, n); +} +``` + +**Some tips:** + +* If you want, you can still override the default action by providing your own + `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`. +* In `DelegateToFake()`, you only need to delegate the methods whose fake + implementation you intend to use. + +* The general technique discussed here works for overloaded methods, but + you'll need to tell the compiler which version you mean. To disambiguate a + mock function (the one you specify inside the parentheses of `ON_CALL()`), + use [this technique](#SelectOverload); to disambiguate a fake function (the + one you place inside `Invoke()`), use a `static_cast` to specify the + function's type. For instance, if class `Foo` has methods `char DoThis(int + n)` and `bool DoThis(double x) const`, and you want to invoke the latter, + you need to write `Invoke(&fake_, static_cast(&FakeFoo::DoThis))` instead of `Invoke(&fake_, &FakeFoo::DoThis)` + (The strange-looking thing inside the angled brackets of `static_cast` is + the type of a function pointer to the second `DoThis()` method.). + +* Having to mix a mock and a fake is often a sign of something gone wrong. + Perhaps you haven't got used to the interaction-based way of testing yet. Or + perhaps your interface is taking on too many roles and should be split up. + Therefore, **don't abuse this**. We would only recommend to do it as an + intermediate step when you are refactoring your code. + +Regarding the tip on mixing a mock and a fake, here's an example on why it may +be a bad sign: Suppose you have a class `System` for low-level system +operations. In particular, it does file and I/O operations. And suppose you want +to test how your code uses `System` to do I/O, and you just want the file +operations to work normally. If you mock out the entire `System` class, you'll +have to provide a fake implementation for the file operation part, which +suggests that `System` is taking on too many roles. + +Instead, you can define a `FileOps` interface and an `IOOps` interface and split +`System`'s functionalities into the two. Then you can mock `IOOps` without +mocking `FileOps`. + +### Delegating Calls to a Real Object + +When using testing doubles (mocks, fakes, stubs, and etc), sometimes their +behaviors will differ from those of the real objects. This difference could be +either intentional (as in simulating an error such that you can test the error +handling code) or unintentional. If your mocks have different behaviors than the +real objects by mistake, you could end up with code that passes the tests but +fails in production. + +You can use the *delegating-to-real* technique to ensure that your mock has the +same behavior as the real object while retaining the ability to validate calls. +This technique is very similar to the [delegating-to-fake](#DelegatingToFake) +technique, the difference being that we use a real object instead of a fake. +Here's an example: + +```cpp +using ::testing::AtLeast; + +class MockFoo : public Foo { + public: + MockFoo() { + // By default, all calls are delegated to the real object. + ON_CALL(*this, DoThis).WillByDefault([this](int n) { + return real_.DoThis(n); + }); + ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) { + real_.DoThat(s, p); + }); + ... + } + MOCK_METHOD(char, DoThis, ...); + MOCK_METHOD(void, DoThat, ...); + ... + private: + Foo real_; +}; + +... + MockFoo mock; + EXPECT_CALL(mock, DoThis()) + .Times(3); + EXPECT_CALL(mock, DoThat("Hi")) + .Times(AtLeast(1)); + ... use mock in test ... +``` + +With this, gMock will verify that your code made the right calls (with the right +arguments, in the right order, called the right number of times, etc), and a +real object will answer the calls (so the behavior will be the same as in +production). This gives you the best of both worlds. + +### Delegating Calls to a Parent Class + +Ideally, you should code to interfaces, whose methods are all pure virtual. In +reality, sometimes you do need to mock a virtual method that is not pure (i.e, +it already has an implementation). For example: + +```cpp +class Foo { + public: + virtual ~Foo(); + + virtual void Pure(int n) = 0; + virtual int Concrete(const char* str) { ... } +}; + +class MockFoo : public Foo { + public: + // Mocking a pure method. + MOCK_METHOD(void, Pure, (int n), (override)); + // Mocking a concrete method. Foo::Concrete() is shadowed. + MOCK_METHOD(int, Concrete, (const char* str), (override)); +}; +``` + +Sometimes you may want to call `Foo::Concrete()` instead of +`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub action, or +perhaps your test doesn't need to mock `Concrete()` at all (but it would be +oh-so painful to have to define a new mock class whenever you don't need to mock +one of its methods). + +The trick is to leave a back door in your mock class for accessing the real +methods in the base class: + +```cpp +class MockFoo : public Foo { + public: + // Mocking a pure method. + MOCK_METHOD(void, Pure, (int n), (override)); + // Mocking a concrete method. Foo::Concrete() is shadowed. + MOCK_METHOD(int, Concrete, (const char* str), (override)); + + // Use this to call Concrete() defined in Foo. + int FooConcrete(const char* str) { return Foo::Concrete(str); } +}; +``` + +Now, you can call `Foo::Concrete()` inside an action by: + +```cpp +... + EXPECT_CALL(foo, Concrete).WillOnce([&foo](const char* str) { + return foo.FooConcrete(str); + }); +``` + +or tell the mock object that you don't want to mock `Concrete()`: + +```cpp +... + ON_CALL(foo, Concrete).WillByDefault([&foo](const char* str) { + return foo.FooConcrete(str); + }); +``` + +(Why don't we just write `{ return foo.Concrete(str); }`? If you do that, +`MockFoo::Concrete()` will be called (and cause an infinite recursion) since +`Foo::Concrete()` is virtual. That's just how C++ works.) + +## Using Matchers + +### Matching Argument Values Exactly + +You can specify exactly which arguments a mock method is expecting: + +```cpp +using ::testing::Return; +... + EXPECT_CALL(foo, DoThis(5)) + .WillOnce(Return('a')); + EXPECT_CALL(foo, DoThat("Hello", bar)); +``` + +### Using Simple Matchers + +You can use matchers to match arguments that have a certain property: + +```cpp +using ::testing::NotNull; +using ::testing::Return; +... + EXPECT_CALL(foo, DoThis(Ge(5))) // The argument must be >= 5. + .WillOnce(Return('a')); + EXPECT_CALL(foo, DoThat("Hello", NotNull())); + // The second argument must not be NULL. +``` + +A frequently used matcher is `_`, which matches anything: + +```cpp + EXPECT_CALL(foo, DoThat(_, NotNull())); +``` + + +### Combining Matchers {#CombiningMatchers} + +You can build complex matchers from existing ones using `AllOf()`, +`AllOfArray()`, `AnyOf()`, `AnyOfArray()` and `Not()`: + +```cpp +using ::testing::AllOf; +using ::testing::Gt; +using ::testing::HasSubstr; +using ::testing::Ne; +using ::testing::Not; +... + // The argument must be > 5 and != 10. + EXPECT_CALL(foo, DoThis(AllOf(Gt(5), + Ne(10)))); + + // The first argument must not contain sub-string "blah". + EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), + NULL)); +``` + +### Casting Matchers {#SafeMatcherCast} + +gMock matchers are statically typed, meaning that the compiler can catch your +mistake if you use a matcher of the wrong type (for example, if you use `Eq(5)` +to match a `string` argument). Good for you! + +Sometimes, however, you know what you're doing and want the compiler to give you +some slack. One example is that you have a matcher for `long` and the argument +you want to match is `int`. While the two types aren't exactly the same, there +is nothing really wrong with using a `Matcher` to match an `int` - after +all, we can first convert the `int` argument to a `long` losslessly before +giving it to the matcher. + +To support this need, gMock gives you the `SafeMatcherCast(m)` function. It +casts a matcher `m` to type `Matcher`. To ensure safety, gMock checks that +(let `U` be the type `m` accepts : + +1. Type `T` can be *implicitly* cast to type `U`; +2. When both `T` and `U` are built-in arithmetic types (`bool`, integers, and + floating-point numbers), the conversion from `T` to `U` is not lossy (in + other words, any value representable by `T` can also be represented by `U`); + and +3. When `U` is a reference, `T` must also be a reference (as the underlying + matcher may be interested in the address of the `U` value). + +The code won't compile if any of these conditions isn't met. + +Here's one example: + +```cpp +using ::testing::SafeMatcherCast; + +// A base class and a child class. +class Base { ... }; +class Derived : public Base { ... }; + +class MockFoo : public Foo { + public: + MOCK_METHOD(void, DoThis, (Derived* derived), (override)); +}; + +... + MockFoo foo; + // m is a Matcher we got from somewhere. + EXPECT_CALL(foo, DoThis(SafeMatcherCast(m))); +``` + +If you find `SafeMatcherCast(m)` too limiting, you can use a similar function +`MatcherCast(m)`. The difference is that `MatcherCast` works as long as you +can `static_cast` type `T` to type `U`. + +`MatcherCast` essentially lets you bypass C++'s type system (`static_cast` isn't +always safe as it could throw away information, for example), so be careful not +to misuse/abuse it. + +### Selecting Between Overloaded Functions {#SelectOverload} + +If you expect an overloaded function to be called, the compiler may need some +help on which overloaded version it is. + +To disambiguate functions overloaded on the const-ness of this object, use the +`Const()` argument wrapper. + +```cpp +using ::testing::ReturnRef; + +class MockFoo : public Foo { + ... + MOCK_METHOD(Bar&, GetBar, (), (override)); + MOCK_METHOD(const Bar&, GetBar, (), (const, override)); +}; + +... + MockFoo foo; + Bar bar1, bar2; + EXPECT_CALL(foo, GetBar()) // The non-const GetBar(). + .WillOnce(ReturnRef(bar1)); + EXPECT_CALL(Const(foo), GetBar()) // The const GetBar(). + .WillOnce(ReturnRef(bar2)); +``` + +(`Const()` is defined by gMock and returns a `const` reference to its argument.) + +To disambiguate overloaded functions with the same number of arguments but +different argument types, you may need to specify the exact type of a matcher, +either by wrapping your matcher in `Matcher()`, or using a matcher whose +type is fixed (`TypedEq`, `An()`, etc): + +```cpp +using ::testing::An; +using ::testing::Matcher; +using ::testing::TypedEq; + +class MockPrinter : public Printer { + public: + MOCK_METHOD(void, Print, (int n), (override)); + MOCK_METHOD(void, Print, (char c), (override)); +}; + +TEST(PrinterTest, Print) { + MockPrinter printer; + + EXPECT_CALL(printer, Print(An())); // void Print(int); + EXPECT_CALL(printer, Print(Matcher(Lt(5)))); // void Print(int); + EXPECT_CALL(printer, Print(TypedEq('a'))); // void Print(char); + + printer.Print(3); + printer.Print(6); + printer.Print('a'); +} +``` + +### Performing Different Actions Based on the Arguments + +When a mock method is called, the *last* matching expectation that's still +active will be selected (think "newer overrides older"). So, you can make a +method do different things depending on its argument values like this: + +```cpp +using ::testing::_; +using ::testing::Lt; +using ::testing::Return; +... + // The default case. + EXPECT_CALL(foo, DoThis(_)) + .WillRepeatedly(Return('b')); + // The more specific case. + EXPECT_CALL(foo, DoThis(Lt(5))) + .WillRepeatedly(Return('a')); +``` + +Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will be +returned; otherwise `'b'` will be returned. + +### Matching Multiple Arguments as a Whole + +Sometimes it's not enough to match the arguments individually. For example, we +may want to say that the first argument must be less than the second argument. +The `With()` clause allows us to match all arguments of a mock function as a +whole. For example, + +```cpp +using ::testing::_; +using ::testing::Ne; +using ::testing::Lt; +... + EXPECT_CALL(foo, InRange(Ne(0), _)) + .With(Lt()); +``` + +says that the first argument of `InRange()` must not be 0, and must be less than +the second argument. + +The expression inside `With()` must be a matcher of type `Matcher>`, where `A1`, ..., `An` are the types of the function arguments. + +You can also write `AllArgs(m)` instead of `m` inside `.With()`. The two forms +are equivalent, but `.With(AllArgs(Lt()))` is more readable than `.With(Lt())`. + +You can use `Args(m)` to match the `n` selected arguments (as a +tuple) against `m`. For example, + +```cpp +using ::testing::_; +using ::testing::AllOf; +using ::testing::Args; +using ::testing::Lt; +... + EXPECT_CALL(foo, Blah) + .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); +``` + +says that `Blah` will be called with arguments `x`, `y`, and `z` where `x < y < +z`. Note that in this example, it wasn't necessary specify the positional +matchers. + +As a convenience and example, gMock provides some matchers for 2-tuples, +including the `Lt()` matcher above. See [here](#MultiArgMatchers) for the +complete list. + +Note that if you want to pass the arguments to a predicate of your own (e.g. +`.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to +take a `std::tuple` as its argument; gMock will pass the `n` selected arguments +as *one* single tuple to the predicate. + +### Using Matchers as Predicates + +Have you noticed that a matcher is just a fancy predicate that also knows how to +describe itself? Many existing algorithms take predicates as arguments (e.g. +those defined in STL's `` header), and it would be a shame if gMock +matchers were not allowed to participate. + +Luckily, you can use a matcher where a unary predicate functor is expected by +wrapping it inside the `Matches()` function. For example, + +```cpp +#include +#include + +using ::testing::Matches; +using ::testing::Ge; + +vector v; +... +// How many elements in v are >= 10? +const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); +``` + +Since you can build complex matchers from simpler ones easily using gMock, this +gives you a way to conveniently construct composite predicates (doing the same +using STL's `` header is just painful). For example, here's a +predicate that's satisfied by any number that is >= 0, <= 100, and != 50: + +```cpp +using testing::AllOf; +using testing::Ge; +using testing::Le; +using testing::Matches; +using testing::Ne; +... +Matches(AllOf(Ge(0), Le(100), Ne(50))) +``` + +### Using Matchers in googletest Assertions + +Since matchers are basically predicates that also know how to describe +themselves, there is a way to take advantage of them in googletest assertions. +It's called `ASSERT_THAT` and `EXPECT_THAT`: + +```cpp + ASSERT_THAT(value, matcher); // Asserts that value matches matcher. + EXPECT_THAT(value, matcher); // The non-fatal version. +``` + +For example, in a googletest test you can write: + +```cpp +#include "gmock/gmock.h" + +using ::testing::AllOf; +using ::testing::Ge; +using ::testing::Le; +using ::testing::MatchesRegex; +using ::testing::StartsWith; + +... + EXPECT_THAT(Foo(), StartsWith("Hello")); + EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); + ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); +``` + +which (as you can probably guess) executes `Foo()`, `Bar()`, and `Baz()`, and +verifies that: + +* `Foo()` returns a string that starts with `"Hello"`. +* `Bar()` returns a string that matches regular expression `"Line \\d+"`. +* `Baz()` returns a number in the range [5, 10]. + +The nice thing about these macros is that *they read like English*. They +generate informative messages too. For example, if the first `EXPECT_THAT()` +above fails, the message will be something like: + +```cpp +Value of: Foo() + Actual: "Hi, world!" +Expected: starts with "Hello" +``` + +**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was borrowed from Joe Walnes' +Hamcrest project, which adds `assertThat()` to JUnit. + +### Using Predicates as Matchers + +gMock provides a [built-in set](#MatcherList) of matchers. In case you find them +lacking, you can use an arbitrary unary predicate function or functor as a +matcher - as long as the predicate accepts a value of the type you want. You do +this by wrapping the predicate inside the `Truly()` function, for example: + +```cpp +using ::testing::Truly; + +int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } +... + // Bar() must be called with an even number. + EXPECT_CALL(foo, Bar(Truly(IsEven))); +``` + +Note that the predicate function / functor doesn't have to return `bool`. It +works as long as the return value can be used as the condition in in statement +`if (condition) ...`. + + + +### Matching Arguments that Are Not Copyable + +When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, gMock saves away a copy of +`bar`. When `Foo()` is called later, gMock compares the argument to `Foo()` with +the saved copy of `bar`. This way, you don't need to worry about `bar` being +modified or destroyed after the `EXPECT_CALL()` is executed. The same is true +when you use matchers like `Eq(bar)`, `Le(bar)`, and so on. + +But what if `bar` cannot be copied (i.e. has no copy constructor)? You could +define your own matcher function or callback and use it with `Truly()`, as the +previous couple of recipes have shown. Or, you may be able to get away from it +if you can guarantee that `bar` won't be changed after the `EXPECT_CALL()` is +executed. Just tell gMock that it should save a reference to `bar`, instead of a +copy of it. Here's how: + +```cpp +using ::testing::ByRef; +using ::testing::Eq; +using ::testing::Lt; +... + // Expects that Foo()'s argument == bar. + EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); + + // Expects that Foo()'s argument < bar. + EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar)))); +``` + +Remember: if you do this, don't change `bar` after the `EXPECT_CALL()`, or the +result is undefined. + +### Validating a Member of an Object + +Often a mock function takes a reference to object as an argument. When matching +the argument, you may not want to compare the entire object against a fixed +object, as that may be over-specification. Instead, you may need to validate a +certain member variable or the result of a certain getter method of the object. +You can do this with `Field()` and `Property()`. More specifically, + +```cpp +Field(&Foo::bar, m) +``` + +is a matcher that matches a `Foo` object whose `bar` member variable satisfies +matcher `m`. + +```cpp +Property(&Foo::baz, m) +``` + +is a matcher that matches a `Foo` object whose `baz()` method returns a value +that satisfies matcher `m`. + +For example: + + +| Expression | Description | +| :--------------------------- | :--------------------------------------- | +| `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`. | +| `Property(&Foo::name, StartsWith("John "))` | Matches `x` where `x.name()` starts with `"John "`. | + + +Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no argument +and be declared as `const`. + +BTW, `Field()` and `Property()` can also match plain pointers to objects. For +instance, + +```cpp +using ::testing::Field; +using ::testing::Ge; +... +Field(&Foo::number, Ge(3)) +``` + +matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, the match +will always fail regardless of the inner matcher. + +What if you want to validate more than one members at the same time? Remember +that there are [`AllOf()` and `AllOfArray()`](#CombiningMatchers). + +Finally `Field()` and `Property()` provide overloads that take the field or +property names as the first argument to include it in the error message. This +can be useful when creating combined matchers. + +```cpp +using ::testing::AllOf; +using ::testing::Field; +using ::testing::Matcher; +using ::testing::SafeMatcherCast; + +Matcher IsFoo(const Foo& foo) { + return AllOf(Field("some_field", &Foo::some_field, foo.some_field), + Field("other_field", &Foo::other_field, foo.other_field), + Field("last_field", &Foo::last_field, foo.last_field)); +} +``` + +### Validating the Value Pointed to by a Pointer Argument + +C++ functions often take pointers as arguments. You can use matchers like +`IsNull()`, `NotNull()`, and other comparison matchers to match a pointer, but +what if you want to make sure the value *pointed to* by the pointer, instead of +the pointer itself, has a certain property? Well, you can use the `Pointee(m)` +matcher. + +`Pointee(m)` matches a pointer if and only if `m` matches the value the pointer +points to. For example: + +```cpp +using ::testing::Ge; +using ::testing::Pointee; +... + EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); +``` + +expects `foo.Bar()` to be called with a pointer that points to a value greater +than or equal to 3. + +One nice thing about `Pointee()` is that it treats a `NULL` pointer as a match +failure, so you can write `Pointee(m)` instead of + +```cpp +using ::testing::AllOf; +using ::testing::NotNull; +using ::testing::Pointee; +... + AllOf(NotNull(), Pointee(m)) +``` + +without worrying that a `NULL` pointer will crash your test. + +Also, did we tell you that `Pointee()` works with both raw pointers **and** +smart pointers (`std::unique_ptr`, `std::shared_ptr`, etc)? + +What if you have a pointer to pointer? You guessed it - you can use nested +`Pointee()` to probe deeper inside the value. For example, +`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points +to a number less than 3 (what a mouthful...). + +### Testing a Certain Property of an Object + +Sometimes you want to specify that an object argument has a certain property, +but there is no existing matcher that does this. If you want good error +messages, you should [define a matcher](#NewMatchers). If you want to do it +quick and dirty, you could get away with writing an ordinary function. + +Let's say you have a mock function that takes an object of type `Foo`, which has +an `int bar()` method and an `int baz()` method, and you want to constrain that +the argument's `bar()` value plus its `baz()` value is a given number. Here's +how you can define a matcher to do it: + +```cpp +using ::testing::Matcher; +using ::testing::MatcherInterface; +using ::testing::MatchResultListener; + +class BarPlusBazEqMatcher : public MatcherInterface { + public: + explicit BarPlusBazEqMatcher(int expected_sum) + : expected_sum_(expected_sum) {} + + bool MatchAndExplain(const Foo& foo, + MatchResultListener* /* listener */) const override { + return (foo.bar() + foo.baz()) == expected_sum_; + } + + void DescribeTo(std::ostream* os) const override { + *os << "bar() + baz() equals " << expected_sum_; + } + + void DescribeNegationTo(std::ostream* os) const override { + *os << "bar() + baz() does not equal " << expected_sum_; + } + private: + const int expected_sum_; +}; + +Matcher BarPlusBazEq(int expected_sum) { + return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); +} + +... + EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; +``` + +### Matching Containers + +Sometimes an STL container (e.g. list, vector, map, ...) is passed to a mock +function and you may want to validate it. Since most STL containers support the +`==` operator, you can write `Eq(expected_container)` or simply +`expected_container` to match a container exactly. + +Sometimes, though, you may want to be more flexible (for example, the first +element must be an exact match, but the second element can be any positive +number, and so on). Also, containers used in tests often have a small number of +elements, and having to define the expected container out-of-line is a bit of a +hassle. + +You can use the `ElementsAre()` or `UnorderedElementsAre()` matcher in such +cases: + +```cpp +using ::testing::_; +using ::testing::ElementsAre; +using ::testing::Gt; +... + MOCK_METHOD(void, Foo, (const vector& numbers), (override)); +... + EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); +``` + +The above matcher says that the container must have 4 elements, which must be 1, +greater than 0, anything, and 5 respectively. + +If you instead write: + +```cpp +using ::testing::_; +using ::testing::Gt; +using ::testing::UnorderedElementsAre; +... + MOCK_METHOD(void, Foo, (const vector& numbers), (override)); +... + EXPECT_CALL(mock, Foo(UnorderedElementsAre(1, Gt(0), _, 5))); +``` + +It means that the container must have 4 elements, which (under some permutation) +must be 1, greater than 0, anything, and 5 respectively. + +As an alternative you can place the arguments in a C-style array and use +`ElementsAreArray()` or `UnorderedElementsAreArray()` instead: + +```cpp +using ::testing::ElementsAreArray; +... + // ElementsAreArray accepts an array of element values. + const int expected_vector1[] = {1, 5, 2, 4, ...}; + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); + + // Or, an array of element matchers. + Matcher expected_vector2[] = {1, Gt(2), _, 3, ...}; + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); +``` + +In case the array needs to be dynamically created (and therefore the array size +cannot be inferred by the compiler), you can give `ElementsAreArray()` an +additional argument to specify the array size: + +```cpp +using ::testing::ElementsAreArray; +... + int* const expected_vector3 = new int[count]; + ... fill expected_vector3 with values ... + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); +``` + +Use `Pair` when comparing maps or other associative containers. + +```cpp +using testing::ElementsAre; +using testing::Pair; +... + std::map m = {{"a", 1}, {"b", 2}, {"c", 3}}; + EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3))); +``` + +**Tips:** + +* `ElementsAre*()` can be used to match *any* container that implements the + STL iterator pattern (i.e. it has a `const_iterator` type and supports + `begin()/end()`), not just the ones defined in STL. It will even work with + container types yet to be written - as long as they follows the above + pattern. +* You can use nested `ElementsAre*()` to match nested (multi-dimensional) + containers. +* If the container is passed by pointer instead of by reference, just write + `Pointee(ElementsAre*(...))`. +* The order of elements *matters* for `ElementsAre*()`. If you are using it + with containers whose element order are undefined (e.g. `hash_map`) you + should use `WhenSorted` around `ElementsAre`. + +### Sharing Matchers + +Under the hood, a gMock matcher object consists of a pointer to a ref-counted +implementation object. Copying matchers is allowed and very efficient, as only +the pointer is copied. When the last matcher that references the implementation +object dies, the implementation object will be deleted. + +Therefore, if you have some complex matcher that you want to use again and +again, there is no need to build it everytime. Just assign it to a matcher +variable and use that variable repeatedly! For example, + +```cpp +using ::testing::AllOf; +using ::testing::Gt; +using ::testing::Le; +using ::testing::Matcher; +... + Matcher in_range = AllOf(Gt(5), Le(10)); + ... use in_range as a matcher in multiple EXPECT_CALLs ... +``` + +### Matchers must have no side-effects {#PureMatchers} + +WARNING: gMock does not guarantee when or how many times a matcher will be +invoked. Therefore, all matchers must be *purely functional*: they cannot have +any side effects, and the match result must not depend on anything other than +the matcher's parameters and the value being matched. + +This requirement must be satisfied no matter how a matcher is defined (e.g., if +it is one of the standard matchers, or a custom matcher). In particular, a +matcher can never call a mock function, as that will affect the state of the +mock object and gMock. + +## Setting Expectations + +### Knowing When to Expect {#UseOnCall} + + + +**`ON_CALL`** is likely the *single most under-utilized construct* in gMock. + +There are basically two constructs for defining the behavior of a mock object: +`ON_CALL` and `EXPECT_CALL`. The difference? `ON_CALL` defines what happens when +a mock method is called, but doesn't imply any expectation on the method +being called. `EXPECT_CALL` not only defines the behavior, but also sets an +expectation that the method will be called with the given arguments, for the +given number of times (and *in the given order* when you specify the order +too). + +Since `EXPECT_CALL` does more, isn't it better than `ON_CALL`? Not really. Every +`EXPECT_CALL` adds a constraint on the behavior of the code under test. Having +more constraints than necessary is *baaad* - even worse than not having enough +constraints. + +This may be counter-intuitive. How could tests that verify more be worse than +tests that verify less? Isn't verification the whole point of tests? + +The answer lies in *what* a test should verify. **A good test verifies the +contract of the code.** If a test over-specifies, it doesn't leave enough +freedom to the implementation. As a result, changing the implementation without +breaking the contract (e.g. refactoring and optimization), which should be +perfectly fine to do, can break such tests. Then you have to spend time fixing +them, only to see them broken again the next time the implementation is changed. + +Keep in mind that one doesn't have to verify more than one property in one test. +In fact, **it's a good style to verify only one thing in one test.** If you do +that, a bug will likely break only one or two tests instead of dozens (which +case would you rather debug?). If you are also in the habit of giving tests +descriptive names that tell what they verify, you can often easily guess what's +wrong just from the test log itself. + +So use `ON_CALL` by default, and only use `EXPECT_CALL` when you actually intend +to verify that the call is made. For example, you may have a bunch of `ON_CALL`s +in your test fixture to set the common mock behavior shared by all tests in the +same group, and write (scarcely) different `EXPECT_CALL`s in different `TEST_F`s +to verify different aspects of the code's behavior. Compared with the style +where each `TEST` has many `EXPECT_CALL`s, this leads to tests that are more +resilient to implementational changes (and thus less likely to require +maintenance) and makes the intent of the tests more obvious (so they are easier +to maintain when you do need to maintain them). + +If you are bothered by the "Uninteresting mock function call" message printed +when a mock method without an `EXPECT_CALL` is called, you may use a `NiceMock` +instead to suppress all such messages for the mock object, or suppress the +message for specific methods by adding `EXPECT_CALL(...).Times(AnyNumber())`. DO +NOT suppress it by blindly adding an `EXPECT_CALL(...)`, or you'll have a test +that's a pain to maintain. + +### Ignoring Uninteresting Calls + +If you are not interested in how a mock method is called, just don't say +anything about it. In this case, if the method is ever called, gMock will +perform its default action to allow the test program to continue. If you are not +happy with the default action taken by gMock, you can override it using +`DefaultValue::Set()` (described [here](#DefaultValue)) or `ON_CALL()`. + +Please note that once you expressed interest in a particular mock method (via +`EXPECT_CALL()`), all invocations to it must match some expectation. If this +function is called but the arguments don't match any `EXPECT_CALL()` statement, +it will be an error. + +### Disallowing Unexpected Calls + +If a mock method shouldn't be called at all, explicitly say so: + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .Times(0); +``` + +If some calls to the method are allowed, but the rest are not, just list all the +expected calls: + +```cpp +using ::testing::AnyNumber; +using ::testing::Gt; +... + EXPECT_CALL(foo, Bar(5)); + EXPECT_CALL(foo, Bar(Gt(10))) + .Times(AnyNumber()); +``` + +A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` statements +will be an error. + +### Understanding Uninteresting vs Unexpected Calls {#uninteresting-vs-unexpected} + +*Uninteresting* calls and *unexpected* calls are different concepts in gMock. +*Very* different. + +A call `x.Y(...)` is **uninteresting** if there's *not even a single* +`EXPECT_CALL(x, Y(...))` set. In other words, the test isn't interested in the +`x.Y()` method at all, as evident in that the test doesn't care to say anything +about it. + +A call `x.Y(...)` is **unexpected** if there are *some* `EXPECT_CALL(x, +Y(...))`s set, but none of them matches the call. Put another way, the test is +interested in the `x.Y()` method (therefore it explicitly sets some +`EXPECT_CALL` to verify how it's called); however, the verification fails as the +test doesn't expect this particular call to happen. + +**An unexpected call is always an error,** as the code under test doesn't behave +the way the test expects it to behave. + +**By default, an uninteresting call is not an error,** as it violates no +constraint specified by the test. (gMock's philosophy is that saying nothing +means there is no constraint.) However, it leads to a warning, as it *might* +indicate a problem (e.g. the test author might have forgotten to specify a +constraint). + +In gMock, `NiceMock` and `StrictMock` can be used to make a mock class "nice" or +"strict". How does this affect uninteresting calls and unexpected calls? + +A **nice mock** suppresses uninteresting call *warnings*. It is less chatty than +the default mock, but otherwise is the same. If a test fails with a default +mock, it will also fail using a nice mock instead. And vice versa. Don't expect +making a mock nice to change the test's result. + +A **strict mock** turns uninteresting call warnings into errors. So making a +mock strict may change the test's result. + +Let's look at an example: + +```cpp +TEST(...) { + NiceMock mock_registry; + EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) + .WillRepeatedly(Return("Larry Page")); + + // Use mock_registry in code under test. + ... &mock_registry ... +} +``` + +The sole `EXPECT_CALL` here says that all calls to `GetDomainOwner()` must have +`"google.com"` as the argument. If `GetDomainOwner("yahoo.com")` is called, it +will be an unexpected call, and thus an error. *Having a nice mock doesn't +change the severity of an unexpected call.* + +So how do we tell gMock that `GetDomainOwner()` can be called with some other +arguments as well? The standard technique is to add a "catch all" `EXPECT_CALL`: + +```cpp + EXPECT_CALL(mock_registry, GetDomainOwner(_)) + .Times(AnyNumber()); // catches all other calls to this method. + EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) + .WillRepeatedly(Return("Larry Page")); +``` + +Remember that `_` is the wildcard matcher that matches anything. With this, if +`GetDomainOwner("google.com")` is called, it will do what the second +`EXPECT_CALL` says; if it is called with a different argument, it will do what +the first `EXPECT_CALL` says. + +Note that the order of the two `EXPECT_CALL`s is important, as a newer +`EXPECT_CALL` takes precedence over an older one. + +For more on uninteresting calls, nice mocks, and strict mocks, read +["The Nice, the Strict, and the Naggy"](#NiceStrictNaggy). + +### Ignoring Uninteresting Arguments {#ParameterlessExpectations} + +If your test doesn't care about the parameters (it only cares about the number +or order of calls), you can often simply omit the parameter list: + +```cpp + // Expect foo.Bar( ... ) twice with any arguments. + EXPECT_CALL(foo, Bar).Times(2); + + // Delegate to the given method whenever the factory is invoked. + ON_CALL(foo_factory, MakeFoo) + .WillByDefault(&BuildFooForTest); +``` + +This functionality is only available when a method is not overloaded; to prevent +unexpected behavior it is a compilation error to try to set an expectation on a +method where the specific overload is ambiguous. You can work around this by +supplying a [simpler mock interface](#SimplerInterfaces) than the mocked class +provides. + +This pattern is also useful when the arguments are interesting, but match logic +is substantially complex. You can leave the argument list unspecified and use +SaveArg actions to [save the values for later verification](#SaveArgVerify). If +you do that, you can easily differentiate calling the method the wrong number of +times from calling it with the wrong arguments. + +### Expecting Ordered Calls {#OrderedCalls} + +Although an `EXPECT_CALL()` statement defined earlier takes precedence when +gMock tries to match a function call with an expectation, by default calls don't +have to happen in the order `EXPECT_CALL()` statements are written. For example, +if the arguments match the matchers in the third `EXPECT_CALL()`, but not those +in the first two, then the third expectation will be used. + +If you would rather have all calls occur in the order of the expectations, put +the `EXPECT_CALL()` statements in a block where you define a variable of type +`InSequence`: + +```cpp +using ::testing::_; +using ::testing::InSequence; + + { + InSequence s; + + EXPECT_CALL(foo, DoThis(5)); + EXPECT_CALL(bar, DoThat(_)) + .Times(2); + EXPECT_CALL(foo, DoThis(6)); + } +``` + +In this example, we expect a call to `foo.DoThis(5)`, followed by two calls to +`bar.DoThat()` where the argument can be anything, which are in turn followed by +a call to `foo.DoThis(6)`. If a call occurred out-of-order, gMock will report an +error. + +### Expecting Partially Ordered Calls {#PartialOrder} + +Sometimes requiring everything to occur in a predetermined order can lead to +brittle tests. For example, we may care about `A` occurring before both `B` and +`C`, but aren't interested in the relative order of `B` and `C`. In this case, +the test should reflect our real intent, instead of being overly constraining. + +gMock allows you to impose an arbitrary DAG (directed acyclic graph) on the +calls. One way to express the DAG is to use the [After](#AfterClause) clause of +`EXPECT_CALL`. + +Another way is via the `InSequence()` clause (not the same as the `InSequence` +class), which we borrowed from jMock 2. It's less flexible than `After()`, but +more convenient when you have long chains of sequential calls, as it doesn't +require you to come up with different names for the expectations in the chains. +Here's how it works: + +If we view `EXPECT_CALL()` statements as nodes in a graph, and add an edge from +node A to node B wherever A must occur before B, we can get a DAG. We use the +term "sequence" to mean a directed path in this DAG. Now, if we decompose the +DAG into sequences, we just need to know which sequences each `EXPECT_CALL()` +belongs to in order to be able to reconstruct the original DAG. + +So, to specify the partial order on the expectations we need to do two things: +first to define some `Sequence` objects, and then for each `EXPECT_CALL()` say +which `Sequence` objects it is part of. + +Expectations in the same sequence must occur in the order they are written. For +example, + +```cpp +using ::testing::Sequence; +... + Sequence s1, s2; + + EXPECT_CALL(foo, A()) + .InSequence(s1, s2); + EXPECT_CALL(bar, B()) + .InSequence(s1); + EXPECT_CALL(bar, C()) + .InSequence(s2); + EXPECT_CALL(foo, D()) + .InSequence(s2); +``` + +specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`): + +```text + +---> B + | + A ---| + | + +---> C ---> D +``` + +This means that A must occur before B and C, and C must occur before D. There's +no restriction about the order other than these. + +### Controlling When an Expectation Retires + +When a mock method is called, gMock only considers expectations that are still +active. An expectation is active when created, and becomes inactive (aka +*retires*) when a call that has to occur later has occurred. For example, in + +```cpp +using ::testing::_; +using ::testing::Sequence; +... + Sequence s1, s2; + + EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 + .Times(AnyNumber()) + .InSequence(s1, s2); + EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 + .InSequence(s1); + EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 + .InSequence(s2); +``` + +as soon as either #2 or #3 is matched, #1 will retire. If a warning `"File too +large."` is logged after this, it will be an error. + +Note that an expectation doesn't retire automatically when it's saturated. For +example, + +```cpp +using ::testing::_; +... + EXPECT_CALL(log, Log(WARNING, _, _)); // #1 + EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 +``` + +says that there will be exactly one warning with the message `"File too +large."`. If the second warning contains this message too, #2 will match again +and result in an upper-bound-violated error. + +If this is not what you want, you can ask an expectation to retire as soon as it +becomes saturated: + +```cpp +using ::testing::_; +... + EXPECT_CALL(log, Log(WARNING, _, _)); // #1 + EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 + .RetiresOnSaturation(); +``` + +Here #2 can be used only once, so if you have two warnings with the message +`"File too large."`, the first will match #2 and the second will match #1 - +there will be no error. + +## Using Actions + +### Returning References from Mock Methods + +If a mock function's return type is a reference, you need to use `ReturnRef()` +instead of `Return()` to return a result: + +```cpp +using ::testing::ReturnRef; + +class MockFoo : public Foo { + public: + MOCK_METHOD(Bar&, GetBar, (), (override)); +}; +... + MockFoo foo; + Bar bar; + EXPECT_CALL(foo, GetBar()) + .WillOnce(ReturnRef(bar)); +... +``` + +### Returning Live Values from Mock Methods + +The `Return(x)` action saves a copy of `x` when the action is created, and +always returns the same value whenever it's executed. Sometimes you may want to +instead return the *live* value of `x` (i.e. its value at the time when the +action is *executed*.). Use either `ReturnRef()` or `ReturnPointee()` for this +purpose. + +If the mock function's return type is a reference, you can do it using +`ReturnRef(x)`, as shown in the previous recipe ("Returning References from Mock +Methods"). However, gMock doesn't let you use `ReturnRef()` in a mock function +whose return type is not a reference, as doing that usually indicates a user +error. So, what shall you do? + +Though you may be tempted, DO NOT use `ByRef()`: + +```cpp +using testing::ByRef; +using testing::Return; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, GetValue, (), (override)); +}; +... + int x = 0; + MockFoo foo; + EXPECT_CALL(foo, GetValue()) + .WillRepeatedly(Return(ByRef(x))); // Wrong! + x = 42; + EXPECT_EQ(42, foo.GetValue()); +``` + +Unfortunately, it doesn't work here. The above code will fail with error: + +```text +Value of: foo.GetValue() + Actual: 0 +Expected: 42 +``` + +The reason is that `Return(*value*)` converts `value` to the actual return type +of the mock function at the time when the action is *created*, not when it is +*executed*. (This behavior was chosen for the action to be safe when `value` is +a proxy object that references some temporary objects.) As a result, `ByRef(x)` +is converted to an `int` value (instead of a `const int&`) when the expectation +is set, and `Return(ByRef(x))` will always return 0. + +`ReturnPointee(pointer)` was provided to solve this problem specifically. It +returns the value pointed to by `pointer` at the time the action is *executed*: + +```cpp +using testing::ReturnPointee; +... + int x = 0; + MockFoo foo; + EXPECT_CALL(foo, GetValue()) + .WillRepeatedly(ReturnPointee(&x)); // Note the & here. + x = 42; + EXPECT_EQ(42, foo.GetValue()); // This will succeed now. +``` + +### Combining Actions + +Want to do more than one thing when a function is called? That's fine. `DoAll()` +allow you to do sequence of actions every time. Only the return value of the +last action in the sequence will be used. + +```cpp +using ::testing::_; +using ::testing::DoAll; + +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, Bar, (int n), (override)); +}; +... + EXPECT_CALL(foo, Bar(_)) + .WillOnce(DoAll(action_1, + action_2, + ... + action_n)); +``` + +### Verifying Complex Arguments {#SaveArgVerify} + +If you want to verify that a method is called with a particular argument but the +match criteria is complex, it can be difficult to distinguish between +cardinality failures (calling the method the wrong number of times) and argument +match failures. Similarly, if you are matching multiple parameters, it may not +be easy to distinguishing which argument failed to match. For example: + +```cpp + // Not ideal: this could fail because of a problem with arg1 or arg2, or maybe + // just the method wasn't called. + EXPECT_CALL(foo, SendValues(_, ElementsAre(1, 4, 4, 7), EqualsProto( ... ))); +``` + +You can instead save the arguments and test them individually: + +```cpp + EXPECT_CALL(foo, SendValues) + .WillOnce(DoAll(SaveArg<1>(&actual_array), SaveArg<2>(&actual_proto))); + ... run the test + EXPECT_THAT(actual_array, ElementsAre(1, 4, 4, 7)); + EXPECT_THAT(actual_proto, EqualsProto( ... )); +``` + +### Mocking Side Effects {#MockingSideEffects} + +Sometimes a method exhibits its effect not via returning a value but via side +effects. For example, it may change some global state or modify an output +argument. To mock side effects, in general you can define your own action by +implementing `::testing::ActionInterface`. + +If all you need to do is to change an output argument, the built-in +`SetArgPointee()` action is convenient: + +```cpp +using ::testing::_; +using ::testing::SetArgPointee; + +class MockMutator : public Mutator { + public: + MOCK_METHOD(void, Mutate, (bool mutate, int* value), (override)); + ... +} +... + MockMutator mutator; + EXPECT_CALL(mutator, Mutate(true, _)) + .WillOnce(SetArgPointee<1>(5)); +``` + +In this example, when `mutator.Mutate()` is called, we will assign 5 to the +`int` variable pointed to by argument #1 (0-based). + +`SetArgPointee()` conveniently makes an internal copy of the value you pass to +it, removing the need to keep the value in scope and alive. The implication +however is that the value must have a copy constructor and assignment operator. + +If the mock method also needs to return a value as well, you can chain +`SetArgPointee()` with `Return()` using `DoAll()`, remembering to put the +`Return()` statement last: + +```cpp +using ::testing::_; +using ::testing::Return; +using ::testing::SetArgPointee; + +class MockMutator : public Mutator { + public: + ... + MOCK_METHOD(bool, MutateInt, (int* value), (override)); +} +... + MockMutator mutator; + EXPECT_CALL(mutator, MutateInt(_)) + .WillOnce(DoAll(SetArgPointee<0>(5), + Return(true))); +``` + +Note, however, that if you use the `ReturnOKWith()` method, it will override the +values provided by `SetArgPointee()` in the response parameters of your function +call. + +If the output argument is an array, use the `SetArrayArgument(first, last)` +action instead. It copies the elements in source range `[first, last)` to the +array pointed to by the `N`-th (0-based) argument: + +```cpp +using ::testing::NotNull; +using ::testing::SetArrayArgument; + +class MockArrayMutator : public ArrayMutator { + public: + MOCK_METHOD(void, Mutate, (int* values, int num_values), (override)); + ... +} +... + MockArrayMutator mutator; + int values[5] = {1, 2, 3, 4, 5}; + EXPECT_CALL(mutator, Mutate(NotNull(), 5)) + .WillOnce(SetArrayArgument<0>(values, values + 5)); +``` + +This also works when the argument is an output iterator: + +```cpp +using ::testing::_; +using ::testing::SetArrayArgument; + +class MockRolodex : public Rolodex { + public: + MOCK_METHOD(void, GetNames, (std::back_insert_iterator>), + (override)); + ... +} +... + MockRolodex rolodex; + vector names; + names.push_back("George"); + names.push_back("John"); + names.push_back("Thomas"); + EXPECT_CALL(rolodex, GetNames(_)) + .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); +``` + +### Changing a Mock Object's Behavior Based on the State + +If you expect a call to change the behavior of a mock object, you can use +`::testing::InSequence` to specify different behaviors before and after the +call: + +```cpp +using ::testing::InSequence; +using ::testing::Return; + +... + { + InSequence seq; + EXPECT_CALL(my_mock, IsDirty()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(my_mock, Flush()); + EXPECT_CALL(my_mock, IsDirty()) + .WillRepeatedly(Return(false)); + } + my_mock.FlushIfDirty(); +``` + +This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called +and return `false` afterwards. + +If the behavior change is more complex, you can store the effects in a variable +and make a mock method get its return value from that variable: + +```cpp +using ::testing::_; +using ::testing::SaveArg; +using ::testing::Return; + +ACTION_P(ReturnPointee, p) { return *p; } +... + int previous_value = 0; + EXPECT_CALL(my_mock, GetPrevValue) + .WillRepeatedly(ReturnPointee(&previous_value)); + EXPECT_CALL(my_mock, UpdateValue) + .WillRepeatedly(SaveArg<0>(&previous_value)); + my_mock.DoSomethingToUpdateValue(); +``` + +Here `my_mock.GetPrevValue()` will always return the argument of the last +`UpdateValue()` call. + +### Setting the Default Value for a Return Type {#DefaultValue} + +If a mock method's return type is a built-in C++ type or pointer, by default it +will return 0 when invoked. Also, in C++ 11 and above, a mock method whose +return type has a default constructor will return a default-constructed value by +default. You only need to specify an action if this default value doesn't work +for you. + +Sometimes, you may want to change this default value, or you may want to specify +a default value for types gMock doesn't know about. You can do this using the +`::testing::DefaultValue` class template: + +```cpp +using ::testing::DefaultValue; + +class MockFoo : public Foo { + public: + MOCK_METHOD(Bar, CalculateBar, (), (override)); +}; + + +... + Bar default_bar; + // Sets the default return value for type Bar. + DefaultValue::Set(default_bar); + + MockFoo foo; + + // We don't need to specify an action here, as the default + // return value works for us. + EXPECT_CALL(foo, CalculateBar()); + + foo.CalculateBar(); // This should return default_bar. + + // Unsets the default return value. + DefaultValue::Clear(); +``` + +Please note that changing the default value for a type can make you tests hard +to understand. We recommend you to use this feature judiciously. For example, +you may want to make sure the `Set()` and `Clear()` calls are right next to the +code that uses your mock. + +### Setting the Default Actions for a Mock Method + +You've learned how to change the default value of a given type. However, this +may be too coarse for your purpose: perhaps you have two mock methods with the +same return type and you want them to have different behaviors. The `ON_CALL()` +macro allows you to customize your mock's behavior at the method level: + +```cpp +using ::testing::_; +using ::testing::AnyNumber; +using ::testing::Gt; +using ::testing::Return; +... + ON_CALL(foo, Sign(_)) + .WillByDefault(Return(-1)); + ON_CALL(foo, Sign(0)) + .WillByDefault(Return(0)); + ON_CALL(foo, Sign(Gt(0))) + .WillByDefault(Return(1)); + + EXPECT_CALL(foo, Sign(_)) + .Times(AnyNumber()); + + foo.Sign(5); // This should return 1. + foo.Sign(-9); // This should return -1. + foo.Sign(0); // This should return 0. +``` + +As you may have guessed, when there are more than one `ON_CALL()` statements, +the newer ones in the order take precedence over the older ones. In other words, +the **last** one that matches the function arguments will be used. This matching +order allows you to set up the common behavior in a mock object's constructor or +the test fixture's set-up phase and specialize the mock's behavior later. + +Note that both `ON_CALL` and `EXPECT_CALL` have the same "later statements take +precedence" rule, but they don't interact. That is, `EXPECT_CALL`s have their +own precedence order distinct from the `ON_CALL` precedence order. + +### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions} + +If the built-in actions don't suit you, you can use an existing callable +(function, `std::function`, method, functor, lambda as an action. + + + +```cpp +using ::testing::_; using ::testing::Invoke; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, Sum, (int x, int y), (override)); + MOCK_METHOD(bool, ComplexJob, (int x), (override)); +}; + +int CalculateSum(int x, int y) { return x + y; } +int Sum3(int x, int y, int z) { return x + y + z; } + +class Helper { + public: + bool ComplexJob(int x); +}; + +... + MockFoo foo; + Helper helper; + EXPECT_CALL(foo, Sum(_, _)) + .WillOnce(&CalculateSum) + .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1))); + EXPECT_CALL(foo, ComplexJob(_)) + .WillOnce(Invoke(&helper, &Helper::ComplexJob)) + .WillRepeatedly([](int x) { return x > 0; }); + + foo.Sum(5, 6); // Invokes CalculateSum(5, 6). + foo.Sum(2, 3); // Invokes Sum3(1, 2, 3). + foo.ComplexJob(10); // Invokes helper.ComplexJob(10). + foo.ComplexJob(-1); // Invokes the inline lambda. +``` + +The only requirement is that the type of the function, etc must be *compatible* +with the signature of the mock function, meaning that the latter's arguments can +be implicitly converted to the corresponding arguments of the former, and the +former's return type can be implicitly converted to that of the latter. So, you +can invoke something whose type is *not* exactly the same as the mock function, +as long as it's safe to do so - nice, huh? + +**`Note:`{.escaped}** + +* The action takes ownership of the callback and will delete it when the + action itself is destructed. +* If the type of a callback is derived from a base callback type `C`, you need + to implicitly cast it to `C` to resolve the overloading, e.g. + + ```cpp + using ::testing::Invoke; + ... + ResultCallback* is_ok = ...; + ... Invoke(is_ok) ...; // This works. + + BlockingClosure* done = new BlockingClosure; + ... Invoke(implicit_cast(done)) ...; // The cast is necessary. + ``` + +### Using Functions with Extra Info as Actions + +The function or functor you call using `Invoke()` must have the same number of +arguments as the mock function you use it for. Sometimes you may have a function +that takes more arguments, and you are willing to pass in the extra arguments +yourself to fill the gap. You can do this in gMock using callbacks with +pre-bound arguments. Here's an example: + +```cpp +using ::testing::Invoke; + +class MockFoo : public Foo { + public: + MOCK_METHOD(char, DoThis, (int n), (override)); +}; + +char SignOfSum(int x, int y) { + const int sum = x + y; + return (sum > 0) ? '+' : (sum < 0) ? '-' : '0'; +} + +TEST_F(FooTest, Test) { + MockFoo foo; + + EXPECT_CALL(foo, DoThis(2)) + .WillOnce(Invoke(NewPermanentCallback(SignOfSum, 5))); + EXPECT_EQ('+', foo.DoThis(2)); // Invokes SignOfSum(5, 2). +} +``` + +### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments + +`Invoke()` is very useful for doing actions that are more complex. It passes the +mock function's arguments to the function, etc being invoked such that the +callee has the full context of the call to work with. If the invoked function is +not interested in some or all of the arguments, it can simply ignore them. + +Yet, a common pattern is that a test author wants to invoke a function without +the arguments of the mock function. `Invoke()` allows her to do that using a +wrapper function that throws away the arguments before invoking an underlining +nullary function. Needless to say, this can be tedious and obscures the intent +of the test. + +`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except that it +doesn't pass the mock function's arguments to the callee. Here's an example: + +```cpp +using ::testing::_; +using ::testing::InvokeWithoutArgs; + +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, ComplexJob, (int n), (override)); +}; + +bool Job1() { ... } +bool Job2(int n, char c) { ... } + +... + MockFoo foo; + EXPECT_CALL(foo, ComplexJob(_)) + .WillOnce(InvokeWithoutArgs(Job1)) + .WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a'))); + + foo.ComplexJob(10); // Invokes Job1(). + foo.ComplexJob(20); // Invokes Job2(5, 'a'). +``` + +**`Note:`{.escaped}** + +* The action takes ownership of the callback and will delete it when the + action itself is destructed. +* If the type of a callback is derived from a base callback type `C`, you need + to implicitly cast it to `C` to resolve the overloading, e.g. + + ```cpp + using ::testing::InvokeWithoutArgs; + ... + ResultCallback* is_ok = ...; + ... InvokeWithoutArgs(is_ok) ...; // This works. + + BlockingClosure* done = ...; + ... InvokeWithoutArgs(implicit_cast(done)) ...; + // The cast is necessary. + ``` + +### Invoking an Argument of the Mock Function + +Sometimes a mock function will receive a function pointer, a functor (in other +words, a "callable") as an argument, e.g. + +```cpp +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, DoThis, (int n, (ResultCallback1* callback)), + (override)); +}; +``` + +and you may want to invoke this callable argument: + +```cpp +using ::testing::_; +... + MockFoo foo; + EXPECT_CALL(foo, DoThis(_, _)) + .WillOnce(...); + // Will execute callback->Run(5), where callback is the + // second argument DoThis() receives. +``` + +NOTE: The section below is legacy documentation from before C++ had lambdas: + +Arghh, you need to refer to a mock function argument but C++ has no lambda +(yet), so you have to define your own action. :-( Or do you really? + +Well, gMock has an action to solve *exactly* this problem: + +```cpp +InvokeArgument(arg_1, arg_2, ..., arg_m) +``` + +will invoke the `N`-th (0-based) argument the mock function receives, with +`arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is a function +pointer, a functor, or a callback. gMock handles them all. + +With that, you could write: + +```cpp +using ::testing::_; +using ::testing::InvokeArgument; +... + EXPECT_CALL(foo, DoThis(_, _)) + .WillOnce(InvokeArgument<1>(5)); + // Will execute callback->Run(5), where callback is the + // second argument DoThis() receives. +``` + +What if the callable takes an argument by reference? No problem - just wrap it +inside `ByRef()`: + +```cpp + ... + MOCK_METHOD(bool, Bar, + ((ResultCallback2* callback)), + (override)); + ... + using ::testing::_; + using ::testing::ByRef; + using ::testing::InvokeArgument; + ... + MockFoo foo; + Helper helper; + ... + EXPECT_CALL(foo, Bar(_)) + .WillOnce(InvokeArgument<0>(5, ByRef(helper))); + // ByRef(helper) guarantees that a reference to helper, not a copy of it, + // will be passed to the callback. +``` + +What if the callable takes an argument by reference and we do **not** wrap the +argument in `ByRef()`? Then `InvokeArgument()` will *make a copy* of the +argument, and pass a *reference to the copy*, instead of a reference to the +original value, to the callable. This is especially handy when the argument is a +temporary value: + +```cpp + ... + MOCK_METHOD(bool, DoThat, (bool (*f)(const double& x, const string& s)), + (override)); + ... + using ::testing::_; + using ::testing::InvokeArgument; + ... + MockFoo foo; + ... + EXPECT_CALL(foo, DoThat(_)) + .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); + // Will execute (*f)(5.0, string("Hi")), where f is the function pointer + // DoThat() receives. Note that the values 5.0 and string("Hi") are + // temporary and dead once the EXPECT_CALL() statement finishes. Yet + // it's fine to perform this action later, since a copy of the values + // are kept inside the InvokeArgument action. +``` + +### Ignoring an Action's Result + +Sometimes you have an action that returns *something*, but you need an action +that returns `void` (perhaps you want to use it in a mock function that returns +`void`, or perhaps it needs to be used in `DoAll()` and it's not the last in the +list). `IgnoreResult()` lets you do that. For example: + +```cpp +using ::testing::_; +using ::testing::DoAll; +using ::testing::IgnoreResult; +using ::testing::Return; + +int Process(const MyData& data); +string DoSomething(); + +class MockFoo : public Foo { + public: + MOCK_METHOD(void, Abc, (const MyData& data), (override)); + MOCK_METHOD(bool, Xyz, (), (override)); +}; + + ... + MockFoo foo; + EXPECT_CALL(foo, Abc(_)) + // .WillOnce(Invoke(Process)); + // The above line won't compile as Process() returns int but Abc() needs + // to return void. + .WillOnce(IgnoreResult(Process)); + EXPECT_CALL(foo, Xyz()) + .WillOnce(DoAll(IgnoreResult(DoSomething), + // Ignores the string DoSomething() returns. + Return(true))); +``` + +Note that you **cannot** use `IgnoreResult()` on an action that already returns +`void`. Doing so will lead to ugly compiler errors. + +### Selecting an Action's Arguments {#SelectingArgs} + +Say you have a mock function `Foo()` that takes seven arguments, and you have a +custom action that you want to invoke when `Foo()` is called. Trouble is, the +custom action only wants three arguments: + +```cpp +using ::testing::_; +using ::testing::Invoke; +... + MOCK_METHOD(bool, Foo, + (bool visible, const string& name, int x, int y, + (const map>), double& weight, double min_weight, + double max_wight)); +... +bool IsVisibleInQuadrant1(bool visible, int x, int y) { + return visible && x >= 0 && y >= 0; +} +... + EXPECT_CALL(mock, Foo) + .WillOnce(Invoke(IsVisibleInQuadrant1)); // Uh, won't compile. :-( +``` + +To please the compiler God, you need to define an "adaptor" that has the same +signature as `Foo()` and calls the custom action with the right arguments: + +```cpp +using ::testing::_; +using ::testing::Invoke; +... +bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, + const map, double>& weight, + double min_weight, double max_wight) { + return IsVisibleInQuadrant1(visible, x, y); +} +... + EXPECT_CALL(mock, Foo) + .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // Now it works. +``` + +But isn't this awkward? + +gMock provides a generic *action adaptor*, so you can spend your time minding +more important business than writing your own adaptors. Here's the syntax: + +```cpp +WithArgs(action) +``` + +creates an action that passes the arguments of the mock function at the given +indices (0-based) to the inner `action` and performs it. Using `WithArgs`, our +original example can be written as: + +```cpp +using ::testing::_; +using ::testing::Invoke; +using ::testing::WithArgs; +... + EXPECT_CALL(mock, Foo) + .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); // No need to define your own adaptor. +``` + +For better readability, gMock also gives you: + +* `WithoutArgs(action)` when the inner `action` takes *no* argument, and +* `WithArg(action)` (no `s` after `Arg`) when the inner `action` takes + *one* argument. + +As you may have realized, `InvokeWithoutArgs(...)` is just syntactic sugar for +`WithoutArgs(Invoke(...))`. + +Here are more tips: + +* The inner action used in `WithArgs` and friends does not have to be + `Invoke()` -- it can be anything. +* You can repeat an argument in the argument list if necessary, e.g. + `WithArgs<2, 3, 3, 5>(...)`. +* You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`. +* The types of the selected arguments do *not* have to match the signature of + the inner action exactly. It works as long as they can be implicitly + converted to the corresponding arguments of the inner action. For example, + if the 4-th argument of the mock function is an `int` and `my_action` takes + a `double`, `WithArg<4>(my_action)` will work. + +### Ignoring Arguments in Action Functions + +The [selecting-an-action's-arguments](#SelectingArgs) recipe showed us one way +to make a mock function and an action with incompatible argument lists fit +together. The downside is that wrapping the action in `WithArgs<...>()` can get +tedious for people writing the tests. + +If you are defining a function (or method, functor, lambda, callback) to be used +with `Invoke*()`, and you are not interested in some of its arguments, an +alternative to `WithArgs` is to declare the uninteresting arguments as `Unused`. +This makes the definition less cluttered and less fragile in case the types of +the uninteresting arguments change. It could also increase the chance the action +function can be reused. For example, given + +```cpp + public: + MOCK_METHOD(double, Foo, double(const string& label, double x, double y), + (override)); + MOCK_METHOD(double, Bar, (int index, double x, double y), (override)); +``` + +instead of + +```cpp +using ::testing::_; +using ::testing::Invoke; + +double DistanceToOriginWithLabel(const string& label, double x, double y) { + return sqrt(x*x + y*y); +} +double DistanceToOriginWithIndex(int index, double x, double y) { + return sqrt(x*x + y*y); +} +... + EXPECT_CALL(mock, Foo("abc", _, _)) + .WillOnce(Invoke(DistanceToOriginWithLabel)); + EXPECT_CALL(mock, Bar(5, _, _)) + .WillOnce(Invoke(DistanceToOriginWithIndex)); +``` + +you could write + +```cpp +using ::testing::_; +using ::testing::Invoke; +using ::testing::Unused; + +double DistanceToOrigin(Unused, double x, double y) { + return sqrt(x*x + y*y); +} +... + EXPECT_CALL(mock, Foo("abc", _, _)) + .WillOnce(Invoke(DistanceToOrigin)); + EXPECT_CALL(mock, Bar(5, _, _)) + .WillOnce(Invoke(DistanceToOrigin)); +``` + +### Sharing Actions + +Just like matchers, a gMock action object consists of a pointer to a ref-counted +implementation object. Therefore copying actions is also allowed and very +efficient. When the last action that references the implementation object dies, +the implementation object will be deleted. + +If you have some complex action that you want to use again and again, you may +not have to build it from scratch everytime. If the action doesn't have an +internal state (i.e. if it always does the same thing no matter how many times +it has been called), you can assign it to an action variable and use that +variable repeatedly. For example: + +```cpp +using ::testing::Action; +using ::testing::DoAll; +using ::testing::Return; +using ::testing::SetArgPointee; +... + Action set_flag = DoAll(SetArgPointee<0>(5), + Return(true)); + ... use set_flag in .WillOnce() and .WillRepeatedly() ... +``` + +However, if the action has its own state, you may be surprised if you share the +action object. Suppose you have an action factory `IncrementCounter(init)` which +creates an action that increments and returns a counter whose initial value is +`init`, using two actions created from the same expression and using a shared +action will exhibit different behaviors. Example: + +```cpp + EXPECT_CALL(foo, DoThis()) + .WillRepeatedly(IncrementCounter(0)); + EXPECT_CALL(foo, DoThat()) + .WillRepeatedly(IncrementCounter(0)); + foo.DoThis(); // Returns 1. + foo.DoThis(); // Returns 2. + foo.DoThat(); // Returns 1 - Blah() uses a different + // counter than Bar()'s. +``` + +versus + +```cpp +using ::testing::Action; +... + Action increment = IncrementCounter(0); + EXPECT_CALL(foo, DoThis()) + .WillRepeatedly(increment); + EXPECT_CALL(foo, DoThat()) + .WillRepeatedly(increment); + foo.DoThis(); // Returns 1. + foo.DoThis(); // Returns 2. + foo.DoThat(); // Returns 3 - the counter is shared. +``` + +### Testing Asynchronous Behavior + +One oft-encountered problem with gMock is that it can be hard to test +asynchronous behavior. Suppose you had a `EventQueue` class that you wanted to +test, and you created a separate `EventDispatcher` interface so that you could +easily mock it out. However, the implementation of the class fired all the +events on a background thread, which made test timings difficult. You could just +insert `sleep()` statements and hope for the best, but that makes your test +behavior nondeterministic. A better way is to use gMock actions and +`Notification` objects to force your asynchronous test to behave synchronously. + +```cpp +using ::testing::DoAll; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +class MockEventDispatcher : public EventDispatcher { + MOCK_METHOD(bool, DispatchEvent, (int32), (override)); +}; + +ACTION_P(Notify, notification) { + notification->Notify(); +} + +TEST(EventQueueTest, EnqueueEventTest) { + MockEventDispatcher mock_event_dispatcher; + EventQueue event_queue(&mock_event_dispatcher); + + const int32 kEventId = 321; + Notification done; + EXPECT_CALL(mock_event_dispatcher, DispatchEvent(kEventId)) + .WillOnce(Notify(&done)); + + event_queue.EnqueueEvent(kEventId); + done.WaitForNotification(); +} +``` + +In the example above, we set our normal gMock expectations, but then add an +additional action to notify the `Notification` object. Now we can just call +`Notification::WaitForNotification()` in the main thread to wait for the +asynchronous call to finish. After that, our test suite is complete and we can +safely exit. + +Note: this example has a downside: namely, if the expectation is not satisfied, +our test will run forever. It will eventually time-out and fail, but it will +take longer and be slightly harder to debug. To alleviate this problem, you can +use `WaitForNotificationWithTimeout(ms)` instead of `WaitForNotification()`. + +## Misc Recipes on Using gMock + +### Mocking Methods That Use Move-Only Types + +C++11 introduced *move-only types*. A move-only-typed value can be moved from +one object to another, but cannot be copied. `std::unique_ptr` is probably +the most commonly used move-only type. + +Mocking a method that takes and/or returns move-only types presents some +challenges, but nothing insurmountable. This recipe shows you how you can do it. +Note that the support for move-only method arguments was only introduced to +gMock in April 2017; in older code, you may find more complex +[workarounds](#LegacyMoveOnly) for lack of this feature. + +Let’s say we are working on a fictional project that lets one post and share +snippets called “buzzes”. Your code uses these types: + +```cpp +enum class AccessLevel { kInternal, kPublic }; + +class Buzz { + public: + explicit Buzz(AccessLevel access) { ... } + ... +}; + +class Buzzer { + public: + virtual ~Buzzer() {} + virtual std::unique_ptr MakeBuzz(StringPiece text) = 0; + virtual bool ShareBuzz(std::unique_ptr buzz, int64_t timestamp) = 0; + ... +}; +``` + +A `Buzz` object represents a snippet being posted. A class that implements the +`Buzzer` interface is capable of creating and sharing `Buzz`es. Methods in +`Buzzer` may return a `unique_ptr` or take a `unique_ptr`. Now we +need to mock `Buzzer` in our tests. + +To mock a method that accepts or returns move-only types, you just use the +familiar `MOCK_METHOD` syntax as usual: + +```cpp +class MockBuzzer : public Buzzer { + public: + MOCK_METHOD(std::unique_ptr, MakeBuzz, (StringPiece text), (override)); + MOCK_METHOD(bool, ShareBuzz, (std::unique_ptr buzz, int64_t timestamp), + (override)); +}; +``` + +Now that we have the mock class defined, we can use it in tests. In the +following code examples, we assume that we have defined a `MockBuzzer` object +named `mock_buzzer_`: + +```cpp + MockBuzzer mock_buzzer_; +``` + +First let’s see how we can set expectations on the `MakeBuzz()` method, which +returns a `unique_ptr`. + +As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or +`.WillRepeatedly()` clause), when that expectation fires, the default action for +that method will be taken. Since `unique_ptr<>` has a default constructor that +returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an +action: + +```cpp + // Use the default action. + EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")); + + // Triggers the previous EXPECT_CALL. + EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello")); +``` + +If you are not happy with the default action, you can tweak it as usual; see +[Setting Default Actions](#OnCall). + +If you just need to return a pre-defined move-only value, you can use the +`Return(ByMove(...))` action: + +```cpp + // When this fires, the unique_ptr<> specified by ByMove(...) will + // be returned. + EXPECT_CALL(mock_buzzer_, MakeBuzz("world")) + .WillOnce(Return(ByMove(MakeUnique(AccessLevel::kInternal)))); + + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world")); +``` + +Note that `ByMove()` is essential here - if you drop it, the code won’t compile. + +Quiz time! What do you think will happen if a `Return(ByMove(...))` action is +performed more than once (e.g. you write `... +.WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time +the action runs, the source value will be consumed (since it’s a move-only +value), so the next time around, there’s no value to move from -- you’ll get a +run-time error that `Return(ByMove(...))` can only be run once. + +If you need your mock method to do more than just moving a pre-defined value, +remember that you can always use a lambda or a callable object, which can do +pretty much anything you want: + +```cpp + EXPECT_CALL(mock_buzzer_, MakeBuzz("x")) + .WillRepeatedly([](StringPiece text) { + return MakeUnique(AccessLevel::kInternal); + }); + + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); +``` + +Every time this `EXPECT_CALL` fires, a new `unique_ptr` will be created +and returned. You cannot do this with `Return(ByMove(...))`. + +That covers returning move-only values; but how do we work with methods +accepting move-only arguments? The answer is that they work normally, although +some actions will not compile when any of method's arguments are move-only. You +can always use `Return`, or a [lambda or functor](#FunctionsAsActions): + +```cpp + using ::testing::Unused; + + EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)).WillOnce(Return(true)); + EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal)), + 0); + + EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce( + [](std::unique_ptr buzz, Unused) { return buzz != nullptr; }); + EXPECT_FALSE(mock_buzzer_.ShareBuzz(nullptr, 0)); +``` + +Many built-in actions (`WithArgs`, `WithoutArgs`,`DeleteArg`, `SaveArg`, ...) +could in principle support move-only arguments, but the support for this is not +implemented yet. If this is blocking you, please file a bug. + +A few actions (e.g. `DoAll`) copy their arguments internally, so they can never +work with non-copyable objects; you'll have to use functors instead. + +#### Legacy workarounds for move-only types {#LegacyMoveOnly} + +Support for move-only function arguments was only introduced to gMock in April +2017. In older code, you may encounter the following workaround for the lack of +this feature (it is no longer necessary - we're including it just for +reference): + +```cpp +class MockBuzzer : public Buzzer { + public: + MOCK_METHOD(bool, DoShareBuzz, (Buzz* buzz, Time timestamp)); + bool ShareBuzz(std::unique_ptr buzz, Time timestamp) override { + return DoShareBuzz(buzz.get(), timestamp); + } +}; +``` + +The trick is to delegate the `ShareBuzz()` method to a mock method (let’s call +it `DoShareBuzz()`) that does not take move-only parameters. Then, instead of +setting expectations on `ShareBuzz()`, you set them on the `DoShareBuzz()` mock +method: + +```cpp + MockBuzzer mock_buzzer_; + EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)); + + // When one calls ShareBuzz() on the MockBuzzer like this, the call is + // forwarded to DoShareBuzz(), which is mocked. Therefore this statement + // will trigger the above EXPECT_CALL. + mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal), 0); +``` + +### Making the Compilation Faster + +Believe it or not, the *vast majority* of the time spent on compiling a mock +class is in generating its constructor and destructor, as they perform +non-trivial tasks (e.g. verification of the expectations). What's more, mock +methods with different signatures have different types and thus their +constructors/destructors need to be generated by the compiler separately. As a +result, if you mock many different types of methods, compiling your mock class +can get really slow. + +If you are experiencing slow compilation, you can move the definition of your +mock class' constructor and destructor out of the class body and into a `.cc` +file. This way, even if you `#include` your mock class in N files, the compiler +only needs to generate its constructor and destructor once, resulting in a much +faster compilation. + +Let's illustrate the idea using an example. Here's the definition of a mock +class before applying this recipe: + +```cpp +// File mock_foo.h. +... +class MockFoo : public Foo { + public: + // Since we don't declare the constructor or the destructor, + // the compiler will generate them in every translation unit + // where this mock class is used. + + MOCK_METHOD(int, DoThis, (), (override)); + MOCK_METHOD(bool, DoThat, (const char* str), (override)); + ... more mock methods ... +}; +``` + +After the change, it would look like: + +```cpp +// File mock_foo.h. +... +class MockFoo : public Foo { + public: + // The constructor and destructor are declared, but not defined, here. + MockFoo(); + virtual ~MockFoo(); + + MOCK_METHOD(int, DoThis, (), (override)); + MOCK_METHOD(bool, DoThat, (const char* str), (override)); + ... more mock methods ... +}; +``` + +and + +```cpp +// File mock_foo.cc. +#include "path/to/mock_foo.h" + +// The definitions may appear trivial, but the functions actually do a +// lot of things through the constructors/destructors of the member +// variables used to implement the mock methods. +MockFoo::MockFoo() {} +MockFoo::~MockFoo() {} +``` + +### Forcing a Verification + +When it's being destroyed, your friendly mock object will automatically verify +that all expectations on it have been satisfied, and will generate googletest +failures if not. This is convenient as it leaves you with one less thing to +worry about. That is, unless you are not sure if your mock object will be +destroyed. + +How could it be that your mock object won't eventually be destroyed? Well, it +might be created on the heap and owned by the code you are testing. Suppose +there's a bug in that code and it doesn't delete the mock object properly - you +could end up with a passing test when there's actually a bug. + +Using a heap checker is a good idea and can alleviate the concern, but its +implementation is not 100% reliable. So, sometimes you do want to *force* gMock +to verify a mock object before it is (hopefully) destructed. You can do this +with `Mock::VerifyAndClearExpectations(&mock_object)`: + +```cpp +TEST(MyServerTest, ProcessesRequest) { + using ::testing::Mock; + + MockFoo* const foo = new MockFoo; + EXPECT_CALL(*foo, ...)...; + // ... other expectations ... + + // server now owns foo. + MyServer server(foo); + server.ProcessRequest(...); + + // In case that server's destructor will forget to delete foo, + // this will verify the expectations anyway. + Mock::VerifyAndClearExpectations(foo); +} // server is destroyed when it goes out of scope here. +``` + +**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a `bool` to +indicate whether the verification was successful (`true` for yes), so you can +wrap that function call inside a `ASSERT_TRUE()` if there is no point going +further when the verification has failed. + +### Using Check Points {#UsingCheckPoints} + +Sometimes you may want to "reset" a mock object at various check points in your +test: at each check point, you verify that all existing expectations on the mock +object have been satisfied, and then you set some new expectations on it as if +it's newly created. This allows you to work with a mock object in "phases" whose +sizes are each manageable. + +One such scenario is that in your test's `SetUp()` function, you may want to put +the object you are testing into a certain state, with the help from a mock +object. Once in the desired state, you want to clear all expectations on the +mock, such that in the `TEST_F` body you can set fresh expectations on it. + +As you may have figured out, the `Mock::VerifyAndClearExpectations()` function +we saw in the previous recipe can help you here. Or, if you are using +`ON_CALL()` to set default actions on the mock object and want to clear the +default actions as well, use `Mock::VerifyAndClear(&mock_object)` instead. This +function does what `Mock::VerifyAndClearExpectations(&mock_object)` does and +returns the same `bool`, **plus** it clears the `ON_CALL()` statements on +`mock_object` too. + +Another trick you can use to achieve the same effect is to put the expectations +in sequences and insert calls to a dummy "check-point" function at specific +places. Then you can verify that the mock function calls do happen at the right +time. For example, if you are exercising code: + +```cpp + Foo(1); + Foo(2); + Foo(3); +``` + +and want to verify that `Foo(1)` and `Foo(3)` both invoke `mock.Bar("a")`, but +`Foo(2)` doesn't invoke anything. You can write: + +```cpp +using ::testing::MockFunction; + +TEST(FooTest, InvokesBarCorrectly) { + MyMock mock; + // Class MockFunction has exactly one mock method. It is named + // Call() and has type F. + MockFunction check; + { + InSequence s; + + EXPECT_CALL(mock, Bar("a")); + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(mock, Bar("a")); + } + Foo(1); + check.Call("1"); + Foo(2); + check.Call("2"); + Foo(3); +} +``` + +The expectation spec says that the first `Bar("a")` must happen before check +point "1", the second `Bar("a")` must happen after check point "2", and nothing +should happen between the two check points. The explicit check points make it +easy to tell which `Bar("a")` is called by which call to `Foo()`. + +### Mocking Destructors + +Sometimes you want to make sure a mock object is destructed at the right time, +e.g. after `bar->A()` is called but before `bar->B()` is called. We already know +that you can specify constraints on the [order](#OrderedCalls) of mock function +calls, so all we need to do is to mock the destructor of the mock function. + +This sounds simple, except for one problem: a destructor is a special function +with special syntax and special semantics, and the `MOCK_METHOD` macro doesn't +work for it: + +```cpp +MOCK_METHOD(void, ~MockFoo, ()); // Won't compile! +``` + +The good news is that you can use a simple pattern to achieve the same effect. +First, add a mock function `Die()` to your mock class and call it in the +destructor, like this: + +```cpp +class MockFoo : public Foo { + ... + // Add the following two lines to the mock class. + MOCK_METHOD(void, Die, ()); + virtual ~MockFoo() { Die(); } +}; +``` + +(If the name `Die()` clashes with an existing symbol, choose another name.) Now, +we have translated the problem of testing when a `MockFoo` object dies to +testing when its `Die()` method is called: + +```cpp + MockFoo* foo = new MockFoo; + MockBar* bar = new MockBar; + ... + { + InSequence s; + + // Expects *foo to die after bar->A() and before bar->B(). + EXPECT_CALL(*bar, A()); + EXPECT_CALL(*foo, Die()); + EXPECT_CALL(*bar, B()); + } +``` + +And that's that. + +### Using gMock and Threads {#UsingThreads} + +In a **unit** test, it's best if you could isolate and test a piece of code in a +single-threaded context. That avoids race conditions and dead locks, and makes +debugging your test much easier. + +Yet most programs are multi-threaded, and sometimes to test something we need to +pound on it from more than one thread. gMock works for this purpose too. + +Remember the steps for using a mock: + +1. Create a mock object `foo`. +2. Set its default actions and expectations using `ON_CALL()` and + `EXPECT_CALL()`. +3. The code under test calls methods of `foo`. +4. Optionally, verify and reset the mock. +5. Destroy the mock yourself, or let the code under test destroy it. The + destructor will automatically verify it. + +If you follow the following simple rules, your mocks and threads can live +happily together: + +* Execute your *test code* (as opposed to the code being tested) in *one* + thread. This makes your test easy to follow. +* Obviously, you can do step #1 without locking. +* When doing step #2 and #5, make sure no other thread is accessing `foo`. + Obvious too, huh? +* #3 and #4 can be done either in one thread or in multiple threads - anyway + you want. gMock takes care of the locking, so you don't have to do any - + unless required by your test logic. + +If you violate the rules (for example, if you set expectations on a mock while +another thread is calling its methods), you get undefined behavior. That's not +fun, so don't do it. + +gMock guarantees that the action for a mock function is done in the same thread +that called the mock function. For example, in + +```cpp + EXPECT_CALL(mock, Foo(1)) + .WillOnce(action1); + EXPECT_CALL(mock, Foo(2)) + .WillOnce(action2); +``` + +if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, gMock will +execute `action1` in thread 1 and `action2` in thread 2. + +gMock does *not* impose a sequence on actions performed in different threads +(doing so may create deadlocks as the actions may need to cooperate). This means +that the execution of `action1` and `action2` in the above example *may* +interleave. If this is a problem, you should add proper synchronization logic to +`action1` and `action2` to make the test thread-safe. + +Also, remember that `DefaultValue` is a global resource that potentially +affects *all* living mock objects in your program. Naturally, you won't want to +mess with it from multiple threads or when there still are mocks in action. + +### Controlling How Much Information gMock Prints + +When gMock sees something that has the potential of being an error (e.g. a mock +function with no expectation is called, a.k.a. an uninteresting call, which is +allowed but perhaps you forgot to explicitly ban the call), it prints some +warning messages, including the arguments of the function, the return value, and +the stack trace. Hopefully this will remind you to take a look and see if there +is indeed a problem. + +Sometimes you are confident that your tests are correct and may not appreciate +such friendly messages. Some other times, you are debugging your tests or +learning about the behavior of the code you are testing, and wish you could +observe every mock call that happens (including argument values, the return +value, and the stack trace). Clearly, one size doesn't fit all. + +You can control how much gMock tells you using the `--gmock_verbose=LEVEL` +command-line flag, where `LEVEL` is a string with three possible values: + +* `info`: gMock will print all informational messages, warnings, and errors + (most verbose). At this setting, gMock will also log any calls to the + `ON_CALL/EXPECT_CALL` macros. It will include a stack trace in + "uninteresting call" warnings. +* `warning`: gMock will print both warnings and errors (less verbose); it will + omit the stack traces in "uninteresting call" warnings. This is the default. +* `error`: gMock will print errors only (least verbose). + +Alternatively, you can adjust the value of that flag from within your tests like +so: + +```cpp + ::testing::FLAGS_gmock_verbose = "error"; +``` + +If you find gMock printing too many stack frames with its informational or +warning messages, remember that you can control their amount with the +`--gtest_stack_trace_depth=max_depth` flag. + +Now, judiciously use the right flag to enable gMock serve you better! + +### Gaining Super Vision into Mock Calls + +You have a test using gMock. It fails: gMock tells you some expectations aren't +satisfied. However, you aren't sure why: Is there a typo somewhere in the +matchers? Did you mess up the order of the `EXPECT_CALL`s? Or is the code under +test doing something wrong? How can you find out the cause? + +Won't it be nice if you have X-ray vision and can actually see the trace of all +`EXPECT_CALL`s and mock method calls as they are made? For each call, would you +like to see its actual argument values and which `EXPECT_CALL` gMock thinks it +matches? If you still need some help to figure out who made these calls, how +about being able to see the complete stack trace at each mock call? + +You can unlock this power by running your test with the `--gmock_verbose=info` +flag. For example, given the test program: + +```cpp +#include "gmock/gmock.h" + +using testing::_; +using testing::HasSubstr; +using testing::Return; + +class MockFoo { + public: + MOCK_METHOD(void, F, (const string& x, const string& y)); +}; + +TEST(Foo, Bar) { + MockFoo mock; + EXPECT_CALL(mock, F(_, _)).WillRepeatedly(Return()); + EXPECT_CALL(mock, F("a", "b")); + EXPECT_CALL(mock, F("c", HasSubstr("d"))); + + mock.F("a", "good"); + mock.F("a", "b"); +} +``` + +if you run it with `--gmock_verbose=info`, you will see this output: + +```shell +[ RUN ] Foo.Bar + +foo_test.cc:14: EXPECT_CALL(mock, F(_, _)) invoked +Stack trace: ... + +foo_test.cc:15: EXPECT_CALL(mock, F("a", "b")) invoked +Stack trace: ... + +foo_test.cc:16: EXPECT_CALL(mock, F("c", HasSubstr("d"))) invoked +Stack trace: ... + +foo_test.cc:14: Mock function call matches EXPECT_CALL(mock, F(_, _))... + Function call: F(@0x7fff7c8dad40"a",@0x7fff7c8dad10"good") +Stack trace: ... + +foo_test.cc:15: Mock function call matches EXPECT_CALL(mock, F("a", "b"))... + Function call: F(@0x7fff7c8dada0"a",@0x7fff7c8dad70"b") +Stack trace: ... + +foo_test.cc:16: Failure +Actual function call count doesn't match EXPECT_CALL(mock, F("c", HasSubstr("d")))... + Expected: to be called once + Actual: never called - unsatisfied and active +[ FAILED ] Foo.Bar +``` + +Suppose the bug is that the `"c"` in the third `EXPECT_CALL` is a typo and +should actually be `"a"`. With the above message, you should see that the actual +`F("a", "good")` call is matched by the first `EXPECT_CALL`, not the third as +you thought. From that it should be obvious that the third `EXPECT_CALL` is +written wrong. Case solved. + +If you are interested in the mock call trace but not the stack traces, you can +combine `--gmock_verbose=info` with `--gtest_stack_trace_depth=0` on the test +command line. + + + +### Running Tests in Emacs + +If you build and run your tests in Emacs using the `M-x google-compile` command +(as many googletest users do), the source file locations of gMock and googletest +errors will be highlighted. Just press `` on one of them and you'll be +taken to the offending line. Or, you can just type `C-x`` to jump to the next +error. + +To make it even easier, you can add the following lines to your `~/.emacs` file: + +```text +(global-set-key "\M-m" 'google-compile) ; m is for make +(global-set-key [M-down] 'next-error) +(global-set-key [M-up] '(lambda () (interactive) (next-error -1))) +``` + +Then you can type `M-m` to start a build (if you want to run the test as well, +just make sure `foo_test.run` or `runtests` is in the build command you supply +after typing `M-m`), or `M-up`/`M-down` to move back and forth between errors. + +## Extending gMock + +### Writing New Matchers Quickly {#NewMatchers} + +WARNING: gMock does not guarantee when or how many times a matcher will be +invoked. Therefore, all matchers must be functionally pure. See +[this section](#PureMatchers) for more details. + +The `MATCHER*` family of macros can be used to define custom matchers easily. +The syntax: + +```cpp +MATCHER(name, description_string_expression) { statements; } +``` + +will define a matcher with the given name that executes the statements, which +must return a `bool` to indicate if the match succeeds. Inside the statements, +you can refer to the value being matched by `arg`, and refer to its type by +`arg_type`. + +The *description string* is a `string`-typed expression that documents what the +matcher does, and is used to generate the failure message when the match fails. +It can (and should) reference the special `bool` variable `negation`, and should +evaluate to the description of the matcher when `negation` is `false`, or that +of the matcher's negation when `negation` is `true`. + +For convenience, we allow the description string to be empty (`""`), in which +case gMock will use the sequence of words in the matcher name as the +description. + +For example: + +```cpp +MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } +``` + +allows you to write + +```cpp + // Expects mock_foo.Bar(n) to be called where n is divisible by 7. + EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); +``` + +or, + +```cpp + using ::testing::Not; + ... + // Verifies that two values are divisible by 7. + EXPECT_THAT(some_expression, IsDivisibleBy7()); + EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); +``` + +If the above assertions fail, they will print something like: + +```shell + Value of: some_expression + Expected: is divisible by 7 + Actual: 27 + ... + Value of: some_other_expression + Expected: not (is divisible by 7) + Actual: 21 +``` + +where the descriptions `"is divisible by 7"` and `"not (is divisible by 7)"` are +automatically calculated from the matcher name `IsDivisibleBy7`. + +As you may have noticed, the auto-generated descriptions (especially those for +the negation) may not be so great. You can always override them with a `string` +expression of your own: + +```cpp +MATCHER(IsDivisibleBy7, + absl::StrCat(negation ? "isn't" : "is", " divisible by 7")) { + return (arg % 7) == 0; +} +``` + +Optionally, you can stream additional information to a hidden argument named +`result_listener` to explain the match result. For example, a better definition +of `IsDivisibleBy7` is: + +```cpp +MATCHER(IsDivisibleBy7, "") { + if ((arg % 7) == 0) + return true; + + *result_listener << "the remainder is " << (arg % 7); + return false; +} +``` + +With this definition, the above assertion will give a better message: + +```shell + Value of: some_expression + Expected: is divisible by 7 + Actual: 27 (the remainder is 6) +``` + +You should let `MatchAndExplain()` print *any additional information* that can +help a user understand the match result. Note that it should explain why the +match succeeds in case of a success (unless it's obvious) - this is useful when +the matcher is used inside `Not()`. There is no need to print the argument value +itself, as gMock already prints it for you. + +NOTE: The type of the value being matched (`arg_type`) is determined by the +context in which you use the matcher and is supplied to you by the compiler, so +you don't need to worry about declaring it (nor can you). This allows the +matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match +any type where the value of `(arg % 7) == 0` can be implicitly converted to a +`bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an +`int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will +be `unsigned long`; and so on. + +### Writing New Parameterized Matchers Quickly + +Sometimes you'll want to define a matcher that has parameters. For that you can +use the macro: + +```cpp +MATCHER_P(name, param_name, description_string) { statements; } +``` + +where the description string can be either `""` or a `string` expression that +references `negation` and `param_name`. + +For example: + +```cpp +MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +``` + +will allow you to write: + +```cpp + EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +``` + +which may lead to this message (assuming `n` is 10): + +```shell + Value of: Blah("a") + Expected: has absolute value 10 + Actual: -9 +``` + +Note that both the matcher description and its parameter are printed, making the +message human-friendly. + +In the matcher definition body, you can write `foo_type` to reference the type +of a parameter named `foo`. For example, in the body of +`MATCHER_P(HasAbsoluteValue, value)` above, you can write `value_type` to refer +to the type of `value`. + +gMock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to `MATCHER_P10` to +support multi-parameter matchers: + +```cpp +MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; } +``` + +Please note that the custom description string is for a particular *instance* of +the matcher, where the parameters have been bound to actual values. Therefore +usually you'll want the parameter values to be part of the description. gMock +lets you do that by referencing the matcher parameters in the description string +expression. + +For example, + +```cpp +using ::testing::PrintToString; +MATCHER_P2(InClosedRange, low, hi, + absl::StrFormat("%s in range [%s, %s]", negation ? "isn't" : "is", + PrintToString(low), PrintToString(hi))) { + return low <= arg && arg <= hi; +} +... +EXPECT_THAT(3, InClosedRange(4, 6)); +``` + +would generate a failure that contains the message: + +```shell + Expected: is in range [4, 6] +``` + +If you specify `""` as the description, the failure message will contain the +sequence of words in the matcher name followed by the parameter values printed +as a tuple. For example, + +```cpp + MATCHER_P2(InClosedRange, low, hi, "") { ... } + ... + EXPECT_THAT(3, InClosedRange(4, 6)); +``` + +would generate a failure that contains the text: + +```shell + Expected: in closed range (4, 6) +``` + +For the purpose of typing, you can view + +```cpp +MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +``` + +as shorthand for + +```cpp +template +FooMatcherPk +Foo(p1_type p1, ..., pk_type pk) { ... } +``` + +When you write `Foo(v1, ..., vk)`, the compiler infers the types of the +parameters `v1`, ..., and `vk` for you. If you are not happy with the result of +the type inference, you can specify the types by explicitly instantiating the +template, as in `Foo(5, false)`. As said earlier, you don't get to +(or need to) specify `arg_type` as that's determined by the context in which the +matcher is used. + +You can assign the result of expression `Foo(p1, ..., pk)` to a variable of type +`FooMatcherPk`. This can be useful when composing +matchers. Matchers that don't have a parameter or have only one parameter have +special types: you can assign `Foo()` to a `FooMatcher`-typed variable, and +assign `Foo(p)` to a `FooMatcherP`-typed variable. + +While you can instantiate a matcher template with reference types, passing the +parameters by pointer usually makes your code more readable. If, however, you +still want to pass a parameter by reference, be aware that in the failure +message generated by the matcher you will see the value of the referenced object +but not its address. + +You can overload matchers with different numbers of parameters: + +```cpp +MATCHER_P(Blah, a, description_string_1) { ... } +MATCHER_P2(Blah, a, b, description_string_2) { ... } +``` + +While it's tempting to always use the `MATCHER*` macros when defining a new +matcher, you should also consider implementing `MatcherInterface` or using +`MakePolymorphicMatcher()` instead (see the recipes that follow), especially if +you need to use the matcher a lot. While these approaches require more work, +they give you more control on the types of the value being matched and the +matcher parameters, which in general leads to better compiler error messages +that pay off in the long run. They also allow overloading matchers based on +parameter types (as opposed to just based on the number of parameters). + +### Writing New Monomorphic Matchers + +A matcher of argument type `T` implements `::testing::MatcherInterface` and +does two things: it tests whether a value of type `T` matches the matcher, and +can describe what kind of values it matches. The latter ability is used for +generating readable error messages when expectations are violated. + +The interface looks like this: + +```cpp +class MatchResultListener { + public: + ... + // Streams x to the underlying ostream; does nothing if the ostream + // is NULL. + template + MatchResultListener& operator<<(const T& x); + + // Returns the underlying ostream. + std::ostream* stream(); +}; + +template +class MatcherInterface { + public: + virtual ~MatcherInterface(); + + // Returns true if and only if the matcher matches x; also explains the match + // result to 'listener'. + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; + + // Describes this matcher to an ostream. + virtual void DescribeTo(std::ostream* os) const = 0; + + // Describes the negation of this matcher to an ostream. + virtual void DescribeNegationTo(std::ostream* os) const; +}; +``` + +If you need a custom matcher but `Truly()` is not a good option (for example, +you may not be happy with the way `Truly(predicate)` describes itself, or you +may want your matcher to be polymorphic as `Eq(value)` is), you can define a +matcher to do whatever you want in two steps: first implement the matcher +interface, and then define a factory function to create a matcher instance. The +second step is not strictly needed but it makes the syntax of using the matcher +nicer. + +For example, you can define a matcher to test whether an `int` is divisible by 7 +and then use it like this: + +```cpp +using ::testing::MakeMatcher; +using ::testing::Matcher; +using ::testing::MatcherInterface; +using ::testing::MatchResultListener; + +class DivisibleBy7Matcher : public MatcherInterface { + public: + bool MatchAndExplain(int n, + MatchResultListener* /* listener */) const override { + return (n % 7) == 0; + } + + void DescribeTo(std::ostream* os) const override { + *os << "is divisible by 7"; + } + + void DescribeNegationTo(std::ostream* os) const override { + *os << "is not divisible by 7"; + } +}; + +Matcher DivisibleBy7() { + return MakeMatcher(new DivisibleBy7Matcher); +} + +... + EXPECT_CALL(foo, Bar(DivisibleBy7())); +``` + +You may improve the matcher message by streaming additional information to the +`listener` argument in `MatchAndExplain()`: + +```cpp +class DivisibleBy7Matcher : public MatcherInterface { + public: + bool MatchAndExplain(int n, + MatchResultListener* listener) const override { + const int remainder = n % 7; + if (remainder != 0) { + *listener << "the remainder is " << remainder; + } + return remainder == 0; + } + ... +}; +``` + +Then, `EXPECT_THAT(x, DivisibleBy7());` may generate a message like this: + +```shell +Value of: x +Expected: is divisible by 7 + Actual: 23 (the remainder is 2) +``` + +### Writing New Polymorphic Matchers + +You've learned how to write your own matchers in the previous recipe. Just one +problem: a matcher created using `MakeMatcher()` only works for one particular +type of arguments. If you want a *polymorphic* matcher that works with arguments +of several types (for instance, `Eq(x)` can be used to match a *`value`* as long +as `value == x` compiles -- *`value`* and `x` don't have to share the same +type), you can learn the trick from `testing/base/public/gmock-matchers.h` but +it's a bit involved. + +Fortunately, most of the time you can define a polymorphic matcher easily with +the help of `MakePolymorphicMatcher()`. Here's how you can define `NotNull()` as +an example: + +```cpp +using ::testing::MakePolymorphicMatcher; +using ::testing::MatchResultListener; +using ::testing::PolymorphicMatcher; + +class NotNullMatcher { + public: + // To implement a polymorphic matcher, first define a COPYABLE class + // that has three members MatchAndExplain(), DescribeTo(), and + // DescribeNegationTo(), like the following. + + // In this example, we want to use NotNull() with any pointer, so + // MatchAndExplain() accepts a pointer of any type as its first argument. + // In general, you can define MatchAndExplain() as an ordinary method or + // a method template, or even overload it. + template + bool MatchAndExplain(T* p, + MatchResultListener* /* listener */) const { + return p != NULL; + } + + // Describes the property of a value matching this matcher. + void DescribeTo(std::ostream* os) const { *os << "is not NULL"; } + + // Describes the property of a value NOT matching this matcher. + void DescribeNegationTo(std::ostream* os) const { *os << "is NULL"; } +}; + +// To construct a polymorphic matcher, pass an instance of the class +// to MakePolymorphicMatcher(). Note the return type. +PolymorphicMatcher NotNull() { + return MakePolymorphicMatcher(NotNullMatcher()); +} + +... + + EXPECT_CALL(foo, Bar(NotNull())); // The argument must be a non-NULL pointer. +``` + +**Note:** Your polymorphic matcher class does **not** need to inherit from +`MatcherInterface` or any other class, and its methods do **not** need to be +virtual. + +Like in a monomorphic matcher, you may explain the match result by streaming +additional information to the `listener` argument in `MatchAndExplain()`. + +### Writing New Cardinalities + +A cardinality is used in `Times()` to tell gMock how many times you expect a +call to occur. It doesn't have to be exact. For example, you can say +`AtLeast(5)` or `Between(2, 4)`. + +If the [built-in set](cheat_sheet.md#CardinalityList) of cardinalities doesn't +suit you, you are free to define your own by implementing the following +interface (in namespace `testing`): + +```cpp +class CardinalityInterface { + public: + virtual ~CardinalityInterface(); + + // Returns true if and only if call_count calls will satisfy this cardinality. + virtual bool IsSatisfiedByCallCount(int call_count) const = 0; + + // Returns true if and only if call_count calls will saturate this + // cardinality. + virtual bool IsSaturatedByCallCount(int call_count) const = 0; + + // Describes self to an ostream. + virtual void DescribeTo(std::ostream* os) const = 0; +}; +``` + +For example, to specify that a call must occur even number of times, you can +write + +```cpp +using ::testing::Cardinality; +using ::testing::CardinalityInterface; +using ::testing::MakeCardinality; + +class EvenNumberCardinality : public CardinalityInterface { + public: + bool IsSatisfiedByCallCount(int call_count) const override { + return (call_count % 2) == 0; + } + + bool IsSaturatedByCallCount(int call_count) const override { + return false; + } + + void DescribeTo(std::ostream* os) const { + *os << "called even number of times"; + } +}; + +Cardinality EvenNumber() { + return MakeCardinality(new EvenNumberCardinality); +} + +... + EXPECT_CALL(foo, Bar(3)) + .Times(EvenNumber()); +``` + +### Writing New Actions Quickly {#QuickNewActions} + +If the built-in actions don't work for you, you can easily define your own one. +Just define a functor class with a (possibly templated) call operator, matching +the signature of your action. + +```cpp +struct Increment { + template + T operator()(T* arg) { + return ++(*arg); + } +} +``` + +The same approach works with stateful functors (or any callable, really): + +``` +struct MultiplyBy { + template + T operator()(T arg) { return arg * multiplier; } + + int multiplier; +} + +// Then use: +// EXPECT_CALL(...).WillOnce(MultiplyBy{7}); +``` + +#### Legacy macro-based Actions + +Before C++11, the functor-based actions were not supported; the old way of +writing actions was through a set of `ACTION*` macros. We suggest to avoid them +in new code; they hide a lot of logic behind the macro, potentially leading to +harder-to-understand compiler errors. Nevertheless, we cover them here for +completeness. + +By writing + +```cpp +ACTION(name) { statements; } +``` + +in a namespace scope (i.e. not inside a class or function), you will define an +action with the given name that executes the statements. The value returned by +`statements` will be used as the return value of the action. Inside the +statements, you can refer to the K-th (0-based) argument of the mock function as +`argK`. For example: + +```cpp +ACTION(IncrementArg1) { return ++(*arg1); } +``` + +allows you to write + +```cpp +... WillOnce(IncrementArg1()); +``` + +Note that you don't need to specify the types of the mock function arguments. +Rest assured that your code is type-safe though: you'll get a compiler error if +`*arg1` doesn't support the `++` operator, or if the type of `++(*arg1)` isn't +compatible with the mock function's return type. + +Another example: + +```cpp +ACTION(Foo) { + (*arg2)(5); + Blah(); + *arg1 = 0; + return arg0; +} +``` + +defines an action `Foo()` that invokes argument #2 (a function pointer) with 5, +calls function `Blah()`, sets the value pointed to by argument #1 to 0, and +returns argument #0. + +For more convenience and flexibility, you can also use the following pre-defined +symbols in the body of `ACTION`: + +`argK_type` | The type of the K-th (0-based) argument of the mock function +:-------------- | :----------------------------------------------------------- +`args` | All arguments of the mock function as a tuple +`args_type` | The type of all arguments of the mock function as a tuple +`return_type` | The return type of the mock function +`function_type` | The type of the mock function + +For example, when using an `ACTION` as a stub action for mock function: + +```cpp +int DoSomething(bool flag, int* ptr); +``` + +we have: + +Pre-defined Symbol | Is Bound To +------------------ | --------------------------------- +`arg0` | the value of `flag` +`arg0_type` | the type `bool` +`arg1` | the value of `ptr` +`arg1_type` | the type `int*` +`args` | the tuple `(flag, ptr)` +`args_type` | the type `std::tuple` +`return_type` | the type `int` +`function_type` | the type `int(bool, int*)` + +#### Legacy macro-based parameterized Actions + +Sometimes you'll want to parameterize an action you define. For that we have +another macro + +```cpp +ACTION_P(name, param) { statements; } +``` + +For example, + +```cpp +ACTION_P(Add, n) { return arg0 + n; } +``` + +will allow you to write + +```cpp +// Returns argument #0 + 5. +... WillOnce(Add(5)); +``` + +For convenience, we use the term *arguments* for the values used to invoke the +mock function, and the term *parameters* for the values used to instantiate an +action. + +Note that you don't need to provide the type of the parameter either. Suppose +the parameter is named `param`, you can also use the gMock-defined symbol +`param_type` to refer to the type of the parameter as inferred by the compiler. +For example, in the body of `ACTION_P(Add, n)` above, you can write `n_type` for +the type of `n`. + +gMock also provides `ACTION_P2`, `ACTION_P3`, and etc to support multi-parameter +actions. For example, + +```cpp +ACTION_P2(ReturnDistanceTo, x, y) { + double dx = arg0 - x; + double dy = arg1 - y; + return sqrt(dx*dx + dy*dy); +} +``` + +lets you write + +```cpp +... WillOnce(ReturnDistanceTo(5.0, 26.5)); +``` + +You can view `ACTION` as a degenerated parameterized action where the number of +parameters is 0. + +You can also easily define actions overloaded on the number of parameters: + +```cpp +ACTION_P(Plus, a) { ... } +ACTION_P2(Plus, a, b) { ... } +``` + +### Restricting the Type of an Argument or Parameter in an ACTION + +For maximum brevity and reusability, the `ACTION*` macros don't ask you to +provide the types of the mock function arguments and the action parameters. +Instead, we let the compiler infer the types for us. + +Sometimes, however, we may want to be more explicit about the types. There are +several tricks to do that. For example: + +```cpp +ACTION(Foo) { + // Makes sure arg0 can be converted to int. + int n = arg0; + ... use n instead of arg0 here ... +} + +ACTION_P(Bar, param) { + // Makes sure the type of arg1 is const char*. + ::testing::StaticAssertTypeEq(); + + // Makes sure param can be converted to bool. + bool flag = param; +} +``` + +where `StaticAssertTypeEq` is a compile-time assertion in googletest that +verifies two types are the same. + +### Writing New Action Templates Quickly + +Sometimes you want to give an action explicit template parameters that cannot be +inferred from its value parameters. `ACTION_TEMPLATE()` supports that and can be +viewed as an extension to `ACTION()` and `ACTION_P*()`. + +The syntax: + +```cpp +ACTION_TEMPLATE(ActionName, + HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), + AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +``` + +defines an action template that takes *m* explicit template parameters and *n* +value parameters, where *m* is in [1, 10] and *n* is in [0, 10]. `name_i` is the +name of the *i*-th template parameter, and `kind_i` specifies whether it's a +`typename`, an integral constant, or a template. `p_i` is the name of the *i*-th +value parameter. + +Example: + +```cpp +// DuplicateArg(output) converts the k-th argument of the mock +// function to type T and copies it to *output. +ACTION_TEMPLATE(DuplicateArg, + // Note the comma between int and k: + HAS_2_TEMPLATE_PARAMS(int, k, typename, T), + AND_1_VALUE_PARAMS(output)) { + *output = T(std::get(args)); +} +``` + +To create an instance of an action template, write: + +```cpp +ActionName(v1, ..., v_n) +``` + +where the `t`s are the template arguments and the `v`s are the value arguments. +The value argument types are inferred by the compiler. For example: + +```cpp +using ::testing::_; +... + int n; + EXPECT_CALL(mock, Foo).WillOnce(DuplicateArg<1, unsigned char>(&n)); +``` + +If you want to explicitly specify the value argument types, you can provide +additional template arguments: + +```cpp +ActionName(v1, ..., v_n) +``` + +where `u_i` is the desired type of `v_i`. + +`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the number of +value parameters, but not on the number of template parameters. Without the +restriction, the meaning of the following is unclear: + +```cpp + OverloadedAction(x); +``` + +Are we using a single-template-parameter action where `bool` refers to the type +of `x`, or a two-template-parameter action where the compiler is asked to infer +the type of `x`? + +### Using the ACTION Object's Type + +If you are writing a function that returns an `ACTION` object, you'll need to +know its type. The type depends on the macro used to define the action and the +parameter types. The rule is relatively simple: + +| Given Definition | Expression | Has Type | +| ----------------------------- | ------------------- | --------------------- | +| `ACTION(Foo)` | `Foo()` | `FooAction` | +| `ACTION_TEMPLATE(Foo,` | `Foo()` : t_m>` : +: `AND_0_VALUE_PARAMS())` : : : +| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP` | +| `ACTION_TEMPLATE(Bar,` | `Bar` | `FooActionP` : +: `AND_1_VALUE_PARAMS(p1))` : : : +| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value,` | `BazActionP2` : +| `ACTION_TEMPLATE(Baz,` | `Baz` | `FooActionP2` : +: `AND_2_VALUE_PARAMS(p1, p2))` : `int_value)` : : +| ... | ... | ... | + +Note that we have to pick different suffixes (`Action`, `ActionP`, `ActionP2`, +and etc) for actions with different numbers of value parameters, or the action +definitions cannot be overloaded on the number of them. + +### Writing New Monomorphic Actions {#NewMonoActions} + +While the `ACTION*` macros are very convenient, sometimes they are +inappropriate. For example, despite the tricks shown in the previous recipes, +they don't let you directly specify the types of the mock function arguments and +the action parameters, which in general leads to unoptimized compiler error +messages that can baffle unfamiliar users. They also don't allow overloading +actions based on parameter types without jumping through some hoops. + +An alternative to the `ACTION*` macros is to implement +`::testing::ActionInterface`, where `F` is the type of the mock function in +which the action will be used. For example: + +```cpp +template +class ActionInterface { + public: + virtual ~ActionInterface(); + + // Performs the action. Result is the return type of function type + // F, and ArgumentTuple is the tuple of arguments of F. + // + + // For example, if F is int(bool, const string&), then Result would + // be int, and ArgumentTuple would be std::tuple. + virtual Result Perform(const ArgumentTuple& args) = 0; +}; +``` + +```cpp +using ::testing::_; +using ::testing::Action; +using ::testing::ActionInterface; +using ::testing::MakeAction; + +typedef int IncrementMethod(int*); + +class IncrementArgumentAction : public ActionInterface { + public: + int Perform(const std::tuple& args) override { + int* p = std::get<0>(args); // Grabs the first argument. + return *p++; + } +}; + +Action IncrementArgument() { + return MakeAction(new IncrementArgumentAction); +} + +... + EXPECT_CALL(foo, Baz(_)) + .WillOnce(IncrementArgument()); + + int n = 5; + foo.Baz(&n); // Should return 5 and change n to 6. +``` + +### Writing New Polymorphic Actions {#NewPolyActions} + +The previous recipe showed you how to define your own action. This is all good, +except that you need to know the type of the function in which the action will +be used. Sometimes that can be a problem. For example, if you want to use the +action in functions with *different* types (e.g. like `Return()` and +`SetArgPointee()`). + +If an action can be used in several types of mock functions, we say it's +*polymorphic*. The `MakePolymorphicAction()` function template makes it easy to +define such an action: + +```cpp +namespace testing { +template +PolymorphicAction MakePolymorphicAction(const Impl& impl); +} // namespace testing +``` + +As an example, let's define an action that returns the second argument in the +mock function's argument list. The first step is to define an implementation +class: + +```cpp +class ReturnSecondArgumentAction { + public: + template + Result Perform(const ArgumentTuple& args) const { + // To get the i-th (0-based) argument, use std::get(args). + return std::get<1>(args); + } +}; +``` + +This implementation class does *not* need to inherit from any particular class. +What matters is that it must have a `Perform()` method template. This method +template takes the mock function's arguments as a tuple in a **single** +argument, and returns the result of the action. It can be either `const` or not, +but must be invokable with exactly one template argument, which is the result +type. In other words, you must be able to call `Perform(args)` where `R` is +the mock function's return type and `args` is its arguments in a tuple. + +Next, we use `MakePolymorphicAction()` to turn an instance of the implementation +class into the polymorphic action we need. It will be convenient to have a +wrapper for this: + +```cpp +using ::testing::MakePolymorphicAction; +using ::testing::PolymorphicAction; + +PolymorphicAction ReturnSecondArgument() { + return MakePolymorphicAction(ReturnSecondArgumentAction()); +} +``` + +Now, you can use this polymorphic action the same way you use the built-in ones: + +```cpp +using ::testing::_; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, DoThis, (bool flag, int n), (override)); + MOCK_METHOD(string, DoThat, (int x, const char* str1, const char* str2), + (override)); +}; + + ... + MockFoo foo; + EXPECT_CALL(foo, DoThis).WillOnce(ReturnSecondArgument()); + EXPECT_CALL(foo, DoThat).WillOnce(ReturnSecondArgument()); + ... + foo.DoThis(true, 5); // Will return 5. + foo.DoThat(1, "Hi", "Bye"); // Will return "Hi". +``` + +### Teaching gMock How to Print Your Values + +When an uninteresting or unexpected call occurs, gMock prints the argument +values and the stack trace to help you debug. Assertion macros like +`EXPECT_THAT` and `EXPECT_EQ` also print the values in question when the +assertion fails. gMock and googletest do this using googletest's user-extensible +value printer. + +This printer knows how to print built-in C++ types, native arrays, STL +containers, and any type that supports the `<<` operator. For other types, it +prints the raw bytes in the value and hopes that you the user can figure it out. +[googletest's advanced guide](../../googletest/docs/advanced.md#teaching-googletest-how-to-print-your-values) +explains how to extend the printer to do a better job at printing your +particular type than to dump the bytes. + +## Useful Mocks Created Using gMock + + + + +### Mock std::function {#MockFunction} + +`std::function` is a general function type introduced in C++11. It is a +preferred way of passing callbacks to new interfaces. Functions are copiable, +and are not usually passed around by pointer, which makes them tricky to mock. +But fear not - `MockFunction` can help you with that. + +`MockFunction` has a mock method `Call()` with the signature: + +```cpp + R Call(T1, ..., Tn); +``` + +It also has a `AsStdFunction()` method, which creates a `std::function` proxy +forwarding to Call: + +```cpp + std::function AsStdFunction(); +``` + +To use `MockFunction`, first create `MockFunction` object and set up +expectations on its `Call` method. Then pass proxy obtained from +`AsStdFunction()` to the code you are testing. For example: + +```cpp +TEST(FooTest, RunsCallbackWithBarArgument) { + // 1. Create a mock object. + MockFunction mock_function; + + // 2. Set expectations on Call() method. + EXPECT_CALL(mock_function, Call("bar")).WillOnce(Return(1)); + + // 3. Exercise code that uses std::function. + Foo(mock_function.AsStdFunction()); + // Foo's signature can be either of: + // void Foo(const std::function& fun); + // void Foo(std::function fun); + + // 4. All expectations will be verified when mock_function + // goes out of scope and is destroyed. +} +``` + +Remember that function objects created with `AsStdFunction()` are just +forwarders. If you create multiple of them, they will share the same set of +expectations. + +Although `std::function` supports unlimited number of arguments, `MockFunction` +implementation is limited to ten. If you ever hit that limit... well, your +callback has bigger problems than being mockable. :-) + + diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/for_dummies.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/for_dummies.md new file mode 100644 index 000000000..93cf06f38 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/for_dummies.md @@ -0,0 +1,700 @@ +## gMock for Dummies {#GMockForDummies} + + + +### What Is gMock? + +When you write a prototype or test, often it's not feasible or wise to rely on +real objects entirely. A **mock object** implements the same interface as a real +object (so it can be used as one), but lets you specify at run time how it will +be used and what it should do (which methods will be called? in which order? how +many times? with what arguments? what will they return? etc). + +**Note:** It is easy to confuse the term *fake objects* with mock objects. Fakes +and mocks actually mean very different things in the Test-Driven Development +(TDD) community: + +* **Fake** objects have working implementations, but usually take some + shortcut (perhaps to make the operations less expensive), which makes them + not suitable for production. An in-memory file system would be an example of + a fake. +* **Mocks** are objects pre-programmed with *expectations*, which form a + specification of the calls they are expected to receive. + +If all this seems too abstract for you, don't worry - the most important thing +to remember is that a mock allows you to check the *interaction* between itself +and code that uses it. The difference between fakes and mocks shall become much +clearer once you start to use mocks. + +**gMock** is a library (sometimes we also call it a "framework" to make it sound +cool) for creating mock classes and using them. It does to C++ what +jMock/EasyMock does to Java (well, more or less). + +When using gMock, + +1. first, you use some simple macros to describe the interface you want to + mock, and they will expand to the implementation of your mock class; +2. next, you create some mock objects and specify its expectations and behavior + using an intuitive syntax; +3. then you exercise code that uses the mock objects. gMock will catch any + violation to the expectations as soon as it arises. + +### Why gMock? + +While mock objects help you remove unnecessary dependencies in tests and make +them fast and reliable, using mocks manually in C++ is *hard*: + +* Someone has to implement the mocks. The job is usually tedious and + error-prone. No wonder people go great distance to avoid it. +* The quality of those manually written mocks is a bit, uh, unpredictable. You + may see some really polished ones, but you may also see some that were + hacked up in a hurry and have all sorts of ad hoc restrictions. +* The knowledge you gained from using one mock doesn't transfer to the next + one. + +In contrast, Java and Python programmers have some fine mock frameworks (jMock, +EasyMock, [Mox](http://wtf/mox), etc), which automate the creation of mocks. As +a result, mocking is a proven effective technique and widely adopted practice in +those communities. Having the right tool absolutely makes the difference. + +gMock was built to help C++ programmers. It was inspired by jMock and EasyMock, +but designed with C++'s specifics in mind. It is your friend if any of the +following problems is bothering you: + +* You are stuck with a sub-optimal design and wish you had done more + prototyping before it was too late, but prototyping in C++ is by no means + "rapid". +* Your tests are slow as they depend on too many libraries or use expensive + resources (e.g. a database). +* Your tests are brittle as some resources they use are unreliable (e.g. the + network). +* You want to test how your code handles a failure (e.g. a file checksum + error), but it's not easy to cause one. +* You need to make sure that your module interacts with other modules in the + right way, but it's hard to observe the interaction; therefore you resort to + observing the side effects at the end of the action, but it's awkward at + best. +* You want to "mock out" your dependencies, except that they don't have mock + implementations yet; and, frankly, you aren't thrilled by some of those + hand-written mocks. + +We encourage you to use gMock as + +* a *design* tool, for it lets you experiment with your interface design early + and often. More iterations lead to better designs! +* a *testing* tool to cut your tests' outbound dependencies and probe the + interaction between your module and its collaborators. + +### Getting Started + +gMock is bundled with googletest. + +### A Case for Mock Turtles + +Let's look at an example. Suppose you are developing a graphics program that +relies on a [LOGO](http://en.wikipedia.org/wiki/Logo_programming_language)-like +API for drawing. How would you test that it does the right thing? Well, you can +run it and compare the screen with a golden screen snapshot, but let's admit it: +tests like this are expensive to run and fragile (What if you just upgraded to a +shiny new graphics card that has better anti-aliasing? Suddenly you have to +update all your golden images.). It would be too painful if all your tests are +like this. Fortunately, you learned about +[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) and know the right thing +to do: instead of having your application talk to the system API directly, wrap +the API in an interface (say, `Turtle`) and code to that interface: + +```cpp +class Turtle { + ... + virtual ~Turtle() {}; + virtual void PenUp() = 0; + virtual void PenDown() = 0; + virtual void Forward(int distance) = 0; + virtual void Turn(int degrees) = 0; + virtual void GoTo(int x, int y) = 0; + virtual int GetX() const = 0; + virtual int GetY() const = 0; +}; +``` + +(Note that the destructor of `Turtle` **must** be virtual, as is the case for +**all** classes you intend to inherit from - otherwise the destructor of the +derived class will not be called when you delete an object through a base +pointer, and you'll get corrupted program states like memory leaks.) + +You can control whether the turtle's movement will leave a trace using `PenUp()` +and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and +`GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the +turtle. + +Your program will normally use a real implementation of this interface. In +tests, you can use a mock implementation instead. This allows you to easily +check what drawing primitives your program is calling, with what arguments, and +in which order. Tests written this way are much more robust (they won't break +because your new machine does anti-aliasing differently), easier to read and +maintain (the intent of a test is expressed in the code, not in some binary +images), and run *much, much faster*. + +### Writing the Mock Class + +If you are lucky, the mocks you need to use have already been implemented by +some nice people. If, however, you find yourself in the position to write a mock +class, relax - gMock turns this task into a fun game! (Well, almost.) + +#### How to Define It + +Using the `Turtle` interface as example, here are the simple steps you need to +follow: + +* Derive a class `MockTurtle` from `Turtle`. +* Take a *virtual* function of `Turtle` (while it's possible to + [mock non-virtual methods using templates](cook_book.md#MockingNonVirtualMethods), + it's much more involved). +* In the `public:` section of the child class, write `MOCK_METHOD();` +* Now comes the fun part: you take the function signature, cut-and-paste it + into the macro, and add two commas - one between the return type and the + name, another between the name and the argument list. +* If you're mocking a const method, add a 4th parameter containing `(const)` + (the parentheses are required). +* Since you're overriding a virtual method, we suggest adding the `override` + keyword. For const methods the 4th parameter becomes `(const, override)`, + for non-const methods just `(override)`. This isn't mandatory. +* Repeat until all virtual functions you want to mock are done. (It goes + without saying that *all* pure virtual methods in your abstract class must + be either mocked or overridden.) + +After the process, you should have something like: + +```cpp +#include "gmock/gmock.h" // Brings in gMock. + +class MockTurtle : public Turtle { + public: + ... + MOCK_METHOD(void, PenUp, (), (override)); + MOCK_METHOD(void, PenDown, (), (override)); + MOCK_METHOD(void, Forward, (int distance), (override)); + MOCK_METHOD(void, Turn, (int degrees), (override)); + MOCK_METHOD(void, GoTo, (int x, int y), (override)); + MOCK_METHOD(int, GetX, (), (const, override)); + MOCK_METHOD(int, GetY, (), (const, override)); +}; +``` + +You don't need to define these mock methods somewhere else - the `MOCK_METHOD` +macro will generate the definitions for you. It's that simple! + +#### Where to Put It + +When you define a mock class, you need to decide where to put its definition. +Some people put it in a `_test.cc`. This is fine when the interface being mocked +(say, `Foo`) is owned by the same person or team. Otherwise, when the owner of +`Foo` changes it, your test could break. (You can't really expect `Foo`'s +maintainer to fix every test that uses `Foo`, can you?) + +So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, +define the mock class in `Foo`'s package (better, in a `testing` sub-package +such that you can clearly separate production code and testing utilities), put +it in a `.h` and a `cc_library`. Then everyone can reference them from their +tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and +only tests that depend on the changed methods need to be fixed. + +Another way to do it: you can introduce a thin layer `FooAdaptor` on top of +`Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb +changes in `Foo` much more easily. While this is more work initially, carefully +choosing the adaptor interface can make your code easier to write and more +readable (a net win in the long run), as you can choose `FooAdaptor` to fit your +specific domain much better than `Foo` does. + + + +### Using Mocks in Tests + +Once you have a mock class, using it is easy. The typical work flow is: + +1. Import the gMock names from the `testing` namespace such that you can use + them unqualified (You only have to do it once per file). Remember that + namespaces are a good idea. +2. Create some mock objects. +3. Specify your expectations on them (How many times will a method be called? + With what arguments? What should it do? etc.). +4. Exercise some code that uses the mocks; optionally, check the result using + googletest assertions. If a mock method is called more than expected or with + wrong arguments, you'll get an error immediately. +5. When a mock is destructed, gMock will automatically check whether all + expectations on it have been satisfied. + +Here's an example: + +```cpp +#include "path/to/mock-turtle.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using ::testing::AtLeast; // #1 + +TEST(PainterTest, CanDrawSomething) { + MockTurtle turtle; // #2 + EXPECT_CALL(turtle, PenDown()) // #3 + .Times(AtLeast(1)); + + Painter painter(&turtle); // #4 + + EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); // #5 +} +``` + +As you might have guessed, this test checks that `PenDown()` is called at least +once. If the `painter` object didn't call this method, your test will fail with +a message like this: + +```text +path/to/my_test.cc:119: Failure +Actual function call count doesn't match this expectation: +Actually: never called; +Expected: called at least once. +Stack trace: +... +``` + +**Tip 1:** If you run the test from an Emacs buffer, you can hit on the +line number to jump right to the failed expectation. + +**Tip 2:** If your mock objects are never deleted, the final verification won't +happen. Therefore it's a good idea to turn on the heap checker in your tests +when you allocate mocks on the heap. You get that automatically if you use the +`gtest_main` library already. + +**Important note:** gMock requires expectations to be set **before** the mock +functions are called, otherwise the behavior is **undefined**. In particular, +you mustn't interleave `EXPECT_CALL()s` and calls to the mock functions. + +This means `EXPECT_CALL()` should be read as expecting that a call will occur +*in the future*, not that a call has occurred. Why does gMock work like that? +Well, specifying the expectation beforehand allows gMock to report a violation +as soon as it rises, when the context (stack trace, etc) is still available. +This makes debugging much easier. + +Admittedly, this test is contrived and doesn't do much. You can easily achieve +the same effect without using gMock. However, as we shall reveal soon, gMock +allows you to do *so much more* with the mocks. + +### Setting Expectations + +The key to using a mock object successfully is to set the *right expectations* +on it. If you set the expectations too strict, your test will fail as the result +of unrelated changes. If you set them too loose, bugs can slip through. You want +to do it just right such that your test can catch exactly the kind of bugs you +intend it to catch. gMock provides the necessary means for you to do it "just +right." + +#### General Syntax + +In gMock we use the `EXPECT_CALL()` macro to set an expectation on a mock +method. The general syntax is: + +```cpp +EXPECT_CALL(mock_object, method(matchers)) + .Times(cardinality) + .WillOnce(action) + .WillRepeatedly(action); +``` + +The macro has two arguments: first the mock object, and then the method and its +arguments. Note that the two are separated by a comma (`,`), not a period (`.`). +(Why using a comma? The answer is that it was necessary for technical reasons.) +If the method is not overloaded, the macro can also be called without matchers: + +```cpp +EXPECT_CALL(mock_object, non-overloaded-method) + .Times(cardinality) + .WillOnce(action) + .WillRepeatedly(action); +``` + +This syntax allows the test writer to specify "called with any arguments" +without explicitly specifying the number or types of arguments. To avoid +unintended ambiguity, this syntax may only be used for methods which are not +overloaded + +Either form of the macro can be followed by some optional *clauses* that provide +more information about the expectation. We'll discuss how each clause works in +the coming sections. + +This syntax is designed to make an expectation read like English. For example, +you can probably guess that + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetX()) + .Times(5) + .WillOnce(Return(100)) + .WillOnce(Return(150)) + .WillRepeatedly(Return(200)); +``` + +says that the `turtle` object's `GetX()` method will be called five times, it +will return 100 the first time, 150 the second time, and then 200 every time. +Some people like to call this style of syntax a Domain-Specific Language (DSL). + +**Note:** Why do we use a macro to do this? Well it serves two purposes: first +it makes expectations easily identifiable (either by `gsearch` or by a human +reader), and second it allows gMock to include the source file location of a +failed expectation in messages, making debugging easier. + +#### Matchers: What Arguments Do We Expect? + +When a mock function takes arguments, we may specify what arguments we are +expecting, for example: + +```cpp +// Expects the turtle to move forward by 100 units. +EXPECT_CALL(turtle, Forward(100)); +``` + +Oftentimes you do not want to be too specific. Remember that talk about tests +being too rigid? Over specification leads to brittle tests and obscures the +intent of tests. Therefore we encourage you to specify only what's necessary—no +more, no less. If you aren't interested in the value of an argument, write `_` +as the argument, which means "anything goes": + +```cpp +using ::testing::_; +... +// Expects that the turtle jumps to somewhere on the x=50 line. +EXPECT_CALL(turtle, GoTo(50, _)); +``` + +`_` is an instance of what we call **matchers**. A matcher is like a predicate +and can test whether an argument is what we'd expect. You can use a matcher +inside `EXPECT_CALL()` wherever a function argument is expected. `_` is a +convenient way of saying "any value". + +In the above examples, `100` and `50` are also matchers; implicitly, they are +the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be +equal (using `operator==`) to the matcher argument. There are many +[built-in matchers](#MatcherList) for common types (as well as +[custom matchers](cook_book.md#NewMatchers)); for example: + +```cpp +using ::testing::Ge; +... +// Expects the turtle moves forward by at least 100. +EXPECT_CALL(turtle, Forward(Ge(100))); +``` + +If you don't care about *any* arguments, rather than specify `_` for each of +them you may instead omit the parameter list: + +```cpp +// Expects the turtle to move forward. +EXPECT_CALL(turtle, Forward); +// Expects the turtle to jump somewhere. +EXPECT_CALL(turtle, GoTo); +``` + +This works for all non-overloaded methods; if a method is overloaded, you need +to help gMock resolve which overload is expected by specifying the number of +arguments and possibly also the +[types of the arguments](cook_book.md#SelectOverload). + +#### Cardinalities: How Many Times Will It Be Called? + +The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We +call its argument a **cardinality** as it tells *how many times* the call should +occur. It allows us to repeat an expectation many times without actually writing +it as many times. More importantly, a cardinality can be "fuzzy", just like a +matcher can be. This allows a user to express the intent of a test exactly. + +An interesting special case is when we say `Times(0)`. You may have guessed - it +means that the function shouldn't be called with the given arguments at all, and +gMock will report a googletest failure whenever the function is (wrongfully) +called. + +We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the +list of built-in cardinalities you can use, see +[here](cheat_sheet.md#CardinalityList). + +The `Times()` clause can be omitted. **If you omit `Times()`, gMock will infer +the cardinality for you.** The rules are easy to remember: + +* If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the + `EXPECT_CALL()`, the inferred cardinality is `Times(1)`. +* If there are *n* `WillOnce()`'s but **no** `WillRepeatedly()`, where *n* >= + 1, the cardinality is `Times(n)`. +* If there are *n* `WillOnce()`'s and **one** `WillRepeatedly()`, where *n* >= + 0, the cardinality is `Times(AtLeast(n))`. + +**Quick quiz:** what do you think will happen if a function is expected to be +called twice but actually called four times? + +#### Actions: What Should It Do? + +Remember that a mock object doesn't really have a working implementation? We as +users have to tell it what to do when a method is invoked. This is easy in +gMock. + +First, if the return type of a mock function is a built-in type or a pointer, +the function has a **default action** (a `void` function will just return, a +`bool` function will return `false`, and other functions will return 0). In +addition, in C++ 11 and above, a mock function whose return type is +default-constructible (i.e. has a default constructor) has a default action of +returning a default-constructed value. If you don't say anything, this behavior +will be used. + +Second, if a mock function doesn't have a default action, or the default action +doesn't suit you, you can specify the action to be taken each time the +expectation matches using a series of `WillOnce()` clauses followed by an +optional `WillRepeatedly()`. For example, + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(100)) + .WillOnce(Return(200)) + .WillOnce(Return(300)); +``` + +says that `turtle.GetX()` will be called *exactly three times* (gMock inferred +this from how many `WillOnce()` clauses we've written, since we didn't +explicitly write `Times()`), and will return 100, 200, and 300 respectively. + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetY()) + .WillOnce(Return(100)) + .WillOnce(Return(200)) + .WillRepeatedly(Return(300)); +``` + +says that `turtle.GetY()` will be called *at least twice* (gMock knows this as +we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no +explicit `Times()`), will return 100 and 200 respectively the first two times, +and 300 from the third time on. + +Of course, if you explicitly write a `Times()`, gMock will not try to infer the +cardinality itself. What if the number you specified is larger than there are +`WillOnce()` clauses? Well, after all `WillOnce()`s are used up, gMock will do +the *default* action for the function every time (unless, of course, you have a +`WillRepeatedly()`.). + +What can we do inside `WillOnce()` besides `Return()`? You can return a +reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among +[others](cook_book.md#using-actions). + +**Important note:** The `EXPECT_CALL()` statement evaluates the action clause +only once, even though the action may be performed many times. Therefore you +must be careful about side effects. The following may not do what you want: + +```cpp +using ::testing::Return; +... +int n = 100; +EXPECT_CALL(turtle, GetX()) + .Times(4) + .WillRepeatedly(Return(n++)); +``` + +Instead of returning 100, 101, 102, ..., consecutively, this mock function will +always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)` +will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will +return the same pointer every time. If you want the side effect to happen every +time, you need to define a custom action, which we'll teach in the +[cook book](http://). + +Time for another quiz! What do you think the following means? + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetY()) + .Times(4) + .WillOnce(Return(100)); +``` + +Obviously `turtle.GetY()` is expected to be called four times. But if you think +it will return 100 every time, think twice! Remember that one `WillOnce()` +clause will be consumed each time the function is invoked and the default action +will be taken afterwards. So the right answer is that `turtle.GetY()` will +return 100 the first time, but **return 0 from the second time on**, as +returning 0 is the default action for `int` functions. + +#### Using Multiple Expectations {#MultiExpectations} + +So far we've only shown examples where you have a single expectation. More +realistically, you'll specify expectations on multiple mock methods which may be +from multiple mock objects. + +By default, when a mock method is invoked, gMock will search the expectations in +the **reverse order** they are defined, and stop when an active expectation that +matches the arguments is found (you can think of it as "newer rules override +older ones."). If the matching expectation cannot take any more calls, you will +get an upper-bound-violated failure. Here's an example: + +```cpp +using ::testing::_; +... +EXPECT_CALL(turtle, Forward(_)); // #1 +EXPECT_CALL(turtle, Forward(10)) // #2 + .Times(2); +``` + +If `Forward(10)` is called three times in a row, the third time it will be an +error, as the last matching expectation (#2) has been saturated. If, however, +the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK, +as now #1 will be the matching expectation. + +**Note:** Why does gMock search for a match in the *reverse* order of the +expectations? The reason is that this allows a user to set up the default +expectations in a mock object's constructor or the test fixture's set-up phase +and then customize the mock by writing more specific expectations in the test +body. So, if you have two expectations on the same method, you want to put the +one with more specific matchers **after** the other, or the more specific rule +would be shadowed by the more general one that comes after it. + +**Tip:** It is very common to start with a catch-all expectation for a method +and `Times(AnyNumber())` (omitting arguments, or with `_` for all arguments, if +overloaded). This makes any calls to the method expected. This is not necessary +for methods that are not mentioned at all (these are "uninteresting"), but is +useful for methods that have some expectations, but for which other calls are +ok. See +[Understanding Uninteresting vs Unexpected Calls](cook_book.md#uninteresting-vs-unexpected). + +#### Ordered vs Unordered Calls {#OrderedCalls} + +By default, an expectation can match a call even though an earlier expectation +hasn't been satisfied. In other words, the calls don't have to occur in the +order the expectations are specified. + +Sometimes, you may want all the expected calls to occur in a strict order. To +say this in gMock is easy: + +```cpp +using ::testing::InSequence; +... +TEST(FooTest, DrawsLineSegment) { + ... + { + InSequence seq; + + EXPECT_CALL(turtle, PenDown()); + EXPECT_CALL(turtle, Forward(100)); + EXPECT_CALL(turtle, PenUp()); + } + Foo(); +} +``` + +By creating an object of type `InSequence`, all expectations in its scope are +put into a *sequence* and have to occur *sequentially*. Since we are just +relying on the constructor and destructor of this object to do the actual work, +its name is really irrelevant. + +In this example, we test that `Foo()` calls the three expected functions in the +order as written. If a call is made out-of-order, it will be an error. + +(What if you care about the relative order of some of the calls, but not all of +them? Can you specify an arbitrary partial order? The answer is ... yes! The +details can be found [here](cook_book.md#OrderedCalls).) + +#### All Expectations Are Sticky (Unless Said Otherwise) {#StickyExpectations} + +Now let's do a quick quiz to see how well you can use this mock stuff already. +How would you test that the turtle is asked to go to the origin *exactly twice* +(you want to ignore any other instructions it receives)? + +After you've come up with your answer, take a look at ours and compare notes +(solve it yourself first - don't cheat!): + +```cpp +using ::testing::_; +using ::testing::AnyNumber; +... +EXPECT_CALL(turtle, GoTo(_, _)) // #1 + .Times(AnyNumber()); +EXPECT_CALL(turtle, GoTo(0, 0)) // #2 + .Times(2); +``` + +Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, gMock will +see that the arguments match expectation #2 (remember that we always pick the +last matching expectation). Now, since we said that there should be only two +such calls, gMock will report an error immediately. This is basically what we've +told you in the [Using Multiple Expectations](#MultiExpectations) section above. + +This example shows that **expectations in gMock are "sticky" by default**, in +the sense that they remain active even after we have reached their invocation +upper bounds. This is an important rule to remember, as it affects the meaning +of the spec, and is **different** to how it's done in many other mocking +frameworks (Why'd we do that? Because we think our rule makes the common cases +easier to express and understand.). + +Simple? Let's see if you've really understood it: what does the following code +say? + +```cpp +using ::testing::Return; +... +for (int i = n; i > 0; i--) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)); +} +``` + +If you think it says that `turtle.GetX()` will be called `n` times and will +return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we +said, expectations are sticky. So, the second time `turtle.GetX()` is called, +the last (latest) `EXPECT_CALL()` statement will match, and will immediately +lead to an "upper bound violated" error - this piece of code is not very useful! + +One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is +to explicitly say that the expectations are *not* sticky. In other words, they +should *retire* as soon as they are saturated: + +```cpp +using ::testing::Return; +... +for (int i = n; i > 0; i--) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)) + .RetiresOnSaturation(); +} +``` + +And, there's a better way to do it: in this case, we expect the calls to occur +in a specific order, and we line up the actions to match the order. Since the +order is important here, we should make it explicit using a sequence: + +```cpp +using ::testing::InSequence; +using ::testing::Return; +... +{ + InSequence s; + + for (int i = 1; i <= n; i++) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)) + .RetiresOnSaturation(); + } +} +``` + +By the way, the other situation where an expectation may *not* be sticky is when +it's in a sequence - as soon as another expectation that comes after it in the +sequence has been used, it automatically retires (and will never be used to +match any call). + +#### Uninteresting Calls + +A mock object may have many methods, and not all of them are that interesting. +For example, in some tests we may not care about how many times `GetX()` and +`GetY()` get called. + +In gMock, if you are not interested in a method, just don't say anything about +it. If a call to this method occurs, you'll see a warning in the test output, +but it won't be a failure. This is called "naggy" behavior; to change, see +[The Nice, the Strict, and the Naggy](cook_book.md#NiceStrictNaggy). diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/gmock_faq.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/gmock_faq.md new file mode 100644 index 000000000..214aabf12 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/gmock_faq.md @@ -0,0 +1,396 @@ +## Legacy gMock FAQ {#GMockFaq} + + + +### When I call a method on my mock object, the method for the real object is invoked instead. What's the problem? + +In order for a method to be mocked, it must be *virtual*, unless you use the +[high-perf dependency injection technique](#MockingNonVirtualMethods). + +### Can I mock a variadic function? + +You cannot mock a variadic function (i.e. a function taking ellipsis (`...`) +arguments) directly in gMock. + +The problem is that in general, there is *no way* for a mock object to know how +many arguments are passed to the variadic method, and what the arguments' types +are. Only the *author of the base class* knows the protocol, and we cannot look +into his or her head. + +Therefore, to mock such a function, the *user* must teach the mock object how to +figure out the number of arguments and their types. One way to do it is to +provide overloaded versions of the function. + +Ellipsis arguments are inherited from C and not really a C++ feature. They are +unsafe to use and don't work with arguments that have constructors or +destructors. Therefore we recommend to avoid them in C++ as much as possible. + +### MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? + +If you compile this using Microsoft Visual C++ 2005 SP1: + +```cpp +class Foo { + ... + virtual void Bar(const int i) = 0; +}; + +class MockFoo : public Foo { + ... + MOCK_METHOD(void, Bar, (const int i), (override)); +}; +``` + +You may get the following warning: + +```shell +warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier +``` + +This is a MSVC bug. The same code compiles fine with gcc, for example. If you +use Visual C++ 2008 SP1, you would get the warning: + +```shell +warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers +``` + +In C++, if you *declare* a function with a `const` parameter, the `const` +modifier is ignored. Therefore, the `Foo` base class above is equivalent to: + +```cpp +class Foo { + ... + virtual void Bar(int i) = 0; // int or const int? Makes no difference. +}; +``` + +In fact, you can *declare* `Bar()` with an `int` parameter, and define it with a +`const int` parameter. The compiler will still match them up. + +Since making a parameter `const` is meaningless in the method declaration, we +recommend to remove it in both `Foo` and `MockFoo`. That should workaround the +VC bug. + +Note that we are talking about the *top-level* `const` modifier here. If the +function parameter is passed by pointer or reference, declaring the pointee or +referee as `const` is still meaningful. For example, the following two +declarations are *not* equivalent: + +```cpp +void Bar(int* p); // Neither p nor *p is const. +void Bar(const int* p); // p is not const, but *p is. +``` + + + +### I can't figure out why gMock thinks my expectations are not satisfied. What should I do? + +You might want to run your test with `--gmock_verbose=info`. This flag lets +gMock print a trace of every mock function call it receives. By studying the +trace, you'll gain insights on why the expectations you set are not met. + +If you see the message "The mock function has no default action set, and its +return type has no default value set.", then try +[adding a default action](for_dummies.md#DefaultValue). Due to a known issue, +unexpected calls on mocks without default actions don't print out a detailed +comparison between the actual arguments and the expected arguments. + +### My program crashed and `ScopedMockLog` spit out tons of messages. Is it a gMock bug? + +gMock and `ScopedMockLog` are likely doing the right thing here. + +When a test crashes, the failure signal handler will try to log a lot of +information (the stack trace, and the address map, for example). The messages +are compounded if you have many threads with depth stacks. When `ScopedMockLog` +intercepts these messages and finds that they don't match any expectations, it +prints an error for each of them. + +You can learn to ignore the errors, or you can rewrite your expectations to make +your test more robust, for example, by adding something like: + +```cpp +using ::testing::AnyNumber; +using ::testing::Not; +... + // Ignores any log not done by us. + EXPECT_CALL(log, Log(_, Not(EndsWith("/my_file.cc")), _)) + .Times(AnyNumber()); +``` + +### How can I assert that a function is NEVER called? + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .Times(0); +``` + + + +### I have a failed test where gMock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? + +When gMock detects a failure, it prints relevant information (the mock function +arguments, the state of relevant expectations, and etc) to help the user debug. +If another failure is detected, gMock will do the same, including printing the +state of relevant expectations. + +Sometimes an expectation's state didn't change between two failures, and you'll +see the same description of the state twice. They are however *not* redundant, +as they refer to *different points in time*. The fact they are the same *is* +interesting information. + +### I get a heapcheck failure when using a mock object, but using a real object is fine. What can be wrong? + +Does the class (hopefully a pure interface) you are mocking have a virtual +destructor? + +Whenever you derive from a base class, make sure its destructor is virtual. +Otherwise Bad Things will happen. Consider the following code: + +```cpp +class Base { + public: + // Not virtual, but should be. + ~Base() { ... } + ... +}; + +class Derived : public Base { + public: + ... + private: + std::string value_; +}; + +... + Base* p = new Derived; + ... + delete p; // Surprise! ~Base() will be called, but ~Derived() will not + // - value_ is leaked. +``` + +By changing `~Base()` to virtual, `~Derived()` will be correctly called when +`delete p` is executed, and the heap checker will be happy. + +### The "newer expectations override older ones" rule makes writing expectations awkward. Why does gMock do that? + +When people complain about this, often they are referring to code like: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. However, I have to write the expectations in the + // reverse order. This sucks big time!!! + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(2)) + .RetiresOnSaturation(); + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .RetiresOnSaturation(); +``` + +The problem, is that they didn't pick the **best** way to express the test's +intent. + +By default, expectations don't have to be matched in *any* particular order. If +you want them to match in a certain order, you need to be explicit. This is +gMock's (and jMock's) fundamental philosophy: it's easy to accidentally +over-specify your tests, and we want to make it harder to do so. + +There are two better ways to write the test spec. You could either put the +expectations in sequence: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. Using a sequence, we can write the expectations + // in their natural order. + { + InSequence s; + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .RetiresOnSaturation(); + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(2)) + .RetiresOnSaturation(); + } +``` + +or you can put the sequence of actions in the same expectation: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .WillOnce(Return(2)) + .RetiresOnSaturation(); +``` + +Back to the original questions: why does gMock search the expectations (and +`ON_CALL`s) from back to front? Because this allows a user to set up a mock's +behavior for the common case early (e.g. in the mock's constructor or the test +fixture's set-up phase) and customize it with more specific rules later. If +gMock searches from front to back, this very useful pattern won't be possible. + +### gMock prints a warning when a function without EXPECT_CALL is called, even if I have set its behavior using ON_CALL. Would it be reasonable not to show the warning in this case? + +When choosing between being neat and being safe, we lean toward the latter. So +the answer is that we think it's better to show the warning. + +Often people write `ON_CALL`s in the mock object's constructor or `SetUp()`, as +the default behavior rarely changes from test to test. Then in the test body +they set the expectations, which are often different for each test. Having an +`ON_CALL` in the set-up part of a test doesn't mean that the calls are expected. +If there's no `EXPECT_CALL` and the method is called, it's possibly an error. If +we quietly let the call go through without notifying the user, bugs may creep in +unnoticed. + +If, however, you are sure that the calls are OK, you can write + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .WillRepeatedly(...); +``` + +instead of + +```cpp +using ::testing::_; +... + ON_CALL(foo, Bar(_)) + .WillByDefault(...); +``` + +This tells gMock that you do expect the calls and no warning should be printed. + +Also, you can control the verbosity by specifying `--gmock_verbose=error`. Other +values are `info` and `warning`. If you find the output too noisy when +debugging, just choose a less verbose level. + +### How can I delete the mock function's argument in an action? + +If your mock function takes a pointer argument and you want to delete that +argument, you can use testing::DeleteArg() to delete the N'th (zero-indexed) +argument: + +```cpp +using ::testing::_; + ... + MOCK_METHOD(void, Bar, (X* x, const Y& y)); + ... + EXPECT_CALL(mock_foo_, Bar(_, _)) + .WillOnce(testing::DeleteArg<0>())); +``` + +### How can I perform an arbitrary action on a mock function's argument? + +If you find yourself needing to perform some action that's not supported by +gMock directly, remember that you can define your own actions using +[`MakeAction()`](#NewMonoActions) or +[`MakePolymorphicAction()`](#NewPolyActions), or you can write a stub function +and invoke it using [`Invoke()`](#FunctionsAsActions). + +```cpp +using ::testing::_; +using ::testing::Invoke; + ... + MOCK_METHOD(void, Bar, (X* p)); + ... + EXPECT_CALL(mock_foo_, Bar(_)) + .WillOnce(Invoke(MyAction(...))); +``` + +### My code calls a static/global function. Can I mock it? + +You can, but you need to make some changes. + +In general, if you find yourself needing to mock a static function, it's a sign +that your modules are too tightly coupled (and less flexible, less reusable, +less testable, etc). You are probably better off defining a small interface and +call the function through that interface, which then can be easily mocked. It's +a bit of work initially, but usually pays for itself quickly. + +This Google Testing Blog +[post](https://testing.googleblog.com/2008/06/defeat-static-cling.html) says it +excellently. Check it out. + +### My mock object needs to do complex stuff. It's a lot of pain to specify the actions. gMock sucks! + +I know it's not a question, but you get an answer for free any way. :-) + +With gMock, you can create mocks in C++ easily. And people might be tempted to +use them everywhere. Sometimes they work great, and sometimes you may find them, +well, a pain to use. So, what's wrong in the latter case? + +When you write a test without using mocks, you exercise the code and assert that +it returns the correct value or that the system is in an expected state. This is +sometimes called "state-based testing". + +Mocks are great for what some call "interaction-based" testing: instead of +checking the system state at the very end, mock objects verify that they are +invoked the right way and report an error as soon as it arises, giving you a +handle on the precise context in which the error was triggered. This is often +more effective and economical to do than state-based testing. + +If you are doing state-based testing and using a test double just to simulate +the real object, you are probably better off using a fake. Using a mock in this +case causes pain, as it's not a strong point for mocks to perform complex +actions. If you experience this and think that mocks suck, you are just not +using the right tool for your problem. Or, you might be trying to solve the +wrong problem. :-) + +### I got a warning "Uninteresting function call encountered - default action taken.." Should I panic? + +By all means, NO! It's just an FYI. :-) + +What it means is that you have a mock function, you haven't set any expectations +on it (by gMock's rule this means that you are not interested in calls to this +function and therefore it can be called any number of times), and it is called. +That's OK - you didn't say it's not OK to call the function! + +What if you actually meant to disallow this function to be called, but forgot to +write `EXPECT_CALL(foo, Bar()).Times(0)`? While one can argue that it's the +user's fault, gMock tries to be nice and prints you a note. + +So, when you see the message and believe that there shouldn't be any +uninteresting calls, you should investigate what's going on. To make your life +easier, gMock dumps the stack trace when an uninteresting call is encountered. +From that you can figure out which mock function it is, and how it is called. + +### I want to define a custom action. Should I use Invoke() or implement the ActionInterface interface? + +Either way is fine - you want to choose the one that's more convenient for your +circumstance. + +Usually, if your action is for a particular function type, defining it using +`Invoke()` should be easier; if your action can be used in functions of +different types (e.g. if you are defining `Return(*value*)`), +`MakePolymorphicAction()` is easiest. Sometimes you want precise control on what +types of functions the action can be used in, and implementing `ActionInterface` +is the way to go here. See the implementation of `Return()` in +`testing/base/public/gmock-actions.h` for an example. + +### I use SetArgPointee() in WillOnce(), but gcc complains about "conflicting return type specified". What does it mean? + +You got this error as gMock has no idea what value it should return when the +mock method is called. `SetArgPointee()` says what the side effect is, but +doesn't say what the return value should be. You need `DoAll()` to chain a +`SetArgPointee()` with a `Return()` that provides a value appropriate to the API +being mocked. + +See this [recipe](cook_book.md#mocking-side-effects) for more details and an +example. + +### I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? + +We've noticed that when the `/clr` compiler flag is used, Visual C++ uses 5~6 +times as much memory when compiling a mock class. We suggest to avoid `/clr` +when compiling native C++ mocks. diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/pump_manual.md b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/pump_manual.md new file mode 100644 index 000000000..cdf7c57da --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/docs/pump_manual.md @@ -0,0 +1,187 @@ +Pump is Useful for Meta Programming. + +# The Problem + +Template and macro libraries often need to define many classes, functions, or +macros that vary only (or almost only) in the number of arguments they take. +It's a lot of repetitive, mechanical, and error-prone work. + +Our experience is that it's tedious to write custom scripts, which tend to +reflect the structure of the generated code poorly and are often hard to read +and edit. For example, a small change needed in the generated code may require +some non-intuitive, non-trivial changes in the script. This is especially +painful when experimenting with the code. + +This script may be useful for generating meta code, for example a series of +macros of FOO1, FOO2, etc. Nevertheless, please make it your last resort +technique by favouring C++ template metaprogramming or variadic macros. + +# Our Solution + +Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta +Programming, or Practical Utility for Meta Programming, whichever you prefer) is +a simple meta-programming tool for C++. The idea is that a programmer writes a +`foo.pump` file which contains C++ code plus meta code that manipulates the C++ +code. The meta code can handle iterations over a range, nested iterations, local +meta variable definitions, simple arithmetic, and conditional expressions. You +can view it as a small Domain-Specific Language. The meta language is designed +to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and +concise, making Pump code intuitive and easy to maintain. + +## Highlights + +* The implementation is in a single Python script and thus ultra portable: no + build or installation is needed and it works cross platforms. +* Pump tries to be smart with respect to + [Google's style guide](https://github.com/google/styleguide): it breaks long + lines (easy to have when they are generated) at acceptable places to fit + within 80 columns and indent the continuation lines correctly. +* The format is human-readable and more concise than XML. +* The format works relatively well with Emacs' C++ mode. + +## Examples + +The following Pump code (where meta keywords start with `$`, `[[` and `]]` are +meta brackets, and `$$` starts a meta comment that ends with the line): + +``` +$var n = 3 $$ Defines a meta variable n. +$range i 0..n $$ Declares the range of meta iterator i (inclusive). +$for i [[ + $$ Meta loop. +// Foo$i does blah for $i-ary predicates. +$range j 1..i +template +class Foo$i { +$if i == 0 [[ + blah a; +]] $elif i <= 2 [[ + blah b; +]] $else [[ + blah c; +]] +}; + +]] +``` + +will be translated by the Pump compiler to: + +```cpp +// Foo0 does blah for 0-ary predicates. +template +class Foo0 { + blah a; +}; + +// Foo1 does blah for 1-ary predicates. +template +class Foo1 { + blah b; +}; + +// Foo2 does blah for 2-ary predicates. +template +class Foo2 { + blah b; +}; + +// Foo3 does blah for 3-ary predicates. +template +class Foo3 { + blah c; +}; +``` + +In another example, + +``` +$range i 1..n +Func($for i + [[a$i]]); +$$ The text between i and [[ is the separator between iterations. +``` + +will generate one of the following lines (without the comments), depending on +the value of `n`: + +```cpp +Func(); // If n is 0. +Func(a1); // If n is 1. +Func(a1 + a2); // If n is 2. +Func(a1 + a2 + a3); // If n is 3. +// And so on... +``` + +## Constructs + +We support the following meta programming constructs: + +| `$var id = exp` | Defines a named constant value. `$id` is | +: : valid util the end of the current meta : +: : lexical block. : +| :------------------------------- | :--------------------------------------- | +| `$range id exp..exp` | Sets the range of an iteration variable, | +: : which can be reused in multiple loops : +: : later. : +| `$for id sep [[ code ]]` | Iteration. The range of `id` must have | +: : been defined earlier. `$id` is valid in : +: : `code`. : +| `$($)` | Generates a single `$` character. | +| `$id` | Value of the named constant or iteration | +: : variable. : +| `$(exp)` | Value of the expression. | +| `$if exp [[ code ]] else_branch` | Conditional. | +| `[[ code ]]` | Meta lexical block. | +| `cpp_code` | Raw C++ code. | +| `$$ comment` | Meta comment. | + +**Note:** To give the user some freedom in formatting the Pump source code, Pump +ignores a new-line character if it's right after `$for foo` or next to `[[` or +`]]`. Without this rule you'll often be forced to write very long lines to get +the desired output. Therefore sometimes you may need to insert an extra new-line +in such places for a new-line to show up in your output. + +## Grammar + +```ebnf +code ::= atomic_code* +atomic_code ::= $var id = exp + | $var id = [[ code ]] + | $range id exp..exp + | $for id sep [[ code ]] + | $($) + | $id + | $(exp) + | $if exp [[ code ]] else_branch + | [[ code ]] + | cpp_code +sep ::= cpp_code | empty_string +else_branch ::= $else [[ code ]] + | $elif exp [[ code ]] else_branch + | empty_string +exp ::= simple_expression_in_Python_syntax +``` + +## Code + +You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). +It is still very unpolished and lacks automated tests, although it has been +successfully used many times. If you find a chance to use it in your project, +please let us know what you think! We also welcome help on improving Pump. + +## Real Examples + +You can find real-world applications of Pump in +[Google Test](https://github.com/google/googletest/tree/master/googletest) and +[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The +source file `foo.h.pump` generates `foo.h`. + +## Tips + +* If a meta variable is followed by a letter or digit, you can separate them + using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` + generate `Foo1Helper` when `j` is 1. +* To avoid extra-long Pump source lines, you can break a line anywhere you + want by inserting `[[]]` followed by a new line. Since any new-line + character next to `[[` or `]]` is ignored, the generated code won't contain + this new line. diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-actions.h b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-actions.h new file mode 100644 index 000000000..4b8dcebb9 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-actions.h @@ -0,0 +1,1234 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ + +#ifndef _WIN32_WCE +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +namespace testing { + +// To implement an action Foo, define: +// 1. a class FooAction that implements the ActionInterface interface, and +// 2. a factory function that creates an Action object from a +// const FooAction*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Action objects can now be copied like plain values. + +namespace internal { + +// BuiltInDefaultValueGetter::Get() returns a +// default-constructed T value. BuiltInDefaultValueGetter::Get() crashes with an error. +// +// This primary template is used when kDefaultConstructible is true. +template +struct BuiltInDefaultValueGetter { + static T Get() { return T(); } +}; +template +struct BuiltInDefaultValueGetter { + static T Get() { + Assert(false, __FILE__, __LINE__, + "Default action undefined for the function return type."); + return internal::Invalid(); + // The above statement will never be reached, but is required in + // order for this function to compile. + } +}; + +// BuiltInDefaultValue::Get() returns the "built-in" default value +// for type T, which is NULL when T is a raw pointer type, 0 when T is +// a numeric type, false when T is bool, or "" when T is string or +// std::string. In addition, in C++11 and above, it turns a +// default-constructed T value if T is default constructible. For any +// other type T, the built-in default T value is undefined, and the +// function will abort the process. +template +class BuiltInDefaultValue { + public: + // This function returns true if and only if type T has a built-in default + // value. + static bool Exists() { + return ::std::is_default_constructible::value; + } + + static T Get() { + return BuiltInDefaultValueGetter< + T, ::std::is_default_constructible::value>::Get(); + } +}; + +// This partial specialization says that we use the same built-in +// default value for T and const T. +template +class BuiltInDefaultValue { + public: + static bool Exists() { return BuiltInDefaultValue::Exists(); } + static T Get() { return BuiltInDefaultValue::Get(); } +}; + +// This partial specialization defines the default values for pointer +// types. +template +class BuiltInDefaultValue { + public: + static bool Exists() { return true; } + static T* Get() { return nullptr; } +}; + +// The following specializations define the default values for +// specific types we care about. +#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \ + template <> \ + class BuiltInDefaultValue { \ + public: \ + static bool Exists() { return true; } \ + static type Get() { return value; } \ + } + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, ""); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0'); + +// There's no need for a default action for signed wchar_t, as that +// type is the same as wchar_t for gcc, and invalid for MSVC. +// +// There's also no need for a default action for unsigned wchar_t, as +// that type is the same as unsigned int for gcc, and invalid for +// MSVC. +#if GMOCK_WCHAR_T_IS_NATIVE_ +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT +#endif + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); + +#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ + +} // namespace internal + +// When an unexpected function call is encountered, Google Mock will +// let it return a default value if the user has specified one for its +// return type, or if the return type has a built-in default value; +// otherwise Google Mock won't know what value to return and will have +// to abort the process. +// +// The DefaultValue class allows a user to specify the +// default value for a type T that is both copyable and publicly +// destructible (i.e. anything that can be used as a function return +// type). The usage is: +// +// // Sets the default value for type T to be foo. +// DefaultValue::Set(foo); +template +class DefaultValue { + public: + // Sets the default value for type T; requires T to be + // copy-constructable and have a public destructor. + static void Set(T x) { + delete producer_; + producer_ = new FixedValueProducer(x); + } + + // Provides a factory function to be called to generate the default value. + // This method can be used even if T is only move-constructible, but it is not + // limited to that case. + typedef T (*FactoryFunction)(); + static void SetFactory(FactoryFunction factory) { + delete producer_; + producer_ = new FactoryValueProducer(factory); + } + + // Unsets the default value for type T. + static void Clear() { + delete producer_; + producer_ = nullptr; + } + + // Returns true if and only if the user has set the default value for type T. + static bool IsSet() { return producer_ != nullptr; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue::Exists(); + } + + // Returns the default value for type T if the user has set one; + // otherwise returns the built-in default value. Requires that Exists() + // is true, which ensures that the return value is well-defined. + static T Get() { + return producer_ == nullptr ? internal::BuiltInDefaultValue::Get() + : producer_->Produce(); + } + + private: + class ValueProducer { + public: + virtual ~ValueProducer() {} + virtual T Produce() = 0; + }; + + class FixedValueProducer : public ValueProducer { + public: + explicit FixedValueProducer(T value) : value_(value) {} + T Produce() override { return value_; } + + private: + const T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); + }; + + class FactoryValueProducer : public ValueProducer { + public: + explicit FactoryValueProducer(FactoryFunction factory) + : factory_(factory) {} + T Produce() override { return factory_(); } + + private: + const FactoryFunction factory_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); + }; + + static ValueProducer* producer_; +}; + +// This partial specialization allows a user to set default values for +// reference types. +template +class DefaultValue { + public: + // Sets the default value for type T&. + static void Set(T& x) { // NOLINT + address_ = &x; + } + + // Unsets the default value for type T&. + static void Clear() { address_ = nullptr; } + + // Returns true if and only if the user has set the default value for type T&. + static bool IsSet() { return address_ != nullptr; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue::Exists(); + } + + // Returns the default value for type T& if the user has set one; + // otherwise returns the built-in default value if there is one; + // otherwise aborts the process. + static T& Get() { + return address_ == nullptr ? internal::BuiltInDefaultValue::Get() + : *address_; + } + + private: + static T* address_; +}; + +// This specialization allows DefaultValue::Get() to +// compile. +template <> +class DefaultValue { + public: + static bool Exists() { return true; } + static void Get() {} +}; + +// Points to the user-set default value for type T. +template +typename DefaultValue::ValueProducer* DefaultValue::producer_ = nullptr; + +// Points to the user-set default value for type T&. +template +T* DefaultValue::address_ = nullptr; + +// Implement this interface to define an action for function type F. +template +class ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + ActionInterface() {} + virtual ~ActionInterface() {} + + // Performs the action. This method is not const, as in general an + // action can have side effects and be stateful. For example, a + // get-the-next-element-from-the-collection action will need to + // remember the current element. + virtual Result Perform(const ArgumentTuple& args) = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); +}; + +// An Action is a copyable and IMMUTABLE (except by assignment) +// object that represents an action to be taken when a mock function +// of type F is called. The implementation of Action is just a +// std::shared_ptr to const ActionInterface. Don't inherit from Action! +// You can view an object implementing ActionInterface as a +// concrete action (including its current state), and an Action +// object as a handle to it. +template +class Action { + // Adapter class to allow constructing Action from a legacy ActionInterface. + // New code should create Actions from functors instead. + struct ActionAdapter { + // Adapter must be copyable to satisfy std::function requirements. + ::std::shared_ptr> impl_; + + template + typename internal::Function::Result operator()(Args&&... args) { + return impl_->Perform( + ::std::forward_as_tuple(::std::forward(args)...)); + } + }; + + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + // Constructs a null Action. Needed for storing Action objects in + // STL containers. + Action() {} + + // Construct an Action from a specified callable. + // This cannot take std::function directly, because then Action would not be + // directly constructible from lambda (it would require two conversions). + template , G>::value>::type> + Action(G&& fun) : fun_(::std::forward(fun)) {} // NOLINT + + // Constructs an Action from its implementation. + explicit Action(ActionInterface* impl) + : fun_(ActionAdapter{::std::shared_ptr>(impl)}) {} + + // This constructor allows us to turn an Action object into an + // Action, as long as F's arguments can be implicitly converted + // to Func's and Func's return type can be implicitly converted to F's. + template + explicit Action(const Action& action) : fun_(action.fun_) {} + + // Returns true if and only if this is the DoDefault() action. + bool IsDoDefault() const { return fun_ == nullptr; } + + // Performs the action. Note that this method is const even though + // the corresponding method in ActionInterface is not. The reason + // is that a const Action means that it cannot be re-bound to + // another concrete action, not that the concrete action it binds to + // cannot change state. (Think of the difference between a const + // pointer and a pointer to const.) + Result Perform(ArgumentTuple args) const { + if (IsDoDefault()) { + internal::IllegalDoDefault(__FILE__, __LINE__); + } + return internal::Apply(fun_, ::std::move(args)); + } + + private: + template + friend class Action; + + // fun_ is an empty function if and only if this is the DoDefault() action. + ::std::function fun_; +}; + +// The PolymorphicAction class template makes it easy to implement a +// polymorphic action (i.e. an action that can be used in mock +// functions of than one type, e.g. Return()). +// +// To define a polymorphic action, a user first provides a COPYABLE +// implementation class that has a Perform() method template: +// +// class FooAction { +// public: +// template +// Result Perform(const ArgumentTuple& args) const { +// // Processes the arguments and returns a result, using +// // std::get(args) to get the N-th (0-based) argument in the tuple. +// } +// ... +// }; +// +// Then the user creates the polymorphic action using +// MakePolymorphicAction(object) where object has type FooAction. See +// the definition of Return(void) and SetArgumentPointee(value) for +// complete examples. +template +class PolymorphicAction { + public: + explicit PolymorphicAction(const Impl& impl) : impl_(impl) {} + + template + operator Action() const { + return Action(new MonomorphicImpl(impl_)); + } + + private: + template + class MonomorphicImpl : public ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} + + Result Perform(const ArgumentTuple& args) override { + return impl_.template Perform(args); + } + + private: + Impl impl_; + + GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); + }; + + Impl impl_; + + GTEST_DISALLOW_ASSIGN_(PolymorphicAction); +}; + +// Creates an Action from its implementation and returns it. The +// created Action object owns the implementation. +template +Action MakeAction(ActionInterface* impl) { + return Action(impl); +} + +// Creates a polymorphic action from its implementation. This is +// easier to use than the PolymorphicAction constructor as it +// doesn't require you to explicitly write the template argument, e.g. +// +// MakePolymorphicAction(foo); +// vs +// PolymorphicAction(foo); +template +inline PolymorphicAction MakePolymorphicAction(const Impl& impl) { + return PolymorphicAction(impl); +} + +namespace internal { + +// Helper struct to specialize ReturnAction to execute a move instead of a copy +// on return. Useful for move-only types, but could be used on any type. +template +struct ByMoveWrapper { + explicit ByMoveWrapper(T value) : payload(std::move(value)) {} + T payload; +}; + +// Implements the polymorphic Return(x) action, which can be used in +// any function that returns the type of x, regardless of the argument +// types. +// +// Note: The value passed into Return must be converted into +// Function::Result when this action is cast to Action rather than +// when that action is performed. This is important in scenarios like +// +// MOCK_METHOD1(Method, T(U)); +// ... +// { +// Foo foo; +// X x(&foo); +// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x)); +// } +// +// In the example above the variable x holds reference to foo which leaves +// scope and gets destroyed. If copying X just copies a reference to foo, +// that copy will be left with a hanging reference. If conversion to T +// makes a copy of foo, the above code is safe. To support that scenario, we +// need to make sure that the type conversion happens inside the EXPECT_CALL +// statement, and conversion of the result of Return to Action is a +// good place for that. +// +// The real life example of the above scenario happens when an invocation +// of gtl::Container() is passed into Return. +// +template +class ReturnAction { + public: + // Constructs a ReturnAction object from the value to be returned. + // 'value' is passed by value instead of by const reference in order + // to allow Return("string literal") to compile. + explicit ReturnAction(R value) : value_(new R(std::move(value))) {} + + // This template type conversion operator allows Return(x) to be + // used in ANY function that returns x's type. + template + operator Action() const { // NOLINT + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename Function::Result Result; + GTEST_COMPILE_ASSERT_( + !std::is_reference::value, + use_ReturnRef_instead_of_Return_to_return_a_reference); + static_assert(!std::is_void::value, + "Can't use Return() on an action expected to return `void`."); + return Action(new Impl(value_)); + } + + private: + // Implements the Return(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + // The implicit cast is necessary when Result has more than one + // single-argument constructor (e.g. Result is std::vector) and R + // has a type conversion operator template. In that case, value_(value) + // won't compile as the compiler doesn't known which constructor of + // Result to call. ImplicitCast_ forces the compiler to convert R to + // Result without considering explicit constructors, thus resolving the + // ambiguity. value_ is then initialized using its copy constructor. + explicit Impl(const std::shared_ptr& value) + : value_before_cast_(*value), + value_(ImplicitCast_(value_before_cast_)) {} + + Result Perform(const ArgumentTuple&) override { return value_; } + + private: + GTEST_COMPILE_ASSERT_(!std::is_reference::value, + Result_cannot_be_a_reference_type); + // We save the value before casting just in case it is being cast to a + // wrapper type. + R value_before_cast_; + Result value_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + }; + + // Partially specialize for ByMoveWrapper. This version of ReturnAction will + // move its contents instead. + template + class Impl, F> : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const std::shared_ptr& wrapper) + : performed_(false), wrapper_(wrapper) {} + + Result Perform(const ArgumentTuple&) override { + GTEST_CHECK_(!performed_) + << "A ByMove() action should only be performed once."; + performed_ = true; + return std::move(wrapper_->payload); + } + + private: + bool performed_; + const std::shared_ptr wrapper_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const std::shared_ptr value_; + + GTEST_DISALLOW_ASSIGN_(ReturnAction); +}; + +// Implements the ReturnNull() action. +class ReturnNullAction { + public: + // Allows ReturnNull() to be used in any pointer-returning function. In C++11 + // this is enforced by returning nullptr, and in non-C++11 by asserting a + // pointer type on compile time. + template + static Result Perform(const ArgumentTuple&) { + return nullptr; + } +}; + +// Implements the Return() action. +class ReturnVoidAction { + public: + // Allows Return() to be used in any void-returning function. + template + static void Perform(const ArgumentTuple&) { + static_assert(std::is_void::value, "Result should be void."); + } +}; + +// Implements the polymorphic ReturnRef(x) action, which can be used +// in any function that returns a reference to the type of x, +// regardless of the argument types. +template +class ReturnRefAction { + public: + // Constructs a ReturnRefAction object from the reference to be returned. + explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT + + // This template type conversion operator allows ReturnRef(x) to be + // used in ANY function that returns a reference to x's type. + template + operator Action() const { + typedef typename Function::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRef(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_(std::is_reference::value, + use_Return_instead_of_ReturnRef_to_return_a_value); + return Action(new Impl(ref_)); + } + + private: + // Implements the ReturnRef(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(T& ref) : ref_(ref) {} // NOLINT + + Result Perform(const ArgumentTuple&) override { return ref_; } + + private: + T& ref_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + T& ref_; + + GTEST_DISALLOW_ASSIGN_(ReturnRefAction); +}; + +// Implements the polymorphic ReturnRefOfCopy(x) action, which can be +// used in any function that returns a reference to the type of x, +// regardless of the argument types. +template +class ReturnRefOfCopyAction { + public: + // Constructs a ReturnRefOfCopyAction object from the reference to + // be returned. + explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT + + // This template type conversion operator allows ReturnRefOfCopy(x) to be + // used in ANY function that returns a reference to x's type. + template + operator Action() const { + typedef typename Function::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRefOfCopy(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_( + std::is_reference::value, + use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); + return Action(new Impl(value_)); + } + + private: + // Implements the ReturnRefOfCopy(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const T& value) : value_(value) {} // NOLINT + + Result Perform(const ArgumentTuple&) override { return value_; } + + private: + T value_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const T value_; + + GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction); +}; + +// Implements the polymorphic ReturnRoundRobin(v) action, which can be +// used in any function that returns the element_type of v. +template +class ReturnRoundRobinAction { + public: + explicit ReturnRoundRobinAction(std::vector values) { + GTEST_CHECK_(!values.empty()) + << "ReturnRoundRobin requires at least one element."; + state_->values = std::move(values); + } + + template + T operator()(Args&&...) const { + return state_->Next(); + } + + private: + struct State { + T Next() { + T ret_val = values[i++]; + if (i == values.size()) i = 0; + return ret_val; + } + + std::vector values; + size_t i = 0; + }; + std::shared_ptr state_ = std::make_shared(); +}; + +// Implements the polymorphic DoDefault() action. +class DoDefaultAction { + public: + // This template type conversion operator allows DoDefault() to be + // used in any function. + template + operator Action() const { return Action(); } // NOLINT +}; + +// Implements the Assign action to set a given pointer referent to a +// particular value. +template +class AssignAction { + public: + AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} + + template + void Perform(const ArgumentTuple& /* args */) const { + *ptr_ = value_; + } + + private: + T1* const ptr_; + const T2 value_; + + GTEST_DISALLOW_ASSIGN_(AssignAction); +}; + +#if !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetErrnoAndReturn action to simulate return from +// various system calls and libc functions. +template +class SetErrnoAndReturnAction { + public: + SetErrnoAndReturnAction(int errno_value, T result) + : errno_(errno_value), + result_(result) {} + template + Result Perform(const ArgumentTuple& /* args */) const { + errno = errno_; + return result_; + } + + private: + const int errno_; + const T result_; + + GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction); +}; + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetArgumentPointee(x) action for any function +// whose N-th argument (0-based) is a pointer to x's type. +template +struct SetArgumentPointeeAction { + A value; + + template + void operator()(const Args&... args) const { + *::std::get(std::tie(args...)) = value; + } +}; + +// Implements the Invoke(object_ptr, &Class::Method) action. +template +struct InvokeMethodAction { + Class* const obj_ptr; + const MethodPtr method_ptr; + + template + auto operator()(Args&&... args) const + -> decltype((obj_ptr->*method_ptr)(std::forward(args)...)) { + return (obj_ptr->*method_ptr)(std::forward(args)...); + } +}; + +// Implements the InvokeWithoutArgs(f) action. The template argument +// FunctionImpl is the implementation type of f, which can be either a +// function pointer or a functor. InvokeWithoutArgs(f) can be used as an +// Action as long as f's type is compatible with F. +template +struct InvokeWithoutArgsAction { + FunctionImpl function_impl; + + // Allows InvokeWithoutArgs(f) to be used as any action whose type is + // compatible with f. + template + auto operator()(const Args&...) -> decltype(function_impl()) { + return function_impl(); + } +}; + +// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action. +template +struct InvokeMethodWithoutArgsAction { + Class* const obj_ptr; + const MethodPtr method_ptr; + + using ReturnType = typename std::result_of::type; + + template + ReturnType operator()(const Args&...) const { + return (obj_ptr->*method_ptr)(); + } +}; + +// Implements the IgnoreResult(action) action. +template +class IgnoreResultAction { + public: + explicit IgnoreResultAction(const A& action) : action_(action) {} + + template + operator Action() const { + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename internal::Function::Result Result; + + // Asserts at compile time that F returns void. + static_assert(std::is_void::value, "Result type should be void."); + + return Action(new Impl(action_)); + } + + private: + template + class Impl : public ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const A& action) : action_(action) {} + + void Perform(const ArgumentTuple& args) override { + // Performs the action and ignores its result. + action_.Perform(args); + } + + private: + // Type OriginalFunction is the same as F except that its return + // type is IgnoredValue. + typedef typename internal::Function::MakeResultIgnoredValue + OriginalFunction; + + const Action action_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const A action_; + + GTEST_DISALLOW_ASSIGN_(IgnoreResultAction); +}; + +template +struct WithArgsAction { + InnerAction action; + + // The inner action could be anything convertible to Action. + // We use the conversion operator to detect the signature of the inner Action. + template + operator Action() const { // NOLINT + using TupleType = std::tuple; + Action::type...)> + converted(action); + + return [converted](Args... args) -> R { + return converted.Perform(std::forward_as_tuple( + std::get(std::forward_as_tuple(std::forward(args)...))...)); + }; + } +}; + +template +struct DoAllAction { + private: + template + std::vector> Convert(IndexSequence) const { + return {std::get(actions)...}; + } + + public: + std::tuple actions; + + template + operator Action() const { // NOLINT + struct Op { + std::vector> converted; + Action last; + R operator()(Args... args) const { + auto tuple_args = std::forward_as_tuple(std::forward(args)...); + for (auto& a : converted) { + a.Perform(tuple_args); + } + return last.Perform(tuple_args); + } + }; + return Op{Convert(MakeIndexSequence()), + std::get(actions)}; + } +}; + +} // namespace internal + +// An Unused object can be implicitly constructed from ANY value. +// This is handy when defining actions that ignore some or all of the +// mock function arguments. For example, given +// +// MOCK_METHOD3(Foo, double(const string& label, double x, double y)); +// MOCK_METHOD3(Bar, double(int index, double x, double y)); +// +// instead of +// +// double DistanceToOriginWithLabel(const string& label, double x, double y) { +// return sqrt(x*x + y*y); +// } +// double DistanceToOriginWithIndex(int index, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXPECT_CALL(mock, Foo("abc", _, _)) +// .WillOnce(Invoke(DistanceToOriginWithLabel)); +// EXPECT_CALL(mock, Bar(5, _, _)) +// .WillOnce(Invoke(DistanceToOriginWithIndex)); +// +// you could write +// +// // We can declare any uninteresting argument as Unused. +// double DistanceToOrigin(Unused, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); +// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); +typedef internal::IgnoredValue Unused; + +// Creates an action that does actions a1, a2, ..., sequentially in +// each invocation. +template +internal::DoAllAction::type...> DoAll( + Action&&... action) { + return {std::forward_as_tuple(std::forward(action)...)}; +} + +// WithArg(an_action) creates an action that passes the k-th +// (0-based) argument of the mock function to an_action and performs +// it. It adapts an action accepting one argument to one that accepts +// multiple arguments. For convenience, we also provide +// WithArgs(an_action) (defined below) as a synonym. +template +internal::WithArgsAction::type, k> +WithArg(InnerAction&& action) { + return {std::forward(action)}; +} + +// WithArgs(an_action) creates an action that passes +// the selected arguments of the mock function to an_action and +// performs it. It serves as an adaptor between actions with +// different argument lists. +template +internal::WithArgsAction::type, k, ks...> +WithArgs(InnerAction&& action) { + return {std::forward(action)}; +} + +// WithoutArgs(inner_action) can be used in a mock function with a +// non-empty argument list to perform inner_action, which takes no +// argument. In other words, it adapts an action accepting no +// argument to one that accepts (and ignores) arguments. +template +internal::WithArgsAction::type> +WithoutArgs(InnerAction&& action) { + return {std::forward(action)}; +} + +// Creates an action that returns 'value'. 'value' is passed by value +// instead of const reference - otherwise Return("string literal") +// will trigger a compiler error about using array as initializer. +template +internal::ReturnAction Return(R value) { + return internal::ReturnAction(std::move(value)); +} + +// Creates an action that returns NULL. +inline PolymorphicAction ReturnNull() { + return MakePolymorphicAction(internal::ReturnNullAction()); +} + +// Creates an action that returns from a void function. +inline PolymorphicAction Return() { + return MakePolymorphicAction(internal::ReturnVoidAction()); +} + +// Creates an action that returns the reference to a variable. +template +inline internal::ReturnRefAction ReturnRef(R& x) { // NOLINT + return internal::ReturnRefAction(x); +} + +// Prevent using ReturnRef on reference to temporary. +template +internal::ReturnRefAction ReturnRef(R&&) = delete; + +// Creates an action that returns the reference to a copy of the +// argument. The copy is created when the action is constructed and +// lives as long as the action. +template +inline internal::ReturnRefOfCopyAction ReturnRefOfCopy(const R& x) { + return internal::ReturnRefOfCopyAction(x); +} + +// Modifies the parent action (a Return() action) to perform a move of the +// argument instead of a copy. +// Return(ByMove()) actions can only be executed once and will assert this +// invariant. +template +internal::ByMoveWrapper ByMove(R x) { + return internal::ByMoveWrapper(std::move(x)); +} + +// Creates an action that returns an element of `vals`. Calling this action will +// repeatedly return the next value from `vals` until it reaches the end and +// will restart from the beginning. +template +internal::ReturnRoundRobinAction ReturnRoundRobin(std::vector vals) { + return internal::ReturnRoundRobinAction(std::move(vals)); +} + +// Creates an action that returns an element of `vals`. Calling this action will +// repeatedly return the next value from `vals` until it reaches the end and +// will restart from the beginning. +template +internal::ReturnRoundRobinAction ReturnRoundRobin( + std::initializer_list vals) { + return internal::ReturnRoundRobinAction(std::vector(vals)); +} + +// Creates an action that does the default action for the give mock function. +inline internal::DoDefaultAction DoDefault() { + return internal::DoDefaultAction(); +} + +// Creates an action that sets the variable pointed by the N-th +// (0-based) function argument to 'value'. +template +internal::SetArgumentPointeeAction SetArgPointee(T value) { + return {std::move(value)}; +} + +// The following version is DEPRECATED. +template +internal::SetArgumentPointeeAction SetArgumentPointee(T value) { + return {std::move(value)}; +} + +// Creates an action that sets a pointer referent to a given value. +template +PolymorphicAction > Assign(T1* ptr, T2 val) { + return MakePolymorphicAction(internal::AssignAction(ptr, val)); +} + +#if !GTEST_OS_WINDOWS_MOBILE + +// Creates an action that sets errno and returns the appropriate error. +template +PolymorphicAction > +SetErrnoAndReturn(int errval, T result) { + return MakePolymorphicAction( + internal::SetErrnoAndReturnAction(errval, result)); +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Various overloads for Invoke(). + +// Legacy function. +// Actions can now be implicitly constructed from callables. No need to create +// wrapper objects. +// This function exists for backwards compatibility. +template +typename std::decay::type Invoke(FunctionImpl&& function_impl) { + return std::forward(function_impl); +} + +// Creates an action that invokes the given method on the given object +// with the mock function's arguments. +template +internal::InvokeMethodAction Invoke(Class* obj_ptr, + MethodPtr method_ptr) { + return {obj_ptr, method_ptr}; +} + +// Creates an action that invokes 'function_impl' with no argument. +template +internal::InvokeWithoutArgsAction::type> +InvokeWithoutArgs(FunctionImpl function_impl) { + return {std::move(function_impl)}; +} + +// Creates an action that invokes the given method on the given object +// with no argument. +template +internal::InvokeMethodWithoutArgsAction InvokeWithoutArgs( + Class* obj_ptr, MethodPtr method_ptr) { + return {obj_ptr, method_ptr}; +} + +// Creates an action that performs an_action and throws away its +// result. In other words, it changes the return type of an_action to +// void. an_action MUST NOT return void, or the code won't compile. +template +inline internal::IgnoreResultAction IgnoreResult(const A& an_action) { + return internal::IgnoreResultAction(an_action); +} + +// Creates a reference wrapper for the given L-value. If necessary, +// you can explicitly specify the type of the reference. For example, +// suppose 'derived' is an object of type Derived, ByRef(derived) +// would wrap a Derived&. If you want to wrap a const Base& instead, +// where Base is a base class of Derived, just write: +// +// ByRef(derived) +// +// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper. +// However, it may still be used for consistency with ByMove(). +template +inline ::std::reference_wrapper ByRef(T& l_value) { // NOLINT + return ::std::reference_wrapper(l_value); +} + +namespace internal { + +// A macro from the ACTION* family (defined later in gmock-generated-actions.h) +// defines an action that can be used in a mock function. Typically, +// these actions only care about a subset of the arguments of the mock +// function. For example, if such an action only uses the second +// argument, it can be used in any mock function that takes >= 2 +// arguments where the type of the second argument is compatible. +// +// Therefore, the action implementation must be prepared to take more +// arguments than it needs. The ExcessiveArg type is used to +// represent those excessive arguments. In order to keep the compiler +// error messages tractable, we define it in the testing namespace +// instead of testing::internal. However, this is an INTERNAL TYPE +// and subject to change without notice, so a user MUST NOT USE THIS +// TYPE DIRECTLY. +struct ExcessiveArg {}; + +// A helper class needed for implementing the ACTION* macros. +template +class ActionHelper { + public: + template + static Result Perform(Impl* impl, const std::tuple& args) { + return Apply(impl, args, MakeIndexSequence{}, + MakeIndexSequence<10 - sizeof...(Ts)>{}); + } + + private: + template + static Result Apply(Impl* impl, const std::tuple& args, + IndexSequence, IndexSequence) { + return impl->template gmock_PerformImpl( + args, std::get(args)..., + ((void)rest_ids, ExcessiveArg())...); + } +}; + +} // namespace internal + +} // namespace testing + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-cardinalities.h b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-cardinalities.h new file mode 100644 index 000000000..46e01e102 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-cardinalities.h @@ -0,0 +1,157 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used cardinalities. More +// cardinalities can be defined by the user implementing the +// CardinalityInterface interface if necessary. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ + +#include +#include +#include // NOLINT +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// To implement a cardinality Foo, define: +// 1. a class FooCardinality that implements the +// CardinalityInterface interface, and +// 2. a factory function that creates a Cardinality object from a +// const FooCardinality*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Cardinality objects can now be copied like plain values. + +// The implementation of a cardinality. +class CardinalityInterface { + public: + virtual ~CardinalityInterface() {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + virtual int ConservativeLowerBound() const { return 0; } + virtual int ConservativeUpperBound() const { return INT_MAX; } + + // Returns true if and only if call_count calls will satisfy this + // cardinality. + virtual bool IsSatisfiedByCallCount(int call_count) const = 0; + + // Returns true if and only if call_count calls will saturate this + // cardinality. + virtual bool IsSaturatedByCallCount(int call_count) const = 0; + + // Describes self to an ostream. + virtual void DescribeTo(::std::ostream* os) const = 0; +}; + +// A Cardinality is a copyable and IMMUTABLE (except by assignment) +// object that specifies how many times a mock function is expected to +// be called. The implementation of Cardinality is just a std::shared_ptr +// to const CardinalityInterface. Don't inherit from Cardinality! +class GTEST_API_ Cardinality { + public: + // Constructs a null cardinality. Needed for storing Cardinality + // objects in STL containers. + Cardinality() {} + + // Constructs a Cardinality from its implementation. + explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } + int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } + + // Returns true if and only if call_count calls will satisfy this + // cardinality. + bool IsSatisfiedByCallCount(int call_count) const { + return impl_->IsSatisfiedByCallCount(call_count); + } + + // Returns true if and only if call_count calls will saturate this + // cardinality. + bool IsSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count); + } + + // Returns true if and only if call_count calls will over-saturate this + // cardinality, i.e. exceed the maximum number of allowed calls. + bool IsOverSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count) && + !impl_->IsSatisfiedByCallCount(call_count); + } + + // Describes self to an ostream + void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } + + // Describes the given actual call count to an ostream. + static void DescribeActualCallCountTo(int actual_call_count, + ::std::ostream* os); + + private: + std::shared_ptr impl_; +}; + +// Creates a cardinality that allows at least n calls. +GTEST_API_ Cardinality AtLeast(int n); + +// Creates a cardinality that allows at most n calls. +GTEST_API_ Cardinality AtMost(int n); + +// Creates a cardinality that allows any number of calls. +GTEST_API_ Cardinality AnyNumber(); + +// Creates a cardinality that allows between min and max calls. +GTEST_API_ Cardinality Between(int min, int max); + +// Creates a cardinality that allows exactly n calls. +GTEST_API_ Cardinality Exactly(int n); + +// Creates a cardinality from its implementation. +inline Cardinality MakeCardinality(const CardinalityInterface* c) { + return Cardinality(c); +} + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-function-mocker.h b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-function-mocker.h new file mode 100644 index 000000000..c5291412b --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-function-mocker.h @@ -0,0 +1,276 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements MOCK_METHOD. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT +#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT + +#include "gmock/gmock-generated-function-mockers.h" // NOLINT +#include "gmock/internal/gmock-pp.h" + +namespace testing { +namespace internal { +template +using identity_t = T; +} // namespace internal +} // namespace testing + +#define MOCK_METHOD(...) \ + GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \ + GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ()) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \ + GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ + GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \ + GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ + GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ + GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ + GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ + GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \ + GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \ + (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args))) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_WRONG_ARITY(...) \ + static_assert( \ + false, \ + "MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \ + "_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \ + "enclosed in parentheses. If _Ret is a type with unprotected commas, " \ + "it must also be enclosed in parentheses.") + +#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \ + static_assert( \ + GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \ + GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.") + +#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \ + static_assert( \ + std::is_function<__VA_ARGS__>::value, \ + "Signature must be a function type, maybe return type contains " \ + "unprotected comma."); \ + static_assert( \ + ::testing::tuple_size::ArgumentTuple>::value == _N, \ + "This method does not take " GMOCK_PP_STRINGIZE( \ + _N) " arguments. Parenthesize all types with unproctected commas.") + +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec) + +#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \ + _Override, _Final, _NoexceptSpec, \ + _CallType, _Signature) \ + typename ::testing::internal::Function::Result \ + GMOCK_INTERNAL_EXPAND(_CallType) \ + _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \ + GMOCK_PP_IF(_Constness, const, ) _NoexceptSpec \ + GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \ + GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .SetOwnerAndName(this, #_MethodName); \ + return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \ + } \ + ::testing::MockSpec gmock_##_MethodName( \ + GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \ + GMOCK_PP_IF(_Constness, const, ) { \ + GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \ + return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \ + } \ + ::testing::MockSpec gmock_##_MethodName( \ + const ::testing::internal::WithoutMatchers&, \ + GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \ + GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _NoexceptSpec { \ + return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \ + GMOCK_PP_IF(_Constness, const, ))(this) \ + ->gmock_##_MethodName(GMOCK_PP_REPEAT( \ + GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \ + } \ + mutable ::testing::FunctionMocker \ + GMOCK_MOCKER_(_N, _Constness, _MethodName) + +#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__ + +// Five Valid modifiers. +#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple)) + +#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \ + GMOCK_PP_HAS_COMMA( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple)) + +#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple)) + +#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple) + +#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem) \ + GMOCK_PP_IF( \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \ + _elem, ) + +#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple) + +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ + static_assert( \ + (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ + GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \ + GMOCK_PP_STRINGIZE( \ + _elem) " cannot be recognized as a valid specification modifier."); + +// Modifiers implementation. +#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_CONST_I_const , + +#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override , + +#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_FINAL_I_final , + +#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept , + +#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \ + GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \ + GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \ + (_elem) + +// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and +// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows +// maybe they can be simplified somehow. +#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \ + GMOCK_INTERNAL_IS_CALLTYPE_I( \ + GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) +#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg) + +#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \ + GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \ + GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) +#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \ + GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg) + +#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype + +// Note: The use of `identity_t` here allows _Ret to represent return types that +// would normally need to be specified in a different way. For example, a method +// returning a function pointer must be written as +// +// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...) +// +// But we only support placing the return type at the beginning. To handle this, +// we wrap all calls in identity_t, so that a declaration will be expanded to +// +// identity_t method(method_args_t...) +// +// This allows us to work around the syntactic oddities of function/method +// types. +#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \ + ::testing::internal::identity_t( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args)) + +#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \ + GMOCK_PP_IDENTITY) \ + (_elem) + +#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ + GMOCK_PP_REMOVE_PARENS(_Signature)) \ + gmock_a##_i + +#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::std::forward( \ + gmock_a##_i) + +#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \ + GMOCK_PP_REMOVE_PARENS(_Signature)) \ + gmock_a##_i + +#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \ + GMOCK_PP_COMMA_IF(_i) \ + gmock_a##_i + +#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::testing::A() + +#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__) + +#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \ + GMOCK_MATCHER_(_tn, _i, __VA_ARGS__) + +#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h new file mode 100644 index 000000000..20b78cd43 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h @@ -0,0 +1,1757 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-actions.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include +#include + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template +// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// Users can, however, define any local functors (e.g. a lambda) that +// can be used as actions. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +// An internal macro needed for implementing ACTION*(). +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ + const args_type& args GTEST_ATTRIBUTE_UNUSED_, \ + const arg0_type& arg0 GTEST_ATTRIBUTE_UNUSED_, \ + const arg1_type& arg1 GTEST_ATTRIBUTE_UNUSED_, \ + const arg2_type& arg2 GTEST_ATTRIBUTE_UNUSED_, \ + const arg3_type& arg3 GTEST_ATTRIBUTE_UNUSED_, \ + const arg4_type& arg4 GTEST_ATTRIBUTE_UNUSED_, \ + const arg5_type& arg5 GTEST_ATTRIBUTE_UNUSED_, \ + const arg6_type& arg6 GTEST_ATTRIBUTE_UNUSED_, \ + const arg7_type& arg7 GTEST_ATTRIBUTE_UNUSED_, \ + const arg8_type& arg8 GTEST_ATTRIBUTE_UNUSED_, \ + const arg9_type& arg9 GTEST_ATTRIBUTE_UNUSED_ + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::std::get(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. +#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0 +#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) kind0 name0, kind1 name1 +#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) kind0 name0, kind1 name1, kind2 name2 +#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3 +#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \ + kind2 name2, kind3 name3, kind4 name4 +#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5 +#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \ + kind5 name5, kind6 name6 +#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \ + kind4 name4, kind5 name5, kind6 name6, kind7 name7 +#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \ + kind8 name8 +#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \ + kind6 name6, kind7 name7, kind8 name8, kind9 name9 + +// Lists the template parameters. +#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0 +#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) name0, name1 +#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) name0, name1, name2 +#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) name0, name1, name2, name3 +#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \ + name4 +#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \ + name2, name3, name4, name5 +#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) name0, name1, name2, name3, name4, name5, name6 +#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7 +#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \ + name6, name7, name8 +#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \ + name3, name4, name5, name6, name7, name8, name9 + +// Declares the types of value parameters. +#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \ + typename p0##_type, typename p1##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \ + typename p0##_type, typename p1##_type, typename p2##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type, typename p8##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \ + typename p2##_type, typename p3##_type, typename p4##_type, \ + typename p5##_type, typename p6##_type, typename p7##_type, \ + typename p8##_type, typename p9##_type + +// Initializes the value parameters. +#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\ + () +#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\ + (p0##_type gmock_p0) : p0(::std::move(gmock_p0)) +#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ + (p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)) +#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\ + (p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) +#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)) +#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) +#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)) +#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) +#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)) +#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) +#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \ + p9(::std::move(gmock_p9)) + +// Declares the fields for storing the value parameters. +#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0; +#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \ + p1##_type p1; +#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \ + p1##_type p1; p2##_type p2; +#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \ + p1##_type p1; p2##_type p2; p3##_type p3; +#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; +#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; +#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; +#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; p7##_type p7; +#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; +#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \ + p9##_type p9; + +// Lists the value parameters. +#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0 +#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1 +#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2 +#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3 +#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \ + p2, p3, p4 +#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \ + p1, p2, p3, p4, p5 +#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0, p1, p2, p3, p4, p5, p6 +#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0, p1, p2, p3, p4, p5, p6, p7 +#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8 +#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 + +// Lists the value parameter types. +#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \ + p1##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \ + p1##_type, p2##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + p0##_type, p1##_type, p2##_type, p3##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \ + p6##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type, p9##_type + +// Declares the value parameters. +#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0 +#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \ + p1##_type p1 +#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \ + p1##_type p1, p2##_type p2 +#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3 +#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4 +#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5 +#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6 +#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6, p7##_type p7 +#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8 +#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9 + +// The suffix of the class template implementing the action template. +#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P +#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2 +#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3 +#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4 +#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5 +#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6 +#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7 +#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) P8 +#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) P9 +#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) P10 + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +#define ACTION_TEMPLATE(name, template_params, value_params)\ + template \ + class GMOCK_ACTION_CLASS_(name, value_params) {\ + public:\ + explicit GMOCK_ACTION_CLASS_(name, value_params)\ + GMOCK_INTERNAL_INIT_##value_params {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(\ + new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ + }\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ + };\ + template \ + inline GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ + GMOCK_INTERNAL_DECL_##value_params) {\ + return GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ + GMOCK_INTERNAL_LIST_##value_params);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ + gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION(name)\ + class name##Action {\ + public:\ + name##Action() {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl() {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl());\ + }\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##Action);\ + };\ + inline name##Action name() {\ + return name##Action();\ + }\ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##Action::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P(name, p0)\ + template \ + class name##ActionP {\ + public:\ + explicit name##ActionP(p0##_type gmock_p0) : \ + p0(::std::forward(gmock_p0)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl(p0##_type gmock_p0) : \ + p0(::std::forward(gmock_p0)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0));\ + }\ + p0##_type p0;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP);\ + };\ + template \ + inline name##ActionP name(p0##_type p0) {\ + return name##ActionP(p0);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P2(name, p0, p1)\ + template \ + class name##ActionP2 {\ + public:\ + name##ActionP2(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP2);\ + };\ + template \ + inline name##ActionP2 name(p0##_type p0, \ + p1##_type p1) {\ + return name##ActionP2(p0, p1);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP2::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P3(name, p0, p1, p2)\ + template \ + class name##ActionP3 {\ + public:\ + name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP3);\ + };\ + template \ + inline name##ActionP3 name(p0##_type p0, \ + p1##_type p1, p2##_type p2) {\ + return name##ActionP3(p0, p1, p2);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP3::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P4(name, p0, p1, p2, p3)\ + template \ + class name##ActionP4 {\ + public:\ + name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP4);\ + };\ + template \ + inline name##ActionP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3) {\ + return name##ActionP4(p0, p1, \ + p2, p3);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP4::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P5(name, p0, p1, p2, p3, p4)\ + template \ + class name##ActionP5 {\ + public:\ + name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP5);\ + };\ + template \ + inline name##ActionP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4) {\ + return name##ActionP5(p0, p1, p2, p3, p4);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP5::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\ + template \ + class name##ActionP6 {\ + public:\ + name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP6);\ + };\ + template \ + inline name##ActionP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3, p4##_type p4, p5##_type p5) {\ + return name##ActionP6(p0, p1, p2, p3, p4, p5);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP6::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\ + template \ + class name##ActionP7 {\ + public:\ + name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP7);\ + };\ + template \ + inline name##ActionP7 name(p0##_type p0, p1##_type p1, \ + p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6) {\ + return name##ActionP7(p0, p1, p2, p3, p4, p5, p6);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP7::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\ + template \ + class name##ActionP8 {\ + public:\ + name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP8);\ + };\ + template \ + inline name##ActionP8 name(p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6, p7##_type p7) {\ + return name##ActionP8(p0, p1, p2, p3, p4, p5, \ + p6, p7);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP8::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\ + template \ + class name##ActionP9 {\ + public:\ + name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP9);\ + };\ + template \ + inline name##ActionP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ + p8##_type p8) {\ + return name##ActionP9(p0, p1, p2, \ + p3, p4, p5, p6, p7, p8);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP9::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\ + template \ + class name##ActionP10 {\ + public:\ + name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)), \ + p9(::std::forward(gmock_p9)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)), \ + p9(::std::forward(gmock_p9)) {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP10);\ + };\ + template \ + inline name##ActionP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9) {\ + return name##ActionP10(p0, \ + p1, p2, p3, p4, p5, p6, p7, p8, p9);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP10::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +namespace testing { + + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +// Various overloads for InvokeArgument(). +// +// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside ByRef(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but ByRef() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. + +namespace internal { +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/gmock-generated-actions.h header. + +template +R InvokeArgumentAdl(AdlTag, F f) { + return f(); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1) { + return f(a1); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) { + return f(a1, a2); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) { + return f(a1, a2, a3); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) { + return f(a1, a2, a3, a4); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + return f(a1, a2, a3, a4, a5); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + return f(a1, a2, a3, a4, a5, a6); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7) { + return f(a1, a2, a3, a4, a5, a6, a7); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8) { + return f(a1, a2, a3, a4, a5, a6, a7, a8); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9, A10 a10) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); +} +} // namespace invoke_argument +} // namespace internal + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_0_VALUE_PARAMS()) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args)); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_1_VALUE_PARAMS(p0)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_2_VALUE_PARAMS(p0, p1)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_3_VALUE_PARAMS(p0, p1, p2)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6, p7); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); +} + +// Various overloads for ReturnNew(). +// +// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new +// instance of type T, constructed on the heap with constructor arguments +// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_0_VALUE_PARAMS()) { + return new T(); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_1_VALUE_PARAMS(p0)) { + return new T(p0); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_2_VALUE_PARAMS(p0, p1)) { + return new T(p0, p1); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_3_VALUE_PARAMS(p0, p1, p2)) { + return new T(p0, p1, p2); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { + return new T(p0, p1, p2, p3); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { + return new T(p0, p1, p2, p3, p4); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { + return new T(p0, p1, p2, p3, p4, p5); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { + return new T(p0, p1, p2, p3, p4, p5, p6); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +// Include any custom callback actions added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gmock/internal/custom/gmock-generated-actions.h" + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h.pump b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h.pump new file mode 100644 index 000000000..1121fbdec --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-actions.h.pump @@ -0,0 +1,579 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert it to +$$ gmock-generated-actions.h. +$$ +$var n = 10 $$ The maximum arity we support. +$$}} This meta comment fixes auto-indentation in editors. +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include +#include + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template +// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// Users can, however, define any local functors (e.g. a lambda) that +// can be used as actions. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +$range i 0..n +$range k 0..n-1 + +// An internal macro needed for implementing ACTION*(). +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ + const args_type& args GTEST_ATTRIBUTE_UNUSED_ +$for k [[, \ + const arg$k[[]]_type& arg$k GTEST_ATTRIBUTE_UNUSED_]] + + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::std::get(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. + +$range j 1..n +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_DECL_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]] + + +]] + +// Lists the template parameters. + +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_LIST_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]] + + +]] + +// Declares the types of value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] + + +]] + +// Initializes the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ + ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]] + + +]] + +// Declares the fields for storing the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DEFN_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]] + + +]] + +// Lists the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]] + + +]] + +// Lists the value parameter types. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]] + + +]] + +// Declares the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$for j, [[p$j##_type p$j]] + + +]] + +// The suffix of the class template implementing the action template. +$for i [[ + + +$range j 0..i-1 +#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$if i==1 [[P]] $elif i>=2 [[P$i]] +]] + + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +$range k 0..n-1 + +#define ACTION_TEMPLATE(name, template_params, value_params)\ + template \ + class GMOCK_ACTION_CLASS_(name, value_params) {\ + public:\ + explicit GMOCK_ACTION_CLASS_(name, value_params)\ + GMOCK_INTERNAL_INIT_##value_params {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template <$for k, [[typename arg$k[[]]_type]]>\ + return_type gmock_PerformImpl(const args_type& args[[]] +$for k [[, const arg$k[[]]_type& arg$k]]) const;\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(\ + new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ + }\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ + };\ + template \ + inline GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ + GMOCK_INTERNAL_DECL_##value_params) {\ + return GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ + GMOCK_INTERNAL_LIST_##value_params);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ + gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +$for i + +[[ +$var template = [[$if i==0 [[]] $else [[ +$range j 0..i-1 + + template <$for j, [[typename p$j##_type]]>\ +]]]] +$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] + $else [[P$i]]]]]] +$range j 0..i-1 +$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::forward(gmock_p$j))]]]]]] +$var param_field_decls = [[$for j +[[ + + p$j##_type p$j;\ +]]]] +$var param_field_decls2 = [[$for j +[[ + + p$j##_type p$j;\ +]]]] +$var params = [[$for j, [[p$j]]]] +$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] +$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]] +$var arg_types_and_names = [[$for k, [[const arg$k[[]]_type& arg$k]]]] +$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]] + $else [[ACTION_P$i]]]] + +#define $macro_name(name$for j [[, p$j]])\$template + class $class_name {\ + public:\ + [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\ + return_type Perform(const args_type& args) override {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template <$typename_arg_types>\ + return_type gmock_PerformImpl(const args_type& args, [[]] +$arg_types_and_names) const;\$param_field_decls + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl($params));\ + }\$param_field_decls2 + private:\ + GTEST_DISALLOW_ASSIGN_($class_name);\ + };\$template + inline $class_name$param_types name($param_types_and_names) {\ + return $class_name$param_types($params);\ + }\$template + template \ + template <$typename_arg_types>\ + typename ::testing::internal::Function::Result\ + $class_name$param_types::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const +]] +$$ } // This meta comment fixes auto-indentation in Emacs. It won't +$$ // show up in the generated code. + + +namespace testing { + + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +// Various overloads for InvokeArgument(). +// +// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside ByRef(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but ByRef() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. + +namespace internal { +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/gmock-generated-actions.h header. + +$range i 0..n +$for i +[[ +$range j 1..i + +template +R InvokeArgumentAdl(AdlTag, F f[[$for j [[, A$j a$j]]]]) { + return f([[$for j, [[a$j]]]]); +} +]] + +} // namespace invoke_argument +} // namespace internal + +$range i 0..n +$for i [[ +$range j 0..i-1 + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args)$for j [[, p$j]]); +} + +]] + +// Various overloads for ReturnNew(). +// +// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new +// instance of type T, constructed on the heap with constructor arguments +// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. +$range i 0..n +$for i [[ +$range j 0..i-1 +$var ps = [[$for j, [[p$j]]]] + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_$i[[]]_VALUE_PARAMS($ps)) { + return new T($ps); +} + +]] + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +// Include any custom callback actions added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gmock/internal/custom/gmock-generated-actions.h" + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h new file mode 100644 index 000000000..cd9578178 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h @@ -0,0 +1,752 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-function-mockers.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements function mockers of various arities. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ + +#include +#include + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" + +namespace testing { +namespace internal { +// Removes the given pointer; this is a helper for the expectation setter method +// for parameterless matchers. +// +// We want to make sure that the user cannot set a parameterless expectation on +// overloaded methods, including methods which are overloaded on const. Example: +// +// class MockClass { +// MOCK_METHOD0(GetName, string&()); +// MOCK_CONST_METHOD0(GetName, const string&()); +// }; +// +// TEST() { +// // This should be an error, as it's not clear which overload is expected. +// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); +// } +// +// Here are the generated expectation-setter methods: +// +// class MockClass { +// // Overload 1 +// MockSpec gmock_GetName() { ... } +// // Overload 2. Declared const so that the compiler will generate an +// // error when trying to resolve between this and overload 4 in +// // 'gmock_GetName(WithoutMatchers(), nullptr)'. +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Removes const from this, calls overload 1 +// return AdjustConstness_(this)->gmock_GetName(); +// } +// +// // Overload 3 +// const string& gmock_GetName() const { ... } +// // Overload 4 +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Does not remove const, calls overload 3 +// return AdjustConstness_const(this)->gmock_GetName(); +// } +// } +// +template +const MockType* AdjustConstness_const(const MockType* mock) { + return mock; +} + +// Removes const from and returns the given pointer; this is a helper for the +// expectation setter method for parameterless matchers. +template +MockType* AdjustConstness_(const MockType* mock) { + return const_cast(mock); +} + +} // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; + +// GMOCK_RESULT_(tn, F) expands to the result type of function type F. +// We define this as a variadic macro in case F contains unprotected +// commas (the same reason that we use variadic macros in other places +// in this file). +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_RESULT_(tn, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Result + +// The type of argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_ARG_(tn, N, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::template Arg::type + +// The matcher type for argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MATCHER_(tn, N, ...) \ + const ::testing::Matcher& + +// The variable for mocking the given method. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ + static_assert(0 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + ) constness { \ + GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(0, constness, Method).Invoke(); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method() constness { \ + GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(0, constness, Method).With(); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ + static_assert(1 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ + GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(1, constness, \ + Method).Invoke(::std::forward(gmock_a1)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ + GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \ + static_assert(2 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2) constness { \ + GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(2, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ + GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \ + static_assert(3 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, \ + __VA_ARGS__) gmock_a3) constness { \ + GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(3, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ + GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \ + static_assert(4 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ + GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(4, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ + GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \ + static_assert(5 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5) constness { \ + GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(5, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ + GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \ + static_assert(6 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, \ + __VA_ARGS__) gmock_a6) constness { \ + GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(6, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ + GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \ + static_assert(7 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ + GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(7, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ + GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \ + static_assert(8 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ + __VA_ARGS__) gmock_a8) constness { \ + GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(8, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7), \ + ::std::forward(gmock_a8)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ + GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \ + static_assert(9 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ + __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, \ + __VA_ARGS__) gmock_a9) constness { \ + GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(9, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7), \ + ::std::forward(gmock_a8), \ + ::std::forward(gmock_a9)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ + GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ + gmock_a9); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \ + static_assert(10 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ + __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \ + GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ + GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(10, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7), \ + ::std::forward(gmock_a8), \ + ::std::forward(gmock_a9), \ + ::std::forward(gmock_a10)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \ + GMOCK_MATCHER_(tn, 10, \ + __VA_ARGS__) gmock_a10) constness { \ + GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ + gmock_a10); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \ + Method) + +#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__) +#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__) +#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__) +#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__) +#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__) +#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__) +#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__) +#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__) +#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__) +#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__) +#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__) + +#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T(m, ...) \ + GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T(m, ...) \ + GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T(m, ...) \ + GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T(m, ...) \ + GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T(m, ...) \ + GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T(m, ...) \ + GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T(m, ...) \ + GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T(m, ...) \ + GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T(m, ...) \ + GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T(m, ...) \ + GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T(m, ...) \ + GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__) + +#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(, , ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__) + +#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__) + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h.pump new file mode 100644 index 000000000..a56e132f3 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-function-mockers.h.pump @@ -0,0 +1,227 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert +$$ it to gmock-generated-function-mockers.h. +$$ +$var n = 10 $$ The maximum arity we support. +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements function mockers of various arities. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ + +#include +#include + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" + +namespace testing { +namespace internal { + +$range i 0..n +// Removes the given pointer; this is a helper for the expectation setter method +// for parameterless matchers. +// +// We want to make sure that the user cannot set a parameterless expectation on +// overloaded methods, including methods which are overloaded on const. Example: +// +// class MockClass { +// MOCK_METHOD0(GetName, string&()); +// MOCK_CONST_METHOD0(GetName, const string&()); +// }; +// +// TEST() { +// // This should be an error, as it's not clear which overload is expected. +// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); +// } +// +// Here are the generated expectation-setter methods: +// +// class MockClass { +// // Overload 1 +// MockSpec gmock_GetName() { ... } +// // Overload 2. Declared const so that the compiler will generate an +// // error when trying to resolve between this and overload 4 in +// // 'gmock_GetName(WithoutMatchers(), nullptr)'. +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Removes const from this, calls overload 1 +// return AdjustConstness_(this)->gmock_GetName(); +// } +// +// // Overload 3 +// const string& gmock_GetName() const { ... } +// // Overload 4 +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Does not remove const, calls overload 3 +// return AdjustConstness_const(this)->gmock_GetName(); +// } +// } +// +template +const MockType* AdjustConstness_const(const MockType* mock) { + return mock; +} + +// Removes const from and returns the given pointer; this is a helper for the +// expectation setter method for parameterless matchers. +template +MockType* AdjustConstness_(const MockType* mock) { + return const_cast(mock); +} + +} // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; + +// GMOCK_RESULT_(tn, F) expands to the result type of function type F. +// We define this as a variadic macro in case F contains unprotected +// commas (the same reason that we use variadic macros in other places +// in this file). +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_RESULT_(tn, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Result + +// The type of argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_ARG_(tn, N, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::template Arg::type + +// The matcher type for argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MATCHER_(tn, N, ...) \ + const ::testing::Matcher& + +// The variable for mocking the given method. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) + + +$for i [[ +$range j 1..i +$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] +$var as = [[$for j, \ + [[::std::forward(gmock_a$j)]]]] +$var matcher_arg_as = [[$for j, \ + [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] +$var matcher_as = [[$for j, [[gmock_a$j]]]] +$var anything_matchers = [[$for j, \ + [[::testing::A()]]]] +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ + static_assert($i == ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + $arg_as) constness { \ + GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method($matcher_arg_as) constness { \ + GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method($anything_matchers); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) + + +]] +$for i [[ +#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ + GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) + +]] + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h new file mode 100644 index 000000000..61892380c --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h @@ -0,0 +1,1097 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-matchers.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic matchers. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ + +#include +#include +#include +#include +#include +#include "gmock/gmock-matchers.h" + +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// std::string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template +// FooMatcherPk +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +#define MATCHER(name, description)\ + class name##Matcher {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl()\ + {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple<>()));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl());\ + }\ + name##Matcher() {\ + }\ + private:\ + };\ + inline name##Matcher name() {\ + return name##Matcher();\ + }\ + template \ + bool name##Matcher::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P(name, p0, description)\ + template \ + class name##MatcherP {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + explicit gmock_Impl(p0##_type gmock_p0)\ + : p0(::std::move(gmock_p0)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0));\ + }\ + explicit name##MatcherP(p0##_type gmock_p0) : p0(::std::move(gmock_p0)) {\ + }\ + p0##_type const p0;\ + private:\ + };\ + template \ + inline name##MatcherP name(p0##_type p0) {\ + return name##MatcherP(p0);\ + }\ + template \ + template \ + bool name##MatcherP::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P2(name, p0, p1, description)\ + template \ + class name##MatcherP2 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1));\ + }\ + name##MatcherP2(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + private:\ + };\ + template \ + inline name##MatcherP2 name(p0##_type p0, \ + p1##_type p1) {\ + return name##MatcherP2(p0, p1);\ + }\ + template \ + template \ + bool name##MatcherP2::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P3(name, p0, p1, p2, description)\ + template \ + class name##MatcherP3 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2));\ + }\ + name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + private:\ + };\ + template \ + inline name##MatcherP3 name(p0##_type p0, \ + p1##_type p1, p2##_type p2) {\ + return name##MatcherP3(p0, p1, p2);\ + }\ + template \ + template \ + bool name##MatcherP3::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P4(name, p0, p1, p2, p3, description)\ + template \ + class name##MatcherP4 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, \ + p1, p2, p3)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3));\ + }\ + name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + private:\ + };\ + template \ + inline name##MatcherP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3) {\ + return name##MatcherP4(p0, \ + p1, p2, p3);\ + }\ + template \ + template \ + bool name##MatcherP4::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\ + template \ + class name##MatcherP5 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4));\ + }\ + name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + private:\ + };\ + template \ + inline name##MatcherP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4) {\ + return name##MatcherP5(p0, p1, p2, p3, p4);\ + }\ + template \ + template \ + bool name##MatcherP5::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\ + template \ + class name##MatcherP6 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5));\ + }\ + name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + private:\ + };\ + template \ + inline name##MatcherP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3, p4##_type p4, p5##_type p5) {\ + return name##MatcherP6(p0, p1, p2, p3, p4, p5);\ + }\ + template \ + template \ + bool name##MatcherP6::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\ + template \ + class name##MatcherP7 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5, \ + p6)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6));\ + }\ + name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + private:\ + };\ + template \ + inline name##MatcherP7 name(p0##_type p0, p1##_type p1, \ + p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6) {\ + return name##MatcherP7(p0, p1, p2, p3, p4, p5, p6);\ + }\ + template \ + template \ + bool name##MatcherP7::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\ + template \ + class name##MatcherP8 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, \ + p3, p4, p5, p6, p7)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7));\ + }\ + name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + private:\ + };\ + template \ + inline name##MatcherP8 name(p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6, p7##_type p7) {\ + return name##MatcherP8(p0, p1, p2, p3, p4, p5, \ + p6, p7);\ + }\ + template \ + template \ + bool name##MatcherP8::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\ + template \ + class name##MatcherP9 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \ + p8(::std::move(gmock_p8)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8));\ + }\ + name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + private:\ + };\ + template \ + inline name##MatcherP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ + p8##_type p8) {\ + return name##MatcherP9(p0, p1, p2, \ + p3, p4, p5, p6, p7, p8);\ + }\ + template \ + template \ + bool name##MatcherP9::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\ + template \ + class name##MatcherP10 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \ + p8(::std::move(gmock_p8)), p9(::std::move(gmock_p9)) {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + p9##_type const p9;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\ + }\ + name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8, p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \ + p9(::std::move(gmock_p9)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + p9##_type const p9;\ + private:\ + };\ + template \ + inline name##MatcherP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9) {\ + return name##MatcherP10(p0, \ + p1, p2, p3, p4, p5, p6, p7, p8, p9);\ + }\ + template \ + template \ + bool name##MatcherP10::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h.pump b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h.pump new file mode 100644 index 000000000..69d2ae418 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-generated-matchers.h.pump @@ -0,0 +1,346 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert +$$ it to gmock-generated-matchers.h. +$$ +$var n = 10 $$ The maximum arity we support. +$$ }} This line fixes auto-indentation of the following code in Emacs. +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic matchers. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ + +#include +#include +#include +#include +#include +#include "gmock/gmock-matchers.h" + +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// std::string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template +// FooMatcherPk +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +$range i 0..n +$for i + +[[ +$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]] + $else [[MATCHER_P$i]]]] +$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]] + $else [[P$i]]]]]] +$range j 0..i-1 +$var template = [[$if i==0 [[]] $else [[ + + template <$for j, [[typename p$j##_type]]>\ +]]]] +$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]] +$var params = [[$for j, [[p$j]]]] +$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] +$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] +$var param_field_decls = [[$for j +[[ + + p$j##_type const p$j;\ +]]]] +$var param_field_decls2 = [[$for j +[[ + + p$j##_type const p$j;\ +]]]] + +#define $macro_name(name$for j [[, p$j]], description)\$template + class $class_name {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\ + $impl_inits {}\ + bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const override;\ + void DescribeTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(false);\ + }\ + void DescribeNegationTo(::std::ostream* gmock_os) const override {\ + *gmock_os << FormatDescription(true);\ + }\$param_field_decls + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl($params));\ + }\ + [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ + }\$param_field_decls2 + private:\ + };\$template + inline $class_name$param_types name($param_types_and_names) {\ + return $class_name$param_types($params);\ + }\$template + template \ + bool $class_name$param_types::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const +]] + + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-matchers.h b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-matchers.h new file mode 100644 index 000000000..67bd7e271 --- /dev/null +++ b/tpl/RAJA/blt/thirdparty_builtin/googletest-master-2020-01-07/googlemock/include/gmock/gmock-matchers.h @@ -0,0 +1,4567 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used argument matchers. More +// matchers can be defined by the user implementing the +// MatcherInterface interface if necessary. +// +// See googletest/include/gtest/gtest-matchers.h for the definition of class +// Matcher, class MatcherInterface, and others. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ + +#include +#include +#include +#include +#include +#include +#include // NOLINT +#include +#include +#include +#include +#include + +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +// MSVC warning C5046 is new as of VS2017 version 15.8. +#if defined(_MSC_VER) && _MSC_VER >= 1915 +#define GMOCK_MAYBE_5046_ 5046 +#else +#define GMOCK_MAYBE_5046_ +#endif + +GTEST_DISABLE_MSC_WARNINGS_PUSH_( + 4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by + clients of class B */ + /* Symbol involving type with internal linkage not defined */) + +namespace testing { + +// To implement a matcher Foo for type T, define: +// 1. a class FooMatcherImpl that implements the +// MatcherInterface interface, and +// 2. a factory function that creates a Matcher object from a +// FooMatcherImpl*. +// +// The two-level delegation design makes it possible to allow a user +// to write "v" instead of "Eq(v)" where a Matcher is expected, which +// is impossible if we pass matchers by pointers. It also eases +// ownership management as Matcher objects can now be copied like +// plain values. + +// A match result listener that stores the explanation in a string. +class StringMatchResultListener : public MatchResultListener { + public: + StringMatchResultListener() : MatchResultListener(&ss_) {} + + // Returns the explanation accumulated so far. + std::string str() const { return ss_.str(); } + + // Clears the explanation accumulated so far. + void Clear() { ss_.str(""); } + + private: + ::std::stringstream ss_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); +}; + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// The MatcherCastImpl class template is a helper for implementing +// MatcherCast(). We need this helper in order to partially +// specialize the implementation of MatcherCast() (C++ allows +// class/struct templates to be partially specialized, but not +// function templates.). + +// This general version is used when MatcherCast()'s argument is a +// polymorphic matcher (i.e. something that can be converted to a +// Matcher but is not one yet; for example, Eq(value)) or a value (for +// example, "hello"). +template +class MatcherCastImpl { + public: + static Matcher Cast(const M& polymorphic_matcher_or_value) { + // M can be a polymorphic matcher, in which case we want to use + // its conversion operator to create Matcher. Or it can be a value + // that should be passed to the Matcher's constructor. + // + // We can't call Matcher(polymorphic_matcher_or_value) when M is a + // polymorphic matcher because it'll be ambiguous if T has an implicit + // constructor from M (this usually happens when T has an implicit + // constructor from any type). + // + // It won't work to unconditionally implict_cast + // polymorphic_matcher_or_value to Matcher because it won't trigger + // a user-defined conversion from M to T if one exists (assuming M is + // a value). + return CastImpl(polymorphic_matcher_or_value, + std::is_convertible>{}, + std::is_convertible{}); + } + + private: + template + static Matcher CastImpl(const M& polymorphic_matcher_or_value, + std::true_type /* convertible_to_matcher */, + std::integral_constant) { + // M is implicitly convertible to Matcher, which means that either + // M is a polymorphic matcher or Matcher has an implicit constructor + // from M. In both cases using the implicit conversion will produce a + // matcher. + // + // Even if T has an implicit constructor from M, it won't be called because + // creating Matcher would require a chain of two user-defined conversions + // (first to create T from M and then to create Matcher from T). + return polymorphic_matcher_or_value; + } + + // M can't be implicitly converted to Matcher, so M isn't a polymorphic + // matcher. It's a value of a type implicitly convertible to T. Use direct + // initialization to create a matcher. + static Matcher CastImpl(const M& value, + std::false_type /* convertible_to_matcher */, + std::true_type /* convertible_to_T */) { + return Matcher(ImplicitCast_(value)); + } + + // M can't be implicitly converted to either Matcher or T. Attempt to use + // polymorphic matcher Eq(value) in this case. + // + // Note that we first attempt to perform an implicit cast on the value and + // only fall back to the polymorphic Eq() matcher afterwards because the + // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end + // which might be undefined even when Rhs is implicitly convertible to Lhs + // (e.g. std::pair vs. std::pair). + // + // We don't define this method inline as we need the declaration of Eq(). + static Matcher CastImpl(const M& value, + std::false_type /* convertible_to_matcher */, + std::false_type /* convertible_to_T */); +}; + +// This more specialized version is used when MatcherCast()'s argument +// is already a Matcher. This only compiles when type T can be +// statically converted to type U. +template +class MatcherCastImpl > { + public: + static Matcher Cast(const Matcher& source_matcher) { + return Matcher(new Impl(source_matcher)); + } + + private: + class Impl : public MatcherInterface { + public: + explicit Impl(const Matcher& source_matcher) + : source_matcher_(source_matcher) {} + + // We delegate the matching logic to the source matcher. + bool MatchAndExplain(T x, MatchResultListener* listener) const override { + using FromType = typename std::remove_cv::type>::type>::type; + using ToType = typename std::remove_cv::type>::type>::type; + // Do not allow implicitly converting base*/& to derived*/&. + static_assert( + // Do not trigger if only one of them is a pointer. That implies a + // regular conversion and not a down_cast. + (std::is_pointer::type>::value != + std::is_pointer::type>::value) || + std::is_same::value || + !std::is_base_of::value, + "Can't implicitly convert from to "); + + return source_matcher_.MatchAndExplain(static_cast(x), listener); + } + + void DescribeTo(::std::ostream* os) const override { + source_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + source_matcher_.DescribeNegationTo(os); + } + + private: + const Matcher source_matcher_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; +}; + +// This even more specialized version is used for efficiently casting +// a matcher to its own type. +template +class MatcherCastImpl > { + public: + static Matcher Cast(const Matcher& matcher) { return matcher; } +}; + +} // namespace internal + +// In order to be safe and clear, casting between different matcher +// types is done explicitly via MatcherCast(m), which takes a +// matcher m and returns a Matcher. It compiles only when T can be +// statically converted to the argument type of m. +template +inline Matcher MatcherCast(const M& matcher) { + return internal::MatcherCastImpl::Cast(matcher); +} + +// This overload handles polymorphic matchers and values only since +// monomorphic matchers are handled by the next one. +template +inline Matcher SafeMatcherCast(const M& polymorphic_matcher_or_value) { + return MatcherCast(polymorphic_matcher_or_value); +} + +// This overload handles monomorphic matchers. +// +// In general, if type T can be implicitly converted to type U, we can +// safely convert a Matcher to a Matcher (i.e. Matcher is +// contravariant): just keep a copy of the original Matcher, convert the +// argument from type T to U, and then pass it to the underlying Matcher. +// The only exception is when U is a reference and T is not, as the +// underlying Matcher may be interested in the argument's address, which +// is not preserved in the conversion from T to U. +template +inline Matcher SafeMatcherCast(const Matcher& matcher) { + // Enforce that T can be implicitly converted to U. + GTEST_COMPILE_ASSERT_((std::is_convertible::value), + "T must be implicitly convertible to U"); + // Enforce that we are not converting a non-reference type T to a reference + // type U. + GTEST_COMPILE_ASSERT_( + std::is_reference::value || !std::is_reference::value, + cannot_convert_non_reference_arg_to_reference); + // In case both T and U are arithmetic types, enforce that the + // conversion is not lossy. + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; + constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; + constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; + GTEST_COMPILE_ASSERT_( + kTIsOther || kUIsOther || + (internal::LosslessArithmeticConvertible::value), + conversion_of_arithmetic_types_must_be_lossless); + return MatcherCast(matcher); +} + +// A() returns a matcher that matches any value of type T. +template +Matcher A(); + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// If the explanation is not empty, prints it to the ostream. +inline void PrintIfNotEmpty(const std::string& explanation, + ::std::ostream* os) { + if (explanation != "" && os != nullptr) { + *os << ", " << explanation; + } +} + +// Returns true if the given type name is easy to read by a human. +// This is used to decide whether printing the type of a value might +// be helpful. +inline bool IsReadableTypeName(const std::string& type_name) { + // We consider a type name readable if it's short or doesn't contain + // a template or function type. + return (type_name.length() <= 20 || + type_name.find_first_of("<(") == std::string::npos); +} + +// Matches the value against the given matcher, prints the value and explains +// the match result to the listener. Returns the match result. +// 'listener' must not be NULL. +// Value cannot be passed by const reference, because some matchers take a +// non-const argument. +template +bool MatchPrintAndExplain(Value& value, const Matcher& matcher, + MatchResultListener* listener) { + if (!listener->IsInterested()) { + // If the listener is not interested, we do not need to construct the + // inner explanation. + return matcher.Matches(value); + } + + StringMatchResultListener inner_listener; + const bool match = matcher.MatchAndExplain(value, &inner_listener); + + UniversalPrint(value, listener->stream()); +#if GTEST_HAS_RTTI + const std::string& type_name = GetTypeName(); + if (IsReadableTypeName(type_name)) + *listener->stream() << " (of type " << type_name << ")"; +#endif + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + + return match; +} + +// An internal helper class for doing compile-time loop on a tuple's +// fields. +template +class TuplePrefix { + public: + // TuplePrefix::Matches(matcher_tuple, value_tuple) returns true + // if and only if the first N fields of matcher_tuple matches + // the first N fields of value_tuple, respectively. + template + static bool Matches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + return TuplePrefix::Matches(matcher_tuple, value_tuple) && + std::get(matcher_tuple).Matches(std::get(value_tuple)); + } + + // TuplePrefix::ExplainMatchFailuresTo(matchers, values, os) + // describes failures in matching the first N fields of matchers + // against the first N fields of values. If there is no failure, + // nothing will be streamed to os. + template + static void ExplainMatchFailuresTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + // First, describes failures in the first N - 1 fields. + TuplePrefix::ExplainMatchFailuresTo(matchers, values, os); + + // Then describes the failure (if any) in the (N - 1)-th (0-based) + // field. + typename std::tuple_element::type matcher = + std::get(matchers); + typedef typename std::tuple_element::type Value; + const Value& value = std::get(values); + StringMatchResultListener listener; + if (!matcher.MatchAndExplain(value, &listener)) { + *os << " Expected arg #" << N - 1 << ": "; + std::get(matchers).DescribeTo(os); + *os << "\n Actual: "; + // We remove the reference in type Value to prevent the + // universal printer from printing the address of value, which + // isn't interesting to the user most of the time. The + // matcher's MatchAndExplain() method handles the case when + // the address is interesting. + internal::UniversalPrint(value, os); + PrintIfNotEmpty(listener.str(), os); + *os << "\n"; + } + } +}; + +// The base case. +template <> +class TuplePrefix<0> { + public: + template + static bool Matches(const MatcherTuple& /* matcher_tuple */, + const ValueTuple& /* value_tuple */) { + return true; + } + + template + static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */, + const ValueTuple& /* values */, + ::std::ostream* /* os */) {} +}; + +// TupleMatches(matcher_tuple, value_tuple) returns true if and only if +// all matchers in matcher_tuple match the corresponding fields in +// value_tuple. It is a compiler error if matcher_tuple and +// value_tuple have different number of fields or incompatible field +// types. +template +bool TupleMatches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + // Makes sure that matcher_tuple and value_tuple have the same + // number of fields. + GTEST_COMPILE_ASSERT_(std::tuple_size::value == + std::tuple_size::value, + matcher_and_value_have_different_numbers_of_fields); + return TuplePrefix::value>::Matches(matcher_tuple, + value_tuple); +} + +// Describes failures in matching matchers against values. If there +// is no failure, nothing will be streamed to os. +template +void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + TuplePrefix::value>::ExplainMatchFailuresTo( + matchers, values, os); +} + +// TransformTupleValues and its helper. +// +// TransformTupleValuesHelper hides the internal machinery that +// TransformTupleValues uses to implement a tuple traversal. +template +class TransformTupleValuesHelper { + private: + typedef ::std::tuple_size TupleSize; + + public: + // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. + // Returns the final value of 'out' in case the caller needs it. + static OutIter Run(Func f, const Tuple& t, OutIter out) { + return IterateOverTuple()(f, t, out); + } + + private: + template + struct IterateOverTuple { + OutIter operator() (Func f, const Tup& t, OutIter out) const { + *out++ = f(::std::get(t)); + return IterateOverTuple()(f, t, out); + } + }; + template + struct IterateOverTuple { + OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { + return out; + } + }; +}; + +// Successively invokes 'f(element)' on each element of the tuple 't', +// appending each result to the 'out' iterator. Returns the final value +// of 'out'. +template +OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { + return TransformTupleValuesHelper::Run(f, t, out); +} + +// Implements A(). +template +class AnyMatcherImpl : public MatcherInterface { + public: + bool MatchAndExplain(const T& /* x */, + MatchResultListener* /* listener */) const override { + return true; + } + void DescribeTo(::std::ostream* os) const override { *os << "is anything"; } + void DescribeNegationTo(::std::ostream* os) const override { + // This is mostly for completeness' safe, as it's not very useful + // to write Not(A()). However we cannot completely rule out + // such a possibility, and it doesn't hurt to be prepared. + *os << "never matches"; + } +}; + +// Implements _, a matcher that matches any value of any +// type. This is a polymorphic matcher, so we need a template type +// conversion operator to make it appearing as a Matcher for any +// type T. +class AnythingMatcher { + public: + template + operator Matcher() const { return A(); } +}; + +// Implements the polymorphic IsNull() matcher, which matches any raw or smart +// pointer that is NULL. +class IsNullMatcher { + public: + template + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return p == nullptr; + } + + void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "isn't NULL"; + } +}; + +// Implements the polymorphic NotNull() matcher, which matches any raw or smart +// pointer that is not NULL. +class NotNullMatcher { + public: + template + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return p != nullptr; + } + + void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "is NULL"; + } +}; + +// Ref(variable) matches any argument that is a reference to +// 'variable'. This matcher is polymorphic as it can match any +// super type of the type of 'variable'. +// +// The RefMatcher template class implements Ref(variable). It can +// only be instantiated with a reference type. This prevents a user +// from mistakenly using Ref(x) to match a non-reference function +// argument. For example, the following will righteously cause a +// compiler error: +// +// int n; +// Matcher m1 = Ref(n); // This won't compile. +// Matcher m2 = Ref(n); // This will compile. +template +class RefMatcher; + +template +class RefMatcher { + // Google Mock is a generic framework and thus needs to support + // mocking any function types, including those that take non-const + // reference arguments. Therefore the template parameter T (and + // Super below) can be instantiated to either a const type or a + // non-const type. + public: + // RefMatcher() takes a T& instead of const T&, as we want the + // compiler to catch using Ref(const_value) as a matcher for a + // non-const reference. + explicit RefMatcher(T& x) : object_(x) {} // NOLINT + + template + operator Matcher() const { + // By passing object_ (type T&) to Impl(), which expects a Super&, + // we make sure that Super is a super type of T. In particular, + // this catches using Ref(const_value) as a matcher for a + // non-const reference, as you cannot implicitly convert a const + // reference to a non-const reference. + return MakeMatcher(new Impl(object_)); + } + + private: + template + class Impl : public MatcherInterface { + public: + explicit Impl(Super& x) : object_(x) {} // NOLINT + + // MatchAndExplain() takes a Super& (as opposed to const Super&) + // in order to match the interface MatcherInterface. + bool MatchAndExplain(Super& x, + MatchResultListener* listener) const override { + *listener << "which is located @" << static_cast(&x); + return &x == &object_; + } + + void DescribeTo(::std::ostream* os) const override { + *os << "references the variable "; + UniversalPrinter::Print(object_, os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "does not reference the variable "; + UniversalPrinter::Print(object_, os); + } + + private: + const Super& object_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + T& object_; + + GTEST_DISALLOW_ASSIGN_(RefMatcher); +}; + +// Polymorphic helper functions for narrow and wide string matchers. +inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { + return String::CaseInsensitiveCStringEquals(lhs, rhs); +} + +inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + return String::CaseInsensitiveWideCStringEquals(lhs, rhs); +} + +// String comparison for narrow or wide strings that can have embedded NUL +// characters. +template +bool CaseInsensitiveStringEquals(const StringType& s1, + const StringType& s2) { + // Are the heads equal? + if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { + return false; + } + + // Skip the equal heads. + const typename StringType::value_type nul = 0; + const size_t i1 = s1.find(nul), i2 = s2.find(nul); + + // Are we at the end of either s1 or s2? + if (i1 == StringType::npos || i2 == StringType::npos) { + return i1 == i2; + } + + // Are the tails equal? + return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); +} + +// String matchers. + +// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. +template +class StrEqualityMatcher { + public: + StrEqualityMatcher(const StringType& str, bool expect_eq, + bool case_sensitive) + : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + if (s == nullptr) { + return !expect_eq_; + } + return MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + const bool eq = case_sensitive_ ? s2 == string_ : + CaseInsensitiveStringEquals(s2, string_); + return expect_eq_ == eq; + } + + void DescribeTo(::std::ostream* os) const { + DescribeToHelper(expect_eq_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + DescribeToHelper(!expect_eq_, os); + } + + private: + void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { + *os << (expect_eq ? "is " : "isn't "); + *os << "equal to "; + if (!case_sensitive_) { + *os << "(ignoring case) "; + } + UniversalPrint(string_, os); + } + + const StringType string_; + const bool expect_eq_; + const bool case_sensitive_; + + GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher); +}; + +// Implements the polymorphic HasSubstr(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class HasSubstrMatcher { + public: + explicit HasSubstrMatcher(const StringType& substring) + : substring_(substring) {} + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + return StringType(s).find(substring_) != StringType::npos; + } + + // Describes what this matcher matches. + void DescribeTo(::std::ostream* os) const { + *os << "has substring "; + UniversalPrint(substring_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "has no substring "; + UniversalPrint(substring_, os); + } + + private: + const StringType substring_; + + GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher); +}; + +// Implements the polymorphic StartsWith(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class StartsWithMatcher { + public: + explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { + } + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= prefix_.length() && + s2.substr(0, prefix_.length()) == prefix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "starts with "; + UniversalPrint(prefix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't start with "; + UniversalPrint(prefix_, os); + } + + private: + const StringType prefix_; + + GTEST_DISALLOW_ASSIGN_(StartsWithMatcher); +}; + +// Implements the polymorphic EndsWith(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class EndsWithMatcher { + public: + explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= suffix_.length() && + s2.substr(s2.length() - suffix_.length()) == suffix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "ends with "; + UniversalPrint(suffix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't end with "; + UniversalPrint(suffix_, os); + } + + private: + const StringType suffix_; + + GTEST_DISALLOW_ASSIGN_(EndsWithMatcher); +}; + +// Implements a matcher that compares the two fields of a 2-tuple +// using one of the ==, <=, <, etc, operators. The two fields being +// compared don't have to have the same type. +// +// The matcher defined here is polymorphic (for example, Eq() can be +// used to match a std::tuple, a std::tuple, +// etc). Therefore we use a template type conversion operator in the +// implementation. +template +class PairMatchBase { + public: + template + operator Matcher<::std::tuple>() const { + return Matcher<::std::tuple>(new Impl&>); + } + template + operator Matcher&>() const { + return MakeMatcher(new Impl&>); + } + + private: + static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT + return os << D::Desc(); + } + + template + class Impl : public MatcherInterface { + public: + bool MatchAndExplain(Tuple args, + MatchResultListener* /* listener */) const override { + return Op()(::std::get<0>(args), ::std::get<1>(args)); + } + void DescribeTo(::std::ostream* os) const override { + *os << "are " << GetDesc; + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << "aren't " << GetDesc; + } + }; +}; + +class Eq2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "an equal pair"; } +}; +class Ne2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "an unequal pair"; } +}; +class Lt2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first < the second"; } +}; +class Gt2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first > the second"; } +}; +class Le2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first <= the second"; } +}; +class Ge2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first >= the second"; } +}; + +// Implements the Not(...) matcher for a particular argument type T. +// We do not nest it inside the NotMatcher class template, as that +// will prevent different instantiations of NotMatcher from sharing +// the same NotMatcherImpl class. +template +class NotMatcherImpl : public MatcherInterface { + public: + explicit NotMatcherImpl(const Matcher& matcher) + : matcher_(matcher) {} + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + return !matcher_.MatchAndExplain(x, listener); + } + + void DescribeTo(::std::ostream* os) const override { + matcher_.DescribeNegationTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + matcher_.DescribeTo(os); + } + + private: + const Matcher matcher_; + + GTEST_DISALLOW_ASSIGN_(NotMatcherImpl); +}; + +// Implements the Not(m) matcher, which matches a value that doesn't +// match matcher m. +template +class NotMatcher { + public: + explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} + + // This template type conversion operator allows Not(m) to be used + // to match any type m can match. + template + operator Matcher() const { + return Matcher(new NotMatcherImpl(SafeMatcherCast(matcher_))); + } + + private: + InnerMatcher matcher_; + + GTEST_DISALLOW_ASSIGN_(NotMatcher); +}; + +// Implements the AllOf(m1, m2) matcher for a particular argument type +// T. We do not nest it inside the BothOfMatcher class template, as +// that will prevent different instantiations of BothOfMatcher from +// sharing the same BothOfMatcherImpl class. +template +class AllOfMatcherImpl : public MatcherInterface { + public: + explicit AllOfMatcherImpl(std::vector > matchers) + : matchers_(std::move(matchers)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") and ("; + matchers_[i].DescribeTo(os); + } + *os << ")"; + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") or ("; + matchers_[i].DescribeNegationTo(os); + } + *os << ")"; + } + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + // If either matcher1_ or matcher2_ doesn't match x, we only need + // to explain why one of them fails. + std::string all_match_result; + + for (size_t i = 0; i < matchers_.size(); ++i) { + StringMatchResultListener slistener; + if (matchers_[i].MatchAndExplain(x, &slistener)) { + if (all_match_result.empty()) { + all_match_result = slistener.str(); + } else { + std::string result = slistener.str(); + if (!result.empty()) { + all_match_result += ", and "; + all_match_result += result; + } + } + } else { + *listener << slistener.str(); + return false; + } + } + + // Otherwise we need to explain why *both* of them match. + *listener << all_match_result; + return true; + } + + private: + const std::vector > matchers_; + + GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl); +}; + +// VariadicMatcher is used for the variadic implementation of +// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). +// CombiningMatcher is used to recursively combine the provided matchers +// (of type Args...). +template