MultiThreading error: no matching overloaded function found - c++

Hi guys I am new to c++ and working on getting multithreading working.
What I am doing is trying to push 5 threads in a vector and make them multiply 2 matrices. However I keep getting this error. I know this will be flagged as a duplicate, but I am only asking because I couldn't really find another similar question in regards to threads.
The error I get based off the code below is the following:
Error C2672 'std::invoke': no matching overloaded function found
C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept()'
Here is my Code
#include "matrices.h"
#include <memory>
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <algorithm>
using namespace std;
int main()
{
std::vector<std::thread> threads;
CMatrix3 matrix1, matrix2, result;
std::thread::hardware_concurrency();
matrix1.SetElement(0, 0, 2);
matrix1.SetElement(0, 1, 2);
matrix1.SetElement(0, 2, 3);
matrix1.SetElement(0, 3, 1);
matrix1.SetElement(1, 0, 0);
matrix1.SetElement(1, 1, 0);
matrix1.SetElement(1, 2, 2);
matrix1.SetElement(1, 3, 5);
matrix1.SetElement(2, 0, 1);
matrix1.SetElement(2, 1, 6);
matrix1.SetElement(2, 2, 2);
matrix1.SetElement(2, 3, 0);
matrix1.SetElement(3, 0, 0);
matrix1.SetElement(3, 1, 2);
matrix1.SetElement(3, 2, 0);
matrix1.SetElement(3, 3, 2);
matrix2.SetElement(0, 0, 1);
matrix2.SetElement(0, 1, 1);
matrix2.SetElement(0, 2, 1);
matrix2.SetElement(0, 3, 1);
matrix2.SetElement(1, 0, 1);
matrix2.SetElement(1, 1, 1);
matrix2.SetElement(1, 2, 1);
matrix2.SetElement(1, 3, 1);
matrix2.SetElement(2, 0, 1);
matrix2.SetElement(2, 1, 1);
matrix2.SetElement(2, 2, 1);
matrix2.SetElement(2, 3, 1);
matrix2.SetElement(3, 0, 0);
matrix2.SetElement(3, 1, 2);
matrix2.SetElement(3, 2, 0);
matrix2.SetElement(3, 3, 2);
for (unsigned i = 0; i<5; ++i)
{
threads.push_back(std::thread(CMatrix3::Multiply, &matrix1, std::ref(matrix1), std::ref(matrix2), std::ref(result)));
}
std::for_each(threads.begin(), threads.end(),std::mem_fn(&std::thread::join));
result.display4by4(result);
int h;
cin >> h;
return 0;
}
CMatrix3::Multiply is the entry point function of the class CMatrix3, it takes in 3 arguments matrix1, matrix2 and resultant matrix which is an identity matrix that will be the result of the two multiplied matrices.
ie;this is what it looks like
CMatrix3 & CMatrix3::Multiply(const CMatrix3 & _rA, const CMatrix3 & _rB, CMatrix3 & _rResult)
If you can help I will be grateful.
Thanks

Since c++11 (specifically the introduction of lambdas and range-based for), constructs such as bind, mem_fn and cref have become much less relevant.
You can achieve what you're trying to do like this (assuming I have correctly inferred the interface of CMatrix3):
for (unsigned i = 0; i<5; ++i)
{
// static interface
threads.emplace_back([&]{ CMatrix3::Multiply(matrix1, matrix2, result); });
// or it could be one of these, depending on CMatrix3's interface:
// threads.emplace_back([&]{ matrix1.Multiply(matrix2, result); });
// threads.emplace_back([&]{ result = matrix1.Multiply(matrix2); });
}
for(std::thread& thread : threads) thread.join();
However, as the example stands, this would result in undefined behaviour since all five threads will race to overwrite the data in result.

Hi So I just fixed the error. The right code inside the for loop was supposed to be threads.push_back(std::thread(CMatrix3::Multiply,std::ref(matrix1), std::ref(matrix2), std::ref(result)));
as opposed to threads.push_back(std::thread(CMatrix3::Multiply, &matrix1,std::ref(matrix1), std::ref(matrix2), std::ref(result))); I added in an extra parameter.
On top of that the reason it threw errors when I used an object as the second parameter after specifying the entry point was because the Multiply function was a static. I apologize and thank you guys for trying to help me

Related

How to define a C++ function in VTK

