Segmentation fault when using OpenMP for_each and BOOST_FOREACH - c++

I searched a lot on a parallelized version of for_each in C++. I found the following piece of code regarding paralleling for_each from here:
template<class T, class Function>
void parallel_for_each(std::vector< T> & obj, Function f)
{
int size = obj.size();
#pragma omp parallel for firstprivate(f) shared(obj)
for (int i = 0; i < size; i++)
{
f(obj[i]);
}
}
Here is a piece of my code:
class A;
typedef std::vector <A> vec_A;
typedef std::vector <vec_A> vec_2D_A;
vec_2D_A a2d;
...
//serial
BOOST_FOREACH(vec_A& av, a2d)
{
for_each(av.begin(), av.end(), boost::bind(detect_Type, _1, CGAL, *this));
}
// parallel (segfault here!)
BOOST_FOREACH(vec_A& av, a2d)
{
parallel_for_each(av, boost::bind(detect_Type, _1, ALL, *this));
}
...
Class A is a class of a specific point. Each member has a variable corresponding to its coordinates and couple of other member variables.
The function detect_type is modifying members of av.
All members inside vec_pnt are independent from each other, but I still receive a segfault.
EDIT:
here is more section of code. detect_type is responsible to find the type of the each object of A using Nearest Neighbor search and help of the XfieldPlus class itself.
void detect_Type(A& PNT, const NNSerach NNType, const xFieldPlus& lst)
{
switch (NNType)
{
case 0:
{
Nvertex = ANN_nearest(tip, lst); // It is NOT thread safe.
}
break;
case 1:
{
Nvertex = BOOST_nearest(tip, lst);
}
break;
case 2: //we use CGAL
{
Nvertex = CGAL_nearest(tip, lst);
}
break;
default:
std::cout << "Unknown NN-Serach" << std::endl;
break;
}
....
for(Entity::edgeIterator edgIter = f.beginEdge(); edgIter!= f.endEdge(); ++edgIter)
{
mesh::Edge edg = *edgIter;
if (edg != ed)
{
if (lst.getVal(edg.vertex(0)) * lst.getVal(edg.vertex(1)) < 0.0 )
{
PNT._type = ON_EDGE_NEED;
return;
}
}
}
...
}

Related

std::coroutine_handle<Promise>::done() returning unexpected value

