diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 736e5ce0..cc1e67ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,6 +69,12 @@ jobs: path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }} key: ${{ runner.os }}-${{ matrix.ghc }}--${{ github.Shah }}-CACHE_V3 # ---------------- + - name: "Install PAPI" + run: | + sudo apt-get install -y libpapi-dev + echo FLAG_PAPI=-fBenchPAPI >> "$GITHUB_ENV" + if: matrix.os == 'ubuntu-latest' + # ---------------- - name: Versions run: | cabal -V @@ -86,13 +92,13 @@ jobs: # ---------------- - name: cabal check run: | - cd vector - cabal -vnormal check + (cd vector-stream && cabal -vnormal check) + (cd vector && cabal -vnormal check) # ---------------- - name: Build run: | - set -x - cabal configure ${{ matrix.flags }} --haddock-all --enable-tests --enable-benchmarks --benchmark-option=-l + echo FLAG_PAPI=$FLAG_PAPI + cabal configure ${{ matrix.flags }} $FLAG_PAPI --haddock-all --enable-tests --enable-benchmarks --benchmark-option=-l cabal build all --write-ghc-environment-files=always # ---------------- - name: Test diff --git a/cabal.project b/cabal.project index 9d90b2bc..abfdfdd7 100644 --- a/cabal.project +++ b/cabal.project @@ -1,3 +1,4 @@ packages: vector vector-stream + vector-bench-papi diff --git a/vector-bench-papi/benchmarks/Main.hs b/vector-bench-papi/benchmarks/Main.hs new file mode 100644 index 00000000..55eec45f --- /dev/null +++ b/vector-bench-papi/benchmarks/Main.hs @@ -0,0 +1,68 @@ +{-# LANGUAGE BangPatterns #-} +module Main where + +import Bench.Vector.Algo.MutableSet (mutableSet) +import Bench.Vector.Algo.ListRank (listRank) +import Bench.Vector.Algo.Rootfix (rootfix) +import Bench.Vector.Algo.Leaffix (leaffix) +import Bench.Vector.Algo.AwShCC (awshcc) +import Bench.Vector.Algo.HybCC (hybcc) +import Bench.Vector.Algo.Quickhull (quickhull) +import Bench.Vector.Algo.Spectral (spectral) +import Bench.Vector.Algo.Tridiag (tridiag) +import Bench.Vector.Algo.FindIndexR (findIndexR, findIndexR_naive, findIndexR_manual) + +import Bench.Vector.TestData.ParenTree (parenTree) +import Bench.Vector.TestData.Graph (randomGraph) +import Bench.Vector.Tasty + +import Data.Proxy +import qualified Data.Vector.Mutable as MV +import qualified Data.Vector.Unboxed as U +import Data.Word +import System.Random.Stateful +import Test.Tasty +import Test.Tasty.PAPI +import Test.Tasty.Options +import Test.Tasty.Runners + +indexFindThreshold :: Double +indexFindThreshold = 2e-5 + +main :: IO () +main = do + let ourOpts = [Option (Proxy :: Proxy VectorSize), Option (Proxy :: Proxy RandomSeed)] + ingredients = includingOptions ourOpts : benchIngredients + opts <- parseOptions ingredients (bench "Fake" (nf id ())) + let VectorSize useSize = lookupOption opts + RandomSeed useSeed = lookupOption opts + + gen <- newIOGenM (mkStdGen useSeed) + + let (!lparens, !rparens) = parenTree useSize + (!nodes, !edges1, !edges2) <- randomGraph gen useSize + + let randomVector l = U.replicateM l (uniformDoublePositive01M gen) + !as <- randomVector useSize + !bs <- randomVector useSize + !cs <- randomVector useSize + !ds <- randomVector useSize + !sp <- randomVector (floor $ sqrt $ fromIntegral useSize) + vi <- MV.new useSize + + defaultMainWithIngredients ingredients $ bgroup "All" + [ bench "listRank" $ whnf listRank useSize + , bench "rootfix" $ whnf rootfix (lparens, rparens) + , bench "leaffix" $ whnf leaffix (lparens, rparens) + , bench "awshcc" $ whnf awshcc (nodes, edges1, edges2) + , bench "hybcc" $ whnf hybcc (nodes, edges1, edges2) + , bench "quickhull" $ whnf quickhull (as,bs) + , bench "spectral" $ whnf spectral sp + , bench "tridiag" $ whnf tridiag (as,bs,cs,ds) + , bench "mutableSet" $ nfIO $ mutableSet vi + , bench "findIndexR" $ whnf findIndexR (( x*x*x)) as + , bench "maximumOn" $ whnf (U.maximumOn (\x -> x*x*x)) as + ] diff --git a/vector-bench-papi/vector-bench-papi.cabal b/vector-bench-papi/vector-bench-papi.cabal new file mode 100644 index 00000000..c224644a --- /dev/null +++ b/vector-bench-papi/vector-bench-papi.cabal @@ -0,0 +1,52 @@ +Cabal-Version: 3.0 +Build-Type: Simple +Name: vector-bench-papi +Version: 0.13.1.0 +License: BSD-3-Clause +License-File: LICENSE + +Author: Alexey Khudyakov +Maintainer: Haskell Libraries Team + Alexey Kuleshevich , + Aleksey Khudyakov , + Andrew Lelechenko + +Copyright: (c) Aleksey Khudyakov 2024, + +Homepage: https://github.com/haskell/vector +Bug-Reports: https://github.com/haskell/vector/issues + +Category: Benchmark +Synopsis: PAPI based benchmarks for vector-package +Description: + Benchmarks for vector package which use CPU counter instead of time measurements. + + Note that benchmarks will not be built unless flag -fBenchPAPI is + specified. + +Flag BenchPAPI + Description: Enable building of benchmarks which use instruction counters. + It requires libpapi and only works on Linux so it's protected by flag + Default: False + Manual: True + +library + default-language: Haskell2010 + +benchmark algorithms-papi + if !flag(BenchPAPI) || impl(ghc < 8.2) + buildable: False + type: exitcode-stdio-1.0 + main-is: Main.hs + hs-source-dirs: benchmarks + default-language: Haskell2010 + + build-depends: + base >= 2 && < 5 + , random >= 1.2 + , tasty + , tasty-papi >= 0.1.2.0 + , vector + , vector:benchmarks-O2 + + ghc-options: -O2