- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have tried a number of ways to get this to work, and I believe that it should. I have a double pointer in a main c++ routine, i.e., a matrix. C++ seems to pad or junk up the memory space somehow, and even when taking precautions for column ranking and indexing, and even when using the c_f_pointer subroutine, I get junk values inserted into the matrix when I pass it to fortran. Here is an example that fails:
module generator_mod
use iso_c_binding
contains
SUBROUTINE POP_GEN(popc,row,cols)
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTEGER, intent(in) :: row, cols
type(c_ptr), intent(in),VALUE :: popc
DOUBLE PRECISION, pointer, dimension(:,:) :: population
INTEGER :: i, j
call C_F_POINTER(popc, population,[row,cols])
print*, "HERE IN POPGEN START\n\n"
DO i=1,cols
DO j=1,row
print*, "begin is ", i, j, population(j,i)
ENDDO
END DO
print*, 'shape ', SHAPE(population), '\n\n'
print*, 'dimen1 ', SIZE(population,1)
print*, 'dimen2 ', SIZE(population,2)
print*, 'pop(row,cols)', population(row,cols)
print*, 'pop(cols,row)', population(cols,row)
END SUBROUTINE POP_GEN
end module generator_mod
The C++ is pretty basic:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
extern "C" {
void generator_mod_mp_pop_gen(double**,int*,int*);
}
int main(int argc, char **argv) {
int i;
int j;
int k=1;
int rows = 8;
int columns = 3;
double **population = new double* [columns];
for(i=0;i population = new double[rows];
for(j=0;j population = double(k);
k++;
}
}
for(j=0;j for(i=0;i cout << "c++: " << j << "," << i << " : " << population << endl;
}
}
int err;
generator_mod_mp_pop_gen(population, &rows, &columns);
return(0);
}
Output:
ifort -fno-math-errno -vec-report0 -nowarn -assume bscc -nofor-main -lstdc++ -assume nounderscore gen.o main.o
c++: 0,0 : 1
c++: 0,1 : 9
c++: 0,2 : 17
c++: 1,0 : 2
c++: 1,1 : 10
c++: 1,2 : 18
c++: 2,0 : 3
c++: 2,1 : 11
c++: 2,2 : 19
c++: 3,0 : 4
c++: 3,1 : 12
c++: 3,2 : 20
c++: 4,0 : 5
c++: 4,1 : 13
c++: 4,2 : 21
c++: 5,0 : 6
c++: 5,1 : 14
c++: 5,2 : 22
c++: 6,0 : 7
c++: 6,1 : 15
c++: 6,2 : 23
c++: 7,0 : 8
c++: 7,1 : 16
c++: 7,2 : 24
HERE IN POPGEN START
begin is 1 1 1.560269586132090E-316
begin is 1 2 1.560273538657257E-316
begin is 1 3 1.560277491182424E-316
begin is 1 4 4.001931731314097E-322
begin is 1 5 1.00000000000000
begin is 1 6 2.00000000000000
begin is 1 7 3.00000000000000
begin is 1 8 4.00000000000000
begin is 2 1 5.00000000000000
begin is 2 2 6.00000000000000
begin is 2 3 7.00000000000000
begin is 2 4 8.00000000000000
begin is 2 5 0.000000000000000E+000
begin is 2 6 4.001931731314097E-322
begin is 2 7 9.00000000000000
begin is 2 8 10.0000000000000
begin is 3 1 11.0000000000000
begin is 3 2 12.0000000000000
begin is 3 3 13.0000000000000
begin is 3 4 14.0000000000000
begin is 3 5 15.0000000000000
begin is 3 6 16.0000000000000
begin is 3 7 0.000000000000000E+000
begin is 3 8 4.001931731314097E-322
shape 8 3
dimen1 8
dimen2 3
pop(row,cols) 4.001931731314097E-322
pop(cols,row) 0.000000000000000E+000
ANY help appreciated. This is very frustrating.
module generator_mod
use iso_c_binding
contains
SUBROUTINE POP_GEN(popc,row,cols)
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTEGER, intent(in) :: row, cols
type(c_ptr), intent(in),VALUE :: popc
DOUBLE PRECISION, pointer, dimension(:,:) :: population
INTEGER :: i, j
call C_F_POINTER(popc, population,[row,cols])
print*, "HERE IN POPGEN START\n\n"
DO i=1,cols
DO j=1,row
print*, "begin is ", i, j, population(j,i)
ENDDO
END DO
print*, 'shape ', SHAPE(population), '\n\n'
print*, 'dimen1 ', SIZE(population,1)
print*, 'dimen2 ', SIZE(population,2)
print*, 'pop(row,cols)', population(row,cols)
print*, 'pop(cols,row)', population(cols,row)
END SUBROUTINE POP_GEN
end module generator_mod
The C++ is pretty basic:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
extern "C" {
void generator_mod_mp_pop_gen(double**,int*,int*);
}
int main(int argc, char **argv) {
int i;
int j;
int k=1;
int rows = 8;
int columns = 3;
double **population = new double* [columns];
for(i=0;i
for(j=0;j
k++;
}
}
for(j=0;j
}
}
int err;
generator_mod_mp_pop_gen(population, &rows, &columns);
return(0);
}
Output:
ifort -fno-math-errno -vec-report0 -nowarn -assume bscc -nofor-main -lstdc++ -assume nounderscore gen.o main.o
c++: 0,0 : 1
c++: 0,1 : 9
c++: 0,2 : 17
c++: 1,0 : 2
c++: 1,1 : 10
c++: 1,2 : 18
c++: 2,0 : 3
c++: 2,1 : 11
c++: 2,2 : 19
c++: 3,0 : 4
c++: 3,1 : 12
c++: 3,2 : 20
c++: 4,0 : 5
c++: 4,1 : 13
c++: 4,2 : 21
c++: 5,0 : 6
c++: 5,1 : 14
c++: 5,2 : 22
c++: 6,0 : 7
c++: 6,1 : 15
c++: 6,2 : 23
c++: 7,0 : 8
c++: 7,1 : 16
c++: 7,2 : 24
HERE IN POPGEN START
begin is 1 1 1.560269586132090E-316
begin is 1 2 1.560273538657257E-316
begin is 1 3 1.560277491182424E-316
begin is 1 4 4.001931731314097E-322
begin is 1 5 1.00000000000000
begin is 1 6 2.00000000000000
begin is 1 7 3.00000000000000
begin is 1 8 4.00000000000000
begin is 2 1 5.00000000000000
begin is 2 2 6.00000000000000
begin is 2 3 7.00000000000000
begin is 2 4 8.00000000000000
begin is 2 5 0.000000000000000E+000
begin is 2 6 4.001931731314097E-322
begin is 2 7 9.00000000000000
begin is 2 8 10.0000000000000
begin is 3 1 11.0000000000000
begin is 3 2 12.0000000000000
begin is 3 3 13.0000000000000
begin is 3 4 14.0000000000000
begin is 3 5 15.0000000000000
begin is 3 6 16.0000000000000
begin is 3 7 0.000000000000000E+000
begin is 3 8 4.001931731314097E-322
shape 8 3
dimen1 8
dimen2 3
pop(row,cols) 4.001931731314097E-322
pop(cols,row) 0.000000000000000E+000
ANY help appreciated. This is very frustrating.
Link Copied
1 Reply
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I thought we had a prior discussion of this on the forums, but I can't find working search terms. According to my recollection, it was agreed there is no Fortran correspondence to a C ** , with or without iso_c_binding. All my own C++ to Fortran interoperability of multiple dimensioned arrays uses the ancient style single pointer to a linear array, with row and column to linear position calculated explicitly on the C++ side, and the leading dimensions passed in the argument parameter list (BLAS style).
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page