cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Browse apps to extend the software in the new JMP Marketplace
Choose Language Hide Translation Bar
Jackie_
Level VI

Optimize the computation

Hi,

 

I have a jsl code to compute the radial distance from the center of the wafer. The data table XYCoord has X, Y and wafer id cols.
It calculates the distance and adds a distance column 1mm from the center to the table
Currently, with 656k rows, it takes > 3- 4min for the process to finish, which is way too much.
Is there a way to optimize and make it faster? 
 
10 REPLIES 10
txnelson
Super User

Re: Optimize the computation

I attempted to execute your script against the data you provided, and it failed.  The first item that I attempted to correct was stray "=" on various lines in the script.

        Lines, 23, 25, 106, 139 and 152 all had single "=" on them

Next the error messages turned to what appears to be columns that apparently are being cleaned up from previous executions, but in the table you provided they are not there, so the script fails.

        RadiusDieCenter, xcentering, ycentering, radius rounded 1mm, radius rounded 0.51mm

I added Try() around the offending lines

The column X Coord on line 21 is referenced but does not exist in the data table

     I changed it to U1_x assuming that is the x coordinate column for the run

The code then ran without error in 2 minutes and 12 seconds, however I do not know if the results are the correct results.  The Xcentering and Ycentering columns are all zeros.  Is this what is expected?

 

txnelson_0-1725470182129.png

 

 

 

 

 

 

Jim
Jackie_
Level VI

Re: Optimize the computation

Hi Jim,

Yes that's correct. You can verify the results by plotting X and Y graph and highlight the 1mm col values. Wondering if this can be optimized further. I have corrected the errors in the above attached jsl file

txnelson
Super User

Re: Optimize the computation

What I see as what could be used to speed your processing up is to recode your script and remove the usage of Table Scripts as intermediate storage.

I ran a little test to check the efficiency of using a table variable vs. using a memory variable, and in my test, table variable method used 26 seconds to process, and the memory variable method took .5 seconds.

Look into using a global memory variable or creating a name space variable to save your interim calculations.  If you want to end up with the table variables having the final values, you just need to set them once at the end of your script.

Jim
Jackie_
Level VI

Re: Optimize the computation

That's great. Do you mind sharing Jim?

txnelson
Super User

Re: Optimize the computation

Here are the 2 test scripts I used

names default to here(1);
dt = new table("example");
dt << new table variable("test",42);
start = tick seconds();
dt=current data table();
for(i=1,i<=1000000,i++,
	x=num(dt<<get table variable("test"));
	x=x+1;
	dt << set table variable("test", x);
);

end = tick seconds();
show(end -start);
names default to here(1);
If(!isnamespace(t), t = new namespace("temp"));
start = tick seconds();
dt=current data table();
t:x=1;
for(i=1,i<=1000000,i++,
y = t:x;
y=y+1;
t:x=y;
);
end = tick seconds();

show(end -start);
Jim
robot
Level VI

Re: Optimize the computation

Hi @Jackie_ ,

The script recalculated several Col values on each loop.  Please try this:

 

end - start = 6.15000000002328;

 

Names Default To Here( 1 );
start = Tick Seconds();
dt = Current Data Table();
dt << Clear Column Selection;
Try( dt << delete columns( RadiusDieCenter ) );
Try(
	dt << delete columns( RadiusDieEdge );


	dt << delete columns( Xcentering );
	dt << delete columns( Ycentering );
	dt << delete columns( Radius Rounded 1mm );
	dt << delete columns( Radius Rounded 0.51mm );
	dt << delete columns( Radius Rounded 1mm );
);

z5Identifier = 1;
Xaxis = "U1_x";
Yaxis = "U1_y";
DieXSize = 1.160; //in mm
DieYSize = 0.810;//in mm

WaferColumns = N Items( Associative Array( As Column( Xaxis ) ) << Get Keys );
columnsRad = ((WaferColumns * DieXSize) / 2);
										
MaxRadiusEntry = 147;

	
				
dt << Set Table Variable( "DieXSize", DieXSize );
dt << Set Table Variable( "DieYSize", DieYSize );
dt << Set Table Variable( "MaxRadius", MaxRadiusEntry );


