历数学习 MPICH2 遇到的坑-程序


如无特别说明,以下对应问题出现在代码注释中。


1. MPI_Send 和 MPI_Recv

这里如果不重新声明 Recv 的目标,则在 Ubuntu 下无法正常 Recv 。
#include "mpi.h"
#include<string.h>
#include<stdio.h>
int main(int argc, char *argv)
{
char message[20];
int myrank;
memset(message, 0, 20);
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (myrank == 1)
{
printf("randk 0 start ok\n");
strcpy_s(message, 20, "Hello, process 1");
/
加_s 是因 VS 编译不通过 /
// strcpy(message, "Hello, process 1");
printf("sended :---%s---\n", message);
MPI_Send(message, strlen(message)+1, MPI_CHAR, 0, 99, MPI_COMM_WORLD);
/
加 1 是因数组最后一位是 \0 表示结束 /
printf("randk 0 finish ok\n");
}
else if (myrank == 0)
{
// char message[20];
/
这里如果不重新声明,则在 Ubuntu 下无法正常 Recv */
printf("randk 1 start ok\n");
MPI_Recv(message, 20, MPI_CHAR, 1, 99, MPI_COMM_WORLD, &status);
printf("received :---%s---\n", message);
printf("randk 1 finish ok\n");
}
MPI_Finalize();
}

2. 时钟函数

参考 MPI程序例子 -- 时间函数测试
(书上莫名其妙调用不存在的 test.h 真的无语,Windows 里多线程没问题,都是 Success;Linux 中线程为 n 则耗时为 n 秒,不知什么问题)
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void sleep(clock_t wait)
/* 如果不重定义,则 Windows 里没有这个函数,Linux 里默认是只对整数参数返回非零值 */
{
clock_t goal;
goal = wait + clock();
while (goal > clock())
    ;
}

int main(int argc, char* argv[])                 /* 必要的命令行参数 */
{
int err = 0;
double t1, t2;
double tick;
int i, myrank;
MPI_Init(&argc, &argv);           
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);      
t1 = MPI_Wtime();             /* 获得当前时间t1 */
t2 = MPI_Wtime();             /* 获得当前时间t2 */
if (t2 - t1>0.1 || t2 - t1<0.0)
{
    /* 若连续两次时间调用得到的时间间隔过大,这里是超过0.1秒,
    或者后调用的函数得到的时间比先调用的时间小,则时间调用有错。 */
    err++;
    fprintf(stderr, "Two successive calls to MPI_Wtime gave strange result:(%f)(%f)\n", t1, t2);
}
/* 循环测试10次,每次循环调用两次时间函数,两次时间调用的时间间隔是1秒。 */
for (i = 1; i<10; i++)
{
    t1 = MPI_Wtime();               /* 计时开始 */
    sleep(1000);                    /* 睡眠1秒 */
    //sleep(1000000);               /* Linux 微秒单位 */
    t2 = MPI_Wtime();               /* 计时结束 */
    if (t2 - t1 >= (1.0 - 0.01) && t2 - t1 <= 5.0) break;
    if (t2 - t1>5.0) break;    /* 两次计时得到时间间隔合理,则退出。 */
}
if (i == 10)
{
    /* 计时函数不正确 */
    fprintf(stderr, "Timer around sleep(1) did not give 1 second;gave %f\n", t2 - t1);
    err++;
}
else/* 输出时间间隔 */
    fprintf(stderr, "Processor %d:Success,t2-t1= %f\n", myrank, t2 - t1);
tick = MPI_Wtick();               /* 得到一个时钟滴答的时间 */
if (tick>1.0 || tick<0.0)
{
    /* 该时间太长或者为负数,则该时间不正确。 */
    err++;
    fprintf(stderr, "MPI_Wtick gave a strange result: (%f)\n", tick);
}
MPI_Finalize();        
return 0;
}

3. Abort 函数

Linux下没问题,输出结果随机顺序。Windows 下 MPI_Abort 会杀掉所有输出,而这不是因为 Windows 反应慢(我为了等这个线程都加了 10 秒富裕时间)。

#include "mpi.h"
#include <stdio.h>
#include <string.h>
#include <time.h>

