Skip to content

Commit c531cba

Browse files
committed
tidy cpp code
1 parent 2da5b4e commit c531cba

13 files changed

+416
-362
lines changed

configure

Lines changed: 104 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,106 @@
1-
#!/bin/sh
2-
3-
# Set the number of cores
4-
if [ -z "$PKG_NCORES" ]; then
5-
PKG_NCORES=$(getconf _NPROCESSORS_ONLN)
6-
if [ -z "$PKG_NCORES" ] || [ "$PKG_NCORES" -lt 1 ]; then
7-
PKG_NCORES=1
8-
elif [ "$PKG_NCORES" -gt 1 ]; then
9-
PKG_NCORES=$((PKG_NCORES - 1))
10-
fi
1+
# Anticonf script by Pacha (2025)
2+
3+
PKG_CONFIG_NAME="capybara"
4+
5+
# Parse command line arguments
6+
for arg in "$@"; do
7+
case "$arg" in
8+
--enable-optimization)
9+
ENABLE_OPTIMIZATION=yes
10+
;;
11+
esac
12+
done
13+
14+
# Find compiler
15+
CXX=$(${R_HOME}/bin/R CMD config CXX)
16+
CXXFLAGS=$(${R_HOME}/bin/R CMD config CXXFLAGS)
17+
CPPFLAGS=$(${R_HOME}/bin/R CMD config CPPFLAGS)
18+
19+
# Set optimization flags if requested
20+
OPTIMIZATION_FLAGS=""
21+
if [ "$ENABLE_OPTIMIZATION" = "yes" ]; then
22+
OPTIMIZATION_FLAGS="-O3 -funroll-loops"
23+
24+
# Check for AVX2 support
25+
if grep -q avx2 /proc/cpuinfo 2>/dev/null; then
26+
OPTIMIZATION_FLAGS="$OPTIMIZATION_FLAGS -mavx2"
27+
fi
28+
29+
echo "Using optimization flags: $OPTIMIZATION_FLAGS"
30+
else
31+
echo "Not using optimization flags"
32+
fi
33+
34+
# Check for OpenMP support
35+
OPENMP_FLAG=""
36+
for flag in -fopenmp -qopenmp -openmp -xopenmp; do
37+
save_CXXFLAGS="$CXXFLAGS"
38+
CXXFLAGS="$CXXFLAGS $flag"
39+
40+
echo "int main() { return 0; }" | $CXX -xc++ -E $CXXFLAGS - >/dev/null 2>&1
41+
if [ $? -eq 0 ]; then
42+
OPENMP_FLAG="$flag"
43+
break
44+
fi
45+
CXXFLAGS="$save_CXXFLAGS"
46+
done
47+
48+
if [ -n "$OPENMP_FLAG" ]; then
49+
echo "OpenMP is enabled: $OPENMP_FLAG"
50+
PKG_CXXFLAGS="$OPENMP_FLAG $PKG_CXXFLAGS"
51+
PKG_LIBS="$OPENMP_FLAG $PKG_LIBS"
52+
else
53+
echo "OpenMP is disabled"
1154
fi
1255

13-
# Write Makevars
14-
sed -e "s|@ncores@|$PKG_NCORES|" \
15-
src/Makevars.in > src/Makevars
16-
56+
# Determine number of cores using OpenMP if available
57+
if [ -n "$CAPYBARA_NCORES" ]; then
58+
num_cores="$CAPYBARA_NCORES"
59+
echo "using environment value: $num_cores"
60+
else
61+
cat > nthreads.cpp << 'EOL'
62+
#include <iostream>
63+
#ifdef _OPENMP
64+
#include <omp.h>
65+
#endif
66+
67+
int main() {
68+
int nthreads;
69+
#ifdef _OPENMP
70+
nthreads = std::max(1, (omp_get_max_threads() + 1) / 2);
71+
#else
72+
nthreads = 1;
73+
#endif
74+
std::cout << nthreads << std::endl;
75+
return 0;
76+
}
77+
EOL
78+
79+
# Need to compile WITH the OpenMP flag
80+
if [ -n "$OPENMP_FLAG" ]; then
81+
$CXX nthreads.cpp -o nthreads $OPENMP_FLAG
82+
else
83+
$CXX nthreads.cpp -o nthreads
84+
fi
85+
86+
# Check if compilation succeeded
87+
if [ $? -eq 0 ] && [ -x ./nthreads ]; then
88+
num_cores=$(./nthreads)
89+
echo "Number of available cores: $num_cores"
90+
else
91+
echo "OpenMP test failed, defaulting to 1"
92+
num_cores=1
93+
fi
94+
95+
# Clean up
96+
rm -f nthreads nthreads.cpp
97+
fi
98+
99+
# Write to Makevars
100+
echo "creating src/Makevars"
101+
sed -e "s|@ncores@|${num_cores}|g" \
102+
-e "s|@OPTIMIZATION_FLAGS@|${OPTIMIZATION_FLAGS}|g" \
103+
src/Makevars.in > src/Makevars
104+
105+
# Success
106+
exit 0

