"openmp parallel for" crashes when looping over QList<class> - thread-safety

I have a class 'MyFITS' holding a 2D image from a camera with detector 'chip'. And I have a QList holding pointers to a number of images from that camera. Now I want to parallelize a for loop like this:
#pragma omp parallel for
for (int chip=0; chip<n; ++chip) {
QStringList filenames = getFilenames(chip);
QList<MyFITS*> images;
// Read in all images from detector 'chip'
for (auto &it : filenames) {
MyFITS *image = new MyFITS(it);
images << image;
}
do_some_calculations(images);
for (auto &it : images) delete it;
}
This works fine without the #pragma directive.
However, with the #pragma directive it crashes in the first line in the second for loop, MyFITS *image = new MyFITS(it). Each thread enters it only once.
I don't understand this. Aren't all variables declared in the for loops private? Which part in this code is not thread safe? I must be overlooking something very simple.
Thank you,
Mischa Schirmer

Related

Attempting to store references to c++ vectors returned by reference still giving me copies

Back in '98 I converted my chemical model from objective-c to c++ after replacing my old NeXT, but I didn't really get a chance to learn c++. I'm now rewriting the code into modern c++, which means learning to use containers, smart pointers, and templates.
I need to parse output variables only once up front, rather than at each time step, so I originally produced a pointer array of output variable pointers (float ***outVars). I could run through the list of pointers after each time interval, and since outVars pointed to the original data, they would always provide the current state of the model.
I'm changing code from matrices of naked pointers to matrices of vectors. I haven't been able to return anything but copies of vectors, rather than references to the original vectors. I don't want to modify the vectors, I just need direct read access.
I can't believe I haven't found my answer online yet. Most that I've found online has simply said use std::vector<float> & to return by reference, but clearly that isn't working.
I saw one note that assigning a reference to a non-reference value (I assume they meant variable) will make it copy, so I tried fvec2D &outVar2D; (see the header file below).
I've tried with and without const, no difference.
I've tried returning vector.data(), but assigning it to a new vector was also copying. Maintaining pointers to .data() memory blocks seems be a very bad idea, if I need to resize the original vector.
I've tried wrapping the vector in std::shared_ptr, but found I'd need to wrap each dimension vector in a shared_ptr, which got overly cumbersome real fast.
I saw one suggestion to return vector::iterators. I haven't managed to get that to work yet. Maybe having 2D data is getting in the way of that. I'm still trying to get that to run without crashing when I examine the iterator.
I don't know if using a 1D array would solve this, but calculating every index reference for millions of calls seems suboptimal.
I considered using std::array too but vectors seemed the simplest conversion. Perhaps I should rethink that.
If anyone has any suggestions for how to do this, I'd very much appreciate it.
class chem - manages original matrix concentration
class chem
{
public:
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
chem(int xstep, int zstep) : concentration(xstep, fvec1D(zstep, 1.5)) {}
...
const fvec2D &getConc() const { return concentration; }
const fvec1D &getConc(int x) const {return concentration[x]; }
private:
fvec2D concentration;
};
class model - needs read access to chem::concentration
class model
{
public:
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
...
private:
fvec2D null2D {{0.0}};
fvec1D null1D {0.0};
fvec2D &outVar2D;// = null2D; // tried this and at ctor
fvec1D &outVar1D;// = null1D;
std::vector<std::unique_ptr<chem> > chemList;
};
model::model() : outVar2D(null2D), outVar1D(null1D)
{
outVar2D = chemList[0]->getConc(); // or
outVar1D = chemList[0]->getConc(1);
}
void model::plot()
{
for (int z=0; z<numZSteps; ++z) {
std::cout << outVar1D[z];
std::cout << outVar2D[1][z];
}
}
void model::run()
{
plot(); // produces init concentration of 1.5 at each z
chemList[0]->changeConc(); // Changes values in concentration
plot(); // STILL produces init conc of 1.5 at each z
}
I don't know if answering my own question is appropriate (please let me know). I know this question will be autodeleted, so I thought I'd present the solution I came up with, because I'm still VERY interested in hearing any suggestions of the best way to do this. I'm still so far down the learning curve I know I can't intuitively see c++ programming techniques.
I gathered from comments that what I was trying won't work, so I wrapped my vectors in shared_ptrs, which I know can work. I created some wrapper classes to manage 2 levels of shared_ptr (one for the multidimensional spatial data, and one for the list of output variables). It also keeps the array-type indexing intact as well as defines behavior for operator=.
I have only included the 2D classes here. I have 4 similar classes to handle the 1D and 3D cases as well.
I know what I'm posting is not great. it's not very elegant, requiring 2 classes for each dimensional case (1D, 2D, 3D data). Perhaps I can simplify it using templates. I've only written very elementary templates so far. Since each class decays (using operator[]) to a unique class I'm not sure if a template will help.
I haven't figured out all the const keyword placements yet - I removed them all for now, out of frustration with the compiler complaints. I'll get that down when I can take the time.
I also don't know exactly what sort of behavior I want for copy and move constructors, though I'm pretty sure I need them for vector resize operations, which I just realized I haven't even implemented yet. The important thing for me here was just to get read access to the vectors across classes, such that when the vectors change it is reflected elsewhere without re-parsing my output variables.
#include <memory>
#include <vector>
namespace MDType {
class fpv2D;
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
typedef std::vector<std::vector<std::vector<float> > > fvec3D;
typedef std::shared_ptr<fvec1D> fvec1Dptr;
typedef std::shared_ptr<fvec2D> fvec2Dptr;
typedef std::shared_ptr<fvec3D> fvec3Dptr;
typedef std::vector<fpv2D> fvpv2D;
typedef std::shared_ptr<fvpv2D> fvpv2Dptr;
class fpv2D
{
public:
fpv2D(int x=1, int z=1, float fill=0.0) : theArray(new fvec2D(x, fvec1D(z, fill))) {}
fpv2D(const fpv2D &otherT) = default; // Pretty sure this needs to change
fpv2D( fpv2D &&otherT) {theArray = otherT.data(); }
fvec2Dptr &data() { return theArray; }
fvec1D &operator[](int index) {return theArray->data()[index]; }
void operator=( fpv2D& rhs) { theArray = rhs.data(); }
private:
fvec2Dptr theArray;
};
class fpvpv2D
{
public:
fpvpv2D(int index, int x=1, int z=1, float fill=0.0) : theArray(new fvpv2D(index, fpv2D(x, z, fill))) {}
fpvpv2D(const fpvpv2D &otherT) = default; // Pretty sure this needs to change
fpvpv2D( fpvpv2D &&otherT) {theArray = otherT.data(); }
fvpv2Dptr &data() { return theArray; }
fpv2D &operator[](int index) {return theArray->data()[index]; }
void operator=( fpvpv2D& rhs) { theArray = rhs.data(); }
private:
fvpv2Dptr theArray;
};
}
... so ...
MDType::fpv2D conc(numX, numZ, 1.5);
MDType::fpvpv2D outVar2D(numOutVars, numX, numZ);
outVar2D[1] = conc;
cout << outVar2D[1][3][5]; // prints 1.5
conc[3][5] = 12.0;
cout << outVar2D[1][3][5]; // prints 12.0

