J'essaie de générer une image pgm avec une fractale de Buddhabrot, en parallèle, en utilisant pthreads et le modèle maître-esclave. Des tests, je peux voir que le programme démarre le modèle avec le bon mode parallèle, mais il semble être dans une boucle infinie. Le problème est que je ne peux pas voir lequel est le problème. Quelqu'un peut-il me donner une lumière à ce sujet? Je vous remercie.Fractale de Buddhabrot avec pthread
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#define N_SLAVES 3
double next = -1;
int i = 0, nColumns = 2048, nLines = 2048, ite = 600;
double y, dt = 0.001;
int completedIterations;
pthread_mutex_t mutex;
pthread_cond_t condM;
pthread_cond_t condE;
typedef struct {
int x;
int y;
} int2;
typedef struct{
double x;
double y;
} double2;
int2 coordinatesConversion(double x,double y, int nColumns,int nLines){
int2 ret;
int2 retError;
retError.x=-1;
retError.y=-1;
ret.x=round(((2.0+x)/3.5) *((double)(nColumns-1)));
ret.y=round(((1.5+y)/3.5) *((double)(nLines-1)));
if(ret.x<0 || ret.x>=nColumns) return retError;
if(ret.y<0 || ret.y>=nLines) return retError;
return ret;
}
int printMatrixToFilePGM(float **mat,int tamx, int nLines, char *srcFile){
printf("First\n");
FILE *arq=fopen(srcFile,"w");
int cont, cont2;
float min,max;
min=mat[0][0];
max=mat[0][0];
for(cont=0;cont<nLines;cont++){
for(cont2=0;cont2<tamx;cont2++){
if(min>mat[cont][cont2]) min=mat[cont][cont2];
if(max<mat[cont][cont2]) max=mat[cont][cont2];
}
}
max=max*0.35;
float delta=max-min;
fprintf(arq,"P2 \n");
fprintf(arq,"#something \n");
fprintf(arq,"%d\n%d \n",tamx,nLines);
fprintf(arq,"255\n");
for(cont=0;cont<nLines;cont++){
for(cont2=0;cont2<tamx;cont2++){
int valpixel=((mat[cont][cont2]-min)/delta)*255.0f;
if(valpixel>255) valpixel=255;
fprintf(arq,"%d \n", valpixel);
}
}
fclose(arq);
}
float** mallocFloatMatrix(int tamx, int nLines, float defaultValueOfTheElementsAtMatrix){
float **errorCodeReturn=0x0;
float **mat;
int i,j;
int condErrorMalloc=0;
mat=malloc(sizeof(float *)*nLines);
if(mat==0x0) return errorCodeReturn;
for(i=0;i<tamx;i++)
mat[i]=malloc(sizeof(float)*tamx);
for(i=0;i<tamx;i++){
if(mat[i]==0x0){
condErrorMalloc=1;
break;
}
}
if(condErrorMalloc==0){
return mat;
}
for(i=0;i<nLines;i++){
for(j=0;j<tamx;j++)
mat[i][j]=defaultValueOfTheElementsAtMatrix;
}
for(i=0;i<tamx;i++)
if(mat[i]!=0x0) free(mat[i]);
free(mat);
return errorCodeReturn;
}
void freeFloatMatrix(float **mat,int tamx, int nLines){
int i;
for(i=0;i<nLines;i++){
if(mat[i]!=0x0) free(mat[i]);
}
free(mat);
}
int iteration(double x,double y, int nColumns,int nLines, int ite,int2 *iterationPath){
int cont;
int condInvalidPointer=1;
double2 z;
z.x=0.0;
z.y=0.0;
double2 c;
c.x=x;
c.y=y;
double2 zt;
for(cont=0;cont<ite;cont++){
zt.x=((z.x*z.x)-(z.y*z.y))+c.x;
zt.y=(2.0*(z.x*z.y))+c.y;
z=zt;
if(((z.x*z.x)+(z.y*z.y))>4.0){
if(cont>100)
condInvalidPointer=0;
break;
}
iterationPath[cont]=coordinatesConversion(z.x,z.y,nColumns,nLines);
}
if(condInvalidPointer)
return 0;
return cont;
}
void *master(void *param){
printf("Second\n");
int size = round(4.0/dt);
int i;
int progress = 0;
for(i = 0; i < size; i++){
next = -2.0+i*dt;
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condE);
pthread_cond_wait(&condM, &mutex);
pthread_mutex_unlock(&mutex);
// progress++;
// if(progress%100 ==0)//print at screen information about progrees of the operation
// printf("2 - %lf \n", next);
}
}
void *slave(void *param){
int size = round(4.0/dt);
printf("Third\n");
int k;
float **mat = mallocFloatMatrix(nColumns, nLines, 0.0f);
if(mat == 0x0) return 0;
while(1){
pthread_mutex_lock(&mutex);
if(i >= size){
pthread_mutex_unlock(&mutex);
pthread_exit(0);
}
i++;
while(next == -1){
pthread_cond_signal(&condM);
pthread_cond_wait(&condE, &mutex);
}
double x = next;
next = -1;
pthread_cond_signal(&condM);
pthread_mutex_unlock(&mutex);
for(y=-2.0;y<2.0;y=y+dt){
int2* iterationPath = (int2 *)malloc(sizeof(int2) * ite);
if(iterationPath==0x0) return 0x0;
completedIterations = iteration(x, y, nColumns, nLines, ite, iterationPath);
for(k = 0; k < completedIterations; k++){
if(iterationPath[k].x!=-1 && iterationPath[k].y!=-1)//test if a point z in the iteration k may be normalized to coordinates at matrix mat.
mat[iterationPath[k].x][iterationPath[k].y] = mat[iterationPath[k].x][iterationPath[k].y]+1.0f;//increments a point in matrix, this point is pointed by z with z points normalized.
}
free(iterationPath);
}
}
printMatrixToFilePGM(mat,nColumns,nLines,"saida3.pgm");
freeFloatMatrix(mat,nColumns,nLines);
}
int main(void){
printf("Main\n");
int i, j, k;
pthread_t master_t;
pthread_t slave_t[N_SLAVES];
pthread_create(&master_t, NULL, master, NULL);
for(i = 0; i < N_SLAVES; i++)
pthread_create(&slave_t[i], NULL, slave, NULL);
pthread_exit(0);
return 0;
}