The objective is to make the chain-fork instances denser (and slightly more difficult). Also, we will make two more specific figures (one for the CV and one for the size) for a specific pair of values for k and m.
The generation method has been adapated to fill the void.
NB <- 10
n_s <- c(10, 30, 100)
k_s <- c(1, 2, 4, 8)
mk_s <- c(1, 2, 3, 5)
CV_s <- c(0.1, 0.2, 0.3, 0.5, 1)
data <- NULL
for (n in n_s)
for (k in k_s)
for (m in k * mk_s)
for (CV in CV_s)
for (func in c("chain_indep", "chain_fork"))
for (i in 1:NB) {
g <- get(func)(m, k, n, CV)
schedule <- HEFT(m, k, g)
LB <- LB_europar(cbind(get.vertex.attribute(g, "CPU"),
get.vertex.attribute(g, "GPU")), m, k)
params <- data.frame(func = func, n = n, m = m, k = k, CV = CV,
num = i, CP = CP(g), LB_europar = LB,
HEFT = schedule$mks)
data <- rbind(data, params)
}
Let’s plot the general plot:
data %>%
mutate(ratio = HEFT / pmax(CP, LB_europar)) %>%
ggplot(aes(x = ratio)) +
geom_histogram() +
facet_grid(m / k ~ k)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Some ratios below 1 were due to a bug in the back-filling implementation of HEFT. It has been fixed.
The lower bound works best when there are as much CPUs as GPUs. The worst is when there are much more CPUs than GPUs.
Let’s analyze the distribution by method:
library(knitr)
data %>%
mutate(ratio = HEFT / pmax(CP, LB_europar)) %>%
group_by(func) %>%
do(data_frame_(summary(.$ratio))) %>%
kable()
func | Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. |
---|---|---|---|---|---|---|
chain_indep | 1 | 1.000000 | 1.000000 | 1.061797 | 1.074030 | 1.912787 |
chain_fork | 1 | 1.014301 | 1.168269 | 1.200384 | 1.315632 | 2.182986 |
data %>%
mutate(ratio = HEFT / pmax(CP, LB_europar)) %>%
group_by(func) %>%
do(data_frame_(quantile(.$ratio, probs = seq(0.2, 0.9, 0.1)))) %>%
kable()
func | 20% | 30% | 40% | 50% | 60% | 70% | 80% | 90% |
---|---|---|---|---|---|---|---|---|
chain_indep | 1 | 1.000000 | 1.00000 | 1.000000 | 1.012290 | 1.055409 | 1.095315 | 1.185268 |
chain_fork | 1 | 1.053859 | 1.10868 | 1.168269 | 1.224646 | 1.285161 | 1.349184 | 1.457351 |
The lower bound works well for chain_indep in most cases (below 10% in more than three quarters of the cases) and reasonably for chain_fork (below 20% in more than half the cases).
set.seed(1)
NB <- 30
n <- 100
k <- 4
mk <- 5
m <- k * mk
CV_s <- c(0.1, 0.2, 0.3, 0.5, 1)
dir_name <- "15_denser_random_graphs/instances/CV"
dir.create(dir_name, showWarnings = FALSE, recursive = TRUE)
for (CV in CV_s)
for (func in c("chain_indep", "chain_fork"))
for (i in 1:NB) {
print(c(n, m, k, CV, func, i))
name <- paste(func, n, m, k, CV, i, sep = "_") %>%
paste("dot", sep = ".")
name <- paste(dir_name, name, sep = "/")
g <- get(func)(m, k, n, CV)
write_graph_str(g, name, "dot")
schedule <- HEFT(m, k, g)
name_HEFT <- paste(name, "HEFT", sep = ".")
capture.output(schedule, file = name_HEFT)
LB <- LB_europar(cbind(get.vertex.attribute(g, "CPU"),
get.vertex.attribute(g, "GPU")), m, k)
params <- data.frame(func = func, n = n, m = m, k = k, CV = CV,
num = i, CP = CP(g), LB_europar = LB,
HEFT = schedule$mks)
name_params <- paste(name, "params", sep = ".")
write.table(params, name_params, row.names = FALSE, sep = ",")
}
PARAM=CV
RESULT=result_$PARAM.csv
> $RESULT
k=4
m=$((k * 5))
rm -rf src/input/$PARAM
mkdir -p src/input/$PARAM
cp instances/$PARAM/*.dot src/input/$PARAM
./src/test -m $m -k $k -i src/input/$PARAM
grep "[^0-9]\+_[0-9]*_$m\_$k\_" output_$m-$k.dat >> $RESULT
head -n 1 output_$m-$k.dat > $RESULT.tmp
cat $RESULT >> $RESULT.tmp
mv $RESULT.tmp $RESULT
sed -i "s/\t/,/g" $RESULT
sed -i "s/ //g" $RESULT
for file in $(awk -F',' 'NR>1 { print "instances/'"$PARAM"'/" $1 ".params" }' $RESULT)
do
header=$(head -n 1 $file)
tail -n 1 $file
done > $RESULT.tmp1
paste $RESULT <(echo $header; cat $RESULT.tmp1) > $RESULT.tmp2
rm $RESULT.tmp1
mv $RESULT.tmp2 $RESULT
data <- read.csv("15_denser_random_graphs/result_CV.csv")
data %>%
mutate(LB = pmax(CP, LB_europar)) %>%
gather(algo, mks, QALS, ERLS, MxQE, EFiT, Quik, Rati, HEFT) %>%
mutate(algo = factor(algo, levels = c("HEFT", "MxQE", "EFiT", "QALS", "ERLS",
"Rati", "Quik"))) %>%
ggplot(aes(x = factor(CV), y = mks / LB, col = algo)) +
geom_boxplot() +
facet_wrap(~ func, ncol = 1)
Differences in performance are higher when the CV is low. Also the differences are more stable.
set.seed(2)
NB <- 30
n_s <- c(30, 50, 100, 200, 300)
k <- 4
mk <- 5
m <- k * mk
CV <- 0.3
dir_name <- "15_denser_random_graphs/instances/n"
dir.create(dir_name, showWarnings = FALSE, recursive = TRUE)
for (n in n_s)
for (func in c("chain_indep", "chain_fork"))
for (i in 1:NB) {
print(c(n, m, k, CV, func, i))
name <- paste(func, n, m, k, CV, i, sep = "_") %>%
paste("dot", sep = ".")
name <- paste(dir_name, name, sep = "/")
g <- get(func)(m, k, n, CV)
write_graph_str(g, name, "dot")
schedule <- HEFT(m, k, g)
name_HEFT <- paste(name, "HEFT", sep = ".")
capture.output(schedule, file = name_HEFT)
LB <- LB_europar(cbind(get.vertex.attribute(g, "CPU"),
get.vertex.attribute(g, "GPU")), m, k)
params <- data.frame(func = func, n = n, m = m, k = k, CV = CV,
num = i, CP = CP(g), LB_europar = LB,
HEFT = schedule$mks)
name_params <- paste(name, "params", sep = ".")
write.table(params, name_params, row.names = FALSE, sep = ",")
}
PARAM=n
RESULT=result_$PARAM.csv
> $RESULT
k=4
m=$((k * 5))
rm -rf src/input/$PARAM
mkdir -p src/input/$PARAM
cp instances/$PARAM/*.dot src/input/$PARAM
./src/test -m $m -k $k -i src/input/$PARAM
grep "[^0-9]\+_[0-9]*_$m\_$k\_" output_$m-$k.dat >> $RESULT
head -n 1 output_$m-$k.dat > $RESULT.tmp
cat $RESULT >> $RESULT.tmp
mv $RESULT.tmp $RESULT
sed -i "s/\t/,/g" $RESULT
sed -i "s/ //g" $RESULT
for file in $(awk -F',' 'NR>1 { print "instances/'"$PARAM"'/" $1 ".params" }' $RESULT)
do
header=$(head -n 1 $file)
tail -n 1 $file
done > $RESULT.tmp1
paste $RESULT <(echo $header; cat $RESULT.tmp1) > $RESULT.tmp2
rm $RESULT.tmp1
mv $RESULT.tmp2 $RESULT
data <- read.csv("15_denser_random_graphs/result_n.csv")
data %>%
mutate(LB = pmax(CP, LB_europar)) %>%
gather(algo, mks, QALS, ERLS, MxQE, EFiT, Quik, Rati, HEFT) %>%
mutate(algo = factor(algo, levels = c("HEFT", "MxQE", "EFiT", "QALS", "ERLS",
"Rati", "Quik"))) %>%
ggplot(aes(x = factor(n), y = mks / LB, col = algo)) +
geom_boxplot() +
facet_wrap(~ func, ncol = 1)
The tendencies are exagerated and more stable with a large number of tasks.
set.seed(3)
NB <- 30
n <- 100
k_s <- c(1, 2, 4, 6, 8)
mk <- 5
CV <- 0.3
dir_name <- "15_denser_random_graphs/instances/k"
dir.create(dir_name, showWarnings = FALSE, recursive = TRUE)
for (k in k_s)
for (func in c("chain_indep", "chain_fork"))
for (i in 1:NB) {
m <- k * mk
print(c(n, m, k, CV, func, i))
name <- paste(func, n, m, k, CV, i, sep = "_") %>%
paste("dot", sep = ".")
name <- paste(dir_name, name, sep = "/")
g <- get(func)(m, k, n, CV)
write_graph_str(g, name, "dot")
schedule <- HEFT(m, k, g)
name_HEFT <- paste(name, "HEFT", sep = ".")
capture.output(schedule, file = name_HEFT)
LB <- LB_europar(cbind(get.vertex.attribute(g, "CPU"),
get.vertex.attribute(g, "GPU")), m, k)
params <- data.frame(func = func, n = n, m = m, k = k, CV = CV,
num = i, CP = CP(g), LB_europar = LB,
HEFT = schedule$mks)
name_params <- paste(name, "params", sep = ".")
write.table(params, name_params, row.names = FALSE, sep = ",")
}
PARAM=k
RESULT=result_$PARAM.csv
> $RESULT
for k in 1 2 4 6 8
do
m=$((k * 5))
rm -rf src/input/$PARAM
mkdir -p src/input/$PARAM
cp instances/$PARAM/*_$m\_$k\_*.dot src/input/$PARAM
./src/test -m $m -k $k -i src/input/$PARAM
grep "[^0-9]\+_[0-9]*_$m\_$k\_" output_$m-$k.dat >> $RESULT
done
head -n 1 output_$m-$k.dat > $RESULT.tmp
cat $RESULT >> $RESULT.tmp
mv $RESULT.tmp $RESULT
sed -i "s/\t/,/g" $RESULT
sed -i "s/ //g" $RESULT
for file in $(awk -F',' 'NR>1 { print "instances/'"$PARAM"'/" $1 ".params" }' $RESULT)
do
header=$(head -n 1 $file)
tail -n 1 $file
done > $RESULT.tmp1
paste $RESULT <(echo $header; cat $RESULT.tmp1) > $RESULT.tmp2
rm $RESULT.tmp1
mv $RESULT.tmp2 $RESULT
data <- read.csv("15_denser_random_graphs/result_k.csv")
data %>%
mutate(LB = pmax(CP, LB_europar)) %>%
gather(algo, mks, QALS, ERLS, MxQE, EFiT, Quik, Rati, HEFT) %>%
mutate(algo = factor(algo, levels = c("HEFT", "MxQE", "EFiT", "QALS", "ERLS",
"Rati", "Quik"))) %>%
ggplot(aes(x = factor(k), y = mks / LB, col = algo)) +
geom_boxplot() +
facet_wrap(~ func, ncol = 1)
Large numbers of GPU yield less stable results.
set.seed(4)
NB <- 30
n <- 100
k <- 4
mk_s <- c(1, 2, 3, 5, 10)
CV <- 0.3
dir_name <- "15_denser_random_graphs/instances/mk"
dir.create(dir_name, showWarnings = FALSE, recursive = TRUE)
for (mk in mk_s)
for (func in c("chain_indep", "chain_fork"))
for (i in 1:NB) {
m <- k * mk
print(c(n, m, k, CV, func, i))
name <- paste(func, n, m, k, CV, i, sep = "_") %>%
paste("dot", sep = ".")
name <- paste(dir_name, name, sep = "/")
g <- get(func)(m, k, n, CV)
write_graph_str(g, name, "dot")
schedule <- HEFT(m, k, g)
name_HEFT <- paste(name, "HEFT", sep = ".")
capture.output(schedule, file = name_HEFT)
LB <- LB_europar(cbind(get.vertex.attribute(g, "CPU"),
get.vertex.attribute(g, "GPU")), m, k)
params <- data.frame(func = func, n = n, m = m, k = k, CV = CV,
num = i, CP = CP(g), LB_europar = LB,
HEFT = schedule$mks)
name_params <- paste(name, "params", sep = ".")
write.table(params, name_params, row.names = FALSE, sep = ",")
}
PARAM=mk
RESULT=result_$PARAM.csv
> $RESULT
k=4
for mk in 1 2 3 5 10
do
m=$((k * mk))
rm -rf src/input/$PARAM
mkdir -p src/input/$PARAM
cp instances/$PARAM/*_$m\_$k\_*.dot src/input/$PARAM
./src/test -m $m -k $k -i src/input/$PARAM
grep "[^0-9]\+_[0-9]*_$m\_$k\_" output_$m-$k.dat >> $RESULT
done
head -n 1 output_$m-$k.dat > $RESULT.tmp
cat $RESULT >> $RESULT.tmp
mv $RESULT.tmp $RESULT
sed -i "s/\t/,/g" $RESULT
sed -i "s/ //g" $RESULT
for file in $(awk -F',' 'NR>1 { print "instances/'"$PARAM"'/" $1 ".params" }' $RESULT)
do
header=$(head -n 1 $file)
tail -n 1 $file
done > $RESULT.tmp1
paste $RESULT <(echo $header; cat $RESULT.tmp1) > $RESULT.tmp2
rm $RESULT.tmp1
mv $RESULT.tmp2 $RESULT
data <- read.csv("15_denser_random_graphs/result_mk.csv")
data %>%
mutate(LB = pmax(CP, LB_europar)) %>%
gather(algo, mks, QALS, ERLS, MxQE, EFiT, Quik, Rati, HEFT) %>%
mutate(algo = factor(algo, levels = c("HEFT", "MxQE", "EFiT", "QALS", "ERLS",
"Rati", "Quik"))) %>%
ggplot(aes(x = factor(m / k), y = mks / LB, col = algo)) +
geom_boxplot() +
facet_wrap(~ func, ncol = 1)
Significant effect: large differences between the number of CPUs and GPUs lead to large differences in the performance of the algorithms.
set.seed(5)
NB <- 30
n <- 100
k <- 4
mk <- 5
CV <- 0.3
mean_cost_s <- 1:5
dir_name <- "15_denser_random_graphs/instances/mean_cost"
dir.create(dir_name, showWarnings = FALSE, recursive = TRUE)
for (mean_cost in mean_cost_s)
for (func in c("chain_indep", "chain_fork"))
for (i in 1:NB) {
m <- k * mk
print(c(n, m, k, mean_cost, CV, func, i))
name <- paste(func, n, m, k, mean_cost, CV, i, sep = "_") %>%
paste("dot", sep = ".")
name <- paste(dir_name, name, sep = "/")
g <- get(func)(m, k, n, CV, tau = mean_cost)
write_graph_str(g, name, "dot")
schedule <- HEFT(m, k, g)
name_HEFT <- paste(name, "HEFT", sep = ".")
capture.output(schedule, file = name_HEFT)
LB <- LB_europar(cbind(get.vertex.attribute(g, "CPU"),
get.vertex.attribute(g, "GPU")), m, k)
params <- data.frame(func = func, n = n, m = m, k = k, CV = CV,
num = i, mean_cost = mean_cost, CP = CP(g),
LB_europar = LB, HEFT = schedule$mks)
name_params <- paste(name, "params", sep = ".")
write.table(params, name_params, row.names = FALSE, sep = ",")
}
PARAM=mean_cost
RESULT=result_$PARAM.csv
> $RESULT
k=4
m=$((k * 5))
rm -rf src/input/$PARAM
mkdir -p src/input/$PARAM
cp instances/$PARAM/*_$m\_$k\_*.dot src/input/$PARAM
./src/test -m $m -k $k -i src/input/$PARAM
grep "[^0-9]\+_[0-9]*_$m\_$k\_" output_$m-$k.dat >> $RESULT
head -n 1 output_$m-$k.dat > $RESULT.tmp
cat $RESULT >> $RESULT.tmp
mv $RESULT.tmp $RESULT
sed -i "s/\t/,/g" $RESULT
sed -i "s/ //g" $RESULT
for file in $(awk -F',' 'NR>1 { print "instances/'"$PARAM"'/" $1 ".params" }' $RESULT)
do
header=$(head -n 1 $file)
tail -n 1 $file
done > $RESULT.tmp1
paste $RESULT <(echo $header; cat $RESULT.tmp1) > $RESULT.tmp2
rm $RESULT.tmp1
mv $RESULT.tmp2 $RESULT
data <- read.csv("15_denser_random_graphs/result_mean_cost.csv")
data %>%
mutate(LB = pmax(CP, LB_europar)) %>%
gather(algo, mks, QALS, ERLS, MxQE, EFiT, Quik, Rati, HEFT) %>%
mutate(algo = factor(algo, levels = c("HEFT", "MxQE", "EFiT", "QALS", "ERLS",
"Rati", "Quik"))) %>%
ggplot(aes(x = factor(mean_cost), y = mks / LB, col = algo)) +
geom_boxplot() +
facet_wrap(~ func, ncol = 1)
Some effect. In particular, Quic and Rati are impacted but the tendencies are unclear. However, the performance of QALS and ERLS decreases when the ratio between the costs increases.
This partial exploration:
The next step is to proceed with random layered graphs and cholesky DAGs.
## R version 3.4.3 (2017-11-30)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.3 LTS
##
## Matrix products: default
## BLAS: /usr/lib/openblas-base/libblas.so.3
## LAPACK: /usr/lib/libopenblasp-r0.2.18.so
##
## locale:
## [1] LC_CTYPE=fr_FR.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=fr_FR.UTF-8 LC_COLLATE=fr_FR.UTF-8
## [5] LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8
## [7] LC_PAPER=fr_FR.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] knitr_1.15.1 bindrcpp_0.2 igraph_1.0.1 ggplot2_2.2.1 dplyr_0.7.4
## [6] tidyr_0.2.0 purrr_0.2.0 stringr_1.2.0
##
## loaded via a namespace (and not attached):
## [1] Rcpp_0.12.10 bindr_0.1 magrittr_1.5 munsell_0.4
## [5] colorspace_1.2-2 R6_2.1.0 rlang_0.1.6 highr_0.3
## [9] plyr_1.8.1 tools_3.4.3 grid_3.4.3 gtable_0.1.2
## [13] pacman_0.4.6 htmltools_0.3.6 lazyeval_0.2.0 yaml_2.1.13
## [17] rprojroot_1.2 digest_0.6.3 assertthat_0.1 tibble_1.3.1
## [21] reshape2_1.2.2 glue_1.2.0 evaluate_0.10 rmarkdown_1.8
## [25] labeling_0.1 stringi_0.5-5 compiler_3.4.3 scales_0.4.1
## [29] backports_1.0.5 pkgconfig_2.0.1