I am trying to write a simple round-robin scheduler for coroutines. My simplified code is the following:
Generator<uint64_t> Counter(uint64_t i) {
for (int j = 0; j < 2; j++) {
co_yield i;
}
}
...
void RunSimple(uint64_t num_coroutines) {
std::vector<std::pair<uint64_t, Generator<uint64_t>>> gens;
for (uint64_t i = 0; i < num_coroutines; i++) {
// Storing coroutines into a vector is safe because we implemented the move
// constructor and move assigment operator for Generator.
gens.push_back({i, Counter(i)});
}
// This is a simple round-robin scheduler for coroutines.
while (true) {
for (auto it = gens.begin(); it != gens.end();) {
uint64_t i = it->first;
Generator<uint64_t>& gen = it->second;
if (gen) {
printf("Coroutine %lu: %lu.\n", i, gen());
it++;
} else {
// `gen` has finished, so remove its pair from the vector.
it = gens.erase(it);
}
}
// Once all of the coroutines have finished, break.
if (gens.empty()) {
break;
}
}
}
When I run RunSimple(/*num_coroutines=*/4), I get the following output:
Coroutine 0: 0.
Coroutine 1: 1.
Coroutine 2: 2.
Coroutine 3: 3.
Coroutine 0: 0.
Coroutine 1: 1.
Coroutine 2: 2.
Coroutine 3: 3.
Coroutine 1: 1.
Coroutine 3: 3.
Coroutine 3: 3.
The last three lines of the output are unexpected... coroutines 1 and 3 do not seem to be exiting when I expect them to. Upon further investigation, this is happening because std::coroutine_handle<Promise>::done() is returning false for both of these coroutines. Do you know why this method is returning false... am I doing something wrong?
Edit: Here is my Generator implementation:
template <typename T>
struct Generator {
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
struct promise_type {
T value_;
std::exception_ptr exception_;
Generator get_return_object() {
return Generator(handle_type::from_promise(*this));
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() { exception_ = std::current_exception(); }
template <std::convertible_to<T> From> // C++20 concept
std::suspend_always yield_value(From&& from) {
value_ = std::forward<From>(from);
return {};
}
void return_void() {}
};
handle_type h_;
Generator(handle_type h) : h_(h) {
}
Generator(Generator&& g) : h_(std::move(g.h_)) { g.h_ = nullptr; }
~Generator() {
if (h_) {
h_.destroy();
}
}
Generator& operator=(Generator&& g) {
h_ = std::move(g.h_);
g.h_ = nullptr;
return *this;
}
explicit operator bool() {
fill();
return !h_.done();
}
T operator()() {
fill();
full_ = false;
return std::move(h_.promise().value_);
}
private:
bool full_ = false;
void fill() {
if (!full_) {
h_();
if (h_.promise().exception_)
std::rethrow_exception(h_.promise().exception_);
full_ = true;
}
}
};
Your program contains undefined behavior.
The issue is your fill resumes the coroutine when !full_, regardless of whether the coroutine is at final suspend or not, which you can learn by calling h_.done().
Generator<uint64_t> Counter(uint64_t i) {
for (int j = 0; j < 2; j++) {
co_yield i;
}
// final suspend
}
If you resume the coroutine at the final suspend point, it will destory itself and you can no longer do anything with the coroutine handle you have.
And you call fill from operator bool, meaning that it, when called while the coroutine is suspended at final suspend, first destroys the coroutine, and then tries to access it, which is UB:
fill(); // potentially destroy the coroutine
return !h_.done(); // access the destroyed coroutine
You could fix this by making fill aware of doneness:
void fill() {
if (!h_.done() && !full_) {
h_();
if (h_.promise().exception_)
std::rethrow_exception(h_.promise().exception_);
full_ = true;
}
}
Also, your move assignment operator leaks the current coroutine:
Generator& operator=(Generator&& g) {
h_ = std::move(g.h_); // previous h_ is leaked
g.h_ = nullptr;
return *this;
}
You probably want to have something like if (h_) h_.destroy(); in the beginning.
Also, as mentioned in the comments, the full_ member has to be carried over in the move constructor and assignment operators:
Generator(Generator&& g)
: h_(std::exchange(g.h_, nullptr))
, full_(std::exchange(g.full_, false)) {}
Generator& operator=(Generator&& g) {
full_ = std::exchange(g.full_, false);
...
}

C/C++ Runtime Multidimensional Dynamic Array

I have the following structure:
typedef struct _DynamicArray {
int *data = nullptr;
_DynamicArray *ptr_next = nullptr;
_DynamicArray *ptr_dim = nullptr;
} DynamicArray; // so that every matrix cell contains another matrix cell
And then the following recursive method:
void _BuildArray(std::string const& source, StringIterator& sit, DynamicArray *dArray, bool& error) {
if (!error) {
while (sit+1 < source.length()) {
++sit;
switch (source[sit]) {
case '[':
dArray->ptr_dim = new DynamicArray();
_BuildArray(source, sit, dArray->ptr_dim, error);
break;
case ']':
return;
case ',':
break;
case ' ':
break;
default:
std::string str;
while (std::isdigit(source[sit])) {
str.push_back(source[sit]);
++sit;
}
--sit;
if (str.empty()) {
error = true;
return;
}
else {
dArray->data = new int(stoi(str));
dArray->ptr_next = new DynamicArray();
dArray = dArray->ptr_next;
}
break;
}
}
}
}
And then if I pass "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]" as a parameter, it builds the following flatten: "[1,2,6,7,8]" (instead of "[1,2,3,4,5,6,7,8]"). Why?
The calling snippet is this:
StringIterator sit = 0;
bool error = false;
this->dynArray = new DynamicArray();
_BuildArray(this->listString, sit, this->dynArray, error);
Once your recursive _BuildArray call returns, you don't advance dArray like you do in the default: case. Meaning the next [ you encounter will overwrite the results of the previous [.
This answer is just to clarify my comment, I was talking about a structure which utilizes C++ STL structures to avoid having to manually manage allocations and dynamic memory, something like:
class CellVisitor
{
public:
virtual accept(Cell* cell) = 0;
};
class Cell
{
public:
virtual void visit() = 0;
};
class ContainerCell : public Cell
{
private:
std::vector<std::unique_ptr<Cell>> cells;
public:
void addCell(...) { ... }
void visit(CellVisitor* visitor) override
{
visitor->accept(this);
for (auto& cell : cells)
cell->visit();
}
};
class IntegerCell : public Cell
{
private:
std::vector<int> data;
public:
void visit(CellVisitor* visitor) override
{
visitor->accept(this);
}
}

Check for changes in POD variables

I'm looking for an efficient way to check if a POD variable is altered between two cycles. I've come up with this solution:
class Foo {
public:
template<typename T>
bool isChanged(T& entry);
void endCycle();
private:
std::map<void*,size_t> entryMap; // <Address orig.,Size>
std::map<void*,void*>oldVals; // <Address orig., Address cpy.>
};
template<typename T> bool Foo::isChanged(T& entry)
{
entryMap[&entry] = sizeof(T);
if(oldVals[&entry] == NULL)
return false;
if(memcmp(&entry, oldVals[&entry], entryMap[&entry]))
return true;
else
return false;
}
void Foo::endCycle()
{
// Copy all the bytes to save them for the next cycle
for( std::map<void*,size_t>::iterator entryIt = entryMap.begin();
entryIt != entryMap.end();
++entryIt)
{
if(oldVals[entryIt->first] == NULL)
oldVals[entryIt->first] = malloc(entryIt->second);
memcpy(oldVals[entryIt->first], entryIt->first, entryIt->second);
}
}
Now i can use it like this:
Foo gBar;
void aFunction()
{
int ar;
char ba[3][3];
// Some code where ar and ba are filled
if(gBar.isChanged(ar))
// Do Something
if(gBar.isChanged(ba))
// Do Something
gBar.endCycle();
}
Is this an efficient way? My goal was a method which is very easy to use inside various cyclically called functions. I cleaned all the init and free logic from the code. Any suggestions? I especially don't like the oldshool malloc, memcpy and memcmp stuff but i don't know any other way how to do it.
Edit: Found a good solution based on Red Alerts suggestions.
I think you can use templates a little more effectively here.
template <typename T>
class Foo
{
public:
static std::map<T*, T> values;
static bool isChanged(T& entry)
{
auto it = values.find(&entry);
if(it == values.end())
{
values[&entry] = entry;
}
else if(entry != it->second)
{
it->second = entry;
return true;
}
return false;
}
};
template <typename T>
std::map<T*, T> Foo<T>::values;
int main() {
int ar = 3;
cout << Foo<int>::isChanged(ar) << endl; // 0
ar = 4;
cout << Foo<int>::isChanged(ar) << endl; // 1
for(auto& value : Foo<int>::values)
cout << value.second << endl; // 4
return 0;
}
This way you get one map per type, and you don't have to worry about inadvertently messing up an alias. You do need to define operator != and have a working copy constructor for your types, but that is much better than blindly using memcmp and memcpy.
You can also make further template specializations for arrays if you need to compare those (will be a bit more code, but nothing very complicated)
Edit: To get you started, this is what your template signature should look like:
template<class T, size_t N> bool isChanged(T(&entry)[N]); //will be called for stack allocated arrays
Or you can use char* to alias all of your values. This will let you use a single map for everything (like you were doing before, but this has no memcpy/memcmp). It will only work for POD. We could manually call the destructor when overwriting the buffer, but since there is no good way to do this in the class's destructor, it's probably best to leave out heap allocated data altogether.
class Foo
{
std::map<char**, char*> values;
public:
~Foo()
{
for(auto& value : values)
{
delete[] value.second;
}
}
template<typename T> bool isChanged(T& entry)
{
char** addr = reinterpret_cast<char**>(&entry);
auto it = values.find(addr);
if(it == values.end())
{
alignas(T) char* oldBuf = new char[sizeof(T)];
T* oldEntry = new(oldBuf) T;
*oldEntry = entry;
values[addr] = oldBuf;
}
else if(entry != *(reinterpret_cast<T*>(it->second)))
{
T* oldEntry = new(it->second) T;
*oldEntry = entry;
return true;
}
return false;
}
};
After many hours i think i found a good solution. The call stays easy and there are no casts. It's a lot more complex than the C-Style version with memcopy but I think its nicer and has also the benefit that it works with complex data not just POD.
class Manager
{
public:
~Manager()
{
funcPtrs.clear();
}
void adFnc(void(*function)())
{
funcPtrs.push_back(function);
}
void runAll()
{
for(auto& val : funcPtrs)
val();
}
private:
std::vector<void (*)()> funcPtrs;
};
Manager gAllClearManager;
template<typename T>
class Data
{
public:
Data()
{
gAllClearManager.adFnc(clearValues);
}
static void clearValues()
{
values.clear();
}
static std::map<T*,std::vector<T>>& getValues() { return values; }
private:
static std::map<T*,std::vector<T>> values;
};
template <typename T>
static bool isChanged(T& entry)
{
const static Data<T>* dataP = new Data<T>();
static std::map<T*,std::vector<T>>& values = dataP->getValues();
auto it = values.find(&entry);
if(it == values.end())
{
values[&entry].push_back(entry);
}
else if(entry != it->second[0])
{
it->second[0] = entry;
return true;
}
return false;
}
template<typename T, size_t N>
bool isChanged(T (&entry)[N])
{
const static Data<T>* dataP = new Data<T>();
static std::map<T*,std::vector<T>>& values = dataP->getValues();
auto it = values.find(entry);
if( it == values.end())
{
for(int i = 0; i < N ; ++i )
values[entry].push_back(entry[i]);
return false;
}
else
{
for(int i = 0; i < N ; ++i )
{
if(it->second[i] != entry[i])
{
for(int j = 0; j < N ; ++j )
{
it->second[j] = entry[j];
}
return true;
}
}
}
return false;
}
template<typename T>
std::map<T*, std::vector<T>> Data<T>::values;
Now i can use it like:
int main() {
int ar;
std::string ba[6];
if(isChange(ar))
// Do something
if(isChange(ba))
// Do something
}
My first template is finally working! :) Thanks again Red Alert.

