天道酬勤,学无止境

fortran

Fortran 派生类型包含可从 C 访问的派生类型(Fortran derived types containing derived types to be accessible from C)

问题 作为这篇文章的扩展,我有派生类型,这些派生类型本身就是派生类型的成员。 下面的例子: module simple use iso_c_binding TYPE SIMPLEF INTEGER :: A INTEGER, POINTER :: B, C(:) END TYPE SIMPLEF TYPE COMPLEXF INTEGER :: X TYPE (SIMPLEF) :: Y END TYPE COMPLEXF end module simple 与上面的帖子一样,目的是在 C 中具有类似的派生类型,并能够将值来回传递给 Fortran。 解决方案可以在这里看到。 然而,在这里它不仅仅是一个派生类型,它是一个派生类型,它的成员是派生类型本身。 我是否需要为 COMPLEXF 创建 Y 的每个成员的子例程,即 SETY_A、QUERYY_A、SETY_B、QUERYY_BSIZE、SQUERYY_B 等? 或者有没有更好的方法来解决这个问题? 回答1 可以使用相同的方法。 什么是最好的取决于您认为 C 客户端与 Fortran 对象交互的最佳方式。 在编写太多代码之前,应该先考虑一下。 正如所介绍的, y组件的存在是 C 代码可能不需要关心的一个细节 - 而不是调用过程sety_a您可以将它命名为set_a 。

2021-09-19 13:33:21    分类:技术分享    c   pointers   fortran   fortran-iso-c-binding   derived-types

complex(8) 的 CABS(x) 函数(CABS(x) function for complex(8))

问题 双精度复数值是否有绝对值函数? 当我尝试CABS()我得到 V(1,j) = R(j,j) + (R(j,j)/cabs(R(j,j)))*complexnorm2(R(j:m,j)) “错误:在 (1) 处调用‘cabs’时参数‘a’的类型应该是 COMPLEX(4),而不是 COMPLEX(8)” 我读过有一个名为CDABS()的函数,但我不确定这是否是同一回事? 回答1 没有理由使用ABS()以外的任何东西。 FORTRAN 77 中已经存在内部过程的泛型。您可以将它们用于所有内部数字类型。 如果您想查看通用ABS()的可用特定函数表,请参阅 https://gcc.gnu.org/onlinedocs/gfortran/ABS.html ,但它们通常仅用于作为实际参数传递。 您可以看到CDABS()是一个非标准扩展,我不建议使用它。 回答2 CABS由标准定义为采用默认复杂类型的参数。 在您的实现中,这看起来像complex(kind=4) 。 没有标准功能CDABS ,尽管您的实现可能会提供一个:阅读适当的文档。 此外,对于采用double complex参数的泛型函数ABS没有标准的特定函数。 同样,您的实现可能会提供一种称为CDABS以外的CDABS 。 也就是说,泛型函数ABS接受任何整数、实数或复数参数。 用那个。 回答3 COMPLEX*8 和

2021-09-19 12:26:25    分类:技术分享    fortran

将数组切片作为参数传递时的 Fortran 性能(Fortran performance when passing array slices as arguments)

