diff --git a/.gitignore b/.gitignore index ac522f0146ed32a7ebd33b9e242b64e7bdc89c16..5c26e73956b30a42dda16d719956d32ba4b9011b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ _build +.Rhistory tmp .build builds @@ -87,3 +88,6 @@ pynrm/docs/manifest.rst */.ipynb_checkpoints .ipynb_checkpoints **/notebook_cookie_secret +.build* + +_output diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index de9357bee730354c484d2538bcc434d6e3a67af7..cf0e03ec7aae700b75e7cfcac14f37dfd1628309 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -270,12 +270,12 @@ nix:app-stream: - nix script: nix-build -A stream --no-build-output -nix:app-stream-raw: +nix:app-stream: stage: build tags: - kvm - nix - script: nix-build -A stream-raw --no-build-output + script: nix-build -A stream --no-build-output nix:nrmFull: stage: build @@ -339,4 +339,4 @@ readthedocs: - nix script: - echo "token=$RTD_TOKEN" - - nix nixpkgs.curl -c curl --fail -X POST -d "token=$RTD_TOKEN" readthedocs.org/api/v2/webhook/hnrm/104604/ + - nix run nixpkgs.curl -c curl --fail -X POST -d "token=$RTD_TOKEN" readthedocs.org/api/v2/webhook/hnrm/104604/ diff --git a/.gitmodules b/.gitmodules index f4ecff4989033ffa47811ccd5a240e8d3ad86c9b..c79203ae5bdf838274d185b67a072ded628aefed 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "hsnrm/dhall-haskell"] path = hsnrm/dhall-haskell url = https://github.com/freuk/dhall-haskell.git +[submodule "dev/hnrm-experiments"] + path = dev/hnrm-experiments + url = https://xgitlab.cels.anl.gov/argo/hnrm-experiments.git diff --git a/README.md b/README.md index d34fbdcc9d30159c87886dce6b6db3ab57c54dbc..007bad6230a1b3f4377d970e24fdd620b59887de 100644 --- a/README.md +++ b/README.md @@ -3,38 +3,31 @@ ## User Documentation - [User documentation](http://hnrm.readthedocs.io) -- Shared library [haddocks](https://hnrm.readthedocs.io/en/latest/_static/haddocks/) -## Development +## Installation/Quickstart -All the following instructions suppose using a local clone, *with submodules -initialized and updated*: +All the following instructions suppose using a local clone *with submodules*: ``` -git clone https://xgitlab.cels.anl.gov/argo/hnrm.git -cd hnrm -git submodule init -git submodule update +git clone --recurse-submodules https://xgitlab.cels.anl.gov/argo/hnrm.git ``` -- local nix profile install: `./install.sh` (`nix-env -f. -iA nrm` if binary cache is down) -- entering a development shell : `./shell.sh` (`nix-shell` if binary cache is down) -- opening jupyter notebooks: `./shell.sh`, then run `jupyter-notebook` and navigate to the `notebooks` folder -- local release nix build: `./build.sh` (`nix-build -A nrm` if binary cache is down) -- deploy to a remote nix-enabled system: `./deploy_nix.sh nrm user@host` -- deploy a g5k notebook setup: `./deploy_g5k.sh nrm user@host` -- running CI jobs: `./ci.sh ` or all jobs using `./ci.sh` +- local nix build: `nix-build -A nrm` +- local nix profile install: `nix-env -f. -iA nrm` -Local development builds can be obtained using the following: +## Development/Local builds -- use `./shake.sh build` to build the `nrm.so` shared library (also runs the code generation step for vendored resources) -- use `./shake.sh client` to build the `nrm` client -- use `./shake.sh pyclient` to build the Python shared library (for use by the python module `nrm.tooling`) -- the appropriate Nix `shellHooks` are in place for you to use `nrm` and `nrmd` after running `./shell.sh`. -## CI +- opening jupyter notebooks: `nix-shell -A expe`, which provisions + `jupyter-notebook`. +- running CI jobs locally: `./ci.sh ` or all jobs using `./ci` + (requires gitlab-runner) +- entering a development shell : `nix-shell -A hack` +- use `./shake.sh build` to build the `nrm.so` shared library (also runs the + code generation step for vendored resources) +- use `./shake.sh client` to build the `nrm` client +- use `./shake.sh pyclient` to build the Python shared library (for use by the + python module `nrm.tooling`) -- [gitlab-ci(master branch)](https://xgitlab.cels.anl.gov/argo/hnrm/pipelines/master/latest) -- [gitlab-ci(develop branch)](https://xgitlab.cels.anl.gov/argo/hnrm/pipelines/develop/latest) -- [hydra(master branch)](http://129.114.24.212/jobset/nrm/master#tabs-jobs) -- [hydra(develop branch)](http://129.114.24.212/jobset/nrm/develop#tabs-jobs) +the appropriate Nix `shellHooks` are in place in the `hack` nix derivation for +you to use the development build using the `nrm` and `nrmd` aliases on the CLI. diff --git a/build.sh b/build.sh deleted file mode 100755 index 8d7b0861be6ef45f9028ae57cff6d04dacd728fc..0000000000000000000000000000000000000000 --- a/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -rm -f .ghc.env* -nix-build -A nrm --option extra-substituters http://129.114.24.212/serve --option trusted-public-keys example-nix-cache-1:HSwzbJmGDidTrax3Lvx1vMSvto04VN2O5cjfXAG9uz0= diff --git a/dev/cabal/common.dhall b/dev/cabal/common.dhall index 953333cff1b9f4598d9df94ef08d6bacb0a3ce2a..9e68ca71306098c65a872864cd956f5652a878e6 100644 --- a/dev/cabal/common.dhall +++ b/dev/cabal/common.dhall @@ -319,6 +319,7 @@ let extramodules = let banditmodules = [ "HBandit.Class" , "HBandit.Exp3" + , "HBandit.Exp4R" , "HBandit.EpsGreedy" , "HBandit.Util" , "HBandit.Types" diff --git a/dev/default.nix b/dev/default.nix index 6fd22b85baeea36e95f3d38d1a572afbac389860..bf6697db8c7f19abd7f83466db818c30c67ee6e9 100644 --- a/dev/default.nix +++ b/dev/default.nix @@ -103,8 +103,22 @@ pkgs // rec { propagatedBuildInputs = (pkgs.lib.lists.remove haskellPackages.nrmbin o.propagatedBuildInputs); buildInputs = with python37Packages; - (pkgs.lib.lists.remove haskellPackages.nrmbin o.buildInputs) - ++ [ flake8 autopep8 black mypy pytype nbformat nbconvert nb_black ]; + (pkgs.lib.lists.remove haskellPackages.nrmbin o.buildInputs) ++ [ + flake8 + autopep8 + black + mypy + pytype + nbformat + nbconvert + pandas + matplotlib + nb_black + msgpack + pyzmq + warlock + seaborn + ]; shellHook = '' export LOCALE_ARCHIVE=${pkgs.glibcLocales}/lib/locale/locale-archive @@ -116,17 +130,9 @@ pkgs // rec { (o: { buildInputs = o.buildInputs ++ [ pkgs.clang-tools ]; }); jupyterWithBatteries = (pkgs.jupyter.override rec { - python3 = (python37Packages.python.withPackages (ps: - with ps; [ - nb_black - msgpack - warlock - pyzmq - pandas - seaborn - ])); + python3 = (python37Packages.python.withPackages + (ps: with ps; [ nb_black msgpack warlock pyzmq pandas seaborn ])); definitions = { - # This is the Python kernel we have defined above. python3 = { displayName = "Python 3"; argv = [ @@ -140,6 +146,36 @@ pkgs // rec { logo32 = "${python3.sitePackages}/ipykernel/resources/logo-32x32.png"; logo64 = "${python3.sitePackages}/ipykernel/resources/logo-64x64.png"; }; + Rdf = { + displayName = "R"; + argv = [ + "${ + pkgs.rWrapper.override { + packages = with pkgs.rPackages; [ + tidyr + purrr + ggthemes + ggplot2 + latex2exp + plotly + phantomjs + webshot + pracma + knitr + JuniperKernel + ]; + } + }/bin/R" + "--slave" + "-e" + "JuniperKernel::bootKernel()" + "--args" + "{connection_file}" + ]; + language = "Rlang"; + logo32 = "${python3.sitePackages}/ipykernel/resources/logo-32x32.png"; + logo64 = "${python3.sitePackages}/ipykernel/resources/logo-64x64.png"; + }; }; }).overrideAttrs (_: { doCheck = false; }); @@ -156,20 +192,13 @@ pkgs // rec { src = patchedSrc (src + "/hsnrm") cabalFileLib; extraCabal2nixOptions = "--extra-arguments src"; }); - NIXFILE_BIN = (haskellPackages.haskellSrc2nix { name = "hsnrm"; src = patchedSrc (src + "/hsnrm") cabalFileBin; extraCabal2nixOptions = "--extra-arguments src"; }); inputsFrom = with pkgs; [ pynrm-hack hsnrm-hack libnrm-hack ]; - buildInputs = [ - pkgs.hwloc - ormolu - haskellPackages.dhrun - jupyterWithBatteries - pkgs.daemonize - ]; + buildInputs = [ pkgs.hwloc haskellPackages.dhrun ]; shellHook = '' # path for NRM dev experimentation export PYNRMSO=${ @@ -184,7 +213,6 @@ pkgs // rec { builtins.toPath ../. }/.build/build/x86_64-linux/ghc-8.6.5/hsnrm-1.0.0/x/nrm/build/nrm:$PATH export PYTHONPATH=${builtins.toPath ../.}/pynrm/:$PYTHONPATH - export JUPYTER_PATH=$JUPYTER_PATH:${builtins.toPath ../.}/pynrm/ # exports for `ghcide` use export NIX_GHC="${haskellPackages.nrmlib.env.NIX_GHC}" export NIX_GHCPKG="${haskellPackages.nrmlib.env.NIX_GHCPKG}" @@ -203,6 +231,37 @@ pkgs // rec { LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive"; }; + hack-with-devtools = + hack.overrideAttrs (o: { buildInputs = o.buildInputs ++ [ ormolu ]; }); + + expe = hack-with-devtools.overrideAttrs (o: { + buildInputs = o.buildInputs ++ [ + pkgs.phantomjs + pkgs.pandoc + pkgs.daemonize + jupyterWithBatteries + pkgs.texlive.combined.scheme-full + (pkgs.rstudioWrapper.override { + packages = with pkgs.rPackages; [ + tidyr + purrr + ggthemes + ggplot2 + latex2exp + plotly + phantomjs + webshot + pracma + knitr + JuniperKernel + ]; + }) + ]; + shellHook = o.shellHook + '' + export JUPYTER_PATH=$JUPYTER_PATH:${builtins.toPath ../.}/pynrm/ + ''; + }); + dhrun = haskellPackages.dhrun.overrideAttrs (old: { installPhase = old.installPhase + '' mkdir -p $out/share/ @@ -245,16 +304,15 @@ pkgs // rec { ''; }); - stream-raw = callPackage ./pkgs/stream { - iterationCount = "2000"; + stream = callPackage ./pkgs/stream { + iterationCount = "400"; inherit libnrm; nrmSupport = false; }; - stream = callPackage ./pkgs/stream { - iterationCount = "2000"; + amg = callPackage ./pkgs/amg { inherit libnrm; - nrmSupport = true; + nrmSupport = false; }; testGeneric = doDhrun genericTestName; diff --git a/dev/dhrun/all-tests.dh b/dev/dhrun/all-tests.dh index cccbd98ce4aa48ebf0b93a91846cb605770e5136..4881ffb4246ebc04e211430de6fa3afad25e31b5 100644 --- a/dev/dhrun/all-tests.dh +++ b/dev/dhrun/all-tests.dh @@ -109,12 +109,12 @@ , errfile = "nrmlisten.err" } - ⫽ { args = [ "listen", "-u", cn ] } + ⫽ { args = [ "listen-cpd", "-u" ] } ] , power = lib.appTest daemonCfg - ( lib.emptyFilterTestArgs "power" "sleep" + ( lib.emptyFilterTestArgs "sleep" ⫽ { timeout = [ +600 ] : Optional Integer , args = @@ -126,7 +126,7 @@ , performance = lib.appTest daemonCfg - ( lib.emptyFilterTestArgs "performance" "sleep" + ( lib.emptyFilterTestArgs "sleep" ⫽ { timeout = [ +600 ] : Optional Integer , args = diff --git a/dev/dhrun/lib.dh b/dev/dhrun/lib.dh index 30587477533794529b7480e8dda3c92200e7ff65..913ddccff371027b000e457f23670b05f1b286dc 100644 --- a/dev/dhrun/lib.dh +++ b/dev/dhrun/lib.dh @@ -165,6 +165,7 @@ let values = ./dhrun/values.dhall , "-s" , args.containerName , "--manifest=" ++ args.manifest + , "--" , args.cmd ] # args.args @@ -203,8 +204,6 @@ let values = ./dhrun/values.dhall let FilterTestArgs = { manifestname : Text - , filter : - Text , cmd : Text , args : @@ -224,14 +223,11 @@ let values = ./dhrun/values.dhall } let emptyFilterTestArgs = - λ(filter : Text) - → λ(cmd : Text) + λ(cmd : Text) → { cmd = cmd , manifestname = "perfwrap.dhall" - , filter = - filter , args = [] : List Text , vars = @@ -261,7 +257,7 @@ let values = ./dhrun/values.dhall then args.manifestname - else "parallel.dhall" + else "perfwrap.dhall" ) , daemonCfg = daemonCfg @@ -303,18 +299,13 @@ let values = ./dhrun/values.dhall } in b - ⫽ { args = - [ "listen", "-s", cn, "--filter", args.filter ] + ⫽ { name = "nrm" , args = + [ "listen-cpd", "-j"] , postchecks = [ { filename = "nrmlisten.out" , filecheck = - { wants = - if args.isTest - - then [ args.filter ] - - else [] : List Text + { wants = [] : List Text , avoids = [] : List Text } @@ -370,7 +361,7 @@ let values = ./dhrun/values.dhall → λ(args : ProgressAppTestArg) → appTest daemonCfg - ( emptyFilterTestArgs "progress" args.cmd + ( emptyFilterTestArgs args.cmd ⫽ { args = args.args , manifestname = @@ -392,23 +383,20 @@ let values = ./dhrun/values.dhall let mkListen = λ(cn : Text) - → λ(filter : Text) → let b = values.emptyCmd { name = "nrm" , outfile = - filter ++ ".out" + "listen-" ++ cn ++ ".out" , errfile = - filter ++ ".err" + "listen-" ++ cn ++ ".err" } - in b ⫽ { args = [ "listen", "-s", cn, "--filter", filter ] } + in b ⫽ { name ="nrm", args = [ "listen-cpd", "-j" ] } let powerexpeCmds = - [ mkListen "testContainer" "power" - , mkListen "testContainer" "performance" - , mkListen "testContainer" "control" + [ mkListen "testContainer" ] : List types.Cmd diff --git a/dev/haskell-overlay.nix b/dev/haskell-overlay.nix index 15af917f7e3de280b78186f32a1939f24dfac80a..ffaa93ff274e8613648599a5a46b335b33bb0594 100644 --- a/dev/haskell-overlay.nix +++ b/dev/haskell-overlay.nix @@ -17,24 +17,23 @@ let cp ${./pkgs/hnrm/lib.cabal} hsnrm.cabal '' + o.configurePhase; }); + nrmbin = (self.callPackage (./pkgs/hnrm/bin.nix) { src = src + "/hsnrm"; }).overrideAttrs (o: { + doHoogle = false; configurePhase = '' cp ${./pkgs/hnrm/bin.cabal} hsnrm.cabal '' + o.configurePhase; }); - #nrmbin = (self.callCabal2nix "hsnrm.cabal" patchedSrcBin { - #inherit nrmlib; - #}).overrideAttrs - #(o: { nativeBuildInputs = o.nativeBuildInputs ++ [ pkgs.glpk ]; }); + dhall = super.dhall_1_24_0; dhall-json = (self.callCabal2nix "dhall-json" (src + "/hsnrm/dhall-haskell/dhall-json") { }).overrideAttrs (o: { doCheck = false; }); dhrun = ((self.callCabal2nix "dhrun" (builtins.fetchGit { inherit (pkgs.stdenv.lib.importJSON ./pkgs/dhrun/pin.json) url rev; - })) { }).overrideAttrs (_:{doCheck = false;}); + })) { }).overrideAttrs (_: { doCheck = false; }); }; in { haskellPackages = pkgs.haskellPackages.override { inherit overrides; }; } diff --git a/dev/hnrm-experiments b/dev/hnrm-experiments new file mode 160000 index 0000000000000000000000000000000000000000..0045b74ad5b26fe8e74067a1ffc625e0d50d0d32 --- /dev/null +++ b/dev/hnrm-experiments @@ -0,0 +1 @@ +Subproject commit 0045b74ad5b26fe8e74067a1ffc625e0d50d0d32 diff --git a/dev/pkgs/amg/default.nix b/dev/pkgs/amg/default.nix new file mode 100644 index 0000000000000000000000000000000000000000..5e5a93c7fbd1ddf1b9efd1b9c639f6066f395fe4 --- /dev/null +++ b/dev/pkgs/amg/default.nix @@ -0,0 +1,20 @@ +{ stdenv, fetchgit, mpich2, nix-update-source +, libnrm +, nrmSupport ? false +}: + +let + inherit (stdenv.lib) optional; +in +stdenv.mkDerivation { + src = if nrmSupport then + (nix-update-source.fetch ./nrm.json).src + else + (nix-update-source.fetch ./raw.json).src; + name = "AMG"; + buildInputs = [mpich2] ++ (optional nrmSupport libnrm); + installPhase = '' + mkdir -p $out/bin + cp test/amg $out/bin + ''; +} diff --git a/dev/pkgs/amg/nrm.json b/dev/pkgs/amg/nrm.json new file mode 100644 index 0000000000000000000000000000000000000000..cb82e8911afc64ed21ad57797262ca7254241f32 --- /dev/null +++ b/dev/pkgs/amg/nrm.json @@ -0,0 +1,14 @@ +{ + "fetch": { + "args": { + "fetchSubmodules": false, + "rev": "359d46107ca53f7d8bfe8187f6c081d815ac864d", + "sha256": "19lqzj2fs5wqj7fh6fx96q6r49icq7l0q7qr388j3bh56nw52blf", + "url": "https://xgitlab.cels.anl.gov/argo/applications/amg.git" + }, + "fn": "fetchgit" + }, + "rev": "refs/heads/progress-nrm", + "type": "fetchgit", + "url": "https://xgitlab.cels.anl.gov/argo/applications/amg.git" +} \ No newline at end of file diff --git a/dev/pkgs/amg/raw.json b/dev/pkgs/amg/raw.json new file mode 100644 index 0000000000000000000000000000000000000000..a9910c31ecc73ab537df62916c4928ab3fb51b38 --- /dev/null +++ b/dev/pkgs/amg/raw.json @@ -0,0 +1,14 @@ +{ + "fetch": { + "args": { + "fetchSubmodules": false, + "rev": "09fe8a78baf6ba5eaef7d2804f7b653885d60fee", + "sha256": "1iqdbkg4dm36qskbyfi30w6rw70g2r6mi0qhzavc21338bf4j9hy", + "url": "https://xgitlab.cels.anl.gov/argo/applications/amg.git" + }, + "fn": "fetchgit" + }, + "rev": "refs/heads/master", + "type": "fetchgit", + "url": "https://xgitlab.cels.anl.gov/argo/applications/amg.git" +} \ No newline at end of file diff --git a/dev/pkgs/hnrm/lib.cabal b/dev/pkgs/hnrm/lib.cabal index b04001efe0d242de604a98a9032303425691d31a..2183e04f5aee8f1d58b2b0a8b890fdf123d93e30 100644 --- a/dev/pkgs/hnrm/lib.cabal +++ b/dev/pkgs/hnrm/lib.cabal @@ -130,6 +130,7 @@ library Algebra.Classes HBandit.Class HBandit.Exp3 + HBandit.Exp4R HBandit.EpsGreedy HBandit.Util HBandit.Types diff --git a/dev/pkgs/hs-tools/default.nix b/dev/pkgs/hs-tools/default.nix index ca1dc853744a6dbb8a7a924d575576406db5262a..02a0c5cc41889ef024366a3a80c2a15a05e0ddb5 100644 --- a/dev/pkgs/hs-tools/default.nix +++ b/dev/pkgs/hs-tools/default.nix @@ -1,26 +1,21 @@ -{ haskell, lib, mkDerivation, stdenv, cabal-install, apply-refact, cabal2nix, - wreq, hdevtools, Glob, hindent, fswatch, hlint, protolude, shake, Cabal -, fix-imports, ghcid, typed-process, optparse-applicative, unix, cabal-helper -, dhall-json, dhall-to-cabal, useGhcide }: +{ haskell, lib, mkDerivation, stdenv, cabal-install, apply-refact, cabal2nix +, wreq, hdevtools, Glob, hindent, fswatch, hlint, protolude, shake, Cabal +, graphmod, fix-imports, ghcid, typed-process, optparse-applicative, unix +, cabal-helper, dhall-json, dhall-to-cabal, useGhcide }: let ghcide = (import (builtins.fetchTarball - "https://github.com/hercules-ci/ghcide-nix/tarball/master") - { }).ghcide-ghc865; + "https://github.com/cachix/ghcide-nix/tarball/master") { }).ghcide-ghc865; in mkDerivation { pname = "dummy"; version = ""; src = ""; libraryHaskellDepends = [ cabal-install - #apply-refact + graphmod hdevtools - #zmcat dhall-to-cabal - #hindent wreq - #fswatch hlint - #protolude fix-imports optparse-applicative shake @@ -29,8 +24,6 @@ in mkDerivation { ghcid dhall-json cabal2nix - #typed-process - #unix ] ++ (lib.optional useGhcide ghcide); #ghcide; description = ""; diff --git a/dev/shake.hs b/dev/shake.hs index c9708d709d57e393925a5ac1cb801a4546e00db0..c0f3b0f087db84b0103f9505f83f9dd3fe2723c3 100644 --- a/dev/shake.hs +++ b/dev/shake.hs @@ -126,9 +126,10 @@ cabalstatic = runProcess_ $ shell "dhall-to-cabal ./dev/pkgs/hsnrm/static.dhall notebooks = do runProcess_ $ shell "notebooks/batchnb.py notebooks/configuration.ipynb" - runProcess_ $ shell "cp notebooks/tutorial.ipynb doc/notebooks/notebooks/" runProcess_ $ shell "jupyter nbconvert doc/notebooks/notebooks/configuration.ipynb --output-dir=doc/notebooks/notebooks" - runProcess_ $ shell "jupyter nbconvert doc/notebooks/notebooks/tutorial.ipynb --output-dir=doc/notebooks/notebooks" + runProcess_ $ shell "rm doc/notebooks/notebooks/configuration.ipynb" + runProcess_ $ shell "jupyter nbconvert notebooks/tutorial.ipynb --output-dir=doc/notebooks/notebooks" + runProcess_ $ shell "jupyter nbconvert notebooks/internal-control.ipynb --output-dir=doc/notebooks/notebooks" runshake as = withArgs as $ shakeArgs shakeOptions $ do @@ -194,7 +195,6 @@ runshake as = "cabal" [ "v2-haddock", "nrm.so", - "--haddock-hyperlink-source", "--haddock-internal", "--builddir=../.build", "--haddock-html-location=\"https://hackage.haskell.org/package/\\$pkg-\\$version/docs\"" diff --git a/doc/notebooks/notebooks/configuration.html b/doc/notebooks/notebooks/configuration.html index 4dc74369c83738fa4707dc4cb1963e5762955509..5bbc845a39c5c13e5fc2d691d6243725a25453c1 100644 --- a/doc/notebooks/notebooks/configuration.html +++ b/doc/notebooks/notebooks/configuration.html @@ -13143,6 +13143,7 @@ div#notebook {
%load_ext nb_black
 import json
 import pprint
