带有英特尔Fortran编译器的f2py [英] f2py with Intel Fortran compiler

查看:232
本文介绍了带有英特尔Fortran编译器的f2py的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在Win7平台上。



我使用最新的Anaconda 64(1.7)作为Python + NumPy堆栈。

我的Fortran编译器是最新的英特尔Fortran编译器64(版本14.0。 0.103 Build 20130728)。

执行 f2py -c -m PyModule FortranModule.f90 --fcompiler = intelvem时遇到了很多问题



最后一个我似乎无法理解的是它看起来像f2py / distutils传递给编译器不符合ifort的期望。



当ifort被调用时,我会得到一系列关于未知选项的警告消息。

  ifort:命令行警告#10006:忽略未知选项'/ LC:\Anconda\libs'
ifort:命令行警告#10006:忽略未知选项'/ LC:\Anconda\PCbuild\amd64'
ifort:命令行警告#10006:忽略未知选项'/ lpython27'

我怀疑这与我在链接器结束时得到的错误有关。

 错误LNK2019:无法解析的外部符号__imp_PyImport_ImportModule在函数中引用_import_array 
错误LNK2019 ...等等(有大约30-40条线,不同的python模块缺失)

并以普通的
结束

 致命错误LNK1120:42无法解析的外部消息

我的猜测这是因为选项序列中缺少/ link标志。因此,/ l / L选项不会传递给链接器,编译器认为这些是发给他的。



由f2py生成的ifort命令如下所示:

  ifort.exe -dll -dll Pymodule.o fortranobject.o FortranModule.o module-f2pywrappers2.o -LC:\\ \\Anaconda\libs -LC:\Anconda\PCbuild\amd64 -lPython27 

我有不知道为什么-dll重复两次(我不得不从原始的共享中更改该标志)。



现在,我试图查看f2py和distutils代码,但还没有想出如何在命令输出中减少额外/链接。我甚至无法找到产生这个输出的地方。



如果有人在过去遇到过这个问题和/或可能有一些建议,我会很非常感谢。



感谢您的时间

解决方案

I前段时间我遇到了类似的问题。如果我正确地理解了这些评论,那么您已经使用了适用于我的方法,所以这仅仅是对所有与f2py和依赖关系相关的人的澄清和总结:

f2py在解决外部源文件依赖问题时似乎有问题。如果外部依赖作为已编译目标文件传递给f2py,链接工作正常,并且python库的构建没有问题。



因此,最简单的解决方案似乎是:
$ b


  1. 使用您的首选编译器和编译器设置将所有依赖项编译为目标文件(* .o)
  2. 将所有目标文件连同主子程序/ function / module / ...的源文件一起传递给f2py
  3. 按预期使用生成的Python库

一个简单的python skript可能看起来像这样(pycompile.py):

< pre $ #!python.exe
# - * - coding:UTF-8 - * -
import os
导入平台
'' '使用f2py编译需要的库'''
#编译命令字符串
#编译命令* .o和* .mod文件
fortran_exe =gfortran
#fortran编译器设置
fortran_flags =< some_gfortran_flags>
#添加源代码的路径
fortran_source =(./relative/path/to/source_1.f90
C:/absolut/path/to/source_2.f90
.. 。)
#汇编fortran命令
fortran_cmd = fortran_exe + fortran_flags + fortran_source

