fortran module name issue

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

fortran module name issue

Juan E. Sanchez
Hi,

It seems like cmake cannot handle the case where the module name is the
result of a macro.  I am using this approach to compile the same code
for different floating point precision.  Any advice appreciated.  This
approach would apply to hundreds of files.

The error is:
Error copying Fortran module "concat".  Tried "CONCAT.mod" and "concat.mod".
make[2]: *** [CMakeFiles/flib.dir/baz.o.provides.build] Error 1
make[1]: *** [CMakeFiles/flib.dir/all] Error 2
make: *** [all] Error 2


Regards,

Juan


baz.F:
#include "fmacros.inc"

       module CONCAT(baz)
       contains
       subroutine car(t3)
       end subroutine
       end module CONCAT(baz)

foo.F:
#include "fmacros.inc"

       module CONCAT(foo)
       contains
       subroutine bar(t1, t2)
       use CONCAT(baz)
       implicit none
       REAL(kind=8) t1
       REAL(kind=DWIDTH) t2
       call baz(t2)
       end subroutine
       end module CONCAT(foo)

fmacros.inc:

#define CONCAT(a) a/**/_double
#define DWIDTH 8

main.cc:
extern "C" {
void
}

CMakeLists.txt:

PROJECT(foo)
ENABLE_LANGUAGE(CXX Fortran)

ADD_LIBRARY(flib foo.F baz.F)



--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fortran module name issue

Burlen Loring
Hi Juan,

I have faced similar challenges when calling Fortran code from C++ templates.

In the solution I came up with, I use a marked up Fortran template code and Cmake's configure_file command to generate a module for each combination of C++ types I need. The markup uses a token for each template argument and a decorator that is appended to Fortran symbols and is used in the module and file names to differentiate all of the CMake generated instantiations.

here is the relevant Cmake code that does all the work, (note: I have two template arguments one for coordinates and variables):
set(teca_alg_f90_srcs)

set(teca_alg_f90_generics
    gfdl_spline
    gfdl_tc_candidates
    )

set(f_type real)
set(c_types float double)
foreach(generic_src ${teca_alg_f90_generics})
    foreach(c_type_var ${c_types})
        set(iso_c_type_var "${f_type}(c_${c_type_var})")
        string(SUBSTRING ${c_type_var} 0 1 var_name)
        foreach(c_type_coord ${c_types})
            string(SUBSTRING ${c_type_coord} 0 1 coord_name)
            set(decorator "c${coord_name}_v${var_name}")
            set(iso_c_type_coord "${f_type}(c_${c_type_coord})")
            configure_file(${generic_src}.f90.in ${generic_src}_${decorator}.f90 @ONLY)
            list(APPEND teca_alg_f90_srcs ${generic_src}_${decorator}.f90)
        endforeach()
    endforeach()
endforeach()

add_library(teca_alg ${teca_alg_cxx_srcs} ${teca_alg_f90_srcs})
And here is a link to an example marked up Fortran template code.
https://github.com/LBL-EESA/TECA/blob/master/alg/gfdl_tc_candidates.f90.in
From C++ I use macros to declare decorated Fortran functions and define C++ overloads that call them.
https://github.com/LBL-EESA/TECA/blob/master/alg/gfdl_tc_candidates.h
It's a bit of a heavy handed solution, but I think you can solve your problem in a similar way. I'm interested in hearing of other approaches that have worked.

Burlen


On 06/26/2017 01:40 PM, Juan E. Sanchez wrote:
Hi,

It seems like cmake cannot handle the case where the module name is the result of a macro.  I am using this approach to compile the same code for different floating point precision.  Any advice appreciated.  This approach would apply to hundreds of files.

The error is:
Error copying Fortran module "concat".  Tried "CONCAT.mod" and "concat.mod".
make[2]: *** [CMakeFiles/flib.dir/baz.o.provides.build] Error 1
make[1]: *** [CMakeFiles/flib.dir/all] Error 2
make: *** [all] Error 2


Regards,

Juan


baz.F:
#include "fmacros.inc"

      module CONCAT(baz)
      contains
      subroutine car(t3)
      end subroutine
      end module CONCAT(baz)

foo.F:
#include "fmacros.inc"

      module CONCAT(foo)
      contains
      subroutine bar(t1, t2)
      use CONCAT(baz)
      implicit none
      REAL(kind=8) t1
      REAL(kind=DWIDTH) t2
      call baz(t2)
      end subroutine
      end module CONCAT(foo)

fmacros.inc:

#define CONCAT(a) a/**/_double
#define DWIDTH 8

main.cc:
extern "C" {
void
}

CMakeLists.txt:

PROJECT(foo)
ENABLE_LANGUAGE(CXX Fortran)

ADD_LIBRARY(flib foo.F baz.F)





--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fortran module name issue

Juan E. Sanchez
Hi Burlen,

Thanks for your response, it inspired me to do something similar.

Starting with the non-processed files, I used the code below.  It also
seems to track the mod file dependencies correctly, but I need to
thoroughly test it.

