0

I have a small C++ thread-based application that compiles and works correctly on my Windows machine with G++ 7.3.0. However, the very same .cpp file does not compile on another Linux machine, also using G++ 7.3.0.

I believe the reason must be in compiler options that I am not aware of. Particularly, I already tried specifying the -std version but it doesn't change anything.

As I believe this is not code-dependent, I'm not posting the code, but I will if it is helpful for someone

This is the error message I get on the second machine:

In file included from ./parallel_prefix_sum.cpp:4:0:
./parallel_executor.cpp: In instantiation of ‘void parallel_executor<T>::test_overhead() [with T = int]’:
./parallel_prefix_sum.cpp:24:19:   required from here
./parallel_executor.cpp:152:29: error: invalid use of non-static member function ‘void parallel_executor<T>::upsweep(std::vector<T>&, int, int, int) [with T = int]’
      threads.push_back(std::thread(upsweep, this, std::ref(input_vector), thread_partition_up[i], thread_partition_up[i+1], i%4));
                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./parallel_executor.cpp:79:8: note: declared here
   void upsweep(std::vector<T>& v, int begin, int stop, int d) {
        ^~~~~~~

Edit2: Here is a MRE

parallel_prefix_sum.cpp

#include <iostream>
#include <chrono>
#include <vector>
#include "parallel_executor.cpp"
using namespace std;

int sum (int a, int b){
    return a+b;
}

int main(){
    int size = 100;
    vector<int> my_input;
    for (int i = 0; i < size; i++) {
        my_input.push_back(i);
    }
    parallel_executor<int>* s = new parallel_executor<int>(my_input, sum, 1);
    s->test_overhead();
    return 0;
}

parallel_executor.cpp

#include <functional>
#include <vector>
#include <math.h>
#include <thread>
#include <chrono>

using namespace std;

template<class T> class parallel_executor{
    //public:
        vector<T> input_vector;
        function<T(T,T)> input_function;
        int workers;
        int size;

    public:
        parallel_executor(vector<T> v, function<T(T,T)> f, int w){
            for (int i = 0; i < v.size(); ++i){
                input_vector.push_back(v[i]);
            }
            input_function = f;
            workers = w;
            size = input_vector.size();
        }

        void upsweep(std::vector<T>& v, int begin, int stop, int d) {
            for (int i = begin + pow(2, d) - 1; i < stop && i < size; i += pow(2,d+1)) {
                int j = i + pow(2, d);
                v[j] = input_function(v[i], v[j]);
            }
        }

        void test_overhead(){
            std::vector<std::thread> threads;
            std::vector<int> thread_partition_up{0,size};
                for(int i = 0; i < thread_partition_up.size(); ++i){
                    threads.push_back(std::thread(upsweep, this, std::ref(input_vector), thread_partition_up[i], thread_partition_up[i+1], 1));
                }
            for(int i = 0; i < threads.size(); ++i){
                threads[i].join();
            }
        }
};
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
skrtskrt
  • 13
  • 3
  • Possible duplicate of [Start thread with member function](https://stackoverflow.com/q/10673585/580083) (hard to tell since we don't see all the relevant code). – Daniel Langr Jun 10 '19 at 08:19
  • I think seeing the code will very likely to help people answer you question, even if it turns out not to be 'code dependent' in the end. – john Jun 10 '19 at 08:35
  • Please provide the definition of the class. – Robert Andrzejuk Jun 10 '19 at 08:36
  • @samini for all that is holy in this post-c++11 world, *why* ? – WhozCraig Jun 10 '19 at 08:49
  • Is there a point to creating one million empty vectors, which you immediately discard? – molbdnilo Jun 10 '19 at 09:09
  • 1
    You should read about how to create a [mcve]. – molbdnilo Jun 10 '19 at 09:10
  • This is a preliminary test function that is supposed to measure very small times (in that one case, the time of creating a vector and assigning a function call result to it); the instruction is executed many times to get a statistically significant average. It is not meant to be called during normal use of the program. – skrtskrt Jun 10 '19 at 09:25

1 Answers1

2

You need an ampersand and a scope name:

threads.push_back(std::thread(&parallel_executor<T>::upsweep, this, std::ref(input_vector), thread_partition_up[i], thread_partition_up[i+1], 1));
//                            ^^^^^^^^^^^^^^^^^^^^^^^

If your code is accepted by MinGW, that's an implementation bug.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055