04 Jun 2008 09:49 AM |
|
Hi everyone,
I am new to IDL, and am trying to understand how IDL_IDLBridge works. Because of how little experience I have had, the examples don't make too much sense to me. I am getting some strange behavior when I try to call procedures that I have made through the bridge object. For example, here is some code that I have written to test out functionality
pro plotbridge
oBridge0 = OBJ_NEW('IDL_IDLBridge')
oBridge1 = OBJ_NEW('IDL_IDLBridge')
oBridge2 = OBJ_NEW('IDL_IDLBridge')
oBridge3 = OBJ_NEW('IDL_IDLBridge')
oBridge0->Execute, "@plot0", /NOWAIT
oBridge1->Execute, "@plot1", /NOWAIT
while(oBridge0->Status() ne 0) do wait, 0.5
OBJ_DESTROY, oBridge0
while(oBridge1->Status() ne 0) do wait, 0.5
OBJ_DESTROY, oBridge1
end
pro plot0
x = sin(2 * !PI / 100 * findgen(1000000))
window, xsize = 1024, ysize = 768
plot, x, psym = 3
end
pro plot1
x = randomu(1,1000000)
window, 1, xsize = 1024, ysize = 768
plot, x, psym = 3
end
It always exits with an error, "Attempt to call undefined procedure/function"
My goal is to have this program open two windows and plot the data sets asynchronously. Any help would be greatly appreciated. Also, could anyone tell me about the performance of IDL_IDLBridge. I plan to use it to emulate threading, but would like to know about the overhead each bridge requires.
|
|
|
|
Deleted User New Member
Posts:  
04 Jun 2008 09:49 AM |
|
Sorry, the code should read as follows:
pro plotbridge
oBridge0 = OBJ_NEW('IDL_IDLBridge')
oBridge1 = OBJ_NEW('IDL_IDLBridge')
oBridge0->Execute, "plot0", /NOWAIT
oBridge1->Execute, "plot1", /NOWAIT
while(oBridge0->Status() ne 0) do wait, 0.5
OBJ_DESTROY, oBridge0
while(oBridge1->Status() ne 0) do wait, 0.5
OBJ_DESTROY, oBridge1
end
pro plot0
x = sin(2 * !PI / 100 * findgen(1000000))
window, xsize = 1024, ysize = 768
plot, x, psym = 3
end
pro plot1
x = randomu(1,1000000)
window, 1, xsize = 1024, ysize = 768
plot, x, psym = 3
end
|
|
|
|
Deleted User New Member
Posts:  
04 Jun 2008 09:49 AM |
|
A few points:
1. As you already discovered, the "Execute" call in your example needs to call "plot0" and "plot1", not "@plot0" and "@plot1".
2. "Attempt to call undefined procedure/function" probably means that there is no file 'plot0.pro' or 'plot1.pro' in your IDL Search path. It is easy to forget that an IDL_IDLBridge child process does not inherit any "state" from the parent IDL process which is calling it. This particularly means that the child process knows nothing about what is compiled and loaded in the parent process, nor does it share any current working directory or search path other than is what is set in user's preferences (or O.S. shell environment variables).
3. Here are the steps for the workaround that I tested based on an assumption that you wanted the above 3 procedures all in one file.
3a) First, I put the main procedure PLOTBRIDGE at the bottom of the file, following preferred IDL coding connventions. I then saved the file in one of my persistent IDL Search Path directories as 'plotbridge.pro'.
3b) I then added the following call right before the first current 'Execute' statement of each bridge object:
oBridge->Execute, "resolve_routine, 'PLOTBRIDGE'"That got the PLOT0 and PLOT1 subroutines in 'plotbridge.pro' to load in each of my child processes. That solved the "Attempt to call undefined procedure" error.
4) If you are thinking about using IDL_IDLBridge for threading, then you should be practising using the IDL_IDLBridge::OnCallback method. See the simple example in Online Help about this. Your current approach is using 'IDL_IDLBridge::Status' to block the parent process right after you issued IDL_IDLBridge::Execute calls with /NOWAIT to prevent blocking, so it is a little illogical. (Probably you already know that.)
5) Efficiency you will have to measure. The IDL_IDLBridge uses system shared memory to pass some of its data and messages between processes. I am not sure, but I believe that shared memory is not the most efficient way to pass very large arrays, so it is sometimes worthwhile to compare passing large data blocks via parameters in 'Execute' calls to passing the same data via the file system. Of course, there is also a new IDL process initialization cost at the very beginning of object creation. Other than those two areas, however, the various IDL processes work independently and the children should be as efficient as the parent.
James Jones
|
|
|
|
Deleted User New Member
Posts:  
03 Nov 2009 10:54 AM |
|
Yeah, using callback makes more sense if the while loops of waiting in the main procedure are only for destroying bridges safely.
It would be nice to see examples how two IDL_IDLBridge child processes can communicate and synchronize with each other. Say, after x = sinc(2*!PI/100*findgen(1000000)) is done in plot0, let it wait until x = randomu(1,1000000) and window 1 are done in plot1. Let plot1 then wait until plot0 completes the whole drawing.
Is a semaphore needed in this case? What are other sychronization approaches available in IDL?
Weidong
[QUOTE]jjayjones@comcast.net wrote
A few points: 1. As you already discovered, the "Execute" call in your example needs to call "plot0" and "plot1", not "@plot0" and "@plot1". 2. "Attempt to call undefined procedure/function" probably means that there is no file 'plot0.pro' or 'plot1.pro' in your IDL Search path. It is easy to forget that an IDL_IDLBridge child process does not inherit any "state" from the parent IDL process which is calling it. This particularly means that the child process knows nothing about what is compiled and loaded in the parent process, nor does it share any current working directory or search path other than is what is set in user's preferences (or O.S. shell environment variables). 3. Here are the steps for the workaround that I tested based on an assumption that you wanted the above 3 procedures all in one file. 3a) First, I put the main procedure PLOTBRIDGE at the bottom of the file, following preferred IDL coding connventions. I then saved the file in one of my persistent IDL Search Path directories as 'plotbridge.pro'. 3b) I then added the following call right before the first current 'Execute' statement of each bridge object:
oBridge->Execute, "resolve_routine, 'PLOTBRIDGE'"
That got the PLOT0 and PLOT1 subroutines in 'plotbridge.pro' to load in each of my child processes. That solved the "Attempt to call undefined procedure" error. 4) If you are thinking about using IDL_IDLBridge for threading, then you should be practising using the IDL_IDLBridge::OnCallback method. See the simple example in Online Help about this. Your current approach is using 'IDL_IDLBridge::Status' to block the parent process right after you issued IDL_IDLBridge::Execute calls with /NOWAIT to prevent blocking, so it is a little illogical. (Probably you already know that.) 5) Efficiency you will have to measure. The IDL_IDLBridge uses system shared memory to pass some of its data and messages between processes. I am not sure, but I believe that shared memory is not the most efficient way to pass very large arrays, so it is sometimes worthwhile to compare passing large data blocks via parameters in 'Execute' calls to passing the same data via the file system. Of course, there is also a new IDL process initialization cost at the very beginning of object creation. Other than those two areas, however, the various IDL processes work independently and the children should be as efficient as the parent. James Jones[/QUOTE]
|
|
|
|