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

C# calls Fortran DLL calls MKL paradiso exited with code 2

Julian_H_
Beginner
1,269 Views

Hello,

I have a C# Unit Test solution, which should test a *.dll created in Fortran. This *.dll is using the mkl library to solve an equation system. Unfortunately the paradiso call crashes. I made an minimal example with the paradiso example provided by Intel

C# Solution: UnitTestProjectMKL (DLLUsingMKL.dll, mkl_core.dll and mkl_sequential.dll are added as Link)

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Runtime.InteropServices;

namespace UnitTestProjectMKL
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            bool passed = false;
            NativeMethods.test_MKL_mod(ref passed);
            Assert.IsTrue(passed);
        }
    }


    public static class NativeMethods
    {
        [DllImport(@"DLLUsingMKL.dll ",
            EntryPoint = "MYMODULE_mp_TEST_MKL",
            CharSet = CharSet.Ansi,
            CallingConvention = CallingConvention.Cdecl)]
        public static extern void test_MKL_mod(ref bool passed);
    }
}

 

Fortran solution: DLLUsingMKL.sln

INCLUDE 'mkl_pardiso.f90'
MODULE myModule
  PUBLIC :: test_mkl
CONTAINS
  SUBROUTINE test_mkl(passed)
  !DEC$ ATTRIBUTES DLLEXPORT :: test_mkl
    USE mkl_pardiso
    IMPLICIT NONE
    
    LOGICAL(4), INTENT(INOUT), OPTIONAL :: passed
    
INTEGER, PARAMETER :: dp = KIND(1.0D0)
!.. Internal solver memory pointer 
TYPE(MKL_PARDISO_HANDLE), ALLOCATABLE  :: pt(:)
!.. All other variables
INTEGER maxfct, mnum, mtype, phase, n, nrhs, error, msglvl, nnz
INTEGER error1
INTEGER, ALLOCATABLE :: iparm( : )
INTEGER, ALLOCATABLE :: ia( : )
INTEGER, ALLOCATABLE :: ja( : )
REAL(KIND=DP), ALLOCATABLE :: a( : )
REAL(KIND=DP), ALLOCATABLE :: b( : )
REAL(KIND=DP), ALLOCATABLE :: x( : )
INTEGER i, idum(1)
REAL(KIND=DP) ddum(1)
!.. Fill all arrays containing matrix data.
n = 8 
nnz = 18
nrhs = 1 
maxfct = 1 
mnum = 1
ALLOCATE(ia(n + 1))
ia = (/ 1, 5, 8, 10, 12, 15, 17, 18, 19 /)
ALLOCATE(ja(nnz))
ja = (/ 1,    3,       6, 7,    &
           2, 3,    5,          &
              3,             8, &
                 4,       7,    &
                    5, 6, 7,    &
                       6,    8, &
                          7,    &
                             8 /)
ALLOCATE(a(nnz))
a = (/ 7.d0,        1.d0,             2.d0, 7.d0,        &
             -4.d0, 8.d0,       2.d0,                    &
                    1.d0,                         5.d0,  &
                          7.d0,             9.d0,        &
                                5.d0, 1.d0, 5.d0,        &
                                     -1.d0,       5.d0,  &
                                           11.d0,        &
                                                  5.d0 /)
ALLOCATE(b(n))
ALLOCATE(x(n))
!..
!.. Set up PARDISO control parameter
!..
ALLOCATE(iparm(64))

DO i = 1, 64
   iparm(i) = 0
END DO

iparm(1) = 1 ! no solver default
iparm(2) = 2 ! fill-in reordering from METIS
iparm(4) = 0 ! no iterative-direct algorithm
iparm(5) = 0 ! no user fill-in reducing permutation
iparm(6) = 0 ! =0 solution on the first n components of x
iparm(8) = 2 ! numbers of iterative refinement steps
iparm(10) = 13 ! perturb the pivot elements with 1E-13
iparm(11) = 1 ! use nonsymmetric permutation and scaling MPS
iparm(13) = 0 ! maximum weighted matching algorithm is switched-off (default for symmetric). Try iparm(13) = 1 in case of inappropriate accuracy
iparm(14) = 0 ! Output: number of perturbed pivots
iparm(18) = -1 ! Output: number of nonzeros in the factor LU
iparm(19) = -1 ! Output: Mflops for LU factorization
iparm(20) = 0 ! Output: Numbers of CG Iterations

