Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
7056 Discussions

Intel MKL Pardiso, LP64, and ILP64 Interfaces

brianlamm
Beginner
1,278 Views
The Intel MKL user guide and the Intel MKL-supplied Fortran 90/95 interface to Pardiso (mkl_pardiso.f90) appear to be in contradiction.

On page 3-5 of MKL User Guide it reads:

"You may alternatively use other 64-bit types for the integer parameters that must be
64-bit in ILP64. For example, with Intel compilers, you may use types:
INTEGER(KIND=8) for Fortran
long long int for C/C++
Note that code written this way will not work for the LP64 interface. Table 3-4 summarizes
usage of the integer types."
(bold mine)

First, this seems odd: if one is using the ILP64 interface (linking to *ilp64* libraries and using /4I8 in build line), then simple INTEGER declarations are 8-byte (64 bit) by default, and so "INTEGER(KIND=8) for Fortran" is redundant (not needed). So that's confusing, and I would like clarification of why that statement is even there.

Now, Pardiso is supposed to work with either the LP64 or the ILP64 interface. However, in the MKL-supplied .f90 file (in the MKL-provided interface directory) for the interface to Pardiso (mkl_pardiso.f90) there is, what amounts to, an explicit specification of INTEGER(KIND=8). This is in flat contradiction to the above-quoted verbiage out of the MKL User Guide. The User guide reads it does not go into specifics of what integer types are used where either the ILP64 or LP64 interface is used, and recommends to the reader to use the MKL-provided intefaces to determine what INTEGERs default to. So that's what I did, I looked into mkl_pardiso.f90, and in that file one finds:

MODULE MKL_PARDISO_PRIVATE
TYPE MKL_PARDISO_HANDLE; INTEGER(KIND=8) DUMMY; END TYPE
END MODULE MKL_PARDISO_PRIVATE

MODULE MKL_PARDISO
USE MKL_PARDISO_PRIVATE

!
! Subroutine prototype for PARDISO
!

INTERFACE
SUBROUTINE PARDISO( PT, MAXFCT, MNUM, MTYPE, PHASE, N, A, IA, JA, PERM, NRHS, IPARM, MSGLVL, B, X, ERROR )
USE MKL_PARDISO_PRIVATE
TYPE(MKL_PARDISO_HANDLE), INTENT(INOUT) :: PT(*)
INTEGER, INTENT(IN) :: MAXFCT
INTEGER, INTENT(IN) :: MNUM
INTEGER, INTENT(IN) :: MTYPE
INTEGER, INTENT(IN) :: PHASE
INTEGER, INTENT(IN) :: N
INTEGER, INTENT(IN) :: IA(*)
INTEGER, INTENT(IN) :: JA(*)
INTEGER, INTENT(IN) :: PERM(*)
INTEGER, INTENT(IN) :: NRHS
INTEGER, INTENT(INOUT) :: IPARM(*)
INTEGER, INTENT(IN) :: MSGLVL
INTEGER, INTENT(OUT) :: ERROR
REAL(KIND=8), INTENT(IN) :: A(*)
REAL(KIND=8), INTENT(INOUT) :: B(*)
REAL(KIND=8), INTENT(OUT) :: X(*)
END SUBROUTINE PARDISO
END INTERFACE

END MODULE MKL_PARDISO

So, there it is, the Pardiso "pointer" "PT" is a derived type whose sole component is an 8-byte INTEGER regardless of whether ILP64 or LP64 interface is used, in direct contradiction to MKL User Guide's own warning this will not work if used with LP64 interface, but this MKL-supplied Pardiso interface is advertised, in MKL User Guide, as being compatible with both ILP64 and LP64 interfaces.

So, which is correct, the MKL-supplied Fortran 90/95 interface or the User Guide?

-Brian
0 Kudos
7 Replies
brianlamm
Beginner
1,278 Views
Well, that was underwhelming. I thought maybe Intel MKL team might have responded.
I'll just post to IPS.
-Brian
0 Kudos
Ying_H_Intel
Employee
1,278 Views
Quoting - brianlamm
Well, that was underwhelming. I thought maybe Intel MKL team might have responded.
I'll just post to IPS.
-Brian


Hi Brian,

We will investigate this. Butthe Pardiso's pt pointer isvery special casefrom the ILPvs. LP point of view.
As you see in the manual, the parametermust be
INTEGER*4 for 32 -bit operating systems; // or 32 bit applicaton
INTEGER*8 for 64 -bit operating systems; // or 64 bit application, either ILP64or LP64.
Array, DIMENSION (64)
On entry, solver internal data address pointer. These addresses are passed to the solver and all related internal
memory management is organized through this pointer.

Thus
C.. Internal solver memory pointer for 64-bit architectures
C.. INTEGER*8 pt(64)
C.. Internal solver memory pointer for 32-bit architectures
C.. INTEGER*4 pt(64)
C.. This is OK in both cases
INTEGER*8 pt(64)

