elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


  Mostrar Mensajes
Páginas: [1]
1  Programación / Programación C/C++ / Problema con C++ y MPI en: 11 Enero 2013, 15:22 pm
Hola a todos

Tengo un problema con un programa en c que usa MPI. La idea es realizar un ordenamiento utilizando pipelines. Es decir, el usuario escribe una serie de números. El primer proceso los lee y los manda a los siguientes. Cada uno recibe un valor. Si es el primer valor recibido, lo almacena. En caso contrario, compara el recibido con el que está guardando. Si el recibido es mayor, guarda el recibido y manda el que tenía guardado inicialmente al siguiente proceso. Si no es mayor, lo manda directamente al siguiente proceso.

Código:
#include "mpi.h"
#include <string.h>
#include <iostream>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

int main(int argc, char *argv[]) {
    int rank, size, value;
    MPI_Status status;
    char* cadena;
    char linea[128];
    bool fin = false;
    int x;
bool semaforo = true;

    /*
     * Consideramos 2 enteros que sirven de "testigo" para cambiar el modo de
     * funcionamiento del programa:
     * 99 : provoca la terminacion (ordenada) de todos los procesos del programa
     * 98 : provoca la descarga de todas la etapas en secuencia;
     *      se transmite hasta el ultimo proceso, pero no lo muestra en pantalla;
     *      despues de enviar el "testigo 98", cada etapa recupera el valor inicial.
     * Dicho valor inicial ha ser menor que todos los enteros que se quieren ordenar
     * y que se  transmiten por las etapas para que el algoritmo funcione.     
     */

    /**
     * Completar con las funciones de inicializacion, obtencion de 'rank' y de 'size';
     * y declarar las variables que falten.
     */

MPI_Init(&argc,&argv);
MPI_Comm_rank (MPI_COMM_WORLD,&rank ) ;
MPI_Comm_size (MPI_COMM_WORLD,& size ) ;


    while (!fin) {
        if (rank == 0) {


                printf("Nueva cadena > ");
            fflush(stdout);


            if (fgets(linea, sizeof (linea), stdin) == NULL)
                fprintf(stderr, "error en entrada");

            // la longitud de la cadena ha de coincidir con el numero
            // de etapas etapas==size
            cadena = (char*) malloc(sizeof (char) *size);
           
            if (sscanf(linea, "%size[^\n]", cadena) < 1) {
                fin = true;
                x = 99;
                /**
                 * Transmitir el valor de finalizacion con la funcion
                 * MPI de paso de mensajes adecuada
                 */
MPI_Send(&x,1,MPI_INT,rank+1,0,MPI_COMM_WORLD);

            } else {
                /**
                 * Efectivamente, se han copiado "size" caracteres de "linea" a "cadena".
                 * Hay que enviar los elementos de cadena[i] convertidos a enteros
                 * al siguiente. Transmitir tambien el ultimo almacenado porque si
                 * se olvida no funcionara. Detras del ultimo hay que enviar el
                 * entero 98 para que la etapa siguiente descargue.
                 */
int entero_final = 98;
char caracter;
for(int contador = 0; contador < size; ++contador){
caracter = cadena[contador];
x = atoi(&caracter);
MPI_Send(&x,1,MPI_INT,rank+1,0,MPI_COMM_WORLD);
}
MPI_Send(&entero_final,1,MPI_INT,rank+1,0,MPI_COMM_WORLD);
            }
        } else {
            /**
             * Este es el codigo que han de ejecutar los procesos del encauzamiento
             * con rank<>0. El primer entero que se recibira es el valor inicialmente
             * asignado a la variable propia de la etapa; hay que saltarselo porque
             * no pertenece a la cadena de enteros que hay que ordenar.
             */

//MPI_Recv (&x, 1 , MPI_INT , rank -1 ,0 ,MPI_COMM_WORLD,&status ) ;
//cout << "valor " << x << endl;
int valor_almacenado = -1;
int valor_a_enviar;

fin = false;
            while (!fin) {
                /**
                 * Cada proceso tambien tiene un bucle porque tiene que "filtrar"
                 * todos los enteros de una cadena --incluyendo el testigo de fin
                 * de hilera == 98-- antes de pasar a la siguiente. El fin se
                 * alcanzara cuando entremos del teclado una hilera vacia y como
                 * consecuencia de esta entrada, el proceso con rank==0
                 * transmita el testigo de finalizacion global.
                 */

bool continuar = true;

while(continuar){
MPI_Recv (&x, 1 , MPI_INT , rank -1 ,0 ,MPI_COMM_WORLD,&status ) ;
if(x != 98){

if(x > valor_almacenado){
valor_a_enviar = valor_almacenado;
valor_almacenado = x;
}
else{
valor_a_enviar = x;
}
}
else{
continuar = false;
cout << valor_almacenado << endl;
valor_a_enviar = 98;
fin = true;
}
if(rank+1 < size)
MPI_Send(&valor_a_enviar,1,MPI_INT,rank+1,0,MPI_COMM_WORLD);
}

            }
        }
    }


    MPI_Finalize();

   
    return 0;
} // end main


Bueno, los números que le paso, los ordena bien. Pero solo hace la ordenación una vez y se supone que debería hacerlo siempre.  Ejemplo de lo que me pasa es el siguiente:

$ mpirun -np 4 ./test
Nueva cadena > 526
Nueva cadena > 6
5
2
(aquí se queda esperando una entrada del usuario, si npedir que introduzca una nueva cadena)
343   (introduzco lo siguiente, y me muestra lo siguiente:)
Nueva cadena > 6
5
4

Oseaa, que vuelve a poner 6 y 5, de la cadena anterior, y añade el 4 de la nueva. Mezclando el resultado anterior con el nuevo.

¿alguien tiene idea de qué puedo estar haciendo mal?

saludos y gracias


Páginas: [1]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines