Use threads and define local variables

Hi,

I solve an optimization problem using parallel threads. I make all the parameters local, so that the computer does not take parameter values from other threads. However, I call another procedure in the main procedure. Since the parameters are all local, the called procedure does not recognize them. The error says "undefined symbols".

I wonder if there is a solution to my problem (assuming someone understands my problem, my description itself seems like a puzzle). Any input or help is greatly appreciated!

Best,

Laura

 

5 Answers



0



If you can come up with a toy example that conveys the logic of the program, that will help.

Am I correct to assume you do not need the parameter values until all of the threads are done? In most cases, your procedure would return any data that you need after its calculation is finished in the retp statement. Is there a reason you cannot return the parameter values in this manner?

aptech

1,773


0



Here is a simple version of my program. I am running p6 with threads. I made b local in p6, and b is used in uc. The program won't run because of that.

threadbegin; r1 = p6(1,5); threadend;
threadbegin; r2 = p6(6,10); threadend;
threadjoin;

proc p6(ss,en);
local a, b, c;
   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a);
    endfor;
retp(c);
endp;

proc uc(x);
   y=x+b;
retp(y);
endp;

Thank you!



0



The answer is to add b as an input to the procedure uc, like this:

proc uc(x, b);
local y;
   y=x+b;
retp(y);
endp;

Which, of course, means you also need to add b to the input of procedure uc in your procedure p6 like this:

proc p6(ss,en);
local a, b, c;
   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a, b);
    endfor;
retp(c);
endp;

A short explanation of 'scope'
Procedures can see 'global' variables and their own 'local' variables only. Procedures cannot see symbols that are 'local' to a procedure that called it. For example the code below:

b = 7;

outerProc();

proc (0) = outerProc();
local b;
   b = 23;
   innerProc();
endp;

proc (0) = innerProc();
   print b;
endp;

will print out:

   7.0000000

This is because it cannot see the b that is local to outerProc. It can ONLY see the global b.

When you pass a variable into a new procedure, then that procedure has its own 'local' version of b. So if we changed to code snippet above, to this:

b = 7;

outerProc();

proc (0) = outerProc();
local b;
   b = 23;
   innerProc(b);
endp;

proc (0) = innerProc(b);
   print b;
endp;

This time the code would print out:

   23.000000

because innerProc now has its own local copy of b that was passed in to it.

For reference, here is the full version of the modified program from the previous post:

threadbegin; r1 = p6(1,5); threadend;
threadbegin; r2 = p6(6,10); threadend;
threadjoin;

proc p6(ss,en);
local a, b, c;

   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a, b);
   endfor;

retp(c);
endp;


proc uc(x, b);
   local y;
   y=x+b;
retp(y);
endp;

aptech

1,773


0



Thank you so much for your reply. It make sense, however, I can not add b into procedure uc. Because uc is called in another procedure GSS:

a=GSS(&uc,0,3);

GSS finds the number in the range of 0 and 3 that maximizes the returned value from uc. For this reason, I can only feed uc one variable.

I hope it makes sense. Do you have a suggestion in this case?

Thank you for help!!

Laura



0



The best answer, unless I am not understanding something about the structure of your code, is to change make the uc statmement take b as a second input and to then also add that as an input to the procedure GSS. This will make following the flow of your code more straightfoward.

However, if uc is just a one-liner, you can make it a GAUSS Function, fn instead. Here is an example:

threadbegin; r1 = p6(1,5); threadend;
threadbegin; r2 = p6(6,10); threadend;
threadjoin;

proc p6(ss,en);
local a, b, c;
fn uc(x) = x+b;

   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a);
   endfor;

retp(c);
endp;

GAUSS Functions do not have a separate scope, so the function uc will see whatever is in-scope at the place that it is called. In this case, it will see the local b inside of p6.

aptech

1,773

Your Answer

5 Answers

0

If you can come up with a toy example that conveys the logic of the program, that will help.

Am I correct to assume you do not need the parameter values until all of the threads are done? In most cases, your procedure would return any data that you need after its calculation is finished in the retp statement. Is there a reason you cannot return the parameter values in this manner?

0

Here is a simple version of my program. I am running p6 with threads. I made b local in p6, and b is used in uc. The program won't run because of that.

threadbegin; r1 = p6(1,5); threadend;
threadbegin; r2 = p6(6,10); threadend;
threadjoin;

proc p6(ss,en);
local a, b, c;
   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a);
    endfor;
retp(c);
endp;

proc uc(x);
   y=x+b;
retp(y);
endp;

Thank you!

0

The answer is to add b as an input to the procedure uc, like this:

proc uc(x, b);
local y;
   y=x+b;
retp(y);
endp;

Which, of course, means you also need to add b to the input of procedure uc in your procedure p6 like this:

proc p6(ss,en);
local a, b, c;
   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a, b);
    endfor;
retp(c);
endp;

A short explanation of 'scope'
Procedures can see 'global' variables and their own 'local' variables only. Procedures cannot see symbols that are 'local' to a procedure that called it. For example the code below:

b = 7;

outerProc();

proc (0) = outerProc();
local b;
   b = 23;
   innerProc();
endp;

proc (0) = innerProc();
   print b;
endp;

will print out:

   7.0000000

This is because it cannot see the b that is local to outerProc. It can ONLY see the global b.

When you pass a variable into a new procedure, then that procedure has its own 'local' version of b. So if we changed to code snippet above, to this:

b = 7;

outerProc();

proc (0) = outerProc();
local b;
   b = 23;
   innerProc(b);
endp;

proc (0) = innerProc(b);
   print b;
endp;

This time the code would print out:

   23.000000

because innerProc now has its own local copy of b that was passed in to it.

For reference, here is the full version of the modified program from the previous post:

threadbegin; r1 = p6(1,5); threadend;
threadbegin; r2 = p6(6,10); threadend;
threadjoin;

proc p6(ss,en);
local a, b, c;

   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a, b);
   endfor;

retp(c);
endp;


proc uc(x, b);
   local y;
   y=x+b;
retp(y);
endp;
0

Thank you so much for your reply. It make sense, however, I can not add b into procedure uc. Because uc is called in another procedure GSS:

a=GSS(&uc,0,3);

GSS finds the number in the range of 0 and 3 that maximizes the returned value from uc. For this reason, I can only feed uc one variable.

I hope it makes sense. Do you have a suggestion in this case?

Thank you for help!!

Laura

0

The best answer, unless I am not understanding something about the structure of your code, is to change make the uc statmement take b as a second input and to then also add that as an input to the procedure GSS. This will make following the flow of your code more straightfoward.

However, if uc is just a one-liner, you can make it a GAUSS Function, fn instead. Here is an example:

threadbegin; r1 = p6(1,5); threadend;
threadbegin; r2 = p6(6,10); threadend;
threadjoin;

proc p6(ss,en);
local a, b, c;
fn uc(x) = x+b;

   for i (ss,en,1);
      a=i+1;
      b=i+4;
      c=uc(a);
   endfor;

retp(c);
endp;

GAUSS Functions do not have a separate scope, so the function uc will see whatever is in-scope at the place that it is called. In this case, it will see the local b inside of p6.


You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.