Note that I had to use the cpp command with brew (on mac os x) to
concatenate the tokens without spaces.  The linux cpp at work should
also be able to handle the traditional-cpp required.

Regards,

Juan


PROJECT(foo)
ENABLE_LANGUAGE(CXX Fortran)

SET(TFILES foo baz)

SET(FFILES "")
FOREACH(I ${TFILES})
   SET(THISFILE ${I}_double.F)
ADD_CUSTOM_COMMAND (
   OUTPUT ${CMAKE_SOURCE_DIR}/${THISFILE}
   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
   COMMAND /usr/local/bin/cpp-7
   ARGS    -traditional-cpp -P ${I}.F > ${THISFILE}
   DEPENDS ${I}.F
)
LIST(APPEND FFILES ${THISFILE})
ENDFOREACH(I)

ADD_LIBRARY(flib ${FFILES})
SET_SOURCE_FILES_PROPERTIES(${FFILES} PROPERTIES GENERATED TRUE)
MESSAGE(INFO ${FFILES})


ADD_EXECUTABLE(main main.cc)
TARGET_LINK_LIBRARIES(main flib)


On 6/26/17 6:06 PM, Burlen Loring wrote:

> Hi Juan,
>
> I have faced similar challenges when calling Fortran code from C++
> templates.
>
> In the solution I came up with, I use a marked up Fortran template code
> and Cmake's configure_file command to generate a module for each
> combination of C++ types I need. The markup uses a token for each
> template argument and a decorator that is appended to Fortran symbols
> and is used in the module and file names to differentiate all of the
> CMake generated instantiations.
>
> here is the relevant Cmake code that does all the work, (note: I have
> two template arguments one for coordinates and variables):
>
>     set(teca_alg_f90_srcs)
>
>     set(teca_alg_f90_generics
>          gfdl_spline
>          gfdl_tc_candidates
>          )
>
>     set(f_type real)
>     set(c_types float double)
>     foreach(generic_src ${teca_alg_f90_generics})
>          foreach(c_type_var ${c_types})
>              set(iso_c_type_var "${f_type}(c_${c_type_var})")
>              string(SUBSTRING ${c_type_var} 0 1 var_name)
>              foreach(c_type_coord ${c_types})
>                  string(SUBSTRING ${c_type_coord} 0 1 coord_name)
>                  set(decorator "c${coord_name}_v${var_name}")
>                  set(iso_c_type_coord "${f_type}(c_${c_type_coord})")
>                  configure_file(${generic_src}.f90.in
>     ${generic_src}_${decorator}.f90 @ONLY)
>                  list(APPEND teca_alg_f90_srcs
>     ${generic_src}_${decorator}.f90)
>              endforeach()
>          endforeach()
>     endforeach()
>
>     add_library(teca_alg ${teca_alg_cxx_srcs} ${teca_alg_f90_srcs})
>
> And here is a link to an example marked up Fortran template code.
>
>     https://github.com/LBL-EESA/TECA/blob/master/alg/gfdl_tc_candidates.f90.in
>
>  From C++ I use macros to declare decorated Fortran functions and define
> C++ overloads that call them.
>
>     https://github.com/LBL-EESA/TECA/blob/master/alg/gfdl_tc_candidates.h
>
> It's a bit of a heavy handed solution, but I think you can solve your
> problem in a similar way. I'm interested in hearing of other approaches
> that have worked.
>
> Burlen
>
>
> On 06/26/2017 01:40 PM, Juan E. Sanchez wrote:
>> Hi,
>>
>> It seems like cmake cannot handle the case where the module name is
>> the result of a macro.  I am using this approach to compile the same
>> code for different floating point precision.  Any advice appreciated.  
>> This approach would apply to hundreds of files.
>>
>> The error is:
>> Error copying Fortran module "concat".  Tried "CONCAT.mod" and
>> "concat.mod".
>> make[2]: *** [CMakeFiles/flib.dir/baz.o.provides.build] Error 1
>> make[1]: *** [CMakeFiles/flib.dir/all] Error 2
>> make: *** [all] Error 2
>>
>>
>> Regards,
>>
>> Juan
>>
>>
>> baz.F:
>> #include "fmacros.inc"
>>
>>       module CONCAT(baz)
>>       contains
>>       subroutine car(t3)
>>       end subroutine
>>       end module CONCAT(baz)
>>
>> foo.F:
>> #include "fmacros.inc"
>>
>>       module CONCAT(foo)
>>       contains
>>       subroutine bar(t1, t2)
>>       use CONCAT(baz)
>>       implicit none
>>       REAL(kind=8) t1
>>       REAL(kind=DWIDTH) t2
>>       call baz(t2)
>>       end subroutine
>>       end module CONCAT(foo)
>>
>> fmacros.inc:
>>
>> #define CONCAT(a) a/**/_double
>> #define DWIDTH 8
>>
>> main.cc:
>> extern "C" {
>> void
>> }
>>
>> CMakeLists.txt:
>>
>> PROJECT(foo)
>> ENABLE_LANGUAGE(CXX Fortran)
>>
>> ADD_LIBRARY(flib foo.F baz.F)
>>
>>
>>
>

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: fortran module name issue