+
 pp = pprint.PrettyPrinter(indent=4)
 
@@ -13162,14 +13163,14 @@ div#notebook { -
+
-
- - - - - - - -
-
-
In [ ]:
-
-
-
 
-
- -
-
-
- -
-
-
-
In [ ]:
-
-
-
 
-
- -
-
-
-
diff --git a/doc/notebooks/notebooks/configuration.ipynb b/doc/notebooks/notebooks/configuration.ipynb deleted file mode 100644 index 8832e1f5909e8451cbdc07011bd85a3522e8b161..0000000000000000000000000000000000000000 --- a/doc/notebooks/notebooks/configuration.ipynb +++ /dev/null @@ -1,666 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# NRM Configuration/Manifest guide\n", - "\n", - "This notebook documents NRM's configuration and manifest format. The two next cells are for setup purposes." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "%%capture\n", - "cd .." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 2;\n", - " var nbb_unformatted_code = \"%load_ext nb_black\\nimport json\\nimport pprint\\npp = pprint.PrettyPrinter(indent=4)\";\n", - " var nbb_formatted_code = \"%load_ext nb_black\\nimport json\\nimport pprint\\n\\npp = pprint.PrettyPrinter(indent=4)\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%load_ext nb_black\n", - "import json\n", - "import pprint\n", - "pp = pprint.PrettyPrinter(indent=4)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Daemon configuration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`nrmd`'s configuration can be defined in the json/yaml/[Dhall](https://dhall-lang.org/) formats. Admissible values are defined in file [resources/configurationSchema.json](./resources/configurationSchema.json), and alternatively available as a Dhall type in [resources/types/Cfg.dhall](resources/types/Configuration.dhall). Schema files get large, so the next cells shows the Dhall Configuration type as a more readable alternative." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{ argo_nodeos_config =\n", - " \"argo_nodeos_config\"\n", - ", argo_perf_wrapper =\n", - " \"nrm-perfwrapper\"\n", - ", controlCfg =\n", - " None\n", - " { learnCfg :\n", - " < KnapsackConstraints :\n", - " { _1 : { _1 : Double } }\n", - " | LagrangeConstraints :\n", - " { _1 : { _1 : Double } }\n", - " >\n", - " , minimumControlInterval :\n", - " { fromuS : Double }\n", - " , referenceMeasurementRoundInterval :\n", - " Integer\n", - " , speedThreshold :\n", - " Double\n", - " }\n", - ", downstreamCfg =\n", - " { downstreamBindAddress = \"ipc:///tmp/nrm-downstream-event\" }\n", - ", dummy =\n", - " True\n", - ", hwloc =\n", - " \"hwloc\"\n", - ", hwmonCfg =\n", - " { hwmonEnabled = True, hwmonPath = \"/sys/class/hwmon\" }\n", - ", libnrmPath =\n", - " None Text\n", - ", logfile =\n", - " \"/tmp/nrm.log\"\n", - ", nodeos =\n", - " False\n", - ", perf =\n", - " \"perf\"\n", - ", pmpi_lib =\n", - " \"pmpi_lib\"\n", - ", raplCfg =\n", - " Some\n", - " { raplFrequency =\n", - " { fromHz = 1.0 }\n", - " , raplPath =\n", - " \"/sys/devices/virtual/powercap/intel-rapl\"\n", - " }\n", - ", singularity =\n", - " False\n", - ", slice_runtime =\n", - " < Dummy | Nodeos | Singularity >.Dummy\n", - ", upstreamCfg =\n", - " { pubPort = +2345, rpcPort = +3456, upstreamBindAddress = \"*\" }\n", - ", verbose =\n", - " < Debug | Error | Info >.Error\n", - "}\n" - ] - }, - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 3;\n", - " var nbb_unformatted_code = \"%%script dhall resolve\\n./resources/defaults/Cfg.dhall\";\n", - " var nbb_formatted_code = \"%%script dhall resolve\\n./resources/defaults/Cfg.dhall\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%script dhall resolve\n", - "./resources/defaults/Cfg.dhall" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Optional values are filled using defaults that can be found in [resources/defaults/Cfg.json](resources/defaults/Configuration.json) (also available in the Dhall format):" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"pmpi_lib\": \"pmpi_lib\",\n", - " \"verbose\": \"Error\",\n", - " \"logfile\": \"/tmp/nrm.log\",\n", - " \"singularity\": false,\n", - " \"argo_nodeos_config\": \"argo_nodeos_config\",\n", - " \"controlCfg\": null,\n", - " \"upstreamCfg\": {\n", - " \"upstreamBindAddress\": \"*\",\n", - " \"rpcPort\": 3456,\n", - " \"pubPort\": 2345\n", - " },\n", - " \"libnrmPath\": null,\n", - " \"perf\": \"perf\",\n", - " \"argo_perf_wrapper\": \"nrm-perfwrapper\",\n", - " \"downstreamCfg\": {\n", - " \"downstreamBindAddress\": \"ipc:///tmp/nrm-downstream-event\"\n", - " },\n", - " \"nodeos\": false,\n", - " \"hwloc\": \"hwloc\",\n", - " \"raplCfg\": {\n", - " \"raplFrequency\": {\n", - " \"fromHz\": 1\n", - " },\n", - " \"raplPath\": \"/sys/devices/virtual/powercap/intel-rapl\"\n", - " },\n", - " \"dummy\": true,\n", - " \"slice_runtime\": \"Dummy\",\n", - " \"hwmonCfg\": {\n", - " \"hwmonPath\": \"/sys/class/hwmon\",\n", - " \"hwmonEnabled\": true\n", - " }\n", - "}\n" - ] - }, - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 4;\n", - " var nbb_unformatted_code = \"%%bash\\ncat ./resources/defaults/Cfg.json | jq\";\n", - " var nbb_formatted_code = \"%%bash\\ncat ./resources/defaults/Cfg.json | jq\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%bash\n", - "cat ./resources/defaults/Cfg.json | jq" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Manifest configuration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Example manifest files are in [resources/examples](../resources/examples) in JSON/YAML/Dhall format. For instance, the manifest file [resources/examples/perfwrap.json](../resources/examples/perfwrap.json) enables enables performance monitoring:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"image\": null,\n", - " \"hwbind\": false,\n", - " \"app\": {\n", - " \"scheduler\": \"FIFO\",\n", - " \"instrumentation\": null,\n", - " \"power\": {\n", - " \"slowdown\": 1,\n", - " \"profile\": false,\n", - " \"policy\": \"NoPowerPolicy\"\n", - " },\n", - " \"perfwrapper\": {\n", - " \"perfLimit\": {\n", - " \"fromOps\": 100000\n", - " },\n", - " \"perfFreq\": {\n", - " \"fromHz\": 1\n", - " }\n", - " },\n", - " \"slice\": {\n", - " \"cpus\": 1,\n", - " \"mems\": 1\n", - " }\n", - " },\n", - " \"name\": \"default\"\n", - "}\n" - ] - }, - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 5;\n", - " var nbb_unformatted_code = \"%%bash\\ncat resources/examples/perfwrap.json | jq\";\n", - " var nbb_formatted_code = \"%%bash\\ncat resources/examples/perfwrap.json | jq\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%bash\n", - "cat resources/examples/perfwrap.json | jq" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Manifest options are documented in schema file [resources/manifestSchema.json](../resources/manifestSchema.json). The next cell shows the corresponding [Dhall](https://dhall-lang.org/) type." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{ app :\n", - " { instrumentation :\n", - " Optional { ratelimit : { fromHz : Double } }\n", - " , perfwrapper :\n", - " < Perfwrapper :\n", - " { perfFreq :\n", - " { fromHz : Double }\n", - " , perfLimit :\n", - " { fromOps : Integer }\n", - " }\n", - " | PerfwrapperDisabled\n", - " >\n", - " , power :\n", - " { policy :\n", - " < Combined | DDCM | DVFS | NoPowerPolicy >\n", - " , profile :\n", - " Bool\n", - " , slowdown :\n", - " Integer\n", - " }\n", - " , scheduler :\n", - " < FIFO | HPC | Other : { _1 : Integer } >\n", - " , slice :\n", - " { cpus : Integer, mems : Integer }\n", - " }\n", - ", hwbind :\n", - " Bool\n", - ", image :\n", - " Optional\n", - " { binds : Optional (List Text), imagetype : < Docker | Sif >, path : Text }\n", - ", name :\n", - " Text\n", - "}\n" - ] - }, - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 6;\n", - " var nbb_unformatted_code = \"%%script dhall resolve\\n./resources/types/Manifest.dhall\";\n", - " var nbb_formatted_code = \"%%script dhall resolve\\n./resources/types/Manifest.dhall\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%script dhall resolve\n", - "./resources/types/Manifest.dhall" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Under-specified manifests like the one in our `workloads` above (with missing optional fields from the schema) fill missing values with defaults, which are located in file [resources/defaults/Manifest.json](../../resources/examples/default.json):" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"image\": null,\n", - " \"hwbind\": false,\n", - " \"app\": {\n", - " \"scheduler\": \"FIFO\",\n", - " \"instrumentation\": null,\n", - " \"power\": {\n", - " \"slowdown\": 1,\n", - " \"profile\": false,\n", - " \"policy\": \"NoPowerPolicy\"\n", - " },\n", - " \"perfwrapper\": \"PerfwrapperDisabled\",\n", - " \"slice\": {\n", - " \"cpus\": 1,\n", - " \"mems\": 1\n", - " }\n", - " },\n", - " \"name\": \"default\"\n", - "}\n" - ] - }, - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 7;\n", - " var nbb_unformatted_code = \"%%bash\\ncat resources/defaults/Manifest.json | jq\";\n", - " var nbb_formatted_code = \"%%bash\\ncat resources/defaults/Manifest.json | jq\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%bash\n", - "cat resources/defaults/Manifest.json | jq" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `dhall` and `dhall-to-json` utilities are available as convenience in this environment should you need them. Dhall is useful as a configuration language in itself:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"image\": null,\n", - " \"hwbind\": false,\n", - " \"app\": {\n", - " \"scheduler\": \"FIFO\",\n", - " \"instrumentation\": null,\n", - " \"power\": {\n", - " \"slowdown\": 1,\n", - " \"profile\": false,\n", - " \"policy\": \"NoPowerPolicy\"\n", - " },\n", - " \"perfwrapper\": \"PerfwrapperDisabled\",\n", - " \"slice\": {\n", - " \"cpus\": 1,\n", - " \"mems\": 1\n", - " }\n", - " },\n", - " \"name\": \"default-appended\"\n", - "}\n" - ] - }, - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 8;\n", - " var nbb_unformatted_code = \"%%script bash\\ndhall-to-json <<< 'let Manifest = ./resources/types/Manifest.dhall \\n let appendName = \\\\(m: Manifest) -> m // {name = m.name ++ \\\"-appended\\\" }\\n in appendName ./resources/defaults/Manifest.dhall\\n' | jq\";\n", - " var nbb_formatted_code = \"%%script bash\\ndhall-to-json <<< 'let Manifest = ./resources/types/Manifest.dhall \\n let appendName = \\\\(m: Manifest) -> m // {name = m.name ++ \\\"-appended\\\" }\\n in appendName ./resources/defaults/Manifest.dhall\\n' | jq\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%script bash\n", - "dhall-to-json <<< 'let Manifest = ./resources/types/Manifest.dhall \n", - " let appendName = \\(m: Manifest) -> m // {name = m.name ++ \"-appended\" }\n", - " in appendName ./resources/defaults/Manifest.dhall\n", - "' | jq" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Remember that any json document is one little step away from being a Python dictionaryy:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{ 'app': { 'instrumentation': None,\n", - " 'perfwrapper': { 'perfFreq': {'fromHz': 1},\n", - " 'perfLimit': {'fromOps': 100000}},\n", - " 'power': { 'policy': 'NoPowerPolicy',\n", - " 'profile': False,\n", - " 'slowdown': 1},\n", - " 'scheduler': 'FIFO',\n", - " 'slice': {'cpus': 1, 'mems': 1}},\n", - " 'hwbind': False,\n", - " 'image': None,\n", - " 'name': 'default'}\n" - ] - }, - { - "data": { - "application/javascript": [ - "\n", - " setTimeout(function() {\n", - " var nbb_cell_id = 9;\n", - " var nbb_unformatted_code = \"with open(\\\"resources/examples/perfwrap.json\\\") as f:\\n pp.pprint(json.load(f))\";\n", - " var nbb_formatted_code = \"with open(\\\"resources/examples/perfwrap.json\\\") as f:\\n pp.pprint(json.load(f))\";\n", - " var nbb_cells = Jupyter.notebook.get_cells();\n", - " for (var i = 0; i < nbb_cells.length; ++i) {\n", - " if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n", - " if (nbb_cells[i].get_text() == nbb_unformatted_code) {\n", - " nbb_cells[i].set_text(nbb_formatted_code);\n", - " }\n", - " break;\n", - " }\n", - " }\n", - " }, 500);\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "with open(\"resources/examples/perfwrap.json\") as f:\n", - " pp.pprint(json.load(f))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python3 - Nix", - "language": "python", - "name": "ipython_nix" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.4" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/doc/notebooks/notebooks/internal-control.html b/doc/notebooks/notebooks/internal-control.html new file mode 100644 index 0000000000000000000000000000000000000000..454084945ed512668addc86fc6e14092d4880f77 --- /dev/null +++ b/doc/notebooks/notebooks/internal-control.html @@ -0,0 +1,14297 @@ + + + + +internal-control + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+