error  = 0 ! initialize error flag
msglvl = 1 ! print statistical information
mtype  = -2 ! symmetric, indefinite

!.. Initialize the internal solver memory pointer. This is only
! necessary for the FIRST call of the PARDISO solver.

ALLOCATE (pt(64))
DO i = 1, 64
   pt(i)%DUMMY =  0 
END DO

!.. Reordering and Symbolic Factorization, This step also allocates
! all memory that is necessary for the factorization

phase = 11 ! only reordering and symbolic factorization

CALL pardiso (pt, maxfct, mnum, mtype, phase, n, a, ia, ja, &
              idum, 0, iparm, msglvl, ddum, ddum, error)
    
WRITE(*,*) 'Reordering completed ... '
IF (error /= 0) THEN
   WRITE(*,*) 'The following ERROR was detected: ', error
   GOTO 1000
END IF
WRITE(*,*) 'Number of nonzeros in factors = ',iparm(18)
WRITE(*,*) 'Number of factorization MFLOPS = ',iparm(19)

!.. Factorization.
phase = 22 ! only factorization
CALL pardiso (pt, maxfct, mnum, mtype, phase, n, a, ia, ja, &
              idum, nrhs, iparm, msglvl, ddum, ddum, error)
WRITE(*,*) 'Factorization completed ... '
IF (error /= 0) THEN
   WRITE(*,*) 'The following ERROR was detected: ', error
   GOTO 1000
ENDIF

!.. Back substitution and iterative refinement
iparm(8) = 2 ! max numbers of iterative refinement steps
phase = 33 ! only solving
DO i = 1, n
   b(i) = 1.d0
END DO
CALL pardiso (pt, maxfct, mnum, mtype, phase, n, a, ia, ja, &
              idum, nrhs, iparm, msglvl, b, x, error)
WRITE(*,*) 'Solve completed ... '
IF (error /= 0) THEN
   WRITE(*,*) 'The following ERROR was detected: ', error
   GOTO 1000
ENDIF
WRITE(*,*) 'The solution of the system is '
DO i = 1, n
   WRITE(*,*) ' x(',i,') = ', x(i)
END DO
      
1000 CONTINUE
!.. Termination and release of memory
phase = -1 ! release internal memory
CALL pardiso (pt, maxfct, mnum, mtype, phase, n, ddum, idum, idum, &
              idum, nrhs, iparm, msglvl, ddum, ddum, error1)

IF (ALLOCATED(ia))      DEALLOCATE(ia)
IF (ALLOCATED(ja))      DEALLOCATE(ja)
IF (ALLOCATED(a))       DEALLOCATE(a)
IF (ALLOCATED(b))       DEALLOCATE(b)
IF (ALLOCATED(x))       DEALLOCATE(x)
IF (ALLOCATED(iparm))   DEALLOCATE(iparm)

IF (error1 /= 0) THEN
   WRITE(*,*) 'The following ERROR on release stage was detected: ', error1
   STOP 1
ENDIF

IF (error /= 0) STOP 1
  END SUBROUTINE test_mkl
END MODULE myModule

 

/nologo /debug:full /Od /Qopenmp_stubs /warn:interfaces /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc160.pdb" /traceback /check:bounds /check:stack /libs:dll /threads /Qmkl:sequential /c

 

The Output is not giving me much clue where to look for the error

