首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >法向int的MPI奇异增量

法向int的MPI奇异增量
EN

Stack Overflow用户
提问于 2022-03-02 22:40:00
回答 1查看 103关注 0票数 0

目前,我正在用C语言使用MPI库进行编程,我有以下代码片段,它们的行为非常奇怪。

这是而不是--一个最小的可重复示例,但是我认为代码片段存在一个明显的问题,甚至与mpi无关,可以很容易地解决这个问题,而无需重放。请让我知道是否有额外的代码需要,我很高兴地提供它!

代码语言:javascript
复制
void monitor_proposals(int people_per_gender) {
    int satisfied_women = 0;
    /* declarations independent of the one above (omitted) */

    while (satisfied_women < people_per_gender) {
        MPI_Recv(&buf, sizeof(buf), MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
        sender = status.MPI_SOURCE;
        index = sender/2;
        printf("here\n");
        printf("ppg=%d, sw=%d\n", people_per_gender, satisfied_women);
        fflush(stdout);
        if (women_atleast_one_proposal[index] == 0) {
            women_atleast_one_proposal[index] = sender+1; /* logical id */
            satisfied_women += 1;
            printf("Monitor: First proposal to woman (%d)\n", sender+1);
            printf("ppg=%d, sw=%d\n", people_per_gender, satisfied_women);
        }
        if (satisfied_women == people_per_gender) {
            MPI_Send(&DONE, sizeof(DONE), MPI_INT, sender, sender, MPI_COMM_WORLD);
            printf("this\n");
        } else {
            MPI_Send(&NOT_DONE, sizeof(NOT_DONE), MPI_INT, sender, sender, MPI_COMM_WORLD);
            printf("that\n");
        }
    }
    printf("outside\n");
}

终端输出:

代码语言:javascript
复制
here
ppg=1, sw=16
Monitor: First proposal to woman (1)
ppg=1, sw=17
that

当然,我的期望是satisfied_women被初始化为0,然后增加到1,因此当它迭代时会中断循环。我还将输出流刷新到stdout,这将显示是否存在不受控制的循环,但似乎没有。

预期产出:

代码语言:javascript
复制
here
ppg=1, sw=0
Monitor: First proposal to woman (1)
ppg=1, sw=1
this
outside

我通过自制的方式使用mpich: stable 4.0.1

编辑I解决了增量问题,这就是现在的代码,我(在几个地方将count参数更改为1,以便该部分现在起作用)。

有n个男人过程和n个女人过程。男人和女人都是一样的。男子通过派遣向妇女求婚,而妇女则等待求婚。如果一个女人比现在接受的男人得到更好的评价,那么前一个男人将不得不向另一个女人求婚。

在women's while-loop中,每迭代一次,就会有一个监视过程,如果它应该退出或不退出,它就会反馈给发送方。当女人离开while-loop时,她们通知了那个男人,最近他们接受了。

代码语言:javascript
复制
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef enum gender {
    MAN,
    WOMAN
} gender_t;

/* men use array of women and fill in each womens rating_t, and vice versa */
typedef struct rating {
    gender_t gender;
    int id;
    int rating;
} rating_t;

/*******************************************************************************************
 * HELPER FUNCTIONS ************************************************************************
 *******************************************************************************************/

/* custom compare for qsort */
int compare(const void *r1, const void *r2) {
    return ((rating_t*)r1)->rating > ((rating_t*)r2)->rating ? -1 : 1;
}

/* random shuffling of ratings */
void shuffle_ratings(rating_t *profiles, int size) {
    int random_index, temp;
    for (int max_index = size-1; max_index > 0; max_index--) {
        random_index = rand() % (max_index+1);
        /* swap values at indexes */
        temp = profiles[max_index].rating;
        profiles[max_index].rating = profiles[random_index].rating;
        profiles[random_index].rating = temp;
    }
}

/*******************************************************************************************
 * PROCESSES *******************************************************************************
 *******************************************************************************************/ 

/* keeps track of women who are with a man, eventually notifies them it's done */
void monitor_proposals(int people_per_gender) {
    MPI_Status status;
    const int DONE = 1;
    const int NOT_DONE = 0;
    int *women_atleast_one_proposal = (int*)calloc(people_per_gender, sizeof(int));
    int satisfied_women = 0;
    int sender, index;
    int buf; /* not useful */

    while (satisfied_women < people_per_gender) {
        MPI_Recv(&buf, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
        sender = status.MPI_SOURCE;
        index = sender/2;
        fflush(stdout);
        if (women_atleast_one_proposal[index] == 0) {
            women_atleast_one_proposal[index] = sender+1; /* logical id */
            satisfied_women++;
            printf("Monitor: First proposal to woman (%d)\n", sender+1);
            printf("ppg=%d, sw=%d\n", people_per_gender, satisfied_women);
        }
        if (satisfied_women == people_per_gender) {
            MPI_Send(&DONE, 1, MPI_INT, sender, sender, MPI_COMM_WORLD);
            printf("this\n");
        } else {
            MPI_Send(&NOT_DONE, 1, MPI_INT, sender, sender, MPI_COMM_WORLD);
            printf("that\n");
        }
    }
}

/* function for men, highest rating is proposed to first */
void propose(int id, rating_t *my_ratings) {
    MPI_Status rec_status;
    int proposals = 0;
    int accepted = 0;
    int propose_dest, propose_rating;

    while (!accepted) {
        propose_dest = my_ratings[proposals].id - 1;
        propose_rating = my_ratings[proposals].rating;
        printf("Man (%d): Proposed to woman (%d) who's rated %d\n", id, propose_dest+1, propose_rating);
        fflush(stdout);
        MPI_Send(&propose_rating, 1, MPI_INT, propose_dest, propose_dest, MPI_COMM_WORLD);
        proposals++;
        MPI_Recv(&accepted, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &rec_status);
    }
    printf("man %d accepted\n", id);
}

/* function for women, accepts first proposal but can replace */
void receive_proposals(int id, rating_t *my_ratings, int monitor_rank) {
    MPI_Status status;

    const int ACCEPT = 1;
    const int REJECT = 0;
    int DONT_CARE = 0;
    int monitor_response;
    int from_man;

    int received_man_rank = -1;
    int received_man_rating = -1;
    int best_man_rank = -1;
    int best_man_rating = -1;

    while (1) {
        MPI_Recv(&from_man, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
        received_man_rank = status.MPI_SOURCE;
        received_man_rating = my_ratings[received_man_rank/2].rating;
        
        if (best_man_rank == -1) { /* first proposal received */
            best_man_rank = received_man_rank;
            best_man_rating = received_man_rating;
            printf("Woman (%d): Accepted man (%d) #%d#\n", id, best_man_rank+1, best_man_rating);
        } else if (received_man_rating > best_man_rating) { /* proposal is better rated than current accepted, notify replaced */
            MPI_Send(&REJECT, 1, MPI_INT, best_man_rank, best_man_rank, MPI_COMM_WORLD);
            printf("Woman (%d): Replaced man (%d) #%d# for man (%d) #%d#\n", id, best_man_rank+1, \
                    best_man_rating, received_man_rank+1, received_man_rating);
            best_man_rank = received_man_rank;
            best_man_rating = received_man_rating;
        } else { /* notify denied man */
            MPI_Send(&REJECT, 1, MPI_INT, received_man_rank, received_man_rank, MPI_COMM_WORLD);
            printf("Woman (%d): Rejected proposing man (%d) #%d# due to best man (%d) #%d#\n", id, received_man_rank+1, \
                    received_man_rating, best_man_rank+1, best_man_rating);
        }

        MPI_Send(&DONT_CARE, 1, MPI_INT, monitor_rank, monitor_rank, MPI_COMM_WORLD);
        MPI_Recv(&monitor_response, 1, MPI_INT, monitor_rank, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

        if (monitor_response) {
            printf("woman here\n");
            break;
        }
    }

    /* send ok to accepted man */
    MPI_Send(&ACCEPT, 1, MPI_INT, best_man_rank, best_man_rank, MPI_COMM_WORLD);
    printf("Woman (%d) + Man (%d) MARRIED\n", id, best_man_rank+1);
}

int main(int argc, char *argv[]) {
    int pool_size, people_per_gender;

    int rank, id, monitor_rank;
    rating_t *my_ratings;
    gender_t gender;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &pool_size);
    
    if (pool_size % 2 != 1) {
        if (rank == 0) 
            printf("Requirement: men == women and 1 extra process!\n");
        MPI_Finalize();
        exit(1);
    }

    people_per_gender = pool_size / 2;                                          /* number of men/women */
    id = rank + 1;                                                              /* logical id */
    monitor_rank = pool_size - 1;                                               /* collecting of proposals */

    if (rank != monitor_rank) {
        gender = (id % 2 == 0 ? MAN : WOMAN);                                   /* odd id - woman, even id - man */
        my_ratings = (rating_t*)malloc(people_per_gender * sizeof(rating_t));   /* rate half of pool, i.e. other gender */

        /* create "profiles" of other gender */
        for (int i = 0; i < people_per_gender; i++) {
            my_ratings[i].gender = (gender == MAN ? WOMAN : MAN);
            my_ratings[i].id = ( gender == MAN ? (2*i+1) : (2*i+2) );
            my_ratings[i].rating = i+1;
        }

        /* randomize ratings of other gender */
        srand(time(NULL) + id);
        shuffle_ratings(my_ratings, people_per_gender);
        qsort(my_ratings, people_per_gender, sizeof(rating_t), compare);

        if (gender == WOMAN)    printf("W(%d) ratings: ", id);
        else if (gender == MAN) printf("M(%d) ratings: ", id);

        for (int i = 0; i < people_per_gender; i++) 
            printf("| {id:%d, %d} | ", my_ratings[i].id, my_ratings[i].rating);
        printf("\n");
    }

    MPI_Barrier(MPI_COMM_WORLD);
    if (rank == monitor_rank) printf("\n");
    fflush(stdout);
    MPI_Barrier(MPI_COMM_WORLD);

    /* call function based on process type */
    if (rank == monitor_rank) {
        monitor_proposals(people_per_gender);
    } else {
        if (gender == WOMAN) 
            receive_proposals(id, my_ratings, monitor_rank);
        else if (gender == MAN)
            propose(id, my_ratings);
    }

    MPI_Barrier(MPI_COMM_WORLD);
    printf("ID (%d): Done\n", id);

    MPI_Finalize();
    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2022-03-02 23:28:27

你没有给我们足够的密码。如何在以下文件中定义缓冲区:

MPI_Recv(&buf, sizeof(buf), MPI_INT,

  1. int buf,这几乎是正确的,因为sizeof将给出4.
  2. int buf[20],然后sizeof将给出以字节为单位的大小,而不是在ints.
  3. buf = (int*)malloc(whatever)中,然后sizeof将为指针提供8个字节。

换句话说,这是绝对错误的,但确切地说,我们无法分辨。

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

https://stackoverflow.com/questions/71330019

复制
相关文章

相似问题

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