How to specify degenerate dimension of boost multi_array at runtime?

I have a 3D multi_array and I would like to make 2D slices using dimensions specified at runtime. I know the index of degenerate dimension and the index of a slice that I want to extract in that degenerate dimension. Currently the ugly workaround looks like that:
if (0 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[slice_index][range()][range()]];
}
else if (1 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[range()][slice_index][range()]];
}
else if (2 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[range()][range()][slice_index]];
}
Is there a more beautiful way to construct index_gen object?
Something like that:
var slicer;
for(int i = 0; i < 3; ++i) {
if (degenerate_dimension == i)
slicer = boost::indices[slice_index];
else
slicer = boost::indices[range()];
}
Slice slice = input_array[slicer];
It seems each subsequent call to boost::indices::operator[] returns a different type depending on the dimensionality (i.e. number of previous calls), so there's no way to use a single variable, that can hold the temporary index_gen object.
Please, try this. Сode has one disadvantage - it refers to ranges_ array variable declared at boost::detail:: multi_array namespace.
#include <boost/multi_array.hpp>
typedef boost::multi_array<double, 3> array_type;
typedef boost::multi_array_types::index_gen::gen_type<2,3>::type index_gen_type;
typedef boost::multi_array_types::index_range range;
index_gen_type
func(int degenerate_dimension, int slice_index)
{
index_gen_type slicer;
int i;
for(int i = 0; i < 3; ++i) {
if (degenerate_dimension == i)
slicer.ranges_[i] = range(slice_index);
else
slicer.ranges_[i] = range();
}
return slicer;
}
int main(int argc, char **argv)
{
array_type myarray(boost::extents[3][3][3]);
array_type::array_view<2>::type myview = myarray[ func(2, 1) ];
return 0;
}
What you're trying to do is move a variable from run time to compile time. This can only be done with a chain of if else statements or a switch statement.
A simplified example
// print a compile time int
template< int I >
void printer( void )
{
std::cout << I << '\n';
}
// print a run time int
void printer( int i )
{
// translate a runtime int to a compile time int
switch( i )
{
case 1: printer<1>(); break;
case 2: printer<2>(); break;
case 3: printer<3>(); break;
case 4: printer<4>(); break;
default: throw std::logic_error( "not implemented" );
}
}
// compile time ints
enum{ enum_i = 2 };
const int const_i = 3;
constexpr i constexper_i( void ) { return 4; }
// run time ints
extern int func_i( void ); // { return 5; }
extern int global_i; // = 6
int main()
{
int local_i = 7;
const int local_const_i = 8;
printer<enum_i>();
printer<const_i>();
printer<constexpr_i()>();
//printer<func_i()>();
//printer<global_i>();
//printer<local_i>();
printer<local_const_i>();
printer( enum_i );
printer( const_i );
printer( constexpr_i() );
printer( func_i() ); // throws an exception
printer( global_i ); // throws an exception
printer( local_i ); // throws an exception
printer( local_const_i ); // throws an exception
}

