Page 1 of 1

Magick++ process hangs on simple iterative program.

Posted: 2010-06-23T01:02:49-07:00
by Nixuz
There is nothing complicated about the code pasted at the end of this post it simply does the following:

1. Randomly generates triangles.
2. Draws the triangles on an image.
3. Checks to see if that new triangle makes the triangle generated image closer to the target image.
4. If it is closer to the target image, keep the triangle and go back to 1, else revert back to image state without the last triangle and try again (goto 1).

However, when I run this code in Ubuntu on a dual-core system after a long while (say past 500 triangle additions) some weird behavior starts happening. When it is running normally top will show me two threads running at nearly 100%, however once the weird behavior starts happening one thread disappears leaving only one thread running at 100%. Even though this thread appears to be running in top, the program is stalled and does not continue to progress not matter how long I wait. The program itself has shown no signs of crashing. If I try to kill the remaining process using "kill -9" the process does not terminate. In fact not matter what I try, including pressing ctrl-c and closing the terminal window in which the program is running, I can not kill this process. Even if I try to shutdown or reset my computer the computer hangs and I have to power cycle the machine. This behavior happens every single time I run the program for a long duration on my dual-core machine but not at exactly the same spot in terms of triangles added. I have never had crashes or behavior like this before on this machine. I also have a FreeBSD box, which uses a older single core processor and when I run this program on the FreeBSD machine I have not experienced these problems at all.

Code: Select all

#include <iostream>
#include <list>
#include <cstdlib>
#include <ctime>
#include <Magick++.h>
#include <vector>
#include <cstring>
#include <cassert>

using namespace std;
using namespace Magick;

const char background[] = "black";
const double opacity = 1;


inline void drawTriangle(Image &img, const vector<unsigned int> &triangle){
	char cmdBuffer[128];
	list<Coordinate> points(3);
	sprintf(cmdBuffer, "rgba(%u, %u, %u, %lf)", triangle[0], triangle[1], triangle[2], opacity);
	img.fillColor(cmdBuffer);
	list<Coordinate>::iterator it = points.begin();
	it->x(triangle[3]);
	it->y(triangle[4]);
	it++;
	it->x(triangle[5]);
	it->y(triangle[6]);
	it++;
	it->x(triangle[7]);
	it->y(triangle[8]);
	img.draw(DrawablePolygon(points));
}

int main(int argc, char **argv){
	Image targetImage, finalImage, workingImage, bestImage;
	Geometry targetGeometry;
	unsigned int i, numTriangles;
	vector<unsigned int> triangle(9);
	double bestError;
	srand(time(NULL));

	if (argc != 3){
		cout << "polypic <filename> <#triangles>" << endl;
		return 1;
	}
	
	try{
		targetImage.read(argv[1]);
		numTriangles = atoi(argv[2]);
		targetGeometry = targetImage.size();
		workingImage = Image(targetGeometry, background);
		bestImage = Image(targetGeometry, background);
		finalImage = Image(Geometry(targetGeometry.width() * 2, targetGeometry.height()), background);
		finalImage.composite(targetImage, 0, 0);		
		targetImage.compare(workingImage);
		bestError = targetImage.meanErrorPerPixel();

		for (i = 0; i < numTriangles; i++){
			do{
				workingImage = bestImage;
				triangle[0] = rand() % 256;
				triangle[1] = rand() % 256;
				triangle[2] = rand() % 256;
				triangle[3] = rand() % targetGeometry.width();
				triangle[4] = rand() % targetGeometry.height();
				triangle[5] = rand() % targetGeometry.width();
				triangle[6] = rand() % targetGeometry.height();
				triangle[7] = rand() % targetGeometry.width();
				triangle[8] = rand() % targetGeometry.height();				
				drawTriangle(workingImage, triangle);
				targetImage.compare(workingImage);
			} while(targetImage.meanErrorPerPixel() >= bestError);
			bestError = targetImage.meanErrorPerPixel();
			bestImage = workingImage;
			cout << i << ". " << bestError << endl;
		}
		finalImage.composite(bestImage, targetGeometry.width(), 0);
		finalImage.write("final1.png");
	}
	catch(exception &error_){
		cout << "Caught exception: " << error_.what() << endl;
		return 1;
	}
	
	return 0;
}


Re: Magick++ process hangs on simple iterative program.

Posted: 2010-06-23T05:56:31-07:00
by magick
Your program ran and completed on our quad core Fedora 13 system with ImageMagick 6.6.2-7, the current release.

Check to see if your release of ImageMagick supports OpenMP:
  • identify -version
We assume so. Now reduce the threads to 1:
  • export MAGICK_THREAD_LIMIT=1
    polypic image.jpg 1000
Does that work? Next, download the latest release of ImageMagick and build from source. Does that fix the problem? If not, build again but disable OpenMP:
  • cd ImageMagick-6.6.2-7
    ./configure --disable-openmp
If that work, it suggests a buggy implementation of OpenMP on your system.