ZooKernel/Support/Fotran

Fortran Support in ZOO Kernel

This page will contain full information about the Fortran support in the ZOO Kernel.

Fortran code snipest

Let us create a small example of a Fortran function which simply multiply by two the value passed as argument.

C     ex4.for 
C     ARRAYS X, Y and Z are respectively :
C     main_conf, inputs and outputs
      FUNCTION HELLOWORLD(X, Y, Z, X0) RESULT (R)
      INTEGER(4) :: R
      CHARACTER*1024 X(10,10)
      CHARACTER*1024 Y(10,10)
      CHARACTER*1024 Z(10,10)
      CHARACTER*100 X0
C      CHARACTER*(*) X(10,10), Y(10,10), Z(10,10)
C     The following will display the right string
      PRINT *,'FROM FORTRAN : '//X0
C     The following won't display the right string
C      PRINT *,Y(1,4)
      Z(1,1) = 'name'
      Z(1,2) = 'result'
      Z(1,3) = 'value'
      Z(1,4) = 'Hello from the Fortran world !'
      Z(1,5) = 'dataType'
      Z(1,6) = 'string'
      PRINT *,Z(1,4)
      R = 3
      END

To create a shared library of this code snipest, use the following command :

gfortran -fno-f2c -shared -s -o ex4.so ex4.for

Then the loading process isthe same as before, using the dlload, dlsym then use the funcion.

The snipest C++ code bellow will load, extract the function from the fortran shared library then run the function and finally close the shared library.

// ex4fortranloader.c
#include <iostream>
#include <dlfcn.h>
int main()
{
    void *hDll = dlopen("./ex3.so", RTLD_NOW);
    typedef int (* LPFNDLLFUNC) (char***,char***,char***,char*);
    LPFNDLLFUNC lpFunc = NULL;
    lpFunc = (LPFNDLLFUNC)dlsym(hDll, "helloworld_");
    int i, numPts = 10;

    char*** main_conf=(char***)malloc(10*sizeof(char**));
    char*** inputs=(char***)malloc(10*sizeof(char**));
    char*** outputs=(char***)malloc(10*sizeof(char**));
    printf("first allocation has been made\n");
    for(int i=0;i<10;i++){
        main_conf[i]=(char**)malloc(10*sizeof(char*));
        inputs[i]=(char**)malloc(10*sizeof(char*));
        outputs[i]=(char**)malloc(10*sizeof(char*));
        printf("allocation for level %d\n",i+1);
        for(int j=0;j<10;j++){
          main_conf[i][j]=(char*)malloc(1024*sizeof(char));
          memset(main_conf[i][j],0,1024);
          main_conf[i][j][0]=0;
          inputs[i][j]=(char*)malloc(1024*sizeof(char));
          memset(inputs[i][j],0,1024);
          inputs[i][j][0]=0;
          outputs[i][j]=(char*)malloc(1024*sizeof(char));
          memset(outputs[i][j],0,1024);
          outputs[i][j][0]=0;
          printf("allocation for elements (%d,%d)\n",i+1,j+1);
       }
    }
    sprintf(inputs[0][0],"name");
    inputs[0][0][4]=0;
    printf("inputs[0][0] = %s\n",inputs[0][0]);
    sprintf(inputs[0][1],"S");
    inputs[0][1][1]=0;
    printf("inputs[0][1] = %s\n",inputs[0][1]);
    sprintf(inputs[0][2],"value");
    inputs[0][2][5]=0;
    printf("inputs[0][2] = %s\n",inputs[0][2]);
    sprintf(inputs[0][3]," Your Name Here ");
    inputs[0][3][16]=0;
    printf("inputs[0][3] = %s\n",inputs[0][3]);
    printf("Allocation made of inputs values\n");
    char *tmp=(char*)malloc(100*sizeof(char));
    sprintf(tmp,"My Test String");
    int res=lpFunc(main_conf,inputs,outputs,tmp);
    printf("function ran successfully and retruned : %d\n",res);
    // Unable to get back the outputs array 
    //printf("z[1][4] = %s\n",outputs[0][0]);
    dlclose(hDll);
    return 0;
}

Compile this code using the following command :

g++ -o ex1fortranloader ex1fortranloader.cpp -ldl

Now, to process the function you'll only have to run the following command :

./ex1fortranloader 

Which should output :

first allocation has been made
inputs[0][0] = name
inputs[0][1] = S
inputs[0][2] = value
inputs[0][3] =  Your Name Here 
Allocation made of inputs values
 FROM FORTRAN : My Test String

 Hello from the Fortran world !
                                                                                                                                              
                                                                                                                                              
                                                                                                                                              
                                                                                                                                              

function ran successfully

Conclusion

So we can say that loading a C SSO (Service Shared Object) or a Fortran one work in the same way.

The goal is now to be able to pass maps* datastructure to the fortran function then let user easily get/set its data using this datastructure. Maybe a simple multidimentional array of CHARACTER* can be used. This way maps will be translated into CHARACTERS[][][] before being passed to the Fortran function.

Documentation list

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png