Optimizing Makefile for LHS Code in Fortran

  • Fortran
  • Thread starter swartzism
  • Start date
  • Tags
    Code Fortran
In summary, the conversation is about a person working on modernizing and optimizing a Latin Hypercube sampling code in Fortran. They are splitting up the code into different files and using a Makefile to compile it. They are wondering if there is a more efficient way to do this.
  • #1
swartzism
103
0
I've always made my own makefiles and it hasn't been an issue because it's usually a small number of subroutines. However, I am working on modernizing and optimizing a Latin Hypercube sampling code in Fortran which has close to 80 functions/subroutines that I am splitting up into different files and putting in a Makefile. This is pretty tedious and makes for a pretty long Makefile in the style that I've always used. My question is this: is there a slicker, prettier, better, etc. way to do this?

Code:
# Start of the makefile

# Defining variables
OBJ = lhs.o chkstr.o chkdim.o chkdat.o betaln.o betaic.o betafn.o beta.o banner.o chktri.o chkzro.o chlsky.o cmcrd.o corcal.o corout.o datout.o datsqz.o dmfsd.o dsinv.o errchk.o errget.o errprt.o erstgt.o erxset.o fdump.o findit.o finver.o finvnor.o histo.o hpsrt.o hstout.o hypgeo.o i1mach.o imtql2.o j4save.o matinv.o mix.o normal.o onechk.o outcrd.o outdat.o pmtrx.o posdef.o pythag.o r1mach.o ranker.o rdpar.o rierfc1.o s88fmt.o setdef.o sift.o sspev.o tqlrat.o trbak3.o tred3.o triang.o unifrm.o vif.o wrtcrd.o wrtpar.o xerabt.o xerctl.o xerprt.o xerror.o xerrwv.o xersav.o xgetua.o usrdst.o
FC = ifort
FCFLAGS = -O3

# Makefile
LHS: $(OBJ)
    $(FC) -o LHS $(FCFLAGS) $(OBJ)
lhs.o: lhs.F90
    $(FC) -c $(FCFLAGS) lhs.F90
chkstr.o: chkstr.F90
    $(FC) -c $(FCFLAGS) chkstr.F90
chkdim.o: chkdim.F90
    $(FC) -c $(FCFLAGS) chkdim.F90
chkdat.o: chkdat.F90
    $(FC) -c $(FCFLAGS) chkdat.F90
betaln.o: betaln.F90
    $(FC) -c $(FCFLAGS) betaln.F90
betaic.o: betaic.F90
    $(FC) -c $(FCFLAGS) betaic.F90
betafn.o: betafn.F90
    $(FC) -c $(FCFLAGS) betafn.F90
beta.o: beta.F90
    $(FC) -c $(FCFLAGS) beta.F90
banner.o: banner.F90
    $(FC) -c $(FCFLAGS) banner.F90
chktri.o: chktri.F90
    $(FC) -c $(FCFLAGS) chktri.F90
chkzro.o: chkzro.F90
    $(FC) -c $(FCFLAGS) chkzro.F90
chlsky.o: chlsky.F90
    $(FC) -c $(FCFLAGS) chlsky.F90
cmcrd.o: cmcrd.F90
    $(FC) -c $(FCFLAGS) cmcrd.F90
corcal.o: corcal.F90
    $(FC) -c $(FCFLAGS) corcal.F90
corout.o: corout.F90
    $(FC) -c $(FCFLAGS) corout.F90
datout.o: datout.F90
    $(FC) -c $(FCFLAGS) datout.F90
datsqz.o: datsqz.F90
    $(FC) -c $(FCFLAGS) datsqz.F90
dmfsd.o: dmfsd.F90
    $(FC) -c $(FCFLAGS) dmfsd.F90
dsinv.o: dsinv.F90
    $(FC) -c $(FCFLAGS) dsinv.F90
errchk.o: errchk.F90
    $(FC) -c $(FCFLAGS) errchk.F90
errget.o: errget.F90
    $(FC) -c $(FCFLAGS) errget.F90
errprt.o: errprt.F90
    $(FC) -c $(FCFLAGS) errprt.F90
erstgt.o: erstgt.F90
    $(FC) -c $(FCFLAGS) erstgt.F90
erxset.o: erxset.F90
    $(FC) -c $(FCFLAGS) erxset.F90
fdump.o: fdump.F90
    $(FC) -c $(FCFLAGS) fdump.F90
findit.o: findit.F90
    $(FC) -c $(FCFLAGS) findit.F90
finver.o: finver.F90
    $(FC) -c $(FCFLAGS) finver.F90
finvnor.o: finvnor.F90
    $(FC) -c $(FCFLAGS) finvnor.F90
histo.o: histo.F90
    $(FC) -c $(FCFLAGS) histo.F90
hpsrt.o: hpsrt.F90
    $(FC) -c $(FCFLAGS) hpsrt.F90
hstout.o: hstout.F90
    $(FC) -c $(FCFLAGS) hstout.F90
hypgeo.o: hypgeo.F90
    $(FC) -c $(FCFLAGS) hypgeo.F90
i1mach.o: i1mach.F90
    $(FC) -c $(FCFLAGS) i1mach.F90
imtql2.o: imtql2.F90
    $(FC) -c $(FCFLAGS) imtql2.F90
j4save.o: j4save.F90
    $(FC) -c $(FCFLAGS) j4save.F90
matinv.o: matinv.F90
    $(FC) -c $(FCFLAGS) matinv.F90
mix.o: mix.F90
    $(FC) -c $(FCFLAGS) mix.F90
normal.o: normal.F90
    $(FC) -c $(FCFLAGS) normal.F90
onechk.o: onechk.F90
    $(FC) -c $(FCFLAGS) onechk.F90
outcrd.o: outcrd.F90
    $(FC) -c $(FCFLAGS) outcrd.F90
outdat.o: outdat.F90
    $(FC) -c $(FCFLAGS) outdat.F90
pmtrx.o: pmtrx.F90
    $(FC) -c $(FCFLAGS) pmtrx.F90
posdef.o: posdef.F90
    $(FC) -c $(FCFLAGS) posdef.F90
pythag.o: pythag.F90
    $(FC) -c $(FCFLAGS) pythag.F90
r1mach.o: r1mach.F90
    $(FC) -c $(FCFLAGS) r1mach.F90
ranker.o: ranker.F90
    $(FC) -c $(FCFLAGS) ranker.F90
rdpar.o: rdpar.F90
    $(FC) -c $(FCFLAGS) rdpar.F90
rierfc1.o: rierfc1.F90
    $(FC) -c $(FCFLAGS) rierfc1.F90
s88fmt.o: s88fmt.F90
    $(FC) -c $(FCFLAGS) s88fmt.F90
setdef.o: setdef.F90
    $(FC) -c $(FCFLAGS) setdef.F90
sift.o: sift.F90
    $(FC) -c $(FCFLAGS) sift.F90
sspev.o: sspev.F90
    $(FC) -c $(FCFLAGS) sspev.F90
tqlrat.o: tqlrat.F90
    $(FC) -c $(FCFLAGS) tqlrat.F90
trbak3.o: trbak3.F90
    $(FC) -c $(FCFLAGS) trbak3.F90
tred3.o: tred3.F90
    $(FC) -c $(FCFLAGS) tred3.F90
triang.o: triang.F90
    $(FC) -c $(FCFLAGS) triang.F90
unifrm.o: unifrm.F90
    $(FC) -c $(FCFLAGS) unifrm.F90
vif.o: vif.F90
    $(FC) -c $(FCFLAGS) vif.F90
wrtcrd.o: wrtcrd.F90
    $(FC) -c $(FCFLAGS) wrtcrd.F90
wrtpar.o: wrtpar.F90
    $(FC) -c $(FCFLAGS) wrtpar.F90
xerabt.o: xerabt.F90
    $(FC) -c $(FCFLAGS) xerabt.F90
xerctl.o: xerctl.F90
    $(FC) -c $(FCFLAGS) xerctl.F90
xerprt.o: xerprt.F90
    $(FC) -c $(FCFLAGS) xerprt.F90
xerror.o: xerror.F90
    $(FC) -c $(FCFLAGS) xerror.F90
xerrwv.o: xerrwv.F90
    $(FC) -c $(FCFLAGS) xerrwv.F90
xersav.o: xersav.F90
    $(FC) -c $(FCFLAGS) xersav.F90
xgetua.o: xgetua.F90
    $(FC) -c $(FCFLAGS) xgetua.F90
usrdst.o: usrdst.F90
    $(FC) -c $(FCFLAGS) usrdst.F90
%.o: %.F90
    $(FC) -c $(FCFLAGS) $<

# Cleaning everything
clean:
    rm $(OBJ)

# End of the makefile
 
Technology news on Phys.org
  • #2
