X
PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 14 Sep 2015 01:17 AM by  anon
Sharing Memory: Structures
 2 Replies
Sort:
You are not authorized to post a reply.
Author Messages

anon



New Member


Posts:6
New Member


--
14 Sep 2015 01:17 AM
    Hello, I'm trying to figure out the proper syntax for assigning a structure to shared memory. The SHMMAP documentation (http://www.exelisvis.com/docs/SHMMAP.html) states: "The array can be of any type except pointer, object reference, or string. (Structure types are allowed as long as they do not contain any pointers, object references, or strings.)" But there are no examples for sharing structures. My basic method for initializing shared memory is: ShFixVardim = size(ShFixVar, /dim) SHMMAP, 'SHFIXVARMEM', /FLOAT, DIMENSION=ShFixVardim SHFIXVARDATA = SHMVAR('SHFIXVARMEM') SHFIXVARDATA[0] = ShFixVar But the dimensions of the structure are not returned (whatever those dimensions may be?). I am trying to share a structure with this basic setup (simplified): x=INDGEN(1,3,8,/FLOAT) y=INDGEN(2,3,12,/FLOAT) z=INDGEN(3,3,4,/FLOAT) STRUCT = {x:x,y:y,z:z} is this possible? Thanks for any help.

    Deleted User



    New Member


    Posts:81
    New Member


    --
    24 Sep 2015 05:13 PM
    Hello Kenneth, If you wanted to get the dimensions of the individual field elements in the structure, you could do something like this: IDL> x=FINDGEN(1,3,8) IDL> y=FINDGEN(2,3,12) IDL> z=FINDGEN(3,3,4) IDL> STRUCT = {x:x,y:y,z:z} IDL> ntags = n_tags(struct) IDL> slist = list() IDL> for i=0, ntags-1 do slist.add, size(struct.(i), /dim) IDL> slist [ [1, 3, 8], [2, 3, 12], [3, 3, 4] ] However, for creating a structure in shared memory, you don't need to explicitly know the dimensions. Instead, you can just pass the structure itself to the TEMPLATE keyword for SHMMAP, for example: IDL> shmmap, 'MYSEG', template=struct IDL> mystruct = shmvar('MYSEG') IDL> mystruct.x = newxvals I hope this can be helpful. Kind regards,

    Deleted User



    New Member


    Posts:6
    New Member


    --
    08 Oct 2015 10:37 PM
    Thank you for your response Jim. I wanted to follow up with what I determined to be my best possible solution to this problem. The real problem was that I needed to know the dimensions of the structure in order to map the structure to shared memory for child processes using IDL to IDL bridges. This means that for Shmmap to run in the child process I would need access to the structure in that process in order to use it as a template, negating the purpose. What I did to solve this issue is to create an [3,n] matrix to store the dimensions of all the sub-matrices within my structure. ;Test Structure is x.(n).(n) for subset array y={one0:fltarr(5,3,2), one1:fltarr(5,1,1), one2:fltarr(5,3,8), one3:fltarr(5,3,2)} z={two0:fltarr(2,3,1895), two1:fltarr(2,3,1), two2:fltarr(2,3,5)} m={three0:fltarr(3,3,20), three1:fltarr(3,3,1), three2:fltarr(3,3,2)} x=create_struct('t1',y, 't2',z, 't3',m) I created a function which pulled apart the dimensions of my structure (I know the general layout of my structure, so this code would need to be modified to be more inclusive of different structure layouts). ;Create template for sharing structures in memory across multiple threads function templ_str, in_array COMPILE_OPT IDL2 ;build and return a template strt = list() print, n_tags(in_array) for i=0, n_tags(in_array)-1 do begin for r=0, n_tags(in_array.(i))-1 do begin tmp_dim = size(in_array.(i).(r), /dim) case_test = n_elements(tmp_dim) CASE case_test OF 3: strt.add, [size(in_array.(i).(r),/dim)] 2: strt.add, [(size(in_array.(i).(r),/dim)),1] 1: strt.add, [(size(in_array.(i).(r),/dim)),1,1] ENDCASE endfor endfor strt = strt.ToArray(/transpose, type='ULONG') ; Array which describes structure level and dimensions return, strt end I shared the resulting array describing the template of the structure in shared memory and sent to child processes via my standard method. Then I ran a Threads->execute in the child process to build the template back into a properly sized structure for use as a template for i = 0 , n_elements(oThreads )-1 do oThreads[i]->Execute, "void = build_str(threaderror=threaderror)" function build_str, threaderror=threaderror COMPILE_OPT IDL2 threaderror = 0 ; catch error block catch, errno if (errno ne 0) then begin catch, /cancel help, /last_message, output=errText threaderror = errText return, threaderror endif ;Reconstruct base structure for template StructDATA = SHMVAR('StructMEM') ; structure template array n_lvls = StructDATA[0,uniq(StructDATA[0,*])] templ_str = {} ; !NULL holding variable for concatenation foreach lvl, n_lvls do begin sub_str = {} ; !NULL holding variable to make arrays in this_lvl = StructDATA[*,where(StructDATA[0,*] EQ lvl)] for i=0, n_elements(this_lvl[0,*])-1 do begin mArr = this_lvl[*,i] sub_str = create_struct(sub_str, 'xEMn'+strtrim(i,2), fltarr(mArr[0],mArr[1],mArr[2])) endfor templ_str = create_struct(templ_str, 'xEM'+strtrim(lvl,2),sub_str) endforeach ;Place template for structure in each child process SHMMAP, 'MainSTRUCT', TEMPLATE=templ_str templ_str = 0 return, 1 end From there I could use SHMVAR to pull in the structure where it was needed for other functions in the child process. Side note: I use this for error checking, for i = 0 , n_elements( oThreads )-1 do begin error_ret = oThreads[i]->Getvar('threaderror') if error_ret[0] then begin print, error_ret void = dialog_message(error_ret, /error) stop endif endfor Having said that, additional research turned up Slug's guide to IDL (http://slugidl.pbworks.co...9/Child%20Processes) that has a program, struct_pass.pro which is supposed to send a structure to a child process which may be able to achieve template sending more easily. I didn't test it however. Thanks for the help!
    You are not authorized to post a reply.