Silverfrost Forums

Welcome to our forums

ASSEMBLY_INTERFACE and FORTRAN arrays

29 Mar 2012 8:11 #9924

For array parameter - correct me, if I am wrong - using ASSEMBLY_INTERFACE has the following implications:

  1. non assumed-shape arrays are not allowed as parameters for FORTRAN subroutines
  2. assumed shape arrays are mapped to multidimensional arrays on the .NET side

Are there any options to control this behavior? I.e., to map all arrays (assumed shape or not assumed shape) to plain pointers (IntPtr or float*, double*,...) parameters?

29 Mar 2012 2:13 #9925

I don't know of any restrictions that would prevent the passing of simple arrays. The relevant information can be found in the help file under .NET Platform>.NET Programming>Calling Fortran from other .NET languages where is says...

Fortran arrays are mapped to .NET arrays. The (column major) ordering is not changed because this transformation would be expensive for large arrays. Your code must allow for this difference. Thus the C# array element c[1,2] becomes C(2,1) in Fortran. Arrays are passed by reference.

30 Mar 2012 11:03 #9929

Let me try to make my question more clear:

A multidimensional array is declared on the FORTRAN side as parameter of a subroutine:

SUBROUTINE FORT_TEST(A,M) INTEGER M REAL A(M,: ) ASSEMBLY_INTERFACE(NAME='FORT_TEST') !...

Targeting .NET, this subroutine would translate to

void FORT_TEST(float[,] A, int M)

I.e., the FORTRAN 2D array is mapped to a 2D array on the .NET side.

While on the FORTRAN side there is no need to prefer one dimensional arrays over multidimensional arrays, latter certainly introduce a performance hit on the .NET side. Moreover, multidimensional arrays in the CLR use row-major orientation - in contrast to column-major orientation in FORTRAN - as you pointed out in the documentation. Hence, one can say, multidimensional arrays on .NET are often not the best choice for computationally intensive algorithms. They are for sure not convenient for interchange with FORTRAN.

My question ist about the existence of an option to translate multidimensional arrays from FORTRAN to what they really are: plain pointers to consecutive memory, stored in column major orientation.

I realized that without using ASSEMBLY_INTERFACE all arrays are mapped to pointer types - which would be the desired behavior. But in this case CHARACTER parameters are hard (impossible?) to use. So the best would be to get the best out of both 'worlds'. Is this any possible?

1 Apr 2012 6:31 #9932

One way might be to pretend the array is a scalar that is passed INTENT(INOUT) then it will be passed by reference. You could do this by passing the first element of the array.

1 Apr 2012 11:51 #9933

Right. This would work. Unfortunately, it would require to modify the FORTRAN source. On the .NET side, the method requires to pin the array manually - in contrast to have it pinned automatically, if the array were exposed as double[] array. I was hoping for some kind of compiler configuration option. Do you know of any?

Background: We are providing high performance libraries to .NET users. Our arrays offer all features of FORTRAN arrays. Using them properly gives the user the same speed as the corresponding FORTRAN implementation - as purely managed .NET assembly. If our users could take their FORTRAN sources and use FTN95 to compile them into ILNumerics code without any manual modifications, they would translate their FORTRAN projects to platform independent .NET assemblies - with very little to no performance penalty. This would require the API generated by FTN95 to be compatible to the ILNumerics arrays.

2 Apr 2012 8:59 #9934

I have looked at the code for DBK_LINK and I cannot see any existing options that would help you. No doubt something could be added but there would probably be a charge for doing this.

2 Apr 2012 10:53 #9935

Thanks Paul! What would be the best way to arrange the terms and conditions regarding those additions?

15 Aug 2012 7:05 #10618

Quoted from PaulLaidler Fortran arrays are mapped to .NET arrays. The (column major) ordering is not changed because this transformation would be expensive for large arrays. Your code must allow for this difference. Thus the C# array element c[1,2] becomes C(2,1) in Fortran. Arrays are passed by reference.

1D array [] ordering are identical in .NET and FTN 2D arrays [,] are simply transposed 3D arrays [,,] can be rearranged back to the desired structure with this code:

subroutine csrank3array2fortran (x,b,nr,nc,np)

    ! converts the rank-3 C# array [x] into the rank-3 fortran array [b] or viceversa
    ! Ever J. Barbero, http://barbero.cadec-online.com

    implicit none

    integer i,j,k,nr,nc,np,idx
    double precision x(1), b(nr,nc,np)

    do i=1,nr
        do j=1,nc
            do k=1,np
    !            idx = 1+(i-1)+(j-1)*nr+(k-1)*nr*nc !Fortran to C#
                idx = k + (j-1)*np + (i-1)*nc*np    !C# to Fortran
                b(i,j,k) = x(idx)
            enddo
        enddo
    enddo

end subroutine
15 Aug 2012 10:09 #10619

Can't you just use the reverse index order, as in subroutine csrank3array2fortran (x,b,nr,nc,np)

    ! converts the rank-3 C# array [x] into the rank-3 fortran array [b] or viceversa 

    integer i,j,k,nr,nc,np
    double precision x(np,nc,nr), b(nr,nc,np) 

    do i=1,nr 
       do j=1,nc 
          do k=1,np 
             b(i,j,k) = x(k,j,i) 
          enddo 
       enddo 
    enddo 

end subroutine 

or simply just refer to X using reverse array indexes. The difference between Fortran and C index order should not be a difficult issue.

16 Aug 2012 6:25 #10635

Yes, it works reversing the indexes. thank you!

Please login to reply.