Sample ZPL Program: SUMMA Matrix Multiplication
program matmultSUMMA;
prototype GetSingleDim(infile:file):integer;
prototype GetInnerDim(infile1:file; infile2:file):integer;
config var
Afilename: string = "";
Bfilename: string = "";
Afile: file = open(Afilename,file_read);
Bfile: file = open(Bfilename,file_read);
default_size:integer = 4;
m:integer = GetSingleDim(Afile);
n:integer = GetInnerDim(Afile,Bfile);
p:integer = GetSingleDim(Bfile);
iters: integer = 1;
printinput: boolean = false;
verbose: boolean = true;
dotiming: boolean = false;
region
RA = [1..m,1..n];
RB = [1..n,1..p];
RC = [1..m,1..p];
FCol = [1..m,*];
FRow = [*,1..p];
var
A : [RA] double;
B : [RB] double;
C : [RC] double;
Aflood : [FCol] double;
Bflood : [FRow] double;
procedure ReadA();
var step:double;
[RA] begin
if (Afile != znull) then
read(Afile,A);
else
step := 1.0/(m*n);
A := ((Index1-1)*n + Index2)*step + 1.0;
end;
end;
procedure ReadB();
var step:double;
[RB] begin
if (Bfile != znull) then
read(Bfile,B);
else
step := 1.0/(n*p);
B := ((Index1-1)*p + Index2)*step + 1.0;
end;
end;
procedure matmultSUMMA();
var
i: integer;
it: integer;
runtime: double;
[RC] begin
ReadA();
ReadB();
if (printinput) then
[RA] writeln("A is:\n",A);
[RB] writeln("B is:\n",B);
end;
ResetTimer();
for it := 1 to iters do
C := 0.0; -- zero C
for i := 1 to n do
[FCol] Aflood := >>[,i] A; -- flood A col
[FRow] Bflood := >>[i,] B; -- flood B row
C += (Aflood * Bflood); -- multiply
end;
end;
runtime := CheckTimer();
if (verbose) then
writeln("C is:\n",C);
end;
if (dotiming) then
writeln("total runtime = %12.6f":runtime);
writeln("actual runtime = %12.6f":runtime/iters);
end;
end;
procedure GetSingleDim(infile:file):integer;
var dim:integer;
begin
if (infile != znull) then
read(infile,dim);
else
dim := default_size;
end;
return dim;
end;
procedure GetInnerDim(infile1:file; infile2:file):integer;
var
col:integer;
row:integer;
retval:integer;
begin
retval := -1;
if (infile1 != znull) then
read(infile1,col);
retval := col;
end;
if (infile2 != znull) then
read(infile2,row);
if (retval = -1) then
retval := row;
else
if (row != col) then
halt("ERROR: Inner dimensions don't match");
end;
end;
end;
if (retval = -1) then
retval := default_size;
end;
return retval;
end;