## tests for 'multicore' and 'snow': _not_ run automatically

runMC <- FALSE

if (runMC) {

    require("NMOF")
    require("RUnit")
    require("rbenchmark")


    ## packages for distr. computing/testing
    if (!require("multicore", quietly = TRUE))
        warning("package 'multicore' not available")
    if (!require("snow", quietly = TRUE))
        warning("package 'snow' not available")
    if (!require("RUnit", quietly = TRUE))
        warning("package 'RUnit' not available")

    ## packages for parallel random numbers
    if (!require("rlecuyer", quietly = TRUE))
        warning("package 'rlecuyer' not available")
    if (!require("rsprng", quietly = TRUE))
        warning("package 'rsprng' not available")



    ## a generic test: is function slow enough for multicore?
    testFun <- function(ignore, delay) {
        Sys.sleep(delay)
        1
    }
    delay <- 0.01  ## running time of function
    n <- 8         ## how many calls per lapply
    repl <- 10     ## how many restarts
    sq <- seq_len(n)
    benchmark(lapply(sq, testFun, delay),
              mclapply(sq, testFun, delay),
              columns = c("test", "replications", "elapsed", "relative"),
              order = "relative", replications = repl)



    ## gridSearch ##
    testFun  <- function(x) {
        Sys.sleep(0.1)
        x[1L] + x[2L]^2
    }
    lower <- 1:2; upper <- 5; n <- 5
    cat(system.time(sol1 <- gridSearch(fun = testFun,
                                       lower = lower, upper = upper,
                                       n = n, printDetail = FALSE)))
    cat(system.time(sol2 <- gridSearch(fun = testFun,
                                       lower = lower, upper = upper,
                                       n = n, printDetail = FALSE,
                                       method = "multicore")))
    cat(system.time(sol3 <- gridSearch(fun = testFun,
                                       lower = lower, upper = upper,
                                       n = n, printDetail = FALSE,
                                       method = "snow", cl = 2L)))
    checkEquals(sol1, sol2)
    checkEquals(sol1, sol3)
    checkEquals(sol3$minlevels, 1:2)

    ## ... with additional argument 'k'
    testFun  <- function(x, k) {
        Sys.sleep(0.1)
        x[1L] + x[2L]^2+k
    }
    lower <- 1:2; upper <- 5; n <- 5; k <- 1
    system.time(sol1 <- gridSearch(fun = testFun,k=k,
                                   lower = lower, upper = upper,
                                   n = n, printDetail = FALSE))
    system.time(sol2 <- gridSearch(fun = testFun,k=k,
                                   lower = lower, upper = upper,
                                   n = n, printDetail = FALSE,
                                   method = "multicore"))
    system.time(sol3 <- gridSearch(fun = testFun,k=k,
                                   lower = lower, upper = upper,
                                   n = n, printDetail = FALSE,
                                   method = "snow", cl = 2L))
    checkEquals(sol1, sol2)
    checkEquals(sol1, sol3)
    checkEquals(sol3$minlevels, 1:2)

    ## ... seeds
    testFun  <- function(x) {
        Sys.sleep(0.1)
        x[1L] + x[2L] + runif(1)
    }
    lower <- 1:2; upper <- 5; n <- 3
    set.seed(5)
    sol2 <- gridSearch(fun = testFun,
                       lower = lower, upper = upper,
                       n = n, printDetail = FALSE,
                       method = "multicore",
                       mc.control = list(mc.set.seed = FALSE))
    temp <- sol2$values
    set.seed(5)
    sol2 <- gridSearch(fun = testFun,
                       lower = lower, upper = upper,
                       n = n, printDetail = FALSE,
                       method = "multicore",
                       mc.control = list(mc.set.seed = FALSE))
    checkEquals(sol2$values, temp)


    cl <- makeCluster(c(rep("localhost", 2)), type = "SOCK")
    clusterSetupSPRNG(cl, seed=rep(12345, 2))
    sol3 <- gridSearch(fun = testFun,
                       lower = lower, upper = upper,
                       n = n, printDetail = FALSE,
                       method = "snow", cl = cl)
    stopCluster(cl)
    temp <- sol3$values
    cl <- makeCluster(c(rep("localhost", 2)), type = "SOCK")
    ##clusterSetupRNGstream (cl, seed=rep(12345, 2))
    clusterSetupSPRNG(cl, seed=rep(12345, 2))
    sol3 <- gridSearch(fun = testFun,
                       lower = lower, upper = upper,
                       n = n, printDetail = FALSE,
                       method = "snow", cl = cl)
    stopCluster(cl)
    checkEquals(sol3$values, temp)


    cl <- makeCluster(c(rep("localhost", 2)), type = "SOCK")
    clusterSetupRNGstream (cl, seed=rep(12345, 2))
    sol3 <- gridSearch(fun = testFun,
                       lower = lower, upper = upper,
                       n = n, printDetail = FALSE,
                       method = "snow", cl = cl)
    stopCluster(cl)
    temp <- sol3$values
    cl <- makeCluster(c(rep("localhost", 2)), type = "SOCK")
    clusterSetupRNGstream (cl, seed=rep(12345, 2))
    sol3 <- gridSearch(fun = testFun,
                       lower = lower, upper = upper,
                       n = n, printDetail = FALSE,
                       method = "snow", cl = cl)
    stopCluster(cl)
    checkEquals(sol3$values, temp)



    ## bracketing ##
    testFun <- function(x) {
        Sys.sleep(0.1)
        cos(1/x^2)
    }
    system.time(sol1 <- bracketing(testFun, interval = c(0.3, 0.9),
                                   n = 100L))
    system.time(sol2 <- bracketing(testFun, interval = c(0.3, 0.9),
                                   n = 100L, method = "multicore"))
    system.time(sol3 <- bracketing(testFun, interval = c(0.3, 0.9),
                                   n = 100L, method = "snow", cl = 2L))
    checkEquals(sol1, sol2)
    checkEquals(sol1, sol3)


    ## restartOpt ##
    xTRUE <- runif(5L)
    data <- list(xTRUE = xTRUE, step = 0.02)
    OF <- function(x, data)
        max(abs(x - data$xTRUE))
    neighbour <- function(x, data)
        x + runif(length(data$xTRUE))*data$step - data$step/2
    x0 <- runif(5L)
    algo <- list(q = 0.05, nS = 100L, nT = 5L,
                 neighbour = neighbour, x0 = x0,
                 printBar = FALSE, printDetail = FALSE)
    system.time(sols1 <- restartOpt(fun = TAopt, n = 100L,
                                    OF = OF, algo = algo, data = data))
    checkEquals(length(sols1), 100L)
    system.time(sols2 <- restartOpt(fun = TAopt, n = 100L,
                                    OF = OF, algo = algo, data = data,
                                    method = "multicore"))
    checkEquals(length(sols2), 100L)
    system.time(sols3 <- restartOpt(fun = TAopt, n = 100L,
                                    OF = OF, algo = algo, data = data,
                                    method = "snow", cl = 2L))
    checkEquals(length(sols3), 100L)



    ## GAopt ##
    size <- 20L            ## the length of the string
    OF <- function(x, y) { ## the objective function
        Sys.sleep(0.02)
        sum(x != y)
    }
    y <- runif(size) > 0.5 ## the true solution
    algo <- list(nB = size, nP = 20L, nG = 10L, prob = 0.002,
                 printBar = FALSE, methodOF = "loop")
    system.time(sol <- GAopt(OF, algo = algo, y = y))

    algo <- list(nB = size, nP = 20L, nG = 10L, prob = 0.002,
                 printBar = FALSE, methodOF = "snow", cl = 2L)
    system.time(sol <- GAopt(OF, algo = algo, y = y))

    algo <- list(nB = size, nP = 20L, nG = 10L, prob = 0.002,
                 printBar = FALSE, methodOF = "multicore")
    system.time(sol <- GAopt(OF, algo = algo, y = y))

    ## test: pass argument to multicore
    algo <- list(nB = size, nP = 20L, nG = 10L, prob = 0.002,
                 printBar = FALSE, methodOF = "multicore",
                 ## nothing to gain from mc
                 mc.control = list(mc.cores = 1L))
    system.time(sol <- GAopt(OF, algo = algo, y = y))


}

