/****Copyright (c) 2002  Alexandros V. Gerbessiotis. 
 **** All rights reserved.                               
 ****Permission to use, copy, modify, and distribute this software,
 ****and to incorporate it, in whole or in part, into 
 ****other software,is hereby granted without fee, provided that
 ****  (1) the above copyright notice and this permission 
 ****      notice appear in all copies of the source code, and 
 ****      the above copyright notice appear in clearly visible 
 ****      form on all supporting documentation and distribution 
 ****      media, and
 ****     (2) any redistribution of the software, in original
 ****         or modified form, be without fee and subject to
 ****         these same conditions.
 ****   No guarantee, whatsoever, is offered that the code works as
 ****   advertised or is absent of any, even damaging,
 ****   side-effects. Use this code at your own personal risk.
 ****/
#undef  MPILIB
#define MPILIB
#define BSPLIB
#undef  BSPLIB


#ifdef BSPLIB
#include "bsp.h"
#define AIGET  bsp_get
#define AIHPGET  bsp_hpget
#define AIPUT  bsp_put
#define APUT  bsp_put
#define AIHPPUT  bsp_hpput
#define AHPPUT  bsp_hpput
#define AISYNC bsp_sync
#define AISNC(X) bsp_sync()
#define AIBARRIER bsp_sync
#define AIREALIZE bsp_sync
#define AIABORT bsp_abort
#define AIPID   bsp_pid
#define AINPROCS bsp_nprocs
#define AIREGISTER bsp_pushregister
#define AIREG bsp_pushregister
#define AIDEREGISTER bsp_popregister
#define AITIME       bsp_time
#define AIBEGIN      bsp_begin
#define AIEND        bsp_end
#define AIL()    (bsp_l())
#define AIG()    (bsp_g())
#define AISETL(X) {}
#define AISETG(X) {}
#endif

#ifdef   MPILIB
#include <mpi.h>
#define AIBEGIN(X) (MPI_Init(&argc,&argv),mpi_basetime=MPI_Wtime())
#define AIPID() ((mpi_pid == -1)?(MPI_Comm_rank(MPI_COMM_WORLD,&mpi_pid),mpi_pid):mpi_pid) 
#define AINPROCS() ((mpi_nprocs== -1)?(MPI_Comm_size(MPI_COMM_WORLD,&mpi_nprocs),mpi_nprocs):mpi_nprocs)
#define AIBARRIER() MPI_Barrier(MPI_COMM_WORLD)
#define AIREGISTER(X,Y) MPI_Win_create((char *)(X),(Y),1,MPI_INFO_NULL\
        ,MPI_COMM_WORLD,&win)
#define AIREG(X,Y) MPI_Win_create((char *)(X),(Y),1,MPI_INFO_NULL\
        ,MPI_COMM_WORLD,&aiwin[aiinsert((void*)X)])
#define AIDEREG(X) {aidelete(X);}
#define AIDEREGISTER(X) {}
#define AISYNC() MPI_Win_fence(0,win)
#define AISNC(Z) MPI_Win_fence(0,aiwin[aisearch((void *)Z)])
#define AIBARRIER() MPI_Barrier(MPI_COMM_WORLD)
#define AIPUT(X,Y,Z,W,R) MPI_Put((char *)(Y),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,win)
#define AIHPPUT(X,Y,Z,W,R) MPI_Put((char *)(Y),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,win)
#define AIGET(X,Y,W,Z,R) MPI_Get((char *)(Z),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,win)
#define AIHPGET(X,Y,W,Z,R) MPI_Get((char *)(Z),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,win)
#define APUT(X,Y,Z,W,R) MPI_Put((char *)(Y),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,aiwin[aisearch((void *)Z)])
#define AHPPUT(X,Y,Z,W,R) MPI_Put((char *)(Y),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,aiwin[aisearch((void *)Z)])
#define AGET(X,Y,W,Z,R) MPI_Get((char *)(Z),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,aiwin[aisearch((void *)Z)])
#define AHPGET(X,Y,W,Z,R) MPI_Get((char *)(Z),(R),MPI_CHAR,(X),(W),(R),MPI_CHAR,aiwin[aisearch((void *)Z)])
#define AIEND() MPI_Barrier(MPI_COMM_WORLD),MPI_Finalize()
#define AIABORT(X) MPI_Abort(MPI_COMM_WORLD, __LINE__ )
#define AITIME() (MPI_Wtime()-mpi_basetime)
#define AIL()    (mpi_bsp_l)
#define AIG()    (mpi_bsp_g)
#define AISETL(X) (mpi_bsp_l=(X))
#define AISETG(X) (mpi_bsp_g=(X))
extern MPI_Comm comm;
extern MPI_Win  win;
extern MPI_Win  aiwin[];
extern int mpi_pid ;
extern int mpi_nprocs ;
extern double mpi_bsp_l ;
extern double mpi_bsp_g ;
extern double mpi_basetime;
#endif
