Passing multidimensional array from R to Fortran using Rcpp - c++

I'm new to C++ and the usage of Rcpp in R. I have many Fortran subroutines that I would like to include in an R package. I have followed this example, and it works perfectly. Now, I would like to implement one of my subroutines, a dummy Fortran subroutine saved in the file mytest.f90, and it looks like this:
module mytest
use, intrinsic :: iso_c_binding, only: c_int
implicit none
public :: mytest_f
contains
subroutine mytest_f(l, m, n, a, c) bind(C)
integer(kind=c_int) :: l, m, n
integer(kind=c_int) :: a(l, m, n), c(l,m,n)
c = c - a
end subroutine mytest_f
end module mytest
The Rcpp code and the C-wrapper are saved in one file called Rcppmytest.cpp and it contains:
#include <Rcpp.h>
using namespace Rcpp;
//C wrapper ??
extern "C" {
void mytest_f(int l, int m, int n, int a, int c);
}
// Rcpp
int c_mytest_f(Rcpp::IntegerVector a3D) {
// receives the 3D array
Rcpp::IntegerVector DIM = a3D.attr("dim");
int l, m, n;
l = DIM[0];
m = DIM[1];
n = DIM[2];
int c[l][m][n];
mytest_f(l, m, n, a3D, c);
return c;
}
However, I have two errors in the IDE (i.e. Rstudio). Firstly, in line mytest_f(l, m, n, a, c);, and the error is
not matching function for call to "mytest_f"
While the second error is:
Error: Cannot initialize return object of type "int *" with an lvalue of type 'int [a_size]'
When I try to get more info from the compilation process using devtools::document() in R, this error message appears:
Rcppmytest.cpp:n function ‘int c_mytest_f(Rcpp::IntegerVector)
Rcppmytest.cpp:21:7:warning: O C++ forbids variable length array ‘c-Wvla
21 | int cze];
| ^
Rcppmytest.cpp:22:7:warning: O C++ forbids variable length array ‘a-Wvla
22 | int aze];
| ^
Rcppmytest.cpp:35:21:error: valid conversion from ‘int*to ‘int-fpermissive
35 | mytest_f(l, m, n, a
| ^
| |
| int*
Rcppmytest.cpp:6:42:note: initializing argument 4 of ‘void mytest_f(int, int, int, int, int)
6 | void mytest_f(int l, int m, int n, int a c);
| ~~~~^
Rcppmytest.cpp:35:24:error: valid conversion from ‘int*to ‘int-fpermissive
35 | mytest_f(l, m, n, a, c
| ^
| |
| int*
Rcppmytest.cpp:6:49:note: initializing argument 5 of ‘void mytest_f(int, int, int, int, int)
6 | void mytest_f(int l, int m, int n, int a, int c
| ~~~~^
Rcppmytest.cpp:37:10:error: valid conversion from ‘int*to ‘int-fpermissive
37 | return c
| ^
| |
| int*
make: *** [/usr/lib/R/etc/Makeconf:178: Rcppmytest.o] Error 1
ERROR: compilation failed for package ‘mytestpackage’
My questions would be:
How to make it work (Any help and hints would be appreciated)?
Should I care about the column-/row-major order difference between R/Fortran and C/C++?
Notes:
The reason I'm using Rcpp is that I tried writing a small init.c file similar to here however, my efforts wasn't successful.

You need to adjust the C++ side of your glue, and the good news is that it is simple -- at least to get to a pointer and pass it along. Here is what I would do:
#include <Rcpp.h>
extern "C" {
void mytest_f(int l, int m, int n, int *a, int *c);
}
// [[Rcpp::export]]
Rcpp::IntegerVector c_mytest_f(Rcpp::IntegerVector a3D) {
// receives the 3D array
Rcpp::IntegerVector dim = a3D.attr("dim");
int l = dim[0],
m = dim[1],
n = dim[2];
Rcpp::IntegerVector c(l*m*n); // vectors are contiguous
mytest_f(l, m, n, &(a3D[0]), &(c[0]));
return c;
}
The changes are to
pass vectors a and c as pointers to double along with the dimension information
allocate the result vector as another Rcpp::IntegerVector which gets you both the allocation and the return object
pass a and c as pointers by accessing the address of their first element.
Lastly, files like the init.c you mention are autowritten for you (at least for the C / C++ part) and as mytest_f is not called from R you need to worry about it in there -- the calling is done by the glue code, and Rcpp makes setting up glue fairly easy.
All that said, you may have a problem with row-versus-column order between C (or C++) and Fortran. In the 2d-case you could do what you did here with RcppArmadillo types and transpose, I am not aware of a 'quick' fix for the 3d case though there may be a common trick.

Related

meaning of these pointers, pointer-to-pointer, function pointer and array pointer

I'm a university student, our teacher told us to tell the meaning of these pointers, but I only manage to figure out some of them:
1. int *p1;
2. int *p2[10];
3. int (*p3)[10];
4. int (*p4)();
5. int **p5();
6. int (**p6)[10];
7. int (**p7)();
8. int *(*p8)();
9. int (*p9[10])();
10. int **p10[10];
This is what I've figured out so far:
p1 is a pointer to an int
p2 is an array of 10 int pointer
p3 is a pointer that point to a static-array with 10 elements
p4 is a function pointer
p5 is not a pointer at all but a prototype of a function that returns int**
p6 is an array of 10 pointer-to-pointer
p7 is a pointer to a function pointer
Can you guys please help me? Because our teacher told us these will be on the exam
cdecl.org can be used to decipher messy declarations like your examples:
int (*p9[10])(); => declare p9 as array 10 of pointer to function returning int
Failing that, you can use Clockwise/Spiral Rule to grind through them manually.
All 7 pointers are correctly determined, but you should specify the parameter type and the return type with.
For example:
int **p5(); - function with no arguments, returning a pointer to pointer to int.
int *(*p8)(); - pointer to function with no arguments, returning a pointer to int.
int (*p9[10])(); - array of 10 pointer to function with no arguments, returning int.
int **p10[10]; - array of 10 pointer to pointer to int.
If I were a compiler I could hint the empty parameter list, like f.e. clang does:
"warning: this function declaration is not a prototype [-Wstrict-prototypes]"
Use (void) instead of () , when using these constructs in practice.
Note if you are on an exam, think of David Anderson`s Clockwise/Spiral Rule, as illustrated here.
1>pointer to integer
int *p1;
```````````````````````````````````````
2>array of 10 pointer which point to integer
`````````````````````````````````
int *p2[10];
`````````````````````````````````
3> pointer to an array of 10 integers
```````````````````````
int (*p3)[10]
``````````````````````````````````````
4> pointer to function that takes void argument and return integer
`````````````
int (*p4)();
```````````````
5>> is a prototype(deceleration) of a function which called p5 and returns int**
````````````
int **p5();
``````````
6>> is an array of 10 pointer-to-pointer which point to integer values
`````````
int (**p6)[10]
````````
7>>is pointer to pointer to function that takes void argument and return int
``````````````
int (**p7)();
````````````````
8>>pointer to function that takes void argument and return address or pointer
`````````````````
int *(*p8)();
`````````````
9>>array of 10 pointers to functions that take void argument and return an integer
``````````````````
int (*p9[10])();
```````````````
10>> it indicate to the first element in an array of 10 pointers which point to integer values
```````````
int **p10[10];
```````````
There are some techniques to reading and understanding complex declarations. There's a trick known as the "clockwise spiral rule", where you start with the identifier and spiral outward starting with whatever's immediately to the right. For example, given the declaration
int *(*a[N])(void);
we'd trace it as:
+-----------------------+
| +-----------+ |
| | +-------+ | |
| | | +-+ | | |
| | | | | | | |
int * ( * a [N] ) ( void ) |
^ | | | | | | |
| | | +---+ | | |
| | +---------+ | |
| +-------------+ |
+---------------------------+
or
a -- a
a[N] -- is an N-element array
*a[N] -- of pointers
(*a[N])( ) -- to functions taking
(*a[N])(void) -- no parameters
*(*a[N])(void) -- returning pointer to
int *(*a[N])(void); -- int
Remember that the postfix subscript [] and function call () operators have higher precedence than the unary dereference * operator, so expressions like *a[i] and *f() are parsed as *(a[i]) and *(f()) - we're dereferencing the results of a[i] and f(). If a points to an array, then we need to index into the result of *a, so we need to use parentheses to explicitly group * with a - (*a)[i]. Similarly, if f points to a function, then we need to call the result of *f, so we have to write (*f)().
Here's an example with multiple indirection:
int **foo(void);
which breaks down as
foo -- foo
foo( ) -- is a function taking
foo(void) -- no parameters
*foo(void) -- returning a pointer
**foo(void) -- to a pointer
int **foo(void); -- to int
You'd recursively apply these rules to any function parameters. Here's the declaration of the signal function from the standard library:
void (*signal(int sig, void (*func)(int)))(int);
which reads as
signal -- signal
signal( ) -- is a function taking
signal( sig ) -- parameter sig
signal(int sig ) -- is an int
signal(int sig, func ) -- parameter func
signal(int sig, *func ) -- is a pointer
signal(int sig, (*func)( )) -- to a function taking
signal(int sig, (*func)(int)) -- parameter unnamed is an int
signal(int sig, void (*func)(int)) -- returning void
(*signal(int sig, void (*func)(int))) -- returning a pointer
(*signal(int sig, void (*func)(int)))( ) -- to a function taking
(*signal(int sig, void (*func)(int)))(int) -- unnamed parameter is an int
void (*signal(int sig, void (*func)(int)))(int); -- returning void
There are also some substitution tricks you can play with. If you need to figure out how to declare an array of pointers to functions returning pointers to other functions returning pointers to arrays of pointers to int, start with an array of T:
T a[N]; // a is an array of T
This is going to be an array of pointers to something, so replace T with a pointer type P:
P *a[N]; // a is an array of pointer to P
Each a[i] is going to be a pointer to a function, so replace P with the function type F:
F (*a[N])( );
Each of these functions returns a pointer, so replace F with another pointer type P:
P *(*a[N])( );
Each of these pointers points to another function, so
F (*(*a[N])( ))( );
Those functions return pointers, so we replace F with another pointer type P:
P *(*(*a[N])( ))( );
Replace P with an array type A:
A (*(*(*a[N])( ))( ))[M];
And from here we can skip straight to the end:
int *(*(*(*a[N])( ))( ))[M];

Passing a two dimensional array, Works in C but not C++ [duplicate]

This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 7 years ago.
I am passing a two dimensional array to the mark function.
void mark(int n, int m, int i, int j, int canvisit[][m], int a[][m]){}
this code is working perfectly in C on Codeblocks but in C++, I am getting errors like :
prog.cpp:9:55: error: use of parameter outside function body before ']' token
void mark(int n, int m, int i, int j, int canvisit[][m], int a[][m]){
^
prog.cpp:9:56: error: expected ')' before ',' token
void mark(int n, int m, int i, int j, int canvisit[][m], int a[][m]){
^
prog.cpp:9:58: error: expected unqualified-id before 'int'
void mark(int n, int m, int i, int j, int canvisit[][m], int a[][m]){
Am I doing something wrong here? I am giving the number of columns before by int m , and this is working in C but not C++. Any help will be highly appreciated.
The array arguments you declare are variable-length arrays and those are not allowed in C++. You have to solve in in other ways, like using templates, std::vector or std::array.
Remember that C and C++ are two very different languages. C++ may have been originally developed from C, and they share syntax for many things, but they are still different languages with different rules.
Only C supports variable length arrays, C++ doesn't. C++ standard says that the size of the array must be a constant expression.
Use std::vector instead. Declaration should be
void mark(int n, int m, int i, int j, vector< vector<int> > &canvisit, vector< vector<int> > &a);

cannot convert 'double (*)[10]' to 'double*' for argument

Please help solving the compile time error. I have the declaration in different files as shown below
type.h
extern block posTime(const int row[MAX_ROW], int Flag, int n,double Time[]=0 );
a.cc
block posTime( const int row[MAX_ROW],
int Flag,
int n,
double* eraseTime[]
)
...
eraseTime[0]=test[1];
..
b.cc
...
double eraseTime[MAX_ROW];
block newB = posTime (0,0,0,&eraseTime);
the last line block newB = posTime (0,0,0,&eraseTime); gives me the error, cannot convertdouble (*)[10] to double* for argument 4
I want to upadte the eraseTime in a.cc and use back in b.cc. Can I do that?
Working solution (GCC 4.9.0 with C++11)
test.hpp
#define MAX_ROW 10
extern double posTime(const int row[MAX_ROW], int Flag, int n,double Time[]=0 );
test1.cpp
#include "test.hpp"
double posTime( const int row[MAX_ROW],
int Flag,
int n,
double* eraseTime
)
{ eraseTime[0] = 2; eraseTime[1] = 3; return eraseTime[0]; }
test.cpp
#include <iostream>
#include "test.hpp"
double eraseTime[MAX_ROW] { 1, 2, 3, 4, 5, 6 ,7, 8, 9, 10 };
int main() {
double newB = posTime (0,0,0,eraseTime);
std::cout << "result: " << newB << std::endl;
for (auto v : eraseTime) {
std::cout << v << std::endl;
}
return 0;
}
compilation command:
g++ -std=c++11 -o e:\test.exe e:\test.cpp e:\test1.cpp
or double eraseTime[MAX_ROW], if you are using MAX_ROW in int row i don't see why not in eraseTime (probably some call location not in the sample restrict this use) or double* eraseTime.
Recommended change to use std::array (constant size) or std::vector (dynamic size).
There are multiple issues here:
The signature in the header and in the implementation file are not the same: The header declares the last argument of posTime() to be of type double* (yes, pointer, not array!), while the implementation declares it to be of type double** (again, the array specification is converted to a pointer declaration because it is a function argument declaration).
The result is, that the implementation declares an overload to the function declared in the header, not an implementation for it.
When you take the address of an array, you get a pointer to an array, i. e. a value of type double (*)[MAX_ROW]. This is incompatible to a double**, which is what your compiler is complaining about. To create a variable of this type, you must use the syntax double (*myArrayPointer)[MAX_ROW];. The parentheses are important because the array subscript operator has a higher precedence than the dereference operator, with the consequence that double* myPointerArray[MAX_ROW]; declares an array of MAX_ROW pointers to doubles.
If you want to pass the array as a pointer to an array, you need to declare your function as
extern block posTime(const int row[MAX_ROW], int Flag, int n,double (*Time)[MAX_ROW]=0 );
This has the advantage that you get type checking on the length of the array, but the disadvantage that you cannot accept arrays of dynamic size. If you need this flexibility, the normal approach is to pass a pointer to the first element:
extern block posTime(const int row[MAX_ROW], int Flag, int n,double *Time=0 );
called with
block newB = posTime (0,0,0,eraseTime);
The call relies on array-pointer-decay to make a double* from your array identifier.

Using Variable Argument List in a Template

I have been trying to figure out the problem that I am facing in the following piece of code.
#include <iostream>
#include <stdarg.h>
#include <vector>
using namespace std;
template <typename T>
class C {
vector<T> vec;
public:
void PrintValues(int size, T val, ...){
va_list v;
va_start(v,val);
for ( int i = 0 ; i < size ; i++ ) {
T p = va_arg(v,T);
vec.push_back(p);
cout<<p<<" ";
}
va_end(v);
}
};
int main() {
C<int> a;
C<char *> b;
cout<<endl;
a.PrintValues(10,1,4,6,2,8,5,3,7,10,9);
cout<<endl;
b.PrintValues(10,"a","b","c","d","e","f","g","h","i","j");
cout<<endl;
return 0;
}
I compiled this code on my Ubuntu 10.04 desktop using g++ 4.4.3.
The code compiled with the following warning
testcode.cpp: In function ‘int main()’:
testcode.cpp:25: warning: deprecated conversion from string constant to ‘char*’
While I was expecting an output like
1 4 6 2 8 5 3 7 10 9
a b c d e f g h i j
I actually got the following output
4 6 2 8 5 3 7 10 9 0
b c d e f g h i j `*#
Can someone please provide me with some pointers regarding why the first element in the list is skipped? I know that I can also do the same thing without using the variable argument list, but I am just trying out if this is possible.
Your first element is being put into the T val parameter, and not into va_list v;. This is because va_start(v, val) sets up v with the var-args which start after val, not including val. Have some documentation
You are eating the first part of your list in val argument and so you actually have one less element in your list than you are indicating with size:
void PrintValues(int size, T val, ...)
^^^^^
So in the first case val will be 1 and the second case a. One potential fix would be to drop the val arg:
void PrintValues(int size, ...)
and alter your va_start:
va_start(v,size);
I realize you are just experimenting but this is not type safe and we have variadic templates with C++11 now. Although since you are using only one type std:::initializer_list is also a viable alternative, as mentioned in the previous link.

Bind C function in C++ (undefined reference)

I have a regular C++ class like PardisoSolver.h:
#ifndef PARDISOSOLVER_H_
#define PARDISOSOLVER_H_
class PardisoSolver {
public:
/* Initializes a new Solver with the given matrix in CSR */
PardisoSolver(
int* ia,
int* ja,
double* a,
int n,
int nja);
virtual ~PardisoSolver();
void setMatrixType(int mtype);
void pardisoSymFactorize();
private:
static int get_nproc(void);
void handle_error(int ierror, int line);
int* ia; // row indices
int* ja; // column pointer
double* a; // non zero values
int n_eq; // size of matrix
int nja; // number of non zero elements
bool factorized;
/* PARDISO SETTINGS */
void *pt[64];
int maxfct;
int mnum;
int mtype;
int perm;
int nrhs;
int iparm[64];
int msglvl;
int error;
double dparm[64];
double dzero;
int izero;
};
#endif /* PARDISOSOLVER_H_ */
And on the other hand I have the implementations in PardisoSolver.cpp. Here I have an additional declaration of a C function just along with the implementations of the class:
extern "C" void pardiso (void *, int *, int *, int *, int *, int *,
double *, int *, int *, int *, int *, int *,
int *, double *, double *, int *, double *);
Now when I try to call that function like
pardiso (pt, &maxfct, &mnum, &mtype, &phase,
&n_eq, a, ia, ja, &izero, &nrhs,
iparm, &msglvl, &dzero, &dzero, &error, dparm);
I get the compile error
PardisoSolver.cpp:94: undefined reference to `pardiso'
where the call is in line 94. Did I declare the C function in the wrong place? As I got it, it cannot be a member of a class so this should be the way to call it. Thanks for the help.
All of this suggest that your program design needs improvment. First of all, there should only be one interface to your "module" (class + other stuff). You should not have "a class, and then some", that doesn't make any sense. All functions related to the functionality of the class should be included in that class. All that aren't related, should be moved to another part of the program.
Once you have straightened that out, you need to clarify the programming language. Is this C or C++? Is it C++ with a caller in C? It seems to be the latter. If so, you need to separate the two languages somehow. As one example: in Windows you could place the C++ class in a DLL, with an interface that can be called from C.
And finally, you should consider whether it makes sense to have a function taking 17 pointers as parameters. Are these parameters not related at all? Could they be grouped in structs/classes? Or perhaps this is simply a needlessly complex monster function, that could be split in several different ones.