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

Results error when sorting long integer array in Linux

zhangyucas
Beginner
730 Views

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   

      Interface
         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
	
	  
      Return
      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


      Cmp_Function_GPU=C1%Index-C2%Index
 
      End Function

 

Thank you very much!

0 Kudos
4 Replies
Mark_Lewy
Valued Contributor I
645 Views

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
cryptogram
New Contributor I
636 Views

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
zhangyucas
Beginner
583 Views

Hi cryptogram,

Your suggestion successfully solves my problem. It finally works!

Thanks for your help!

 

-Yu

0 Kudos
zhangyucas
Beginner
583 Views

Hi Mark,

Your suggestion successfully solves my problem. It finally works!

Thanks for your help!

 

-Yu

0 Kudos
Reply