This on its own:
Code:
OBJ = lhs.o chkstr.o chkdim.o chkdat.o betaln.o betaic.o betafn.o beta.o \
      banner.o chktri.o chkzro.o chlsky.o cmcrd.o corcal.o corout.o \
      datout.o datsqz.o dmfsd.o dsinv.o errchk.o errget.o errprt.o erstgt.o \
      erxset.o fdump.o findit.o finver.o finvnor.o histo.o hpsrt.o hstout.o \
      hypgeo.o i1mach.o imtql2.o j4save.o matinv.o mix.o normal.o onechk.o \
      outcrd.o outdat.o pmtrx.o posdef.o pythag.o r1mach.o ranker.o rdpar.o \
      rierfc1.o s88fmt.o setdef.o sift.o sspev.o tqlrat.o trbak3.o tred3.o \
      triang.o unifrm.o vif.o wrtcrd.o wrtpar.o xerabt.o xerctl.o xerprt.o \
      xerror.o xerrwv.o xersav.o xgetua.o usrdst.o
FC = ifort
FCFLAGS = -O3

LHS: $(OBJ)
    $(FC) -o LHS $(FCFLAGS) $(OBJ)
%.o: %.F90
    $(FC) -c $(FCFLAGS) $<

.PHONY: clean
clean:
    rm $(OBJ)
doesn't work?
 
Last edited:
  • #3
Learn something new every day! This makes my life a lot simpler.
 
  • #4
wle said:
This on its own:
Code:
OBJ = lhs.o chkstr.o chkdim.o chkdat.o betaln.o betaic.o betafn.o beta.o \
      banner.o chktri.o chkzro.o chlsky.o cmcrd.o corcal.o corout.o \
      datout.o datsqz.o dmfsd.o dsinv.o errchk.o errget.o errprt.o erstgt.o \
      erxset.o fdump.o findit.o finver.o finvnor.o histo.o hpsrt.o hstout.o \
      hypgeo.o i1mach.o imtql2.o j4save.o matinv.o mix.o normal.o onechk.o \
      outcrd.o outdat.o pmtrx.o posdef.o pythag.o r1mach.o ranker.o rdpar.o \
      rierfc1.o s88fmt.o setdef.o sift.o sspev.o tqlrat.o trbak3.o tred3.o \
      triang.o unifrm.o vif.o wrtcrd.o wrtpar.o xerabt.o xerctl.o xerprt.o \
      xerror.o xerrwv.o xersav.o xgetua.o usrdst.o
FC = ifort
FCFLAGS = -O3

LHS: $(OBJ)
    $(FC) -o LHS $(FCFLAGS) $(OBJ)
%.o: %.F90
    $(FC) -c $(FCFLAGS) $<

.PHONY: clean
clean:
    rm $(OBJ)
doesn't work?

This can be written even more succinctly, assuming gnu make and assuming every .F90 file in the directory is to be compiled:
Code:
OBJ := $(patsubst %.F90,%.o,$(wildcard *.F90))
FC = ifort
FCFLAGS = -O3
# Remainder remains the same
 
  • #5
D H said:
This can be written even more succinctly, assuming gnu make and assuming every .F90 file in the directory is to be compiled:
Code:
OBJ := $(patsubst %.F90,%.o,$(wildcard *.F90))
FC = ifort
FCFLAGS = -O3
# Remainder remains the same

Very cool.
 

Related to Optimizing Makefile for LHS Code in Fortran

1. How can I improve the performance of my Fortran code through Makefile optimization?

Makefile optimization for Fortran code involves using compiler flags, such as -O and -fast, to enable compiler optimizations and improve code execution speed. Additionally, rearranging the order of source files in the Makefile can also help improve performance.

2. What are some common mistakes to avoid when optimizing a Makefile for Fortran code?

Some common mistakes to avoid when optimizing a Makefile for Fortran code include not using the -O flag to enable compiler optimizations, not properly specifying dependencies between source files, and not using parallel compilation to take advantage of multiple CPU cores.

3. What are the advantages of using a Makefile to optimize Fortran code?

A Makefile allows for the automation of the compilation process, making it easier to optimize and recompile code as needed. It also allows for parallel compilation, which can significantly improve performance on multi-core systems.

4. Are there any tools or techniques specifically designed for optimizing Makefiles for Fortran code?

Yes, there are tools such as "make" and "makefile2graph" that can help visualize the dependencies between source files and identify potential areas for optimization in a Makefile for Fortran code.

5. How can I ensure that my optimized Makefile for Fortran code is portable and can be used on different systems?

To ensure portability, it is important to use standard compiler flags and avoid system-specific optimizations in the Makefile. It is also recommended to test the Makefile on different systems and make any necessary adjustments to ensure compatibility.

Back
Top