Skip to content

[R-pkg-devel] Fwd: CRAN Submission rkriging 1.0.1

2 messages · Bill Huang, Ivan Krylov

#
Hi, Team.

I am working on a package that uses RcppEigen. The package can be installed
successfully locally and passed CRAN auto-check. However, it cannot pass
the gcc-UBSAN test with the following error message: a problem with the LLT
function in Eigen. I am not sure how to fix this. Any suggestion or help is
highly appreciated!

rkriging.Rcheck/rkriging-Ex.Rout:/data/gannet/ripley/R/test-dev/RcppEigen/include/Eigen/src/Cholesky/LLT.h:66:49:
runtime error: load of value 20880, which is not a valid value for type
'ComputationInfo'
     #0 0x7f967645dfc6 in Eigen::LLT<Eigen::Matrix<double, -1, -1, 0,
-1, -1>, 1>::operator=(Eigen::LLT<Eigen::Matrix<double, -1, -1, 0, -1,
-1>, 1>&&)
/data/gannet/ripley/R/test-dev/RcppEigen/include/Eigen/src/Cholesky/LLT.h:66
     #1 0x7f967645dfc6 in Kriging::Kriging(Eigen::Matrix<double, -1, -1,
0, -1, -1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&,
Kernel&, bool const&)
/data/gannet/ripley/R/packages/incoming/rkriging.Rcheck/00_pkg_src/rkriging/src/kriging.cpp:26
     #2 0x7f96769cac53 in
UniversalKriging::UniversalKriging(Eigen::Matrix<double, -1, -1, 0, -1,
-1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Kernel&, bool
const&, unsigned long const&,
Rcpp::Function_Impl<Rcpp::PreserveStorage>)
/data/gannet/ripley/R/packages/incoming/rkriging.Rcheck/00_pkg_src/rkriging/src/kriging.cpp:385
     #3 0x7f9676929f68 in Rcpp::Constructor_6<UniversalKriging,
Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1,
0, -1, 1>, Kernel&, bool, unsigned long,
Rcpp::Function_Impl<Rcpp::PreserveStorage> >::get_new(SEXPREC**, int)
/data/gannet/ripley/R/test-dev/Rcpp/include/Rcpp/module/Module_generated_Constructor.h:115
     #4 0x7f96767c091f in
Rcpp::class_<UniversalKriging>::newInstance(SEXPREC**, int)
/data/gannet/ripley/R/test-dev/Rcpp/include/Rcpp/module/class.h:131
     #5 0x7f967c9d56a8 in class__newInstance(SEXPREC*)
/tmp/Rtmp7QBClZ/R.INSTALL19fb7f3cfc39c8/Rcpp/src/module.cpp:143

Thank you!
Best,
Chaofan

---------- Forwarded message ---------
From: Uwe Ligges <ligges at statistik.tu-dortmund.de>
Date: Tue, Jul 16, 2024 at 2:19?AM
Subject: Re: CRAN Submission rkriging 1.0.1
To: Bill Huang <10billhuang01 at gmail.com>


Please ask on the mailing list <r-package-devel at r-project.org>

Best,
Uwe Ligges
On 16.07.2024 08:32, Bill Huang wrote:
rkriging.Rcheck/rkriging-Ex.Rout:/data/gannet/ripley/R/test-dev/RcppEigen/include/Eigen/src/Cholesky/LLT.h:66:49:
type
/data/gannet/ripley/R/test-dev/RcppEigen/include/Eigen/src/Cholesky/LLT.h:66
/data/gannet/ripley/R/packages/incoming/rkriging.Rcheck/00_pkg_src/rkriging/src/kriging.cpp:26
-1,
/data/gannet/ripley/R/packages/incoming/rkriging.Rcheck/00_pkg_src/rkriging/src/kriging.cpp:385
/data/gannet/ripley/R/test-dev/Rcpp/include/Rcpp/module/Module_generated_Constructor.h:115

  
  
#
Hi Chaofan and welcome to R-package-devel!

? Wed, 17 Jul 2024 11:52:53 -0700
Bill Huang <10billhuang01 at gmail.com> ?????:
The problem is detected by special, normally disabled instrumentation
called UBSanitizer [1]. If you don't want to compile R with sanitizers
enabled yourself, ready-made Docker/Podman containers
rocker-org/r-devel-san and rocker-org/r-devel-san-clang [2] (and
others, there are sanitizer containers published by the R-hub
project as well) should help you reproduce the problem.

In this case, I suspect that you stumbled upon a problem in Eigen
itself: the Eigen::LLT constructor does not initialise an enumeration
field, ComputationInfo m_info, which results in the field being
populated by something out of range of the enumeration, which invokes
undefined behaviour.

You can reproduce the problem without building an R package at all:

#include <iostream>
#include <Eigen>

struct foo : Eigen::LLT<Eigen::MatrixXd> {
	foo() : Eigen::LLT<Eigen::MatrixXd>(42) {
		// m_info is protected, hence use of inheritance
		std::cout << m_info << std::endl;
	}
};

int main() {
	foo L;
}

g++ -fsanitize=undefined -g -Og -I $LIBRARY/RcppEigen/include/Eigen \
 -o ex ex.cpp
./ex
# ex.cpp:7:16: runtime error: load of value 32608, which is not a valid
# value for type 'ComputationInfo'
# 32608

A workaround for the problem is to move the initialization of the
Eigen::LLT<Eigen::MatrixXd> Kriging::L_ field from the constructor body
into the member initializer list:

--- rkriging.orig/src/kriging.cpp       2024-07-04 06:45:57.000000000 +0300
+++ rkriging/src/kriging.cpp    2024-07-18 14:10:54.000000000 +0300
@@ -20,10 +20,9 @@
     return kriging->get_nllh(log_lengthscale, nugget);
 }

-Kriging::Kriging(const Eigen::MatrixXd& X, const Eigen::VectorXd& y, Kernel& Ker, const bool& interpolation): n_(X.rows()), p_(X.cols()), X_(X), y_(y), Ker_(Ker), interpolation_(interpolation) {
+Kriging::Kriging(const Eigen::MatrixXd& X, const Eigen::VectorXd& y, Kernel& Ker, const bool& interpolation): n_(X.rows()), p_(X.cols()), X_(X), y_(y), Ker_(Ker), interpolation_(interpolation), L_(n_) {
     a_.resize(n_);
     b_.resize(n_);
-    L_ = Eigen::LLT<Eigen::MatrixXd>(n_);
     y_tss_ = y_.squaredNorm() - std::pow(y_.sum(),2)/n_;
     nugget_ = interpolation_ ? 1e-6 : 1e-3;
     nllh_ = std::numeric_limits<double>::infinity();

This seems to avoid poking the bear of undefined behaviour with
potential copying of invalid enum value in L_ until something
initialises it properly.

I'm not sure whether this is worth reporting to Eigen as something to
fix. I hope that people here with more experience in C++ and Eigen will
be able to answer that question.