问题 我喜欢 fortran 的数组切片符号( array(1:n) ),但我想知道如果我在不必要的时候使用它们是否会降低性能。 例如,考虑一下这个简单的快速排序代码(它有效,但显然它没有注意选择一个好的枢轴): recursive subroutine quicksort(array, size) real, dimension(:), intent(inout) :: array integer, intent(in) :: size integer :: p if (size > 1) then p = partition(array, size, 1) call quicksort(array(1:p-1), p-1) call quicksort(array(p+1:size), size-p) end if end subroutine quicksort function partition(array, size, pivotdex) result(p) real, dimension(:), intent(inout) :: array integer, intent(in) :: size, pivotdex real :: pivot integer :: i, p pivot = array(pivotdex) call swap(array

2021-09-19 06:14:20    分类:技术分享    fortran   slice   fortran90

如何找出给定对象所在的库?(How can I find out which library is home to a given object?)

问题 我在运行 Irix 6.5 的 SGI 上使用 FORTRAN 和 C 进行编程,但这应该适用于所有类 Unix 系统。 当我收到“未解析的文本符号”链接错误时,如何找到需要链接到我的程序的库? 这是我从链接器看到的示例: ld32: ERROR 33 Unresolved text symbol "ortho2_" -- first referenced by ./libfoo.a 我是否只需要知道需要哪些库,或者是否有一些工具或命令可以帮助我解决这个问题? 回答1 您可以使用nm命令列出共享库中的动态符号: nm -D /lib/libc.so.6 然后grep查找您要查找的符号。 省略静态库的 -D。 您可以在循环中或与 xargs 一起使用它来扫描多个库。 我通常只使用谷歌(假设符号来自公开可用的库)。 回答2 使用nm (如 Robert Gamble 的回答)是您问题的正确答案。 诀窍在于知道在哪里寻找图书馆。 你的程序是做什么的? 如果有大量的数字,很可能你应该链接数学库(如 LAPACK 或 BLAS),并且可能想要开始寻找那里。 网络搜索也很有帮助——我在我最喜欢的搜索引擎中输入了“ortho2”,并得到了这个文档,表明它在libfgl.a 请注意,当您搜索时,您可能应该省略尾随的下划线 - 它通常由编译器添加到例程名称中。 回答3 我抵制了将其添加到

2021-09-19 06:02:50    分类:技术分享    c   unix   linker   fortran   sgi

有没有理由写.eqv。 。真的。?(Is there ever a reason to write .eqv. .true.?)

问题 在逻辑上,以及在 *ahem*正确设计的编程语言中,将布尔值与 true 进行比较总是多余的,即a == True应该简单地替换为a 。 (同样, a == False not a )。 许多语言,包括C,没有一个正确的布尔类型,因此它可以有所作为,你是否有真比较(例如2 == true收益率0 ,这是一个布尔表示假,而2本身可以代表真正的)。 这也是 Fortran 中的一个问题,还是我可以随时替换a .eqv. .true. a .eqv. .true. 通过a ? (我发现在一些遗留代码中,我严重怀疑这只是作者没有真正考虑过的众多事情之一......但我很好奇是否真的隐藏了一些我应该注意的特殊情况.) 回答1 不,没有理由写那个。 a .eqv. .true. 与a相同。 只是不要使用== ,它用于不同的数据类型。 关于遗留代码中发现的东西,不要忘记很多(如果不是大多数)Fortran 用户不是专业程序员,也从未接受过正确编程技术方面的全面培训。 通常,他们只是学习语言规则。 回答2 这真的是一个普遍存在的问题吗? 既然你问“永远的原因,”我能想象在开发过程中使用它作为一个占位符/调试: c if(a.eqv.b) .. if(a.eqv..true.) 同样,我可以看到是否有人修改了最初将a作为整数并更改为逻辑的代码,您最终可能a.eq.1 a.eqv..true

2021-09-19 03:32:19    分类:技术分享    boolean   fortran   fortran95

在 FORTRAN 2003 中完成(Finalisation in FORTRAN 2003)

问题 根据 Fortran Wiki,英特尔 fortran编译器版本 14 应支持 FORTRAN 2003 标准中定义的终结。 我尝试将此功能与ifort 14一起使用,但观察到奇怪的行为。 以下示例应显示这一点: module mtypes implicit none type mytype integer, private :: nr contains final :: delete_mytype procedure :: print_mytype end type contains !> \brief Constructs a new mytype !! \return The created mytype !> function init_mytype(number) type(mytype) :: init_mytype integer, intent(in) :: number ! allocate(init_mytype) init_mytype = mytype(number) print *, 'init mytype', number end function !> \brief De-constructs a mytype object !> subroutine delete_mytype(this) type(mytype) :: this !<

2021-09-19 03:26:08    分类:技术分享    fortran   intel-fortran   fortran2003

为什么覆盖参数的名称必须与抽象接口的名称匹配?(Why do the names of overriding arguments have to match those of the abstract interface?)

问题 为什么覆盖过程中的参数名称需要与抽象接口的参数名称匹配? 我明白显然需要TYPE 、 INTENT等参数来匹配接口,但是编译器为什么要关心我调用的变量? 在下面,我定义了一个简单的抽象实用程序类,其中包含一个采用双精度参数的延迟过程EVAL 。 !------------------------------------- an abstract utility class ! type, abstract :: func_1d contains procedure(interface_1d),deferred :: eval end type func_1d !-------------------------------------------- interface for eval ! abstract interface function interface_1d(this,data) result(rval) import :: func_1d class(func_1d), intent(inout) :: this real*8 , intent(in) :: data real*8 :: rval end function interface_1d end interface 为EVAL定义一个覆盖类和一个实现: type, extends(func_1d)

2021-09-19 02:39:00    分类:技术分享    fortran   gfortran   fortran2003

SIGFPE:此错误的浮点异常回溯:0x7F70C71AF7D7(SIGFPE: Floating-point exception backtrace for this error: 0x7F70C71AF7D7)

问题 我在 Ubuntu 14.04 下使用 Fortran 90 模型。 gfortran 95 编译器 (gfortran 4:4.8.2-1ubuntu6) 和 gcc 4:4.8.2-1ubuntu6 由 Ubuntu 软件中心安装。 运行模型后,我收到以下错误消息: Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation. Backtrace for this error: #0 0x7F70C71AF7D7 #1 0x7F70C71AFDDE #2 0x7F70C68EAD3F #3 0x7F70C6EB6913 有人能解释一下这些回溯代码是什么意思吗? 我该如何处理这些错误? 回答1 在编译期间使用选项-O -Wall -fcheck=all -g -fbacktrace并运行可执行文件。 如果这没有提供必要的信息,请尝试在 gdb 和/或 valgrind 下运行您的程序。 回答2 当我编译 Fortran95 代码时,我遇到了同样的错误。 就我而言,我只是调试了我的代码。 存在错误的数学运算(除以零)。 一旦我修复它,编译错误就消失了。 尝试检查您的代码是否存在数学错误。 我希望它能帮助你。

2021-09-18 15:22:09    分类:技术分享    floating-point   fortran   gfortran

从 R 调用并行 fortran MPI 子例程(Call parallel fortran MPI subroutine from R)

问题 我想在可由 R 调用的子例程中编写一些并行 Fortran 代码(我想从 R 中读取数据并将其发送到并行 Fortran MPI)。 但是,我注意到,当我将以下程序作为子例程运行时(即,将“子例程”替换为“程序”),代码不再编译(当它是程序时,它会编译)。 我正在使用 Linux 中 MPICH 的mpif90编译代码。 是否可以在 Fortran 的子程序中初始化和完成 MPI? 如果没有,是否仍然可以从 R 以某种方式调用并行 Fortran MPI? 如果不是在 Fortran 中,可以在 C 中完成吗? 这是代码: module global integer numnodes,myid,mpi_err integer, parameter :: my_root=0 end module global module fmpi include 'mpif.h' end module fmpi subroutine init use fmpi use global implicit none call MPI_INIT( mpi_err ) call MPI_COMM_SIZE( MPI_COMM_WORLD, numnodes, mpi_err ) call MPI_Comm_rank(MPI_COMM_WORLD, myid, mpi_err) end

2021-09-18 14:16:33    分类:技术分享    r   parallel-processing   fortran   mpi   subroutine

为什么 Fortran 在 julia 基准测试“rand_mat_mul”中运行缓慢?(Why Fortran is slow in the julia benchmark “rand_mat_mul”?)

问题 Julia (http://julialang.org/) 主页上的基准测试结果表明,在“rand_mat_mul”基准测试中,Fortran 比 Julia/Numpy 慢约 4 倍。 我不明白为什么从同一个 fortran 库 (BLAS) 调用时 fortran 速度较慢?? 我还对矩阵乘法演进 fortran、julia 和 numpy 进行了一个简单的测试,并得到了类似的结果: 朱莉娅 n = 1000; A = rand(n,n); B = rand(n,n); @time C = A*B; >> 已用时间:0.069577896 秒(已分配 7 MB) IPython 中的 Numpy from numpy import * n = 1000; A = random.rand(n,n); B = random.rand(n,n); %time C = dot(A,B); >> 挂墙时间:98 毫秒 复式 PROGRAM TEST IMPLICIT NONE INTEGER, PARAMETER :: N = 1000 INTEGER :: I,J REAL*8 :: T0,T1 REAL*8 :: A(N,N), B(N,N), C(N,N) CALL RANDOM_SEED() DO I = 1, N, 1 DO J = 1, N, 1 CALL RANDOM

2021-09-18 13:39:06    分类:技术分享    numpy   fortran   julia   blas