0

I am creating a program with a dynamic number of threads. I have a vector for the threads (thanks, Mohamad); then I attempt to call a function and pass multiple arguments for the thread of execution.

However, my current code gives an error which I assume is due to my odd usage of the 2D array:

In function 'int main()': 102 77 [Error] no matching function for call to 'std::thread::thread(void (&)(float ()[2], float, int, int), float [(((sizetype)(((ssizetype)nodeNumber) + -1)) + 1)][2], float [(((sizetype)(((ssizetype)nodeNumber) + -1)) + 1)], int&, int&)'

102 77 [Note] candidates are: 4 0

133 7 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread [Note] template std::thread::thread(_Callable&&, _Args&& ...)

133 7 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread [Note] template argument deduction/substitution failed:

102 77 [Note] variable-sized array type 'float (&)[(((sizetype)(((ssizetype)nodeNumber) + -1)) + 1)][2]' is not a valid template argument

4 0 In file included from

128 5 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread [Note] std::thread::thread(std::thread&&)

128 5 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread [Note] candidate expects 1 argument, 5 provided

122 5 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread [Note] std::thread::thread() 122 5 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread [Note] candidate expects 0 arguments, 5 provided

Here are some of the chunks of code where I am attempting this:

#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <vector>
using namespace std;


void map(float rank_matrix[][2], float adjacency_matrix[], int nodeNumber, int node);

int main()  {
    // setup code, initialization section here

        float adjacency_matrix[nodeNumber][nodeNumber];
        float rank_matrix[nodeNumber][2];

    while(iter < terminate)  {

        vector<thread> threads;

        for(int i = 0; i < nodeNumber; i++)  {
            threads.push_back(std::thread(map, rank_matrix, adjacency_matrix[i], nodeNumber, i);
        }

        for(int i = 0; i < nodeNumber; i++)  {
            threads.join();
        }

        // Flush out the mass for each node (will be updated based on mapper's work.
        for(i = 0; i < nodeNumber; i++)  {
            rank_matrix[i][0] = 0;
        }

        iter++;
        cout << endl;
        cout << endl;
    }

    return 0;
}


// Mapper code for each individual node and computation.
void map(float rank_matrix[][2], float adjacency_matrix[], int nodeNumber,    int node)  {
    for(int i = 0; i < nodeNumber; i++)  {
        if(rank_matrix[node][1] != 0 && adjacency_matrix[i] > 0)
            adjacency_matrix[i] = (rank_matrix[node][0] / rank_matrix[node][1]); 
    }
}

Any suggestions on what I'm doing wrong? Help would be much appreciated! Thanks!

NathanOliver
  • 171,901
  • 28
  • 288
  • 402

2 Answers2

3
thread myThread[nodeNumber];

This creates a number of default-initialized threads i.e threads that do not represent any thread of execution.

myThread[i](map, rank_matrix, adjacency_matrix[i], nodeNumber, i);

Does not initialize your threads.

I would suggest using a vector of threads like in this example

std::vector<std::thread> threads;

This does not create any actual threads. Just the container to hold them.

Then you can populate it like so:

for(int i = 0; i < nodeNumber; i++)  {
    threads.push_back(std::thread(map, rank_matrix, adjacency_matrix[i], nodeNumber, i);
}
Mohamad Elghawi
  • 2,071
  • 10
  • 14
  • Thanks for the response. I tried your suggestion, but I get this error: [Error] no matching function for call to 'std::thread::thread(void (&)(float (*)[2], float*, int, int), float [(((sizetype)(((ssizetype)nodeNumber) + -1)) + 1)][2], float [(((sizetype)(((ssizetype)nodeNumber) + -1)) + 1)], int&, int&)' – RecursionIsSexy Oct 21 '15 at 16:09
  • I included the vector library. I'm wondering if it doesn't like my map function. Basically, the adjacency_matrix is a 2D array, but I have hacked it so that I only pass in rows and do calculations. It works without using threads when I test it. Now I am just trying to use threads to split work between pieces of the array (using the nodes). – RecursionIsSexy Oct 21 '15 at 16:10
  • Could you edit your existing post or ask another question and post an [mcve](http://stackoverflow.com/help/mcve). Post just enough code to allow us to fire it up and see what the problem is. – Mohamad Elghawi Oct 21 '15 at 16:16
  • I think the issue is the variable sized array adjacency_matrix. – RecursionIsSexy Oct 21 '15 at 16:32
  • Does your example compile for you? Because it doesn't for me. – Mohamad Elghawi Oct 21 '15 at 16:37
  • It doesn't compile because of the errors I posted. I know the map function works because I can use it without threading. – RecursionIsSexy Oct 21 '15 at 16:38
  • I'm going to delete this question and tweak a few things and come back later. Since I know the problem isn't the way I'm doing the threads, I think my function arguments must have some problem. I'll be back with a new post if I can't figure it out. Thanks for your help! – RecursionIsSexy Oct 21 '15 at 16:41
  • I gave you credit, though, because your answer in general will help other users. – RecursionIsSexy Oct 21 '15 at 16:42
2
myThread[i](map, rank_matrix, adjacency_matrix[i], nodeNumber, i);

Is attemting to call the function call operator on myThread[i] with the supplied parameters not calling a constructor. thread myThread[nodeNumber]; already constructs the threads so what you need to do is assign a thread to each element of the array

myThread[i] = thread(map, rank_matrix, adjacency_matrix[i], nodeNumber, i);
NathanOliver
  • 171,901
  • 28
  • 288
  • 402