
/*******************************************************************************
*
* File bg_fcts.c
*
* Copyright (C) 2007 Bjoern Leder
*
* This software is distributed under the terms of the GNU General Public
* License (GPL)
*
* BlueGene specific functions
*
* The externally accessible functions are 
*
*   void write_bglinfo(int my_rank, char *name)
*     On a BG/L this functions collects information from all MPI tasks about
*     the CPU they are running on:
*     - physical location in the processor grid
*     - CO or VN mode
*     - ID of the node
*     This information is formatted and written to the file "name"
*
* Notes:
*
* For a more detailed description of the available information see the
* IBM Redbook "Unfolding the IBM eServer Blue Gene Solution".
*
*******************************************************************************/

#define BG_FCTS_C

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "mpi.h"
#include "global.h"

#if (defined BGL)
#include <bglpersonality.h>

#define BG_INFO_LENGTH 16
static int bg_info[BG_INFO_LENGTH];
static char location[BGLPERSONALITY_MAX_LOCATION];


void write_bglinfo(int my_rank, char *name)
{
   FILE *info=NULL;
   MPI_Status stat;
   BGLPersonality p;
   int n,tag;

   if (my_rank==0)
   {
      error_root(iup[0][0]==0,1,"write_bglinfo [bg_fcts.c]",
                 "Lattice coordinates are not initalised");
      
      info=fopen(name,"w");
      error_root(info==NULL,1,"write_bglinfo [bg_fcts.c]",
                 "Unable to open info file");
      fprintf(info,"MPI rank/total     internal Coord.  BGL Torus Coord./ "
              "Grid shape  isTorus CO/VN    Node ID\n");
   }
   
   rts_get_personality(&p,sizeof(p));
   BGLPersonality_getLocationString(&p,location);
   bg_info[0]=my_rank;
   bg_info[1]=cpr[0];
   bg_info[2]=cpr[1];
   bg_info[3]=cpr[2];
   bg_info[4]=cpr[3];
   bg_info[5]=BGLPersonality_xCoord(&p);
   bg_info[6]=BGLPersonality_yCoord(&p);
   bg_info[7]=BGLPersonality_zCoord(&p);
   bg_info[8]=rts_get_processor_id();
   bg_info[9]=BGLPersonality_xSize(&p);
   bg_info[10]=BGLPersonality_ySize(&p);
   bg_info[11]=BGLPersonality_zSize(&p);
   bg_info[12]=BGLPersonality_virtualNodeMode(&p);
   bg_info[13]=BGLPersonality_isTorusX(&p);
   bg_info[14]=BGLPersonality_isTorusY(&p);
   bg_info[15]=BGLPersonality_isTorusZ(&p);
   
   for (n=0;n<NPROC;n++)
   {
      MPI_Barrier(MPI_COMM_WORLD);

      if (n>0)
      {
         tag=mpi_tag();

         if (my_rank==n)
            MPI_Send(bg_info,BG_INFO_LENGTH,MPI_INT,0,
                     tag,MPI_COMM_WORLD);

         if (my_rank==0)
            MPI_Recv(bg_info,BG_INFO_LENGTH,MPI_INT,n,
                     tag,MPI_COMM_WORLD,&stat);
      }
      
      if (my_rank==0)
      {
         fprintf(info,"W: %04i/%04i cpr: <%03i,%03i,%03i,%03i>  "
                 "BGL T: <%03i,%03i,%03i,%03i>/<%03i,%03i,%03i,%03i> "
                 "%1d%1d%1d %2s L: %s\n",
                 bg_info[0],NPROC,bg_info[1],bg_info[2],bg_info[3],bg_info[4],
                 bg_info[5],bg_info[6],bg_info[7], bg_info[8],
                 bg_info[9],bg_info[10],bg_info[11], bg_info[12]+1,
                 bg_info[13],bg_info[14],bg_info[15],bg_info[12] ? "VN" : "CO",
                 location);
      }
   }
   
   if (my_rank==0)
      fclose(info);
}

#endif
