Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner

MKL sjacobix void pointer problem

Hi there,

I am having problems calling the sjacobix MKL subroutine when passing a void pointer to my resource type for use in my cost function.  I have tried following the example program in which the final dummy argument of the extended_powell is  type(my_data) :: user_data, and the actual argument is the address of the resource type with a pass by value directive %VAL(LOC(m_data))

res = sjacobix(cost_function, n, m, fjac, x, eps(1), %val(loc(this)))

    subroutine cost_function(m, n, x, f, myARMA)
    
        use MKLMatrix_module
        use ARMA_data
        use iso_c_binding
    
        integer :: m                            ! dimension of f
        integer :: n                            ! dimension of x
        real(WP), dimension(n)  :: x            ! input values
        real(WP), dimension(m)  :: f            ! output values (residuals)
        type(ARMA)              :: myARMA         ! ARMA model (& Training Data)

        ...

    end subroutine cost_function

This doesn't compile and I receive the following error diagnostic...

error #7065: The characteristics of dummy argument 5 of the associated actual procedure differ from the characteristics of dummy argument 5 of the dummy procedure.

I have been trying to find a workaround and have managed to compile by passing the actual argument int(loc(this),c_intptr_t) to an integer dummy argument integer(c_intptr_t) :: ipRes.  I have tried to associate a pointer to my own resource type type(ARMA) to this address via an iso_c_binding type(c_ptr) and although this seems to pass the resource to my cost function, this seems to be corrupting the program stack.  My cost function & calling code now look something like this...

res = sjacobix(cost_function, n, m, fjac, x, eps(1), int(loc(this),c_intptr_t))
    subroutine cost_function(m, n, x, f, ipRes)
    
        use MKLMatrix_module
        use ARMA_data
        use iso_c_binding
    
        integer :: m                            ! dimension of f
        integer :: n                            ! dimension of x
        real(WP), dimension(n)  :: x            ! input values
        real(WP), dimension(m)  :: f            ! output values (residuals)
        integer(c_intptr_t)     :: ipRes        ! int(void*) to resources
        type(c_ptr)             :: pRes         ! void* to resources
        type(ARMA),pointer      :: pARMA        ! ARMA model (& Training Data)

        ! associate type with raw pointer address ~ 
        pRes = transfer(ipRes,pRes)             ! convert raw 4 byte address into a c_ptr
        call c_f_pointer(pRes,pARMA)            !  associate pARMA with  c_ptr
        ...
    end subroutine cost_function

 

Please could somebody advise me on what to try next?  Additional info: Package ID: w_fcompxe_2015.2.179

0 Kudos
3 Replies
Highlighted

I think you want to go back

I think you want to go back to passing %VAL(LOC(data)) and then do this:

subroutine cost_function(m, n, x, f, ipRes)

    use MKLMatrix_module
    use ARMA_data
    use iso_c_binding

    integer :: m                            ! dimension of f
    integer :: n                            ! dimension of x
    real(WP), dimension(n)  :: x            ! input values
    real(WP), dimension(m)  :: f            ! output values (residuals)
    integer(c_intptr_t)     :: ipRes        ! int(void*) to resources
    type(ARMA),pointer      :: pARMA        ! ARMA model (& Training Data)

    ! associate type with raw pointer address ~ 
    call c_f_pointer(C_LOC(ipRes),pARMA)            !  associate pARMA with  c_ptr
    ...
end subroutine cost_function

 

Retired 12/31/2016
0 Kudos
Highlighted
Beginner

Thanks Steve,

Thanks Steve,

I knew using transfer was the wrong thing to do.  I thought c_loc would have returned the address of the register holding the dummy which was being past.  Here it is casting the value of the scalar dummy into an address of type c_ptr.

On a side note, it looks like the my memory issue was actually caused by something else.

0 Kudos
Highlighted

>> I thought c_loc would have

>> I thought c_loc would have returned the address of the register holding the dummy

On IA32 and Intel64 processors, registers do not have addresses. This said, depending on the calling convention (for architecture), the DUMMY variable being passed in register, may/will have stack space reserved for it in the event that the register will have to be saved and restored. This stack reserve space will have an address (but the contents are not initially written). The compiler "should" flush the register to RAM in the event you take the LOC/C_LOC of the dummy but some assumptions by the programmer may circumvent this (e.g. assuming memory order on stack of dummys m,n,x,f,ipRes)

Also, a limited number of first arguments are capable of being passed by register. Do not rely on a specific number as this is subject to change.

Jim Dempsey

0 Kudos