- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>> 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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page