我应该用这个庞大的Fortran 77程序进行研究(我最近将它移植到Fortran 90表面).它是一个非常古老的软件,用于使用有限元方法进行建模.
>这是一个怪物.它大约有240,000行.
>自从它开始在Fortran 77中使用它以来,它使用了一些非常脏的黑客进行动态内存分配;基本上它使用C标准库中的函数,使用C和Fortran进行混合编程.我还没有完全掌握分配的工作原理.该程序可以由用户轻松扩展,用户通常需要分配一些全局可访问的数组供以后使用.这是通过具有一组内存地址来完成的,这些内存地址指向动态可分配数组的起始地址.当然,在开始真正编程之前,地址数组的哪个元素指向哪些信息都取决于用户必须学习的约定.有两个地址数组,一个用于整数,另一个用于浮点.
>肮脏的黑客,我的意思是不一致的.例如,GNU编译器的优化算法中的更新导致程序以随机内存泄漏退出.
>该计划远非优雅.全局变量名称通常较短(3-4个字符)且含糊不清.当然,通过使用包括所有程序开关和前述阵列的公共块来实现跨例程传递数据.
>该程序的使用大致类似于交互式shell,尽管是一个愚蠢的程序.首先,程序本身读取输入文件,然后根据选择,将用户放入伪shell中,用户必须键入4个字符宽的命令,然后输入参数.然后解析器解析命令,并使用参数调用相应的子例程.你会猜到这个伪解析器中存在一个循环结构(相反的是goto bonanza),它以比21世纪更复杂的方式包装子程序行为.
>输入文件的格式相同(命令,然后参数),因为它是相同的解析器.但是语法并不是真的一致(我的意思是它缺乏控制结构,有些命令会导致有限状态机做与其他命令相矛盾的行为;它缺乏明确的语法),不时导致最终用户发现陷阱.用户必须通过经验了解这些陷阱;我没有在程序的任何文档中看到它们.这是一个可以使用python轻松避免的问题,甚至不需要实现解析器.
我想做的事:
>将程序的端口部分导入python,即与数值计算无关的部分.这包括
>在python中使用OOP方法清理和抽象API,
>提供有意义的变量名称,
>将动态分配迁移到numpy或Fortran 90并丢失C部分,
>将非数字执行迁移到python,并使用f2py包装数字对象,因此性能没有任何损失.我是否告诉过该程序目前处于快速状态?希望将对数字子程序和I / O的调用移植到python不会减慢到不切实际的水平(或者它会吗?).
>利用python的交互式shell作为伪shell的替代品.这样,最终用户就不会有任何不一致之处.上述命令将简单地由python中定义的函数替换.这将允许用户实际访问数据.此外,用户将能够扩展程序而无需深入.
我想知道:
> f2py是否适用于包装大量子程序和公共块而没有任何混淆的任务?我只在网上看到了f2py的单文件示例;我知道numpy已经用它来包装LAPACK和东西,但我需要保证f2py是一个足以完成这项任务的工具.
>对于我应该遵循的一般策略是否有任何建议,或者我应该避免的陷阱.
>怎么能&我应该在这个python包装的Fortran 90环境中实现一个系统,这样我就可以在fortran例程中修改(分配和分配)全局可访问的数组和变量.这应该优选地省略地址数组,并且我应该优选地能够将口头表示注入命名空间.这些变量最好在python和fortran中都可以访问.
笔记:
>我可能一直在要求太多,超出了可能范围的界限.在这种情况下,请原谅我,因为我是这方面编程的初学者;并且毫不犹豫地纠正我.
>我一直在谈论的“程序”是开源的,但它是商业的,许可证不允许其分发,所以我决定不提它的名字.但是,您可以从第二句和我给出的描述中推断出它.
我建议不要试图重写大部分程序,无论是在python还是其他任何东西.这是耗时,令人不愉快的,而且在很大程度上是不必要的.作为替代方案,获取F77代码库,以确定它是否足够干净,您是否愿意信任它,然后编写接口例程.
我现在有一个庞大,丑陋的F77代码库,它位于一个接口后面.该程序需要输入作为文本文件,因此接口的大部分工作是生成该文本文件.除此之外,遗留代码被简化为单个网关例程,该例程采用一些参数(包括识别文本文件的方法)并返回答案.如果您使用Fortran 2003的iso_c_binding,您可以以C理解的格式公开接口,此时您可以将其链接到您想要的任何内容.
就现代代码(主要是优化例程)而言,遗留代码库是C接口背后的单个子例程.这比尝试进一步修改旧代码要好得多,也可能是针对您的案例的有效策略.