Internal control experiments

This notebooks runs NRM with internal bandit NRM control enabled.

+ +
+
+
+
+
+
+

For the application of the NRM model to resource management to one +computational job, the global resource optimization problem is the following:

+$$ +\begin{array}{l} + \min \quad e_{\text{total}} \\ + \text{s.t.} \quad t > \tau t_{\text{ref}} +\end{array} +$$

Where $e_{\text{total}}$ denotes the total energy spent by the system during +the lifetime of the job, whose duration is denoted by $t^T$. We denote by +$t_{\text{ref}}$ a reference measurement of the runtime of the job on an +unmanaged system. $\tau <1$ is a parameter controlling the amount of runtime +degradation allowed for the job.

+

The value of this global objective can be easily measured a-posteriori for a +computational job using power instrumentation techniques. Assuming both +workload and platform behavior to be deterministic, this objective is measured +using two runs of the system: A first run without resource management to +acquire $t_{\text{ref}}$, and one run with NRM enabled. In order for NRM's +round-based control strategy to address this problem, we need an online loss +value however. This loss is obtained using the following loose assumptions:

+
    +
  • The passive power consumption of the node is fixed and known. [1]

    +
  • +
  • The total power consumption in a given time period can be estimated as +the sum of the static node consumption over that period and the RAPL power +measurement over that period. [2]

    +
  • +
  • The impact of a choice of power-cap on the job's runtime can be +interpolated linearly from its impact on CPU counters. [3]

    +
  • +
