Boost C++ Libraries: Ticket #5849: all_to_all() passes invalid args to allocate when sending lots of data https://svn.boost.org/trac10/ticket/5849 <p> For boost 1.47.0 code of the following form fails... </p> <div class="wikipage" style="font-size: 80%"><div class="wiki-code"><div class="code"><pre><span class="n">boost</span><span class="o">::</span><span class="n">mpi</span><span class="o">::</span><span class="n">communicator</span> <span class="n">communicator</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o">&lt;</span><span class="n">Thing</span><span class="o">*&gt;</span> <span class="o">&gt;</span> <span class="n">in_values</span><span class="p">(</span><span class="n">communicator</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o">&lt;</span><span class="n">Thing</span><span class="o">*&gt;</span> <span class="o">&gt;</span> <span class="n">out_values</span><span class="p">(</span><span class="n">communicator</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> <span class="c1">// Point the lists in in_values to more than numeric_limits&lt;int&gt;::max() bytes of data</span> <span class="n">boost</span><span class="o">::</span><span class="n">mpi</span><span class="o">::</span><span class="n">all_to_all</span><span class="p">(</span><span class="n">communicator</span><span class="p">,</span><span class="n">in_values</span><span class="p">,</span><span class="n">out_values</span><span class="p">);</span> </pre></div></div></div><p> Such code ends up passing the allocator, using openmpi-1.4.3, an invalid argument. </p> <p> Looking at all_to_all.hpp and the method... </p> <div class="wikipage" style="font-size: 80%"><div class="wiki-code"><div class="code"><pre><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="kt">void</span> <span class="n">all_to_all_impl</span><span class="p">(</span><span class="k">const</span> <span class="n">communicator</span><span class="o">&amp;</span> <span class="n">comm</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">*</span> <span class="n">in_values</span><span class="p">,</span> <span class="kt">int</span> <span class="n">n</span><span class="p">,</span> <span class="n">T</span><span class="o">*</span> <span class="n">out_values</span><span class="p">,</span> <span class="n">mpl</span><span class="o">::</span><span class="n">false_</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span> </pre></div></div></div><p> I think I see why this happens. The method begins as follows... </p> <div class="wikipage" style="font-size: 80%"><div class="wiki-code"><div class="code"><pre> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">send_sizes</span><span class="p">(</span><span class="n">size</span><span class="p">);</span> <span class="c1">// The displacements for each outgoing value.</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">send_disps</span><span class="p">(</span><span class="n">size</span><span class="p">);</span> <span class="c1">// The buffer that will store all of the outgoing values</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="n">allocator</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">outgoing</span><span class="p">;</span> <span class="c1">// Pack the buffer with all of the outgoing values.</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">dest</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">dest</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="o">++</span><span class="n">dest</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Keep track of the displacements</span> <span class="n">send_disps</span><span class="p">[</span><span class="n">dest</span><span class="p">]</span> <span class="o">=</span> <span class="n">outgoing</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="c1">// Our own value will never be transmitted, so don&#39;t pack it.</span> <span class="k">if</span> <span class="p">(</span><span class="n">dest</span> <span class="o">!=</span> <span class="n">rank</span><span class="p">)</span> <span class="p">{</span> <span class="n">packed_oarchive</span> <span class="n">oa</span><span class="p">(</span><span class="n">comm</span><span class="p">,</span> <span class="n">outgoing</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">oa</span> <span class="o">&lt;&lt;</span> <span class="n">in_values</span><span class="p">[</span><span class="n">dest</span> <span class="o">*</span> <span class="n">n</span> <span class="o">+</span> <span class="n">i</span><span class="p">];</span> <span class="p">}</span> <span class="c1">// Keep track of the sizes</span> <span class="n">send_sizes</span><span class="p">[</span><span class="n">dest</span><span class="p">]</span> <span class="o">=</span> <span class="n">outgoing</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">send_disps</span><span class="p">[</span><span class="n">dest</span><span class="p">];</span> <span class="p">}</span> </pre></div></div></div><p> If outgoing.size() or (outgoing.size() - send_disps[dest]) is greater than numeric_limits&lt;int&gt;::max(), then send_disps[dest] or send_sizes[dest] flips over to negative values or is simply junk. After that happens the rest of the code in all_to_all_impl() doesn't really make any sense. </p> <p> My guess is that instead of using int here... </p> <div class="wikipage" style="font-size: 80%"><div class="wiki-code"><div class="code"><pre><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">send_sizes</span><span class="p">(</span><span class="n">size</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">send_disps</span><span class="p">(</span><span class="n">size</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">recv_sizes</span><span class="p">(</span><span class="n">size</span><span class="p">);</span> <span class="p">...</span> </pre></div></div></div><p> you should use allocator::size_type. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5849 Trac 1.4.3 Matthias Troyer Tue, 01 Jan 2013 11:39:18 GMT owner changed https://svn.boost.org/trac10/ticket/5849#comment:1 https://svn.boost.org/trac10/ticket/5849#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Douglas Gregor</span> to <span class="trac-author">Matthias Troyer</span> </li> </ul> Ticket