0

What is wrong with the following code walltime.c?

#include <sys/time.h>

void get_walltime_(double* wcTime) {
  struct timeval tp;
  gettimeofday(&tp, NULL);
  *wcTime = (double)(tp.tv_sec + tp.tv_usec/1000000.0);
}

void get_walltime(double* wcTime) {
 get_walltime_(wcTime);
}

It is a C routine meant get time stamp at the time of execution. It's an exact copy of the code in page 6 of this book. It is meant to be called in the following Fortran code to measure time elapsed between floating point operations:

double precision, dimension(N) :: A,B,C,D
double precision :: S,E,MFLOPS

do i=1,N                          !initialize arrays
  A(i) = 0.d0; B(i) = 1.d0
  C(i) = 2.d0; D(i) = 3.d0
enddo

call get_walltime(S)                ! get time stamp
do j=1,R
  do i=1,N
    A(i) = B(i) + C(i) * D(i)       ! 3 loads, 1 store
  enddo
  if(A(2).lt.0) call dummy(A,B,C,D) ! prevent loop interchange
enddo
call get_walltime(E)                ! get time stamp
MFLOPS = R*N*2.d0/((E-S)*1.d6)      ! compute MFlop/sec rate

When I try compiling on Ubuntu 20.04 with gcc walltime.c -o walltime, I get this error:

walltime.c:6:27: error: ‘NULL’ undeclared (first use in this function)
    6 |         gettimeofday(&tp, NULL);
      |                           ^~~~
walltime.c:3:1: note: ‘NULL’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
    2 | #include <sys/time.h>
  +++ |+#include <stddef.h>
    3 | 
walltime.c:6:27: note: each undeclared identifier is reported only once for each function it appears in
    6 |         gettimeofday(&tp, NULL);
      |                           ^~~~

If I add #include <stddef.h> at the top and try to compile again, I get this error:

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
skirthy
  • 1
  • 1
  • 1
    You aren't providing a [mre], but it seems the Fortran side is providing the "main program". You'll need to link against the Fortran object providing the main, as given in a couple of answers to the linked question – francescalus Jul 15 '23 at 15:44
  • I suggest taking the [tour]. It will also show how you can accept or later upvote answers to your questions. – Vladimir F Героям слава Jul 17 '23 at 11:39

1 Answers1

0

You've worked out how to define 'NULL', which fixes the first error. You need to compile with gcc -c walltime.c -o walltime.o because you have just defined a module. If you link this to your Fortran program it should do as required.

Dave Atkinson
  • 46
  • 1
  • 5
  • Dave, thanks for your respose. I'm able to generate the object file 'walltime.o' using 'gcc -c walltime.c'. What you're saying is, since this doesn't have a 'main' function declaration, I can't create an executable file, but can link the this object file with the other object file from the main Fortran code. Is that correct? – skirthy Jul 15 '23 at 15:32
  • @skirthy, that is exactly what I'm saying ;-) I'm afraid I don't immediately know how to do this for fortran, as I've never written or compiled it myself, but that is the basic idea. In C, you can link a bunch of .o files together, and one and only one of them must contain a function called main, and that will allow an executable program to be created. I would have to go and read the manual to see what the rules are for fortan... – Dave Atkinson Jul 15 '23 at 20:21
  • It worked. I generated an object file from the main fortran code using used 'gfortran -c main.f90' and linked the object files using 'gfortran -o mflops main.o walltime.o'. This generated an executable called mflops, which ran without any issues. Thanks! – skirthy Jul 16 '23 at 16:11