diff --git a/garlic/exp/nbody/tampi.nix b/garlic/exp/nbody/tampi.nix index ca2745d..c5fd69f 100644 --- a/garlic/exp/nbody/tampi.nix +++ b/garlic/exp/nbody/tampi.nix @@ -17,7 +17,7 @@ let cc = [ bsc.icc ]; mpi = [ bsc.impi ]; #mpi = [ bsc.mpichDebug ]; - blocksize = [ 1024 ]; + blocksize = [ 1024 2048 ]; }; # Common configuration @@ -164,7 +164,7 @@ let inherit cc blocksize mpi gitBranch; }; - launch = w.launch.override { + experimentFn = w.experiment.override { nixPrefix = common.nixPrefix; }; @@ -193,13 +193,14 @@ let stages = stdStages ++ debugStages ++ [ argv nbodyFn ]; # List of actual programs to be executed - jobs = map (conf: w.stagen { inherit conf stages; }) configs; + units = map (conf: w.unit { inherit conf stages; }) configs; - launcher = launch jobs; + experiment = experimentFn units; trebuchet = stage: w.trebuchet { program = stageProgram stage; nixPrefix = common.nixPrefix; + experiment = experiment; }; isolatedRun = stage: isolate { @@ -207,9 +208,10 @@ let conf = common; }; - final = trebuchet (isolatedRun launcher); + final = trebuchet (isolatedRun experiment); in # We simply run each program one after another #launch jobs final + #jobs diff --git a/garlic/stages/experiment/default.nix b/garlic/stages/experiment/default.nix new file mode 100644 index 0000000..a397fbc --- /dev/null +++ b/garlic/stages/experiment/default.nix @@ -0,0 +1,34 @@ +{ + stdenv +, nixPrefix ? "" +}: + +units: + +with stdenv.lib; + +let + stageProgram = stage: + if stage ? programPath + then "${stage}${stage.programPath}" else "${stage}"; + + unitsString = builtins.concatStringsSep "\n" + (map (x: "${stageProgram x}") units); +in +stdenv.mkDerivation { + name = "experiment"; + phases = [ "installPhase" ]; + preferLocalBuild = true; + dontPatchShebangs = true; + inherit units; + + installPhase = '' + cat > $out << EOF + #!/bin/sh + + # This is an experiment formed by the following units: + ${unitsString} + EOF + chmod +x $out + ''; +} diff --git a/garlic/stages/experiment/old.nix b/garlic/stages/experiment/old.nix new file mode 100644 index 0000000..763bdb4 --- /dev/null +++ b/garlic/stages/experiment/old.nix @@ -0,0 +1,50 @@ +{ + stdenv +, nixPrefix ? "" +}: + +apps: # Each app must be unique + +stdenv.mkDerivation { + name = "launcher"; + preferLocalBuild = true; + + buildInputs = [] ++ apps; + apps = apps; + phases = [ "unpackPhase" "patchPhase" "installPhase" ]; + dontPatchShebangs = true; + programPath = "/bin/run"; + + src = ./.; + + inherit nixPrefix; + + patchPhase = '' + substituteAllInPlace run + ''; + + installPhase = '' + mkdir -p $out/apps + for j in $apps; do + target=$out/apps/$(basename $j) + if [ -e $target ]; then + echo "Duplicated app: $j" + echo + echo "Provided apps: " + printf "%s\n" $apps + echo + exit 1 + fi + ln -s $j $target + done + + mkdir -p $out/bin + install -m755 run $out/bin/run + chmod +x $out/bin/* + + # Mark the launcher for upload + touch $out/.upload-to-mn + # And mark it as an experiment + touch $out/.experiment + ''; +} diff --git a/garlic/stages/experiment/run b/garlic/stages/experiment/run new file mode 100644 index 0000000..3c98c2c --- /dev/null +++ b/garlic/stages/experiment/run @@ -0,0 +1,20 @@ +#!/bin/sh -ex + +>&2 echo "Running launcher" + +if [ ! -e "/nix" ]; then + >&2 echo "missing /nix" + exit 1 +fi + +if [ -z "$GARLIC_OUT" ]; then + >&2 echo "GARLIC_OUT is not set" + exit 1 +fi + +mkdir -p "$GARLIC_OUT" +cd "$GARLIC_OUT" + +for j in @out@/apps/*; do + $j/bin/run +done diff --git a/garlic/stages/launcher/default.nix b/garlic/stages/launcher/default.nix index 763bdb4..aa019da 100644 --- a/garlic/stages/launcher/default.nix +++ b/garlic/stages/launcher/default.nix @@ -3,48 +3,33 @@ , nixPrefix ? "" }: -apps: # Each app must be unique +units: +with stdenv.lib; + +let + + stageProgram = stage: + if stage ? programPath + then "${stage}${stage.programPath}" else "${stage}"; + + unitsString = builtins.concatStringsSep "\n" + (map (x: "${stageProgram x}") units); +in stdenv.mkDerivation { - name = "launcher"; + name = "experiment"; + phases = [ "installPhase" ]; preferLocalBuild = true; - - buildInputs = [] ++ apps; - apps = apps; - phases = [ "unpackPhase" "patchPhase" "installPhase" ]; dontPatchShebangs = true; - programPath = "/bin/run"; - - src = ./.; - - inherit nixPrefix; - - patchPhase = '' - substituteAllInPlace run - ''; + inherit units; installPhase = '' - mkdir -p $out/apps - for j in $apps; do - target=$out/apps/$(basename $j) - if [ -e $target ]; then - echo "Duplicated app: $j" - echo - echo "Provided apps: " - printf "%s\n" $apps - echo - exit 1 - fi - ln -s $j $target - done + cat > $out << EOF + #!/bin/sh - mkdir -p $out/bin - install -m755 run $out/bin/run - chmod +x $out/bin/* - - # Mark the launcher for upload - touch $out/.upload-to-mn - # And mark it as an experiment - touch $out/.experiment + # This is an experiment formed by the following units: + ${unitsString} + EOF + chmod +x $out ''; } diff --git a/garlic/stages/launcher/old.nix b/garlic/stages/launcher/old.nix new file mode 100644 index 0000000..763bdb4 --- /dev/null +++ b/garlic/stages/launcher/old.nix @@ -0,0 +1,50 @@ +{ + stdenv +, nixPrefix ? "" +}: + +apps: # Each app must be unique + +stdenv.mkDerivation { + name = "launcher"; + preferLocalBuild = true; + + buildInputs = [] ++ apps; + apps = apps; + phases = [ "unpackPhase" "patchPhase" "installPhase" ]; + dontPatchShebangs = true; + programPath = "/bin/run"; + + src = ./.; + + inherit nixPrefix; + + patchPhase = '' + substituteAllInPlace run + ''; + + installPhase = '' + mkdir -p $out/apps + for j in $apps; do + target=$out/apps/$(basename $j) + if [ -e $target ]; then + echo "Duplicated app: $j" + echo + echo "Provided apps: " + printf "%s\n" $apps + echo + exit 1 + fi + ln -s $j $target + done + + mkdir -p $out/bin + install -m755 run $out/bin/run + chmod +x $out/bin/* + + # Mark the launcher for upload + touch $out/.upload-to-mn + # And mark it as an experiment + touch $out/.experiment + ''; +} diff --git a/garlic/stages/trebuchet/default.nix b/garlic/stages/trebuchet/default.nix index 68405f4..6b397c7 100644 --- a/garlic/stages/trebuchet/default.nix +++ b/garlic/stages/trebuchet/default.nix @@ -8,8 +8,37 @@ , nixPrefix , sshHost ? "mn" , targetCluster ? "mn4" +, experiment ? "" }: +with stdenv.lib; + +let + + dStages = foldr (stageFn: {conf, prevStage, stages}: { + conf = conf; + prevStage = stageFn {stage=prevStage; conf=conf;}; + stages = [ (stageFn {stage=prevStage; conf=conf;}) ] ++ stages; + }) + {conf=conf; stages=[]; prevStage=null;} stages; + + stageProgram = stage: + if stage ? programPath + then "${stage}${stage.programPath}" else "${stage}"; + + linkStages = imap1 (i: s: { + num = "${toString i}"; + name = "${toString i}-${baseNameOf s.name}"; + stage = s; + programPath = stageProgram s; + }) dStages.stages; + + units = builtins.concatStringsSep "\n" + (map (x: "# ${x}") experiment.units); + + firstStage = (x: x.programPath) (elemAt linkStages 0); +in + stdenv.mkDerivation { name = "trebuchet"; phases = [ "installPhase" ]; @@ -23,6 +52,12 @@ stdenv.mkDerivation { # Take a look at ${program} # to see what is being executed. + # Executes the following experiment in MN4: + # ${experiment} + + # Which contains the following experiment units: + ${units} + nixtools=${nixPrefix}${nixtools}/bin runexp=\$nixtools/${targetCluster}/runexp diff --git a/garlic/stages/unit.nix b/garlic/stages/unit.nix new file mode 100644 index 0000000..f20a4dd --- /dev/null +++ b/garlic/stages/unit.nix @@ -0,0 +1,62 @@ +{ + stdenv +, bash +}: + +{ + stages +, conf +}: + +with stdenv.lib; + +let + + dStages = foldr (stageFn: {conf, prevStage, stages}: { + conf = conf; + prevStage = stageFn {stage=prevStage; conf=conf;}; + stages = [ (stageFn {stage=prevStage; conf=conf;}) ] ++ stages; + }) + {conf=conf; stages=[]; prevStage=null;} stages; + + stageProgram = stage: + if stage ? programPath + then "${stage}${stage.programPath}" else "${stage}"; + + linkStages = imap1 (i: s: { + num = "${toString i}"; + name = "${toString i}-${baseNameOf s.name}"; + stage = s; + programPath = stageProgram s; + }) dStages.stages; + + stageList = builtins.concatStringsSep "\n" + (map (x: "# ${x.stage}") linkStages); + + firstStage = (x: x.programPath) (elemAt linkStages 0); +in +stdenv.mkDerivation { + name = "unit"; + preferLocalBuild = true; + phases = [ "installPhase" ]; + installPhase = '' + cat > $out << EOF + #!/bin/sh -e + + # This script defines an experimental unit with the following stages: + ${stageList} + + # Set the experiment unit in the environment + export GARLIC_UNIT=$(basename $out) + + # And change the working directory + mkdir \$GARLIC_UNIT + cd \$GARLIC_UNIT + + # Finally, execute the first stage: + exec ${firstStage} + EOF + + chmod +x $out + ''; +} diff --git a/overlay.nix b/overlay.nix index 8b848fd..72de9e2 100644 --- a/overlay.nix +++ b/overlay.nix @@ -209,6 +209,8 @@ let isolate = callPackage ./garlic/stages/isolate { }; trebuchet = callPackage ./garlic/stages/trebuchet { }; strace = callPackage ./garlic/stages/strace.nix { }; + unit = callPackage ./garlic/stages/unit.nix { }; + experiment= callPackage ./garlic/stages/experiment/default.nix { }; }; # Tests (move to bsc ?)