soes
soes

Reputation: 33

Running MPI fortran code sample make file

I am given a code to run on clusters, and the .sh file content is as below:

compiler  =  mpifort

in8.3     =  mac-ns-2d.8.3.f90

out       =  a.out

inc       =  hypre/include

libs      =  src/hypre/lib

opts      =  -O4

8.3:
    $(compiler) $(opts) -I$(inc) $(in8.3) -o $(out) -L$(libs) -lHYPRE -lm -lstdc++

I see what is the first line, which is my compiler mpifortran, but what is the second line meaning, in8.3? I also know the meaning for out, inc, libs, but what is the purpose of opts -04 and what does 8.3: mean and the line after that?

Upvotes: 2

Views: 749

Answers (2)

Oo.oO
Oo.oO

Reputation: 13415

Well, the format and way of using Makefile here is quite strange. It's OK, but it could be done slightly different way.

Let's say you have file: mac-ns-2d.8.3.f90

program main
  use mpi

  integer error, id, p
  call MPI_Init ( error )
  call MPI_Comm_size ( MPI_COMM_WORLD, p, error )
  call MPI_Comm_rank ( MPI_COMM_WORLD, id, error )
  write (*,*) 'Hello: ', id, '/', p
  call MPI_Finalize ( error )
end

Then, you can slightly modify your Makefile to be more "elegant"

compiler  =  mpifort
#I am commenting out these two to make compilation go trhough
#inc       =  hypre/include
#libs      =  src/hypre/lib
opts      =  -O4

a.out: mac-ns-2d.8.3.f90
    $(compiler) $(opts) -I$(inc) -L$(libs) -lm -lstdc++ $< -o $@

clean:
    -rm a.out

And the, you can simply make the target and run the code

> make
mpifort -O4 -I -L -lm -lstdc++ mac-ns-2d.8.3.f90 -o a.out
> mpirun -np 2 ./a.out
 Hello:            0 /           2
 Hello:            1 /           2

I, personally, would have changed this line

a.out: mac-ns-2d.8.3.f90

To something more suitable, like

name_of_my_executable: mac-ns-2d.8.3.f90

Upvotes: 1

Kusalananda
Kusalananda

Reputation: 15633

This is a standard Unix Makefile, but it's using weird variable names.

The first few lines are all assignments:

compiler  =  mpifort
in8.3     =  mac-ns-2d.8.3.f90
out       =  a.out
inc       =  hypre/include
libs      =  src/hypre/lib
opts      =  -O4

These basically assign strings to variables. For example, later in the Makefile, one may use $(out) and get a.out substituted in. This is a common way of collecting all things that may need tweaking later such as what compiler to use, what compilation flags one uses and other things.

You asked specifically about opts. This variable's value is -O4 which is a compiler flag that enables "optimization level 4" (usually the highest optimization level, but check your compiler's manual).

The next two lines is a target and a rule for building the target:

8.3:
    $(compiler) $(opts) -I$(inc) $(in8.3) -o $(out) -L$(libs) -lHYPRE -lm -lstdc++

The second of these two lines should be indented with a single tab.

I'm not going to describe what a target is and what a rule for making a target is, other than saying that make will "make" the first target of the Makefile using the specified rule. Targets may have dependencies (other targets) that needs to be considered before running the rules for the top target. This is not the case here.

As you can see, the last line uses the variables previously defined to compile the program.

Running make will produce:

$ make
mpifort -O4 -Ihypre/include mac-ns-2d.8.3.f90 -o a.out -Lsrc/hypre/lib -lHYPRE -lm -lstdc++
mpifort: not found
*** Error 1 in /tmp/shell-ksh.l1TMWqET (Makefile:14 '8.3')

Since I don't have mpifort (the compiler) installed, I'm getting an error message, but you can also see the command that make tried to execute. This corresponds to the last line of this Makefile with all variables substituted by their values.

I'd recommend seeking out a tutorial on make and Makefiles.

Upvotes: 1

Related Questions