diff --git a/garlic/exp/index.nix b/garlic/exp/index.nix index 35453371967416146523bdccdad3b52de87f726d..5477fd5c48d054d8c7c9db716ee37868a1b06ad3 100644 --- a/garlic/exp/index.nix +++ b/garlic/exp/index.nix @@ -8,27 +8,9 @@ { nbody = rec { - baseline = callPackage ./nbody/nblocks.nix { }; - - # Experiment variants - small = baseline.override { - particles = 12 * 4096; - }; - - # Some experiments with traces - trace = { - # Only one unit repeated 30 times - baseline = small.override { - enableCTF = true; - loops = 30; - steps = 1; - }; - - }; - - scaling = callPackage ./nbody/scaling.nix { - particles = 12 * 4096; - }; + granularity = callPackage ./nbody/granularity-mpi.nix { }; + nodesorsockets = callPackage ./nbody/nodes-or-sockets-mpi.nix { }; + scaling = callPackage ./nbody/strong-scaling-mpi.nix { }; }; saiph = { diff --git a/garlic/exp/nbody/granularity-mpi.nix b/garlic/exp/nbody/granularity-mpi.nix index 4c1d6a8549a0712e8585770fd00dc7966654e60d..59eae238d93d0f0a8a8414327446d48e4aef97ab 100644 --- a/garlic/exp/nbody/granularity-mpi.nix +++ b/garlic/exp/nbody/granularity-mpi.nix @@ -4,48 +4,42 @@ , bsc , targetMachine , stages +, garlicTools }: with stdenv.lib; +with garlicTools; let # Initial variable configuration varConf = with bsc; { blocksize = [ 128 256 512 1024 2048 4096 ]; + gitBranch = [ + "garlic/mpi+send+oss+task" + "garlic/tampi+send+oss+task" + "garlic/tampi+isend+oss+task" + ]; }; - machineConfig = targetMachine.config; - # Generate the complete configuration for each unit - genConf = with bsc; c: targetMachine.config // rec { - expName = "nbody.test"; - unitName = "${expName}.nb-${toString nblocks}"; - - inherit (machineConfig) hw; - # nbody options - particles = 1024 * 64; + genConf = c: targetMachine.config // rec { + hw = targetMachine.config.hw; + particles = 4096 * hw.cpusPerSocket; timesteps = 10; - inherit (c) blocksize; - totalTasks = ntasksPerNode * nodes; - particlesPerTask = particles / totalTasks; - cc = icc; - mpi = impi; - gitBranch = "garlic/mpi+send"; + blocksize = c.blocksize; + gitBranch = c.gitBranch; - # Repeat the execution of each unit 30 times - loops = 10; + expName = "nbody-granularity"; + unitName = expName + "-${toString gitBranch}" + "-bs${toString blocksize}"; - # Resources - qos = "debug"; - ntasksPerNode = 48; - nodes = 1; - time = "02:00:00"; - cpuBind = "sockets,verbose"; - jobName = "bs-${toString blocksize}-${gitBranch}-nbody"; + loops = 30; - # Experiment revision: this allows a user to run again a experiment already - # executed - rev = 0; + qos = "bsc_cs"; + ntasksPerNode = 1; + nodes = 1; + time = "04:00:00"; + cpusPerTask = hw.cpusPerSocket; + jobName = unitName; }; # Compute the array of configurations @@ -53,18 +47,13 @@ let inherit varConf genConf; }; - exec = {nextStage, conf, ...}: with conf; stages.exec { + exec = {nextStage, conf, ...}: stages.exec { inherit nextStage; - argv = [ "-t" timesteps "-p" particles ]; + argv = [ "-t" conf.timesteps "-p" conf.particles ]; }; - program = {nextStage, conf, ...}: with conf; - # FIXME: This is becoming very slow: - #let - # customPkgs = stdexp.replaceMpi conf.mpi; - #in - bsc.garlic.apps.nbody.override { - inherit cc blocksize mpi gitBranch; + program = {nextStage, conf, ...}: with conf; bsc.garlic.apps.nbody.override { + inherit (conf) blocksize gitBranch; }; pipeline = stdexp.stdPipeline ++ [ exec program ]; diff --git a/garlic/exp/nbody/granularity-oss.nix b/garlic/exp/nbody/granularity-oss.nix deleted file mode 100644 index 1becb3acb3aaa7998e5ccd9089188364b50507af..0000000000000000000000000000000000000000 --- a/garlic/exp/nbody/granularity-oss.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - stdenv -, stdexp -, bsc -, targetMachine -, stages -}: - -with stdenv.lib; - -let - # Initial variable configuration - varConf = with bsc; { - blocksize = [ 128 256 512 1024 2048 4096 ]; - }; - - # Generate the complete configuration for each unit - genConf = with bsc; c: targetMachine.config // rec { - # nbody options - particles = 1024 * 64; - timesteps = 10; - inherit (c) blocksize; - cc = icc; - mpi = impi; - gitBranch = "garlic/oss+task"; - - # Repeat the execution of each unit 30 times - loops = 30; - - # Resources - qos = "debug"; - ntasksPerNode = 1; - nodes = 1; - time = "02:00:00"; - cpuBind = "sockets,verbose"; - jobName = "nbody-bs-${toString blocksize}-${gitBranch}"; - }; - - # Compute the array of configurations - configs = stdexp.buildConfigs { - inherit varConf genConf; - }; - - exec = {nextStage, conf, ...}: with conf; stages.exec { - inherit nextStage; - argv = [ "-t" timesteps "-p" particles ]; - }; - - program = {nextStage, conf, ...}: with conf; - let - customPkgs = stdexp.replaceMpi conf.mpi; - in - customPkgs.apps.nbody.override { - inherit cc blocksize mpi gitBranch; - }; - - pipeline = stdexp.stdPipeline ++ [ exec program ]; - -in - - stdexp.genExperiment { inherit configs pipeline; } diff --git a/garlic/exp/nbody/nodes-or-sockets-mpi.nix b/garlic/exp/nbody/nodes-or-sockets-mpi.nix new file mode 100644 index 0000000000000000000000000000000000000000..44c0c16e6d71de4bcee925728fa360d9303cafd8 --- /dev/null +++ b/garlic/exp/nbody/nodes-or-sockets-mpi.nix @@ -0,0 +1,72 @@ +{ + stdenv +, stdexp +, bsc +, targetMachine +, stages +, garlicTools +, numactl +}: + +with stdenv.lib; +with garlicTools; + +let + # Initial variable configuration + varConf = with bsc; { + blocksize = [ 256 512 1024 ]; + gitBranch = [ "garlic/tampi+send+oss+task" ]; + attachToSocket = [ true false ]; + numactl = [ true false ]; + }; + + # Generate the complete configuration for each unit + genConf = c: targetMachine.config // rec { + hw = targetMachine.config.hw; + particles = 4 * 4096 * hw.cpusPerSocket; + timesteps = 10; + blocksize = c.blocksize; + gitBranch = c.gitBranch; + socketAtt = c.attachToSocket; + useNumact = c.numactl; + + expName = "nbody-granularity"; + attachName = if (socketAtt) then "PerSocket" else "PerNode"; + numaName = if (useNumact) then "True" else "False"; + unitName = expName + + "-${toString gitBranch}" + + "-bs${toString blocksize}" + + "-ranks${toString attachName}" + + "-useNuma${toString numaName}"; + + loops = 30; + + qos = "debug"; + ntasksPerNode = if (socketAtt) then 2 else 1; + nodes = 4; + time = "02:00:00"; + cpusPerTask = if (socketAtt) then hw.cpusPerSocket else 2*hw.cpusPerSocket; + jobName = unitName; + }; + + # Compute the array of configurations + configs = stdexp.buildConfigs { + inherit varConf genConf; + }; + + exec = {nextStage, conf, ...}: stages.exec ({ + inherit nextStage; + argv = [ "-t" conf.timesteps "-p" conf.particles ]; + } // optionalAttrs (conf.useNumact) { + program = "${numactl}/bin/numactl --interleave=all ${stageProgram nextStage}"; + }); + + program = {nextStage, conf, ...}: with conf; bsc.garlic.apps.nbody.override { + inherit (conf) blocksize gitBranch; + }; + + pipeline = stdexp.stdPipeline ++ [ exec program ]; + +in + + stdexp.genExperiment { inherit configs pipeline; } diff --git a/garlic/exp/nbody/old/granularity-oss.nix b/garlic/exp/nbody/old/granularity-oss.nix new file mode 100644 index 0000000000000000000000000000000000000000..1b1dd364d23ea6650aa0d5fd5768c1be83da3cbf --- /dev/null +++ b/garlic/exp/nbody/old/granularity-oss.nix @@ -0,0 +1,59 @@ +{ + stdenv +, stdexp +, bsc +, targetMachine +, stages +, garlicTools +}: + +with stdenv.lib; +with garlicTools; + +let + + # Initial variable configuration + varConf = { + blocksize = [ 128 256 512 1024 2048 4096 ]; + }; + + # Generate the complete configuration for each unit + genConf = c: targetMachine.config // rec { + hw = targetMachine.config.hw; + particles = 4096 * hw.cpusPerSocket; + timesteps = 10; + blocksize = c.blocksize; + + gitBranch = "garlic/oss+task"; + expName = "nbody-granularity"; + unitName = expName + "-bs${toString blocksize}"; + + loops = 30; + + qos = "debug"; + ntasksPerNode = 1; + nodes = 1; + time = "02:00:00"; + cpusPerTask = hw.cpusPerSocket; + jobName = unitName; + }; + + # Compute the array of configurations + configs = stdexp.buildConfigs { + inherit varConf genConf; + }; + + exec = {nextStage, conf, ...}: stages.exec { + inherit nextStage; + argv = [ "-t" conf.timesteps "-p" conf.particles ]; + }; + + program = {nextStage, conf, ...}: with conf; bsc.garlic.apps.nbody.override { + inherit (conf) blocksize gitBranch; + }; + + pipeline = stdexp.stdPipeline ++ [ exec program ]; + +in + + stdexp.genExperiment { inherit configs pipeline; } diff --git a/garlic/exp/nbody/nblocks.nix b/garlic/exp/nbody/old/nblocks.nix similarity index 100% rename from garlic/exp/nbody/nblocks.nix rename to garlic/exp/nbody/old/nblocks.nix diff --git a/garlic/exp/nbody/scaling.nix b/garlic/exp/nbody/old/scaling.nix similarity index 100% rename from garlic/exp/nbody/scaling.nix rename to garlic/exp/nbody/old/scaling.nix diff --git a/garlic/exp/nbody/strong-scaling-oss.nix b/garlic/exp/nbody/old/strong-scaling-oss.nix similarity index 100% rename from garlic/exp/nbody/strong-scaling-oss.nix rename to garlic/exp/nbody/old/strong-scaling-oss.nix diff --git a/garlic/exp/nbody/weak-scaling-mpi.nix b/garlic/exp/nbody/old/weak-scaling-mpi.nix similarity index 100% rename from garlic/exp/nbody/weak-scaling-mpi.nix rename to garlic/exp/nbody/old/weak-scaling-mpi.nix diff --git a/garlic/exp/nbody/weak-scaling-oss.nix b/garlic/exp/nbody/old/weak-scaling-oss.nix similarity index 100% rename from garlic/exp/nbody/weak-scaling-oss.nix rename to garlic/exp/nbody/old/weak-scaling-oss.nix diff --git a/garlic/exp/nbody/strong-scaling-mpi.nix b/garlic/exp/nbody/strong-scaling-mpi.nix index b7e77c2129d1832c415ec2bbcc20a3c86881d3ac..3ca70411c207b0531013972602df59847451800d 100644 --- a/garlic/exp/nbody/strong-scaling-mpi.nix +++ b/garlic/exp/nbody/strong-scaling-mpi.nix @@ -4,37 +4,44 @@ , bsc , targetMachine , stages +, garlicTools }: with stdenv.lib; +with garlicTools; let # Initial variable configuration varConf = with bsc; { - numProcsAndParticles = [ 1 2 4 8 16 32 48 ]; + blocksize = [ 512 ]; + nodes = [ 1 2 4 8 16 ]; + gitBranch = [ + "garlic/mpi+send+oss+task" + "garlic/tampi+send+oss+task" + "garlic/tampi+isend+oss+task" + ]; }; # Generate the complete configuration for each unit - genConf = with bsc; c: targetMachine.config // rec { - # nbody options - inherit (c) numProcsAndParticles; - particles = 1024 * numProcsAndParticles * 2; + genConf = c: targetMachine.config // rec { + hw = targetMachine.config.hw; + particles = 16 * 4096 * hw.cpusPerSocket; timesteps = 10; - blocksize = 1024; - cc = icc; - mpi = impi; - gitBranch = "garlic/mpi+send"; + blocksize = c.blocksize; + numNodes = c.nodes; + gitBranch = c.gitBranch; + + expName = "nbody-scaling"; + unitName = expName + "-${toString gitBranch}" + "-nodes${toString numNodes}"; - # Repeat the execution of each unit 30 times loops = 30; - # Resources + nodes = numNodes; qos = "debug"; - ntasksPerNode = numProcsAndParticles; - nodes = 1; + ntasksPerNode = 2; time = "02:00:00"; - cpuBind = "sockets,verbose"; - jobName = "nbody-bs-${toString numProcsAndParticles}-${gitBranch}"; + cpusPerTask = hw.cpusPerSocket; + jobName = unitName; }; # Compute the array of configurations @@ -42,18 +49,14 @@ let inherit varConf genConf; }; - exec = {nextStage, conf, ...}: with conf; stages.exec { + exec = {nextStage, conf, ...}: stages.exec { inherit nextStage; - argv = [ "-t" timesteps "-p" particles ]; + argv = [ "-t" conf.timesteps "-p" conf.particles ]; }; - program = {nextStage, conf, ...}: with conf; - let - customPkgs = stdexp.replaceMpi conf.mpi; - in - customPkgs.apps.nbody.override { - inherit cc blocksize mpi gitBranch; - }; + program = {nextStage, conf, ...}: with conf; bsc.garlic.apps.nbody.override { + inherit (conf) blocksize gitBranch; + }; pipeline = stdexp.stdPipeline ++ [ exec program ]; diff --git a/garlic/fig/index.nix b/garlic/fig/index.nix index 63da83ebcb33a9033446a4ecd648867e022d61de..263a574dc3bcbf3ebf8a547d5203a0151ffc798f 100644 --- a/garlic/fig/index.nix +++ b/garlic/fig/index.nix @@ -30,11 +30,9 @@ let in { nbody = with exp.nbody; { - baseline = stdPlot ./nbody/baseline.R [ baseline ]; - small = stdPlot ./nbody/baseline.R [ small ]; - jemalloc = stdPlot ./nbody/jemalloc.R [ baseline jemalloc ]; - ctf = stdPlot ./nbody/baseline.R [ ctf ]; - scaling = stdPlot ./nbody/baseline.R [ scaling ]; + granularity = stdPlot ./nbody/granularity.R [ granularity ]; + nodesorsockets = stdPlot ./nbody/nodes-or-sockets.R [ nodesorsockets ]; + scaling = stdPlot ./nbody/scaling.R [ scaling ]; }; hpcg = with exp.hpcg; { diff --git a/garlic/fig/nbody/granularity.R b/garlic/fig/nbody/granularity.R new file mode 100644 index 0000000000000000000000000000000000000000..495f0e332096d8cefa3f710c8dd3db11c0c96fd1 --- /dev/null +++ b/garlic/fig/nbody/granularity.R @@ -0,0 +1,92 @@ +library(ggplot2) +library(dplyr, warn.conflicts = FALSE) +library(scales) +library(jsonlite) +library(viridis, warn.conflicts = FALSE) + +# Load the arguments (argv) +args = commandArgs(trailingOnly=TRUE) +if (length(args)>0) { input_file = args[1] } else { input_file = "input" } + +df = jsonlite::stream_in(file(input_file), verbose=FALSE) %>% + jsonlite::flatten() %>% + select(config.blocksize, config.gitBranch, unit, time) %>% + rename(blocksize=config.blocksize, branch=config.gitBranch) %>% + + mutate(blocksize = as.factor(blocksize)) %>% + mutate(branch = as.factor(branch)) %>% + mutate(unit = as.factor(unit)) %>% + + group_by(unit) %>% + + mutate(median.time = median(time)) %>% + mutate(normalized.time = time / median.time - 1) %>% + mutate(log.median.time = log(median.time)) %>% + + ungroup() + +dpi = 300 +h = 5 +w = 8 + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=blocksize, y=median.time, color=branch)) + + geom_point() + + geom_line(aes(group=branch)) + + theme_bw() + + labs(x="Blocksize", y="Median time (s)", title="NBody Granularity: Median Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("median.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("median.time.pdf", plot=p, width=w, height=h, dpi=dpi) + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=blocksize, y=normalized.time, color=branch)) + + geom_boxplot() + + geom_hline(yintercept=c(-0.01, 0.01), linetype="dashed", color="red") + + facet_wrap(~ branch) + + theme_bw() + + labs(x="Blocksize", y="Normalized Time", title="NBody Granularity: Normalized Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("normalized.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("normalized.time.pdf", plot=p, width=w, height=h, dpi=dpi) + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=blocksize, y=time, color=branch)) + + geom_point(shape=21, size=3) + + theme_bw() + + labs(x="Blocksize", y="Time (s)", title="NBody Granularity: Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time.pdf", plot=p, width=w, height=h, dpi=dpi) + + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=blocksize, y=branch, fill=median.time)) + + geom_raster() + + scale_fill_viridis(option="plasma") + + coord_fixed() + + theme_bw() + + labs(x="Blocksize", y="Branch", title="NBody Granularity: Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("time.heatmap.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time.heatmap.pdf", plot=p, width=w, height=h, dpi=dpi) diff --git a/garlic/fig/nbody/nodes-or-sockets.R b/garlic/fig/nbody/nodes-or-sockets.R new file mode 100644 index 0000000000000000000000000000000000000000..21b6b3fa75a82ad97e1abf73a1cc8234afb7dbe9 --- /dev/null +++ b/garlic/fig/nbody/nodes-or-sockets.R @@ -0,0 +1,168 @@ +library(ggplot2) +library(dplyr, warn.conflicts = FALSE) +library(scales) +library(jsonlite) +library(viridis, warn.conflicts = FALSE) + +# Load the arguments (argv) +args = commandArgs(trailingOnly=TRUE) +if (length(args)>0) { input_file = args[1] } else { input_file = "input" } + +dfNuma = jsonlite::stream_in(file(input_file), verbose=FALSE) %>% + jsonlite::flatten() %>% + select(config.blocksize, config.gitBranch, config.socketAtt, config.useNumact, unit, time) %>% + rename(blocksize=config.blocksize, branch=config.gitBranch, attachment=config.socketAtt, usenuma=config.useNumact) %>% + + mutate(blocksize = as.factor(blocksize)) %>% + mutate(branch = as.factor(branch)) %>% + mutate(attachment = as.factor(attachment)) %>% + mutate(usenuma = as.factor(usenuma)) %>% + mutate(unit = as.factor(unit)) %>% + + group_by(unit) %>% + + mutate(median.time = median(time)) %>% + mutate(normalized.time = time / median.time - 1) %>% + mutate(log.median.time = log(median.time)) %>% + + filter(usenuma == TRUE) %>% + + ungroup() + +dfNonuma = jsonlite::stream_in(file(input_file), verbose=FALSE) %>% + jsonlite::flatten() %>% + select(config.blocksize, config.gitBranch, config.socketAtt, config.useNumact, unit, time) %>% + rename(blocksize=config.blocksize, branch=config.gitBranch, attachment=config.socketAtt, usenuma=config.useNumact) %>% + + mutate(blocksize = as.factor(blocksize)) %>% + mutate(branch = as.factor(branch)) %>% + mutate(attachment = as.factor(attachment)) %>% + mutate(usenuma = as.factor(usenuma)) %>% + mutate(unit = as.factor(unit)) %>% + + group_by(unit) %>% + + mutate(median.time = median(time)) %>% + mutate(normalized.time = time / median.time - 1) %>% + mutate(log.median.time = log(median.time)) %>% + + filter(usenuma == FALSE) %>% + + ungroup() + +dpi = 300 +h = 5 +w = 8 + + +# --------------------------------------------------------------------- + +p = ggplot(dfNuma, aes(x=blocksize, y=median.time, color=attachment)) + + geom_point() + + geom_line(aes(group=attachment)) + + theme_bw() + + labs(x="Blocksize", y="Median time (s)", title="NBody Granularity (tampi+send+oss+task | numactl ON | 4 Nodes): Median Time", + subtitle=input_file, color="Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + +ggsave("median-numactl.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("median-numactl.time.pdf", plot=p, width=w, height=h, dpi=dpi) + +p = ggplot(dfNonuma, aes(x=blocksize, y=median.time, color=attachment)) + + geom_point() + + geom_line(aes(group=attachment)) + + theme_bw() + + labs(x="Blocksize", y="Median time (s)", title="NBody Granularity (tampi+send+oss+task | numactl OFF | 4 Nodes): Median Time", + subtitle=input_file, color="Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + +ggsave("median.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("median.time.pdf", plot=p, width=w, height=h, dpi=dpi) +# --------------------------------------------------------------------- + +p = ggplot(dfNuma, aes(x=blocksize, y=normalized.time, color=attachment)) + + geom_boxplot() + + geom_hline(yintercept=c(-0.01, 0.01), linetype="dashed", color="red") + + facet_wrap(~ attachment) + + theme_bw() + + labs(x="Blocksize", y="Normalized Time", title="NBody Granularity (tampi+send+oss+task | numactl ON | 4 Nodes): Normalized Time", + subtitle=input_file, color="Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + +ggsave("normalized-numactl.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("normalized-numactl.time.pdf", plot=p, width=w, height=h, dpi=dpi) + +p = ggplot(dfNonuma, aes(x=blocksize, y=normalized.time, color=attachment)) + + geom_boxplot() + + geom_hline(yintercept=c(-0.01, 0.01), linetype="dashed", color="red") + + facet_wrap(~ attachment) + + theme_bw() + + labs(x="Blocksize", y="Normalized Time", title="NBody Granularity (tampi+send+oss+task | 4 Nodes): Normalized Time", + subtitle=input_file, color="Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + +ggsave("normalized.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("normalized.time.pdf", plot=p, width=w, height=h, dpi=dpi) +# --------------------------------------------------------------------- + +p = ggplot(dfNuma, aes(x=blocksize, y=time, color=attachment)) + + geom_point(shape=21, size=3) + + theme_bw() + + labs(x="Blocksize", y="Time (s)", title="NBody Granularity (tampi+send+oss+task | numactl ON | 4 Nodes): Time", + subtitle=input_file, color="Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + +ggsave("time-numactl.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time-numactl.pdf", plot=p, width=w, height=h, dpi=dpi) + +p = ggplot(dfNonuma, aes(x=blocksize, y=time, color=attachment)) + + geom_point(shape=21, size=3) + + theme_bw() + + labs(x="Blocksize", y="Time (s)", title="NBody Granularity (tampi+send+oss+task | 4 Nodes): Time", + subtitle=input_file, color="Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + + +ggsave("time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time.pdf", plot=p, width=w, height=h, dpi=dpi) +# --------------------------------------------------------------------- + +p = ggplot(dfNuma, aes(x=blocksize, y=attachment, fill=median.time)) + + geom_raster() + + scale_fill_viridis(option="plasma") + + coord_fixed() + + theme_bw() + + labs(x="Blocksize", y="Attachment", title="NBody Granularity (tampi+send+oss+task | numactl ON | 4 Nodes): Time", + subtitle=input_file, color = "Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + +ggsave("time-numactl.heatmap.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time-numactl.heatmap.pdf", plot=p, width=w, height=h, dpi=dpi) + +p = ggplot(dfNonuma, aes(x=blocksize, y=attachment, fill=median.time)) + + geom_raster() + + scale_fill_viridis(option="plasma") + + coord_fixed() + + theme_bw() + + labs(x="Blocksize", y="Attachment", title="NBody Granularity (tampi+send+oss+task | 4 Nodes): Time", + subtitle=input_file, color = "Rank Attachment") + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + scale_color_manual(labels = c("RanksPerNode", "RanksPerSocket"), values=c("blue", "red")) + +ggsave("time.heatmap.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time.heatmap.pdf", plot=p, width=w, height=h, dpi=dpi) diff --git a/garlic/fig/nbody/baseline.R b/garlic/fig/nbody/old/baseline.R similarity index 100% rename from garlic/fig/nbody/baseline.R rename to garlic/fig/nbody/old/baseline.R diff --git a/garlic/fig/nbody/freeCpu.R b/garlic/fig/nbody/old/freeCpu.R similarity index 100% rename from garlic/fig/nbody/freeCpu.R rename to garlic/fig/nbody/old/freeCpu.R diff --git a/garlic/fig/nbody/jemalloc.R b/garlic/fig/nbody/old/jemalloc.R similarity index 100% rename from garlic/fig/nbody/jemalloc.R rename to garlic/fig/nbody/old/jemalloc.R diff --git a/garlic/fig/nbody/old/scaling.R b/garlic/fig/nbody/old/scaling.R new file mode 100644 index 0000000000000000000000000000000000000000..cf91a87f83b9788f895ddc340dc39eca3daae88c --- /dev/null +++ b/garlic/fig/nbody/old/scaling.R @@ -0,0 +1,110 @@ +library(ggplot2) +library(dplyr) +library(scales) +library(jsonlite) + +args=commandArgs(trailingOnly=TRUE) + +# Read the timetable from args[1] +input_file = "input.json" +if (length(args)>0) { input_file = args[1] } + +# Load the dataset in NDJSON format +dataset = jsonlite::stream_in(file(input_file)) %>% + jsonlite::flatten() + +particles = unique(dataset$config.particles) + +# We only need the nblocks and time +df = select(dataset, config.nblocks, config.hw.cpusPerSocket, time) %>% + rename(nblocks=config.nblocks, + cpusPerSocket=config.hw.cpusPerSocket) + +df = df %>% mutate(blocksPerCpu = nblocks / cpusPerSocket) +df$nblocks = as.factor(df$nblocks) +df$blocksPerCpuFactor = as.factor(df$blocksPerCpu) + +# Normalize the time by the median +D=group_by(df, nblocks) %>% + mutate(tnorm = time / median(time) - 1) %>% + mutate(bad = max(ifelse(abs(tnorm) >= 0.01, 1, 0))) + +D$bad = as.factor(D$bad) + +#D$bad = as.factor(ifelse(abs(D$tnorm) >= 0.01, 2, +# ifelse(abs(D$tnorm) >= 0.005, 1, 0))) + +bs_unique = unique(df$nblocks) +nbs=length(bs_unique) + +print(D) + +ppi=300 +h=5 +w=5 + +png("box.png", width=w*ppi, height=h*ppi, res=ppi) +# +# +# +# Create the plot with the normalized time vs nblocks +p = ggplot(data=D, aes(x=blocksPerCpuFactor, y=tnorm, color=bad)) + + + # Labels + labs(x="Blocks/CPU", y="Normalized time", + title=sprintf("Nbody normalized time. Particles=%d", particles), + subtitle=input_file) + + + + # Center the title + #theme(plot.title = element_text(hjust = 0.5)) + + + # Black and white mode (useful for printing) + #theme_bw() + + + # Add the maximum allowed error lines + geom_hline(yintercept=c(-0.01, 0.01), + linetype="dashed", color="gray") + + + # Draw boxplots + geom_boxplot() + + scale_color_manual(values=c("black", "brown")) + + + #scale_y_continuous(breaks = scales::pretty_breaks(n = 10)) + + + theme_bw() + + + theme(plot.subtitle=element_text(size=8)) + + theme(legend.position = "none") + #theme(legend.position = c(0.85, 0.85)) + + + + +# Render the plot +print(p) + +## Save the png image +dev.off() +# +png("scatter.png", width=w*ppi, height=h*ppi, res=ppi) +# +## Create the plot with the normalized time vs nblocks +p = ggplot(D, aes(x=blocksPerCpuFactor, y=time)) + + + labs(x="Blocks/CPU", y="Time (s)", + title=sprintf("Nbody granularity. Particles=%d", particles), + subtitle=input_file) + + theme_bw() + + theme(plot.subtitle=element_text(size=8)) + + theme(legend.position = c(0.5, 0.88)) + + + geom_point(shape=21, size=3) + + #scale_x_continuous(trans=log2_trans()) + + scale_y_continuous(trans=log2_trans()) + +# Render the plot +print(p) + +# Save the png image +dev.off() diff --git a/garlic/fig/nbody/scaling.R b/garlic/fig/nbody/scaling.R index cf91a87f83b9788f895ddc340dc39eca3daae88c..60a9e4a1c72b2172ee92ebe4dbad0f8eaa87f77f 100644 --- a/garlic/fig/nbody/scaling.R +++ b/garlic/fig/nbody/scaling.R @@ -1,110 +1,93 @@ library(ggplot2) -library(dplyr) +library(dplyr, warn.conflicts = FALSE) library(scales) library(jsonlite) - -args=commandArgs(trailingOnly=TRUE) - -# Read the timetable from args[1] -input_file = "input.json" -if (length(args)>0) { input_file = args[1] } - -# Load the dataset in NDJSON format -dataset = jsonlite::stream_in(file(input_file)) %>% - jsonlite::flatten() - -particles = unique(dataset$config.particles) - -# We only need the nblocks and time -df = select(dataset, config.nblocks, config.hw.cpusPerSocket, time) %>% - rename(nblocks=config.nblocks, - cpusPerSocket=config.hw.cpusPerSocket) - -df = df %>% mutate(blocksPerCpu = nblocks / cpusPerSocket) -df$nblocks = as.factor(df$nblocks) -df$blocksPerCpuFactor = as.factor(df$blocksPerCpu) - -# Normalize the time by the median -D=group_by(df, nblocks) %>% - mutate(tnorm = time / median(time) - 1) %>% - mutate(bad = max(ifelse(abs(tnorm) >= 0.01, 1, 0))) - -D$bad = as.factor(D$bad) - -#D$bad = as.factor(ifelse(abs(D$tnorm) >= 0.01, 2, -# ifelse(abs(D$tnorm) >= 0.005, 1, 0))) - -bs_unique = unique(df$nblocks) -nbs=length(bs_unique) - -print(D) - -ppi=300 -h=5 -w=5 - -png("box.png", width=w*ppi, height=h*ppi, res=ppi) -# -# -# -# Create the plot with the normalized time vs nblocks -p = ggplot(data=D, aes(x=blocksPerCpuFactor, y=tnorm, color=bad)) + - - # Labels - labs(x="Blocks/CPU", y="Normalized time", - title=sprintf("Nbody normalized time. Particles=%d", particles), - subtitle=input_file) + - - - # Center the title - #theme(plot.title = element_text(hjust = 0.5)) + - - # Black and white mode (useful for printing) - #theme_bw() + - - # Add the maximum allowed error lines - geom_hline(yintercept=c(-0.01, 0.01), - linetype="dashed", color="gray") + - - # Draw boxplots - geom_boxplot() + - scale_color_manual(values=c("black", "brown")) + - - #scale_y_continuous(breaks = scales::pretty_breaks(n = 10)) + - - theme_bw() + - - theme(plot.subtitle=element_text(size=8)) + - theme(legend.position = "none") - #theme(legend.position = c(0.85, 0.85)) - - - - -# Render the plot -print(p) - -## Save the png image -dev.off() -# -png("scatter.png", width=w*ppi, height=h*ppi, res=ppi) -# -## Create the plot with the normalized time vs nblocks -p = ggplot(D, aes(x=blocksPerCpuFactor, y=time)) + - - labs(x="Blocks/CPU", y="Time (s)", - title=sprintf("Nbody granularity. Particles=%d", particles), - subtitle=input_file) + - theme_bw() + - theme(plot.subtitle=element_text(size=8)) + - theme(legend.position = c(0.5, 0.88)) + - - geom_point(shape=21, size=3) + - #scale_x_continuous(trans=log2_trans()) + - scale_y_continuous(trans=log2_trans()) - -# Render the plot -print(p) - -# Save the png image -dev.off() +library(viridis, warn.conflicts = FALSE) + +# Load the arguments (argv) +args = commandArgs(trailingOnly=TRUE) +if (length(args)>0) { input_file = args[1] } else { input_file = "input" } + +df = jsonlite::stream_in(file(input_file), verbose=FALSE) %>% + jsonlite::flatten() %>% + select(config.blocksize, config.gitBranch, config.numNodes, unit, time) %>% + rename(nodes = config.numNodes, blocksize=config.blocksize, branch=config.gitBranch) %>% + + mutate(blocksize = as.factor(blocksize)) %>% + mutate(nodes = as.factor(nodes)) %>% + mutate(branch = as.factor(branch)) %>% + mutate(unit = as.factor(unit)) %>% + + group_by(unit) %>% + + mutate(median.time = median(time)) %>% + mutate(normalized.time = time / median.time - 1) %>% + mutate(log.median.time = log(median.time)) %>% + + ungroup() + +dpi = 300 +h = 5 +w = 8 + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=nodes, y=median.time, color=branch)) + + geom_point() + + geom_line(aes(group=branch)) + + theme_bw() + + labs(x="Nodes", y="Median time (s)", title="NBody Scaling: Median Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("median.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("median.time.pdf", plot=p, width=w, height=h, dpi=dpi) + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=nodes, y=normalized.time, color=branch)) + + geom_boxplot() + + geom_hline(yintercept=c(-0.01, 0.01), linetype="dashed", color="red") + + facet_wrap(~ branch) + + theme_bw() + + labs(x="Nodes", y="Normalized time (s)", title="NBody Scaling: Normalized Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("normalized.time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("normalized.time.pdf", plot=p, width=w, height=h, dpi=dpi) + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=nodes, y=time, color=branch)) + + geom_point(shape=21, size=3) + + theme_bw() + + labs(x="Nodes", y="Time (s)", title="NBody Scaling: Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("time.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time.pdf", plot=p, width=w, height=h, dpi=dpi) + + +# --------------------------------------------------------------------- + +p = ggplot(df, aes(x=nodes, y=branch, fill=median.time)) + + geom_raster() + + scale_fill_viridis(option="plasma") + + coord_fixed() + + theme_bw() + + labs(x="Nodes", y="Branch", title="NBody Scaling: Time", + subtitle=input_file) + + theme(plot.subtitle=element_text(size=5)) + + theme(legend.position="bottom") + + theme(legend.text = element_text(size=7)) + +ggsave("time.heatmap.png", plot=p, width=w, height=h, dpi=dpi) +ggsave("time.heatmap.pdf", plot=p, width=w, height=h, dpi=dpi)