66#include < RcppArmadillo.h>
77
88// we need OpenMP for parallelisation
9+ #include < omp.h>
910// [[Rcpp::plugins(openmp)]]
1011
12+
13+ // helper function for deciding number of threads
14+ static int check_nThreads (int nThreads) {
15+ // maximum number of threads available
16+ int maxThreads = omp_get_max_threads ();
17+
18+ if (nThreads <= 0 ) {
19+ // if nThreads is set to zero then use everything
20+ nThreads = maxThreads;
21+ }
22+ else if (nThreads > maxThreads) {
23+ // don't allow more threads than the maximum available
24+ nThreads = maxThreads;
25+ }
26+
27+ return nThreads;
28+ }
29+
30+
1131// function for finding row medians (alternative to apply(depth, 1, median))
1232// requires integer type matrix as input, returns list of doubles
1333// [[Rcpp::export]]
14- std::vector<double > rcpp_rowMedians (const arma::imat &depth) {
34+ std::vector<double > rcpp_rowMedians (const arma::imat &depth, int nThreads) {
35+ // set up number of threads
36+ nThreads = check_nThreads (nThreads);
37+
1538 // number of rows
1639 const int nrows = depth.n_rows ;
1740
1841 // vector for storing the result
1942 std::vector<double > medians (nrows);
2043
2144 // loop over the rows
22- #pragma omp parallel for
45+ #pragma omp parallel for num_threads(nThreads)
2346 for (int i = 0 ; i < nrows; i++) {
2447 // convert the row to double type, to compute median correctly
2548 arma::rowvec row = arma::conv_to<arma::rowvec>::from (depth.row (i));
@@ -34,14 +57,18 @@ std::vector<double> rcpp_rowMedians(const arma::imat &depth) {
3457// function for finding row maximums (alternative to apply(mat, 1, max))
3558// requires integer type matrix as input, return list of integers
3659// [[Rcpp::export]]
37- std::vector<int > rcpp_rowMaximums (const arma::imat &mat) {
60+ std::vector<int > rcpp_rowMaximums (const arma::imat &mat, int nThreads) {
61+ // set up number of threads
62+ nThreads = check_nThreads (nThreads);
63+
64+ // number of rows
3865 const int nrows = mat.n_rows ;
3966
4067 // create vector to store the result
4168 std::vector<int > maximums (nrows);
4269
4370 // loop over rows
44- #pragma omp parallel for
71+ #pragma omp parallel for num_threads(nThreads)
4572 for (int i = 0 ; i < nrows; i++) {
4673 // find the maximum for this row
4774 maximums[i] = mat.row (i).max ();
@@ -52,15 +79,18 @@ std::vector<int> rcpp_rowMaximums(const arma::imat &mat) {
5279
5380// C++ version of depth2K function
5481// [[Rcpp::export]]
55- Rcpp::NumericMatrix rcpp_depth2K (const Rcpp::NumericMatrix &A) {
82+ Rcpp::NumericMatrix rcpp_depth2K (const Rcpp::NumericMatrix &A, int nThreads) {
83+ // set up number of threads
84+ nThreads = check_nThreads (nThreads);
85+
5686 // create the output matrix (same size as input)
5787 Rcpp::NumericMatrix Aout (A.rows (), A.cols ());
5888
5989 // number of elements
6090 const long Asize = A.rows () * A.cols ();
6191
6292 // loop over elements in parallel and apply operation
63- #pragma omp parallel for
93+ #pragma omp parallel for num_threads(nThreads)
6494 for (long i = 0 ; i < Asize; i++) {
6595 Aout[i] = 1.0 / pow (2.0 , A[i]);
6696 }
@@ -71,15 +101,18 @@ Rcpp::NumericMatrix rcpp_depth2K(const Rcpp::NumericMatrix &A) {
71101
72102// C++ version of depth2Kmodp function
73103// [[Rcpp::export]]
74- Rcpp::NumericMatrix rcpp_depth2Kmodp (const Rcpp::NumericMatrix &depthvals, double modp = 0.5 ) {
104+ Rcpp::NumericMatrix rcpp_depth2Kmodp (const Rcpp::NumericMatrix &depthvals, double modp, int nThreads) {
105+ // set up number of threads
106+ nThreads = check_nThreads (nThreads);
107+
75108 // create matrix for storing the result
76109 Rcpp::NumericMatrix result (depthvals.rows (), depthvals.cols ());
77110
78111 // size of the matrix
79112 const long size = depthvals.rows () * depthvals.cols ();
80113
81114 // loop over the elements in parallel
82- #pragma omp parallel for
115+ #pragma omp parallel for num_threads(nThreads)
83116 for (long i = 0 ; i < size; i++) {
84117 double value = 0.5 * pow (modp, depthvals[i] - 1.0 );
85118 result[i] = (value == 0 ) ? 1.0 : value;
@@ -89,15 +122,17 @@ Rcpp::NumericMatrix rcpp_depth2Kmodp(const Rcpp::NumericMatrix &depthvals, doubl
89122
90123// C++ version of depth2Kbb function
91124// [[Rcpp::export]]
92- Rcpp::NumericMatrix rcpp_depth2Kbb (const Rcpp::NumericMatrix & depthvals, const double alph = 9999 ) {
125+ Rcpp::NumericMatrix rcpp_depth2Kbb (const Rcpp::NumericMatrix & depthvals, int nThreads, const double alph = 9999 ) {
126+ // set up number of threads
127+ nThreads = check_nThreads (nThreads);
93128 // create matrix for storing the result
94129 Rcpp::NumericMatrix result (depthvals.rows (), depthvals.cols ());
95130 // size of the matrix
96131 const long size = depthvals.rows () * depthvals.cols ();
97132 // precompute factor
98133 const double factor = 1.0 /R::beta (alph, alph);
99134 // loop over the elements in parallel
100- #pragma omp parallel for
135+ #pragma omp parallel for num_threads(nThreads)
101136 for (long i = 0 ; i < size; i++) {
102137 result[i] = R::beta (alph, depthvals[i] + alph) * factor;
103138 }
@@ -109,12 +144,15 @@ Rcpp::NumericMatrix rcpp_depth2Kmodp(const Rcpp::NumericMatrix &depthvals, doubl
109144// modifies the matrices in-place (i.e. doesn't return anything)
110145// [[Rcpp::export]]
111146void rcpp_assignP0P1Genon01 (Rcpp::NumericMatrix &P0, Rcpp::NumericMatrix &P1, Rcpp::NumericMatrix &genon01,
112- const Rcpp::LogicalMatrix &usegeno, const Rcpp::NumericMatrix &dsub) {
147+ const Rcpp::LogicalMatrix &usegeno, const Rcpp::NumericMatrix &dsub, int nThreads) {
148+ // set up number of threads
149+ nThreads = check_nThreads (nThreads);
150+
113151 // number of elements (assumes all inputs are the same size!)
114152 const long size = P0.rows () * P0.cols ();
115153
116154 // loop over elements in parallel
117- #pragma omp parallel for
155+ #pragma omp parallel for num_threads(nThreads)
118156 for (long i = 0 ; i < size; i++) {
119157 // set to zero if they match the conditions
120158 if (dsub[i] < 2.0 ) {
0 commit comments