Hello,
I am trying to call the BLAS Level1 function zdotc from R via
a .C call like this:
#include "R.h"
#include "R_ext/BLAS.h"
void testzdotc() {
Rcomplex zx[3], zy[3], ret_val;
zx[0].r = 1.0; zx[0].i = 0.0;
zx[1].r = 2.0; zx[0].i = 0.0;
zx[2].r = 3.0; zx[0].i = 0.0;
zy[0].r = 1.0; zy[0].i = 0.0;
zy[1].r = 2.0; zy[0].i = 0.0;
zy[2].r = 3.0; zy[0].i = 0.0;
int n=3, incx=1, incy=1;
F77_CALL(zdotc)(&ret_val, &n, zx, &incx, zy, &incy);
Rprintf("ret_val = %f, %f\n", ret_val.r, ret_val.i);
}
This does not work. When I run '.C('testzdotc')' there is
typically a delay for a second or so, then I get: 0.0, 0.0
instead of the correct ans: 14.0, 0.0.
Section 5.2 of the R manual (on Extending R) says that only
FORTRAN subroutines can be called (not functions), probably
because of the non-standard way the compilers map FORTRAN
function names to symbols in the DLL.
This is consistent with the interface prototype for the BLAS
routine zdotc contained in <R>/include/R_ext/BLAS.h, namely,
BLAS_extern Rcomplex
F77_NAME(zdotc)(Rcomplex * ret_val, int *n,
Rcomplex *zx, int *incx, Rcomplex *zy, int *incy);
But this seems to BOTH return a result, and pass the result
as the first argument?
On the other hand, this is not consistent with the standard
FORTRAN definition for zdotc that is contained in
<R>/src/extra/blas/cmplxblas.f, where the first argument is
n, not ret_val. Consequently, it is not clear where the wrapper
is defined that is called via the prototype.
My search is complicated by the fact that the libraries
libR.so, libRblas.so, libRlapack.so are stripped.
When I install the standard (FORTRAN-based) BLAS on my
system (Fedora 16), I find that zdotc is defined in the traditional
way (without adjustment to the first argument). This is probably
irrelevant because R does not use it in my configuration.
I found some documentation on Intel FORTRAN that seems to
suggest that the first argument on the C side is always the
same as (a pointer to) the FORTRAN function return value, but
this is not so if I use the standard definition of zdotc.f with
gfortran.
Any ideas?
Thanks,
Dominick
G'day Dominick, On Mon, 5 Mar 2012 19:21:01 -0500 Dominick Samperi <djsamperi at gmail.com> wrote:> Section 5.2 of the R manual (on Extending R) says that only > FORTRAN subroutines can be called (not functions), probably > because of the non-standard way the compilers map FORTRAN > function names to symbols in the DLL.Section 5.2 deals with calling C/FORTRAN code from R via .C() or .Fortran(), and is not directly relevant to the question on how to call FORTRAN code from C code. :)> This is consistent with the interface prototype for the BLAS > routine zdotc contained in <R>/include/R_ext/BLAS.h, namely, > > BLAS_extern Rcomplex > F77_NAME(zdotc)(Rcomplex * ret_val, int *n, > Rcomplex *zx, int *incx, Rcomplex *zy, int *incy); > >[...] > > On the other hand, this is not consistent with the standard > FORTRAN definition for zdotc that is contained in > <R>/src/extra/blas/cmplxblas.f, where the first argument is > n, not ret_val.This seems to be indeed inconsistent and, presumably, a bug. Applying the attach patch to R's development version (compiles, installs and passes all checks with this patch), and changing in your code the line F77_CALL(zdotc)(&ret_val, &n, zx, &incx, zy, &incy); to ret_val = F77_CALL(zdotc)(&n, zx, &incx, zy, &incy); produces the expected output.> Consequently, it is not clear where the wrapper > is defined that is called via the prototype.The F77_xxxx macros seem to be defined in <R>/include/R_ext/RS.h, and their sole purpose seems to be to append a _ to the argument if needed. Cheers, Berwin -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: R-Patch URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20120306/848a76d6/attachment.pl>
On 06-03-2012, at 01:21, Dominick Samperi wrote:> Hello, > > I am trying to call the BLAS Level1 function zdotc from R via > a .C call like this: > > #include "R.h" > #include "R_ext/BLAS.h" > > void testzdotc() { > Rcomplex zx[3], zy[3], ret_val; > > zx[0].r = 1.0; zx[0].i = 0.0; > zx[1].r = 2.0; zx[0].i = 0.0; > zx[2].r = 3.0; zx[0].i = 0.0; > > zy[0].r = 1.0; zy[0].i = 0.0; > zy[1].r = 2.0; zy[0].i = 0.0; > zy[2].r = 3.0; zy[0].i = 0.0; > > int n=3, incx=1, incy=1; > F77_CALL(zdotc)(&ret_val, &n, zx, &incx, zy, &incy); > Rprintf("ret_val = %f, %f\n", ret_val.r, ret_val.i); > } > > This does not work. When I run '.C('testzdotc')' there is > typically a delay for a second or so, then I get: 0.0, 0.0 > instead of the correct ans: 14.0, 0.0.I tried calling zdotc through an intermediate Fortran routine hoping it would solve your problem. Above C routine changed to <code> #include "R.h" void F77_NAME(callzdotc)(Rcomplex *, int *, Rcomplex *, int *, Rcomplex *, int *); void testzdotc() { Rcomplex zx[3], zy[3], ret_val; zx[0].r = 1.0; zx[0].i = 0.0; zx[1].r = 2.0; zx[0].i = 0.0; zx[2].r = 3.0; zx[0].i = 0.0; zy[0].r = 1.0; zy[0].i = 0.0; zy[1].r = 2.0; zy[0].i = 0.0; zy[2].r = 3.0; zy[0].i = 0.0; int n=3, incx=1, incy=1; F77_CALL(callzdotc)(&ret_val, &n, zx, &incx, zy, &incy); Rprintf("ret_val = %f, %f\n", ret_val.r, ret_val.i); } </code> The fortran subroutine is <code> subroutine callzdotc(retval,n, zx, incx, zy, incy) integer n, incx, incy double complex retval, zx(*), zy(*) external double complex zdotc retval = zdotc(n, zx, incx, zy, incy) return end </code> Made a shared object with R CMD SHLIB --output=dozdot.so callzdotc.f czdot.c and ran dyn.load("dozdot.so") .C("testzdotc") with the result 0.0, 0.0 I would've expected this to give the correct result. Berend Mac OS X 10.6.8 R2.14.2 Using reference Rblas.