Software Archive
Read-only legacy content
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17060 Discussions

Using QSort with derived types

craigshirley
Beginner
1,247 Views
I keep getting the same error message when I attempt to compile the attached code.

Error: There is no matching specific subroutine for this generic subroutine call. [QSORT]

I followed the example but no joy, any suggestions.

==========================================================
Module QSortTypeTest
Use portlib
implicit none

Type IndxArray
Integer(kind=4) :: Idx
Real(kind=4) :: Val
EndType IndxArray

Interface qsort
Subroutine qsort_type_IndxArray(Array, Len, ISize, Compar)
!DEC$ Attributes alias: '_QSORT@16' :: qsort_type_IndxArray
Type IndxArray
Integer(kind=4) :: Idx
Real(kind=4) :: Val
EndType IndxArray

Type(IndxArray) :: Array(:)
Intege
0 Kudos
6 Replies
Jugoslav_Dujic
Valued Contributor II
1,247 Views
You are hit with Fortran's scoping rules -- types IndxArray declared in MODULE QSortTest and in INTERFACE block, although identical, have nothing to do with each other -- they are distinct worlds. Compiler complains that you call the routine using argument of type QSortTypeTest::IndxType, but it expects INTERFACE qsort::IndxType.

You have to do something like this:
 
MODULE QSTTypes 
Type IndxArray  
   Integer(kind=4) :: Idx  
   Real(kind=4) :: Val  
EndType IndxArray  
END MODULE QSTTypes 
!--------------------------------------------------------------------- 
Module QSortTypeTest  
!Use portlib        I think this should be commented -- you want to override  
!                   these declarations 
USE QSTTypes 
 
implicit none  
 
Interface qsort  
   Subroutine qsort_type_IndxArray(Array, Len, ISize, Compar)  
   !DEC$ Attributes alias: '_QSORT@16' :: qsort_type_IndxArray  
   USE QSTTypes 
   Type(IndxArray) :: Array(:)... 
Jugoslav
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,247 Views
Oh, I just spotted last line in your code:
   Type(IndxArray) :: Array(:)...  
. That will cause a run-time crash. You have to use assumed-size array (Array(*)) as is used for all other "flavors" of qsort. Remember, although you can declare many generics for qsort, you're always calling one same routine.

Btw, I just opened DFPORT.f90 -- there's an error in the sample code and in the comment:
!!* NOTE you must either include another copy of the declaration 
!!* for foo here, or place foo in a separate module and USE 
!!* here and in module goo. 
The first variant won't work, as you discovered.
0 Kudos
craigshirley
Beginner
1,247 Views
Thanks for your help. When I moved the type declarations to a Module and then used that module in the interface, the problem was resolved. I hope Compaq fixes that error in DFPort, I spent a couple of days being stumped.
0 Kudos
Steven_L_Intel1
Employee
1,247 Views
What error?

Steve
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,247 Views
The error is in the (commented) sample code regarding usage of QuickSort and in the note I quoted above. It is located just above INTERFACE block for QSort. That sample doesn't work as craigs discovered. Worse still, the documentation on QSort refers to that comment in dfport.f90.
0 Kudos
Steven_L_Intel1
Employee
1,247 Views
The rules for type visibility in interface blocks are rather funky, and there may have been some tightening up in the rules since the comments in dfport were written (since they clearly were written initially by Microsoft for PowerStation). This works:



module mytypes
        type foo 
          integer a, b
        end type
end module mytypes
program sort
use dfport
use mytypes

        interface qsort
          subroutine qsort_typefoo( array, len, isize, compar )
            !DEC$ ATTRIBUTES alias:'_QSORT@16' :: qsort_typefoo
 	    use mytypes ! Required!
            type(foo) array(*)
            integer len, isize
            integer(2), external :: compar
          end subroutine
        end interface

integer(2), external :: compar

type (foo) :: array(4)
call qsort (array, 4,8, compar)
end program sort
integer(2) function compar (arg1, arg2)
use mytypes
compar = 0
return
End


Note that the declaration of the type has been moved to a separate module - this is required. I'll look into this a bit more and have the comments changed accordingly.

Steve
0 Kudos
Reply