xavier lacoste
Hello,

You could also concatenate words with gfortran preprocessor using :

#define PASTE(a) a
#define CONCAT(a,b) PASTE(a)b

My two cents,

XL

Le 27 juin 2017 4:01 AM, "Juan E. Sanchez" <[hidden email]> a écrit :
Hi Burlen,

Thanks for your response, it inspired me to do something similar.

Starting with the non-processed files, I used the code below.  It also seems to track the mod file dependencies correctly, but I need to thoroughly test it.

Note that I had to use the cpp command with brew (on mac os x) to concatenate the tokens without spaces.  The linux cpp at work should also be able to handle the traditional-cpp required.

Regards,

Juan


PROJECT(foo)
ENABLE_LANGUAGE(CXX Fortran)

SET(TFILES foo baz)

SET(FFILES "")
FOREACH(I ${TFILES})
  SET(THISFILE ${I}_double.F)
ADD_CUSTOM_COMMAND (
  OUTPUT ${CMAKE_SOURCE_DIR}/${THISFILE}
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
  COMMAND /usr/local/bin/cpp-7
  ARGS    -traditional-cpp -P ${I}.F > ${THISFILE}
  DEPENDS ${I}.F
)
LIST(APPEND FFILES ${THISFILE})
ENDFOREACH(I)

ADD_LIBRARY(flib ${FFILES})
SET_SOURCE_FILES_PROPERTIES(${FFILES} PROPERTIES GENERATED TRUE)
MESSAGE(INFO ${FFILES})


ADD_EXECUTABLE(main main.cc)
TARGET_LINK_LIBRARIES(main flib)


On 6/26/17 6:06 PM, Burlen Loring wrote:
Hi Juan,

I have faced similar challenges when calling Fortran code from C++ templates.

In the solution I came up with, I use a marked up Fortran template code and Cmake's configure_file command to generate a module for each combination of C++ types I need. The markup uses a token for each template argument and a decorator that is appended to Fortran symbols and is used in the module and file names to differentiate all of the CMake generated instantiations.

here is the relevant Cmake code that does all the work, (note: I have two template arguments one for coordinates and variables):

    set(teca_alg_f90_srcs)

    set(teca_alg_f90_generics
         gfdl_spline
         gfdl_tc_candidates
         )

    set(f_type real)
    set(c_types float double)
    foreach(generic_src ${teca_alg_f90_generics})
         foreach(c_type_var ${c_types})
             set(iso_c_type_var "${f_type}(c_${c_type_var})")
             string(SUBSTRING ${c_type_var} 0 1 var_name)
             foreach(c_type_coord ${c_types})
                 string(SUBSTRING ${c_type_coord} 0 1 coord_name)
                 set(decorator "c${coord_name}_v${var_name}")
                 set(iso_c_type_coord "${f_type}(c_${c_type_coord})")
                 configure_file(${generic_src}.f90.in
    ${generic_src}_${decorator}.f90 @ONLY)
                 list(APPEND teca_alg_f90_srcs
    ${generic_src}_${decorator}.f90)
             endforeach()
         endforeach()
    endforeach()

    add_library(teca_alg ${teca_alg_cxx_srcs} ${teca_alg_f90_srcs})

And here is a link to an example marked up Fortran template code.

    https://github.com/LBL-EESA/TECA/blob/master/alg/gfdl_tc_candidates.f90.in

 From C++ I use macros to declare decorated Fortran functions and define C++ overloads that call them.

    https://github.com/LBL-EESA/TECA/blob/master/alg/gfdl_tc_candidates.h

It's a bit of a heavy handed solution, but I think you can solve your problem in a similar way. I'm interested in hearing of other approaches that have worked.

Burlen


On 06/26/2017 01:40 PM, Juan E. Sanchez wrote:
Hi,

It seems like cmake cannot handle the case where the module name is the result of a macro.  I am using this approach to compile the same code for different floating point precision.  Any advice appreciated.  This approach would apply to hundreds of files.

The error is:
Error copying Fortran module "concat".  Tried "CONCAT.mod" and "concat.mod".
make[2]: *** [CMakeFiles/flib.dir/baz.o.provides.build] Error 1
make[1]: *** [CMakeFiles/flib.dir/all] Error 2
make: *** [all] Error 2


Regards,

Juan


baz.F:
#include "fmacros.inc"

      module CONCAT(baz)
      contains
      subroutine car(t3)
      end subroutine
      end module CONCAT(baz)

foo.F:
#include "fmacros.inc"

      module CONCAT(foo)
      contains
      subroutine bar(t1, t2)
      use CONCAT(baz)
      implicit none
      REAL(kind=8) t1
      REAL(kind=DWIDTH) t2
      call baz(t2)
      end subroutine
      end module CONCAT(foo)

fmacros.inc:

#define CONCAT(a) a/**/_double
#define DWIDTH 8

main.cc:
extern "C" {
void
}

CMakeLists.txt:

PROJECT(foo)
ENABLE_LANGUAGE(CXX Fortran)

ADD_LIBRARY(flib foo.F baz.F)





--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Loading...