Add multiple QFrames into a single QFrame at runtime while using MSVC

I am creating a main window having a number of frames as child frames on it. I want to add these frames at runtime and i am using the following code.
in NFrame.h
In NFrame.h
QList<QFrame *> nFrame;
and initialize them in NFrame.cpp as
In Nframe.cpp
for(int i=1;i<=n;i++)
{
nFrame[i] = new QFrame(this);
nFrame[i]->show();
}
Is this a correct way to do this or i have to do something else.
I have found my mistake in the above code. I was trying to initialize a QList with a new Instance of of QFrame. As structure of QList is very much similar to an array so In the QList we can add items either byinsert() method or by append().
The following code correct my mistakes.
for(int i=0;i<n;i++)
{
nFrame.append(new QFrame(this));
nFrame[i]->show();
}

Merging multiple images to get a video in OpenCV

What I want to do is to produce a video composed from a single image, repeated for many frames.
I have tried the below code but it is producing a video file of size 0 bytes.
IplImage *image = cvLoadImage("images/img1.jpg", 1);
CvVideoWriter* writer = cvCreateVideoWriter("Video from Images.flv",
CV_FOURCC('D','I','V','X'), fps, size);
for(int counter=0; counter < 300; counter++)
{
/*The below statement writes the frame one by one to the video ...*/
cvWriteFrame(writer, image);
}
You need to call cvReleaseVideoWriter(CvVideoWriter** writer) at the end.
Had you used the C++ API, the destructor would have taken care of this for you.

How to get multitouch to work in QGraphicsView, Qt 5.0.2 in Windows 8