Getting crash while calling a function which need reference to vector

I want to know is there something wrong in passing in passing vector reference to a function as in the example below. This code is running well and nice. But the same type of code in my project gives me crash. I don't know why.
In that case whenever I calls the function which need std::vector & . then in the called function the size of the vector reaches some millionsss.... I have attached screenshot where I am actually getting this crash.
I just wants to know is there something wrong in these type of implementations...
#include <iostream>
#include <vector>
#include <string>
class A {
public:
A() {}
~A() {}
void GetVector(std::vector<std::wstring> &in) {
std::wstring s = L"Hello";
for(int i = 0; i < 10; i++)
in.push_back(s);
}
};
class B {
public:
B() {}
~B() {}
void GetData() {
A a;
std::vector<std::wstring> s;
a.GetVector(s);
}
};
int main() {
B b;
b.GetData();
return 0;
}
Real code where I am getting the crash...
void SCPreferenceComp::PopulateComboBox()
{
SCConfig *config = SCConfig::GetInstance();
std::vector<std::wstring> languages;
config->GetAllLangugesName(languages);
for(size_t i = 0; i != languages.size(); i++)
mLangListComboBox->addItem(languages[i].c_str(), i+1);
if(mLangListComboBox->getNumItems() > 0)
mLangListComboBox->setSelectedId(1);
}
bool SCConfig::GetAllLangugesName(std::vector<std::wstring> &outLangNames)
{
bool retVal = false;
do
{
if(!mXMLDoc)
break;
xercesc::DOMNodeList *langNodeList = mXMLDoc->getElementsByTagName(strToX("language"));
if(!langNodeList)
break;
const XMLSize_t langCount = langNodeList->getLength();
for(XMLSize_t i = 0; i < langCount; i++)
{
xercesc::DOMNode *curLangNode = langNodeList->item(i);
if(!curLangNode)
continue;
xercesc::DOMElement *curLangElem = dynamic_cast<xercesc::DOMElement*>(curLangNode);
if(!curLangElem)
continue;
wxString s = strToW(curLangElem->getAttribute(strToX("name")));
outLangNames.push_back(s.c_str());
}
retVal = true;
}while(false);
return retVal;
}
I can't see anything wrong in that implementation other than the fact that it doesn't have any visible end result which leads me to believe it may not exactly match your failing code.