Rcpp function call from function in the same cpp file - rcpp

Hi i have this rcpp file :
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int ricercamin (NumericVector p, NumericVector u, int n1){
int trovato=0;
int m;
int i=0;
while(trovato==0 & i<n1){
if(u[i]==1){
trovato=1;
m=i;
}
else{
i++;
}
}
for(i=0;i<n1;i++){
if(p[i]<p[m]){
m=i;
}
}
return m;
}
}
// [[Rcpp::export]]
NumericMatrix trai (NumericMatrix weigth, CharacterVector src, CharacterVector rn){
int n=weigth.nrow();
NumericVector potenziale[n];
NumericVector predecessore [n];
NumericVector insieme [n];
int i,j,k;
for(i=0;i<n;i++){
j=ricercamin(potenziale,insieme,n);
.....
}
The error is :
use of undeclared identifier 'ricercamin'
How can i solve this ?
it seems like it does not found the function but the function is in the same cpp file and the declaration is before the call of the fun.

Your example code does not compile since the braces are not balanced and a literal .... within the source code is probably not want you want. Anyway, I have reduced your code to what I believe to be the heart of the issue:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int ricercamin (NumericVector p, NumericVector u, int n1){
return 0;
}
// [[Rcpp::export]]
NumericMatrix trai (NumericMatrix weigth, CharacterVector src, CharacterVector rn){
int n=weigth.nrow();
NumericVector potenziale[n];
NumericVector insieme [n];
int i,j;
for(i=0;i<n;i++){
j=ricercamin(potenziale,insieme,n);
}
return weigth;
}
Compiling this I do not get the quoted message but instead:
58911878.cpp: In function ‘Rcpp::NumericMatrix trai(Rcpp::NumericMatrix, Rcpp::CharacterVector, Rcpp::CharacterVector)’:
58911878.cpp:19:22: error: could not convert ‘(Rcpp::NumericVector*)(& potenziale)’ from ‘Rcpp::NumericVector*’ {aka ‘Rcpp::Vector<14, Rcpp::PreserveStorage>*’} to ‘Rcpp::NumericVector’ {aka ‘Rcpp::Vector<14, Rcpp::PreserveStorage>’}
19 | j=ricercamin(potenziale,insieme,n);
| ^~~~~~~~~~
| |
| Rcpp::NumericVector* {aka Rcpp::Vector<14, Rcpp::PreserveStorage>*}
make: *** [/usr/lib/R/etc/Makeconf:176: 58911878.o] Error 1
Now this error message tells me something useful: The function ricercamin expects a NumericVector, but I am giving it a pointer to a NumericVector. The correct fix depends on what the variable potenziale is supposed to contain. Since you mention "a NumericVector of size n" in the comments, you should use (n) instead of [n], since the latter declares an array of NumericVectors:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int ricercamin (NumericVector p, NumericVector u, int n1){
return 0;
}
// [[Rcpp::export]]
NumericMatrix trai (NumericMatrix weigth, CharacterVector src, CharacterVector rn){
int n=weigth.nrow();
NumericVector potenziale(n);
NumericVector insieme(n);
int i,j;
for(i=0;i<n;i++){
j=ricercamin(potenziale,insieme,n);
}
return weigth;
}
This compiles without errors or warnings for me.

Related

Pointer of arma::mat or arma::vet as arguments of Rcpp function for internal purpose only

I am developing an R package using RcppArmadillo. I was writing a few util functions, which manipulate arma::mat and arma::vec objects. So I was trying to use pointer of arma::mat (or arma::vec) as arguments of those functions. Just like the following C++ example (https://onlinegdb.com/mNczwaPaV), I just want to pass the address of object, then manipulate the object value:
#include <iostream>
using namespace std;
void plus_one(int *x){
*x = *x + 1;
}
int main(){
int x = 1;
plus_one(&x);
printf("%d", x);
return 0;
}
2
...Program finished with exit code 0
Press ENTER to exit console.
Here is a toy example I was trying. RStudio gave me the error message "called object type 'arma::vec *' (aka 'Col *') is not a function or function pointer."
#include <RcppArmadillo.h>
using namespace Rcpp;
//
// [[Rcpp::depends(RcppArmadillo)]]
void f2(arma::vec *v){
*v = (*v)%log(*v) + (1-(*v))*log(1-(*v));
}
void trim(arma::vec *v, double tol){
*v(find(*v<=0.0)).fill(tol);
*v(find(*v>=1.0)).fill(1-tol);
}
// [[Rcpp::export]]
arma::vec f1(arma::vec v){
trim(&v, 1e-8);
return(f2(&v));
}
/*** R
f1(seq(0,1,0.2))
*/
I don't think v.memptr() allows me to manipulate the vector by R-like vector operations. For example,
double* v_mem = v.memptr();
*v_mem+1;
does not give the entrywise addition result. (Here, I want is v+1 in R). Do you have any suggestions?
Thank you!

Calling 'mypackage' function within public worker

I know the problem I have is a thread-safety issue. As the code I have now will execute with 'seThreadOptions(1)'. My question is what would be a good practice to overcome this.
I know this: Threadsafe function pointer with Rcpp and RcppParallel via std::shared_ptr Will come into play somehow. And I have also been thinking/playing around with making the internal function part of the structure for the parallel worker. Realistically, I am calling two internal functions and I would like one to be variable and the other to be constant, this tends me to think that i will need 2 solutions.
The error is that the R session, in rstudio, crashes.
Two things of note here:
1. if I 'setThreadOptions(1)' this runs fine.
2. if I move 'myfunc' into the main cpp file and make the call simply 'myfunc' this also runs fine.
Here is a detailed example:
First cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(cpp)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
Second,cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(ParallelExample)]]
#include "RcppArmadillo.h"
#include "RcppParallel.h"
#include "ParallelExample.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace std;
struct PARALLEL_WORKER : public Worker{
const arma::vec &input;
arma::vec &output;
PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}
void operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = ParallelExample::myfunc(index);
}
}
};
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
PARALLEL_WORKER parallel_woker(input, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
Makevars, as I am using a macintosh:
CXX_STD = CXX11
PKG_CXXFLAGS += -I../inst/include
And Namespace:
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)
importFrom(RcppParallel,RcppParallelLibs)
useDynLib(ParallelExample, .registration = TRUE)
export(Parallelfunc)
When you call ParallelExample::myfunc, you are calling a function defined in inst/include/ParallelExample_RcppExport.h, which uses the R API. This is something one must not do in a parallel context. I see two possibilities:
Convert myfunc to header-only and include it in int/include/ParallelExample.h.
If the second cpp file is within the same package, put a suitable declaration for myfunc into src/first.h, include that file in both src/first.cpp and src/second.cpp, and call myfunc instead of ParallelExample::myfunc. After all, it is not necessary to register a function with R if you only want to call it within the same package. Registring with R is for functions that are called from the outside.
In some ways this kinda defeats the purpose of the built in interface cpp feature of Rcpp.
First, cpp saved as 'ExampleInternal.h':
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
namespace ExampleInternal
{
double myfunc3(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
}
and second:
#include "ParallelExample.h"
#include "ExampleInternal.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace ExampleInternal;
using namespace std;
struct PARALLEL_WORKER : public Worker{
const arma::vec &input;
arma::vec &output;
PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}
void operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = ExampleInternal::myfunc3(index);
}
}
};
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
PARALLEL_WORKER parallel_woker(input, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}