dt << begin data update;
				

xcoordmax = Col Maximum( As Column( Xaxis ) );
xcoordmin = Col Minimum( As Column( Xaxis ) );
ycoordmax = Col Maximum( As Column( Yaxis ) );
ycoordmin = Col Minimum( As Column( Yaxis ) );

					
New Column( "RadiusDieCenter",
	Formula( Sqrt( (Abs( (As Column( Xaxis ) - CenterXCoord) * DieXSize )) ^ 2 + Abs( ((As Column( Yaxis ) - CenterYCoord) * DieYSize) ) ^ 2 ) )
);
							
 

					  
New Column( "RadiusDieEdge",
	Formula(
		Sqrt(
			(Abs( (As Column( Xaxis ) - CenterXCoord) * DieXSize ) + Abs( DieXSize / 2 )) ^ 2 + (Abs(
				(As Column( Yaxis ) - CenterYCoord) * DieYSize
			) + Abs( DieYSize / 2 )) ^ 2
		)
	)
);
							


xcoordrange = xcoordmax - xcoordmin;
ycoordrange = ycoordmax - ycoordmin;
dt << Set Table Variable( "CenterXCoord", xcoordmin + xcoordrange / 4 );
dt << Set Table Variable( "CenterYCoord", ycoordmin + ycoordrange / 4 );
dt << Run Formulas;
xiter = Ceiling( Log( xcoordrange * 1600, 1.8 ) );
yiter = Ceiling( Log( ycoordrange * 1600, 1.8 ) );
maxiter = Max( xiter, yiter );



New Column( "Xcentering",
	Numeric,
	Formula(
		If( As Column( Xaxis ) > :CenterXCoord & :RadiusDieEdge > :MaxRadius,
			1,
			If( As Column( Xaxis ) < :CenterXCoord & :RadiusDieEdge > :MaxRadius,
				-1,
				0
			)
		)
	)
);

New Column( "Ycentering",
	Numeric,
	Formula(
		If( As Column( Yaxis ) > :CenterYCoord & :RadiusDieEdge > :MaxRadius,
			1,
			If( As Column( Yaxis ) < :CenterYCoord & :RadiusDieEdge > :MaxRadius,
				-1,
				0
			)
		)
	)
);


dt << end data update;

sum_x_centering = Col Sum( :Xcentering );
min_x_centering = Col Min( :Xcentering );
max_x_centering = Col Max( :Xcentering );
sum_y_centering = Col Sum( :Ycentering );
min_y_centering = Col Min( :Ycentering );
max_y_centering = Col Max( :Ycentering );

For( i = 1, i <= maxiter, i++, 



	centerx = Num( dt << Get Table Variable( "CenterXCoord" ) );
	centery = Num( dt << Get Table Variable( "CenterYCoord" ) );

	xcoordrange = xcoordrange / 1.8;
	ycoordrange = ycoordrange / 1.8;
	dt << Run Formulas;
	If( sum_x_centering > 0,
		dt << Set Table Variable( "CenterXCoord", centerx + xcoordrange );
		centerx = centerx + xcoordrange;
	,
		If( sum_x_centering < 0, 

			dt << Set Table Variable( "CenterXCoord", centerx - xcoordrange );
			centerx = centerx + xcoordrange;
					
		)
	);

	If( sum_y_centering > 0,
		dt << Set Table Variable( "CenterYCoord", centery + ycoordrange );
		centery = centery + ycoordrange;
	,
		If( sum_y_centering < 0, 

			dt << Set Table Variable( "CenterYCoord", centery - ycoordrange );
			centery = centery + ycoordrange;
					
		)
	);
				
	If( max_x_centering < 1 & min_x_centering > -1 & max_y_centering < 1 & min_y_centering > -1, 
					
		OldRadius = dt << Get Table Variable( "MaxRadius" );
		NewRadius = Num( OldRadius ) - 0.01;
		dt << Set Table Variable( "MaxRadius", Char( NewRadius ) );
		xcoordrange = xcoordmax - xcoordmin;
		ycoordrange = ycoordmax - ycoordmin;
		dt << Run Formulas;
		i = 1;
	);

	dt << Run Formulas;

);

