From 51190fe49827498189bc0a4b30d5400a0c1694d1 Mon Sep 17 00:00:00 2001 From: Lukas Schneiderbauer Date: Sun, 29 Dec 2024 16:58:33 +0100 Subject: [PATCH] add `avx_enabled()` --- NAMESPACE | 1 + NEWS.md | 2 +- R/cpp11.R | 4 +++ R/openmp.R | 28 --------------- R/sys_support.R | 58 +++++++++++++++++++++++++++++++ _pkgdown.yml | 5 +-- man/avx_enabled.Rd | 29 ++++++++++++++++ man/openmp_enabled.Rd | 11 ++++-- src/cpp11.cpp | 8 +++++ src/interface_fcwt.cpp | 9 +++++ tests/testthat/test-openmp.R | 5 --- tests/testthat/test-sys_support.R | 11 ++++++ 12 files changed, 132 insertions(+), 39 deletions(-) delete mode 100644 R/openmp.R create mode 100644 R/sys_support.R create mode 100644 man/avx_enabled.Rd delete mode 100644 tests/testthat/test-openmp.R create mode 100644 tests/testthat/test-sys_support.R diff --git a/NAMESPACE b/NAMESPACE index d359139..04f573c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,6 +8,7 @@ S3method(plot,fcwtr_scalogram) S3method(print,fcwtr_scalogram) S3method(rbind,fcwtr_scalogram) S3method(tibble::as_tibble,fcwtr_scalogram) +export(avx_enabled) export(du) export(fcwt) export(fcwt_batch) diff --git a/NEWS.md b/NEWS.md index 53e1530..44c91bd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -18,7 +18,7 @@ - add more convenience S3 methods: `print()`, `[]`, `as.matrix()`, `rbind()`, `as_tibble()`. -- `openmp_enabled()`: new function to check for OpenMP support. +- `openmp_enabled()`/`avx_enabled()` new function to check for system OpenMP/AVX support. - add a [package logo](https://lschneiderbauer.github.io/fCWTr/logo.svg) diff --git a/R/cpp11.R b/R/cpp11.R index 9efe60e..b73c173 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -4,6 +4,10 @@ has_openmp <- function() { .Call(`_fCWTr_has_openmp`) } +has_avx <- function() { + .Call(`_fCWTr_has_avx`) +} + fcwt_raw <- function(signal, fs, f0, f1, fn, sigma, nthreads, scaletype, optplans, abs) { .Call(`_fCWTr_fcwt_raw`, signal, fs, f0, f1, fn, sigma, nthreads, scaletype, optplans, abs) } diff --git a/R/openmp.R b/R/openmp.R deleted file mode 100644 index 92c1ec3..0000000 --- a/R/openmp.R +++ /dev/null @@ -1,28 +0,0 @@ - -#' Check for OpenMP support -#' -#' This function checks if OpenMP support is enabled. It is responsible for -#' the multithreading capabilities of [fcwt()]. If OpenMP is not enabled -#' the parameter `n_threads` of [fcwt()] is ignored. -#' -#' @details -#' OpenMP can be used by the underlying fCWT library if -#' * the fftw library on your platform was compiled with OpenMP support and -#' * the fCWTr package itself was compiled with OpenMP support. -#' -#' When using pre-built package binaries (like it is typical when you are using -#' R on Windows), whether or not these conditions are met, depend on the (CRAN) -#' build server. They cannot be influenced by the package author. -#' -#' If the user is building the R package yourself, the user needs to make sure -#' that the fftw library on her platform are built with OpenMP support. -#' The fCWTr package is configured to use OpenMP if fftw-OpenMP support is -#' available. -#' -#' @return ( `TRUE` | `FALSE` ) -#' Returns `TRUE` if OpenMP support is enabled, `FALSE` otherwise. -#' -#' @export -openmp_enabled <- function() { - has_openmp() -} diff --git a/R/sys_support.R b/R/sys_support.R new file mode 100644 index 0000000..566330d --- /dev/null +++ b/R/sys_support.R @@ -0,0 +1,58 @@ + +#' Check for OpenMP support +#' +#' This function checks if OpenMP support is enabled. It is responsible for +#' the multithreading capabilities of [fcwt()]. If OpenMP is not enabled +#' the parameter `n_threads` of [fcwt()] is ignored. +#' +#' @details +#' OpenMP can be used by the underlying fCWT library if +#' * the fftw library on your platform was compiled with OpenMP support and +#' * the fCWTr package itself was compiled with OpenMP support. +#' +#' When using pre-built package binaries (like it is typical when you are using +#' R on Windows), it depends on the (CRAN) build server whether or not +#' these conditions are met. They cannot be influenced by the package author. +#' +#' If the user is building the R package yourself, the user needs to make sure +#' that the fftw library on her platform are built with OpenMP support. +#' The fCWTr package is configured to use OpenMP if fftw-OpenMP support is +#' available. +#' +#' @return ( `TRUE` | `FALSE` ) +#' Returns `TRUE` if OpenMP support is enabled, `FALSE` otherwise. +#' +#' @examples +#' openmp_enabled() +#' +#' @export +#' @concept sys_support +openmp_enabled <- function() { + has_openmp() +} + + +#' Check for AVX instruction set support +#' +#' This function checks if fCWTr was compiled with AVX instruction set support. +#' AVX instructions need to be supported by the users' CPU in order for this +#' to work. +#' +#' @details +#' By default, most compiler setups do not make use of AVX to increase +#' portability of the binary. If you are an R user that has a CPU supporting +#' AVX and want to make use of it, you might need to manually enable compiler +#' flags to let R know about it, and install the package from source +#' (so that it gets compiled on your machine). +#' +#' @return ( `TRUE` | `FALSE` ) +#' Returns `TRUE` if AVX support is enabled, `FALSE` otherwise. +#' +#' @examples +#' avx_enabled() +#' +#' @export +#' @concept sys_support +avx_enabled <- function() { + has_avx() +} diff --git a/_pkgdown.yml b/_pkgdown.yml index a32334a..4abb9e5 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -21,9 +21,10 @@ reference: - print.fcwtr_scalogram - plot.fcwtr_scalogram - autoplot.fcwtr_scalogram -- title: "Multithreading support" +- title: "System support" + desc: "Helper functions that let you check if your platform provides OpenMP or AVX support." contents: - - openmp_enabled + - has_concept("sys_support") - title: "Sample data" desc: > Sample signal data mainly used to generate examples. The signals consist diff --git a/man/avx_enabled.Rd b/man/avx_enabled.Rd new file mode 100644 index 0000000..55cd115 --- /dev/null +++ b/man/avx_enabled.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/sys_support.R +\name{avx_enabled} +\alias{avx_enabled} +\title{Check for AVX instruction set support} +\usage{ +avx_enabled() +} +\value{ +( \code{TRUE} | \code{FALSE} ) +Returns \code{TRUE} if AVX support is enabled, \code{FALSE} otherwise. +} +\description{ +This function checks if fCWTr was compiled with AVX instruction set support. +AVX instructions need to be supported by the users' CPU in order for this +to work. +} +\details{ +By default, most compiler setups do not make use of AVX to increase +portability of the binary. If you are an R user that has a CPU supporting +AVX and want to make use of it, you might need to manually enable compiler +flags to let R know about it, and install the package from source +(so that it gets compiled on your machine). +} +\examples{ +avx_enabled() + +} +\concept{sys_support} diff --git a/man/openmp_enabled.Rd b/man/openmp_enabled.Rd index a0faeb0..97bc669 100644 --- a/man/openmp_enabled.Rd +++ b/man/openmp_enabled.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/openmp.R +% Please edit documentation in R/sys_support.R \name{openmp_enabled} \alias{openmp_enabled} \title{Check for OpenMP support} @@ -23,11 +23,16 @@ OpenMP can be used by the underlying fCWT library if } When using pre-built package binaries (like it is typical when you are using -R on Windows), whether or not these conditions are met, depend on the (CRAN) -build server. They cannot be influenced by the package author. +R on Windows), it depends on the (CRAN) build server whether or not +these conditions are met. They cannot be influenced by the package author. If the user is building the R package yourself, the user needs to make sure that the fftw library on her platform are built with OpenMP support. The fCWTr package is configured to use OpenMP if fftw-OpenMP support is available. } +\examples{ +openmp_enabled() + +} +\concept{sys_support} diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 42e5281..67f6f2f 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -13,6 +13,13 @@ extern "C" SEXP _fCWTr_has_openmp() { END_CPP11 } // interface_fcwt.cpp +cpp11::r_bool has_avx(); +extern "C" SEXP _fCWTr_has_avx() { + BEGIN_CPP11 + return cpp11::as_sexp(has_avx()); + END_CPP11 +} +// interface_fcwt.cpp std::vector fcwt_raw(std::vector signal, int fs, double f0, double f1, int fn, double sigma, int nthreads, bool scaletype, bool optplans, bool abs); extern "C" SEXP _fCWTr_fcwt_raw(SEXP signal, SEXP fs, SEXP f0, SEXP f1, SEXP fn, SEXP sigma, SEXP nthreads, SEXP scaletype, SEXP optplans, SEXP abs) { BEGIN_CPP11 @@ -23,6 +30,7 @@ extern "C" SEXP _fCWTr_fcwt_raw(SEXP signal, SEXP fs, SEXP f0, SEXP f1, SEXP fn, extern "C" { static const R_CallMethodDef CallEntries[] = { {"_fCWTr_fcwt_raw", (DL_FUNC) &_fCWTr_fcwt_raw, 10}, + {"_fCWTr_has_avx", (DL_FUNC) &_fCWTr_has_avx, 0}, {"_fCWTr_has_openmp", (DL_FUNC) &_fCWTr_has_openmp, 0}, {NULL, NULL, 0} }; diff --git a/src/interface_fcwt.cpp b/src/interface_fcwt.cpp index f8a181b..78be54c 100644 --- a/src/interface_fcwt.cpp +++ b/src/interface_fcwt.cpp @@ -28,6 +28,15 @@ cpp11::r_bool has_openmp() { #endif } +[[cpp11::register]] +cpp11::r_bool has_avx() { + #ifdef AVX + return(false); + #else + return(true); + #endif +} + [[cpp11::register]] std::vector fcwt_raw( std::vector signal, diff --git a/tests/testthat/test-openmp.R b/tests/testthat/test-openmp.R deleted file mode 100644 index 57bb0db..0000000 --- a/tests/testthat/test-openmp.R +++ /dev/null @@ -1,5 +0,0 @@ -test_that("openmp() works", { - expect_true( - openmp_enabled() == TRUE | openmp_enabled() == FALSE - ) -}) diff --git a/tests/testthat/test-sys_support.R b/tests/testthat/test-sys_support.R new file mode 100644 index 0000000..9ed6bf0 --- /dev/null +++ b/tests/testthat/test-sys_support.R @@ -0,0 +1,11 @@ +test_that("openmp_enabled() works", { + expect_true( + openmp_enabled() == TRUE | openmp_enabled() == FALSE + ) +}) + +test_that("avx_enabled() works", { + expect_true( + avx_enabled() == TRUE | avx_enabled() == FALSE + ) +})