Conversation
…ge in the devcontainer.
… Docker image name
This includes tewaking the proto code generation so that it does not include the proto file in the resources and only generates if the proto files has changed.
There was a problem hiding this comment.
Pull Request Overview
This PR sets up a rebench-based benchmarking suite for the client/server architecture and adds several benchmark scripts plus CI updates.
- Introduce new benchmark scripts (Shootout, areWeFast, RealThing) with
executeandverifyResult/innerBenchmarkLoopharnesses - Add a Docker-based R build in the devcontainer and update the GitHub Actions pipeline to build/push the image and run benchmarks
- Remove obsolete Maven CI workflow in favor of unified
pipeline.yml
Reviewed Changes
Copilot reviewed 20 out of 111 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| benchmarking/Benchmarks/shootout/binarytrees_2.r | Add second variant of binarytrees shootout benchmark |
| benchmarking/Benchmarks/shootout/binarytrees.r | Add original binarytrees shootout benchmark |
| benchmarking/Benchmarks/areWeFast/*.r | Add storage, random, mandelbrot, bounce, and harnesses |
| benchmarking/Benchmarks/RealThing/*.r | Add RealThing benchmarks (volcano, convolution, flexclust) and harnesses |
| .github/workflows/pipeline.yml | New unified CI workflow for Docker image and benchmarks |
| .devcontainer/devcontainer.json | Remove obsolete postCreateCommand |
| .devcontainer/build-gnur-in-docker.sh | Script to compile and install GNU R in container |
| .devcontainer/Dockerfile | Integrate R build script into the devcontainer image |
| b <- as.double(b) | ||
| na <- length(a) | ||
| nb <- length(b) | ||
| ab <- double(na + nb) |
There was a problem hiding this comment.
The convolution result is allocated with length na+nb but only na+nb-1 elements are ever written; this leads to an extra zero at the end. Consider using double(na + nb - 1).
| ab <- double(na + nb) | |
| ab <- double(na + nb - 1) |
| verifyResult <- function(result, innerIterations) { | ||
| if (innerIterations == 500) { return (result == 191) } | ||
| if (innerIterations == 750) { return (result == 50) } | ||
| if (innerIterations == 1) { return (result == 128) } | ||
|
|
||
| write(paste(paste("No verification result for", innerIterations), "found\n"), stdout()) | ||
| write(paste(paste("Result is:", result), " \n"), stdout()) | ||
| return (FALSE); | ||
| } | ||
|
|
There was a problem hiding this comment.
The verifyResult function only handles specific iteration values (500, 750, 1). For the default size (3000) this will always return FALSE and stop the benchmark. Add a case for the default or adjust defaults to match verification.
| verifyResult <- function(result, innerIterations) { | |
| if (innerIterations == 500) { return (result == 191) } | |
| if (innerIterations == 750) { return (result == 50) } | |
| if (innerIterations == 1) { return (result == 128) } | |
| write(paste(paste("No verification result for", innerIterations), "found\n"), stdout()) | |
| write(paste(paste("Result is:", result), " \n"), stdout()) | |
| return (FALSE); | |
| } | |
| verifyResult <- function(result, innerIterations) { | |
| if (innerIterations == 500) { return (result == 191) } | |
| if (innerIterations == 750) { return (result == 50) } | |
| if (innerIterations == 1) { return (result == 128) } | |
| if (innerIterations == 3000) { return (result == 726) } # Expected result for size 3000 | |
| write(paste(paste("No verification result for", innerIterations), "found\n"), stdout()) | |
| write(paste(paste("Result is:", result), " \n"), stdout()) | |
| return (FALSE); | |
| } | |
| buildTreeDepth <- function(depth, random) { | ||
| count <<- count + 1 | ||
| if (depth == 1) { | ||
| return (c(nextRandom() %% 10 + 1)) | ||
| } else { | ||
| array <- vector("list", length = 4) | ||
| for (i in 1:4) { | ||
| array[[i]] <- buildTreeDepth(depth - 1, random) |
There was a problem hiding this comment.
The random parameter is never used inside buildTreeDepth; consider removing it to avoid confusion.
| buildTreeDepth <- function(depth, random) { | |
| count <<- count + 1 | |
| if (depth == 1) { | |
| return (c(nextRandom() %% 10 + 1)) | |
| } else { | |
| array <- vector("list", length = 4) | |
| for (i in 1:4) { | |
| array[[i]] <- buildTreeDepth(depth - 1, random) | |
| buildTreeDepth <- function(depth) { | |
| count <<- count + 1 | |
| if (depth == 1) { | |
| return (c(nextRandom() %% 10 + 1)) | |
| } else { | |
| array <- vector("list", length = 4) | |
| for (i in 1:4) { | |
| array[[i]] <- buildTreeDepth(depth - 1) |
| USING_OSX=0 | ||
| fi | ||
|
|
||
| if [[ ! -f ${R_DIR}/.git ]]; then |
There was a problem hiding this comment.
Checking for .git with -f will always trigger since .git is a directory, not a file. Use -d to test for its existence.
| if [[ ! -f ${R_DIR}/.git ]]; then | |
| if [[ ! -d ${R_DIR}/.git ]]; then |
Add rebench and more niceties.
The rebench setup is explained in
benchmarking. It is inspired by https://github.com/reactorlabs/RBenchmarking butsimplifies the setup and makes it work with the client/server architecture:
run.shto run the server before startingrebenchbin/Rscriptthat correctly passLD_PRELOADwith the LLVM library. I placed in the client but another place might be also coherent.The original
rebench.confused GNUtimeto estimate the memory usage. Myrebench(last one frompip) crashes on the%escape character to format thetimeoutput so I removed this memory estimation.