1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
<Chapter Label="Parallel">
<Heading>Parallel computing with &SCSCP;</Heading>
<Section Label="Workflows">
<Heading>Managing multiple requests</Heading>
Using procedure calls explained in the previous section, the user can
create several requests to multiple services to execute them in parallel,
or to wait until the fastest result will be available.
<#Include Label="SynchronizeProcesses">
<#Include Label="FirstProcess">
<ManSection>
<Var Name="SCSCPservers" />
<Description>
<Ref Var="SCSCPservers" /> is
a list of hosts and ports to search for &SCSCP; services
(which may be not only represented by &GAP; services, but also
by another &SCSCP;-compliant systems).
<P/>
It is used by parallel skeletons <Ref Func="ParQuickWithSCSCP" />
and <Ref Func="ParListWithSCSCP" />.
<P/>
The initial value of this variable is specified in the file
<File>scscp/configpar.g</File> and may be reassigned later.
</Description>
</ManSection>
<#Include Label="ParQuickWithSCSCP">
<#Include Label="FirstTrueProcess">
</Section>
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="MasterWorker">
<Heading>MasterWorker skeleton</Heading>
In this section we will present more general framework to run parallel
computations, which has a number of useful features:
<List>
<Item>
it is implemented purely in &GAP;;
</Item>
<Item>
the client (i.e. master, which orchestrates the computation)
will work in UNIX/Linux, Mac OS X and MS Windows;
</Item>
<Item>
it may orchestrate both &GAP; and non-&GAP; &SCSCP; servers;
</Item>
<Item>
if one of servers (i.e. workers) will be lost, it will retry the
computation on another available server;
</Item>
<Item>
it allows to add dynamically new workers during the computation
on hostnames and ports from a range perviously declared in
<Ref Var="SCSCPservers" />.
</Item>
</List>
To configure this functionality,
the file <File>scscp/configpar.g</File> assigns the global variable
<C>SCSCPservers</C> which specifies a list of hosts and ports to
search for &SCSCP; services (which may be not only represented by
&GAP; services, but also by another &SCSCP;-compliant systems).
See comments in this file for further instructions.
<#Include Label="ParListWithSCSCP">
<#Include Label="SCSCPreset">
<#Include Label="SCSCPLogTracesToGlobal">
<Ref Func="ParListWithSCSCP" /> can be easily modified to have parallel versions
of other list operations like
<Ref BookName="ref" Func="ForAll" />,
<Ref BookName="ref" Func="ForAny" />,
<Ref BookName="ref" Func="First" />,
<Ref BookName="ref" Func="Number" />,
<Ref BookName="ref" Func="Filtered" />,
and also to have the skeleton in which the queue may be modified during
the computation (for example, to compute orbits).
We plan to provide such tools in one of the next versions of the package.
</Section>
<Section Label="Karatsuba">
<Heading>Example: parallelising Karatsuba multiplication for polynomials</Heading>
The file <File>scscp/example/karatsuba.g</File> contains an implementation of
the Karatsuba multiplication algorithm for polynomials. This algorithm can
be easily parallelized since each recursive step creates three recursive
calls of the same function for other polynomials. <E>We will not parallelize
each</E> recursive call, since this will create enormous data flow. Instead
of this we parallelize only the top-level function.
For our experiments with parallelising Karatsuba multiplication for
polynomials with integer coefficients we used the multi-core workstation,
on which we started one &SCSCP; client and two &SCSCP; servers. To use
it, modify the server configuration file adding to it the command to
read the file <File>scscp/example/karatsuba.g</File>, then define there
the following function
<Log>
<![CDATA[
KaratsubaPolynomialMultiplicationExtRepByString:=function(s1,s2)
return String( KaratsubaPolynomialMultiplicationExtRep(
EvalString(s1), EvalString(s2) ) );
end;;
]]>
</Log>
and finally add the following lines to made it available as an &SCSCP;
procedure under the name <C>WS_Karatsuba</C>:
<Log>
<![CDATA[
InstallSCSCPprocedure( "WS_Karatsuba",
KaratsubaPolynomialMultiplicationExtRepByString);
]]>
</Log>
(we do not include it into the default <File>scscp/example/myserver.g</File>
since the code contains a call to <Ref BookName="ref" Func="EvalString"/>).
<P/>
This function provides a "bridge" between the client's function
<C>KaratsubaPolynomialMultiplicationWS</C> and the server's function
<C>KaratsubaPolynomialMultiplicationExtRep</C>, which performs the
actual work on the server. <C>WS_Karatsuba</C> converts its string arguments
into internal representation of univariate polynomials (basically, lists of
integers) and then converts the result back into string (since such data
exchange format was chosen).
<Alt Only="LaTeX">
\newpage
</Alt>
We are going to parallelize the following part of the client's code:
<Log>
<![CDATA[
...
u := KaratsubaPolynomialMultiplicationExtRep(f1,g1);
v := KaratsubaPolynomialMultiplicationExtRep(f0,g0);
w := KaratsubaPolynomialMultiplicationExtRep(
PlusLaurentPolynomialsExtRep(f1,f0),
PlusLaurentPolynomialsExtRep(g1,g0) );
...
]]>
</Log>
and this can be done straightforwardly - we replace two first calls by
calls of the appropriate &SCSCP; services, then perform the 3rd call locally
and then collect the results from the two remote calls:
<Log>
<![CDATA[
...
u := NewProcess( "WS_Karatsuba",[ String(f1), String(g1) ],"localhost", 26133);
v := NewProcess( "WS_Karatsuba",[ String(f0), String(g0) ],"localhost", 26134);
w := KaratsubaPolynomialMultiplicationExtRep(
PlusLaurentPolynomialsExtRep(f1,f0),
PlusLaurentPolynomialsExtRep(g1,g0) );
wsresult:=SynchronizeProcesses2( u,v );
u := EvalString( wsresult[1].object );
v := EvalString( wsresult[2].object );
...
]]>
</Log>
We obtain almost double speedup on three cores on randomly generated polynomials
of degree 32000:
<Example>
<![CDATA[
gap> ReadPackage("scscp/example/karatsuba.g");
gap> fam:=FamilyObj(1);;
gap> f:=LaurentPolynomialByCoefficients( fam,
> List([1..32000],i->Random(Integers)), 0, 1 );;
gap> g:=LaurentPolynomialByCoefficients( fam,
> List([1..32000],i->Random(Integers)), 0, 1 );;
gap> t2:=KaratsubaPolynomialMultiplication(f,g);;time;
5892
gap> t3:=KaratsubaPolynomialMultiplicationWS(f,g);;time;
2974
]]>
</Example>
</Section>
</Chapter>
|