Is it a compilation error ?

Is it a compilation error ?

I have the follwoing solution structure

1. C main projectcalls Fortran interface subroutines

int main(int argc, char **argv) {
...
interface1_(&x,&y);
interface2_(&x,&y);
...
}

2. Fortran static lib project (libinterface.a)calls fortran subroutines from a fortran module

subroutine interface1(x,y)

    use amodule
    ...
    call test1(x,y)

end subroutine

subroutine interface2(x,y)

    use amodule
    ...
    call test2(x,y)

end subroutine

3. Fortran static lib project (libamodule.a)
a module that contains some computation routines

module amodule
    implicit none
contains

subroutine test1(x,y)
...
end subroutine test1

subroutine test2(x,y)
...
end subroutine test

end module

Now I comment the subroutine 'test2', recompile libamodule.a, and when I'll compile libinterface.a (which reference to test2 subroutine), it will be successfully compiled. The compiler does not detect that libinterface.a references on the subroutine that does not exist! Is it an error ?Thanks

20 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

No, it is not an error. If the compiler does not see test2 in a module it assumes it is an external procedure. You would see an error when you linked the program.

Steve - Intel Developer Support

I could take a look at this, but what you're doing in the main program is not good. You should never rely on name decoration with the underscore like you're doing. Firstly, g77 wouldn't compile this - it uses 2 underscores. And there is no guarantee that we might someday do some other name decoration.

Why aren't you using an interface for interface1 and interface2? Or put them into a module and USE the module in your main program? You do know there is a -gen-interfaces compiler option that could be used to compile the source file with interface1 and interface2 to automatically generate the interfaces.

Aside from the benefits of making the code more readable, a module or interface could prevent some potential unnecessary data copy-in copy-out for the arguments. It enhances code maintenance and performance. It's a win-win as they say.

I'll take a look at this later today. What compiler version are you using?

ron

I would suggest using BIND(C) to make sure that naming is consistent. That would remove the trailing underscore.

Steve - Intel Developer Support

Thank you, Ron!
I did not know about an interface option, it looks very promising, could you give me the reference/link to read more about it, please ?I use 11.1 (cluster) and 12 (local) versions of compilers.Could you advice me the other thing I cannot resolve since several days: IDB does not see breakpoints in my code, and it skips them. But if I do line by line from the start I can attain these lines without problem.What may be the reason of such unresolved breakpoints? Something wrong in the code that compiler does not understand? but I cannot find what exactly it is...Thank you for your help!

About the breakpoints: if you compiled the code with any optimizations turned on (whether you specified such options explicitly or they are turned on in your default configuration or in your project) the compiled code will probably not execute in the same order as your source statements.

For instance, the compiler can turn nested DO loops inside out. Stepping through such source lines can be disconcerting if you are not used to this behavior. In fact, you can press F10 or F11 and the cursor can go back several lines.

Anyway, we need a more complete and specific description of the debugger problem.

debugger options :

FORT        = ifort -g3 -O0 -fpp -threads -traceback -w -C -c
LINKER      = ifort -static -nofor_main -o
FLAGS       = -I/usr/local/include -I/usr/include
C           = icc -g3 -O0 -fpp -traceback -w -C -c

the structure of the solution as descibed above :main in C that calls fortran subroutines via fortran interface projectproblem :debugger skips any breakpoint (warning: unresolved breakpoint)please, let me know what other information do you need ?

One explanation, which you can easily rule out by checking: sometimes, one has two sets of sources: e.g., a back up set and a working set, in different directories. If the working set is modified and compiled, but the debugger us told to open up the source files from the backup set, it is going to be very confusing when it uses incorrect mapping from program counter to line number.

I did not touch working sets at all. I use makefile compilation which indicates the paths to source code.is there other reasons to have unresolved breakpoints ?

Try placing a break point in your C main, then step into the Fortran code. Does the source window show the correct position?

If Step Into performs a Step Over then this is an indication that debug information was stripped from the Fortran code (example, linker settings set to remove debug info).

If Step Into goes into (something) but the source window does not reflect the correct position in the Fortran file then this indicates one of

a) The source file viewed is not the one used for build (what mecej4 was referring to).
b) The object file linked was not built with the source file viewed
c) The (a) preprocessor or Fortran INCLUDEbunged up the line numbers

