英特尔Fortran排序例程的开源版本

英特尔Fortran排序例程的开源版本,fortran,gfortran,intel-fortran,Fortran,Gfortran,Intel Fortran,我正在尝试使用gfortran在GNU平台上编译一些专有的Fortran代码。有人知道例程sortqq()或qsort\u up()是否有开源的对应程序吗?libc包含qsort()。如果用Fortran为它编写绑定(c)接口,就可以调用它 首先,下面是一个示例模块,它提供了模仿专有功能的my_qsort包装器: $ cat sort.f90 module m use, intrinsic :: iso_c_binding implicit none private inter

我正在尝试使用gfortran在GNU平台上编译一些专有的Fortran代码。有人知道例程
sortqq
()或
qsort\u up
()是否有开源的对应程序吗?

libc包含qsort()。如果用Fortran为它编写绑定(c)接口,就可以调用它

首先,下面是一个示例模块,它提供了模仿专有功能的my_qsort包装器:

$ cat sort.f90
module m
  use, intrinsic :: iso_c_binding
  implicit none
  private

  interface
    subroutine qsort(base, nel, width, compar) bind(c, name='qsort')
      import c_size_t, c_int
      implicit none
      type(*), intent(inout) :: base(*)
      integer(c_size_t), value :: nel
      integer(c_size_t), value :: width
      abstract interface
        function compar_iface(a, b) bind(c)
          import c_int, c_ptr
          implicit none
          integer(c_int) compar_iface
          type(c_ptr), value :: a, b
        end function
      end interface
      procedure(compar_iface) compar
    end subroutine
  end interface

  interface my_qsort
    module procedure my_qsort_int4
    module procedure my_qsort_int8
    module procedure my_qsort_real4
    module procedure my_qsort_real8
  end interface
  public my_qsort
contains
  subroutine my_qsort_int4(a, nel)
    integer(c_int), intent(inout) :: a(*)
    integer(4), value :: nel
    call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_int4)
  end subroutine

  subroutine my_qsort_int8(a, nel)
    integer(c_long_long), intent(inout) :: a(*)
    integer(4), value :: nel
    call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_int8)
  end subroutine

  subroutine my_qsort_real4(a, nel)
    real(c_float), intent(inout) :: a(*)
    integer(4), value :: nel
    call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_real4)
  end subroutine

  subroutine my_qsort_real8(a, nel)
    real(c_double), intent(inout) :: a(*)
    integer(4), value :: nel
    call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_real8)
  end subroutine

  function less_int4(a, b) result(result)
    integer(c_int) result
    type(c_ptr), value :: a, b
    integer(c_int), pointer :: ap, bp
    call c_f_pointer(a, ap)
    call c_f_pointer(b, bp)
    result = int(ap - bp, c_int)
  end function

  function less_int8(a, b) result(result)
    integer(c_int) result
    type(c_ptr), value :: a, b
    integer(c_long_long), pointer :: ap, bp
    call c_f_pointer(a, ap)
    call c_f_pointer(b, bp)
    result = int(ap - bp, c_int)
  end function

  function less_real4(a, b) result(result)
    integer(c_int) result
    type(c_ptr), value :: a, b
    real(c_float), pointer :: ap, bp
    call c_f_pointer(a, ap)
    call c_f_pointer(b, bp)
    result = int(ap - bp, c_int)
  end function

  function less_real8(a, b) result(result)
    integer(c_int) result
    type(c_ptr), value :: a, b
    real(c_double), pointer :: ap, bp
    call c_f_pointer(a, ap)
    call c_f_pointer(b, bp)
    result = int(ap - bp, c_int)
  end function
end module

program main
  use m
  implicit none
  integer(4) a(10)
  real(4) b(4)

  a = [ 2, 6 , 1, 3, 10, 9, 7, 8, 4, 5 ]
  call my_qsort(a, 10)
  print *, a

  b = [ 2.0, 5.0, 1.0, -5.0 ]
  call my_qsort(b, 4)
  print *, b
end program

$ gfortran sort.f90
$ ./a.out
           1           2           3           4           5           6           7           8           9          10
  -5.00000000       1.00000000       2.00000000       5.00000000
$

我让您的示例工作,但当我尝试将其推广到我的特定情况时,编译器警告您的
less_real()
函数中的
a-b
可能会导致转换中的值发生变化。我还得到了一系列接口不匹配错误:
参数'a'(Type(*)/REAL(8))中的类型不匹配。
等是包含所有调用以及完整错误输出的GitHub要点。您知道这里发生了什么吗?
a-b
警告在这种情况下是无害的,但是可以通过使用
int()
函数进行显式转换来删除。至于类型不匹配错误,我以前版本的gfortran没有捕捉到。我已经在编辑中解决了这两个问题。