I am a complete beginner in using Boost, and I would like to multithread a certain function defined as (I have been following this thread in defining this function),
void function(size_t thread, size_t start_index, size_t sub_length, std::vector<double> vector, double** array, std::vector<std::string> list, std::vector<double> results) {
double value;
std::string line, buffer;
size_t end_index = start_index + sub_length;
for (size_t i = start_index; i < end_index; i++) {
int index = vector.at(i);
if (array[0][index] == -9999.0 || array[1][index] == -9999.0) {
continue;
}
else {
std::ofstream output_file("input_thread_" + std::to_string(thread) + ".inp");
output_file << std::to_string(array[0][index]) << "\n";
output_file << std::to_string(array[1][index]) << "\n";
output_file.close();
boost::process::system("sample_executable.exe", boost::process::std_in < "input_thread_" + std::to_string(thread) + ".inp", boost::process::std_out > "output_thread_" + std::to_string(thread) + ".out");
std::ifstream input_file("output_thread_" + std::to_string(thread) + ".out");
while (std::getline(input_file, line)) {
if (line.find("Output") != std::string::npos) {
std::istringstream iss(line);
iss >> buffer >> value;
results.at(i) = value;
break;
}
}
}
}
}
The results vector is my desired output of the function, and the desired output of the main script. I then call this function with,
double** array;
std::vector<std::thread> threads;
std::vector<double> vector, results;
std::vector<std::string> list;
size_t sub_length = 500 / 20;
size_t start_index = i * sub_length;
for (size_t i = 1; i < 3; i++) {
list.push_back(std::string(argv[i]));
}
for (size_t i = 0; i < 500; i++) {
vector.push_back(any_random_number);
}
array = new double*[2];
for (size_t i = 0; i < 2; i++) {
array[i] = new double[500];
}
for (size_t i = 0; i < 500; i++) {
array[0][i] = any_random_number;
array[1][i] = any_random_number;
}
// initializes the results vector
for (size_t i = 0; i < 500; i++) {
results.push_back(-9999.0);
}
for (size_t i = 0; i < num_threads; i++) {
threads.emplace(boost::bind(function, i, start_index, sub_length, vector, array, list, results));
}
for (auto& th : threads) {
th.join();
}
where array is a two-dimensional matrix. All the variables are declared and initialized in the main script.
Upon compilation, I receive this error:
function_name.cpp: In function ‘int main(int, char**)’:
function_name.cpp:254:151: error: no matching function for call to ‘std::vector<boost::thread>::emplace(boost::_bi::bind_t<void, void (*)(long unsigned int, long unsigned int, long unsigned int, std::vector<double>, double**, std::vector<std::__cxx11::basic_string<char> >, std::vector<double>), boost::_bi::list7<boost::_bi::value<long unsigned int>, boost::_bi::value<long unsigned int>, boost::_bi::value<long unsigned int>, boost::_bi::value<std::vector<double> >, boost::_bi::value<double**>, boost::_bi::value<std::vector<std::__cxx11::basic_string<char> > >, boost::_bi::value<std::vector<double> > > >)’
threads.emplace(boost::bind(function, i, start_index, sub_length, vector, array, list, results));
^
In file included from /share/hpcc/CPU/gcc/8.4.0/include/c++/8.4.0/vector:64,
from /share/hpcc/CPU/gcc/8.4.0/include/c++/8.4.0/bits/random.h:34,
from /share/hpcc/CPU/gcc/8.4.0/include/c++/8.4.0/random:49,
from function_name.cpp:8:
/share/hpcc/CPU/gcc/8.4.0/include/c++/8.4.0/bits/stl_vector.h:1135:2: note: candidate: ‘template<class ... _Args> std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::emplace(std::vector<_Tp, _Alloc>::const_iterator, _Args&& ...) [with _Args = {_Args ...}; _Tp = boost::thread; _Alloc = std::allocator<boost::thread>]’
emplace(const_iterator __position, _Args&&... __args)
^~~~~~~
/share/hpcc/CPU/gcc/8.4.0/include/c++/8.4.0/bits/stl_vector.h:1135:2: note: template argument deduction/substitution failed:
function_name.cpp:254:39: note: cannot convert ‘boost::bind(R (*)(B1, B2, B3, B4, B5, B6, B7), A1, A2, A3, A4, A5, A6, A7) [with R = void; B1 = long unsigned int; B2 = long unsigned int; B3 = long unsigned int; B4 = std::vector<double>; B5 = double**; B6 = std::vector<std::__cxx11::basic_string<char> >; B7 = std::vector<double>; A1 = long unsigned int; A2 = long unsigned int; A3 = long unsigned int; A4 = std::vector<double>; A5 = double**; A6 = std::vector<std::__cxx11::basic_string<char> >; A7 = std::vector<double>; typename boost::_bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type = boost::_bi::list7<boost::_bi::value<long unsigned int>, boost::_bi::value<long unsigned int>, boost::_bi::value<long unsigned int>, boost::_bi::value<std::vector<double> >, boost::_bi::value<double**>, boost::_bi::value<std::vector<std::__cxx11::basic_string<char> > >, boost::_bi::value<std::vector<double> > >](i, start_index, sub_length, std::vector<double>(vector), array, std::vector<std::__cxx11::basic_string<char> >(list), std::vector<double>(results))’ (type ‘boost::_bi::bind_t<void, void (*)(long unsigned int, long unsigned int, long unsigned int, std::vector<double>, double**, std::vector<std::__cxx11::basic_string<char> >, std::vector<double>), boost::_bi::list7<boost::_bi::value<long unsigned int>, boost::_bi::value<long unsigned int>, boost::_bi::value<long unsigned int>, boost::_bi::value<std::vector<double> >, boost::_bi::value<double**>, boost::_bi::value<std::vector<std::__cxx11::basic_string<char> > >, boost::_bi::value<std::vector<double> > > >’) to type ‘std::vector<boost::thread>::const_iterator’ {aka ‘__gnu_cxx::__normal_iterator<const boost::thread*, std::vector<boost::thread> >’}
threads.emplace(boost::bind(function, i, start_index, sub_length, vector, array, list, results));
~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Most of the posts I see regarding this error concerns member functions and templated functions, so I suspect that this might just be a simple fix that I do not know of.
Thank you in advance.