我正在为C库编写Fortran绑定.
使用枚举翻译定义的常量(在库头中)的最佳实践是什么,例如
typedef enum cufftType_t {
CUFFT_R2C = 0x2a, // Real to Complex (interleaved)
CUFFT_C2R = 0x2c, // Complex (interleaved) to Real
CUFFT_C2C = 0x29, // Complex to Complex, interleaved
CUFFT_D2Z = 0x6a, // Double to Double-Complex
CUFFT_Z2D = 0x6c, // Double-Complex to Double
CUFFT_Z2Z = 0x69 // Double-Complex to Double-Complex
} cufftType;
Run Code Online (Sandbox Code Playgroud)
以及如何使用翻译常数#define,例如
#define CUFFT_FORWARD -1 // Forward FFT
#define CUFFT_INVERSE 1 // Inverse FFT
Run Code Online (Sandbox Code Playgroud)
或这些的组合
typedef enum cufftCompatibility_t {
CUFFT_COMPATIBILITY_NATIVE = 0x00, …Run Code Online (Sandbox Code Playgroud) 现在我正在使用f2pyFortran 代码调用 Python 函数。我尝试了一个非常简单的例子,但没有成功。
Fortran90代码:
subroutine foo(fun,r)
external fun
integer ( kind = 4 ) i
real ( kind = 8 ) r
r=0.0D+00
do i= 1,5
r=r+fun(i)
enddo
end
Run Code Online (Sandbox Code Playgroud)
使用命令行:
f2py -c -m 回调callback.f90
Python代码:
import callback
def f(i):
return i * i
print callback.foo(f)
Run Code Online (Sandbox Code Playgroud)
错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: `Required argument 'r' (pos 2) not found`
Run Code Online (Sandbox Code Playgroud) 好吧,我先说一下我为什么要这样做.我经常用C/C++编写代码,所以对我来说定义函数非常自然:
vector<int> TestFunct (int a, int b){
<some code here>
return <result>;}
Run Code Online (Sandbox Code Playgroud)
现在我正在学习Fortran,所以我声明这样的函数:
function TestFunc(a,b)
integer, dimension(:) :: TestFunc
integer :: a
integer :: b
<some code here>
endfunction TestFunc
Run Code Online (Sandbox Code Playgroud)
但我最近了解到结果的数据类型可以在函数语句中定义,例如:<data_type> function TestFunc(a,b),这对我来说更自然,因为我习惯了类似的C++声明.
问题是,当我'尝试定义一个向量(实际上是一个integer, dimension(:)严格说话)作为结果数据类型时,我有ifort错误#5082(我将在下一行详述).
在一个例子中,对于代码:
real, dimension(:) function TestFunc(a,b)
integer, intent(in) :: a
integer, intent(in) :: b
<more code here>
endfunction Testfunc
Run Code Online (Sandbox Code Playgroud)
我得到输出:
main.f90(23): error #5082: Syntax error, found ',' when expecting one of: ( * ) ( :: %FILL , …Run Code Online (Sandbox Code Playgroud) fortran function variable-declaration fortran90 intel-fortran
我有一个关于在 Fortran 中编写用户定义运算符的正确方法的问题。更具体地说,我将提供我的问题的示例。我正在致力于为称为“粒子”的球形粒子创建用户定义的数据类型。我想定义一个运算符,它采用现有的 Particle 对象数组并向其中添加一个新的 Particle 对象。我想知道如何定义用户定义的运算符来执行这样的操作。
目前,在 Particle 的类型定义中,我有以下几行:
procedure, public:: addNewParticleTo
generic:: operator(.spawn.) => addNewParticleTo
Run Code Online (Sandbox Code Playgroud)
接下来,我有一个定义如下的子例程:
subroutine addNewParticleTo(a_LHS, a_RHS)
implicit none
class(Particle), dimension(:), allocatable, intent(in):: a_LHS
class(Particle), dimension(:), allocatable, intent(inout):: a_RHS
<rest of the code>
end subroutine addNewParticleTo
Run Code Online (Sandbox Code Playgroud)
我打算将运算符调用为:
particle .spawn. particleArray
Run Code Online (Sandbox Code Playgroud)
我想知道这是否是执行此操作的正确方法。对此的任何建议或建议都会非常有帮助。
fortran user-defined-functions user-defined-types fortran90 fortran95
关于 SO 上的堆栈的问题,终于!我的一生都让我走到了这一步。
所以我需要将我制作的一些相当大的自定义数据结构合并到一个堆栈中。我决定编写一个仅包含一个整数值的最小堆栈结构。这里是 -
MODULE STACK_MODULE
IMPLICIT NONE
TYPE ELEMENT_TYPE
INTEGER(4) :: VAL
TYPE(ELEMENT_TYPE), POINTER :: PREV
END TYPE ELEMENT_TYPE
TYPE STACK_TYPE
INTEGER(4) :: SIZE=0
TYPE(ELEMENT_TYPE), POINTER :: LASTIN
END TYPE STACK_TYPE
CONTAINS
SUBROUTINE PUSH(VAL_,STACK)
IMPLICIT NONE
INTEGER(4), INTENT(IN) :: VAL_
TYPE(STACK_TYPE), INTENT(INOUT) :: STACK
TYPE(ELEMENT_TYPE),TARGET :: CURRENT
! INIT CURRENT
CURRENT%VAL = VAL_
CURRENT%PREV => STACK%LASTIN
! ADD CURRENT TO STACK
STACK%LASTIN => CURRENT
STACK%SIZE = STACK%SIZE+1
RETURN
END SUBROUTINE PUSH
SUBROUTINE POP(STACK,VAL_)
IMPLICIT NONE
TYPE(STACK_TYPE), INTENT(INOUT) :: …Run Code Online (Sandbox Code Playgroud) 我想从文件中获取数据,该文件的数据内容可以具有可变大小。然而,结构非常简单。3 列和未定义的行数。我认为使用可分配的多维数组和显式 DO 循环可以解决我的问题。到目前为止,这是我的代码
program arraycall
implicit none
integer, dimension(:,:), allocatable :: array
integer :: max_rows, max_cols, row, col
allocate(array(row,col))
open(10, file='boundary.txt', access='sequential', status='old', FORM='FORMATTED')
DO row = 1, max_rows
DO col = 1, max_cols
READ (10,*) array (row, col)
END DO
END DO
print *, array (row,col)
deallocate(array)
end program arraycall
Run Code Online (Sandbox Code Playgroud)
现在我面临的问题是我不知道应该如何定义这些 max_rows 和 max_cols ,这与它的大小未知的事实产生共鸣。
示例文件可能看起来像
11 12 13
21 22 23
31 32 33
41 42 43
Run Code Online (Sandbox Code Playgroud)
所以我想出了一种动态(动态)估计文件记录长度的方法。更新一下,方便以后给其他人参考
!---------------------------------------------------------------------
! Estimate the number of records in the …Run Code Online (Sandbox Code Playgroud) 两者之间有区别吗?
integer, intent(in) :: n
integer, dimension(:), allocatable :: a
allocate(a(n))
Run Code Online (Sandbox Code Playgroud)
和
integer, intent(in) :: n
integer, dimension(n) :: a
Run Code Online (Sandbox Code Playgroud)
在哪种情况下我们会使用第一个版本?也许我误解了可分配的数组,第二个版本甚至是可分配的数组?
当我最初无法预测数组的确切大小时,我需要在 Fortran 90 中使用动态数组。所以我编写了一段代码,每次将新元素添加到数组末尾时,该代码都应该扩展可分配数组:
subroutine DArray()
double precision, dimension(:), allocatable :: list
allocate(list(1))
list(1) = 1.1
call AddToList(list, 2.2)
call AddToList(list, 3.2)
call AddToList(list, 4.2)
call AddToList(list, 5.2)
print *, list(1)
print *, list(2)
print *, list(3)
print *, list(4)
print *, list(5)
end
subroutine AddToList(list, element)
double precision :: element
double precision, dimension(:), allocatable :: list
double precision, dimension(:), allocatable :: clist
if(allocated(list)) then
isize = size(list)
allocate(clist(isize+1))
do i=1,isize
clist(i) = list(i)
end do
clist(i+1) = element
deallocate(list) …Run Code Online (Sandbox Code Playgroud) 我有一个 fortran90 代码,(到目前为止)大部分时间都花在 I/O 上,因为需要读取非常大的数据文件(至少 1GB 及以上)。需要写入包含计算结果的较小但仍然很大的数据文件。相比之下,一些快速傅里叶变换和其他计算很快就能完成。我已经并行化 (OpenMP) 其中一些计算,但考虑到上述 I/O 问题,总体性能增益很小。
我目前的策略是立即读取整个文件:
open(unit=10, file="data", status="old")
do i=1,verylargenumber
read(10,*) var1(i), var2(i), var3(i)
end do
close(10)
Run Code Online (Sandbox Code Playgroud)
然后执行操作var1等。我的问题是是否有一个合适的策略使用(最好是)OpenMP 来加速读取过程,特别是考虑到数据文件(如果有任何区别)都很大。
我可以在 Lustre 文件系统上运行这些计算,原则上这为并行 I/O 提供了优势,尽管常规文件系统的通用解决方案将受到赞赏。
我的直觉是这个问题没有解决办法,但我想确认一下。
我有一个带有嵌套 WHERE 语句的 Fortran 90 源代码。有一个问题,但似乎很难理解到底发生了什么。我想把它转换成DO-IF结构以便调试。我不清楚的是如何翻译嵌套的 WHERE。
所有数组都具有相同的大小。
WHERE (arrayA(:) > 0)
diff_frac(:) = 1.5 * arrayA(:)
WHERE (diff_frac(:) > 2)
arrayC(:) = arrayC(:) + diff_frac(:)
ENDWHERE
ENDWHERE
Run Code Online (Sandbox Code Playgroud)
我的选项A:
DO i=1, SIZE(arrayA)
IF (arrayA(i) > 0) THEN
diff_frac(i) = 1.5 * arrayA(i)
DO j=1, SIZE(diff_frac)
IF (diff_frac(j) > 2) THEN
arrayC(j) = arrayC(j) + diff_frac(j)
ENDIF
ENDDO
ENDIF
ENDDO
Run Code Online (Sandbox Code Playgroud)
我的选项B:
DO i=1, SIZE(arrayA)
IF (arrayA(i) > 0) THEN
diff_frac(i) = 1.5 * arrayA(i)
IF (diff_frac(i) > 2) THEN
arrayC(i) = …Run Code Online (Sandbox Code Playgroud)