+

Denoting as in the previous section the round counter by $0<r<T$, the known +passive static power consumption by $p_{\text{static}}$, the starting time of +the job by $t^0$ and the end time of round $r$ by $t^r$, we can write the total +energy expenditure of the job based on RAPL power measurements $p^r$ using +assumptions 1 and 2 as:

+$$ + e_{\text{total}} = \sum_{r=1}^{r=T} (p^r + p_{\text{static}}) (t^{r-1} - t^{r}) +$$

Using assumption 3 means that we can reasonably estimate the +change in job runtime incurred by the choice of power-cap in round $r$ by +evaluating $\frac{s^r_{\text{ref}}}{s^r}$. We use this as part of our proxy +cost in two ways. First, this quantity is used to evaluate breaching of the +constraint on $t$, and second, it is used to adjust for an expected increase in +the number of rounds due to the impact on job runtime. This gives rise to the +following value for the loss at round $r$:

+$$ + \ell^r = \mathbb{\huge 1}_{\left( \frac{s^r}{s^r_{\text{ref}}}>\tau \right)} + \left( \frac{s^r_{\text{ref}}}{s^r} \left( p^r + p_{\text{static}} \right) \right) +$$ +
+
+
+
+
+
In [1]:
+
+
+
cd ..
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
/home/fre/workspace/hnrm
+
+
+
+ +
+
+ +
+
+
+
In [2]:
+
+
+
%%capture
+%%bash
+./shake.sh build # Zfor the daemon 
+./shake.sh client # for the upstream client
+./shake.sh pyclient # for the shared client library
+
+ +
+
+
+ +
+
+
+
In [3]:
+
+
+
%load_ext nb_black
+import json
+
+daemonCfgs = {}
+
+
+for cap in [100, 150, 200]:
+    daemonCfgs["pcap" + str(cap)] = {
+        "controlCfg": {"fixedPower": {"fromuW": cap * 1000000}}
+    }
+daemonCfgs["controlOn"] = {
+    "controlCfg": {
+        "staticPower": {"fromuW": 200000000},
+        "referenceMeasurementRoundInterval": 10,
+        "learnCfg": {"lagrangeConstraint": 1},
+        "speedThreshold": 0.9,
+        "minimumControlInterval": {"fromuS": 1000000},
+    },
+    "verbose": "Debug",
+}
+
+
+def perfwrapped(cmd, args):
+    return [
+        {
+            "cmd": cmd,
+            "args": args,
+            "sliceID": "toto",
+            "manifest": {
+                "app": {
+                    "slice": {"cpus": 1, "mems": 1},
+                    "perfwrapper": {
+                        "perfLimit": {"fromOps": 100000},
+                        "perfFreq": {"fromHz": 1},
+                    },
+                },
+                "name": "perfwrap",
+            },
+        }
+    ]
+
+
+stream = perfwrapped("stream_c", [])
+lammps = perfwrapped(
+    "mpiexec",
+    ["-n", "24", "amg", "-problem", "2", "-n", "90", "90", "90", "-P", "2", "12", "1"],
+)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
In [4]:
+
+
+
import nrm.tooling as nrm
+
+host = nrm.Local()
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
In [5]:
+
+
+
host.start_daemon(daemonCfgs["pcap100"])
+# assert host.check_daemon()
+print(host.get_cpd())
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
connecting
+connected to tcp://localhost:2345
+Problem 
+    { sensors = Map 
+        [ 
+            ( SensorID { sensorID = "RaplKey (PackageID 0)" }
+            , Sensor 
+                { range = 0.0 ... 300.0
+                , maxFrequency = 3.0
+                } 
+            ) 
+        ]
+    , actuators = Map 
+        [ 
+            ( ActuatorID { actuatorID = "RaplKey (PackageID 0)" }
+            , Actuator 
+                { actions = 
+                    [ DiscreteDouble 100.0
+                    , DiscreteDouble 200.0
+                    ] 
+                }
+            ) 
+        ]
+    , objectives = []
+    , constraints = []
+    } 
+
+
+
+ +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
+