#使用f2py编译主源文件的命令
f2py_exe =f2py -c
#Linux / Windows的特殊编译器选项
if(platform.system()=='Linux'):
f2py_flags =--compiler = unix --fcompiler = gnu95
elif(platform.system()=='Windows'):
f2py_flags =--compiler = mingw32 --fcompiler = gnu95
#为源代码/依赖关系添加路径
f2py_source =(-m for_to_py_lib
./path/to/main_source.f90
source_1.o
source_2.o
...

#assemble f2py command
f2py_cmd = f2py_exe + f2py_flags + f2py_source

#compile .o和.m od文件
打印编译目标文件和模块文件...
print
print fortran_cmd
os.system(fortran_cmd)
#compile main_source.f90 with f2py
print=========================================== =====================
printstart f2py ...
print
print f2py_cmd
os .system(f2py_cmd)






更灵活的解决方案大型项目可以通过Makefile提供,详见 @bdforbes 中的评论(

 

############################################ ###################################
#一般项目属性
### ################################################## ###########################
#设置项目名称
项目(for_to_py_lib)
#设置版本Numbe
set(for_to_py_lib_VERSION_MAJOR 1)
set(for_to_py_lib_VERSION_MINOR 0)
#保存文件夹位置供以后使用/编写脚本(请参阅pycompile.py)
#相对于SOURCE文件夹
set(source_root $ {CMAKE_CURRENT_LIST_DIR} / SOURCE)#保存顶级源代码目录以备后用
set(lib_root $ {CMAKE_CURRENT_LIST_DIR} / LIBRARIES)#保存顶级lib目录以备后用
#相对于BUILD文件夹
set(build_root $ {CMAKE_CURRENT_BINARY_DIR})#保存顶级构建目录供以后使用

###
### Fortran到Python库
# ##
find_package(PythonInterp)
if(PYTHONINTERP_FOUND)
#复制python编译skript文件来构建文件夹并替换CMake变量
configure_file($ {source_root} /pycompile.py $ {build_root} /pycompile.py @ONLY)
#define for_to_py库结尾
if(UNIX)
set(CMAKE_PYTHON_LIBRARY_SUFFIX .so)
elseif(WIN32)
set (CMAKE_PYTHON_LIBRARY_SUFFIX .pyd)
endif ()
#将自定义目标添加到ALL,构建for_to_py python库(使用f2py)
add_custom_target(for_to_py ALL
DEPENDS $ {build_root} / for_to_py $ {CMAKE_PYTHON_LIBRARY_SUFFIX})
#build命令用于python库(执行包含实际生成命令的python脚本pycompile.py)
add_custom_command(OUTPUT $ {build_root} / for_to_py $ {CMAKE_PYTHON_LIBRARY_SUFFIX}
COMMAND $ {PYTHON_EXECUTABLE} $ {build_root} / pycompile.py
WORKING_DIRECTORY $ {build_root}
DEPENDS $ {build_root} /pycompile.py
$ {source_root} /path/to/source_1.f90
$ {source_root} / path / to / source_2.f90
$ {source_root} /INOUT/s4binout.f90
COMMENT生成fortran到python库)
#python库的生成后命令(复制生成的fil es)
add_custom_command(TARGET for_to_py
POST_BUILD
COMMAND $ {CMAKE_COMMAND} -E copy_if_different
$ {build_root} / s4_to_py $ {CMAKE_PYTHON_LIBRARY_SUFFIX}
$ {lib_root} / for_to_py $ {CMAKE_PYTHON_LIBRARY_SUFFIX}
评论\
********************************* ************************************************** **************** \\\
\
放置在$ {lib_root} / for_to_py $ {CMAKE_PYTHON_LIBRARY_SUFFIX}中的python库for_to_py $ {CMAKE_PYTHON_LIBRARY_SUFFIX}副本\ n \\ \\
********************************************* ************************************************** ****

endif(PYTHONINTERP_FOUND)

修改过的pycompile :

$ $ p $ #!python.exe
# - * - 编码:UTF-8 - * -
...
fortran_source =(@ source_root @ / source_1.f 90
@ source_root @ / source_2.f90
...)
...
#向源代码/依赖添加路径
f2py_source = (-m for_to_py_lib
@ build_root @ / for_to_py.f90
source_1.o
source_2.o
...

...

#编译.o和.mod文件
...


I am trying to use f2py to interface my python programs with my Fortran modules.

I am on a Win7 platform.

I use latest Anaconda 64 (1.7) as a Python+NumPy stack.

My Fortran compiler is the latest Intel Fortran compiler 64 (version 14.0.0.103 Build 20130728).

I have been experiencing a number of issues when executing f2py -c -m PyModule FortranModule.f90 --fcompiler=intelvem

The last one, which I can't seem to sort out is that it looks like the sequence of flags f2py/distutils passes to the compiler does not match what ifort expects.

I get a series of warning messages regarding unknown options when ifort is invoked.

ifort: command line warning #10006: ignoring unknown option '/LC:\Anaconda\libs'
ifort: command line warning #10006: ignoring unknown option'/LC:\Anaconda\PCbuild\amd64'
ifort: command line warning #10006: ignoring unknown option '/lpython27'

I suspect this is related to the errors I get from the linker at the end

error LNK2019: unresolved external symbol __imp_PyImport_ImportModule referenced in function _import_array
error LNK2019... and so forth (there are about 30-40 lines like that, with different python modules missing)

and it concludes with a plain

fatal error LNK1120: 42 unresolved externals

My guess is that this is because the /link flag is missing in the sequence of options. Because of this, the /l /L options are not passed to the linker and the compiler believes these are addressed to him.

The ifort command generated by f2py looks like this:

ifort.exe -dll -dll Pymodule.o fortranobject.o FortranModule.o module-f2pywrappers2.o -LC:\Anaconda\libs -LC:\Anaconda\PCbuild\amd64 -lPython27

I have no idea why the "-dll" is repeated twice (I had to change that flag from an original "-shared").

Now, I have tried to look into the f2py and distutils codes but haven't figured out how to bodge an additional /link in the command output. I haven't even been able to locate where this output is generated.

If anyone has encountered this problem in the past and/or may have some suggestions, I would very much appreciate it.

Thank you for your time

解决方案

I encountered similar problems with my own code some time ago. If I understand the comments correctly you already used the approach that worked for me, so this is just meant as clarification and summary for all those that struggle with f2py and dependencies:

f2py seems to have problems resolving dependecies on external source files. If the external dependencies get passed to f2py as already compiled object files though, the linking works fine and the python library gets build without problems.

The easiest solution therefore seems to be:

  1. compile all dependencies to object files (*.o) using your prefered compiler and compiler settings
  2. pass all object files to f2py, together with the source file of your main subroutine/ function/ module/ ...
  3. use generated python library as expected

A simple python skript could look like this (pycompile.py):

#!python.exe
# -*- coding: UTF-8 -*-
import os
import platform
'''Uses f2py to compile needed library'''
# build command-strings
# command for compling *.o and *.mod files
fortran_exe = "gfortran "
# fortran compiler settings
fortran_flags = "<some_gfortran_flags> "
# add path to source code
fortran_source = ("./relative/path/to/source_1.f90 "
                  "C:/absolut/path/to/source_2.f90 "                 
                  "...")
# assemble fortran command
fortran_cmd = fortran_exe + fortran_flags + fortran_source

# command for compiling main source file using f2py
f2py_exe = "f2py -c "
# special compiler-options for Linux/ Windows
if (platform.system() == 'Linux'):
    f2py_flags = "--compiler=unix --fcompiler=gnu95 "
elif (platform.system() == 'Windows'):
    f2py_flags = "--compiler=mingw32 --fcompiler=gnu95 "
# add path to source code/ dependencies
f2py_source = ("-m for_to_py_lib "
               "./path/to/main_source.f90 "
               "source_1.o "
               "source_2.o "
               "... "
               )
# assemble f2py command
f2py_cmd = f2py_exe + f2py_flags + f2py_source

# compile .o and .mod files
print "compiling object- and module-files..."
print
print fortran_cmd
os.system(fortran_cmd)
# compile main_source.f90 with f2py
print "================================================================"
print "start f2py..."
print
print f2py_cmd
os.system(f2py_cmd)


A more flexible solution for large projects could be provided via Makefile, as dicussed by @bdforbes in the comments (for reference) or a custom CMake User Command in combination with the above skript:

###############################################################################
# General project properties
################################################################################
# Set Project Name
project (for_to_py_lib)
# Set Version Number
set (for_to_py_lib_VERSION_MAJOR 1)
set (for_to_py_lib_VERSION_MINOR 0)
# save folder locations for later use/ scripting (see pycompile.py)
# relative to SOURCE folder
set(source_root ${CMAKE_CURRENT_LIST_DIR}/SOURCE) # save top level source dir for later use
set(lib_root ${CMAKE_CURRENT_LIST_DIR}/LIBRARIES) # save top level lib dir for later use
# relative to BUILD folder
set(build_root ${CMAKE_CURRENT_BINARY_DIR}) # save top level build dir for later use

###
### Fortran to Python library
###
find_package(PythonInterp)
if (PYTHONINTERP_FOUND)
    # copy python compile skript file to build folder and substitute CMake variables
    configure_file(${source_root}/pycompile.py ${build_root}/pycompile.py @ONLY)
    # define for_to_py library ending
    if (UNIX)
        set(CMAKE_PYTHON_LIBRARY_SUFFIX .so)
    elseif (WIN32)
        set(CMAKE_PYTHON_LIBRARY_SUFFIX .pyd)
    endif()
    # add custom target to ALL, building the for_to_py python library (using f2py)
    add_custom_target(for_to_py ALL
                      DEPENDS ${build_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX})
    # build command for python library (execute python script pycompile.py containing the actual build commands)
    add_custom_command(OUTPUT ${build_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX}
                       COMMAND ${PYTHON_EXECUTABLE} ${build_root}/pycompile.py
                       WORKING_DIRECTORY ${build_root}
                       DEPENDS ${build_root}/pycompile.py
                               ${source_root}/path/to/source_1.f90
                               ${source_root}/path/to/source_2.f90
                               ${source_root}/INOUT/s4binout.f90
                       COMMENT "Generating fortran to python library")
    # post build command for python library (copying of generated files)
    add_custom_command(TARGET for_to_py
                       POST_BUILD
                       COMMAND ${CMAKE_COMMAND} -E copy_if_different 
                               ${build_root}/s4_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX}
                               ${lib_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX}
                       COMMENT "\
***************************************************************************************************\n\
 copy of python library for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX} placed in ${lib_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX} \n\
***************************************************************************************************"
                       )
endif (PYTHONINTERP_FOUND)

with modified pycompile:

#!python.exe
# -*- coding: UTF-8 -*-
...
fortran_source = ("@source_root@/source_1.f90 "
                  "@source_root@/source_2.f90 "                 
                  "...")
...
# add path to source code/ dependencies
f2py_source = ("-m for_to_py_lib "
               "@build_root@/for_to_py.f90 "
               "source_1.o "
               "source_2.o "
               "... "
               )
...

# compile .o and .mod files
...

这篇关于带有英特尔Fortran编译器的f2py的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