Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28181 Discussions

Results error when sorting long integer array in Linux


Hi all,

Recently I'm trying to call qsort to sort a long integer array on Linux, however, the result looks like wrong. And I try to call qsort to sort the same array on Windows, finding that the result is correct. Is there something wrong when I call qsort on Linux? Any suggestions will be appreciated!

The codes call qsort on Linux are as follows:


      Module Share_Type_GPU
      Type Element_Type_GPU
         Integer          :: Row
         Integer          :: Col
         Integer(8)       :: Index
         Double Precision :: Val
      End Type
      End Module Share_Type_GPU    
      Subroutine Qsort_COO_Linux_GPU
      Use Global_Variables,            ONLY: Nelem,Nevab,Mposn
      Use,Intrinsic :: Iso_C_Binding,  ONLY: C_Size_T
      Use Ifport, ONLY: Qsort_Element_Types_GPU => Qsort
      Use Share_Type_GPU   

         Subroutine Qsort(Array, Len, Isize, Comp)
            Use, Intrinsic :: Iso_C_Binding, Only: C_Size_T
            Use Share_Type_GPU
            Type(Element_Type_GPU) Array(Len)
            Integer(C_Size_T) Len, Isize
            Integer(8), External :: Comp

         End Subroutine Qsort
      End Interface

      Type(Element_Type_GPU) :: C(Nelem*Nevab*Nevab)	  
      Integer(8), External  :: Cmp_Function_GPU
      Integer (C_Size_T) :: Size_Of_Element, Size_Of_Array
      Integer I
      Do I=1,Nelem*Nevab*Nevab
         C(I)%Val   = COO_Value(I)
         C(I)%Row   = COO_Index(I,1)
         C(I)%Col   = COO_Index(I,2)
         C(I)%Index = COO_Index(I,2)*Mposn+COO_Index(I,1)        ! Long integer larger than integer(4), so use integer(8)
      End Do
      Size_Of_Array   = Size(C)     
      Size_Of_Element = Sizeof(C(1))   
      Call Qsort(C, Size_Of_Array, Size_Of_Element, Cmp_Function_GPU) 
      Do I=1,Nelem*Nevab*Nevab
         COO_Value(I)  = C(I)%Val
         COO_Index(I,1)= C(I)%Row 
         COO_Index(I,2)= C(I)%Col   
      End Do
      End Subroutine
      Function Cmp_Function_GPU(C1, C2)
      Use Share_Type_GPU

      Implicit None

      Type(Element_Type_GPU), Intent(In) :: C1 
      Type(Element_Type_GPU), Intent(In) :: C2 

      Integer(8) :: Cmp_Function_GPU

      End Function


Thank you very much!

0 Kudos
4 Replies
Valued Contributor I

We don't have a full compilable example here, but I suggest going back to the documentation for the ifport implementation of qsort and comparing what you have done with the example there.  One obvious thing that stands out to me is that you have declared the compare function to have a return value of integer(8), when the documentation suggests integer(2).

0 Kudos
New Contributor I

Might be onto something with the integer(2) vs. integer(8)


If the comp argument is passed by reference, the endianness of windows provide a little leeway to get it wrong.


If I pass an integer(8) value to a routine expecting integer(2) on windows, it will work as expected because the first two bytes

of an integer(8) value that would fit into an integer(2) are the same as the integer(2)


For example integer(8)  value of 1 on windows shows up in memory as  01 00 00 00 00 00 00 00

and integer(2) value of 1 shows up in memory as  01 00.  So if I pass the address of integer(8) 1 to a routine expecting integer(2), it

still works.


On unix systems the order in memory is swapped to something a bit for user friendly, such that integer(8) value of 1 is

00 00 00 00 00 00 00 01

and integer(2) value of 1 is

00 01


But then passing integer(8) by reference to a routine expecting integer(2),  the subroutine will see the first 2 bytes of the integer(8) number, and so it would see 0 instead of 1.








0 Kudos

Hi cryptogram,

Your suggestion successfully solves my problem. It finally works!

Thanks for your help!



0 Kudos

Hi Mark,

Your suggestion successfully solves my problem. It finally works!

Thanks for your help!



0 Kudos