void sleep(clock_t wait)
{
clock_t goal;
goal = wait + clock();
while (goal > clock())
    ;
}
int main(int argc, char **argv)
{
int node, size, i;
int masternode = 0;
/* 设置缺省初始值 */
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &node);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* 检查参数 */
for (i = 0; i<argc; i++) {
    fprintf(stdout, "myid=%d,procs=%d,argv[%d]=%s\n", node, size, i, argv[i]);
}

//if (node == masternode) {
if (node == size - 1) {
    /* 由master进程执行退出操作 */
    fprintf(stdout, "myid=%d is masternode Abort!\n", node);
    sleep(10000);
    MPI_Abort(MPI_COMM_WORLD, 100);
    //MPI_Barrier(MPI_COMM_WORLD);
    /* MPI_Barrier 就可以得到应有的输出 */
}
else {
    /* 非master进程等待 */
    fprintf(stderr, "myid=%d is not masternode Barrier!\n", node);
    MPI_Barrier(MPI_COMM_WORLD);
}

MPI_Finalize();
}

4. 传值函数

在 Linux 上直接就通过了,而且结果正确。在 Windows 上不能输入,没有任何输出,程序死掉了。
#include <stdio.h>
#include "mpi.h"
int main(int argc, char argv)
{
int rank, value, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
do {
if (rank == 0) {
fprintf(stderr, "\nPlease give new value=");
/
进程0读入要传递的数据
/
scanf("%d", &value);
fprintf(stderr, "%d read <-<- (%d)\n", rank, value);
if (size>1) {
MPI_Send(&value, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
fprintf(stderr, "%d send (%d)->-> %d\n",
rank, value, rank + 1);
/* 若不少于一个进程 则向下一个进程传递该数据/
}
}
else {
MPI_Recv(&value, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD,
&status);
/
其它进程从前一个进程接收传递过来的数据/
fprintf(stderr, "%d receive (%d)<-<- %d\n", rank, value, rank - 1);
if (rank < size - 1) {
MPI_Send(&value, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
fprintf(stderr, "%d send (%d)->-> %d\n",
rank, value, rank + 1);
/
若当前进程不是最后一个进程 则将该数据继续向后传递/
}
}
MPI_Barrier(MPI_COMM_WORLD);
/
执行一下同步 加入它主要是为了将前后两次数据传递分开/
} while (value >= 0);
/
循环执行 直到输入的数据为负时才退出 */
MPI_Finalize();
}

5. 互相问候

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
void Hello(void);
int main(int argc, char *argv[])
{
int me, option, namelen, size;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/*得到当前进程标识和总的进程数*/
if (size < 2) {
    /*若总进程数小于2 则出错退出*/
    fprintf(stderr, "systest requires at least 2 processes");
    MPI_Abort(MPI_COMM_WORLD, 1);
}
MPI_Get_processor_name(processor_name, &namelen);
/*得到当前机器名字*/
fprintf(stderr, "Process %d is alive on %s\n", me, processor_name);
MPI_Barrier(MPI_COMM_WORLD);
/*同步*/
Hello();
/*调用问候过程*/
MPI_Finalize();
}
void Hello(void)
/*任意两个进程间交换问候信息 问候信息由发送进程标识和接收进程标识组成*/
{
int nproc, me;
int type = 1;
int buffer[2], node;
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
/*得到当前进程标识和总的进程数*/
if (me == 0) {
    /* 进程0负责打印提示信息*/
    printf("\nHello test from all to all\n");
    fflush(stdout);
}
for (node = 0; node<nproc; node++) {
    /*循环对每一个进程进行问候*/
    if (node != me) {
        /* 得到一个和自身不同的进程标识*/
        buffer[0] = me; /*将自身标识放入消息中*/
        buffer[1] = node; /*将被问候的进程标识也放入消息中*/
        MPI_Send(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD);
        /*首先将问候消息发出 */
        MPI_Recv(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD, &status);
        /*然后接收被问候进程对自己发送的问候消息*/
        if ((buffer[0] != node) || (buffer[1] != me)) {
            /*若接收到的消息的内容不是问候自己的或不是以被问候方的身份问候自
            己 则出错*/
            (void)fprintf(stderr, "Hello: %d!=%d or %d!=%d\n",
                buffer[0], node, buffer[1], me);
            printf("Mismatch on hello process ids; node = %d\n", node);
        }
        printf("Hello from %d to %d\n", me, node);
        /*打印出问候对方成功的信息*/
        fflush(stdout);
    }
}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容