<ahref="subsolver_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aid="l00001"name="l00001"></a><spanclass="lineno"> 1</span><spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aid="l00002"name="l00002"></a><spanclass="lineno"> 2</span><spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aid="l00003"name="l00003"></a><spanclass="lineno"> 3</span><spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aid="l00004"name="l00004"></a><spanclass="lineno"> 4</span><spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aid="l00008"name="l00008"></a><spanclass="lineno"> 8</span><spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aid="l00009"name="l00009"></a><spanclass="lineno"> 9</span><spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aid="l00010"name="l00010"></a><spanclass="lineno"> 10</span><spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aid="l00011"name="l00011"></a><spanclass="lineno"> 11</span><spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aid="l00012"name="l00012"></a><spanclass="lineno"> 12</span><spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aid="l00014"name="l00014"></a><spanclass="lineno"> 14</span><spanclass="comment">// Simple framework for choosing and distributing a solver "sub-tasks" on a set</span></div>
<divclass="line"><aid="l00015"name="l00015"></a><spanclass="lineno"> 15</span><spanclass="comment">// of threads.</span></div>
<divclass="line"><aid="l00038"name="l00038"></a><spanclass="lineno"> 38</span><spanclass="comment">// The API used for distributing work. Each subsolver can generate tasks and</span></div>
<divclass="line"><aid="l00039"name="l00039"></a><spanclass="lineno"> 39</span><spanclass="comment">// synchronize itself with the rest of the world.</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// Note that currently only the main thread interact with subsolvers. Only the</span></div>
<divclass="line"><aid="l00042"name="l00042"></a><spanclass="lineno"> 42</span><spanclass="comment">// tasks generated by GenerateTask() are executed in parallel in a threadpool.</span></div>
<divclass="line"><aid="l00048"name="l00048"></a><spanclass="lineno"> 48</span><spanclass="comment">// Returns true iff GenerateTask() can be called.</span></div>
<divclass="line"><aid="l00050"name="l00050"></a><spanclass="lineno"> 50</span><spanclass="comment">// Note(user): In the current design, a SubSolver is never deleted until the</span></div>
<divclass="line"><aid="l00051"name="l00051"></a><spanclass="lineno"> 51</span><spanclass="comment">// end of the Solve() that created it. But is is okay to always return false</span></div>
<divclass="line"><aid="l00052"name="l00052"></a><spanclass="lineno"> 52</span><spanclass="comment">// here and release the memory used by the Subsolver internal if there is no</span></div>
<divclass="line"><aid="l00053"name="l00053"></a><spanclass="lineno"> 53</span><spanclass="comment">// need to call this Subsolver ever again. The overhead of iterating over it</span></div>
<divclass="line"><aid="l00054"name="l00054"></a><spanclass="lineno"> 54</span><spanclass="comment">// in the main solver loop should be minimal.</span></div>
<divclass="line"><aid="l00057"name="l00057"></a><spanclass="lineno"> 57</span><spanclass="comment">// Returns a task to run. The task_id is just an ever increasing counter that</span></div>
<divclass="line"><aid="l00058"name="l00058"></a><spanclass="lineno"> 58</span><spanclass="comment">// correspond to the number of total calls to GenerateTask().</span></div>
<divclass="line"><aid="l00060"name="l00060"></a><spanclass="lineno"> 60</span><spanclass="comment">// TODO(user): We could use a more complex selection logic and pass in the</span></div>
<divclass="line"><aid="l00061"name="l00061"></a><spanclass="lineno"> 61</span><spanclass="comment">// deterministic time limit this subtask should run for. Unclear at this</span></div>
<divclass="line"><aid="l00065"name="l00065"></a><spanclass="lineno"> 65</span><spanclass="comment">// Synchronizes with the external world from this SubSolver point of view.</span></div>
<divclass="line"><aid="l00066"name="l00066"></a><spanclass="lineno"> 66</span><spanclass="comment">// Also incorporate the results of the latest completed tasks if any.</span></div>
<divclass="line"><aid="l00068"name="l00068"></a><spanclass="lineno"> 68</span><spanclass="comment">// Note(user): The intended implementation for determinism is that tasks</span></div>
<divclass="line"><aid="l00069"name="l00069"></a><spanclass="lineno"> 69</span><spanclass="comment">// update asynchronously (and so non-deterministically) global "shared"</span></div>
<divclass="line"><aid="l00070"name="l00070"></a><spanclass="lineno"> 70</span><spanclass="comment">// classes, but this global state is incorporated by the Subsolver only when</span></div>
<divclass="line"><aid="l00071"name="l00071"></a><spanclass="lineno"> 71</span><spanclass="comment">// Synchronize() is called.</span></div>
<divclass="line"><aid="l00074"name="l00074"></a><spanclass="lineno"> 74</span><spanclass="comment">// Returns the score as updated by the completed tasks before the last</span></div>
<divclass="line"><aid="l00075"name="l00075"></a><spanclass="lineno"> 75</span><spanclass="comment">// Synchronize() call. Everything else being equal, we prefer to run a</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// SubSolver with the highest score.</span></div>
<divclass="line"><aid="l00081"name="l00081"></a><spanclass="lineno"> 81</span><spanclass="comment">// Returns the total deterministic time spend by the completed tasks before</span></div>
<divclass="line"><aid="l00082"name="l00082"></a><spanclass="lineno"> 82</span><spanclass="comment">// the last Synchronize() call.</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// Returns the name of this SubSolver. Used in logs.</span></div>
<divclass="line"><aid="l00097"name="l00097"></a><spanclass="lineno"> 97</span><spanclass="comment">// A simple wrapper to add a synchronization point in the list of subsolvers.</span></div>
<divclass="line"><aid="l00110"name="l00110"></a><spanclass="lineno"> 110</span><spanclass="comment">// Executes the following loop:</span></div>
<divclass="line"><aid="l00111"name="l00111"></a><spanclass="lineno"> 111</span><spanclass="comment">// 1/ Synchronize all in given order.</span></div>
<divclass="line"><aid="l00112"name="l00112"></a><spanclass="lineno"> 112</span><spanclass="comment">// 2/ generate and schedule one task from the current "best" subsolver.</span></div>
<divclass="line"><aid="l00113"name="l00113"></a><spanclass="lineno"> 113</span><spanclass="comment">// 3/ repeat until no extra task can be generated and all tasks are done.</span></div>
<divclass="line"><aid="l00115"name="l00115"></a><spanclass="lineno"> 115</span><spanclass="comment">// The complexity of each selection is in O(num_subsolvers), but that should</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// be okay given that we don't expect more than 100 such subsolvers.</span></div>
<divclass="line"><aid="l00118"name="l00118"></a><spanclass="lineno"> 118</span><spanclass="comment">// Note that it is okay to incorporate "special" subsolver that never produce</span></div>
<divclass="line"><aid="l00119"name="l00119"></a><spanclass="lineno"> 119</span><spanclass="comment">// any tasks. This can be used to synchronize classes used by many subsolvers</span></div>
<divclass="line"><aid="l00120"name="l00120"></a><spanclass="lineno"> 120</span><spanclass="comment">// just once for instance.</span></div>
<divclass="line"><aid="l00124"name="l00124"></a><spanclass="lineno"> 124</span><spanclass="comment">// Similar to NonDeterministicLoop() except this should result in a</span></div>
<divclass="line"><aid="l00125"name="l00125"></a><spanclass="lineno"> 125</span><spanclass="comment">// deterministic solver provided that all SubSolver respect the Synchronize()</span></div>
<divclass="line"><aid="l00128"name="l00128"></a><spanclass="lineno"> 128</span><spanclass="comment">// Executes the following loop:</span></div>
<divclass="line"><aid="l00129"name="l00129"></a><spanclass="lineno"> 129</span><spanclass="comment">// 1/ Synchronize all in given order.</span></div>
<divclass="line"><aid="l00130"name="l00130"></a><spanclass="lineno"> 130</span><spanclass="comment">// 2/ generate and schedule up to batch_size tasks using an heuristic to select</span></div>
<divclass="line"><aid="l00131"name="l00131"></a><spanclass="lineno"> 131</span><spanclass="comment">// which one to run.</span></div>
<divclass="line"><aid="l00132"name="l00132"></a><spanclass="lineno"> 132</span><spanclass="comment">// 3/ wait for all task to finish.</span></div>
<divclass="line"><aid="l00133"name="l00133"></a><spanclass="lineno"> 133</span><spanclass="comment">// 4/ repeat until no task can be generated in step 2.</span></div>
<divclass="line"><aid="l00138"name="l00138"></a><spanclass="lineno"> 138</span><spanclass="comment">// Same as above, but specialized implementation for the case num_threads=1.</span></div>
<divclass="line"><aid="l00139"name="l00139"></a><spanclass="lineno"> 139</span><spanclass="comment">// This avoids using a Threadpool altogether. It should have the same behavior</span></div>
<divclass="line"><aid="l00140"name="l00140"></a><spanclass="lineno"> 140</span><spanclass="comment">// than the functions above with num_threads=1 and batch_size=1. Note that an</span></div>
<divclass="line"><aid="l00141"name="l00141"></a><spanclass="lineno"> 141</span><spanclass="comment">// higher batch size will not behave in the same way, even if num_threads=1.</span></div>
<divclass="ttc"id="anamespaceoperations__research_1_1sat_html_a0b26de551c3b5b1831568f623f66cb16"><divclass="ttname"><ahref="namespaceoperations__research_1_1sat.html#a0b26de551c3b5b1831568f623f66cb16">operations_research::sat::DeterministicLoop</a></div><divclass="ttdeci">void DeterministicLoop(const std::vector< std::unique_ptr< SubSolver >>&subsolvers, int num_threads, int batch_size)</div><divclass="ttdef"><b>Definition:</b><ahref="subsolver_8cc_source.html#l00093">subsolver.cc:93</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_html"><divclass="ttname"><ahref="namespaceoperations__research.html">operations_research</a></div><divclass="ttdoc">Collection of objects used to extend the Constraint Solver library.</div><divclass="ttdef"><b>Definition:</b><ahref="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></div>