The next cell just stops the daemon cleanly.

+ +
+
+
+
+
+
In [6]:
+
+
+
host.stop_daemon()
+assert host.check_daemon() == False
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
+

Helpers

For performing experiments:

+ +
+
+
+
+
+
In [7]:
+
+
+
import time
+from collections import defaultdict
+
+
+def do_workload(host, daemonCfg, workload):
+    host.start_daemon(daemonCfg)
+    print("Starting the workload")
+    host.run_workload(workload)
+    history = defaultdict(list)
+    # print(host.get_state())
+    getCPD = True
+    try:
+        while host.check_daemon() and not host.workload_finished():
+            measurement_message = host.workload_recv()
+            msg = json.loads(measurement_message)
+            if "pubMeasurements" in msg:
+                if getCPD:
+                    getCPD = False
+                    time.sleep(3)
+                    cpd = host.get_cpd()
+                    print(cpd)
+                    cpd = dict(cpd)
+                    print("Sensor identifier list:")
+                    for sensorID in [sensor[0] for sensor in cpd["sensors"]]:
+                        print("- %s" % sensorID)
+                    print("Actuator identifier list:")
+                    for sensorID in [sensor[0] for sensor in cpd["actuators"]]:
+                        print("- %s" % sensorID)
+                content = msg["pubMeasurements"][1][0]
+                t = content["time"]
+                sensorID = content["sensorID"]
+                x = content["sensorValue"]
+                print(
+                    ".",
+                    end=""
+                    # "Measurement: originating at time %s for sensor %s of value %s"
+                    #% (content["time"], content["sensorID"], content["sensorValue"])
+                )
+                history["sensor-" + sensorID].append((t, x))
+            if "pubCPD" in msg:
+                print("R")
+            if "pubAction" in msg:
+                # print(host.get_state())
+                # print(msg)
+                t, contents, meta, controller = msg["pubAction"]
+                if "bandit" in controller.keys():
+                    for key in meta.keys():
+                        history["actionType"].append((t, key))
+                    if "referenceMeasurementDecision" in meta.keys():
+                        print("(ref)", end="")
+                    elif "initialDecision" in meta.keys():
+                        print("(init)", end="")
+                    elif "innerDecision" in meta.keys():
+                        print("(inner)", end="")
+                        counter = 0
+                        for value in meta["innerDecision"]["constraints"]:
+                            history["constraint-" + str(counter)].append(
+                                (t, value["fromConstraintValue"])
+                            )
+                            counter = counter + 1
+                        counter = 0
+                        for value in meta["innerDecision"]["objectives"]:
+                            history["objective-" + str(counter)].append(
+                                (t, value["fromObjectiveValue"])
+                            )
+                            counter = counter + 1
+                        history["loss"].append((t, meta["innerDecision"]["loss"]))
+                for (arm, (visits, stat)) in controller["armstats"]:
+                    history["armstat-" + str(arm)].append((t, stat))
+                    history["visits-" + str(arm)].append((t, visits))
+                for content in contents:
+                    actuatorID = content["actuatorID"] + "(action)"
+                    x = content["actuatorValue"]
+                    history[actuatorID].append((t, x))
+                    for arm in controller["bandit"]["lagrange"]["lagrangeConstraint"][
+                        "weights"
+                    ]:
+                        value = arm["action"][0]["actuatorValue"]
+                        history[str(value / 1000000) + "-probability"].append(
+                            (t, arm["probability"]["getProbability"])
+                        )
+                        history[str(value / 1000000) + "-cumulativeLoss"].append(
+                            (t, arm["cumulativeLoss"]["getCumulativeLoss"])
+                        )
+                # print(
+                # "Action: originating at time %s for actuator %s of value %s"
+                #% (t,actuatorID,x)
+                # )
+            host.check_daemon()
+    except:
+        return history
+    host.stop_daemon()
+    return history
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
+