If the Step Into steped correctly, try placing a break point on the next statement. Does the break point set? If so, does Continue run to the break point?

Jim Dempsey

www.quickthreadprogramming.com

any breakpoint in main C is unresolved breakpoint (debugger show a warning message, and the line is red highlighted in eclipse)thus if I set some breakpoints in main C , all they will be skiped.if I set a breakpoint in my fortran project, debugger stops at this breakpoint

now>>if I set a breakpoint in my fortran project, debugger stops at this breakpoint

earlier>>debugger skips any breakpoint (warning: unresolved breakpoint)

I'm confused - conflicting statements.

also>>any breakpoint in main C is unresolved breakpoint

then main C is not compiled with debug informaton (or linker stripped it out).

One of the purposes of breaking in main C, then stepping into the Fortran function (which may require you to step in via the dissassembly window(if stepping in from source window does not work)), is, when using the dynamic load library the step into (at some point) will (on first call)trap into theO/Sto locate and load the library, then continue the step into in the called function. At this point, it may become evident that the library loaded is not the library you think is being loaded. To aid this, temporarily adda statement just after the entry point thatdoessomething innoucous, but is clearly seen in source and dissassembly (and is not inlined)

subroutine foo
! data declarations
! first code statement
X = DRAND(0) ! call external function, store in existing variable
! original code follows

IIF you can step intousing sorce window, restart and step into using Dissassembly window. In either case, after the
library loads, you will notice one of the following

a) source without X = DRAND(0) is shown
b) source with X = DRAND(0) is shown *** however,dissassembly code does notcontain calldrand...
c) source with X = DRAND(0) is shownand call drand is present
d) no sorce is shown call drand is NOT present
e) no sorce isshown call drand is present

What do you observe?

Jim Dempsey

www.quickthreadprogramming.com

I found a very strange case :when i is global variable

module m
...
integer i
...
subroutine sb...
...
    DO i=1,n
        print *, i
        some_array(i) =  ...
    END DO
...
end subroutine sb
...
end module

the function 'print' will print the correct values, while in Variables or Expression windows of Eclipse i=16843009it means that the next breakpoint step the index i will be out of the range, and breakpoint become unresolvedif I declare the variable i as a local one the breakpoint is skipped tooDo you know what is the reason ?Thanks

Jim, sorry for this ambigous phrases.I tested different cases, and they gave different results, and I could not find any logic between themat this stage, I took an empty C project, created only main function and called my fortran subroutine stored in static library modulethis way I can be concentrated only on errors from Fortran codefortran module was compiled with debug info and linked with static option to main C object filethe options of compilation and linking you can find at the beginning of this topic, as well as the struction of my projects.as you've probably read my previous message, I found that there is something wrong with global module variables, because the debugger does not see their right values when it is stopped in some subroutine.it was one of the cases when the breakpoints became unresolved, perhaps there are other cases that I did not find yet.

When compiling with optimizations enabled, your integer i might get hoisted into a register. Your print *,i will work fine, but examining the memory location of i becomes meaningless.

Note, at the end of the DO i= loop, the register copy of i should be copied back into the global i. However, if the whole program is visible to the compiler and i is not used excepting for in this subroutine, then the loop control variable (in register) i might not get copied into the global (module) variable i.

Note 2, if the copy from register i to module i is performed after end of loop, it won't be copied back at break point (say on the print). There is where you will see the discrepancy. In this case, the debugger, while in scope of DO i loop should indicate i is a register variable. The memory watch window (set outside the loop) will observe the global i (not the registered copy of i) so you will either see it as load image initialization or after termination of DO loop, whichever occured last. If you want to track i during execution, call a dummy external routine (not visiable to the compiler optimization). You can also compile with OpenMP enabled, then add:

DO i=1,n
!$OMP FLUSH (i)
...

Note, this is a convienence for debugging and not pertinant for the execution of your do loop unless i is used as a progress indicator by some other thread, and in which case you will need something like !$OMP FLUSH (i) or attribute the variable i as volatile. Note, the !$OMP FLUSH (i) may be a better choice than volatile or add a integer, volatile ::iProgress

and then use

iProgress = i

in your DO loop

Jim Dempsey

www.quickthreadprogramming.com