src/00_main.h

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <armadillo.hpp>
12
#include <cpp11.hpp>
23
#include <cpp11armadillo.hpp>
34
#include <regex>
@@ -8,44 +9,26 @@ using namespace cpp11;
89

910
// used across the scripts
1011

11-
#ifdef _OPENMP
12-
const size_t n_threads = omp_get_max_threads();
13-
#endif
14-
1512
void center_variables_(mat &V, const vec &w, const list &klist,
16-
const double &tol, const size_t &maxiter,
17-
const size_t &interrupt_iter);
13+
const double &tol, const int &maxiter);
1814

1915
vec solve_beta_(mat MX, const mat &MNU, const vec &w);
2016

2117
vec solve_eta_(const mat &MX, const mat &MNU, const vec &nu, const vec &beta);
2218

2319
mat crossprod_(const mat &X, const vec &w);
2420

25-
// Enum for GLM family types
26-
enum FamilyType {
27-
GAUSSIAN,
28-
POISSON,
29-
BINOMIAL,
30-
GAMMA,
31-
INV_GAUSSIAN,
32-
NEG_BIN,
33-
UNKNOWN
34-
};
35-
3621
std::string tidy_family_(const std::string &family);
3722

38-
FamilyType get_family_type(const std::string &fam);
39-
40-
vec link_inv_(const vec &eta, const FamilyType &fam);
23+
vec link_inv_(const vec &eta, const std::string &fam);
4124

4225
double dev_resids_(const vec &y, const vec &mu, const double &theta,
43-
const vec &wt, const FamilyType &fam);
26+
const vec &wt, const std::string &fam);
4427

45-
vec mu_eta_(const vec &eta, const FamilyType &fam);
28+
vec mu_eta_(const vec &eta, const std::string &fam);
4629

47-
vec variance_(const vec &mu, const double &theta, const FamilyType &fam);
30+
vec variance_(const vec &mu, const double &theta, const std::string &fam);
4831

49-
bool valid_eta_(const vec &eta, const FamilyType &fam);
32+
bool valid_eta_(const vec &eta, const std::string &fam);
5033

51-
bool valid_mu_(const vec &mu, const FamilyType &fam);
34+
bool valid_mu_(const vec &mu, const std::string &fam);

src/01_linear_algebra.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ mat crossprod_(const mat &X, const vec &w) {
66
return Y.t() * Y;
77
}
88

9-
// vec solve_beta_(mat MX, const mat &MNU, const vec &w) {
9+
// vec solve_beta_(mat MX, const mat &MNU,
10+
// const vec &w) {
1011
// const vec sqrt_w = sqrt(w);
1112
// MX.each_col() %= sqrt_w;
1213

@@ -15,27 +16,29 @@ mat crossprod_(const mat &X, const vec &w) {
1516
// stop("QR decomposition failed");
1617
// }
1718

18-
// return solve(trimatu(R), Q.t() * (MNU.each_col() % sqrt_w), solve_opts::fast);
19+
// return solve(trimatu(R), Q.t() * (MNU.each_col() % sqrt_w),
20+
// solve_opts::fast);
1921
// }
2022

23+
// Cholesky decomposition
2124
vec solve_beta_(mat MX, const mat &MNU, const vec &w) {
2225
const vec sqrt_w = sqrt(w);
26+
2327
MX.each_col() %= sqrt_w;
28+
mat WMNU = MNU.each_col() % sqrt_w;
29+
2430
mat XtX = MX.t() * MX;
31+
vec XtY = MX.t() * (MNU.each_col() % sqrt_w);
2532

26-
// Cholesky decomposition: XtX = L * L.t()
33+
// XtX = L * L.t()
2734
mat L;
2835
if (!chol(L, XtX, "lower")) {
2936
stop("Cholesky decomposition failed.");
3037
}
3138

32-
vec Xty = MX.t() * (MNU.each_col() % sqrt_w);
33-
3439
// Solve L * z = Xty
35-
vec z = solve(trimatl(L), Xty, solve_opts::fast);
36-
37-
// Solve L.t() * beta = z
38-
vec beta = solve(trimatu(L.t()), z, solve_opts::fast);
40+
vec z = solve(trimatl(L), XtY, solve_opts::fast);
3941

40-
return beta;
42+
// Solve Lt * beta = z
43+
return solve(trimatu(L.t()), z, solve_opts::fast);
4144
}

0 commit comments

Comments
 (0)