/*
 *
 * Copyright 1998-1999, University of Notre Dame.
 * Authors: Jeffrey M. Squyres, Kinis L. Meyer with M. D. McNally 
 *          and Andrew Lumsdaine
 *
 * This file is part of the Notre Dame LAM implementation of MPI.
 *
 * You should have received a copy of the License Agreement for the
 * Notre Dame LAM implementation of MPI along with the software; see
 * the file LICENSE.  If not, contact Office of Research, University
 * of Notre Dame, Notre Dame, IN 46556.
 *
 * Permission to modify the code and to distribute modified code is
 * granted, provided the text of this NOTICE is retained, a notice that
 * the code was modified is included with the above COPYRIGHT NOTICE and
 * with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
 * file is distributed with the modified code.
 *
 * LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
 * By way of example, but not limitation, Licensor MAKES NO
 * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
 * PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
 * OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
 * OR OTHER RIGHTS.  
 *
 * Additional copyrights may follow.
 *
 *	Ohio Trollius
 *	Copyright 1997 The Ohio State University
 *	RBD/NJN
 *
 *	$Id: mpietc.c,v 6.4 1999/07/28 20:14:37 kmeyer1 Exp $
 *
 *	Function:	- misc. shared MPI-related functions
 *			- used by libmpi and MPI tools
 */

#include <app_mgmt.h>
#include <mpi.h>
#include <mpisys.h>
#include <rpisys.h>

/*
 * macros
 */
#define FLIPCID(x)	(-((x) + 1))

/*
 *	lam_pt2coll
 *
 *	Function:	- change context ID from pt2pt to collective
 *	Accepts:	- pt2pt context ID
 *	Returns:	- collective context ID
 */
int
lam_pt2coll(cid)

int			cid;

{
	if (cid >= 0) cid = FLIPCID(cid);
	return(cid);
}

/*
 *	lam_coll2pt
 *
 *	Function:	- change context ID from collective to pt2pt
 *	Accepts:	- collective context ID
 *	Returns:	- pt2pt context ID
 */
int
lam_coll2pt(cid)

int			cid;

{
	if (cid < 0) cid = FLIPCID(cid);
	return(cid);
}

/*
 *	lam_mkcoll
 *
 *	Function:	- switch communicator to collective context ID
 *	Accepts:	- communicator
 */
void
lam_mkcoll(comm)

MPI_Comm		comm;

{
	if (comm) comm->c_contextid = lam_pt2coll(comm->c_contextid);
}

/*
 *	lam_mkpt
 *
 *	Function:	- switch communicator to pt2pt context ID
 *	Accepts:	- communicator
 */
void
lam_mkpt(comm)

MPI_Comm		comm;

{
	if (comm) comm->c_contextid = lam_coll2pt(comm->c_contextid);
}

/*
 *	lam_unsyncsql
 *
 *	Function:	- extract SQL sync. information
 *	Accepts:	- event
 *			- type
 *			- tag (out)
 *			- context ID (out)
 *			- ACK flag (out)
 *			- destination index (out)
 *			- source node (out)
 *			- source index (out)
 */
void
lam_unsyncsql(event, type, ptag, pcid, pack, pdidx, psnode, psidx)

int			event;
int			type;
int			*ptag;
int			*pcid;
int			*pack;
int			*pdidx;
int			*psnode;
int			*psidx;

{
	*pdidx = event & 0x7FFF;
	*pack = event & 0x10000;
	*pcid = (event >> 18) & 0xFFF;
	if (*pcid & 0x800) *pcid |= 0xFFFFF000;

	*ptag = type & 0xFFFF;
	if (*ptag & 0x8000) *ptag |= 0xFFFF0000;

	type >>= 16;
	*psnode = type & 0x3FF;
	*psidx = (type >> 10) & 0x3F;

	if (*psnode == 0x3FF) *psnode = MPI_ANY_SOURCE;
	if (*psidx == 0x3F) *psidx = MPI_ANY_SOURCE;
}

/*
 *	lam_rank_in_group
 *
 *	Function:	- find rank of process in a group
 *	Accepts:	- group
 *			- process
 *	Returns:	- rank in group else MPI_UNDEFINED
 */
int
lam_rank_in_group(group, proc)

MPI_Group		group;
struct _proc		*proc;

{
	int		i;
	struct _gps	*gps;

	gps = &proc->p_gps;
	
	for (i = 0; i < group->g_nprocs; i++) {
		if (LAM_FULL_GPSCMP(&group->g_procs[i]->p_gps, gps) == 0) {
			return(i);
		}
	}

	return(MPI_UNDEFINED);
}