I am struggling with getting multi-touch to work on a couple of QWidgets that I have added to a QGraphicsView. I have created a subclass of QWidget in which I set up a QGraphicsScene and QGraphicsView. This is my (test) subclass of QWidget:
#include "qttest1.h"
#include <QtWidgets>
#include <QTouchEvent>
qttest1::qttest1(QWidget *parent)
: QWidget(parent)
{
setEnabled(true);
if(!QCoreApplication::testAttribute(Qt::AA_DontCreateNativeWidgetSiblings))
setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_AcceptTouchEvents);
scene = new QGraphicsScene(this);
scene->setSceneRect(0, 0, 1920, 1080);
graphicsView = new QGraphicsView(scene, this);
graphicsView->setRenderHints(QPainter::Antialiasing);
graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
graphicsView->setAttribute(Qt::WA_AcceptTouchEvents);
graphicsView->viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
QBoxLayout *layout = new QVBoxLayout;
layout->addWidget(graphicsView);
setLayout(layout);
}
qttest1::~qttest1() {}
void qttest1::showGraphics()
{
for(int i = 0; i < 10; i++)
{
Dial *dial = new QDial();
dial->move(i * 120 + 50, 200);
dial->resize(120, 120);
dial->setAttribute(Qt::WA_AcceptTouchEvents);
QGraphicsProxyWidget *proxy = scene->addWidget(dial);
proxy->setAcceptTouchEvents(true);
}
}
This is my main:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
QRect rect = app.desktop()->screenGeometry();
qttest1 test;
test.resize(rect.width(), rect.height());
test.showFullScreen();
test.showGraphics();
return app.exec();
}
I know the code isn't pretty and probably leaking a bit, but the point is to try to get multi-touch to work.
I can see and use every kind of widget I add to the scene, but as soon as I touch a dial it swallows every touch that comes after the first. Which makes the dial jump between several positions. What I want is that every dial (or any type of widget) can be used individually and at the same time. I am using QT 5.0.2, Windows 8 with a monitor that supports up to 10 touches.
The Qt docs state : -
Reimplement QWidget::event() or QAbstractScrollArea::viewportEvent()
for widgets and QGraphicsItem::sceneEvent() for items in a graphics
view to receive touch events.
With that, I believe that you need to handle the QEvent::TouchBegin, QEvent::TouchUpdate and QEvent::TouchEnd events, which I don't see in the code you've posted.
Qt may handle the first touch for you, but it's not going to know what you want to do with the second, third, fourth etc. simultaneous touches. For example, you may want your app to do any of the following with the second touch moving: -
1) Rotate the object that the first item is over
2) Scale the object that the first item is over
3) Select the second item
4) Translate the view
5) etc.
So, you need to handle the consecutive touches to do what you want it to do. Also, you may want to look at Gestures in Qt.

Lua - Cocoa - String Concat - Simple Table to NSArray

Mac OS X 10.5 compatibility, Lua 5.0 compatibility required (hence cannot use current batch of LuaObjc bridges.)
My lua script produces an indexed table containing tens of thousands of strings.
Basic problem: how to concat those strings with a newline separator, to one string, quickly?
Fly in ointment: even using garbage-collection friendly concat code (provided at stackoverflow) the results take far too long for this purpose. (10 seconds vs 1 minute for a brute force solution.)
Proposed solution: offload the job to Cocoa, where it can be done in a fraction of a second, using NSArray's -componentsJoinedByString method.
New fly in ointment: how to get table data from Lua to Cocoa?
The script calls a registered C function, passing it the table. The C function tries to grab the table on the stack:
// Get an NSArray of strings from the first argument on the stack (a table).
NSArray *strings = nsArrayFromIndexedTable(luaState, index_1Based);
...
// Given a simple table consisting of numbers or strings, returns an NSArray.
// Nested subtables are not followed.
NSArray * nsArrayFromIndexedTable(lua_State *L, int argIdx)
{
// (Allegedly) stops GC.
lua_setgcthreshold(L, INT_MAX);
// Arg must be a table.
luaL_checktype(L, argIdx, LUA_TTABLE);
// Get num elements in table, build an array with that many.
int count = luaL_getn(L, 1);
NSMutableArray *array = [NSMutableArray arrayWithCapacity: count];
int i;
for (i = 1; i <= count; i++) {
lua_rawgeti(L, argIdx, i);
int valueType = lua_type(L, -1);
id value = 0x00;
if (valueType is_eq LUA_TNUMBER) {
value = [NSNumber numberWithDouble:lua_tonumber(L, -1)];
} else if (valueType is_eq LUA_TSTRING) {
value = [NSString stringWithUTF8String:lua_tostring(L, -1)];
}
if (value) {
[array addObject:value];
}
}
// Resume GC
lua_setgcthreshold(L, 0); // INTERMITTENT EXC_BAD_ACCESS CRASH HERE!!!!
return array;
}
Problem: calling this function with a (very large) Lua table of strings (intermittently) results in a EXC_BAD_ACCESS.
Debugger results are sporadic; sometimes not providing anything useful, but I've been able to glean that:
If those Lua GC lines included, the crash happens at lua_setgcthreshold, near the end of the function.
But... if those Lua GC lines are commented out, the crash happens at [array addObject:value]
(NSZombieEnabled is on, but is not providing useful info.)
Any help is appreciated.
This:
int count = luaL_getn(L, 1);
Should be:
int count = luaL_getn(L, argIdx);
So you may be getting an incorrect row count and scanning off the end of the table.
Maybe you grow your C stack too much. I am not familiar with Cocoa, but I guess that the Lua values need not be accessible all the time - the string should be copied into NSString. If it is so, try including a lua_pop(L, 1) at the end of the loop, to clean up the C stack and keep it from growing.

Resources