2012-05-13 4 views
2

C에서 MPI 프로그래밍에 대한 기본적인 질문이 있습니다. 본질적으로 내가 원하는 것은 특정 수의 하위 프로세스를 생성하고 모든 프로세스에서 일부 정보를 수집하는 마스터 프로세스가 있다는 것입니다 모든 자식이 끝날 때까지 대기), 메트릭을 계산합니다.이 메트릭을 기반으로 더 많은 스레드를 생성해야하는지 여부를 결정합니다. 메트릭이 특정 조건을 충족 할 때까지이 작업을 계속 수행합니다. 나는 문학을 조사했지만 아무 소용이 없다. 어떻게 할 수 있습니까? 어떤 포인터?C MPI - 배치에서 여러 스레드 생성하기

도움 주셔서 감사합니다.

예치 : An introduction to the Message Passing Interface (MPI) using C. "배열을 합친 완전한 병렬 프로그램"에서는 "약간의 절름발이"라고 말하면 마스터 프로세스가 배열의 내용을 두 번 더 합산하기를 원합니다. 즉, 첫 번째 반복에서 마스터 프로세스는 배열의 합계를 계산하는 슬레이브 프로세스를 시작합니다. 일단 완료되고 마스터 프로세스가 값을 반환하면 마스터 프로세스를 호출하여 다른 스레드 세트를 다시 호출하여 해당 스레드를 다시 호출합니다. 다시 계산. 아래 코드가 왜 작동하지 않을까요? 슬레이브 프로세스를 생성하는 마스터 프로세스 프로세스에 while 루프를 추가했습니다.

#include <stdio.h> 
    #include <mpi.h> 

    #define max_rows 100000 
    #define send_data_tag 2001 
    #define return_data_tag 2002 

    int array[max_rows]; 
    int array2[max_rows]; 

main(int argc, char **argv) 
{ 
    long int sum, partial_sum,number_of_times; 

    number_of_times=0; 

    MPI_Status status; 

    int my_id, root_process, ierr, i, num_rows, num_procs, 
    an_id, num_rows_to_receive, avg_rows_per_process, 
    sender, num_rows_received, start_row, end_row, num_rows_to_send; 

    /* Now replicte this process to create parallel processes. 
    * From this point on, every process executes a seperate copy 
    * of this program */ 

    ierr = MPI_Init(&argc, &argv); 

    root_process = 0; 

    /* find out MY process ID, and how many processes were started. */ 

    ierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_id); 
    ierr = MPI_Comm_size(MPI_COMM_WORLD, &num_procs); 

    if(my_id == root_process) { 

    /* I must be the root process, so I will query the user 
     * to determine how many numbers to sum. */ 

    //printf("please enter the number of numbers to sum: "); 
    //scanf("%i", &num_rows); 

     num_rows=10; 

     while (number_of_times<2) 
     { 

     number_of_times++; 
     start_row=0; 
     end_row=0; 



    if(num_rows > max_rows) { 
     printf("Too many numbers.\n"); 
     exit(1); 
    } 

    avg_rows_per_process = num_rows/num_procs; 

    /* initialize an array */ 

    for(i = 0; i < num_rows; i++) { 
     array[i] = i + 1; 
    } 

    /* distribute a portion of the bector to each child process */ 

    for(an_id = 1; an_id < num_procs; an_id++) { 
     start_row = an_id*avg_rows_per_process + 1; 
     end_row = (an_id + 1)*avg_rows_per_process; 

     if((num_rows - end_row) < avg_rows_per_process) 
      end_row = num_rows - 1; 

     num_rows_to_send = end_row - start_row + 1; 

     ierr = MPI_Send(&num_rows_to_send, 1 , MPI_INT, 
       an_id, send_data_tag, MPI_COMM_WORLD); 

     ierr = MPI_Send(&array[start_row], num_rows_to_send, MPI_INT, 
       an_id, send_data_tag, MPI_COMM_WORLD); 
    } 

    /* and calculate the sum of the values in the segment assigned 
     * to the root process */ 

    sum = 0; 
    for(i = 0; i < avg_rows_per_process + 1; i++) { 
     sum += array[i]; 
    } 

    printf("sum %i calculated by root process\n", sum); 

    /* and, finally, I collet the partial sums from the slave processes, 
     * print them, and add them to the grand sum, and print it */ 

    for(an_id = 1; an_id < num_procs; an_id++) { 

     ierr = MPI_Recv(&partial_sum, 1, MPI_LONG, MPI_ANY_SOURCE, 
       return_data_tag, MPI_COMM_WORLD, &status); 

     sender = status.MPI_SOURCE; 

     printf("Partial sum %i returned from process %i\n", partial_sum, sender); 

     sum += partial_sum; 
    } 

    printf("The grand total is: %i\n", sum); 


     } 



    } 

    else { 

    /* I must be a slave process, so I must receive my array segment, 
     * storing it in a "local" array, array1. */ 

    ierr = MPI_Recv(&num_rows_to_receive, 1, MPI_INT, 
      root_process, send_data_tag, MPI_COMM_WORLD, &status); 

    ierr = MPI_Recv(&array2, num_rows_to_receive, MPI_INT, 
      root_process, send_data_tag, MPI_COMM_WORLD, &status); 

    num_rows_received = num_rows_to_receive; 

    /* Calculate the sum of my portion of the array */ 

    partial_sum = 0; 
    for(i = 0; i < num_rows_received; i++) { 
     partial_sum += array2[i]; 
    } 

    /* and finally, send my partial sum to hte root process */ 

    ierr = MPI_Send(&partial_sum, 1, MPI_LONG, root_process, 
      return_data_tag, MPI_COMM_WORLD); 
    } 


    ierr = MPI_Finalize(); 
} 
+0