Using c++11's std::async inside an abstract base class

Why doesn't making threads like this work inside of an abstract base class? I'm trying to abstract away all of the multithreading details for users who derive from this base class. I don't understand why it says "no type named 'type'" when I clearly write that callbackSquare returns type int.
#include <iostream>
#include <future>
#include <vector>
class ABC{
public:
std::vector<std::future<int> > m_results;
ABC(){};
~ABC(){};
virtual int callbackSquare(int& a) = 0;
void doStuffWithCallBack();
};
void ABC::doStuffWithCallBack(){
for(int i = 0; i < 10; ++i)
m_results.push_back(std::async(&ABC::callbackSquare, this, i));
for(int j = 0; j < 10; ++j)
std::cout << m_results[j].get() << "\n";
}
class Derived : public ABC {
Derived() : ABC() {};
~Derived(){};
int callbackSquare(int& a) {return a * a;};
};
int main(int argc, char **argv)
{
std::cout << "testing\n";
return 0;
}
The strange errors I'm getting are:
/usr/include/c++/5/future:1709:67: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/usr/include/c++/5/future:1725:19: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/home/taylor/Documents/ssmworkspace/callbacktest/main.cpp:16:69: required from here
/usr/include/c++/5/functional:1505:61: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/5/functional:1526:9: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
_M_invoke(_Index_tuple<_Indices...>)
Your problem can be reproduced with any function that accepts a reference:
#include <future>
int f(int& a)
{
return a * a;
}
int main()
{
int i = 42;
auto r = std::async(f, i);
}
Accepting a reference in your code is risky since the variable will be modified by the loop iteration, creating a data race because the called function also accesses the variable.
Change the function to accept the input parameter by value, or call std::async by passing std::ref(i) or std::cref(i) (in case the function accepts a const reference) if you acknowledge the risk.

