Menu

Writing MAT with fortran

Help
bles
2024-05-06
2025-04-07
  • bles

    bles - 2024-05-06

    Thank you for your effort in the MATIO library and I have successfully compiled this library using ifort and gcc as well as a gfortran/gcc on ALMAlinux 9.3. I did not manage to compile it with icc and ifort (newest API version).

    I have a test program for writing a MAT file but I can't get this to work and I guess my knowledge of c is reason for this but I have not found a solution for this (after extensive search).

    The test program :
    ++++++++++++++++++++++++++++++++++++++++++

    program test_mat_file
        use, intrinsic :: iso_c_binding
        implicit none
    
        type(c_ptr) :: matfile
        character(*), parameter :: filename = 'zzz.mat'
    
        REAL(8), target, dimension(10) :: d
        integer :: i
        type(c_ptr) :: matvar
        integer(c_size_t), dimension(2) :: dims
    
        INTEGER,PARAMETER :: MAT_FT_MAT4      = 16
        INTEGER,PARAMETER :: MAT_FT_MAT5      = 256
        INTEGER,PARAMETER :: MAT_FT_MAT73     = 512
    
        INTEGER,PARAMETER :: COMPRESSION_NONE = 0
        INTEGER,PARAMETER :: COMPRESSION_ZLIB = 1
    
        INTEGER,PARAMETER :: MAT_T_INT32      =  5
        INTEGER,PARAMETER :: MAT_T_SINGLE     =  7
        INTEGER,PARAMETER :: MAT_T_DOUBLE     =  9
    
        INTEGER,PARAMETER :: MAT_C_CHAR       =  4
        INTEGER,PARAMETER :: MAT_C_DOUBLE     =  6
        INTEGER,PARAMETER :: MAT_C_SINGLE     =  7
        INTEGER,PARAMETER :: MAT_C_INT32      = 12
        INTEGER,PARAMETER :: MAT_C_UINT32     = 13
    
        interface
            function Mat_CreateVer(filename, header, mat_file_ver) bind(c, name="Mat_CreateVer")
                import :: c_int, c_ptr , c_char
                type(c_ptr) :: Mat_CreateVer
                character(c_char), intent(in) :: filename(*)
                character(c_char), intent(in) :: header(*)
                integer(c_int), value :: mat_file_ver
            end function Mat_CreateVer
    
            function Mat_VarCreate(name, class_type, data_type, rank, dims, data , opt) bind(c, name="Mat_VarCreate")
                import :: c_int, c_ptr , c_char, c_size_t
                type(c_ptr) :: Mat_VarCreate
                character(c_char), intent(in) :: name(*)
                integer(c_int), value :: class_type, data_type, rank
                integer(c_size_t), intent(in) :: dims(*)
                type(c_ptr), intent(in) :: data
                integer(c_int), value :: opt
            end function Mat_VarCreate
    
            subroutine Mat_VarWrite(matfp, matvar, compression) bind(c, name="Mat_VarWrite")
                import :: c_int, c_ptr
                type(c_ptr), intent(in) :: matfp, matvar
                integer(c_int), value :: compression
            end subroutine Mat_VarWrite
    
            subroutine Mat_Close(mat) bind(c, name="Mat_Close")
                import :: c_int, c_ptr
                type(c_ptr), value :: mat
            end subroutine Mat_Close
        end interface
    
        d = [(i, i = 1, 10)]
        matfile = Mat_CreateVer(filename, 'HEADERSTRING',MAT_FT_MAT4)
        dims = [size(d , 1), 1]
        matvar = Mat_VarCreate('reeks',MAT_C_DOUBLE, MAT_T_DOUBLE, 2 , dims, c_loc(d), 0)
    
        call Mat_VarWrite(matfile,matvar, COMPRESSION_NONE )
        call Mat_Close(matfile)
    
    end program test_mat_file
    

    +++++++++++++++++++++++++
    COMPILING & RUNNING :

    $ gfortran -o xx ww.f90 -I/apps/MATIO/matio-1.5.26/include -L/apps/MATIO/matio-1.5.26/lib -lmatio
    $ xx

    Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

    Backtrace for this error:
    0 0x2B66C14266D7
    1 0x2B66C1426D1E
    2 0x2B66C1EB93FF
    3 0x2B66C1296FF1
    4 0x400905 in MAIN__ at ww.f90:?
    Segmentation fault

    or with ifort

    $ xx
    forrtl: severe (174): SIGSEGV, segmentation fault occurred
    Image PC Routine Line Source
    xx 0000000000405AEA Unknown Unknown Unknown
    libc.so.6 000014AE66E54DB0 Unknown Unknown Unknown
    libc.so.6 000014AE66E94E06 ftello Unknown Unknown
    libmatio.so.11.1. 000014AE6732320B Mat_GetDir Unknown Unknown
    libmatio.so.11.1. 000014AE67323151 Mat_VarWrite Unknown Unknown
    xx 0000000000404C3E MAIN__ 66 ww.f90
    xx 0000000000404AE2 Unknown Unknown Unknown
    libc.so.6 000014AE66E3FEB0 Unknown Unknown Unknown
    libc.so.6 000014AE66E3FF60 __libc_start_main Unknown Unknown
    xx 00000000004049E9 Unknown Unknown Unknown

    My main question - is this an error in compiling or is there something wrong in the fortran code calling C-routines?

    And excuse me for the typo in the title..

     

    Last edit: tbeu 2025-04-07
  • tbeu

    tbeu - 2024-05-15

    Thanks for your efforts and report. Unfortunately Fortran interface is not tested. I gave up on https://github.com/tbeu/matio/issues/51 as I failed. (That#s why it says "help wanted".) I would appreciate if we could set up a CI stage to build and run the Fortran interface.

     
  • bles

    bles - 2025-04-07

    it is working now, see the correct code below:

    program test_mat_file
      use, intrinsic :: iso_c_binding
      implicit none
    
      type(c_ptr) :: matfile
      character(kind=c_char, len=*), parameter :: filename = 'zzz.mat'//c_null_char
      character(kind=c_char, len=*), parameter :: header   = 'HEADERSTRING'//c_null_char
      character(kind=c_char, len=*), parameter :: varname  = 'reeks'//c_null_char
    
      real(c_double), target, dimension(1000) :: d
      integer :: i
      type(c_ptr) :: matvar
      integer(c_size_t), dimension(2) :: dims
    
      integer, parameter :: MAT_FT_MAT5      = 256
      integer, parameter :: COMPRESSION_NONE = 0
      integer, parameter :: MAT_T_DOUBLE     = 9
      integer, parameter :: MAT_C_DOUBLE     = 6
    
      interface
        function Mat_CreateVer(filename, header, mat_file_ver) bind(c, name="Mat_CreateVer")
          import :: c_int, c_ptr, c_char
          type(c_ptr) :: Mat_CreateVer
          character(kind=c_char), intent(in) :: filename(*)
          character(kind=c_char), intent(in) :: header(*)
          integer(c_int), value :: mat_file_ver
        end function Mat_CreateVer
    
        function Mat_VarCreate(name, class_type, data_type, rank, dims, data, opt) bind(c, name="Mat_VarCreate")
          import :: c_int, c_ptr, c_char, c_size_t
          type(c_ptr) :: Mat_VarCreate
          character(kind=c_char), intent(in) :: name(*)
          integer(c_int), value :: class_type, data_type, rank
          integer(c_size_t), intent(in) :: dims(*)
          type(c_ptr), value :: data
          integer(c_int), value :: opt
        end function Mat_VarCreate
    
        subroutine Mat_VarWrite(matfp, matvar, compression) bind(c, name="Mat_VarWrite")
          import :: c_int, c_ptr
          type(c_ptr), value :: matfp
          type(c_ptr), value :: matvar
          integer(c_int), value :: compression
        end subroutine Mat_VarWrite
    
        subroutine Mat_Close(mat) bind(c, name="Mat_Close")
          import :: c_ptr
          type(c_ptr), value :: mat
        end subroutine Mat_Close
      end interface
    
      ! Initialize data
      do i = 1,1000
         d(i) = real(i, kind=c_double)
      end do
    
      ! Create MAT file
      matfile = Mat_CreateVer(filename(1:1), header(1:1), MAT_FT_MAT5)
      if (.not. c_associated(matfile)) then
        print *, "Error: Could not create MAT file."
        stop
      end if
    
      ! Define dimensions
      dims = [size(d, 1, kind=c_size_t), 1_c_size_t]
    
      ! Create MAT variable
      matvar  = Mat_VarCreate(varname(1:1), MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, c_loc(d), 0)
      if (.not. c_associated(matvar)) then
        print *, "Error: Mat_VarCreate returned a null pointer."
        call Mat_Close(matfile)
        stop
      end if
    
      ! Write MAT variable to file
      call Mat_VarWrite(matfile, matvar, COMPRESSION_NONE)
    
      ! Close MAT file
      call Mat_Close(matfile)
    
      print *, "MAT file successfully written."
    
    end program test_mat_file
    
     

    Last edit: tbeu 2025-04-07
  • tbeu

    tbeu - 2025-04-07

    Thanks for reporting. I notice that the test_mat_file.f90 does not used the provided fartran interface in ./matio/src/fortran at all and instead uses own binding interfaces.

     

Log in to post a comment.

MongoDB Logo MongoDB