Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Passing a 2 dimensional array from c++ to fortran

Reply
Thread Tools

Passing a 2 dimensional array from c++ to fortran

 
 
Sam
Guest
Posts: n/a
 
      06-30-2005



Hello all
I have a two dimensional array (the dimensions are not known) that
needs to be passed
to fortran from c++, allocate the dimensions of the array in fortran
code, do some filling up
of the array in fortran and then accessing it in my c++ code.

Say in my c++ code I have;

extern "C" { void foo_(float **, int &, int &); }

int main()
{
............
..............
int rows, columns;
float **array2d; // Now i need to pass this to the fortran code, the
allocation of the array and
// and filling it is done in the fortran code.
// How do i pass this to the fortran subroutine now, i did it this way

foo_(array2d, rows, columns);

// One more question, do i need to do the allocation and stuff here
again
// Do some stuff to manipulate with the array2d

return 0;

}

and my Fortran routine:

subroutine foo(arr,rows,columns)
integer rows, columns
real*8 ,allocatable:: arr (:,
! do some stuff to allocate the arrray and fil the stuff

end subroutine


Any help would be greatly appreciated

Regards
Sam

 
Reply With Quote
 
 
 
 
E. Robert Tisdale
Guest
Posts: n/a
 
      06-30-2005
Sam wrote:

> I have a two dimensional array (the dimensions are not known)
> that needs to be passed to Fortran from C++,
> allocate the dimensions of the array in Fortran code,
> do some filling up of the array in Fortran and then
> accessing it in my C++ code.
>
> Say in my C++ code I have;
>
> extern "C" { void foo_(float **, int&, int&); }


Fortran won't know what to do with an array of pointers to float.

> int main(int argc, char* argv[]) {
> // ...
> // ...
> int rows, columns;
> float **array2d; // Now I need to pass this to the Fortran code,
> // the allocation of the array and filling it
> // is done in the Fortran code.
> // How do I pass this to the fortran subroutine now, I did it this way
>
> foo_(array2d, rows, columns);
>
> // One more question,
> // "Do I need to do the allocation and stuff here again?"
> // Do some stuff to manipulate with the array2d.
>
> return 0;
> }
>
> and my Fortran routine:
>
> subroutine foo(arr,rows,columns)
> integer rows, columns
> real*8 ,allocatable:: arr (:,
> ! Do some stuff to allocate the arrray and fill the stuff
>
> end subroutine foo
>
>
> Any help would be greatly appreciated


To do this,
you must pass a Fortran 90 pointer [to a 2D array]
to a Fortran 90 subroutine foo which allocates memory
for the 2D array and assigns a pointer to the array
to the pointer that you passed into subroutine foo.
Your C++ program must include f90_adapter.h
which contains an f90_2DPointer type definition
for a Fortran 90 2D array pointer (for Absoft in this case).
Function main(int, char**) invokes
function f90_2DPointerPointer(const f90_2DPointer*)
to retrieve the pointer to the beginning of the array
from the Fortran 90 pointer object.

> cat foo.f90

subroutine foo(rows, columns, arr)
integer, intent(in):: rows, columns
integer:: row, column
double precision, pointer, dimension(:,:: arr
double precision, pointer, dimension(:,:: tmp
allocate(tmp(rows, columns))
do column = 1, columns
do row = 1, rows
tmp(row, column) = row + 10*column
end do
end do
arr => tmp
end subroutine foo

> f90 -YEXT_NAMES=LCS -YEXT_SFX=_ -c foo.f90
> cat f77_adapter.h

#ifndef guard_f77_adapter_h
#define guard_f77_adapter_h

#include<stdint.h>
#include<stddef.h>
#include<string.h>

/*
* All Fortran 77 type names are of the form:
*
* f77_<type>
*
* where
*
* <type> in {subroutine, character, integer<size>, logical<size>,
* real_4, real_8, single, double, offset, length} and
* <size> in {, _1, _2, _4}.
*
* Note that the <size> parameter includes the empty string.
*/

typedef void f77_subroutine;

typedef char f77_character;

typedef int8_t f77_integer_1;
typedef int16_t f77_integer_2;
typedef int32_t f77_integer_4;
typedef f77_integer_4 f77_integer;

typedef uint8_t f77_logical_1;
typedef uint16_t f77_logical_2;
typedef uint32_t f77_logical_4;
typedef f77_logical_4 f77_logical;

typedef float f77_real_4;
typedef double f77_real_8;
typedef f77_real_4 f77_real;
typedef f77_real_4 f77_single;
typedef f77_real_8 f77_double;

typedef int f77_offset;
typedef size_t f77_length;

#endif/*guard_f77_adapter_h */

> cat f90_adapter.h

#ifndef guard_f90_adapter_h
#define guard_f90_adapter_h

#include<f77_adapter.h>

#ifdef __cplusplus
#define INLINE inline
#define STATIC
#define PRIVATE private:
#define PUBLIC public:
#else /*__cplusplus */
#define INLINE inline
#define STATIC static
#define PRIVATE
#define PUBLIC
#endif/*__cplusplus */

/*
* All Fortran 90 pointer type names are of the form:
*
* f90_<rank><type>Pointer
*
* where
*
* <rank> in {, 1D, 2D, 3D, 4D, 5D, 6D, 7D},
* <type> in {, single, double, integer<size>, logical<size>,
character}
* and
* <size> in {, _1, _2, _3, _4}.
*
* Note that all three parameters include the empty string.
*/

struct f90_Pointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
void* f90_PointerPointer(const struct f90_Pointer*);
}
#endif/*__cplusplus */

typedef struct f90_Pointer { /* generic scalar pointer */
PRIVATE
void* P[6];
#ifdef __cplusplus
public:
friend const void* f90_PointerPointer(const struct f90_Pointer*);
#endif/*__cplusplus */
} f90_Pointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
void* f90_PointerPointer(const f90_Pointer* p) {
return p->P[0]; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_triplet; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC
size_t f90_tripletExtent(const struct f90_triplet*);
INLINE STATIC
ptrdiff_t f90_tripletStride(const struct f90_triplet*);
}
#endif/*__cplusplus */

typedef struct f90_triplet {
PRIVATE
f77_integer lbound;
f77_integer ubound;
f77_integer stride;
#ifdef __cplusplus
public:
friend size_t f90_tripletExtent(const struct f90_triplet*);
friend ptrdiff_t f90_tripletStride(const struct f90_triplet*);
#endif/*__cplusplus */
} f90_triplet;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC
size_t f90_tripletExtent(const f90_triplet* p) {
return (p->lbound < p->ubound)? (p->ubound - p->lbound + 1):
(p->lbound - p->ubound + 1); }

INLINE STATIC
ptrdiff_t f90_tripletStride(const f90_triplet* p) {
return p->stride; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_1DPointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
void* f90_1DPointerPointer(const struct f90_1DPointer*);
INLINE STATIC
size_t f90_1DPointerExtent1(const struct f90_1DPointer*);
INLINE STATIC
ptrdiff_t f90_1DPointerStride1(const struct f90_1DPointer*);
}
#endif/*__cplusplus */

typedef struct f90_1DPointer { /* generic 1D array pointer */
PRIVATE
void* P[6];
f90_triplet T[1];
#ifdef __cplusplus
public:
friend const void* f90_1DPointerPointer(const struct f90_1DPointer*);
friend size_t f90_1DPointerExtent1(const struct f90_1DPointer*);
friend ptrdiff_t f90_1DPointerStride1(const struct f90_1DPointer*);
#endif/*__cplusplus */
} f90_1DPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
void* f90_1DPointerPointer(const f90_1DPointer* p) {
return p->P[0]; }

INLINE STATIC
size_t f90_1DPointerExtent1(const f90_1DPointer* p) {
return f90_tripletExtent(&(p->T[0])); }

INLINE STATIC
ptrdiff_t f90_1DPointerStride1(const f90_1DPointer* p) {
return f90_tripletStride(&(p->T[0])); }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_2DPointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
void* f90_2DPointerPointer(const struct f90_2DPointer*);
INLINE STATIC
size_t f90_2DPointerExtent1(const struct f90_2DPointer*);
INLINE STATIC
ptrdiff_t f90_2DPointerStride1(const struct f90_2DPointer*);
INLINE STATIC
size_t f90_2DPointerExtent2(const struct f90_2DPointer*);
INLINE STATIC
ptrdiff_t f90_2DPointerStride2(const struct f90_2DPointer*);
}
#endif/*__cplusplus */

typedef struct f90_2DPointer { /* generic 2D array pointer */
PRIVATE
void* P[6];
f90_triplet T[2];
#ifdef __cplusplus
public:
friend const void* f90_2DPointerPointer(const struct f90_2DPointer*);
friend size_t f90_2DPointerExtent1(const struct f90_2DPointer*);
friend ptrdiff_t f90_2DPointerStride1(const struct f90_2DPointer*);
friend size_t f90_2DPointerExtent2(const struct f90_2DPointer*);
friend ptrdiff_t f90_2DPointerStride2(const struct f90_2DPointer*);
#endif/*__cplusplus */
} f90_2DPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
void* f90_2DPointerPointer(const f90_2DPointer* p) {
return p->P[0]; }

INLINE STATIC
size_t f90_2DPointerExtent1(const f90_2DPointer* p) {
return f90_tripletExtent(&(p->T[0])); }

INLINE STATIC
ptrdiff_t f90_2DPointerStride1(const f90_2DPointer* p) {
return f90_tripletStride(&(p->T[0])); }

INLINE STATIC
size_t f90_2DPointerExtent2(const f90_2DPointer* p) {
return f90_tripletExtent(&(p->T[1])); }

INLINE STATIC
ptrdiff_t f90_2DPointerStride2(const f90_2DPointer* p) {
return f90_tripletStride(&(p->T[1])); }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_characterPointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
char* f90_characterPointerPointer(
const struct f90_characterPointer*);
INLINE STATIC
size_t f90_characterPointerLength(
const struct f90_characterPointer*);
}
#endif/*__cplusplus */

typedef struct f90_characterPointer { /* character string scalar
pointer */
PRIVATE
char* P[6];
#ifdef __cplusplus
public:
friend const char* f90_characterPointerPointer(
const struct f90_characterPointer*);
friend size_t f90_characterPointerLength(
const struct f90_characterPointer*);
#endif/*__cplusplus */
} f90_characterPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
char* f90_characterPointerPointer(const f90_characterPointer*
p) {
return p->P[0]; }

INLINE STATIC
size_t f90_characterPointerLength(const f90_characterPointer* p) {
return (size_t)p->P[1]; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_1DcharacterPointer; /* forward de3claration */
#ifdef __cplusplus
extern "C" {
INLINE STATIC const
char* f90_1DcharacterPointerPointer(const
f90_1DcharacterPointer*);

INLINE STATIC
size_t f90_1DcharacterPointerExtent1(const
f90_1DcharacterPointer*);

INLINE STATIC
ptrdiff_t f90_1DcharacterPointerStride1(const
f90_1DcharacterPointer*);

INLINE STATIC
size_t f90_1DcharacterPointerLength(const
f90_1DcharacterPointer*);
}
#endif/*__cplusplus */

typedef struct f90_1DcharacterPointer {/* 1D character string array
pointer*/
PRIVATE
char* P[6];
f90_triplet T[1];
#ifdef __cplusplus
public:
friend const char* f90_1DcharacterPointerPointer(
const struct f90_1DcharacterPointer*);
friend size_t f90_1DcharacterPointerExtent1(
const struct f90_1DcharacterPointer*);
friend ptrdiff_t f90_1DcharacterPointerStride1(
const struct f90_1DcharacterPointer*);
friend size_t f90_1DcharacterPointerLength(
const struct f90_1DcharacterPointer*);
#endif/*__cplusplus */
} f90_1DcharacterPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
char* f90_1DcharacterPointerPointer(const
f90_1DcharacterPointer* p) { return p->P[0]; }

INLINE STATIC
size_t f90_1DcharacterPointerExtent1(const
f90_1DcharacterPointer* p) { return f90_tripletExtent(&(p->T[0])); }

INLINE STATIC
ptrdiff_t f90_1DcharacterPointerStride1(const
f90_1DcharacterPointer* p) { return f90_tripletStride(&(p->T[0])); }

INLINE STATIC
size_t f90_1DcharacterPointerLength(const
f90_1DcharacterPointer* p) {
return (size_t)p->P[2]; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

#undef PRIVATE
#undef PUBLIC
#undef STATIC
#undef INLINE

#endif/*guard_f90_adapter_h */

> cat main.cc

#include <iostream>
#include <f90_adapter.h>

extern "C" {
f77_subroutine foo_(
const
f77_integer&, // rows
const
f77_integer&, // columns
f90_2DPointer& // 2D array
);
}
int main(int argc, char* argv[]) {
const
f77_integer rows = 3;
const
f77_integer columns = 5;
f90_2DPointer arr;
foo_(columns, rows, arr);
f77_double* A = (f77_double*)f90_2DPointerPointer(&arr);
for (f77_integer row = 0; row < rows; ++row) {
for (f77_integer column = 0; column < columns; ++column) {
std::cout << ' ' << A[row*columns + column];
}
std::cout << std::endl;
}

return 0;
}

> g++ -I. -L/opt/absoft/lib -Wall -ansi -pedantic \

-o main main.cc foo.o -lfio -lf77math
> ./main

11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Passing an array from FORTRAN to C then passing it within C andReturning it to FORTRAN deadpickle C Programming 1 11-07-2010 02:38 PM
passing an array to an extern C for fortran routine foice C++ 4 10-14-2010 09:01 AM
To convert a one dimensional array into a two dimensional array using C amrutha0303 Software 0 08-03-2010 10:02 PM
Many Fortran code! How to call Fortran code from C/C++? Luna Moon C++ 9 09-04-2007 03:49 PM
How do copy Strings from a single dimensional array to double dimensional array Venkat C++ 4 12-05-2003 09:23 AM



Advertisments