'testhost.x86.exe' (Win32): Loaded 'D:\...\BugMinimalFortranUTestMKL\UnitTestProjectMKL\bin\Debug\mkl_core.dll'. Module was built without symbols.
'testhost.x86.exe' (Win32): Unloaded 'D:\...\BugMinimalFortranUTestMKL\UnitTestProjectMKL\bin\Debug\mkl_core.dll'
'testhost.x86.exe' (Win32): Loaded 'D:\...\BugMinimalFortranUTestMKL\UnitTestProjectMKL\bin\Debug\mkl_core.dll'. Module was built without symbols.
'testhost.x86.exe' (Win32): Loaded 'C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\mpirt\libimalloc.dll'. 
'testhost.x86.exe' (Win32): Unloaded 'C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\mpirt\libimalloc.dll'
'testhost.x86.exe' (Win32): Loaded 'C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\mpirt\libimalloc.dll'. 
'testhost.x86.exe' (Win32): Unloaded 'C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\mpirt\libimalloc.dll'
The thread 0x5494 has exited with code 2 (0x2).
The thread 0x5444 has exited with code 2 (0x2).
The thread 0x7cbc has exited with code 2 (0x2).
The thread 0x3304 has exited with code 2 (0x2).
The thread 0x60cc has exited with code 2 (0x2).
The thread 0x27b0 has exited with code 2 (0x2).
The thread 0xa74 has exited with code 2 (0x2).
The thread 0x4ec4 has exited with code 2 (0x2).
The thread 0x620c has exited with code 2 (0x2).
The thread 0x4108 has exited with code 2 (0x2).
The thread 0x7038 has exited with code 2 (0x2).
The thread 0x360c has exited with code 2 (0x2).
The thread 0x2538 has exited with code 2 (0x2).
The thread 0x52b4 has exited with code 2 (0x2).
The thread 0x3ee0 has exited with code 2 (0x2).
The thread 0x1e4c has exited with code 2 (0x2).
The thread 0x528 has exited with code 2 (0x2).
The thread 0x11bc has exited with code 2 (0x2).
The thread 0x68ac has exited with code 2 (0x2).
The thread 0x74e4 has exited with code 2 (0x2).
The thread 0x22b8 has exited with code 2 (0x2).
The thread 0x27d0 has exited with code 2 (0x2).
The program '[6832] testhost.x86.exe' has exited with code 2 (0x2).

 

I would be happy if someone could point me in the right direction.

0 Kudos
5 Replies
FortranFan
Honored Contributor III
1,269 Views

Does a unit test written in Fortran of your 'test_mkl' subroutine work as you expect?

0 Kudos
Julian_H_
Beginner
1,269 Views

FortranFan wrote:

Does a unit test written in Fortran of your 'test_mkl' subroutine work as you expect?

Yes it works in general. I created allready several tests all working fine. I just have a few test examples where I need to solve an equation system, for this I am using the MKL library and only then its not working. Not in the minimal example but in one of my own ones the phase=11 passed and the phase=22 is not passing. In the example I posted also phase=11 is failing. To be sure hat the example in general is working (without C#) I simply created a fortran PROGRAM and from there the test function is called successfully and the MKL solver executed proper way. I was thinking that maybe some *.dlls needed by the MKL library are not loaded and checked with the dependency walker which *.dlls have to be present but this also did not help.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,269 Views

Why is your application using the Intel Redistributables from the ia32_win folder instead of intel64_win folder?

Jim Dempsey

0 Kudos
Julian_H_
Beginner
1,269 Views

jimdempseyatthecove (Blackbelt) wrote:

Why is your application using the Intel Redistributables from the ia32_win folder instead of intel64_win folder?

Jim Dempsey

Because the *.dll is build ia32.

 

I was able to solve the problem. The *.dlls mkl_avx2.dll and mkl_vml_avx2.dll were missing. I checked again the *.dlls the mkl calls need but this time I did not use the dependency walker to check. I used my Fortran Programm and checked in Visual Studio which *.dlls are loaded while debugging.

'ProgramTestMKL.exe' (Win32): Loaded 'C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.4.245\windows\redist\ia32_win\mkl\mkl_avx2.dll'. Module was built without symbols.
'ProgramTestMKL.exe' (Win32): Loaded 'C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.4.245\windows\redist\ia32_win\mkl\mkl_vml_avx2.dll'. Module was built without symbols.

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,269 Views

The folder containing MKL DLLs is not added to PATH when you install MKL; you need to do it manually.

0 Kudos
Reply