diff --git a/.gitignore b/.gitignore index c1aa91dc..b67a86fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ __pycache__/ venv/ +.direnv .venv/ .idea/ .vscode/ .DS_Store results/ benchkit.egg-info/ +.envrc diff --git a/.nix/default.nix b/.nix/default.nix new file mode 100644 index 00000000..244d6bea --- /dev/null +++ b/.nix/default.nix @@ -0,0 +1,79 @@ +{ + config, + lib, + dream2nix, + pkgs, + pythainer, + ... +}: let + pyproject = lib.importTOML (config.mkDerivation.src + /pyproject.toml); +in { + + imports = [ + dream2nix.modules.dream2nix.pip + ]; + + # package dependencies + deps = { nixpkgs, pythainer, ... } : { + + python = nixpkgs.python3; + pythainerPackage = pythainer.default; + inherit + (nixpkgs) + stress-ng + tmux + git + ; + }; + + inherit (pyproject.project) name version; + + mkDerivation = { + nativeBuildInputs = []; + + propagatedBuildInputs = [ + config.deps.pythainerPackage + config.deps.stress-ng + config.deps.git + ]; + + src = lib.cleanSourceWith { + src = lib.cleanSource ./..; + filter = name : type: + !(builtins.any (x: x) [ + (lib.hasSuffix ".nix" name) # do not package nix files + (lib.hasPrefix "." (builtins.baseNameOf name)) # do not package hidden files + (lib.hasSuffix "flake.lock" name) # do not include the flake lock + ]); + }; + }; + + buildPythonPackage = { + pyproject = true; + pythonImportsCheck = [ # checks that python can import pythainer + "benchkit" + "pythainer" + ]; + }; + + pip = { + # concatenate both the build system (above) and the requirements.txt + requirementsList = + pyproject.build-system.requires or [] + ++ pyproject.project.dependencies or []; + flattenDependencies = true; + + # this is required as the pypi version of docopt makes the build fail + overrides.docopt = { + buildPythonPackage.pyproject = true; + mkDerivation.buildInputs = [config.deps.python.pkgs.setuptools]; + }; + + overrides.wget = { + buildPythonPackage.pyproject = true; + mkDerivation.buildInputs = [config.deps.python.pkgs.setuptools]; + }; + }; + + +} diff --git a/.nix/lock.x86_64-linux.json b/.nix/lock.x86_64-linux.json new file mode 100644 index 00000000..88b15e44 --- /dev/null +++ b/.nix/lock.x86_64-linux.json @@ -0,0 +1,101 @@ +{ + "fetchPipMetadata": { + "sources": { + "docopt": { + "is_direct": false, + "sha256": "49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", + "type": "url", + "url": "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", + "version": "0.6.2" + }, + "hatchling": { + "is_direct": false, + "sha256": "dc48722b68b3f4bbfa3ff618ca07cdea6750e7d03481289ffa8be1521d18a961", + "type": "url", + "url": "https://files.pythonhosted.org/packages/0d/a5/48cb7efb8b4718b1a4c0c331e3364a3a33f614ff0d6afd2b93ee883d3c47/hatchling-1.28.0-py3-none-any.whl", + "version": "1.28.0" + }, + "markdown-it-py": { + "is_direct": false, + "sha256": "87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", + "type": "url", + "url": "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", + "version": "4.0.0" + }, + "mdurl": { + "is_direct": false, + "sha256": "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "type": "url", + "url": "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", + "version": "0.1.2" + }, + "packaging": { + "is_direct": false, + "sha256": "29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "type": "url", + "url": "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", + "version": "25.0" + }, + "pathspec": { + "is_direct": false, + "sha256": "1373719036e64a2b9de3b8ddd9e30afb082a915619f07265ed76d9ae507800ae", + "type": "url", + "url": "https://files.pythonhosted.org/packages/05/bb/39e6768529454cc2b57e1e2fa0a0a18ff64397a16303270e215a3e03285f/pathspec-1.0.0-py3-none-any.whl", + "version": "1.0.0" + }, + "pluggy": { + "is_direct": false, + "sha256": "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", + "type": "url", + "url": "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", + "version": "1.6.0" + }, + "pygments": { + "is_direct": false, + "sha256": "86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", + "type": "url", + "url": "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", + "version": "2.19.2" + }, + "rich": { + "is_direct": false, + "sha256": "76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", + "type": "url", + "url": "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", + "version": "14.2.0" + }, + "trove-classifiers": { + "is_direct": false, + "sha256": "a8206978ede95937b9959c3aff3eb258bbf7b07dff391ddd4ea7e61f316635ab", + "type": "url", + "url": "https://files.pythonhosted.org/packages/4f/7e/bc19996fa86cad8801e8ffe6f1bba5836ca0160df76d0410d27432193712/trove_classifiers-2025.12.1.14-py3-none-any.whl", + "version": "2025.12.1.14" + } + }, + "targets": { + "default": { + "docopt": [], + "hatchling": [ + "packaging", + "pathspec", + "pluggy", + "trove-classifiers" + ], + "markdown-it-py": [ + "mdurl" + ], + "mdurl": [], + "packaging": [], + "pathspec": [], + "pluggy": [], + "pygments": [], + "rich": [ + "markdown-it-py", + "pygments" + ], + "trove-classifiers": [] + } + } + }, + "invalidationHash": "156fe21e28238080e9b7e35e84dfb16761c3a17d21291acf0487ba850888dd18" +} diff --git a/flake.lock b/flake.lock index 681c095d..8db42b51 100644 --- a/flake.lock +++ b/flake.lock @@ -1,24 +1,300 @@ { "nodes": { + "dream2nix": { + "inputs": { + "nixpkgs": "nixpkgs", + "purescript-overlay": "purescript-overlay", + "pyproject-nix": "pyproject-nix" + }, + "locked": { + "lastModified": 1765953015, + "narHash": "sha256-5FBZbbWR1Csp3Y2icfRkxMJw/a/5FGg8hCXej2//bbI=", + "owner": "nix-community", + "repo": "dream2nix", + "rev": "69eb01fa0995e1e90add49d8ca5bcba213b0416f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "dream2nix", + "type": "github" + } + }, + "dream2nix_2": { + "inputs": { + "nixpkgs": "nixpkgs_3", + "purescript-overlay": "purescript-overlay_2", + "pyproject-nix": "pyproject-nix_2" + }, + "locked": { + "lastModified": 1765953015, + "narHash": "sha256-5FBZbbWR1Csp3Y2icfRkxMJw/a/5FGg8hCXej2//bbI=", + "owner": "nix-community", + "repo": "dream2nix", + "rev": "69eb01fa0995e1e90add49d8ca5bcba213b0416f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "dream2nix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1741048562, - "narHash": "sha256-W4YZ3fvWZiFYYyd900kh8P8wU6DHSiwaH0j4+fai1Sk=", + "lastModified": 1750215678, + "narHash": "sha256-Rc/ytpamXRf6z8UA2SGa4aaWxUXRbX2MAWIu2C8M+ok=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5395fb3ab3f97b9b7abca147249fa2e8ed27b192", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1766736597, + "narHash": "sha256-BASnpCLodmgiVn0M1MU2Pqyoz0aHwar/0qLkp7CjvSQ=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6af28b834daca767a7ef99f8a7defa957d0ade6f", + "rev": "f560ccec6b1116b22e6ed15f4c510997d99d5852", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-24.11", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1750215678, + "narHash": "sha256-Rc/ytpamXRf6z8UA2SGa4aaWxUXRbX2MAWIu2C8M+ok=", + "owner": "NixOS", "repo": "nixpkgs", + "rev": "5395fb3ab3f97b9b7abca147249fa2e8ed27b192", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1766736597, + "narHash": "sha256-BASnpCLodmgiVn0M1MU2Pqyoz0aHwar/0qLkp7CjvSQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f560ccec6b1116b22e6ed15f4c510997d99d5852", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "purescript-overlay": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "dream2nix", + "nixpkgs" + ], + "slimlock": "slimlock" + }, + "locked": { + "lastModified": 1728546539, + "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=", + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "type": "github" + } + }, + "purescript-overlay_2": { + "inputs": { + "flake-compat": "flake-compat_2", + "nixpkgs": [ + "pythainer", + "dream2nix", + "nixpkgs" + ], + "slimlock": "slimlock_2" + }, + "locked": { + "lastModified": 1728546539, + "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=", + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "type": "github" + } + }, + "pyproject-nix": { + "inputs": { + "nixpkgs": [ + "dream2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763017646, + "narHash": "sha256-Z+R2lveIp6Skn1VPH3taQIuMhABg1IizJd8oVdmdHsQ=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "47bd6f296502842643078d66128f7b5e5370790c", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "type": "github" + } + }, + "pyproject-nix_2": { + "inputs": { + "nixpkgs": [ + "pythainer", + "dream2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763017646, + "narHash": "sha256-Z+R2lveIp6Skn1VPH3taQIuMhABg1IizJd8oVdmdHsQ=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "47bd6f296502842643078d66128f7b5e5370790c", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "type": "github" + } + }, + "pythainer": { + "inputs": { + "dream2nix": "dream2nix_2", + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1767975120, + "narHash": "sha256-QU9dMACDn9nxbXfSa+rGPmi/xGXyae6PehI0BDX2jHQ=", + "owner": "apaolillo", + "repo": "pythainer", + "rev": "2c247cf419725e23a8c2386db7a4349028d563d0", + "type": "github" + }, + "original": { + "owner": "apaolillo", + "repo": "pythainer", "type": "github" } }, "root": { "inputs": { - "nixpkgs": "nixpkgs" + "dream2nix": "dream2nix", + "nixpkgs": "nixpkgs_2", + "pythainer": "pythainer" + } + }, + "slimlock": { + "inputs": { + "nixpkgs": [ + "dream2nix", + "purescript-overlay", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688756706, + "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=", + "owner": "thomashoneyman", + "repo": "slimlock", + "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "slimlock", + "type": "github" + } + }, + "slimlock_2": { + "inputs": { + "nixpkgs": [ + "pythainer", + "dream2nix", + "purescript-overlay", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688756706, + "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=", + "owner": "thomashoneyman", + "repo": "slimlock", + "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "slimlock", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index c5814373..d8154a57 100644 --- a/flake.nix +++ b/flake.nix @@ -1,430 +1,92 @@ { - # The current NixPkgs release - inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; - - outputs = - { nixpkgs, ... }: + description = "Minimal flake for benchkit"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; + pythainer.url = "github:apaolillo/pythainer"; + dream2nix.url = "github:nix-community/dream2nix"; + }; + + outputs = { + self, + nixpkgs, + dream2nix, + pythainer + }: let - supportedSystems = [ - "x86_64-linux" - "x86_64-darwin" - "aarch64-linux" + eachSystem = nixpkgs.lib.genAttrs [ "aarch64-darwin" + "aarch64-linux" + "x86_64-darwin" + "x86_64-linux" ]; - /** - Run the given function for all the systems in `supportedSystems`. - - # Example - - ```nix - forAllSystems (system: pkgs: {packages.default = pkgs.coreutils;}) - => - { - packages = { - x86_64-linux.default = pkgs.coreutils; - x86_64-darwin.default = pkgs.coreutils; - aarch64-linux.default = pkgs.coreutils; - aarch64-darwin.default = pkgs.coreutils; - }; - }; - ``` - - # Type - - ``` - forAllSystems :: (String -> { ... } -> { ... }) -> { ... } - ``` - */ - forAllSystems = - f: - nixpkgs.lib.foldr nixpkgs.lib.recursiveUpdate { } ( - nixpkgs.lib.forEach supportedSystems ( - system: - builtins.mapAttrs (name: value: { ${system} = value; }) (f system nixpkgs.legacyPackages.${system}) - ) - ); - in - forAllSystems ( - system: pkgs: - let - # The version of benchkit - version = "0.0.1"; - # The version of python to use - python = pkgs.python3; - # The Linux kernel to use, this is used for packages like `perf` - # Uses the latest LTS release (as of 2025-03-12) - # NOTE: This should be updated when a new LTS version is released - linuxKernel = pkgs.linuxKernel.packages.linux_6_12; - # From where to get the python packages, these are packages like `numpy`, `matplotlib`, ... - pythonPackages = pkgs.python3Packages; - # The main benchkit python package - benchkit = pythonPackages.buildPythonPackage { - inherit version; - pname = "pybenchkit"; - src = ./.; - propagatedBuildInputs = [ - pythonPackages.matplotlib - pythonPackages.pandas - pythonPackages.seaborn - pythonPackages.hatchling + in { + + packages = eachSystem (system : { + default = dream2nix.lib.evalModules { + packageSets.nixpkgs = nixpkgs.legacyPackages.${system}; + packageSets.pythainer = pythainer.packages.${system}; + modules = [ + .nix/default.nix + { + paths.lockFile = ".nix/lock.${system}.json"; + paths.projectRoot = ./.; + paths.projectRootFile = "flake.nix"; + paths.package = ./.; + } ]; - # Use a `pyproject.toml` file - format = "pyproject"; }; - /** - Make a derivation for a benchmark using the [benchkit](https://github.com/open-s4c/benchkit) - - # Type - - ```nix - buildBenchmark :: - name :: String; - src :: String | Path; - extraPythonPackages :: ({...} -> [{...}]) ? (_: [ ]); - benchmark :: String ? "benchmark.py"; - replaceBenchmarkSrcDir :: Bool ? false; - benchmarkSrcDirVariable :: String ? "_bench_src_path"; - benchmarkSrcDir :: String ? "."; - replaceBuildDir :: Bool ? false; - buildDirVariable :: String ? "_build_dir"; - buildDir :: String ? "./build/build_${name}"; - dirsFile :: String ? benchmark; - useSudo :: Bool ? false, - } // Derivation -> {...} - ``` - - # Arguments - - name - : The name of your benchmark. - - src - : The source directory of your benchmark, this should include both your Python benchmark file, - and the code that you want to benchmark. - - extraPythonPackages - : Extra Python packages that should be used when running the benchmark. - - benchmark - : The name of the benchmark Python file that, relative to the `src` directory, - this the entry file of your benchmark. - - replaceBenchmarkSrcDir - : Replace the value of the variable in `benchmarkSrcDirVariable` with the path - to your benchmarking code in the Nix store. - This means that, if `benchmarkSrcDirVariable` is `_bench_src_path` and `benchmarkSrcDir` - is `src/`, then `_bench_src_path = ` will be replaced with - `_bench_src_path = /src`, this substitution will be done in `dirsFile`. - - benchmarkSrcDirVariable - : The variable for which to replace the value in the Nix store, see `replaceBenchmarkSrcDir`. - - benchmarkSrcDir - : The directory in which your benchmarking code is, relative to the root directory given to by `src`, - see `replaceBenchmarkSrcDir`. - - replaceBuildDir - : Replace the value of the variable in `buildDirVariable` with the `buildDir`. - This means that, if `buildDirVariable` is `_build_dir` and `buildDir` - is `./build`, then `_build_dir = ` will be replaced with - `_build_dir = "./build"`, this substitution will be done in `dirsFile`. - - buildDirVariable - : The variable for which to replace the value to `buildDir`, see 'replaceBuildDir'. + }); - buildDir - : The directory in which your benchmark should be compiled, this is only used when `replaceBuildDir` is `true`, - see 'replaceBuildDir'. - dirsFile - : The file in which the build directory and benchmark source directory should be replaced, - see `replaceBenchmarkSrcDir` and `replaceBuildDir`. + devShells = eachSystem (system: + let + pkgs = import nixpkgs {inherit system;}; + benchkit = self.packages.${system}.default; + python = benchkit.config.deps.python; - useSudo - : Whether or not `sudo` should be added to the path. - */ - buildBenchmark = - { - name, - src, - extraPythonPackages ? (_: [ ]), - buildInputs ? [ ], - nativeBuildInputs ? [ ], - benchmark ? "benchmark.py", - replaceBenchmarkSrcDir ? false, - benchmarkSrcDirVariable ? "_bench_src_path", - benchmarkSrcDir ? ".", - replaceBuildDir ? false, - buildDirVariable ? "_build_dir", - buildDir ? "./build/build_${name}", - dirsFile ? benchmark, - useSudo ? false, - ... - }@attrs: - let - benchPython = python.withPackages (pks: [ benchkit ] ++ extraPythonPackages pks); - bin = pkgs.writeShellScript "benchmark_${name}" ''${pkgs.lib.getExe benchPython} "@out@/${benchmark}"''; - attrNames = [ - "name" - "src" - "extraPythonPackages" - "buildInputs" - "nativeBuildInputs" - "benchmark" - "replaceBenchmarkSrcDir" - "benchmarkSrcDirVariable" - "benchmarkSrcDir" - "replaceBuildDir" - "buildDirVariable" - "buildDir" - "dirsFile" - "useSudo" - ]; - in - pkgs.stdenv.mkDerivation - <| - builtins.removeAttrs attrs attrNames - // { - name = "benchmark_" + name; - src = src; - nativeBuildInputs = nativeBuildInputs ++ [ pkgs.makeWrapper ]; - postPatch = - # There are some paths that need to be changed, since the source code of the benchmark is in - # the Nix store, where to program wouldn't be able to find it normally, - # and the build folder should be done locally, since the Nix store is immutable. - pkgs.lib.optionalString (replaceBenchmarkSrcDir || replaceBuildDir) ( - "\nsubstituteInPlace '${dirsFile}'" - + pkgs.lib.optionalString replaceBenchmarkSrcDir " --replace-warn '${benchmarkSrcDirVariable} = ' \"${benchmarkSrcDirVariable} = pathlib.Path('$out/${benchmarkSrcDir}') #\"" - + pkgs.lib.optionalString replaceBuildDir " --replace-warn '${buildDirVariable} = ' '${buildDirVariable} = pathlib.Path(\"${buildDir}\") #'" - ); - installPhase = '' - runHook preInstall - - mkdir -p "$out/bin" - cp -r * "$out/" - substitute "${bin}" "$out/bin/benchmark_${name}" --replace-fail "@out@" "$out" - chmod +x "$out/bin/benchmark_${name}" - wrapProgram "$out/bin/benchmark_${name}" --set PATH ${ - pkgs.lib.makeBinPath - <| - buildInputs - ++ [ - pkgs.coreutils - pkgs.nettools - pkgs.git - pkgs.which - ] - ++ (pkgs.lib.optional useSudo "/run/wrappers/") - } - - runHook postInstall - ''; - meta.mainProgram = "benchmark_" + name; - dontBuild = true; - }; - # ======== TUTORIALS ======== - /** - This is a wrapper for `buildBenchmark` that makes it easier to build the tutorials included in `benchkit` - - # Type - - ```nix - buildTutorial :: { - deps :: { [ depName :: String ] :: String | Path } ? { }; - depsInTopLevelDir :: Bool ? false; - importKit :: { [ name :: String ] :: String } ? { }; - benchmarkSrcDir :: String; - } // buildBenchmark // Derivation -> {...} - ``` - - # Arguments - - deps - : The dependencies that are used for this tutorial, this should be an attribute set, - with as key the name of the dependency, and as value the path to the source code. - Any dependency, here will be symlinked into either `benchmarkSrcDir/deps/depName`, or `deps/depName` - depending on `depsInTopLevelDir`. - - depsInTopLevelDir - : If true, place `dep` folder, the dependencies from the `deps` argument in the top level directory, otherwise place it in `benchmarkSrcDir` directory - - importKit - : Most tutorials use a `kit` directory which is added to the python path at the top level, - because of this references to these files usually have to be prefixed with `.kit`, this is - done by this variable. - To do this, you give a attribute set that maps files, relative to the source directory, - to a list of imports in that file, every input in this list will then be prefixed with `.kit`. - This means that the following Nix code would replace `import vsyncmicrobench` in the file - `campaign_locks.py` with `import kit.vsyncmicrobench`. - ```nix - importKit = { "campaign_locks.py" = [ "vsyncmicrobench" ]; }; - ``` - - benchmarkSrcDir - : The directory in which your benchmarking source files are located - */ - buildTutorial = - { - deps ? { }, - depsInTopLevelDir ? false, - importKit ? { }, - benchmarkSrcDir, - postInstall ? "", - prePatch ? "", - buildInputs ? [ ], - ... - }@attrs: - buildBenchmark - <| - builtins.removeAttrs attrs [ - "deps" - "depsInTopLevelDir" - "importKit" - "buildInputs" - "postInstall" - ] - // { - replaceBuildDir = true; - buildInputs = [ - pkgs.cmake - pkgs.gnumake - pkgs.gcc - ] ++ buildInputs; - prePatch = - pkgs.lib.foldlAttrs ( - acc: file: importModules: - acc - + (pkgs.lib.foldr ( - importModule: acc: acc + " --replace-fail 'from ${importModule}' 'from kit.${importModule}'" - ) "\nsubstituteInPlace '${file}'" importModules) - ) "" importKit - + "\n" - + prePatch; - postInstall = - ''mkdir -p "$out/${pkgs.lib.optionalString (!depsInTopLevelDir) "${benchmarkSrcDir}/"}deps"'' - + pkgs.lib.foldlAttrs ( - acc: dep: src: - acc - + "\nln -s ${src} \"$out/${ - pkgs.lib.optionalString (!depsInTopLevelDir) "${benchmarkSrcDir}/" - }deps/${dep}\"" - ) "" deps - + "\n" - + postInstall; - dontConfigure = true; - }; - tutorials = { - # A library of synchronization primitives that is used in the benchmarks of some tutorials, - # only the source is here since `benchkit` expects source code so it can compile the program - # with differing options - libvsync-src = pkgs.fetchFromGitHub { - rev = "refs/tags/v4.1.0"; - owner = "open-s4c"; - repo = "libvsync"; - hash = "sha256-Sb1sbs5TnGyD2vxaDRUbCQjpYAHeu3zWo9ft3evXpV0="; - }; - leveldb-src = pkgs.stdenv.mkDerivation { - name = "leveldb-src"; - src = pkgs.fetchFromGitHub { - rev = "068d5ee1a3ac40dabd00d211d5013af44be55bea"; - owner = "google"; - repo = "leveldb"; - fetchSubmodules = true; - hash = "sha256-D12hjWT80YMwliVqNtryZkA1US0JUhtDFT9xBm9o8ng="; - }; - patches = [ ./tutorials/leveldb-bench/patch.diff ]; - buildPhase = '' - runHook preBuild + benchkitCorePackages = [ + benchkit.config.deps.pythainerPackage + benchkit.config.deps.stress-ng + benchkit.config.deps.tmux + ]; - mkdir -p "$out" - mv * "$out" + pythonToolingPackages = [ + python.pkgs.python-lsp-ruff + python.pkgs.numpy + python.pkgs.pip + ]; - runHook postBuild - ''; - dontConfigure = true; - }; - # The [lybvsync locks](tutorials/libvsync-locks/README.md) tutorial - libvsync-locks = buildTutorial { - name = "tutorial_libvsync-locks"; - src = tutorials/libvsync-locks; - benchmarkSrcDir = "microbench/"; - benchmark = "campaign_locks.py"; - dirsFile = "kit/vsyncmicrobench.py"; - deps = { - "libvsync" = tutorials.libvsync-src; - }; - importKit = { - "campaign_locks.py" = [ "vsyncmicrobench" ]; - }; - }; - leveldb-opts = { - src = tutorials/leveldb-bench; - benchmarkSrcDir = "deps/leveldb"; - deps = { - "leveldb" = tutorials.leveldb-src; - }; - depsInTopLevelDir = true; - dirsFile = "leveldb.py"; - prePatch = "cp ${./examples/leveldb/kit/leveldb.py} 'leveldb.py'"; - }; - leveldb = - buildTutorial - <| - tutorials.leveldb-opts - // { - name = "tutorial_leveldb"; - benchmark = "campaign_leveldb.py"; - }; - leveldb_perf = - buildTutorial - <| - tutorials.leveldb-opts - // { - name = "tutorial_leveldb_perf"; - buildInputs = [ - pkgs.procps - # Use latest LTS release - linuxKernel.perf - ]; - useSudo = true; - benchmark = "campaign_leveldb_perf.py"; - }; - }; - in - { - packages = - let - buildableBenchkit = benchkit // { - inherit buildBenchmark; - }; - in - { - default = buildableBenchkit; - benchkit = buildableBenchkit; - }; - apps = rec { - default = libvsync-locks; - libvsync-locks = { - type = "app"; - program = "${pkgs.lib.getExe tutorials.libvsync-locks}"; - }; - leveldb = { - type = "app"; - program = "${pkgs.lib.getExe tutorials.leveldb}"; - }; - leveldb_perf = { - type = "app"; - program = "${pkgs.lib.getExe tutorials.leveldb_perf}"; - }; - }; - devShells.default = pkgs.mkShell { - packages = [ - pkgs.pyright - (python.withPackages (_: [ benchkit ])) - tutorials.libvsync-locks + formattingPackages = [ + python.pkgs.flake8 + pkgs.pylint + pkgs.isort + pkgs.black + pkgs.ruff ]; + in { + core = pkgs.mkShell { # + inputsFrom = [benchkit.devShell]; # + packages = benchkitCorePackages + ++ pythonToolingPackages + ++ formattingPackages + ++ []; + }; - }; - } - ); + # example of a devshell where non free software is required + # unfree = pkgs.mkShell { + # inputsFrom = [self.devShells.${system}.core]; + # packages = let + # pkgs = import nixpkgs { + # inherit system; + # config.allowUnfree = true; + # }; + # in benchkitCorePackages + # ++ pythonToolingPackages + # ++ formattingPackages + # ++ []; + # }; + + default = self.devShells.${system}.core; + }); + }; }