experiments:

+ +
+
+
+
+
+
In [8]:
+
+
+
results = {}
+for key, cfg in daemonCfgs.items():
+    results[key] = do_workload(host, cfg, stream)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
connecting
+connected to tcp://localhost:2345
+Starting the workload
+Problem 
+    { sensors = Map 
+        [ 
+            ( SensorID { sensorID = "DownstreamCmdKey (DownstreamCmdID 706df7b0-bce1-4384-8274-e62b5a6937c3)" }
+            , Sensor 
+                { range = 0.0 ... 8.614535308e9
+                , maxFrequency = 1.0
+                } 
+            ) 
+        , 
+            ( SensorID { sensorID = "RaplKey (PackageID 0)" }
+            , Sensor 
+                { range = 0.0 ... 300.0
+                , maxFrequency = 3.0
+                } 
+            ) 
+        ] 
+    , actuators = Map 
+        [ 
+            ( ActuatorID { actuatorID = "RaplKey (PackageID 0)" }
+            , Actuator 
+                { actions = 
+                    [ DiscreteDouble 100.0
+                    , DiscreteDouble 200.0
+                    ] 
+                }
+            ) 
+        ]
+    , objectives = []
+    , constraints = []
+    } 
+Sensor identifier list:
+- DownstreamCmdKey (DownstreamCmdID 706df7b0-bce1-4384-8274-e62b5a6937c3)
+- RaplKey (PackageID 0)
+Actuator identifier list:
+- RaplKey (PackageID 0)
+...................................................................................................................................................................................................................................................................................................................................................................................connecting
+connected to tcp://localhost:2345
+Starting the workload
+Problem 
+    { sensors = Map 
+        [ 
+            ( SensorID { sensorID = "DownstreamCmdKey (DownstreamCmdID 8ae8153d-532b-42a0-9c53-185ca78697f8)" }
+            , Sensor 
+                { range = 0.0 ... 1.0153094158e10
+                , maxFrequency = 1.0
+                } 
+            ) 
+        , 
+            ( SensorID { sensorID = "RaplKey (PackageID 0)" }
+            , Sensor 
+                { range = 0.0 ... 300.0
+                , maxFrequency = 3.0
+                } 
+            ) 
+        ] 
+    , actuators = Map 
+        [ 
+            ( ActuatorID { actuatorID = "RaplKey (PackageID 0)" }
+            , Actuator 
+                { actions = 
+                    [ DiscreteDouble 100.0
+                    , DiscreteDouble 200.0
+                    ] 
+                }
+            ) 
+        ]
+    , objectives = []
+    , constraints = []
+    } 
+Sensor identifier list:
+- DownstreamCmdKey (DownstreamCmdID 8ae8153d-532b-42a0-9c53-185ca78697f8)
+- RaplKey (PackageID 0)
+Actuator identifier list:
+- RaplKey (PackageID 0)
+...........................................connecting
+connected to tcp://localhost:2345
+Starting the workload
+Problem 
+    { sensors = Map 
+        [ 
+            ( SensorID { sensorID = "DownstreamCmdKey (DownstreamCmdID b4deb461-ff70-4db1-8302-d02facbd9a4d)" }
+            , Sensor 
+                { range = 0.0 ... 8.73804945e9
+                , maxFrequency = 1.0
+                } 
+            ) 
+        , 
+            ( SensorID { sensorID = "RaplKey (PackageID 0)" }
+            , Sensor 
+                { range = 0.0 ... 300.0
+                , maxFrequency = 3.0
+                } 
+            ) 
+        ] 
+    , actuators = Map 
+        [ 
+            ( ActuatorID { actuatorID = "RaplKey (PackageID 0)" }
+            , Actuator 
+                { actions = 
+                    [ DiscreteDouble 100.0
+                    , DiscreteDouble 200.0
+                    ] 
+                }
+            ) 
+        ]
+    , objectives = []
+    , constraints = []
+    } 
+Sensor identifier list:
+- DownstreamCmdKey (DownstreamCmdID b4deb461-ff70-4db1-8302-d02facbd9a4d)
+- RaplKey (PackageID 0)
+Actuator identifier list:
+- RaplKey (PackageID 0)
+.....................................................................................................................connecting
+connected to tcp://localhost:2345
+Starting the workload
+Problem 
+    { sensors = Map 
+        [ 
+            ( SensorID { sensorID = "DownstreamCmdKey (DownstreamCmdID aade1bd4-3402-4c1e-a5b3-3a9935302a27)" }
+            , Sensor 
+                { range = 0.0 ... 100000.0
+                , maxFrequency = 1.0
+                } 
+            ) 
+        , 
+            ( SensorID { sensorID = "RaplKey (PackageID 0)" }
+            , Sensor 
+                { range = 0.0 ... 300.0
+                , maxFrequency = 3.0
+                } 
+            ) 
+        ] 
+    , actuators = Map 
+        [ 
+            ( ActuatorID { actuatorID = "RaplKey (PackageID 0)" }
+            , Actuator 
+                { actions = 
+                    [ DiscreteDouble 100.0
+                    , DiscreteDouble 200.0
+                    ] 
+                }
+            ) 
+        ]
+    , objectives = []
+    , constraints = []
+    } 
+Sensor identifier list:
+- DownstreamCmdKey (DownstreamCmdID aade1bd4-3402-4c1e-a5b3-3a9935302a27)
+- RaplKey (PackageID 0)
+Actuator identifier list:
+- RaplKey (PackageID 0)
+........................................
+
+
+ +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
In [9]:
+
+
+
import pandas as pd
+import matplotlib.pyplot as plt
+import seaborn as sns
+import numpy as np
+import scipy.integrate as integrate
+from functools import reduce
+
+
+def history_to_dataframe(key, history):
+    name = key
+
+    def mkdf(columnName, measurements):
+        dataframe = pd.DataFrame(
+            data=[(pd.Timestamp(t, unit="us"), m) for t, m in measurements]
+        )
+        dataframe.columns = ["time", columnName]
+        return dataframe
+
+    data_frames = [
+        mkdf(columnName, measurements) for (columnName, measurements) in history.items()
+    ]
+    merged = reduce(
+        lambda left, right: pd.merge(left, right, on=["time"], how="outer"), data_frames
+    )
+    return merged.melt(id_vars=["time"]).assign(name=name)
+
+
+result_df = pd.concat(
+    [history_to_dataframe(key, history) for key, history in results.items()]
+)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
+

