Loading...
You are not logged-in Login/Register





  • Posts   Search Threads
  • riccardo42July 7, 2009 5:31 AM PDT   
    Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    Hi,

    I'm exploring the opportunities offered by the Fortran 2003 standard to create C-interoperable functions and subroutines and I stumbled in what seems like an error in the code generated by the compiler on a rather simple function.

    Here is the fortran module (lines marked as OPTIONAL can be commented without changing the behaviour of the code generated, I left them to give an idea of what my original test was):


    ----------- test_module.f90 -----------
    module test_module

    contains

    function arrayfunc(size) bind(c)
    use iso_c_binding
    implicit none
    integer(c_int),value::size
    type(c_ptr),target::arrayfunc
    real(c_double),target,allocatable,dimension(:)::array
    integer::i !OPTIONAL

    print *,"The size received is: ",size

    allocate(array(1:size)) ! OPTIONAL
    if (.not. allocated(array)) then ! OPTIONAL
    print *, "Array not allocated..." ! OPTIONAL
    end if ! OPTIONAL
    ! OPTIONAL
    do i=1,size ! OPTIONAL
    array(i) = i*i ! OPTIONAL
    enddo ! OPTIONAL
    ! OPTIONAL
    arrayfunc=C_LOC(array) ! OPTIONAL
    return
    end function arrayfunc

    end module test_module
    ----------------------------

    Here is the C header file:

    ----------- test_module.h -----------
    #ifndef TEST__MODULE_H
    #define TEST__MODULE_H

    // Intent: interface Fortran with C to create a function that returns
    // a C array of allocated memory
    extern double *arrayfunc(int size);

    #endif
    ----------------------------------------

    And this is the C code used to call the fortran function:

    ------------- test.c -----------------

    #include <stdlib.h>
    #include <stdio.h>
    #include "test_module.h"

    int main(int argc, char *argv[])
    {
    double *testarray=NULL;
    int i;

    testarray=arrayfunc(10);

    for(i=0;i&lt;10;i++)
    printf("Element %2d of the Fortran array: %gn", i, testarray[i]);

    return 0;
    }
    ---------------------------

    The function arrayfunc (which should have allocated an array and passed it to the C function) is supposed to print it's "size" argument as the first action (10, which is to be received by value, as explicitly specified in the declaration), however both on ifort 10.1 (ia32) and ifort Version 11.1 (ia64) where I tested the code, the argument seems to be received incorrectly (in fact in the 64bit example, the variable seems to point to uninitialized memory...).

     

    This is what happens with ifort 10.1 on my atom N270 (ia32):

    $ ./test
    The size received is: 134520820

    and those are a couple of results on my Q9550 (ia64 with a 64bit ubuntu):

    $ ./test 
    The size received is: -1720334552
    Segmentation fault
    $ ./test
    The size received is: -2028769016
    Segmentation fault
    $ ./test
    The size received is: 1024856360
    forrtl: severe (41): insufficient virtual memory
    Image PC Routine Line Source
    libintlc.so.5 00007F6133E3BB2D Unknown Unknown Unknown
    libintlc.so.5 00007F6133E3A635 Unknown Unknown Unknown
    libifcore.so.5 00007F6134842535 Unknown Unknown Unknown
    libifcore.so.5 00007F61347B4A2D Unknown Unknown Unknown
    libifcore.so.5 00007F6134801CF8 Unknown Unknown Unknown
    libifcore.so.5 00007F6134801B51 Unknown Unknown Unknown
    libtest_module.so 00007F6134D4198B Unknown Unknown Unknown
    test 000000000040068D Unknown Unknown Unknown
    libc.so.6 00007F61349ED5A6 Unknown Unknown Unknown
    test 00000000004005A9 Unknown Unknown Unknown

    I have tested the same example with 2 other compilers on both computers and the result was, as expected, something like:

     

     The size received is:           10
    Element 0 of the Fortran array: 1
    Element 1 of the Fortran array: 4
    Element 2 of the Fortran array: 9
    Element 3 of the Fortran array: 16
    Element 4 of the Fortran array: 25
    Element 5 of the Fortran array: 36
    Element 6 of the Fortran array: 49
    Element 7 of the Fortran array: 64
    Element 8 of the Fortran array: 81
    Element 9 of the Fortran array: 100

    The code was interfaced with gcc-4.33 (although for what I know about assembly I'm rather positive it isn't relevant to the matter at hand) and the fortran code compiled in many different ways (as a shared library, as a simple object file, with/without debugging symbols, with/without optimization enabled and so forth...).

     

    Now because I'm not coding in Fortran since a long while the fortran code might not be fit to my purpose, however I think there is still a glitch in the compiler that might be worth a bug report.

     

    I read some documentation on this site and elsewhere about C-Fortran interfaces, but since I'm new to the task, any comment, suggestion or costructive critic will be highly appreciated.

     

    Thank you for your time and patience,

    Riccardo

    PS: I apologize for the poor look of this post (I'm in the software network since half an hour and I'm not yet skilled with the composer :-) )



    riccardo42July 7, 2009 7:47 AM PDT
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    So far I've tested this on IA-32 with 11.1 and it works correctly.  I'll try some other combinations.

    is there any information i can add to help track down the problem (e.g. i could post the annotated assembly, if it could be of any help, or some other info about my system)?

    Thank you very much for your help!

    Riccardo


    Steve Lionel (Intel)July 7, 2009 7:56 AM PDT
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    I retract what I wrote earlier (I deleted my post before seeing yours).  The test I did was not close enough to what you did.  I can see a problem on IA-32 but don't yet know where the problem lies.  I'll get back to you.


    Steve

    Attaching or including files in a post
    Doctor Fortran blog
    @DoctorFortran on Twitter

    TimP (Intel)July 7, 2009 9:10 AM PDT
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    In order to reproduce the error, I used
    ifort -c -g test_module.f90
    icc -g test.c test_module.o -lifcore
    The result varies according to whether I run in idb or directly from command line, and with optimization.
    As indicated, 'gfortran test_module.f90 test.c' produces the expected results.


    Steve Lionel (Intel)July 10, 2009 7:47 AM PDT
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    Curiously, this fails on Linux but works on Windows.  I can't quite tell what the Linux code is doing except that it doesn't seem to be doing the "obvious" error of ignoring VALUE.  Rather, it seems to be looking in the wrong location for the argument.

    I have escalated this to the developers - the issue ID is DPD200137800. As a workaround, I'd suggest removing the VALUE attribute and passing the size by reference.


    Steve

    Attaching or including files in a post
    Doctor Fortran blog
    @DoctorFortran on Twitter

    Steve Lionel (Intel)July 10, 2009 8:48 AM PDT
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    I forgot to mention - there's an error in your code as well.  You need to declare the allocatable array with the SAVE attribute, as without it, the array is automatically deallocated on exit from the routine.


    Steve

    Attaching or including files in a post
    Doctor Fortran blog
    @DoctorFortran on Twitter

    riccardo42July 10, 2009 10:06 AM PDT
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    Curiously, this fails on Linux but works on Windows.  I can't quite tell what the Linux code is doing except that it doesn't seem to be doing the "obvious" error of ignoring VALUE.  Rather, it seems to be looking in the wrong location for the argument.

    I have escalated this to the developers - the issue ID is DPD200137800. As a workaround, I'd suggest removing the VALUE attribute and passing the size by reference.


    My personal solution was to just use a subroutine with an extra argument for the output, but I'll try the size passed by reference as well, Thank you!

    I had the impression that something funny was happening on the stack, but not being so good with asm, I tought not to mention it.

    Thank you for your help,
    Riccardo

    PS: you definitely made my day with the SAVE correction. As a C programmer I had never expected garbage collecting behaviours from an "old" language like fortran. That's explains all those: "double free errors" from libc :-D


    Steve Lionel (Intel)July 22, 2009 11:54 AM PDT
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    Your workaround is good - the problem is that on Linux and Mac OS, the compiler is using a hidden extra argument to return values that are small structures, such as C_PTR - it doesn't do this on Windows.  Since C isn't calling the routine this way, the arguments are in the wrong place and everything goes downhill from there.

    This will be fixed in a future update.  The compiler ought not to be using hidden arguments for any BIND(C) routine.


    Steve

    Attaching or including files in a post
    Doctor Fortran blog
    @DoctorFortran on Twitter

    Steve Lionel (Intel)November 3, 2009 7:52 AM PST
    Rate
     
    Re: Fortran 2003 C-interoperable code: possible wrong assembly generation by the compiler

    This is fixed in 11.1 Update 3.


    Steve

    Attaching or including files in a post
    Doctor Fortran blog
    @DoctorFortran on Twitter

Forum jump:  

Intel Software Network Forums Statistics

17,025 users have contributed to 48,319 threads and 172,758 posts to date.

In the past 24 hours, we have 11 new thread(s) 54 new posts(s), and 47 new user(s).

In the past 3 days, the most popular thread for everyone has been Optimalization of sine function\'s taylor expansion The most posts were made to Most likely, the issue is that The post with the most views is Optimalization of sine function\'s taylor expansion

Please welcome our newest member redfruit83


For more complete information about compiler optimizations, see our Optimization Notice.