Thank you, Jim, for your explanation!the fact that the code is compiled without optimization enable, the options -g3 -O0 and -static for linking are used.and I switched off the MPI partsI've replaced my global module i by a local variable, and this does not solve the problem with unresolved breakpointsThe fortran module has thousands of arrays to allocate as global variables with SAVE option, the debugger steps between neigbour statements are unreally very long (15 sec and more). is it possible that the debugger can not handle such volumes of variables ? or does SAVE option disturbe the debug process ?

When single stepping across

arrayA = arrayB

while compiled with array bounds checking enabled (an option in the Debug and/or release builds) then each element of arrayA = arrayB will be bounds tested. You may want to turn off bounds checking (for those source files tested at least once with bounds checking and retest later when varying a parameter that might cause an array indexing error).

Note,

arrayA(i) = (expression)

will get set eventhough i may get registerized.

Also note, vectorization might store multiple sequences at once

arrayA(i) = (expression)
arrayA(i+1) = (expression')
arrayA(i+2) = (expression'')
arrayA(i+3) = (expression''')

When data is aligned properly and the compiler can reliably compute expression', expression'' and expression '''

Jim Dempsey

www.quickthreadprogramming.com

I have this error when I try to run an executable.

"filename truncated to thirty one characters"

someone who can help me?

Thanks

If I may be permitted to be facetious, I would offer the following program as a candidate:

print *,"filename truncated to thirty one characters"
end 

If you want a more helpful answer, you should give more particulars about your program.

Hello,

I see that (one of) your question(s) still hasn't been answered yet.

I've tried to reproduce the problem reported (BPs in C source file cannot be set). However, I've not seen anything like that.
Instead I'd like to provide a working example based on your previous posts for verification:

main.c:

int main(int argc, char **argv) {
    int x = argc;
    int y = argc / 2;

    interface1_(&x,&y);
    interface2_(&y,&x);
}

module.f90:

module amodule
    implicit none
    contains

    subroutine test1(x,y)
    integer x, y
        write (*,*) x, y
    end subroutine test1

    subroutine test2(x,y)
    integer x, y
        write (*,*) x, y
    end subroutine test2
end module

interface.f90:

subroutine interface1(x,y)
    use amodule
    integer x, y
    call test1(x,y)

end subroutine

subroutine interface2(x,y)
    use amodule
    integer x, y
    call test2(x,y)

end subroutine

Compile, using ICC & IFORT (both should have same version):

ifort -g3 -O0 -fpp -threads -traceback -w -C -c module.f90
ar rcs libmodule.a module.o
ifort -g3 -O0 -fpp -threads -traceback -w -C -c interface.f90
ar rcs libinterface.a interface.o
icc -g3 -O0 -fpp -traceback -w -C -c main.c

ifort -static -nofor_main -o main_fort main.o -L. -linterface -lmodule
icc -static -o main_c main.o -L. -linterface -lmodule -lifcore

I've tested both 12.1 Update 6 & 11.1 Update 9.

Testing the binaries, you'll see this:

$ ./main_c
           1           0
           0           1

$ ./main_fort 
           1           0
           0           1

Now start IDB. I'll be using 12.1 Update 6 here but also tested with the older 11.1 version.
Load either main_c or main_fort and set a BP for symbol main. Once the debuggee was executed you'll stop there and soruce file main.c is shown.
In my case I was able to set BPs in all C & Fortran source files at the same time, and actually stopping there:

Maybe you can try the exact same steps and let me know if something does not work for you or what you're doing differently.

Regarding your other problem (evaluating variable "i") you might
use the provided code and extend it to reproduce what you're seeing.
Please don't forget to specify exactly what you're doing with the
debugger to evaluate it (were you set BPs, continue, step, etc.). The context during evaluation is critical for
the results of evaluations and clarifies whether this is expected
behavior (by language standard) or a problem (e.g. debug information).

@Jim, the DWARF debug standard defines "location expressions" that can be both memory or registers. The presentation is transparent for the user, which means it's not relevant where a variable "i" is stored (permanently or even temporarily). Thanks the debug information the debugger always reads from the correct location, depending on the current PC.
The only case where the debugger might fail to handle a location expression is for variables being optimized away. However, that's not the case here -> #15.

Best regards,

Georg Zitzlsberger

Leave a Comment

Please sign in to add a comment. Not a member? Join today