Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speedup render by avoiding repeated vector copies. #176

Merged
merged 10 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ jobs:
steps:
- uses: actions/checkout@v2

- uses: r-lib/actions/setup-r@v1
- uses: r-lib/actions/setup-r@v2

- uses: r-lib/actions/setup-pandoc@v1
- uses: r-lib/actions/setup-pandoc@v2

- name: Query dependencies
run: |
Expand Down
14 changes: 13 additions & 1 deletion R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,18 @@ integer_ragged_variable_queue_shrink_bitset <- function(variable, index) {
invisible(.Call(`_individual_integer_ragged_variable_queue_shrink_bitset`, variable, index))
}

create_render_vector <- function(data) {
.Call(`_individual_create_render_vector`, data)
}

render_vector_update <- function(v, index, value) {
invisible(.Call(`_individual_render_vector_update`, v, index, value))
}

render_vector_data <- function(v) {
.Call(`_individual_render_vector_data`, v)
}

execute_process <- function(process, timestep) {
invisible(.Call(`_individual_execute_process`, process, timestep))
}
Expand All @@ -455,5 +467,5 @@ variable_resize <- function(variable) {

# Register entry points for exported C++ functions
methods::setLoadAction(function(ns) {
.Call('_individual_RcppExport_registerCCallable', PACKAGE = 'individual')
.Call(`_individual_RcppExport_registerCCallable`)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change comes from an Rcpp change at RcppCore/Rcpp#1256

})
10 changes: 5 additions & 5 deletions R/render.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Render <- R6Class(
#' @param timesteps number of timesteps in the simulation.
initialize = function(timesteps) {
private$.timesteps = timesteps
private$.vectors[['timestep']] <- seq_len(timesteps)
private$.vectors[['timestep']] <- create_render_vector(seq_len(timesteps))
},

#' @description
Expand All @@ -28,7 +28,7 @@ Render <- R6Class(
if (name == 'timestep') {
stop("Cannot set default value for variable 'timestep'")
}
private$.vectors[[name]] = rep(value, private$.timesteps)
private$.vectors[[name]] = create_render_vector(rep(value, private$.timesteps))
plietar marked this conversation as resolved.
Show resolved Hide resolved
},

#' @description
Expand All @@ -41,15 +41,15 @@ Render <- R6Class(
stop("Please don't name your variable 'timestep'")
}
if (!(name %in% names(private$.vectors))) {
private$.vectors[[name]] = rep(NA, private$.timesteps)
private$.vectors[[name]] = create_render_vector(rep(NA, private$.timesteps))
plietar marked this conversation as resolved.
Show resolved Hide resolved
}
private$.vectors[[name]][[timestep]] = value
render_vector_update(private$.vectors[[name]], timestep, value)
},

#' @description
#' Return the render as a \code{\link[base]{data.frame}}.
to_dataframe = function() {
data.frame(private$.vectors)
data.frame(lapply(private$.vectors, render_vector_data))
}
)
)
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Individual <img src='man/figures/logo.png' align="right" height="139" />
# Individual <img src='man/figures/logo.png' align="right" style="height:139px !important" />

