- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
事实是,“C_F_POINTER”以“可分配数组”作为参数成功编译(ifort 版本 19.0.5.281),并且它的工作方式与使用“指针”作为参数的情况完全相同。
program test1
use mkl_spblas
use omp_lib
use iso_c_binding
implicit none
integer, parameter :: DIM_ = 4, DIM_2 = 6
integer :: stat, i
integer :: irn(DIM_2), jcn(DIM_2)
real*8 :: val(DIM_2)
integer(c_int) :: indexing
integer :: DIM_r, DIM_c
type(c_ptr) :: rows_start_c, rows_end_c, col_indx_c, values_c
(*1)!integer,allocatable :: rows_start_f(:), rows_end_f(:), col_indx_f(:)
!real*8 ,allocatable :: values_f(:)
(*2)integer ,pointer :: rows_start_f(:), rows_end_f(:), col_indx_f(:)
real*8 ,pointer :: values_f(:)
type(SPARSE_MATRIX_T) :: mat1, mat2
irn = (/ 2, 2, 3, 4, 0, 0 /)
jcn = (/ 1, 2, 3, 2, 0, 0 /)
val = (/ 5, 8, 3, 6, 0, 0 /)
call omp_set_num_threads(1)
stat = mkl_sparse_d_create_coo (A=mat1, indexing=SPARSE_INDEX_BASE_ONE, &
rows=DIM_, cols=DIM_, nnz=DIM_,&
row_indx=irn, col_indx=jcn, values=val )
if (stat /= 0) stop 'Error in mkl_sparse_d_create_coo'
stat = mkl_sparse_convert_csr (source=mat1,&
operation=SPARSE_OPERATION_NON_TRANSPOSE, &
dest = mat2 )
if (stat /= 0) stop 'Error in mkl_sparse_convert_csr'
stat = mkl_sparse_d_export_csr(mat2, indexing, DIM_r, DIM_c, &
rows_start_c, rows_end_c, col_indx_c, values_c)
(*3)call c_f_pointer(rows_start_c, rows_start_f, [DIM_r])
call c_f_pointer(rows_end_c , rows_end_f , [DIM_c])
call c_f_pointer(col_indx_c , col_indx_f , [rows_end_f(DIM_r)-1])
call c_f_pointer(values_c , values_f , [rows_end_f(DIM_r)-1])
stat = mkl_sparse_destroy (A=mat1)
if (stat /= 0) stop 'Error in mkl_sparse_destroy (mat1)'
stat = mkl_sparse_destroy (A=mat2)
if (stat /= 0) stop 'Error in mkl_sparse_destroy (mat2)'
call mkl_free_buffers
(*4)print *, 'rows_start'
print *, rows_start_f
print *, 'rows_end'
print *, rows_end_f
print *, 'col_indx'
print *, col_indx_f
print *, 'values'
print *, values_f
print *, 'indexing'
print *, indexing
print *, 'size(values_f,1)'
print *, size(values_f,1)
end program test1
在上面的测试代码中,我在代码的左侧将一些点标记为(*1)、(*2)等。
(*1) & (*2) :代码的可分配数组版本和指针版本(*3) :我称之为“C_F_POINTER”的地方(*4) : 打印语句以查看输出
(*1) 和 (*2) 情况下的结果“完全”相同,并且所有值都已正确转换为所需的 CSR 格式。
rows_start
1 1 3 4
rows_end
1 3 4 5
col_indx
1 2 3 2
values
5.00000000000000 8.00000000000000 3.00000000000000
6.00000000000000
indexing
1
size(values_f,1)
4
我 2 年前在 StackOverflow 中发现了一个类似的问题 ( difference between fortran pointers or allocatable arrays for c_f_pointer call )。
这个问题现在在问我脑海中完全相同的问题。
如果我用我的话重新排列问题,
program assumed_size_array_test
implicit none
external assign_A
real*8 :: tot_array(2,2)
integer:: i
! Initially 'tot_array' set to be 1.d0
tot_array = 1.d0
write(*,*) 'Before'
write(*,'(5f5.2)') tot_array
call assign_A(tot_array(1,2))
write(*,*) 'After'
write(*,'(5f5.2)') tot_array
end program
subroutine assign_A(A)
implicit none
real*8, intent(inout) :: A(*)
integer :: i
do i = 1,5
A(i) = 2.d0
enddo
end subroutine
Before
1.00 1.00 1.00 1.00
After
1.00 1.00 2.00 2.00
感谢您阅读这个问题。
最佳答案
显然,Fortran POINTER
变量和ALLOCATABLE
变量在内部实现上有很多共同点。其中大部分都在幕后,不应直接访问。两者都分配一些内存并且可能使用相同的操作系统或 C 运行时库的分配器。例如,malloc()
。
两者都分配或指向一些内存,并通过简单地址(对于标量)或数组描述符(对于数组)进行描述。
指针和可分配变量的主要区别在于您可以使用它们做什么以及编译器将为您做什么。您可以将可分配项视为一种与 C++ 中的 std::unique_ptr
非常相似的“智能指针”。回想一下 C++ 中发生的事情,你有 new
和 delete
,它们依次调用 malloc
和 free
但你不允许混合它们。而且您当然也不允许手动修改存储在 C++ 智能指针中的地址。
当您将可分配变量发送到需要指针的过程时,任何事情都可能发生,这是未定义的行为。但是,如果内部隐藏结构具有类似的布局,则可能会发生您实际上将 allocatable internals 设置为指向一些未通过 allocatable 分配的内存。然后您可能会认为一切正常并且您拥有了一项新功能。然而,当释放时间到来时,可分配对象通常会自动释放,它很容易以非常不可预测的方式失败。它可能会在代码非常奇怪的地方崩溃,结果可能是错误的等等。任何事情都有可能发生。
例如,这个极其丑陋的程序也适用于我(在 gfortran 中):
subroutine point(ptr, x)
pointer :: ptr
target :: x
ptr => x
end subroutine
interface
subroutine point(ptr, x)
allocatable :: ptr
target :: x
end subroutine
end interface
allocatable z
y = 1.0
call point(z, y)
print *, z
end
但是你不应该永远做这样的事情。这真的是非常非常错误的事情。如果您将 z
设为局部变量,以便它被释放,或者如果您尝试释放它,它将崩溃。那是因为编译器拥有的唯一信息是地址。在内部,可分配对象看起来真的和指针一样。它只是一个地址(对于标量)。唯一的区别是您可以用它做什么以及编译器会自动为您做什么。
这甚至不会崩溃,因为我提到的内部实现相似性。但这同样是错误的。
subroutine point(ptr, x)
pointer :: ptr
target :: x
ptr => x
end subroutine
interface
subroutine point(ptr, x)
allocatable :: ptr
target :: x
end subroutine
end interface
allocatable z
pointer y
allocate(y)
y = 1.0
call point(z, y)
print *, z
deallocate(z)
end
它幸存下来是因为可分配和指针在 gfortran 中使用相同的内部分配器 (malloc
),并且它们都作为简单地址实现。
关于c - 调用 C_F_POINTER 时 Fortran 指针和 Fortran 可分配的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61776293/
是的,我知道..,这不是想象的...这是一个真正的 Fortran 问题。 以前的版本是指 Fortran 2003、95、90,甚至 77。 我所说的“向后兼容”是指可以轻松运行为 2008 年以前
我有一个程序,它的变量中有一个值。一旦确定了该值,我想调用另一个程序并使用该变量的值来确定在新程序中的位置。有人知道该怎么做吗? 最佳答案 如果您有 Fortran 2008 编译器,您将拥有标准子例
namelist 是一种有用的 fortran 结构,可以从文件中快速初始化变量。 namelist 有一个名称并包含一组具有已知类型的变量。这使得它类似于 type 结构。 通常情况下,给程序或子例
我正在遍历索引,我正在检查我是否不在第一个循环交互和另一个条件中。如果第一个条件是 .False.,我不想评估第二个条件。 do i = 1, n if ( i /= 1 .and. var(
Fortran 2003 具有用于数组连接的方括号语法,Intel fortran 编译器也支持它。我在这里为矩阵连接写了一个简单的代码: program matrix implicit none r
我正在尝试通过重载类型名称来制作自定义数据类型构造函数。但是,在进行调用时,将调用默认构造函数。我不明白我做错了什么。 这是有问题的代码片段。 module test type, pu
我的最终目标是在 Fortran 中有一个通用的映射函数,即一个接受任意类型 A 的数组和一个 A->B 类型的函数的函数,将此函数应用于给定数组的所有元素并返回一个B 类型的数组。我无法用数组实现它
我正在学习 Fortran,在使用格式编写时发现了一些奇怪的东西(我使用的是 Fortran onlinegdb) Program Hello real, dimension(3,2):: array
Fortran 中的INTERFACE 语句是否使其成为正式实现multiple dispatch 的编程语言? ? (我问是因为所链接的维基百科文章在其看似全面的支持相关范式的示例编程语言列表中并未
我可以使用 Fortran 95 编译器编译 Fortran 90 文件吗? Fortran 95 似乎有很多,但 Fortran 90 没有。 最佳答案 这个可以: NAGWare f95 Comp
嗨,我在 Fortran 中对二维离散化问题强加边界条件时遇到了麻烦。我的离散化网格是一个二维正方形,在 x,y 方向上从 -L 到 L。 我想强加这样的边界条件, 在 x=L 的边界线上,指定了函数
Fortran 是否有与 C assert 等效的标准函数/关键字? ? 我找不到 assert我在Fortran2003标准中提到过。我发现了一些如何使用预处理器的方法,但是在这个 answer建议
我有一系列的作业,使用“;”将它们分配给同一个ike。分开statemnts,但我收到此错误: 1.0;磅(1,9) 1个 错误:(1)处无法分类的陈述 在文件LJ.F90:223中 如果每个语句都在
我正在使用 gfortran -std=f2008。我有一个函数,它返回一个包含可分配数组的派生类型。该函数在返回之前调用allocate()。似乎在分配数组的函数返回之后,数组会自动释放一段时间,并
我制作了这个小型测试程序来“证明”在编译之前(或者如果你让它们可分配),你不能在不指定它们的大小的情况下使用向量。我的观点失败了。我期待本地向量“num”会失败。程序在执行程序之前无法知道它的大小。大
出于优化原因,Fortran 强制子例程或函数的虚拟参数不是别名,即它们不指向相同的内存位置。 我想知道相同的约束是否适用于函数的返回值。 换句话说,对于给定的 myfunc 函数: function
我已经在Fortran 90中编写了一个相当大的程序。它已经运行了一段时间了,但是今天我尝试将其提高一个档次并增加问题的大小(这是研究非标准的有限元求解器,如果那样的话)。可以帮助任何人...)现在,
在 C 和 C++ 中,有许多操作会导致未定义的行为,即允许编译器做任何它想做的事情的情况。 Examples包括在释放变量后使用它,释放变量两次和取消引用空指针。 Fortran 是否也有未定义的行
通常我使用fortran进行数值分析,然后使用matlab、R和python进行后期和前期工作。 我发现 matlab、R 和 python 在终端中提供了命令提示符,以便您可以运行脚本以及从命令行立
在 Fortran 中将变量设置为 +Infinity 的最安全方法是什么?目前我正在使用: program test implicit none print *,infinity() con
我是一名优秀的程序员,十分优秀!