Let's display the evolution of the proxy objective and the performance of these three strategies on the final objective.

+ +
+
+
+
+
+
In [10]:
+
+
+
import pandas as pd
+import matplotlib.pyplot as plt
+import seaborn as sns
+
+
+def plot_history(history):
+    nplots = len(history.keys())
+    fig = plt.figure()
+    fig, (axes) = plt.subplots(nplots, 1, sharex=True)
+    fig.subplots_adjust(wspace=0.1)
+    fig.set_size_inches(17, 25 * nplots / 10, forward=True)
+
+    minTime = min(
+        [
+            min([pd.Timestamp(m[0], unit="us") for m in measurements])
+            for cname, measurements in history.items()
+        ]
+    )
+    maxTime = max(
+        [
+            max([pd.Timestamp(m[0], unit="us") for m in measurements])
+            for cname, measurements in history.items()
+        ]
+    )
+
+    plt.xlim(minTime, maxTime)
+
+    for ((columnName, measurements), ax) in zip(history.items(), axes):
+        ax.set_title(columnName)
+        dataframe = pd.DataFrame(
+            data=[(pd.Timestamp(t, unit="us"), m) for t, m in measurements]
+        )
+        dataframe.columns = ["time", "value"]
+        if dataframe.dtypes["value"] == "object":
+            sns.catplot(ax=ax, x="time", y="value", kind="swarm", data=dataframe)
+        else:
+            sns.lineplot(ax=ax, x="time", y="value",data=dataframe)
+    return (fig,minTime, maxTime)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
In [11]:
+
+
+
for k, h in results.items():
+    plot_history(h)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
/nix/store/ws7algif7c1inwk7s6hvmml5rhsfca4w-python3.7-pandas-0.24.2/lib/python3.7/site-packages/pandas/plotting/_converter.py:129: FutureWarning: Using an implicitly registered datetime converter for a matplotlib plotting method. The converter was registered by pandas on import. Future versions of pandas will require you to explicitly register matplotlib converters.
+
+To register the converters:
+	>>> from pandas.plotting import register_matplotlib_converters
+	>>> register_matplotlib_converters()
+  warnings.warn(msg, FutureWarning)
+
+
+
+ +
+ +
+ + + + +
+
<Figure size 432x288 with 0 Axes>
+
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ +
+ +
+ + + + +
+
<Figure size 432x288 with 0 Axes>
+
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ +
+ +
+ + + + +
+
<Figure size 432x288 with 0 Axes>
+
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ +
+ +
+ + + + +
+
<Figure size 432x288 with 0 Axes>
+
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ +
+ +
+ + + + + +
+
+ +
+ +
+ +
+
+ +
+
+
+
In [ ]:
+
+
+
 
+
+ +
+
+
+ +
+
+
+ + + + + + diff --git a/doc/notebooks/notebooks/tutorial.html b/doc/notebooks/notebooks/tutorial.html index 6957aa002f277b1a7bd92e457df16210c01f8f8d..7152391ff012a4e6be72662b7a28e82e1ef305a9 100644 --- a/doc/notebooks/notebooks/tutorial.html +++ b/doc/notebooks/notebooks/tutorial.html @@ -13117,36 +13117,25 @@ div#notebook {

NRM python upstream client library tutorial

This tutorial covers the use of NRM's python upstream client library, in the context of running an external resource management strategy. Its cell's output are deterministic, and the executed version that is vendored in the source tree is checked by the project's CI, so its behavior should always be up-to-date with the latest version of the software, and no cells should be throwing exceptions.

-

The next few cells are for setup purposes.

-
-
-
In [ ]:
-
-
-
%%capture
-cd ..
-
+
+
+
+

Setup

This notebook uses nrm's python library bindings and needs the nrmd daemon in the $PATH.

+

Assuming the project is cloned with submodules updated (and the code unmodified), one needs to run the following from the root of the project before running it:

-
-
-
In [2]:
+
In [1]:
-
%load_ext nb_black
-import nrm.tooling as nrm
-import time
-import json
-import pandas as pd
-import matplotlib.pyplot as plt
+
cd ..
 
@@ -13162,32 +13151,10 @@ div#notebook {
- - - -
-
- +
+
/home/fre/workspace/hnrm
+
-
@@ -13197,15 +13164,14 @@ var element = $('#998a5903-cc80-4929-b514-303c7d00378f');
-

Setup

This notebook uses nrm's python library bindings and needs the nrmd daemon in the $PATH.

-

Assuming the project is cloned with submodules updated (and the code unmodified), one needs to run the following from the root of the project before running it:

+

The next cell builds the shared libraries. This should take about a minute on a modern laptop.

-
In [3]:
+
In [2]:
%%capture
@@ -13219,46 +13185,6 @@ var element = $('#998a5903-cc80-4929-b514-303c7d00378f');
 
-
-
- - -
- -
- - - - - -
-
- -
- -
- -
-
-
@@ -13270,7 +13196,7 @@ var element = $('#9b88b56b-2ecd-4095-8e32-cc258241d70f');
-
In [4]:
+
In [3]:
%%bash
@@ -13304,51 +13230,17 @@ Available options:
   -y,--yaml                Assume configuration to be yaml(json is valid yaml)
                            instead of dhall.
   -h,--help                Show this help text
-0 ExitSuccess
 
-
- -
- - - - - -
-
- -
- -
-
-
In [5]:
+
In [4]:
%%bash 
@@ -13419,6 +13311,39 @@ Available options:
 
+
+
+ +
+
+
+
+

Defining experiments

Now that the daemon is properly set-up, we will configure and run some experiments using the python interface.

+ +
+
+
+
+
+
In [5]:
+
+
+
%load_ext nb_black
+import nrm.tooling as nrm
+import time
+import json
+import pandas as pd
+import matplotlib.pyplot as plt
+
+ +
+
+
+ +
+
+ +
@@ -13427,15 +13352,15 @@ Available options: -
+
+
+ +
+ +
+
+ +
+
+
+
+

The next cell shows how to start the daemon. This acts as a silent restart in case the daemon was still running beforehand.

+ +
+
+
+
+
+
In [11]:
+
+
+
host.start_daemon(daemonCfgs["manyActions"])
 assert host.check_daemon()
 
@@ -13795,15 +13788,15 @@ connected to tcp://localhost:2345 -
+
Safe HaskellSafe
LanguageHaskell2010

Algebra.Classes

Synopsis

Documentation

class Additive a where Source #

Additive monoid

Minimal complete definition

(+), zero

Methods

(+) :: a -> a -> a infixl 6 Source #

zero :: a Source #

times :: Natural -> a -> a Source #

Instances
Additive Double Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Double -> Double -> Double Source #

zero :: Double Source #

times :: Natural -> Double -> Double Source #

Additive Float Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Float -> Float -> Float Source #

zero :: Float Source #

times :: Natural -> Float -> Float Source #

Additive Int Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Int -> Int -> Int Source #

zero :: Int Source #

times :: Natural -> Int -> Int Source #

Additive Integer Source # 
Instance details

Defined in Algebra.Classes

Additive Word8 Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Word8 -> Word8 -> Word8 Source #

zero :: Word8 Source #

times :: Natural -> Word8 -> Word8 Source #

Additive Word16 Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Word16 -> Word16 -> Word16 Source #

zero :: Word16 Source #

times :: Natural -> Word16 -> Word16 Source #

Additive Word32 Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Word32 -> Word32 -> Word32 Source #

zero :: Word32 Source #

times :: Natural -> Word32 -> Word32 Source #

Additive CInt Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: CInt -> CInt -> CInt Source #

zero :: CInt Source #

times :: Natural -> CInt -> CInt Source #

