Matrix multiplication: Difference between revisions

Content added Content deleted
m (→‎[[Matrix multiplication#ELLA]]: move to E section.)
m (→‎[[Matrix multiplication#ALGOL 68]]: use BOLD as per specification.)
Line 142: Line 142:


Alternatively, for multicore CPUs, the following recursive algorithm can be used:
Alternatively, for multicore CPUs, the following recursive algorithm can be used:
<u>int</u> default upb := 3;
'''int''' default upb := 3;
<u>mode</u> <u>field</u> = <u>long</u> <u>real</u>;
'''mode''' '''field''' = '''long''' '''real''';
<u>mode</u> <u>vector</u> = [default upb]<u>field</u>;
'''mode''' '''vector''' = [default upb]'''field''';
<u>mode</u> <u>matrix</u> = [default upb, default upb]<u>field</u>;
'''mode''' '''matrix''' = [default upb, default upb]'''field''';
&cent; crude exception handling &cent;
&cent; crude exception handling &cent;
<u>proc</u> <u>void</u> raise index error := <u>void</u>: <u>goto</u> exception index error;
'''proc''' '''void''' raise index error := '''void''': '''goto''' exception index error;
<u>sema</u> idle cpus = <u>level</u> ( 8 - 1 ); &cent; 8 = number of CPU cores minus parent CPU &cent;
'''sema''' idle cpus = '''level''' ( 8 - 1 ); &cent; 8 = number of CPU cores minus parent CPU &cent;
&cent; define an operator to slice array into quarters &cent;
&cent; define an operator to slice array into quarters &cent;
<u>op</u> <u>top</u> = (<u>matrix</u> m)<u>int</u>: ( &lfloor;m + &lceil;m ) %2,
'''op''' '''top''' = ('''matrix''' m)'''int''': ( &lfloor;m + &lceil;m ) %2,
<u>bot</u> = (<u>matrix</u> m)<u>int</u>: <u>top</u> m + 1,
'''bot''' = ('''matrix''' m)'''int''': '''top''' m + 1,
<u>left</u> = (<u>matrix</u> m)<u>int</u>: ( 2 &lfloor;m + 2 &lceil;m ) %2,
'''left''' = ('''matrix''' m)'''int''': ( 2 &lfloor;m + 2 &lceil;m ) %2,
<u>right</u> = (<u>matrix</u> m)<u>int</u>: <u>left</u> m + 1,
'''right''' = ('''matrix''' m)'''int''': '''left''' m + 1,
<u>left</u> = (<u>vector</u> v)<u>int</u>: ( &lfloor;v + &lceil;v ) %2,
'''left''' = ('''vector''' v)'''int''': ( &lfloor;v + &lceil;v ) %2,
<u>right</u> = (<u>vector</u> v)<u>int</u>: <u>left</u> v + 1;
'''right''' = ('''vector''' v)'''int''': '''left''' v + 1;
<u>prio</u> <u>top</u> = 8, <u>bot</u> = 8, <u>left</u> = 8, <u>right</u> = 8; &cent; Operator priority - same as LWB & UPB &cent;
'''prio''' '''top''' = 8, '''bot''' = 8, '''left''' = 8, '''right''' = 8; &cent; Operator priority - same as LWB & UPB &cent;
<u>op</u> &times; = (<u>vector</u> a, b)<u>field</u>: ( &cent; dot product &cent;
'''op''' &times; = ('''vector''' a, b)'''field''': ( &cent; dot product &cent;
<u>if</u> (&lfloor;a, &lceil;a) &ne; (&lfloor;b, &lceil;b) <u>then</u> raise index error <u>fi</u>;
'''if''' (&lfloor;a, &lceil;a) &ne; (&lfloor;b, &lceil;b) '''then''' raise index error '''fi''';
<u>if</u> &lfloor;a = &lceil;a <u>then</u>
'''if''' &lfloor;a = &lceil;a '''then'''
a[&lceil;a] &times; b[&lceil;b]
a[&lceil;a] &times; b[&lceil;b]
<u>else</u>
'''else'''
<u>field</u> begin, end;
'''field''' begin, end;
[]<u>proc</u> <u>void</u> schedule=(
[]'''proc''' '''void''' schedule=(
<u>void</u>: begin:=a[:<u>left</u> a] &times; b[:<u>left</u> b],
'''void''': begin:=a[:'''left''' a] &times; b[:'''left''' b],
<u>void</u>: end :=a[<u>right</u> a:] &times; b[<u>right</u> b:]
'''void''': end :=a['''right''' a:] &times; b['''right''' b:]
);
);
<u>if</u> <u>level</u> idle cpus = 0 <u>then</u> &cent; use current CPU &cent;
'''if''' '''level''' idle cpus = 0 '''then''' &cent; use current CPU &cent;
<u>for</u> thread <u>to</u> &lceil;schedule <u>do</u> schedule[thread] <u>od</u>
'''for''' thread '''to''' &lceil;schedule '''do''' schedule[thread] '''od'''
<u>else</u>
'''else'''
<u>par</u> ( &cent; run vector in parallel &cent;
'''par''' ( &cent; run vector in parallel &cent;
schedule[1], &cent; assume parent CPU &cent;
schedule[1], &cent; assume parent CPU &cent;
( &darr;idle cpus; schedule[2]; &uarr;idle cpus)
( &darr;idle cpus; schedule[2]; &uarr;idle cpus)
)
)
<u>fi</u>;
'''fi''';
begin+end
begin+end
<u>fi</u>
'''fi'''
);
);
<u>op</u> &times; = (<u>matrix</u> a, b)<u>matrix</u>: &cent; matrix multiply &cent;
'''op''' &times; = ('''matrix''' a, b)'''matrix''': &cent; matrix multiply &cent;
<u>if</u> (&lfloor;a, 2 &lfloor;b) = (&lceil;a, 2 &lceil;b) <u>then</u>
'''if''' (&lfloor;a, 2 &lfloor;b) = (&lceil;a, 2 &lceil;b) '''then'''
a[&lfloor;a, ] &times; b[, 2 &lceil;b] &cent; dot product &cent;
a[&lfloor;a, ] &times; b[, 2 &lceil;b] &cent; dot product &cent;
<u>else</u>
'''else'''
[&lceil;a, 2 &lceil;b] <u>field</u> out;
[&lceil;a, 2 &lceil;b] '''field''' out;
<u>if</u> (2 &lfloor;a, 2 &lceil;a) &ne; (&lfloor;b, &lceil;b) <u>then</u> raise index error <u>fi</u>;
'''if''' (2 &lfloor;a, 2 &lceil;a) &ne; (&lfloor;b, &lceil;b) '''then''' raise index error '''fi''';
[]<u>struct</u>(<u>bool</u> required, <u>proc</u> <u>void</u> thread) schedule = (
[]'''struct'''('''bool''' required, '''proc''' '''void''' thread) schedule = (
( <u>true</u>, &cent; calculate top left corner &cent;
( '''true''', &cent; calculate top left corner &cent;
<u>void</u>: out[:<u>top</u> a, :<u>left</u> b] := a[:<u>top</u> a, ] &times; b[, :<u>left</u> b]),
'''void''': out[:'''top''' a, :'''left''' b] := a[:'''top''' a, ] &times; b[, :'''left''' b]),
( &lfloor;a &ne; &lceil;a, &cent; calculate bottom left corner &cent;
( &lfloor;a &ne; &lceil;a, &cent; calculate bottom left corner &cent;
<u>void</u>: out[<u>bot</u> a:, :<u>left</u> b] := a[<u>bot</u> a:, ] &times; b[, :<u>left</u> b]),
'''void''': out['''bot''' a:, :'''left''' b] := a['''bot''' a:, ] &times; b[, :'''left''' b]),
( 2 &lfloor;b &ne; 2 &lceil;b, &cent; calculate top right corner &cent;
( 2 &lfloor;b &ne; 2 &lceil;b, &cent; calculate top right corner &cent;
<u>void</u>: out[:<u>top</u> a, <u>right</u> b:] := a[:<u>top</u> a, ] &times; b[, <u>right</u> b:]),
'''void''': out[:'''top''' a, '''right''' b:] := a[:'''top''' a, ] &times; b[, '''right''' b:]),
( (&lfloor;a, 2 &lfloor;b) &ne; (&lceil;a, 2 &lceil;b) , &cent; calculate bottom right corner &cent;
( (&lfloor;a, 2 &lfloor;b) &ne; (&lceil;a, 2 &lceil;b) , &cent; calculate bottom right corner &cent;
<u>void</u>: out[<u>bot</u> a:, <u>right</u> b:] := a[<u>bot</u> a:, ] &times; b[, <u>right</u> b:])
'''void''': out['''bot''' a:, '''right''' b:] := a['''bot''' a:, ] &times; b[, '''right''' b:])
);
);
<u>if</u> <u>level</u> idle cpus = 0 <u>then</u> &cent; use current CPU &cent;
'''if''' '''level''' idle cpus = 0 '''then''' &cent; use current CPU &cent;
<u>for</u> thread <u>to</u> &lceil;schedule <u>do</u> (required &rarr;schedule[thread] | thread &rarr;schedule[thread] ) <u>od</u>
'''for''' thread '''to''' &lceil;schedule '''do''' (required &rarr;schedule[thread] | thread &rarr;schedule[thread] ) '''od'''
<u>else</u>
'''else'''
<u>par</u> ( &cent; run vector in parallel &cent;
'''par''' ( &cent; run vector in parallel &cent;
thread &rarr;schedule[1], &cent; thread is always required, and assume parent CPU &cent;
thread &rarr;schedule[1], &cent; thread is always required, and assume parent CPU &cent;
( required &rarr;schedule[4] | &darr;idle cpus; thread &rarr;schedule[4]; &uarr;idle cpus),
( required &rarr;schedule[4] | &darr;idle cpus; thread &rarr;schedule[4]; &uarr;idle cpus),
Line 209: Line 209:
( required &rarr;schedule[2] | &darr;idle cpus; thread &rarr;schedule[2]; &uarr;idle cpus)
( required &rarr;schedule[2] | &darr;idle cpus; thread &rarr;schedule[2]; &uarr;idle cpus)
)
)
<u>fi</u>;
'''fi''';
out
out
<u>fi</u>;
'''fi''';
<u>format</u> real fmt = $g(-6,2)$; &cent; width of 6, with no '+' sign, 2 decimals &cent;
'''format''' real fmt = $g(-6,2)$; &cent; width of 6, with no '+' sign, 2 decimals &cent;
<u>proc</u> real matrix printf= (<u>format</u> real fmt, <u>matrix</u> m)<u>void</u>:(
'''proc''' real matrix printf= ('''format''' real fmt, '''matrix''' m)'''void''':(
<u>format</u> vector fmt = $"("n(2 &lceil;m-1)(f(real fmt)",")f(real fmt)")"$;
'''format''' vector fmt = $"("n(2 &lceil;m-1)(f(real fmt)",")f(real fmt)")"$;
<u>format</u> matrix fmt = $x"("n(&lceil;m-1)(f(vector fmt)","lxx)f(vector fmt)");"$;
'''format''' matrix fmt = $x"("n(&lceil;m-1)(f(vector fmt)","lxx)f(vector fmt)");"$;
&cent; finally print the result &cent;
&cent; finally print the result &cent;
printf((matrix fmt,m))
printf((matrix fmt,m))
Line 222: Line 222:
&cent; Some sample matrices to test &cent;
&cent; Some sample matrices to test &cent;
<u>matrix</u> a=((1, 1, 1, 1), &cent; matrix A &cent;
'''matrix''' a=((1, 1, 1, 1), &cent; matrix A &cent;
(2, 4, 8, 16),
(2, 4, 8, 16),
(3, 9, 27, 81),
(3, 9, 27, 81),
(4, 16, 64, 256));
(4, 16, 64, 256));
<u>matrix</u> b=(( 4 , -3 , 4/3, -1/4 ), &cent; matrix B &cent;
'''matrix''' b=(( 4 , -3 , 4/3, -1/4 ), &cent; matrix B &cent;
(-13/3, 19/4, -7/3, 11/24),
(-13/3, 19/4, -7/3, 11/24),
( 3/2, -2 , 7/6, -1/4 ),
( 3/2, -2 , 7/6, -1/4 ),
( -1/6, 1/4, -1/6, 1/24));
( -1/6, 1/4, -1/6, 1/24));
<u>matrix</u> c = a &times; b; &cent; actual multiplication example of A x B &cent;
'''matrix''' c = a &times; b; &cent; actual multiplication example of A x B &cent;
print((" A x B =",new line));
print((" A x B =",new line));
real matrix printf(real fmt, c)
real matrix printf(real fmt, c).
exception index error:
exception index error: