/*
 *              	   Exemple "Slave1.c" PVM versio 3.3
 *		 Susana Maria Bajo Sanchez (ei05646@salleURL.edu)
 *		 Josep Maria Garrell i Guiu (josepmg@salleURL.edu)
 *				Software Paral.lel
 *		           Departament d'Informatica (DI)
 *   	               Enginyeria i Arquitectura La Salle
 *		           Universitat Ramon Llull (URL)
 * 			         Curs 1999/2000
*/

#include <stdio.h>
#include "pvm3.h"


//----------------------------------------------------------------------
// Los "slaves" intercambian datos con los vecinos de la izquierda (wrapping)
float work (int me,int n, float *data,int *tids,int nproc)
{
    int i, dest;
    float psum = 0.0;
    float sum = 0.0;
    for (i=0; i<n ; i++) sum += me * data[i];

    // comunicacion nodo a nodo
    pvm_initsend(PvmDataDefault);
    pvm_pkfloat(&sum,1,1);
    dest = me+1;
    if (dest==nproc) dest = 0;
    pvm_send(tids[dest],22);
    pvm_recv(-1,22);
    pvm_upkfloat(&psum,1,1);

    return(sum+psum);
}

//----------------------------------------------------------------------
void main()
{
	int mytid;
	int tids[32];
	int n, me, i, nproc, master, msgtype;
	float data[100], result;
	float work();

	mytid = pvm_mytid();
	printf("Slave1: Soy la tarea #%x\n",mytid);

	// recibe datos del 'Master1'
	msgtype = 0;
	pvm_recv(-1,msgtype);

	pvm_upkint(&nproc,1,1);
	printf("Slave1: Desempaqueto el entero %d\n",nproc);

	pvm_upkint(tids,nproc,1);
	printf("Slave1: Desempaqueto el entero %d\n",tids);

	pvm_upkint(&n,1,1);
	printf("Slave1: Desempaqueto el entero %d\n",n);

	pvm_upkfloat(data,n,1);
	printf("Slave1: Desempaqueto el float %x\n",data);

	// determino que 'Slave1' soy
	for (i=0;i<nproc;i++)
		if (mytid == tids[i])
		{
			me = i;
			break;
		}
		
	// realizo los calculos con 'data'
	result = work(me,n,data,tids,nproc);

	// envio los resultados a 'Master1'
	pvm_initsend(PvmDataDefault);
	printf("Slave1: Inicializo el SEND\n");

	pvm_pkint(&me,1,1);
	printf("Slave1: Empaqueto el entero %d\n",me);

	pvm_pkfloat(&result,1,1);
	printf("Slave1: Empaqueto el float %x\n",result);

	msgtype = 5;
	master = pvm_parent();
	pvm_send(master,msgtype);
	printf("Slave1: Envio a la tarea %x con msgtag %d\n",master,msgtype);
	
	pvm_exit();
	printf("Slave1: Salgo de PVM\n");
}