Issue in predicate function in wait in thread C++

I am trying to put the condition inside a function but it is throwing confusing compile time error . While if I write it in lambda function like this []{ retur i == k;} it is showing k is unidentified . Can anybody tell How to solve this problem .
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
#include <chrono>
#include <condition_variable>
using namespace std;
condition_variable cv;
mutex m;
int i;
bool check_func(int i,int k)
{
return i == k;
}
void print(int k)
{
unique_lock<mutex> lk(m);
cv.wait(lk,check_func(i,k)); // Line 33
cout<<"Thread no. "<<this_thread::get_id()<<" parameter "<<k<<"\n";
i++;
return;
}
int main()
{
thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = thread(print,i);
for(auto &t : threads)
t.join();
return 0;
}
Compiler Error:
In file included from 6:0:
/usr/include/c++/4.9/condition_variable: In instantiation of 'void std::condition_variable::wait(std::unique_lock<std::mutex>&, _Predicate) [with _Predicate = bool]':
33:30: required from here
/usr/include/c++/4.9/condition_variable:97:14: error: '__p' cannot be used as a function
while (!__p())
^
wait() takes a predicate, which is a callable unary function returning bool. wait() uses that predicate like so:
while (!pred()) {
wait(lock);
}
check_func(i,k) is a bool. It's not callable and it's a constant - which defeats the purpose. You're waiting on something that can change. You need to wrap it in something that can be repeatedly callable - like a lambda:
cv.wait(lk, [&]{ return check_func(i,k); });

How do I set up a function to convert vector of strings to vector of integers in VC++?

The question is in the title. Need help figuring out why my code compiles but doesn't work as intended. Thanks!
//This example demonstrates how to do vector<string> to vectro<int> conversion using a function.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
vector<int>* convertStringVectorToIntVector (vector<string> *vectorOfStrings)
{
vector<int> *vectorOfIntegers = new vector<int>;
int x;
for (int i=0; i<vectorOfStrings->size(); i++)
{
stringstream str(vectorOfStrings->at(i));
str >> x;
vectorOfIntegers->push_back(x);
}
return vectorOfIntegers;
}
int main(int argc, char* argv[]) {
//Initialize test vector to use for conversion
vector<string> *vectorOfStringTypes = new vector<string>();
vectorOfStringTypes->push_back("1");
vectorOfStringTypes->push_back("10");
vectorOfStringTypes->push_back("100");
delete vectorOfStringTypes;
//Initialize target vector to store conversion result
vector<int> *vectorOfIntTypes;
vectorOfIntTypes = convertStringVectorToIntVector(vectorOfStringTypes);
//Test if conversion is successful and the new vector is open for manipulation
int sum = 0;
for (int i=0; i<vectorOfIntTypes->size(); i++)
{
sum+=vectorOfIntTypes->at(i);
cout<<sum<<endl;
}
delete vectorOfIntTypes;
cin.get();
return 0;
}
The code above has only one problem: You are deleting your vectorOfStringTypes before you pass it to your conversion function.
Move the line delete vectorOfStringTypes; to after you have called your convert function and the program works as intended.

Resources