Include new fortran90 module into existing huge fortran90 model

120 Views Asked by At

I am a beginner of fortran90. What I want to do is to call a new module (also fortran90) from an existing huge model which was written by fortran90. What I knew is that running fortran scripts highly depends on the compilation by gfortran using make or cmake. And make&cmake will compile the Makefile&CMakefile. I checked that, this huge model uses commands make with a large Makefile. The new module I wanted to use contains several .f90 files. So it's impossible to just simply write this module into one existing .f90 file of the model...And one thing is that, I just want to use this new module in ONE subroutine in the existing fortran90 model.

For the new module, it's downloaded from GitHub and the compilation was done by cmake. Firstly I need to run a bash file !sh build_steps.sh (the ! is used for running bash commands in python terminal). And the !sh build_steps.sh simply follows:

rm -rf build
mkdir build
cd build

FC=gfortran cmake .. -DSERIAL=1
# FC='mpif90 -qopenmp' cmake .. -DSERIAL=1

make

cd CMakeFiles/neural.dir/

mv mod_activation.mod.stamp mod_activation.o
mv mod_io.mod.stamp mod_io.o
mv mod_kinds.mod.stamp mod_kinds.o
mv mod_layer.mod.stamp mod_layer.o
mv mod_mnist.mod.stamp mod_mnist.o
mv mod_network.mod.stamp mod_network.o
mv mod_parallel.mod.stamp mod_parallel.o
mv mod_random.mod.stamp mod_random.o
mv mod_ensemble.mod.stamp mod_ensemble.o
mv mod_dense_layer.mod.stamp mod_dense_layer.o
mv mod_batchnorm_layer.mod.stamp mod_batchnorm_layer.o
mv mod_dropout_layer.mod.stamp mod_dropout_layer.o

Then the CMakelists.txt follows:

# cmake version, project name, language
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(neural-fortran Fortran)

# set output paths for modules, archives, and executables
set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/include)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# if build type not specified, default to release
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "release")
endif()

# handle integer size
if(INT)
  message(STATUS "Configuring build for ${INT}-bit integers")
  add_definitions(-DINT${INT})
else()
  message(STATUS "Configuring build for 32-bit integers")
  add_definitions(-DINT32)
endif()

# handle real size
if(REAL)
  message(STATUS "Configuring build for ${REAL}-bit reals")
  add_definitions(-DREAL${REAL})
else()
  message(STATUS "Configuring build for 32-bit reals")
  add_definitions(-DREAL32)
endif()

if(SERIAL)
  message(STATUS "Configuring build for serial execution")
else()
  message(STATUS "Configuring build for parallel execution")
  add_definitions(-DCAF)
endif()

# compiler flags for gfortran
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)

  if(SERIAL)
    message(STATUS "Configuring to build with -fcoarray=single")
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fcoarray=single")
  endif()

  if(BLAS)
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fexternal-blas ${BLAS}")
    set(LIBS "${LIBS} blas")
    message(STATUS "Configuring build to use BLAS from ${BLAS}")
  endif()

  set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp -fopenmp")
  set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -C -fbacktrace")
  set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -ffast-math")
endif()

# compiler flags for ifort
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)

  set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp -assume byterecl,realloc_lhs -heap-arrays -qopenmp")
  set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -C -traceback")
  set(CMAKE_Fortran_FLAGS_RELEASE "-O3")

  if(NOT SERIAL)
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -coarray=shared")
  endif()

endif()

# compiler flags for Cray ftn
if(CMAKE_Fortran_COMPILER_ID MATCHES Cray)
  set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -h noomp")
  set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g")
  set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
endif()

# library to archive (libneural.a)
add_library(neural src/lib/mod_activation.F90 src/lib/mod_io.F90 src/lib/mod_kinds.F90 src/lib/mod_layer.F90 src/lib/mod_dense_layer.F90 src/lib/mod_dropout_layer.F90 src/lib/mod_batchnorm_layer.F90 src/lib/mod_mnist.F90 src/lib/mod_network.F90 src/lib/mod_ensemble.F90 src/lib/mod_parallel.F90 src/lib/mod_random.F90)

# Remove leading or trailing whitespace
string(REGEX REPLACE "^ | $" "" LIBS "${LIBS}")

# tests
enable_testing()
#  mnist network_save network_sync set_activation_function
foreach(execid keras bulk ensembles training save_and_load keras_mymodel)
  add_executable(test_${execid} src/tests/test_${execid}.F90)
  target_link_libraries(test_${execid} neural ${LIBS})
  add_test(test_${execid} bin/test_${execid})
endforeach()

# foreach(execid mnist save_and_load simple sine)
#   add_executable(example_${execid} src/tests/example_${execid}.F90)
#   target_link_libraries(example_${execid} neural ${LIBS})
#   add_test(example_${execid} bin/example_${execid})
# endforeach()

The Makefile is too long, so I keep it in a google doc https://docs.google.com/document/d/10naj1WgE9P4qbILT3n85TosZCd1KISwSzGw2u5FIOwo/edit?usp=sharing. (this model is open-source...)

I knew something about bash, but nothing about Make and Cmake. So I just want to know, is there a simple way to combine this two makefiles? how can I declare the subroutine dependency in the existing makefile? or just simply import the new module in the existing fortran 90 subroutine like import numpy in python. Or do I need to change the dependency one by one?

Thanks a lot!

0

There are 0 best solutions below