I'm new with C++ and VTK. I'm trying to get cells ID into a rectilinearGrid basic example. I'm using this code, but the compiler say that is wrong with the error that I wrote in comment
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkFloatArray.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRectilinearGrid.h>
#include <vtkRectilinearGridGeometryFilter.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <array>
int main()
{
vtkNew<vtkNamedColors> colors;
std::array<int, 16> x = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> y = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> z = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
// Create a rectilinear grid by defining three arrays specifying the
// coordinates in the x-y-z directions.
vtkNew<vtkFloatArray> xCoords;
for (auto&& i : x)
{
xCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> yCoords;
for (auto&& i : y)
{
yCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> zCoords;
for (auto&& i : z)
{
zCoords->InsertNextValue(i);
}
// The coordinates are assigned to the rectilinear grid. Make sure that
// the number of values in each of the XCoordinates, YCoordinates,
// and ZCoordinates is equal to what is defined in SetDimensions().
//
vtkNew<vtkRectilinearGrid> rgrid;
rgrid->SetDimensions(int(x.size()), int(y.size()), int(z.size()));
rgrid->SetXCoordinates(xCoords);
rgrid->SetYCoordinates(yCoords);
rgrid->SetZCoordinates(zCoords);
vtkCell* GetCell(vtkRectilinearGrid * rgrid, int i, int j, int k) //I SHOULD INSERT IN HERE ";" FOR
{ //CLOSING THE STATEMENT. BUT IN
int dims[3]; //THIS WAY THE FUNCTION PARAMETER
rgrid->GetDimensions(dims); // BEHIND WOULDN'T BE CONNECTED.
if (i < 0 || i > dims[0] - 1 ||
j < 0 || j > dims[1] - 1 ||
k < 0 || k > dims[2] - 1)
{
return NULL; // out of bounds!
}
int pos[3];
pos[0] = i;
pos[1] = j;
pos[2] = k;
vtkIdType id;
id = vtkStructuredData::ComputeCellId(dims, pos);
return rgrid->GetCell(id);
};
// Extract a plane from the grid to see what we've got.
vtkNew<vtkRectilinearGridGeometryFilter> plane;
plane->SetInputData(rgrid);
plane->SetExtent(0, 46, 16, 16, 0, 43);
vtkNew<vtkPolyDataMapper> rgridMapper;
rgridMapper->SetInputConnection(plane->GetOutputPort());
vtkNew<vtkActor> wireActor;
wireActor->SetMapper(rgridMapper);
wireActor->GetProperty()->SetRepresentationToWireframe();
wireActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData());
// Create the usual rendering stuff.
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->AddActor(wireActor);
renderer->SetBackground(1, 1, 1);
renderer->ResetCamera();
renderer->GetActiveCamera()->Elevation(30.0);
renderer->GetActiveCamera()->Azimuth(15.0);
renderer->GetActiveCamera()->Zoom(1.0);
renderer->SetBackground(colors->GetColor3d("Beige").GetData());
renWin->SetSize(600, 600);
// interact with data
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}
How could be fixed?
UPDATE 1: I have inserted an image of the compiling error. Should be inserted ";" for closing the statement before {}
UPDATE 2: the exact error is
Errore (attivo) E0065 expected ';' RGrid C:\vtk\VTK-8.2.0\Examples\DataManipulation\Cxx\RGrid.cxx 73
I'm using Visual Studio. I have tried to drop the last ";" but nothing change
UPDATE 3: I have uploaded all the code
You have defined your GetCell function inside the body of the main function, which is not allowed in C++. Only a declaration would be allowed inside the body, hence the compiler expects a semicolon after the function header.
Move the whole GetCell function block outside the main function. If that leads to problems you cannot solve ask another question about them.

C++ Problem filling structs with values from another struct

I'm having an issue trying to figure out why I am not getting the correct functionality with a piece of code. I have looked around to try and find a solution however, I haven't been able to do so. Below is an example of my code:
//Structs
typedef struct
{
int gene[60];
int fitness;
} individual;
typedef struct
{
int cond[5];
int out;
}rule;
//Array of individuals
individual population[P]
int function(individual solution){
int k = 0;
//Array of rules
rule rulebase[10]
for (int i = 0; i < 10; i++){
for (int j = 0; j < 5; j++){
rulebase[i].cond[j] = solution.gene[k++];
}
rulebase[i].out = solution.gene[k++];
}
for (int i = 0; i < 5; i++){
cout << rulebase[0].cond[i];
}
The solution that is passed into the function is the first individual in 'population' and the gene array contains only binary numbers, for example:
gene = [0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1] //There will be 60 in total
The desired functionality is to fill the rule structures in the rulebase with the values found in the solution. For example, using the example above the first rule in the rulebase will have the values below in the 'cond' array:
[0, 0, 1, 0, 1]
and the 'out' will be the next integer in the solution:
[1]
Then the next rule will be filled with the next values in the solution the same way.
The problem that I am having is the code seems to be filling the 'cond' array of each rule with all of the values in the solution, as oppose to the desired way described above. For example, when I print the genes in 'rulebase[0]' I get:
[0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1]
As oppose to:
[0, 0, 1, 0, 1]
I can't seem to figure out why I am getting this problem as the code looks to me like it should work? Any help would be greatly appreciated as I am seriously struggling!
A rule contains only 5 values in cond, not 10 as you show. Its just your code that prints the values of rulebase[0] that is wrong, i.e. it exceeds array bounds and prints - in addition to the cond-values of rulebase[0] - the values of out and cond of the next rule, which - in memory - come next.

GEOS OverlayOp intersection operation

I am using GEOS 3.6.2 to compute an intersection between two polygons. I was able to construct my polygons, but when I try to compute the intersection it won't work.
Compiling my program in Debug mode, I get the error message:
The inferior stopped because it received a signal from the operating
system.
Signal name : SIGSEG
Signal meaning : Segmentation fault
Any idea where I'm wrong?
Here is my code:
#include <geos/geom/Polygon.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/operation/overlay/OverlayOp.h>
#include <iostream>
#include <array>
////////////////////////////////////////////////////////////////////////////////
geos::geom::Polygon* MakePoly(std::vector<std::vector<int>> const& polyCoords)
{
geos::geom::GeometryFactory* factory = geos::geom::GeometryFactory::create().get();
geos::geom::CoordinateSequence* temp = factory->getCoordinateSequenceFactory()->create((std::size_t) 0, 0);
std::vector<std::vector<int>>::const_iterator it_x = polyCoords.begin();
int size = it_x->size();
for (int i=0; i<size; i++)
{
temp->add(geos::geom::Coordinate(polyCoords[0][i], polyCoords[1][i]));
}
geos::geom::LinearRing *shell=factory->createLinearRing(temp);
//NULL in this case could instead be a collection of one or more holes
//in the interior of the polygon
return factory->createPolygon(shell,NULL);
}
////////////////////////////////////////////////////////////////////////////////
int main()
{
// Create geometry.
std::vector<std::vector<int>> polyCoords1 = {
{1, 1, 2, 2, 1, 1, 4, 5, 4, 1},
{1, 2, 2, 4, 4, 5, 5, 3, 1, 1}
};
geos::geom::Polygon* poly1 = MakePoly(polyCoords1);
std::vector<std::vector<int>> polyCoords2 = {
{4, 4, 6, 6, 4},
{1, 5, 5, 1, 1}
};
geos::geom::Polygon* poly2 = MakePoly(polyCoords2);
// Actually perform the operation.
geos::operation::overlay::OverlayOp intersection(poly1, poly2);
// Extracting the geometry of the intersection (position of the error).
geos::geom::Geometry* intersectionGeo = intersection.getResultGeometry( geos::operation::overlay::OverlayOp::OpCode::opINTERSECTION );
std::cout<<intersectionGeo->getArea()<<std::endl;
}
The problem in your code is getting the GeometryFactory pointer.
geos::geom::GeometryFactory::create() returns a smart pointer (std::unique_ptr) so after this line:
geos::geom::GeometryFactory* factory = geos::geom::GeometryFactory::create().get();
The unique_ptr returned by create is disposed.
Change that line with:
geos::geom::GeometryFactory::Ptr factory = geos::geom::GeometryFactory::create();
And the code works.

Why some fields of a object can be automatically initialized sometimes?(C++ in Eclipse using MacOSX GCC)

My title might be confusing, please read on. The question seems long, but rather simple to understand.
I am using Eclipse Oxygen MacOSX GCC to write C++. In my project, I have a class called FilterArray, and inside of it there are three private fields:
int arrayLength;
int * originalArray;
int * filteredArray;
And, (1)a function that prints out the array (2)a function to set array length with a random number up to 50 (3)a function to initialize the original array (4)a function that's to filter the original array and store the filtered array in filteredArray, several getter functions, and so on.
void FilterArray::printArray(int *arr);
void FilterArray::setArrayLength();
void FilterArray::createOrginalArray(); //random value assigned to each index
void FilterArray::filterTheArray(); //by a certain algorithm
void FilterArray::getOriginalArray();
I made three test cases to test my filterArray() function in main(). At first, I forgot to initialize the fliteredArray with the size(only declared it) for each of the objects, but to my surprise, two of the original arrays gets filtered succesfully, and the program gets halted at the process when the function filtered the third array.
I soon realized that the problem is indeed that I forgot to initialize the filtered array with the size so when the function runs, fliteredArray[index] would make no sense, however, why this situation did happen to the first two objects, but not the third??
If you need to further understand my question, please refer to the following code. I've cut it to the most succinct.
In my FilterArray.hpp:
#ifndef FILTERARRAY_HPP_
#define FILTERARRAY_HPP_
class FilterArray {
int *originalArray;
int arrayLength;
int *filteredArray;
public:
// Constructor
FilterArray();
void setArraySize();
int getArraySize();
int * getOriginalArray(int index);
int * getFilteredArray();
void printArray(int *arr);
};
#endif /* FILTERARRAY_HPP_ */
In my FilterArray.cpp:
#include "FilterArray.hpp"
#include <iostream>
#include <stdlib.h>
using namespace std;
#include <math.h>
// Constructor
FilterArray::FilterArray(){
}
// function definitions
void FilterArray::setArraySize(){
this->arrayLength = rand() % 25 + 25;
}
int FilterArray::getArraySize(){
return this->arrayLength;
}
int * FilterArray::getOriginalArray(int index){
return &this->originalArray[index];
}
int * FilterArray::getFilteredArray(){
return this->filteredArray;
}
void FilterArray::printArr(int *arr){
cout <<"["<<arr[0]<<", ";
for (int i = 1; i < this->arrayLength - 1; i++){
cout <<arr[i]<<", ";
}
cout <<arr[this->arrayLength - 1]<<"]"<<endl;
}
In my main.cpp:
#include <iostream>
#include <stdlib.h>
using namespace std;
#include <string>
#include "FilterArray.hpp"
int main() {
srand(time(NULL));
// Test Cases
// Object array1 is for case 1, and the same for 2 and 3.
FilterArray *array1 = new FilterArray();
FilterArray *array2 = new FilterArray();
FilterArray *array3 = new FilterArray();
array1->setArraySize();
array2->setArraySize();
array3->setArraySize();
cout <<"1"<<endl;
//array1->printArr(array1->getOriginalArray(0));
array1->printArr(array1->getFilteredArray());
cout <<"2"<<endl;
//array2->printArr(array2->getOriginalArray(0));
array2->printArr(array2->getFilteredArray());
cout <<"3"<<endl;
//array3->printArr(array3->getOriginalArray(0));
array3->printArr(array3->getFilteredArray());
delete array1;
array1 = NULL;
delete array2;
array2 = NULL;
delete array3;
array3 = NULL;
return 1;
}
And to my suprise, the output is:
1
[8, 0, 0, 0, -824775304, 32767, -666960016, 32767, 0, 0, 0, 0, 0, 0, 0, 0, 27, 1, -1201811687, 32767, -824775248, 32767, -824816597, 32767, 17, 40, 40, 0, 0, 0, -824775295, 32767, -666959792]
2
[524288, 0, 0, 0, -310902784, 2147471062, -9437184, 2147473470, 0, 0, 0, 0, 0, 0, 0, 0, 1769472, 65536, -820445184, 2147465309, -307232768, 2147471062, 1277886464, 2147471062, 1114112, 2621440, 2621440, 0, 0, 0, -310312960, 2147471062, 5242880, 2147473471, 0, 0, 0, 0, 0, 0, 0, 0, 1769472, 196608]
3
You can see in my main() there is nowhere I initialized the filteredArray, but why the first two objects can have it, but not the third? I delete the pointer after the main though, or is it because the program halts before the deletion of the pointer or what?
Thanks a lot guys!

Store pointer to Eigen Vector 'segment' without copy?

I have an Eigen Vector that I would like to refer to a segment at a later time (e.g. pass between functions) instead of modifying immediately.
Eigen::Matrix<float, Eigen::Dynamic, 1> vec(10);
// initialize
vec << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
I would like to create a pointer to a segment that I can refer to later. The following works but it creates a copy so any changes made to the segment are not reflected in the original vector.
const int start = 2;
const int end = 8
Eigen::Matrix<float, Eigen::Dynamic, 1> *block = new Eigen::Matrix<float, Eigen::Dynamic, 1>(end - start + 1, 1);
*block = vec.segment(start-1,end-1);
How can I keep a reference to the segment without copying?
You can use an Eigen::Map to wrap an existing segment of memory without copying. I'm not sure why you're allocating the *block object and not just using block. Using a Map it would look like
Eigen::Map<Eigen::VectorXf> block(&vec(start - 1), end - start + 1);
You then use the Map as you would a normal VectorXd, sans resizing and stuff. Simpler yet (at least according to #ggael), you can use an Eigen:Ref to refer to part of an Eigen object without inducing a copy. For example:
void times2(Eigen::Ref< Eigen::VectorXf> rf)
{
rf *= 2.f;
}
int main()
{
Eigen::Matrix<float, Eigen::Dynamic, 1> vec(10);
// initialize
vec << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
const int start = 2;
const int end = 8;
// This would work as well
//Eigen::Map<Eigen::VectorXf> block(&vec(start - 1), end - start + 1);
Eigen::Ref<Eigen::VectorXf> block = vec.segment(start, end - start + 1);
std::cout << block << "\n\n";
times2(block);
std::cout << vec << "\n";
return 0;
}
P.S. I think you're misusing the segment function. It takes a beginning position an the number of elements, i.e. (start, end-start+1).