首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用c+ mpi在统计扁钢中显示bmp

用c+ mpi在统计扁钢中显示bmp
EN

Stack Overflow用户
提问于 2018-02-13 09:23:17
回答 2查看 227关注 0票数 0
代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
#include <time.h>
#include <math.h>
#include <sys/time.h>

#define NUM 512

int id,nproc;
int colorbuf[NUM * NUM];
double cx0,cx1,cy0,cy1;
int n;
double dx,dy;
int p_n;
struct timeval startTime, endTime;
double timeused_p;


void draw()
{
int i = 0;
int j = 0;
int k = 0;
FILE *fp = fopen("001.ppm", "wb");
fprintf(fp, "P6\n# Mandelbrot, xmin=%d, xmax=%d, ymin=%d, ymax=%d, maxiter=%d\n%d\n%d\n%d\n",-2,2,-2,2,NUM,NUM,NUM,(NUM < 256 ? 256 : NUM));
for (j=0;j<n;j++)
{    
    for(i=0;i<n;i++) 
    {        
        int temp=colorbuf[j*n+i];
    if (temp == NUM)
    {
    const unsigned char black[] = {0,0,0};
    fwrite(black, 3, 1, fp);
    }
    else
    {
    unsigned char color[3];
    color[0] = temp >> 8;
    color[1] = temp & 255;
    color[2] = temp >> 8;
    fwrite(color, 3, 1, fp);
    };
} 

}
fclose(fp);
}

int compColor(double creal, double cimage)
{
double real, image;
double nreal, nimage;
double tmp;
int i;

real = creal;
image = cimage;

for (i = 0; i < NUM; i++) 
{
    tmp = real*real + image*image;
    if (tmp >= 4.0) return i;
    nreal = real*real - image*image + creal;
    nimage = real*image*2.0 + cimage;
    real = nreal;
    image = nimage;
}

return NUM;
}

void colorCalculate()
{
dx=(cx1-cx0)/n;
dy=(cy1-cy0)/n;
int locN=n/nproc;
int i,j,k;
double cx,cy;
for (j=id*locN;j<=id*locN+locN-1;j++)
{  
    cy= cy0+j*dy;    
    for(i=0;i<n;i++) 
    {       
        cx=cx0+i*dx; 
        colorbuf[j*n+i]=compColor(cx, cy);
    }
 }
}


int main()
{ 
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&id);//id存放进程的标识
MPI_Comm_size(MPI_COMM_WORLD,&nproc);//nproc存放总进程数
if(id==0)
{
    gettimeofday(&startTime, NULL);
    cx0=-2;
    cx1=2;
    cy0=-2;
    cy1=2;
    n=NUM;
}

MPI_Bcast(&cx0, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&cx1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&cy0, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&cy1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

colorCalculate();
int locN=n/nproc;

if(id!=0){
     MPI_Gather(&colorbuf, locN*n, MPI_INT, &colorbuf[id*locN*n], locN*n, MPI_INT, 0, MPI_COMM_WORLD);
}

if(id==0){
 gettimeofday(&endTime, NULL);
 timeused_p =  1000000 * (endTime.tv_sec - startTime.tv_sec) + endTime.tv_usec - startTime.tv_usec;
timeused_p /= 1000;
printf("静态调度运行时间 : %f ms\n", timeused_p);
draw();
}

MPI_Barrier(MPI_COMM_WORLD);        
MPI_Finalize();      
return 0; 
}

这是C+ mpi的代码,用统计模式来实现mandelbrot集。这是run命令。我的环境是ubuntu 14.04。

其结果是:

这不正常。似乎只有一半的图像。我真的不知道怎么回事。很抱歉有这么长的转储代码。有人能帮忙吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-13 11:09:04

all队伍必须调用MPI_Gather(),并且参数的顺序是正确的。由于colorbuf同时用作发送和接收缓冲区,所以必须使用MPI_IN_PLACE

由于数据足够小,非根级别不会挂起,但是colorbuf没有组装在根级别上,因此结果不正确。

作为一种风格,您可以考虑去掉全局变量,并将参数添加到子程序中。

票数 0
EN

Stack Overflow用户

发布于 2018-02-13 09:40:39

我想你打错了,看看这些台词

代码语言:javascript
复制
    cx0=-2;
    cx1=2;
    cy1=-2;  // <- should be cy0 
    cy1=2;   // 

请记住,cy0被定义为全局变量,因此它的默认值为0.0,因此您得到了一半的图像。

为什么要将数据写入文件为6字节序列。根据参考资料format

PPM每像素使用24位:红色8位,绿色8位,蓝色8位。

所以你应该改变这些行

代码语言:javascript
复制
const unsigned char black[] = {0,0,0,0,0,0};
fwrite(black, 6, 1, fp);

代码语言:javascript
复制
const unsigned char black[] = {0,0,0};
fwrite(black, 3, 1, fp);

代码语言:javascript
复制
unsigned char color[6];
color[0] = temp >> 8;
    color[1] = temp & 255;
    color[2] = temp >> 8;
    color[3] = temp & 255;
    color[4] = temp >> 8;
    color[5] = temp & 255;
fwrite(color, 6, 1, fp);

代码语言:javascript
复制
unsigned char color[3];
color[0] = red; 
color[1] = green;
color[2] = blue;
fwrite(color, 3, 1, fp);

值红色、绿色、蓝色取决于temp值(0-512),因此应该将该值缩放到0-255范围。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48763319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档