Integral a => Additive (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Ratio a -> Ratio a -> Ratio a Source #

zero :: Ratio a Source #

times :: Natural -> Ratio a -> Ratio a Source #

(Ord k, Additive v) => Additive (Map k v) Source # 
Instance details

Defined in Algebra.Classes

Methods

(+) :: Map k v -> Map k v -> Map k v Source #

zero :: Map k v Source #

times :: Natural -> Map k v -> Map k v Source #

(Ord v, Additive c) => Additive (LinExpr v c) Source # 
Instance details

Defined in Data.LinearProgram.LinExpr

Methods

(+) :: LinExpr v c -> LinExpr v c -> LinExpr v c Source #

zero :: LinExpr v c Source #

times :: Natural -> LinExpr v c -> LinExpr v c Source #

class Additive a => Group a where Source #

Minimal complete definition

(negate | (-))

Methods

(-) :: a -> a -> a infixl 6 Source #

negate :: a -> a Source #

mult :: Integer -> a -> a Source #

Instances
Group Double Source # 
Instance details

Defined in Algebra.Classes

Group Float Source # 
Instance details

Defined in Algebra.Classes

Group Int Source # 
Instance details

Defined in Algebra.Classes

Methods

(-) :: Int -> Int -> Int Source #

negate :: Int -> Int Source #

mult :: Integer -> Int -> Int Source #

Group Integer Source # 
Instance details

Defined in Algebra.Classes

Group Word8 Source # 
Instance details

Defined in Algebra.Classes

Group Word16 Source # 
Instance details

Defined in Algebra.Classes

Group Word32 Source # 
Instance details

Defined in Algebra.Classes

Group CInt Source # 
Instance details

Defined in Algebra.Classes

Integral a => Group (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

Methods

(-) :: Ratio a -> Ratio a -> Ratio a Source #

negate :: Ratio a -> Ratio a Source #

mult :: Integer -> Ratio a -> Ratio a Source #

(Ord k, Group v) => Group (Map k v) Source # 
Instance details

Defined in Algebra.Classes

Methods

(-) :: Map k v -> Map k v -> Map k v Source #

negate :: Map k v -> Map k v Source #

mult :: Integer -> Map k v -> Map k v Source #

(Ord v, Group c) => Group (LinExpr v c) Source # 
Instance details

Defined in Data.LinearProgram.LinExpr

Methods

(-) :: LinExpr v c -> LinExpr v c -> LinExpr v c Source #

negate :: LinExpr v c -> LinExpr v c Source #

mult :: Integer -> LinExpr v c -> LinExpr v c Source #

class (Module a a, PreRing a) => Ring a where Source #

Minimal complete definition

Nothing

Methods

fromInteger :: Integer -> a Source #

Instances
Ring Double Source # 
Instance details

Defined in Algebra.Classes

Ring Float Source # 
Instance details

Defined in Algebra.Classes

Ring Int Source # 
Instance details

Defined in Algebra.Classes

Ring Integer Source # 
Instance details

Defined in Algebra.Classes

Ring CInt Source # 
Instance details

Defined in Algebra.Classes

Integral a => Ring (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

class (AbelianAdditive a, PreRing scalar) => Module scalar a where Source #

Module

Methods

(*^) :: scalar -> a -> a infixr 7 Source #

Instances
Module Double Double Source # 
Instance details

Defined in Algebra.Classes

Methods

(*^) :: Double -> Double -> Double Source #

Module Float Float Source # 
Instance details

Defined in Algebra.Classes

Methods

(*^) :: Float -> Float -> Float Source #

Module Int Int Source # 
Instance details

Defined in Algebra.Classes

Methods

(*^) :: Int -> Int -> Int Source #

Module Integer Integer Source # 
Instance details

Defined in Algebra.Classes

Module Rational Double Source # 
Instance details

Defined in Algebra.Classes

Methods

(*^) :: Rational -> Double -> Double Source #

Module CInt CInt Source # 
Instance details

Defined in Algebra.Classes

Methods

(*^) :: CInt -> CInt -> CInt Source #

(Ord k, Module v v) => Module v (Map k v) Source # 
Instance details

Defined in Algebra.Classes

Methods

(*^) :: v -> Map k v -> Map k v Source #

(Ord v, Ring c) => Module c (LinExpr v c) Source # 
Instance details

Defined in Data.LinearProgram.LinExpr

Methods

(*^) :: c -> LinExpr v c -> LinExpr v c Source #

Integral a => Module (Ratio a) (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

Methods

(*^) :: Ratio a -> Ratio a -> Ratio a Source #

newtype Product a Source #

Constructors

Product 

Fields

Instances
Multiplicative a => Semigroup (Product a) Source # 
Instance details

Defined in Algebra.Classes

Methods

(<>) :: Product a -> Product a -> Product a #

sconcat :: NonEmpty (Product a) -> Product a #

stimes :: Integral b => b -> Product a -> Product a #

Multiplicative a => Monoid (Product a) Source # 
Instance details

Defined in Algebra.Classes

Methods

mempty :: Product a #

mappend :: Product a -> Product a -> Product a #

mconcat :: [Product a] -> Product a #

newtype Exponential a Source #

Constructors

Exponential 

Fields

Instances
Group a => Division (Exponential a) Source # 
Instance details

Defined in Algebra.Classes

Additive a => Multiplicative (Exponential a) Source # 
Instance details

Defined in Algebra.Classes

class (Ring a, Division a) => Field a where Source #

Minimal complete definition

Nothing

Methods

fromRational :: Rational -> a Source #

Instances
Field Double Source # 
Instance details

Defined in Algebra.Classes

Field Float Source # 
Instance details

Defined in Algebra.Classes

Integral a => Field (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

class Additive a => AbelianAdditive a Source #

Instances
AbelianAdditive Double Source # 
Instance details

Defined in Algebra.Classes

AbelianAdditive Float Source # 
Instance details

Defined in Algebra.Classes

AbelianAdditive Int Source # 
Instance details

Defined in Algebra.Classes

AbelianAdditive Integer Source # 
Instance details

Defined in Algebra.Classes

AbelianAdditive CInt Source # 
Instance details

Defined in Algebra.Classes

Integral a => AbelianAdditive (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

(Ord k, AbelianAdditive v) => AbelianAdditive (Map k v) Source # 
Instance details

Defined in Algebra.Classes

(Ord v, AbelianAdditive c) => AbelianAdditive (LinExpr v c) Source # 
Instance details

Defined in Data.LinearProgram.LinExpr

type MyRational = Ratio Integer Source #

class Multiplicative a where Source #

Multiplicative monoid

Minimal complete definition

(*), one

Methods

(*) :: a -> a -> a infixl 7 Source #

one :: a Source #

(^) :: a -> Natural -> a Source #

Instances
Multiplicative Double Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Double -> Double -> Double Source #

one :: Double Source #

(^) :: Double -> Natural -> Double Source #

Multiplicative Float Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Float -> Float -> Float Source #

one :: Float Source #

(^) :: Float -> Natural -> Float Source #

Multiplicative Int Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Int -> Int -> Int Source #

one :: Int Source #

(^) :: Int -> Natural -> Int Source #

Multiplicative Integer Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Integer -> Integer -> Integer Source #

one :: Integer Source #

(^) :: Integer -> Natural -> Integer Source #

Multiplicative Word8 Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Word8 -> Word8 -> Word8 Source #

one :: Word8 Source #

(^) :: Word8 -> Natural -> Word8 Source #

Multiplicative Word16 Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Word16 -> Word16 -> Word16 Source #

one :: Word16 Source #

(^) :: Word16 -> Natural -> Word16 Source #

Multiplicative Word32 Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Word32 -> Word32 -> Word32 Source #

one :: Word32 Source #

(^) :: Word32 -> Natural -> Word32 Source #

Multiplicative CInt Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: CInt -> CInt -> CInt Source #

one :: CInt Source #

(^) :: CInt -> Natural -> CInt Source #

Integral a => Multiplicative (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

Methods

(*) :: Ratio a -> Ratio a -> Ratio a Source #

one :: Ratio a Source #

(^) :: Ratio a -> Natural -> Ratio a Source #

Additive a => Multiplicative (Exponential a) Source # 
Instance details

Defined in Algebra.Classes

type VectorSpace scalar a = (Field scalar, Module scalar a) Source #

class Multiplicative a => Division a where Source #

Minimal complete definition

(recip | (/))

Methods

recip :: a -> a Source #

(/) :: a -> a -> a infixl 7 Source #

Instances
Division Double Source # 
Instance details

Defined in Algebra.Classes

Division Float Source # 
Instance details

Defined in Algebra.Classes

Integral a => Division (Ratio a) Source # 
Instance details

Defined in Algebra.Classes

Methods

recip :: Ratio a -> Ratio a Source #

(/) :: Ratio a -> Ratio a -> Ratio a Source #

Group a => Division (Exponential a) Source # 
Instance details

Defined in Algebra.Classes

add :: (Foldable t, Additive a) => t a -> a Source #

multiply :: (Multiplicative a, Foldable f) => f a -> a Source #

quot, rem :: Integral a => a -> a -> a Source #

quot, rem :: Integral a => a -> a -> a Source #

toInteger :: Integral a => a -> Integer Source #

gcd :: Integral a => a -> a -> a Source #

ifThenElse :: Bool -> t -> t -> t Source #

\ No newline at end of file +Algebra.Classes
Safe HaskellSafe
LanguageHaskell2010

Algebra.Classes

Synopsis