title: Passing multidimensionals vector to C++11 threads
body: <p>I'm working on a program that reads a large binary file (> 80GB) full of unsigned chars into a std::vector, then runs computations on chunks of the elements in that vector. I would like to speed things up by having independent threads run these computations on different sections of the vector simultaneously, and combine the results at the end.</p>
  
  <p>These threads should all be storing the results of their calculations in a pair of 2-dimensional std::vectors, which I am attempting to pass into the thread function call as references. I can get this all to work in a generic function call, but when I try to launch it using std::thread I get the following compilation errors:</p>
  
  <pre><code>In file included from /usr/include/c++/4.8/thread:39:0,
                   from test.cpp:12:
  /usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple&lt;int (*(long long unsigned int, long long unsigned int, std::vector&lt;unsigned char&gt;, std::vector&lt;std::vector&lt;long double&gt; &gt;, std::vector&lt;std::vector&lt;long long unsigned int&gt; &gt;))(long long unsigned int, long long unsigned int, std::vector&lt;unsigned char&gt;&amp;, std::vector&lt;std::vector&lt;long double&gt; &gt;&amp;, std::vector&lt;std::vector&lt;long long unsigned int&gt; &gt;&amp;)&gt;’:
  /usr/include/c++/4.8/thread:137:47:   required from ‘std::thread::thread(_Callable&amp;&amp;, _Args&amp;&amp; ...) [with _Callable = int (&amp;)(long long unsigned int, long long unsigned int, std::vector&lt;unsigned char&gt;&amp;, std::vector&lt;std::vector&lt;long double&gt; &gt;&amp;, std::vector&lt;std::vector&lt;long long unsigned int&gt; &gt;&amp;); _Args = {long long unsigned int&amp;, long long unsigned int&amp;, std::vector&lt;unsigned char, std::allocator&lt;unsigned char&gt; &gt;&amp;, std::vector&lt;std::vector&lt;long double, std::allocator&lt;long double&gt; &gt;, std::allocator&lt;std::vector&lt;long double, std::allocator&lt;long double&gt; &gt; &gt; &gt;&amp;, std::vector&lt;std::vector&lt;long long unsigned int, std::allocator&lt;long long unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;long long unsigned int, std::allocator&lt;long long unsigned int&gt; &gt; &gt; &gt;&amp;}]’
  test.cpp:44:130:   required from here
  /usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of&lt;int (*(long long unsigned int, long long unsigned int, std::vector&lt;unsigned char&gt;, std::vector&lt;std::vector&lt;long double&gt; &gt;, std::vector&lt;std::vector&lt;long long unsigned int&gt; &gt;))(long long unsigned int, long long unsigned int, std::vector&lt;unsigned char&gt;&amp;, std::vector&lt;std::vector&lt;long double&gt; &gt;&amp;, std::vector&lt;std::vector&lt;long long unsigned int&gt; &gt;&amp;)&gt;’
         typedef typename result_of&lt;_Callable(_Args...)&gt;::type result_type;
                                                               ^
  /usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of&lt;int (*(long long unsigned int, long long unsigned int, std::vector&lt;unsigned char&gt;, std::vector&lt;std::vector&lt;long double&gt; &gt;, std::vector&lt;std::vector&lt;long long unsigned int&gt; &gt;))(long long unsigned int, long long unsigned int, std::vector&lt;unsigned char&gt;&amp;, std::vector&lt;std::vector&lt;long double&gt; &gt;&amp;, std::vector&lt;std::vector&lt;long long unsigned int&gt; &gt;&amp;)&gt;’
           _M_invoke(_Index_tuple&lt;_Indices...&gt;)
       ^
  </code></pre>
  
  <p>I'm compiling in Linux using g++ 4.8.2 using:</p>
  
  <pre><code>g++ -Wall test.cpp -o test -std=c++0x 
  </code></pre>
  
  <p>Any feedback would be greatly appreciated. Thanks very much!</p>
  
  <p>My code is below:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;vector&gt;
  #include &lt;fstream&gt;
  #include &lt;thread&gt;
  #include &lt;cstdlib&gt;
  #include &lt;cmath&gt;
  
  
  int functionToRun (unsigned long long startingNum, unsigned long long endingNum, std::vector&lt;unsigned char&gt;&amp; mainReadCountVector, std::vector&lt;std::vector&lt;long double&gt;&gt;&amp; threadPWP, std::vector&lt;std::vector&lt;unsigned long long int&gt;&gt;&amp; threadWeightings);
  
  int main(int argc, const char * argv[])
  {
      int numThreads = 32;
  
      std::streampos size;
      std::ifstream file ("data.bin", std::ios::in|std::ios::binary|std::ios::ate);
      if (file.is_open()) {
          // Create and populate the vector that holds all the data in the binary file
          size = file.tellg();
          file.seekg (0, std::ios::beg);
          std::vector&lt;unsigned char&gt; data(size);
          file.read((char*) &amp;data[0], size);
          file.close();
  
          // The resulting calculations within each thread will be stored in a 2D vector that looks like std::vector&lt;std::vector&lt;long double&gt;&gt; calc1(272, std::vector&lt;long double&gt;(272,0)) and std::vector&lt;std::vector&lt;unsigned long long int&gt;&gt; calc2(272, std::vector&lt;unsigned long long int&gt;(272,0))
          // Create one of these vectors for each of the threads by making a 3D vector:
          std::vector&lt;std::vector&lt;std::vector&lt;long double&gt;&gt;&gt; calc1(numThreads, std::vector&lt;std::vector&lt;long double&gt;&gt; (272, std::vector&lt;long double&gt; (272,0) ) ); //calc1[0] is the first 2D array for the first thread, etc...
          std::vector&lt;std::vector&lt;std::vector&lt;unsigned long long int&gt;&gt;&gt; calc2(numThreads, std::vector&lt;std::vector&lt;unsigned long long int&gt; &gt; (272, std::vector&lt;unsigned long long int&gt; (272,0) ) );
  
          //Launch a group of threads
          std::vector&lt;std::thread&gt; threadsVec;
          for (int threadRunning = 0; threadRunning &lt; numThreads; threadRunning++) {
              unsigned long long firstNum = threadRunning * 1000000;
              unsigned long long secondNum = (threadRunning * 1000000) + 1000000 - 1;
              threadsVec.push_back(std::thread(functionToRun, firstNum, secondNum, data, calc1[threadRunning], calc2[threadRunning]));
          }
  
          // Wait on threads to finish
          for (int i = 0; i &lt; numThreads; ++i) {
              threadsVec[i].join();
          }
  
          // Now aggregate the results of the threads
          std::vector&lt;std::vector&lt;long double&gt;&gt; calc1Sum(272, std::vector&lt;long double&gt;(272,0));
          std::vector&lt;std::vector&lt;long double&gt;&gt; calc2Sum(272, std::vector&lt;long double&gt;(272,0));
          for (int element = 0; element &lt; 272; element++) {
              for (int comparisonElement = 0; comparisonElement &lt;= element; comparisonElement++) {
                  for (int threadVector = 0; threadVector &lt;= numThreads; threadVector++) {
                      calc1Sum[element][comparisonElement] += calc1[threadVector][element][comparisonElement];
                      calc2Sum[element][comparisonElement] += calc2[threadVector][element][comparisonElement];
                  }
              }
          }
      } else std::cout &lt;&lt; "Unable to open data.bin";
  
      return 0;
  }
  
  
  int functionToRun (unsigned long long startingNum, unsigned long long endingNum, std::vector&lt;unsigned char&gt;&amp; mainDataVector, std::vector&lt;std::vector&lt;long double&gt;&gt;&amp; calc1ret, std::vector&lt;std::vector&lt;unsigned long long int&gt;&gt;&amp; calc2ret) {
  
      int internalData[272];
  
      for (unsigned long long dataSpot = startingNum; dataSpot &lt; endingNum; dataSpot++) {
          for (int ind1 = 0; ind1 &lt; 272; ind1++) {
              unsigned long long firstIndex = dataSpot * 544 + 2 * ind1;
              unsigned long long secondIndex = dataSpot * 544 + 2 * ind1 + 1;
              internalData[ind1] = mainDataVector[firstIndex] + mainDataVector[secondIndex];
  
              for (int ind2 = 0; ind2 &lt;= ind1; ind2++) {
                  calc1ret[ind1][ind2] = internalData[ind1] + internalData[ind2];
                  calc2ret[ind1][ind2] = internalData[ind1] / (std::pow(internalData[ind2],2));
              }
          }
      }
      return 0;
  }
  </code></pre>