--- title: "Executing `koma` in Parallel" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{parallel} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(koma) ``` ## Introduction This vignette demonstrates how to use the `future::plan` function to run `koma` package functions either sequentially or in parallel, depending on your operating system and other preferences. For more details, see the [future package documentation](https://CRAN.R-project.org/package=future). ## Preliminaries Install the `future` and `parallelly` packages: ```{R install-future-parallelly, eval=FALSE} install.packages("future") install.packages("parallelly") ``` We will use the simulated data contained in `koma` to illustrate the use of `future::plan`. The setup is the following: ```{R model-setup} library(koma) equations <- "consumption ~ gdp + consumption.L(1), investment ~ investment.L(1), exports ~ world_gdp + exports.L(1), imports ~ domestic_demand + imports.L(1), prices ~ exchange_rate + oil_price + prices.L(1), interest_rate ~ prices + interest_rate_germany + prices.L(1), gdp == 0.6*consumption + 0.6*domestic_demand + 0.5*exports - 0.4*imports, domestic_demand == 0.6*consumption + 0.4*investment" exogenous_variables <- c("world_gdp", "interest_rate_germany", "exchange_rate", "oil_price") dates <- list( estimation = list(start = c(1996, 1), end = c(2019, 4)), forecast = list(start = c(2023, 1), end = c(2023, 4)) ) sys_eq <- system_of_equations(equations, exogenous_variables) series <- names(small_open_economy) series <- series[!series %in% c("interest_rate", "interest_rate_germany")] ts_data <- lapply(series, function(x) { as_ets(small_open_economy[[x]], series_type = "level", method = "diff_log" ) }) names(ts_data) <- series ts_data$interest_rate <- as_ets(small_open_economy$interest_rate, series_type = "rate", method = "none" ) ts_data$interest_rate_germany <- as_ets(small_open_economy$interest_rate_germany, series_type = "rate", method = "none" ) ``` ## Sequential Execution By default, R executes code sequentially. For example: ```{R sequential-exec, eval=FALSE} estimates <- estimate(ts_data, sys_eq, dates) ``` ## Parallel Execution with `future::plan` To enable parallel execution, you can use `future::plan`. The type of parallel execution depends on your operating system or whether you are running the code on a cluster. #### Worker Setup You need to define the number of workers that your parallel job to run on. Here we use all cores except one. ```{R workers, eval=FALSE} # Get the available workers workers <- parallelly::availableCores(omit = 1) ``` ### Windows For Windows, you can use **multisession**: ```{R multisession, eval=FALSE} future::plan("future::multisession", workers = workers) estimates <- estimate(ts_data, sys_eq, dates) ``` ### Linux On Linux, you can use **multicore** (fork-based, lower overhead): ```{R multicore, eval=FALSE} future::plan("future::multicore", workers = workers) estimates <- estimate(ts_data, sys_eq, dates) ``` ### macOS On macOS, **do not use `multicore`**. Apple's Accelerate framework (the BLAS/LAPACK backend used by `eigen()`) relies on Grand Central Dispatch internally, which is not fork-safe. Forked workers will segfault with "invalid permissions" inside `eigen()`. Use **multisession** instead — it spawns fresh R processes rather than forking: ```{R multisession-macos, eval=FALSE} future::plan("future::multisession", workers = workers) estimates <- estimate(ts_data, sys_eq, dates) ```