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