Dear Rcpp-devel,
Apologies in advance for the laborious problem statement. I hope
your experienced eyes will see a trivial mistake obscured to my
nascent ones.
We have a C++ core
library providing an API that is wrapped in R (Rcpp) and
Python (pybind11).
A new feature implements the addition of a boolean vector (validLib) as an API argument.
When adding this to one of the API functions (Simplex), there is
no issue. Note that Simplex returns a DataFrame class object.
When adding the same code to the API function SMap, which returns
a list, there seems to be a compiler error regarding the argument
as not allowed. (Error Log below).
sessionInfo is also listed below.
The same error (template argument deduction/substitution failed)
is found if I replace std::vector< bool > with
Rcpp::LogicalVector.
The code layout:
R API is accessed by R package user, function SMap() in R code
interface EDM.R.
SMap (R) calls the Rcpp wrapped function RtoCpp_SMap(), returning a list of R data.frames.
RtoCpp_SMap() is mapped to SMap_rcpp() (cpp code in SMap.cpp) in RcppEDMCommon.cpp.
The function SMap_rcpp() calls the C++ API function SMap().
Note, function (SMap) is overloaded.
In RcppEDMCommon.h a prototype is defined. In RcppEDMCommon.cpp an argument list is defined: Protoype in RcppEDMCommon.h
namespace r = Rcpp;
r::List SMap_rcpp( std::string
pathIn,
std::string dataFile,
r::DataFrame dataList,
std::string pathOut,
std::string predictFile,
std::string lib,
std::string pred,
int E,
int Tp,
int knn,
int tau,
double theta,
int exclusionRadius,
std::string columns,
std::string target,
std::string smapFile,
std::string jacobians,
bool embedded,
bool const_predict,
bool verbose,
std::vector<bool> validLib );
Argument list in RcppEDMCommon.cpp:
auto SMapArgs = r::List::create(
r::_["pathIn"] = std::string("./"),
r::_["dataFile"] = std::string("./"),
r::_["dataFrame"] = r::DataFrame(),
r::_["pathOut"] = std::string("./"),
r::_["predictFile"] = std::string(""),
r::_["lib"] = std::string(""),
r::_["pred"] = std::string(""),
r::_["E"] = 0,
r::_["Tp"] = 1,
r::_["knn"] = 0,
r::_["tau"] = -1,
r::_["theta"] = 0,
r::_["exclusionRadius"] = 0,
r::_["columns"] = std::string(""),
r::_["target"] = std::string(""),
r::_["smapFile"] = std::string(""),
r::_["jacobians"] = std::string(""),
r::_["embedded"] = false,
r::_["const_predict"] = false,
r::_["verbose"] = false,
r::_["validLib"] = std::vector<bool>() ); //
<== This is reported as the error
Mapping in RcppEDMCommon.cpp:
//-------------------------------------------------------------------------
// Export / map the functions
// First argument: R function name, see ../R/EDM.R
// Second argument: pointer to Rcpp interface function
// Third argument: arguments of the R function that
encapsulates the
// C++ function in a Rcpp::List
//-------------------------------------------------------------------------
RCPP_MODULE(EDMInternal) {
r::function( "RtoCpp_Simplex", &Simplex_rcpp,
SimplexArgs );
r::function( "RtoCpp_SMap", &SMap_rcpp,
SMapArgs );
}
C++ API function call (overloaded) to core library from function SMap_rcpp() in SMap.cc (C++ API prototype listed below):
//----------------------------------------------------------
//
//----------------------------------------------------------
r::List SMap_rcpp( std::string pathIn,
std::string dataFile,
r::DataFrame dataFrame,
std::string pathOut,
std::string predictFile,
std::string lib,
std::string pred,
int E,
int Tp,
int knn,
int tau,
double theta,
int exlusionRadius,
std::string columns,
std::string target,
std::string smapFile,
std::string jacobians,
bool embedded,
bool const_predict,
bool verbose,
std::vector<bool> validLib ) {
SMapValues SM;
if ( dataFile.size() ) {
// dataFile specified, dispatch overloaded SMap, ignore
dataFrame
SM = SMap( pathIn,
dataFile,
pathOut,
predictFile,
lib,
pred,
E,
Tp,
knn,
tau,
theta,
exlusionRadius,
columns,
target,
smapFile,
jacobians,
embedded,
const_predict,
verbose,
validLib );
}
else if ( dataFrame.size() ) {
DataFrame< double > dataFrame_ = DFToDataFrame(
dataFrame );
SM = SMap( dataFrame_,
pathOut,
predictFile,
lib,
pred,
E,
Tp,
knn,
tau,
theta,
exlusionRadius,
columns,
target,
smapFile,
jacobians,
embedded,
const_predict,
verbose,
validLib );
}
else {
Rcpp::warning( "SMap_rcpp(): Invalid input.\n" );
}
r::DataFrame df_pred = DataFrameToDF( SM.predictions );
r::DataFrame df_coef = DataFrameToDF( SM.coefficients );
r::List output = r::List::create( r::Named("predictions") =
df_pred,
r::Named("coefficients") =
df_coef );
return output;
}
As far as I can tell, the function arguments match the
definition. Again, this same code is implemented in another
function where there is no issue.
An interesting feature of the error log is a "countdown" of function arguments, variously providing notes, until the final note and error exit:
candidate expects 0 arguments, 21 providedcandidate expects 1 argument, 21 provided
...
candidate expects 20 arguments, 21 provided
-- Error Log --
> R CMD build .
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘rEDM’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* installing the package to build vignettes
-----------------------------------
* installing *source* package ‘rEDM’ ...
** using staged installation
** libs
...
g++ -std=gnu++11 -I"/usr/share/R/include"
-DNDEBUG -I ./cppEDM/src/
-I'/usr/local/lib/R/site-library/Rcpp/include'
-I'/usr/local/lib/R/site-library/RcppThread/include' -fpic
-g -O2 -fdebug-prefix-map=/build/r-base-tbZjLv/r-base-4.1.0=.
-fstack-protector-strong -Wformat -Werror=format-security
-Wdate-time -D_FORTIFY_SOURCE=2 -g -c RcppEDMCommon.cpp -o
RcppEDMCommon.o
RcppEDMCommon.cpp:60:51: error: no matching function for call to
‘Rcpp::Vector<19>::create(Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<Rcpp::DataFrame_Impl<Rcpp::PreserveStorage>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>, Rcpp::traits::named_object<int>,
Rcpp::traits::named_object<int>,
Rcpp::traits::named_object<int>,
Rcpp::traits::named_object<int>,
Rcpp::traits::named_object<int>,
Rcpp::traits::named_object<int>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>,
Rcpp::traits::named_object<std::__cxx11::basic_string<char>
>, Rcpp::traits::named_object<bool>,
Rcpp::traits::named_object<bool>,
Rcpp::traits::named_object<bool>,
Rcpp::traits::named_object<std::vector<bool> >)’
60 | r::_["validLib"] = std::vector<bool>()
);
| ^
In file included from
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/Vector.h:52,
from
/usr/local/lib/R/site-library/Rcpp/include/Rcpp.h:40,
from RcppEDMCommon.h:10,
from RcppEDMCommon.cpp:14:
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/vector/Vector.h:1122:19:
note: candidate: ‘static Rcpp::Vector<RTYPE,
StoragePolicy> Rcpp::Vector<RTYPE,
StoragePolicy>::create() [with int RTYPE = 19; StoragePolicy
= Rcpp::PreserveStorage]’
1122 | static Vector create(){
| ^~~~~~
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/vector/Vector.h:1122:19:
note: candidate expects 0 arguments, 21 provided
...
In file included from
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/vector/Vector.h:1126,
from
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/Vector.h:52,
from
/usr/local/lib/R/site-library/Rcpp/include/Rcpp.h:40,
from RcppEDMCommon.h:10,
from RcppEDMCommon.cpp:14:
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/generated/Vector__create.h:70:16:
note: candidate: ‘template<class T1> static
Rcpp::Vector<RTYPE, StoragePolicy> Rcpp::Vector<RTYPE,
StoragePolicy>::create(const T1&) [with T1 = T1; int
RTYPE = 19; StoragePolicy = Rcpp::PreserveStorage]’
70 | static Vector create(const T1& t1){
| ^~~~~~
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/generated/Vector__create.h:70:16:
note: template argument deduction/substitution failed:
RcppEDMCommon.cpp:60:51: note: candidate expects 1 argument,
21 provided
...
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/generated/Vector__create.h:1159:16:
note: template argument deduction/substitution failed:
RcppEDMCommon.cpp:60:51: note: candidate expects 20 arguments,
21 provided
60 | r::_["validLib"] = std::vector<bool>()
);
| ^
make: *** [/usr/lib/R/etc/Makeconf:177: RcppEDMCommon.o] Error 1
ERROR: compilation failed for package ‘rEDM’
* removing ‘/tmp/RtmpWluzdI/Rinst8d5e56742eb9/rEDM’
-----------------------------------
ERROR: package installation failed
-- Version Info --
> sessionInfo()
R version 4.1.0 (2021-05-18)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.1 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods
base
other attached packages:
[1] Rcpp_1.0.5
loaded via a namespace (and not attached):
[1] compiler_4.1.0
// to the SVD solver. This is done so that interfaces such as pybind11
// can provide their own object for the solver.
// 1) Data path/file with default SVD (LAPACK) assigned in Smap.cc 2)
SMapValues SMap( std::string pathIn = "./data/",
std::string dataFile = "",
std::string pathOut = "./",
std::string predictFile = "",
std::string lib = "",
std::string pred = "",
int E = 0,
int Tp = 1,
int knn = 0,
int tau = -1,
double theta = 0,
int exclusionRadius = 0,
std::string columns = "",
std::string target = "",
std::string smapFile = "",
std::string derivatives = "",
bool embedded = false,
bool const_predict = false,
bool verbose = true,
std::vector<bool> validLib = std::vector<bool>() );
// 2) DataFrame with default SVD (LAPACK) assigned in Smap.cc 2)
SMapValues SMap( DataFrame< double > &dataFrameIn,
std::string pathOut = "./",
std::string predictFile = "",
std::string lib = "",
std::string pred = "",
int E = 0,
int Tp = 1,
int knn = 0,
int tau = -1,
double theta = 0,
int exclusionRadius = 0,
std::string columns = "",
std::string target = "",
std::string smapFile = "",
std::string derivatives = "",
bool embedded = false,
bool const_predict = false,
bool verbose = true,
std::vector<bool> validLib = std::vector<bool>() );
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel