如何在GNU Octave中运行Fortran程序? [英] How to run a Fortran program within GNU Octave?

查看:94
本文介绍了如何在GNU Octave中运行Fortran程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Octave中运行一个Fortran程序.我想这样做是出于自动化的目的,并使用Octave进行所有数据处理.

I want to run a Fortran program within Octave. I would like to do this for automation purposes and use Octave for all the data processing.

是否可以使用cygwin从八度运行一个Fortran程序,如果可以的话,您能提供沿该方向的一些指针吗?

Is it possible to run a Fortran program from octave using cygwin, if so, could you provide me some pointers along that direction?

此外,我的系统中安装了一个gfortran编译器,有没有办法利用它来完成上述任务?

Moreover, I have a gfortran compiler installed in my system, Is there a way I could make use of it to complete my task mentioned above?

此外,我尝试使用mex执行相同的操作:

Furthermore, I tried to use mex to perform the same:

mckoctfile --mex HelloWorld.f

尝试混合方法后出现以下错误:

I got the following error after trying the mex approach:

c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\rajan\AppData\Local\Temp/oct-qur1RF.o: in function `hi': C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_st_write'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_transfer_character_write'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_st_write_done'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\rajan\AppData\Local\Temp/oct-qur1RF.o: in function `main':C:\Tech Stuff\Fortran Programs/HelloWorld.f:6: undefined reference to `_gfortran_set_args'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:6: undefined reference to `_gfortran_set_options'
collect2.exe: error: ld returned 1 exit status
warning: mkoctfile: building exited with failure sta

如何解决此错误以继续前进?

How do I resolve this error to move forward?

推荐答案

很明显,您的特定用例可能比这要复杂得多,但这是一个简单的示例,可以帮助您入门(或帮助您确定是否值得)完全沿着那条路线走...)

Obviously your particular use-case may be a lot more complex than this, but here's a simple example to get you started (or to help you decide whether it's worth going down that route at all...)

让我们从一个简单的octfile开始,该文件执行简单的整数加法,现在不涉及fortran.

Let's start with a simple octfile which performs simple integer addition, no fortran involved for now.

// in: simple_addition.cpp 
#include <octave/oct.h>

DEFUN_DLD (simple_addition, args, ,"Add two integers via C++")
{
  octave_value retval = args(0).int_value() + args(1).int_value();
  return retval;
}

编译:

mkoctfile -c simple_addition.cpp                 # compiles a simple_addition.o file
mkoctfile -o simple_addition simple_addition.o   # links .o file to named output file

八度:

octave:1> simple_addition(1,2)
ans =  3

现在让我们搁置一分钟,看看如何从纯c ++调用fortran定义的函数.首先让我们创建一个简单的整数加法函数:

Now let's put this aside for a minute, and see how we might call a fortran-defined function from pure c++. First let's create a simple integer addition function:

 ! in fortran_addition.f90 
 function fortran_addition(a,b) result(Out)
    integer, intent(in) :: a,b ! input
    integer             :: Out ! output
    Out = a + b
 end function fortran_addition

并使用gfortran进行编译:

and compile it using gfortran:

gfortran -c fortran_addition.f90    # creates fortran_addition.o

您可以看到(例如,使用 nm fortran_addition.o )生成的对象包含对名称为 fortran_addition _ 的符号的引用(请注意在末尾添加了下划线)).

You can see (e.g. using nm fortran_addition.o) that the generated object contains a reference to a symbol under the name fortran_addition_ (note the added underscore at the end).

现在让我们创建一个普通的(即与八度无关的)c ++包装程序,该程序将调用通过此符号定义的函数:

Now let's create a normal (i.e. non-octave-related) c++ wrapper program which calls the function defined via this symbol:

// in generic_fortran_addition_wrapper.cpp
#include <iostream>
extern "C" { int fortran_addition_( int *, int * ); }
int main() {
    int a = 1, b = 2, fortran_result;
    fortran_result = fortran_addition_( &a, &b );
    std::cout << a << " + " << b << " = " << fortran_result << std::endl;
}

编译:

g++ -c generic_fortran_addition_wrapper.cpp
g++ -o addints generic_fortran_addition_wrapper.o fortran_addition.o
./addints   # outputs `1 + 2 = 3` on the terminal

现在,我们已经具备了创建包含fortran函数的octfile的所有要素:

Now we have all the ingredients to create an octfile that wraps a fortran function:

// in fortran_addition_wrapper.cpp
#include <octave/oct.h>
extern "C" { int fortran_addition_( int *, int *); }
DEFUN_DLD (fortran_addition_wrapper, args, ,"Add two integers via fortran")
{
  int a, b, fortran_result;
  a = args(0).int_value();
  b = args(1).int_value();
  fortran_result = fortran_addition_( &a, &b );
  octave_value retval(fortran_result);
  return retval;
}

使用mkoctfile编译:

compile with mkoctfile:

mkoctfile -c fortran_addition_wrapper.cpp
mkoctfile -o fortran_addition_wrapper fortran_addition_wrapper.o fortran_addition.o

然后八度:

octave:1> fortran_addition_wrapper(1,2)
ans =  3


说了这么多,显然,如果您有一个完全定义的fortran程序,而不仅仅是可链接的函数,并且您的系统上有一个正在运行的已编译可执行文件,那么您可以跳过上述所有形式"并仅调用您的可执行文件通过八度的 system()命令.显然,在这种情况下,您需要以与八度无关的方式传递数据……但是,如果您有一个独立的fortran可执行文件,那么大概已经可以从操作系统中读取输入数据了.


Having said all this, obviously if you have a fully defined fortran program, rather than just linkable functions, and you have a running compiled executable on your system, then you can skip all the above 'formalities' and just call your executable via the system() command from octave. Obviously in this scenario it's up to you to pass the data in an octave-agnostic way ... but presumably if you have a standalone fortran executable, then presumably it already has a way of reading input data from the operating system.

EDIT (根据以下评论),我被提醒我被跟踪并回答了对原始问题的评论中提出的问题,却忘了解决错误消息在原始问题中.如我的评论中所述,mkoctave是gnu编译器集合的通用包装.这些消息听起来并不是特定于八度的,而是编译器/链接器抱怨您缺少定义这些基本功能的fortran运行时库.

EDIT as per the comments below, I've been reminded that I got side-tracked and answered the question that was asked in the comments to the original question, and forgot to address the error messages in the original question. As mentioned in my comment there, mkoctave is a generic wrapper to the gnu compiler collection. Those messages do not sound specific to octave, but rather that the compiler/linker complains that you're missing the fortran runtime libraries that define these basic functions.

这篇关于如何在GNU Octave中运行Fortran程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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