<!-- badges: start -->
[![R build status](https://github.com/mrc-ide/individual/workflows/R-CMD-check/badge.svg)](https://github.com/mrc-ide/individual/actions)
[![R build status](https://github.com/mrc-ide/individual/actions/workflows/R-CMD-check.yaml/badge.svg?branch=dev)](https://github.com/mrc-ide/individual/actions)
[![codecov.io](https://codecov.io/github/mrc-ide/individual/coverage.svg)](https://codecov.io/github/mrc-ide/individual)
[![CRAN](https://www.r-pkg.org/badges/version/individual)](https://cran.r-project.org/package=individual)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
Expand Down
36 changes: 36 additions & 0 deletions inst/include/RenderVector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* RenderVector.h
*
* Created on: 21 Dec 2023
* Author: pl2113
*/

#ifndef INST_INCLUDE_RENDER_VECTOR_H_
#define INST_INCLUDE_RENDER_VECTOR_H_

#include <Rcpp.h>

/**
* A thin wrapper around a NumericVector, used to provide by-reference
* semantics and guaranteed in-place mutation in the Render class.
*
*/
struct RenderVector {
RenderVector(Rcpp::NumericVector data) : _data(data) { }

void update(size_t index, float value) {
if (index < 1 || index > _data.size()) {
Rcpp::stop("index out-of-bounds");

Check warning on line 23 in inst/include/RenderVector.h

View check run for this annotation

Codecov / codecov/patch

inst/include/RenderVector.h#L23

Added line #L23 was not covered by tests
}
_data[index - 1] = value;
}

const Rcpp::NumericVector& data() const {
return _data;
}

private:
Rcpp::NumericVector _data;
};

#endif /* INST_INCLUDE_RENDER_VECTOR_H_ */
1 change: 1 addition & 0 deletions inst/include/individual_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
#include "RaggedInteger.h"
#include "RaggedDouble.h"
#include "Event.h"
#include "RenderVector.h"

#endif /* INDIVIDUAL_TYPES_H_ */
39 changes: 38 additions & 1 deletion src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,40 @@ BEGIN_RCPP
return R_NilValue;
END_RCPP
}
// create_render_vector
Rcpp::XPtr<RenderVector> create_render_vector(Rcpp::NumericVector data);
RcppExport SEXP _individual_create_render_vector(SEXP dataSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::NumericVector >::type data(dataSEXP);
rcpp_result_gen = Rcpp::wrap(create_render_vector(data));
return rcpp_result_gen;
END_RCPP
}
// render_vector_update
void render_vector_update(Rcpp::XPtr<RenderVector> v, size_t index, float value);
RcppExport SEXP _individual_render_vector_update(SEXP vSEXP, SEXP indexSEXP, SEXP valueSEXP) {
BEGIN_RCPP
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::XPtr<RenderVector> >::type v(vSEXP);
Rcpp::traits::input_parameter< size_t >::type index(indexSEXP);
Rcpp::traits::input_parameter< float >::type value(valueSEXP);
render_vector_update(v, index, value);
return R_NilValue;
END_RCPP
}
// render_vector_data
Rcpp::NumericVector render_vector_data(Rcpp::XPtr<RenderVector> v);
RcppExport SEXP _individual_render_vector_data(SEXP vSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::XPtr<RenderVector> >::type v(vSEXP);
rcpp_result_gen = Rcpp::wrap(render_vector_data(v));
return rcpp_result_gen;
END_RCPP
}
// execute_process
void execute_process(Rcpp::XPtr<process_t> process, size_t timestep);
RcppExport SEXP _individual_execute_process(SEXP processSEXP, SEXP timestepSEXP) {
Expand Down Expand Up @@ -1362,7 +1396,7 @@ RcppExport SEXP _individual_RcppExport_registerCCallable() {
return R_NilValue;
}

RcppExport SEXP run_testthat_tests(SEXP);
RcppExport SEXP run_testthat_tests(void *);

static const R_CallMethodDef CallEntries[] = {
{"_individual_create_bitset", (DL_FUNC) &_individual_create_bitset, 1},
Expand Down Expand Up @@ -1475,6 +1509,9 @@ static const R_CallMethodDef CallEntries[] = {
{"_individual_integer_ragged_variable_queue_extend", (DL_FUNC) &_individual_integer_ragged_variable_queue_extend, 2},
{"_individual_integer_ragged_variable_queue_shrink", (DL_FUNC) &_individual_integer_ragged_variable_queue_shrink, 2},
{"_individual_integer_ragged_variable_queue_shrink_bitset", (DL_FUNC) &_individual_integer_ragged_variable_queue_shrink_bitset, 2},
{"_individual_create_render_vector", (DL_FUNC) &_individual_create_render_vector, 1},
{"_individual_render_vector_update", (DL_FUNC) &_individual_render_vector_update, 3},
{"_individual_render_vector_data", (DL_FUNC) &_individual_render_vector_data, 1},
{"_individual_execute_process", (DL_FUNC) &_individual_execute_process, 2},
{"_individual_variable_get_size", (DL_FUNC) &_individual_variable_get_size, 1},
{"_individual_variable_update", (DL_FUNC) &_individual_variable_update, 1},
Expand Down
26 changes: 26 additions & 0 deletions src/render_vector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* render_vector.cpp
*
* Created on: 21 Dec 2023
* Author: pl2113
*/


#include "../inst/include/RenderVector.h"
#include <Rcpp.h>


//[[Rcpp::export]]
Rcpp::XPtr<RenderVector> create_render_vector(Rcpp::NumericVector data) {
return Rcpp::XPtr<RenderVector>(new RenderVector(data), true);
plietar marked this conversation as resolved.
Show resolved Hide resolved
}

//[[Rcpp::export]]
void render_vector_update(Rcpp::XPtr<RenderVector> v, size_t index, float value) {
plietar marked this conversation as resolved.
Show resolved Hide resolved
v->update(index, value);
}

//[[Rcpp::export]]
Rcpp::NumericVector render_vector_data(Rcpp::XPtr<RenderVector> v) {
return v->data();
}
Loading