따라서 루프가 추가되지 않아도 코드가 작동합니까? 정확히 무엇이 잘못 되었습니까? 세분화 오류가 있습니까? 프로그램이 종료되지 않습니까? 아니면 단순히 예상 한대로 작동하지 않습니까? – mort

+0

네, 맞습니다. while 루프가 없어도 정상적으로 작동합니다 ... 첫 번째 루프를 실행 한 후 프로그램이 멈 춥니 다. –

답변

0

먼저 MPI_Comm_spawn 및 일괄 작업을 살펴보아야합니다. 오래된 하위 프로세스로부터 정보를 수집하기 위해 일반적으로 MPI_Reduce를 사용합니다.

This stackoverflow question도 도움이 될 수 있습니다.

...to spawn more threads... 

난 당신이 대부분 대신에 "실"의 "프로세스"를 사용하지만, 단지 명확히하기 때문에 당신이 옳은 일을 의미하는 것 같아요 : MPI는 프로세스가 아닌 스레드를 다루고있다.

MPI를 얼마나 잘 알고 있는지 잘 모르겠습니다. 내 답변이 도움이되었거나 힌트가 더 필요한지 알려주세요.

+0

감사 Mort. 저는 MPI 프로그래밍의 초보자입니다. 나는 당신 같은 경계선 덕분에 학습 과정이 원활하게되기를 바랍니다. –

+0

도움이된다면 제 답변을 upvote하십시오. 후속 질문에 답변하게되어 기쁩니다. – mort

+0

안녕하세요, Mort, 나는 upvote (atleast thats 시스템이 말하는 것)를 사용하기에는 너무 젊은 하사관이기 때문에 현재 upvote 할 수 없습니다. 코드에 첨부 된 코드 스 니펫을 살펴보십시오. 문제를 해결할 수 있도록 도와 주시겠습니까? –

0

MPI-2 표준은 프로세스 관리 기능을 포함합니다. 자세한 내용은 Chapter 5에 설명되어 있습니다. 나는 그것을 직접 사용해 본적이 없기 때문에 아마도 다른 누군가가 좀 더 실용적인 힌트를 얻어야 할 것입니다.