here we claimed the pt INTEGER(KIND=8) ismainly from the view of 32 bit vs. 64bit.

Soas my unterstand,the "not work" if used with LP64 interface here may mean
for most of other MKL functions, whichtake 32bit interger as parameter under LP interface, if claim
INTEGER(KIND=8) for Fortran
long long int for C/C++
to useLP64 interface library will cause error. But looks ambiguous here.I will check this again.

For pardiso pt parameter, which require 64bit intergeras input whatever ILP 64 interface and LP64 interface,then we define it as INTEGER(KIND=8), as a result,it can workunder IA32, ILP64 and LP64 interface.

Best Regards,
Ying

0 Kudos
Sergey_P_Intel2
Employee
1,278 Views

Hi Brian,

Let me also clarify this issue. pt is the special PARDISO parameter. Original PARDISO doc says that "...pt is the internal data address pointer. The integer length should be 4-byte on 32-bit operating memory an 8-byte on 64-bit operating systems". So the type of pt is determined by operating systems but not LP64 or ILP64 interfaces.

Consequently, this interface will not work on IA32 systems, so there is a bug in the PARDISO docs.It will be fixed in nearest builds.

Kind regards,

Sergey

0 Kudos
brianlamm
Beginner
1,278 Views
Wow, from underwhelming to overwhelming, thanks much Ying and Sergey.

I'm taking away from this defining the componenet "dummy" of the derived type "mkl_pardiso_handle" as INTEGER(8)) or INTEGER(SELECTED_INT_KIND(12)) will work with both the ILP and LP interfacs, and either of those interfaces are only use for an Intel64 or and IA64 target.

But what I'm still confused about is whether using INTEGER(8) will allow Pardiso to work correctly on IA32 target, where neither LP nor ILP interfaces are used. It appears Ying posits yes and Sergey posits no.

Thanks to you both for the helpful replies.

-Brian
0 Kudos
Ying_H_Intel
Employee
1,277 Views
Quoting - brianlamm
Wow, from underwhelming to overwhelming, thanks much Ying and Sergey.

I'm taking away from this defining the componenet "dummy" of the derived type "mkl_pardiso_handle" as INTEGER(8)) or INTEGER(SELECTED_INT_KIND(12)) will work with both the ILP and LP interfacs, and either of those interfaces are only use for an Intel64 or and IA64 target.

But what I'm still confused about is whether using INTEGER(8) will allow Pardiso to work correctly on IA32 target, where neither LP nor ILP interfaces are used. It appears Ying posits yes and Sergey posits no.

Thanks to you both for the helpful replies.

-Brian

Hi Brian,

Thank you for pointing out this.


From the view of test and programming, INTEGER(8) works on all architectures (IA32, LP64, ILP64) practically. The explicit specification of INTEGER(KIND=8) in mkl_pardiso.f90cansimply the interface declaration.


But it is contradict with MKL documentations,

Namely, MKL manual said:

pt INTEGER*4 for 32 -bit operating systems;

INTEGER*8 for 64 -bit operating systems;

Let's take this as common rules.


So from the theoretical point of view, Sergey is right. We shouldprovide F90 interface for IA32 with INTEGER (4) pt in order to coincide with other interfaces and MKL docs. Or mentionedthisin MKL documentation

Thanks
Ying
0 Kudos
Andrew_Smith
Valued Contributor I
1,278 Views

The help file also says that the memory pointer array PT must be initialized to zero. The integer component if the type MKL_PARDISO_HANDLE is called DUMMY. It is not initialized so presumably the user must add coding to do this?

Why not be more explicit in the help file rather than make users dig around for the difinition of what MKL_PARDISO_HANDLE contains?

Or perhaps modify the definition to integer(INT_PTR_KIND()) :: DUMMY = 0.

0 Kudos
mecej4
Honored Contributor III
1,278 Views

Andrew Smith wrote:

The help file also says that the memory pointer array PT must be initialized to zero. The integer component if the type MKL_PARDISO_HANDLE is called DUMMY. It is not initialized so presumably the user must add coding to do this?

Why not be more explicit in the help file rather than make users dig around for the difinition of what MKL_PARDISO_HANDLE contains?

Or perhaps modify the definition to integer(INT_PTR_KIND()) :: DUMMY = 0.

This is one of those instances where the declaration of the type of one of the arguments is no longer the same (in a compiler's view) as it was a few years ago. I, too, was caught unawares about the change when using one of the older Pardiso examples that I had modified and later attempted to use with a newer version of MKL.

Changing the type declaration to add initialization to zero, as you suggested, will not be sufficient. That is because a program that uses Pardiso may solve more than one problem using Pardiso, and your suggested initialization will work only for the sequence of Pardiso calls pertaining to the first problem.

As you can see in some the MKL example source files, you can do

   DO i = 1, 64

        PT(i)%DUMMY = 0

   END DO

Or, if calling from C, call memset() to set the 256 (IA32) or 512 (X64) bytes to zero.

0 Kudos
Reply