/*
** User-defined reduce function to check a sorted list
** This one is not guaranteed to work.
** Copyright Rolf Riesen 2008
**
*/
#include <stdio.h>
#include <mpi.h>

#define TRUE	(1)

/*
** Local functions
*/
void my_func(void *invec, void *inoutvec, int *len, MPI_Datatype *dt);


/*
** Globals
*/
int my_rank, nproc;


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

int my_value;
int result;
int root;
int count;
int calc;
MPI_Op my_op;



    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    /* Each node contributes its own node number */
    my_value= my_rank;
    calc= 0;
    result= 0;
    root= 2;
    count= 1;

    MPI_Op_create(my_func, TRUE, &my_op);

    /* Do an integer reduction */
    MPI_Reduce(&my_value, &result, count, MPI_INT, my_op, root,
            MPI_COMM_WORLD);

    if (my_rank == root)   {
	printf("[%3d] root received %d\n", my_rank, result);
    }

    MPI_Op_free(&my_op);
    MPI_Finalize();
    return 0;

}  /* end of main() */



void
my_func(void *invec, void *inoutvec, int *len, MPI_Datatype *dt)
{

int left, right;


    if (*dt == MPI_INT)   {
        left= *((int *)invec);
        right= *((int *)inoutvec);

	if (left > right)   {
	    *((int *)inoutvec)= left;
	}   else   {
	    *((int *)inoutvec)= right;
	}

	printf("my_func() rank %d, left %d, right %d\n", my_rank, left, right);
    } else   {
        /* A data type we cannot handle */
	MPI_Abort(MPI_COMM_WORLD, -1);
    }

}  /* end of my_func() */
