/****Copyright (c) 2001-2003  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


/**** BSP lib related definitions */
#ifdef BSPLIB
#include "bsp.h"
#define AIBEGIN     bsp_begin
#define AIOBEGIN    bsp_begin
#define AIEND       bsp_end
#define AIOEND      bsp_end

#define AIGET       bsp_get
#define AIHPGET     bsp_hpget
#define AIPUT       bsp_put
#define AIHPPUT     bsp_hpput
#define AIOGET      bsp_get
#define AIOHPGET    bsp_hpget
#define AIOPUT      bsp_put
#define AIOHPPUT    bsp_hpput

#define AIREGISTER  bsp_pushregister
#define AIOREGISTER bsp_pushregister
#define AIREG       bsp_pushregister
#define AIOREG      bsp_pushregister
#define AIDEREGISTER  bsp_popregister
#define AIODEREGISTER bsp_popregister
#define AIDEREG     bsp_popregister
#define AIODEREG    bsp_popregister

#define AISYNC      bsp_sync
#define AILSYNC(X)  bsp_sync()
#define AIOSYNC(X)  bsp_sync()

#define AIBARRIER   bsp_sync
#define AIOBARRIER  bsp_sync

#define AIABORT     bsp_abort
#define AIOABORT    bsp_abort

#define AIPID       bsp_pid
#define AIOPID      bsp_pid
#define AINPROCS    bsp_nprocs
#define AIONPROCS   bsp_nprocs

#define AITIME      bsp_time
#define AIOTIME     bsp_time
#define AIL()       (bsp_l())
#define AIOL()      (bsp_l())
#define AIG()       (bsp_g())
#define AIOG()      (bsp_g())
#define AISETL(X)   {}
#define AIOSETL(X)  {}
#define AISETG(X)   {}
#define AIOSETG(X)  {}
#endif


/* MPI related definitions (MPI-2 MPI_Put and MPI_Get must be supported*/
#ifdef   MPILIB
#include <mpi.h>
#define AIBEGIN(X)     (MPI_Init(&argc,&argv),mpi_basetime=MPI_Wtime())     
#define AIOBEGIN(X)    (MPI_Init(&argc,&argv),mpi_basetime=MPI_Wtime())     
#define AIEND()        MPI_Barrier(MPI_COMM_WORLD),MPI_Finalize()
#define AIOEND()       MPI_Barrier(MPI_COMM_WORLD),MPI_Finalize()
#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 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 AIOGET(X,Y,W,Z,R)   MPI_Get((char *)(Z),(R),MPI_CHAR,(X),(W),(R),\
                                     MPI_CHAR,aiwin[aisearch((void *)Y)])
#define AIOHPGET(X,Y,W,Z,R) MPI_Get((char *)(Z),(R),MPI_CHAR,(X),(W),(R),\
                                     MPI_CHAR,aiwin[aisearch((void *)Y)])
#define AIOPUT(X,Y,Z,W,R)   MPI_Put((char *)(Y),(R),MPI_CHAR,(X),(W),(R),\
                                     MPI_CHAR,aiwin[aisearch((void *)Z)])
#define AIOHPPUT(X,Y,Z,W,R) MPI_Put((char *)(Y),(R),MPI_CHAR,(X),(W),(R),\
                                     MPI_CHAR,aiwin[aisearch((void *)Z)]) 
#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,&win)
#define AIOREGISTER(X,Y)    MPI_Win_create((char *)(X),(Y),1,MPI_INFO_NULL\
                                ,MPI_COMM_WORLD,&aiwin[aiinsert((void*)X)]) 
#define AIOREG(X,Y)    MPI_Win_create((char *)(X),(Y),1,MPI_INFO_NULL\
                                ,MPI_COMM_WORLD,&aiwin[aiinsert((void*)X)])
#define AIDEREGISTER(X)     {;}  
#define AIDEREG(X)          {;}     
#define AIODEREGISTER(X)    {aidelete(X);} 
#define AIODEREG(X)         {aidelete(X);}
#define AISYNC(Z)            MPI_Win_fence(0,win) 
#define AIOSYNC(Z)          MPI_Win_fence(0,aiwin[aisearch((void *)Z)])
#define AIBARRIER()         MPI_Barrier(MPI_COMM_WORLD)
#define AIOBARRIER()        MPI_Barrier(MPI_COMM_WORLD)
#define AIABORT(X)          MPI_Abort(MPI_COMM_WORLD, __LINE__ )
#define AIOABORT(X)         MPI_Abort(MPI_COMM_WORLD, __LINE__ )
#define AIPID()             ((mpi_pid == -1)?(MPI_Comm_rank(MPI_COMM_WORLD,&mpi_pid),\
                            mpi_pid):mpi_pid)        
#define AIOPID()            ((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 AIONPROCS()    ((mpi_nprocs== -1)?(MPI_Comm_size(MPI_COMM_WORLD,&mpi_nprocs),\
                            mpi_nprocs):mpi_nprocs)
#define AITIME()            (MPI_Wtime()-mpi_basetime)      
#define AIOTIME()           (MPI_Wtime()-mpi_basetime)
#define AIL()               (mpi_bsp_l)
#define AIOL()              (mpi_bsp_l)
#define AIG()               (mpi_bsp_g)
#define AIOG()              (mpi_bsp_g)
#define AISETL(X)           (mpi_bsp_l=(X))
#define AIOSETL(X)          (mpi_bsp_l=(X))
#define AISETG(X)           (mpi_bsp_g=(X))
#define AIOSETG(X)          (mpi_bsp_g=(X))
extern MPI_Comm comm;
extern MPI_Win  win;
extern MPI_Win  aiwin[];
extern void*    bspmpi[];
extern int bspmpi_max ;
extern int bspmpi_first;
extern int bspmpicur_max ;
extern int mpi_pid ;
extern int mpi_nprocs ;
extern double mpi_bsp_l ;
extern double mpi_bsp_g ;
extern double mpi_basetime;
#endif
