Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 1 addition & 2 deletions .github/workflows/manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ jobs:
container:
- 'clang-asan'
- 'clang-ubsan'
- 'gcc-asan'
- 'rchk'
# - 'rchk' yaml has issues as of 2026-07-17
- 'valgrind'

env:
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: nn2poly
Title: Neural Network Weights Transformation into Polynomial Coefficients
Version: 1.0.0
Version: 1.0.1
Authors@R: c(
person(given = "Pablo", family = "Morala", role = c("aut", "cre"),
email = "moralapablo@gmail.com",
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# nn2poly 1.0.1

- Fix UB in hash implementation (#84).

# nn2poly 1.0.0

- Implement print method for nn2poly objects.
Expand Down
4 changes: 2 additions & 2 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Release 1.0.0
## Release 1.0.1

- This release marks version 1.0.0 of the package. It includes the changes and improvements documented in NEWS.md, with significant performance improvements.
Fixes UB in hash implementation as reported in M1-SAN machine.

## Test environments

Expand Down
6 changes: 3 additions & 3 deletions src/linalg_arma.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ inline Weights trans(const Weights& mat) {
}

inline Weights alg_linear(Weights& coeffs_list, const Weights& layer) {
arma::rowvec intercept = arma::zeros<arma::rowvec>(coeffs_list.n_cols);
intercept[0] = 1.0;
return arma::trans(layer) * arma::join_cols(intercept, coeffs_list);
Weights mat = layer.rows(1, layer.n_rows - 1).t() * coeffs_list;
mat.col(0) += layer.row(0).t();
return mat;
}

inline void add_partition(Weights& mat, int i, double scalar, const Vector& vec) {
Expand Down
12 changes: 5 additions & 7 deletions src/linalg_eigen.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,21 @@ inline int n_rows(const Weights& m) { return m.rows(); }
inline int n_cols(const Weights& m) { return m.cols(); }

inline Weights zeros(int rows, int cols) {
return Eigen::MatrixXd::Zero(rows, cols);
return Weights::Zero(rows, cols);
}

inline Vector zeros(int size) {
return Eigen::VectorXd::Zero(size);
return Vector::Zero(size);
}

inline Weights trans(const Weights& mat) {
return mat.transpose();
}

inline Weights alg_linear(const Weights& coeffs_list, const Weights& layer) {
Weights joined(coeffs_list.rows() + 1, coeffs_list.cols());
joined.row(0).setZero();
joined(0, 0) = 1.0;
joined.bottomRows(coeffs_list.rows()) = coeffs_list;
return layer.transpose() * joined;
Weights mat = layer.bottomRows(layer.rows() - 1).transpose() * coeffs_list;
mat.col(0) += layer.row(0).transpose();
return mat;
}

inline void add_partition(Weights& mat, int i, double scalar, const Vector& vec) {
Expand Down
11 changes: 5 additions & 6 deletions src/linalg_torch.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ inline Weights trans(const Weights& mat) {
}

inline Weights alg_linear(Weights& coeffs_list, const Weights& layer) {
auto intercept = torch::zeros({1, coeffs_list.size(1)}, coeffs_list.options());
intercept[0][0] = 1.0;
auto joined = torch::cat({intercept, coeffs_list}, /*dim=*/0);
return torch::matmul(layer.t(), joined);
Weights mat = torch::matmul(layer.slice(0, 1, layer.size(0)).t(), coeffs_list);
mat.select(1, 0).add_(layer[0]);
return mat;
}

inline void add_partition(Weights& mat, int i, double scalar, const Vector& vec) {
Expand Down Expand Up @@ -65,8 +64,8 @@ inline Vector accumulate_partition(const Weights& coeffs_input, int d,
#include <Rcpp.h>

namespace Rcpp {
template <> torch::Tensor as(SEXP x);
NumericMatrix wrap(const torch::Tensor& data);
template <> nn2poly::linalg::Weights as(SEXP x);
NumericMatrix wrap(const nn2poly::linalg::Weights& data);
}

#endif
4 changes: 3 additions & 1 deletion src/nn2poly_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <vector>
#include <iostream>
#include <string>
#include <cstdint>

using Term = std::vector<int>;
using Terms = std::vector<Term>;
Expand All @@ -20,7 +21,8 @@ struct PartitionsList {
struct TermHash {
std::size_t operator()(Term const& key) const noexcept {
std::size_t seed = key.size();
for(auto x : key) {
for(auto item : key) {
uint32_t x = static_cast<uint32_t>(item);
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
Expand Down
6 changes: 3 additions & 3 deletions src/wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ List wrap(const WeightsLists& data) {
#ifdef TORCH_VERSION

template <>
torch::Tensor as(SEXP x) {
Weights as(SEXP x) {
NumericMatrix data(x);
return torch::from_blob(const_cast<double*>(data.begin()),
{data.nrow(), data.ncol()}, {1, data.nrow()}, torch::kFloat64
).clone();
}

NumericMatrix wrap(const torch::Tensor& data) {
torch::Tensor cpu_t = data.to(torch::kCPU).to(torch::kFloat64).contiguous();
NumericMatrix wrap(const Weights& data) {
Weights cpu_t = data.to(torch::kCPU).to(torch::kFloat64).contiguous();
int rows = cpu_t.size(0);
int cols = cpu_t.size(1);
NumericMatrix r_mat(rows, cols);
Expand Down