New Column( "Radius Rounded 1mm", Numeric, "Continuous", Format( "Best", 12 ), Formula( Ceiling( :RadiusDieEdge ) ) );


end = Tick Seconds();

Show( end - start );
Jackie_
Level VI

Re: Optimize the computation

The results are incorrect @robot 

Jackie__0-1725479994782.png

Should be with my script

Jackie__0-1725480676319.png

 

jthi
Super User

Re: Optimize the computation

Quickly looking through the script there are most likely a lot of different optimizations which can be done but I'm a bit confused what you are calculating.

  • How is the center of wafer determined from this data?
  • Distance from center of wafer to which radius?
  • Does the whole die have to belong to the radii or just center?
-Jarmo
jthi
Super User

Re: Optimize the computation

Lots of assumptions made

/*""" Optimize the computation
author: jthi
date: 2024-09-05
url: https://community.jmp.com/t5/Discussions/Optimize-the-computation/m-p/795219
keywords/tags: [semiconductor,wafer,distance,matrix,die]

Description: Calculate distance from center of wafer (coordinates) to corner of die
"""*/

Names Default To Here(1);

dt_temp = Open("$DOWNLOADS/XYCoord.jmp");

die_width = 1.160;
die_height = 0.810;


dt = dt_temp << Summary(
	Group(:U1_x, :U1_y),
	Freq("None"),
	Weight("None"),
	Link to original data table(0),
	output table name("Coords")
);
dt << Delete Scripts(dt << Get Table Script Names);

// Use Update to join the distances back using U1_x and U1_y as linking ids
Close(dt_temp, no save); // Close as not needed for this demo


m_x = Column(dt, "U1_x") << get values;
m_y = Column(dt, "U1_y") << get values;


// Origo to 0, 0 and coordinates to "real" measures
// This most likely will require some adjustments but you know your data so you should be able to modify this as needed
xcoords = (m_x - Max(m_x) / 2) * die_width + die_width / 2;
ycoords = (m_y - Max(m_y) / 2) * die_height + die_height / 2;


// Distance from center to each of the corners of rectangle
// assumes that the "coordinate" is at the center of die
top_left = xcoords - die_width / 2 || ycoords + die_height / 2;
bottom_left = xcoords - die_width / 2 || ycoords - die_height / 2;
top_right = xcoords + die_width / 2 || ycoords + die_height / 2;
bottom_right = xcoords + die_width / 2 || ycoords - die_height / 2;

d_tl = Sqrt(Distance(top_left, [0 0]));
d_bl = Sqrt(Distance(bottom_left, [0 0]));
d_tr = Sqrt(Distance(top_right, [0 0]));
d_br = Sqrt(Distance(bottom_right, [0 0]));

// Assume that furthest part of die is the determining factor for distance
die_distance_to_center = Round(V Max((d_tl || d_bl || d_tr || d_br)`));

dt << New Column("D", Numeric, Ordinal, Values(die_distance_to_center));



nw = New Window("Demo",
	H List Box(
		dt << Data Filter(
			Add Filter(columns(:D), Display(:D, N Items(15), Find(Set Text(""))))
		),
		gb = dt << Graph Builder(
			Size(528, 463),
			Show Control Panel(0),
			Lock Scales(1),
			Variables(X(:U1_x), Y(:U1_y)),
			Elements(Points(X, Y, Legend(4))),
			SendToReport(
				Dispatch({}, "U1_x", ScaleBox,
					{Format("Fixed Dec", 12, 0), Min(-2.87573722663528), Max(261.04),
					Inc(50), Minor Ticks(1)}
				),
				Dispatch({}, "U1_y", ScaleBox,
					{Format("Fixed Dec", 12, 0), Min(-3.300675), Max(380), Inc(100),
					Minor Ticks(4)}
				)
			)
		)
	)
);

Write();

jthi_0-1725521631451.png

jthi_1-1725521657318.png

 

-Jarmo