You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Fortran调用Python函数?含TensorFlow与数组传递需求

从Fortran调用Python函数并传递数组到TensorFlow的可行方案

方案一:利用f2py实现反向调用(Fortran调Python)

f2py支持反向调用,可直接通过它生成的接口让Fortran调用Python函数,步骤如下:

  1. 编写Fortran驱动代码
    声明要调用的Python函数接口,直接传递Fortran数组:

    program call_python_tf
      implicit none
      real, dimension(2,3) :: fortran_arr
      integer :: i, j
    
      ! 初始化列优先的Fortran数组
      do j=1,3
        do i=1,2
          fortran_arr(i,j) = real(i+j)
        end do
      end do
    
      ! 调用Python端的TensorFlow处理函数
      call py_tf_processor(fortran_arr)
    
    end program call_python_tf
    
  2. 编写Python回调函数
    用f2py.callback装饰器定义被Fortran调用的函数,自动处理数组转换并对接TensorFlow:

    import numpy as np
    import tensorflow as tf
    import f2py
    
    @f2py.callback
    def py_tf_processor(arr):
        # f2py自动将Fortran数组转为numpy数组(保留列优先布局)
        np_arr = np.asarray(arr)
        # 转换为TensorFlow张量并执行运算
        tf_tensor = tf.convert_to_tensor(np_arr, dtype=tf.float32)
        result = tf.matmul(tf_tensor, tf_tensor, transpose_b=True)
        print("TensorFlow运算结果:\n", result.numpy())
        return
    
  3. 编译绑定并运行
    用f2py编译生成可调用模块:

    f2py -c -m fortran_py_bridge fortran_code.f90 python_callback.py
    

    直接运行生成的模块,或在Fortran环境中调用即可。

方案二:通过ISO_C_BINDING借助C语言中转

如果f2py的方式无法满足定制需求,C作为中间层是更灵活的选择:

  1. 编写C中转函数
    嵌入Python解释器调用逻辑,处理Fortran数组的C绑定:

    #include <Python.h>
    #include <numpy/arrayobject.h>
    
    // Fortran可调用的C函数(注意Fortran会自动给函数名加下划线)
    void call_python_tf_(float *arr, int *rows, int *cols) {
        // 初始化Python解释器(长期运行的程序建议只初始化一次)
        if (!Py_IsInitialized()) {
            Py_Initialize();
            import_array(); // 初始化numpy C API
        }
    
        // 导入Python端的TensorFlow处理模块
        PyObject *pModule = PyImport_ImportModule("tf_handler");
        PyObject *pFunc = PyObject_GetAttrString(pModule, "process_array");
    
        // 将C数组转为numpy数组(复用Fortran内存,无拷贝)
        npy_intp dims[2] = {*rows, *cols};
        PyObject *pArr = PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, arr);
    
        // 调用Python函数并传递数组
        PyObject *pArgs = PyTuple_New(1);
        PyTuple_SetItem(pArgs, 0, pArr);
        PyObject_CallObject(pFunc, pArgs);
    
        // 清理资源(长期运行的程序可延迟清理)
        Py_DECREF(pArgs);
        Py_DECREF(pArr);
        Py_DECREF(pFunc);
        Py_DECREF(pModule);
    }
    
  2. 编写Fortran绑定代码
    用iso_c_binding声明C函数接口,传递数组参数:

    program call_via_c
      use iso_c_binding
      implicit none
      interface
        subroutine call_python_tf(arr, rows, cols) bind(C, name='call_python_tf_')
          import :: c_float, c_int
          real(c_float), intent(inout) :: arr(*)
          integer(c_int), intent(in) :: rows, cols
        end subroutine call_python_tf
      end interface
    
      real(c_float), dimension(2,3) :: fortran_arr
      integer(c_int) :: rows=2, cols=3
      integer :: i,j
    
      ! 初始化数组
      do j=1,3
        do i=1,2
          fortran_arr(i,j) = real(i+j, c_float)
        end do
      end do
    
      ! 通过C中转调用Python函数
      call call_python_tf(fortran_arr, rows, cols)
    
    end program call_via_c
    
  3. 编写Python TensorFlow处理脚本(tf_handler.py)

    import tensorflow as tf
    import numpy as np
    
    def process_array(arr):
        tf_tensor = tf.convert_to_tensor(arr, dtype=tf.float32)
        print("输入Fortran数组:\n", arr)
        result = tf.reduce_mean(tf_tensor)
        print("TensorFlow均值计算结果:", result.numpy())
        return
    
  4. 编译运行

    • 编译C代码为共享库:
      gcc -shared -fPIC -I/usr/include/python3.x -lpython3.x -lnumpy c_bridge.c -o libpybridge.so
      
    • 编译Fortran代码:
      gfortran fortran_caller.f90 libpybridge.so -o fortran_c_py
      
    • 运行程序:./fortran_c_py

关键注意事项

  • 内存效率:两种方案都支持直接复用Fortran数组内存,无需额外拷贝,适合处理大数组。
  • 解释器生命周期:如果Fortran程序长期运行,避免频繁初始化/销毁Python解释器,可在程序启动时初始化一次。
  • 架构一致性:确保Python、Fortran、C的编译架构(32/64位)完全一致,避免兼容性问题。

内容的提问来源于stack exchange,提问作者Nicola Clinco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 04:51:22