xref: /inferno-os/appl/math/linbench.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth# Translated to Limbo by Eric Grosse <ehg@netlib.bell-labs.com> 3/96
2*37da2899SCharles.Forsyth# Translated to Java by Reed Wade  (wade@cs.utk.edu) 2/96
3*37da2899SCharles.Forsyth# Translated to C by Bonnie Toy 5/88
4*37da2899SCharles.Forsyth# Will Menninger, 10/93
5*37da2899SCharles.Forsyth# Jack Dongarra, linpack, 3/11/78.
6*37da2899SCharles.Forsyth# Cleve Moler, linpack, 08/14/78
7*37da2899SCharles.Forsyth
8*37da2899SCharles.Forsythimplement linbench;
9*37da2899SCharles.Forsyth
10*37da2899SCharles.Forsythinclude "sys.m";
11*37da2899SCharles.Forsyth	sys: Sys;
12*37da2899SCharles.Forsyth	print: import sys;
13*37da2899SCharles.Forsythinclude "math.m";
14*37da2899SCharles.Forsyth	math: Math;
15*37da2899SCharles.Forsyth	dot, fabs, gemm, iamax: import math;
16*37da2899SCharles.Forsythinclude "draw.m";
17*37da2899SCharles.Forsyth	draw: Draw;
18*37da2899SCharles.Forsyth	Rect, Screen, Display, Image: import draw;
19*37da2899SCharles.Forsythinclude "tk.m";
20*37da2899SCharles.Forsyth	tk: Tk;
21*37da2899SCharles.Forsyth	Toplevel: import tk;
22*37da2899SCharles.Forsythinclude "tkclient.m";
23*37da2899SCharles.Forsyth	tkclient: Tkclient;
24*37da2899SCharles.Forsythinclude "bufio.m";
25*37da2899SCharles.Forsyth	bufio: Bufio;
26*37da2899SCharles.Forsyth	Iobuf: import bufio;
27*37da2899SCharles.Forsythinclude "linalg.m";
28*37da2899SCharles.Forsyth	linalg: LinAlg;
29*37da2899SCharles.Forsyth	dgefa, dgesl, printmat: import linalg;
30*37da2899SCharles.Forsyth
31*37da2899SCharles.Forsythctxt: ref Draw->Context;
32*37da2899SCharles.Forsythtop: ref Tk->Toplevel;
33*37da2899SCharles.Forsythbuttonlist: string;
34*37da2899SCharles.Forsyth
35*37da2899SCharles.Forsyth
36*37da2899SCharles.Forsythlinbench: module
37*37da2899SCharles.Forsyth{
38*37da2899SCharles.Forsyth	init:   fn(nil: ref Draw->Context, argv: list of string);
39*37da2899SCharles.Forsyth};
40*37da2899SCharles.Forsyth
41*37da2899SCharles.Forsythtkcmd(arg: string): string{
42*37da2899SCharles.Forsyth	rv := tk->cmd(top,arg);
43*37da2899SCharles.Forsyth	if(rv!=nil && rv[0]=='!')
44*37da2899SCharles.Forsyth		print("tk->cmd(%s): %s\n",arg,rv);
45*37da2899SCharles.Forsyth	return rv;
46*37da2899SCharles.Forsyth}
47*37da2899SCharles.Forsyth
48*37da2899SCharles.Forsythinit(xctxt: ref Draw->Context, nil: list of string)
49*37da2899SCharles.Forsyth{
50*37da2899SCharles.Forsyth	sys    = load Sys  Sys->PATH;
51*37da2899SCharles.Forsyth	math   = load Math Math->PATH;
52*37da2899SCharles.Forsyth	draw   = load Draw Draw->PATH;
53*37da2899SCharles.Forsyth	tk     = load Tk   Tk->PATH;
54*37da2899SCharles.Forsyth	tkclient  = load Tkclient Tkclient->PATH;
55*37da2899SCharles.Forsyth	linalg = load LinAlg LinAlg->PATH;
56*37da2899SCharles.Forsyth		if(linalg==nil) print("couldn't load LinAlg\n");
57*37da2899SCharles.Forsyth	sys->pctl(Sys->NEWPGRP, nil);
58*37da2899SCharles.Forsyth	tkclient->init();
59*37da2899SCharles.Forsyth	ctxt = xctxt;
60*37da2899SCharles.Forsyth	menubut: chan of string;
61*37da2899SCharles.Forsyth	(top, menubut) = tkclient->toplevel(ctxt, "",
62*37da2899SCharles.Forsyth				"Linpack in Limbo", Tkclient->Appl);
63*37da2899SCharles.Forsyth	cmd := chan of string;
64*37da2899SCharles.Forsyth	tk->namechan(top, cmd, "cmd");
65*37da2899SCharles.Forsyth
66*37da2899SCharles.Forsyth	tkcmd("pack .Wm_t -fill x");
67*37da2899SCharles.Forsyth	tkcmd("frame .b");
68*37da2899SCharles.Forsyth	tkcmd("button .b.Run -text Run -command {send cmd run}");
69*37da2899SCharles.Forsyth	tkcmd("entry .b.N -width 10w");  tkcmd(".b.N insert 0 200");
70*37da2899SCharles.Forsyth	tkcmd("pack .b.Run .b.N -side left");
71*37da2899SCharles.Forsyth	tkcmd("pack .b -anchor w");
72*37da2899SCharles.Forsyth	tkcmd("frame .d");
73*37da2899SCharles.Forsyth	tkcmd("listbox .d.f -width 35w -height 150 -selectmode single -yscrollcommand {.d.fscr set}");
74*37da2899SCharles.Forsyth	tkcmd("scrollbar .d.fscr -command {.d.f yview}");
75*37da2899SCharles.Forsyth	tkcmd("pack .d.f .d.fscr -expand 1 -fill y -side right");
76*37da2899SCharles.Forsyth	tkcmd("pack .d -side top");
77*37da2899SCharles.Forsyth	tkcmd("focus .b.N");
78*37da2899SCharles.Forsyth	tkcmd("pack propagate . 0;update");
79*37da2899SCharles.Forsyth	tkclient->onscreen(top, nil);
80*37da2899SCharles.Forsyth	tkclient->startinput(top, "kbd"::"ptr"::nil);
81*37da2899SCharles.Forsyth
82*37da2899SCharles.Forsyth	for(;;) alt {
83*37da2899SCharles.Forsyth	s := <-top.ctxt.kbd =>
84*37da2899SCharles.Forsyth		tk->keyboard(top, s);
85*37da2899SCharles.Forsyth	s := <-top.ctxt.ptr =>
86*37da2899SCharles.Forsyth		tk->pointer(top, *s);
87*37da2899SCharles.Forsyth	s := <-top.ctxt.ctl or
88*37da2899SCharles.Forsyth	s = <-top.wreq or
89*37da2899SCharles.Forsyth	s = <-menubut =>
90*37da2899SCharles.Forsyth		tkclient->wmctl(top, s);
91*37da2899SCharles.Forsyth	press := <-cmd =>
92*37da2899SCharles.Forsyth		case press {
93*37da2899SCharles.Forsyth		"run" =>
94*37da2899SCharles.Forsyth			tkcmd("cursor -bitmap cursor.wait; update");
95*37da2899SCharles.Forsyth			nstr := tkcmd(".b.N get");
96*37da2899SCharles.Forsyth			n := int nstr;
97*37da2899SCharles.Forsyth			(mflops,secs) := benchmark(n);
98*37da2899SCharles.Forsyth			result := sys->sprint("%8.2f Mflops %8.1f secs",mflops,secs);
99*37da2899SCharles.Forsyth			tkcmd("cursor -default");
100*37da2899SCharles.Forsyth			tkcmd(".d.f insert end {" + result + "}");
101*37da2899SCharles.Forsyth			tkcmd(".d.f yview moveto 1; update");
102*37da2899SCharles.Forsyth		}
103*37da2899SCharles.Forsyth	}
104*37da2899SCharles.Forsyth}
105*37da2899SCharles.Forsyth
106*37da2899SCharles.Forsythbenchmark(n: int): (real,real)
107*37da2899SCharles.Forsyth{
108*37da2899SCharles.Forsyth	math = load Math Math->PATH;
109*37da2899SCharles.Forsyth
110*37da2899SCharles.Forsyth	time := array [2] of real;
111*37da2899SCharles.Forsyth	lda := 201;
112*37da2899SCharles.Forsyth	if(n>lda) lda = n;
113*37da2899SCharles.Forsyth	a := array [lda*n] of real;
114*37da2899SCharles.Forsyth	b := array [n] of real;
115*37da2899SCharles.Forsyth	x := array [n] of real;
116*37da2899SCharles.Forsyth	ipvt := array [n] of int;
117*37da2899SCharles.Forsyth	ops := (2*n*n*n)/3 + 2*n*n;
118*37da2899SCharles.Forsyth
119*37da2899SCharles.Forsyth	norma := matgen(a,lda,n,b);
120*37da2899SCharles.Forsyth	printmat("a",a,lda,n,n);
121*37da2899SCharles.Forsyth	printmat("b",b,lda,n,1);
122*37da2899SCharles.Forsyth	t1 := second();
123*37da2899SCharles.Forsyth	dgefa(a,lda,n,ipvt);
124*37da2899SCharles.Forsyth	time[0] = second() - t1;
125*37da2899SCharles.Forsyth	printmat("a",a,lda,n,n);
126*37da2899SCharles.Forsyth	t1 = second();
127*37da2899SCharles.Forsyth	dgesl(a,lda,n,ipvt,b,0);
128*37da2899SCharles.Forsyth	time[1] = second() - t1;
129*37da2899SCharles.Forsyth	total := time[0] + time[1];
130*37da2899SCharles.Forsyth
131*37da2899SCharles.Forsyth	for(i := 0; i < n; i++) {
132*37da2899SCharles.Forsyth		x[i] = b[i];
133*37da2899SCharles.Forsyth	}
134*37da2899SCharles.Forsyth	printmat("x",x,lda,n,1);
135*37da2899SCharles.Forsyth	norma = matgen(a,lda,n,b);
136*37da2899SCharles.Forsyth	for(i = 0; i < n; i++) {
137*37da2899SCharles.Forsyth		b[i] = -b[i];
138*37da2899SCharles.Forsyth	}
139*37da2899SCharles.Forsyth	dmxpy(b,x,a,lda);
140*37da2899SCharles.Forsyth	resid := 0.;
141*37da2899SCharles.Forsyth	normx := 0.;
142*37da2899SCharles.Forsyth	for(i = 0; i < n; i++){
143*37da2899SCharles.Forsyth		if(resid<fabs(b[i])) resid = fabs(b[i]);
144*37da2899SCharles.Forsyth		if(normx<fabs(x[i])) normx = fabs(x[i]);
145*37da2899SCharles.Forsyth	}
146*37da2899SCharles.Forsyth
147*37da2899SCharles.Forsyth	eps_result := math->MachEps;
148*37da2899SCharles.Forsyth	residn_result := (real n)*norma*normx*eps_result;
149*37da2899SCharles.Forsyth	if(residn_result!=0.)
150*37da2899SCharles.Forsyth		residn_result = resid/residn_result;
151*37da2899SCharles.Forsyth	else
152*37da2899SCharles.Forsyth		print("can't scale residual.");
153*37da2899SCharles.Forsyth	if(residn_result>math->sqrt(real n))
154*37da2899SCharles.Forsyth		print("resid/MachEps=%.3g\n",residn_result);
155*37da2899SCharles.Forsyth	time_result := total;
156*37da2899SCharles.Forsyth	mflops_result := 0.;
157*37da2899SCharles.Forsyth	if(total!=0.)
158*37da2899SCharles.Forsyth		mflops_result = real ops/(1e6*total);
159*37da2899SCharles.Forsyth	else
160*37da2899SCharles.Forsyth		print("can't measure time\n");
161*37da2899SCharles.Forsyth	return (mflops_result,time_result);
162*37da2899SCharles.Forsyth}
163*37da2899SCharles.Forsyth
164*37da2899SCharles.Forsyth
165*37da2899SCharles.Forsyth# multiply matrix m times vector x and add the r_result to vector y.
166*37da2899SCharles.Forsythdmxpy(y, x, m:array of real, ldm: int)
167*37da2899SCharles.Forsyth{
168*37da2899SCharles.Forsyth	n1 := len y;
169*37da2899SCharles.Forsyth	n2 := len x;
170*37da2899SCharles.Forsyth	gemm('N','N',n1,1,n2,1.,m,ldm,x,n2,1.,y,n1);
171*37da2899SCharles.Forsyth}
172*37da2899SCharles.Forsyth
173*37da2899SCharles.Forsythsecond(): real
174*37da2899SCharles.Forsyth{
175*37da2899SCharles.Forsyth	return(real sys->millisec()/1000.);
176*37da2899SCharles.Forsyth}
177*37da2899SCharles.Forsyth
178*37da2899SCharles.Forsyth
179*37da2899SCharles.Forsyth# generate a (fixed) random matrix and right hand side
180*37da2899SCharles.Forsyth# a[i][j] => a[lda*i+j]
181*37da2899SCharles.Forsythmatgen(a: array of real, lda, n: int, b: array of real): real
182*37da2899SCharles.Forsyth{
183*37da2899SCharles.Forsyth	seed := 1325;
184*37da2899SCharles.Forsyth	norma := 0.;
185*37da2899SCharles.Forsyth	for(j := 0; j < n; j++)
186*37da2899SCharles.Forsyth		for(i := 0; i < n; i++){
187*37da2899SCharles.Forsyth			seed = 3125*seed % 65536;
188*37da2899SCharles.Forsyth			a[lda*j+i] = (real seed - 32768.0)/16384.0;
189*37da2899SCharles.Forsyth			if(norma < a[lda*j+i]) norma = a[lda*j+i];
190*37da2899SCharles.Forsyth		}
191*37da2899SCharles.Forsyth	for (i = 0; i < n; i++)
192*37da2899SCharles.Forsyth		b[i] = 0.;
193*37da2899SCharles.Forsyth	for (j = 0; j < n; j++)
194*37da2899SCharles.Forsyth		for (i = 0; i < n; i++)
195*37da2899SCharles.Forsyth			b[i] += a[lda*j+i];
196*37da2899SCharles.Forsyth	return norma;
197*37da2899SCharles.Forsyth}
198