#!/usr/bin/python
""" -- Communism with PYTHON

Program performing coarse grain parallelization

Specs:
------

 Simple script performing a window of the input files
 listed in the .politburo file and then sending order
 to the nodes listed in .comrades file.

 Plus:
  -resistant to thread failures
  -accept multiple input/output files

 Minus:
  -nfs should run on every node
  -automount should run on every node

 A log file .communism_log contains a full report 

Files needed:
-------------

 >>.politburo<<
 
   overlap
   order
   winaxis
   cataxis
   inpufile
   outputfile
   auxilliary files

   Example:

   overlap=0
   order=Agc
   winaxis=3
   cataxis=3
   inputfile=cmp.H
   outputfile=out.H
   outputfile2=out2.H out  # tagname=filename type (o,ou,out,output,0 are valid answers)
   inputfile2=in2.H in     # tagname=filename type (i,in,input,1 are valid answers)

 >>.comrades<<

   box name/speed/#cpus

   Example:

   sep210 2 2
   sep211 2 1
   sep101 1 2

System requirements:
--------------------

 -nfs/autofs should be running on the nodes

"""
__author__ ='Antoine Guitton'
__version__='1.0'
__credits__='James Rickett for the previous Communism.c'
__date__='22 July 2004'

import anarchy
import string
import re
import os

class machine:
    """Class Machine"""
    def __init__(self,name,speed,cpu):
        """Machine

        name=machine name
        speed=relative speed
        cpu=number of cpus to use per machine
        """
        self.name=name
        self.speed=speed
        self.cpu=cpu

class process:
    """Class Process"""
    def __init__(self,name,start,share,done,overlap,ndone,nerr,nin,nout):
        """Process

        name=name of the machine for the current process
        start=starting point of the Window
        share=number of gathers per process
        done=check if the node is done or not
        overlap=number of gathers overlaping
        ndone=name of the temp file when the process is done
        nerr=name of the temp file when the process has died
        nin=name of the temp input file
        nout=name of the temp output file
        """
        self.name=name
        self.start=start
        self.share=share
        self.done=done
        self.overlap=overlap
        self.ndone=ndone
        self.nerr=nerr
        self.nin=nin
        self.nout=nout

class auxilliary_file:
    """Class Auxilliary file"""
    def __init__(self,flag,name,type,tmpn,ncpus):
        """Auxilliary files

        flag=tag name
        name=file name for the tag
        type=input or output file
        tmpn=name of the tmp file for the output auxilliary files
        ncpus=number of processors
        """
        self.flag=flag
        self.name=name
        self.type=type
        self.tmpn=range(ncpus)
        for i in range(ncpus):
            self.tmpn[i]=tmpn

class used_command:
    """Class Used Command"""
    def __init__(self,rm,seprm,sepcp,cat,rsh,win,touch):
        """Commands to be ran by processors

        rm=remove
        seprm=sep remove
        sepcp=sep sp
        cat=sep cat
        rsh=remote shell command
        win=sep window
        touch=touch command
        """
        self.RM=rm
        self.SEPRM=seprm
        self.SEPCP=sepcp
        self.CAT=cat
        self.RSH=rsh
        self.WIN=win
        self.TOUCH=touch
        
def main():
    """Communism with python

    1-Read .comrades
    2-Read .politburo
    3-Share the work
    4-Collect and cat the results

    Check the log file .communism_log
    """
    
    RM="/bin/rm -f"    
    SEPRM="Rm"   
    SEPCP="Cp"
    CAT="Cat3d"
    RSH="rsh"
    WIN="Window3d"
    TOUCH="touch"

    command = used_command(RM,SEPRM,SEPCP,CAT,RSH,WIN,TOUCH)
    
    atof=string.atof
    atoi=string.atoi
    
    computers=anarchy.read_comrades()
    (overlap,order,winaxis,cataxis,infile,outfile,aux_flag,aux_name,aux_type)=anarchy.read_politburo()

    ncomputers=len(computers)
    m=range(ncomputers)
    naux=len(aux_flag)
    auxfile=range(naux)
    
    for i in range(ncomputers):
        tmp=re.split('\s+',computers[i])
        name="%s"%(tmp[0])
        tmp2=machine(name,atof(tmp[1]),int(atof(tmp[2])))
        m[i]=tmp2
        
    (totalspeed,ncpus)=anarchy.countmachines(m,ncomputers)
        
    proc=range(ncpus)
    for i in range(ncpus):
        proc[i]=process(' ',0,0.,0,overlap,' ',' ',' ',' ') 

    if naux!=0:
        for i in range(naux):
            auxfile[i]=auxilliary_file(aux_flag[i],aux_name[i],aux_type[i],' ',ncpus)
           
    f=open('./.communism_log','w')
    f.write('-----------------------------------------------\n')
    f.write('           Communism is still ALIVE !!!        \n')
    f.write('         Python version by Antoine Guitton     \n')
    f.write('                 21 July 2004                  \n')
    f.write('-----------------------------------------------\n')
    f.write('-                                             -\n')
    f.write('-                                             -\n')
    f.write('-                                             -\n')

    anarchy.time_start(f)

    ngathers=anarchy.from_sep(infile,winaxis)
    anarchy.createproc(ncpus,proc,naux,auxfile)
    anarchy.divideup(m,proc,f,totalspeed,ncomputers,ncpus,ngathers)
    if overlap>0: anarchy.patch(proc,ncpus,overlap,ngathers,f)
    anarchy.doworkload(infile,outfile,auxfile,proc,order,command,f,winaxis,cataxis,ngathers,0,ncpus,naux)

    anarchy.time_stop(f)
    
    f.write('-----------------------------------------------\n')
    f.write('      THE END Communism is still ALIVE !!!     \n')
    f.write('-----------------------------------------------\n')
    f.close()

if __name__ == "__main__":        

    main()

