| | |
| | | import base64 |
| | | import zlib |
| | | import io |
| | | |
| | | import os |
| | | from itertools import islice |
| | | import mmap |
| | | import shlex |
| | | import psutil |
| | | import time |
| | | import datetime |
| | | |
| | | ''' |
| | | This is a trisurf instance manager written in python |
| | |
| | | |
| | | ''' |
| | | |
| | | class FileContent: |
| | | def __init__(self,filename): |
| | | self.filename=filename |
| | | self.data="" |
| | | self.readfile() |
| | | |
| | | def readfile(self): |
| | | try: |
| | | with open (self.filename, "r") as myfile: |
| | | self.data=myfile.read().replace('\n', '') |
| | | except: |
| | | pass |
| | | |
| | | |
| | | def writefile(self, data, mode='w'): |
| | | with open (self.filename, mode) as myfile: |
| | | myfile.write(data) |
| | | |
| | | def getText(self): |
| | | return self.data |
| | | |
| | | def __str__(self): |
| | | return self.getText() |
| | | |
| | | class Tape: |
| | | '''Has all the info on the tape''' |
| | |
| | | except: |
| | | print("Error reading or parsing tape file!\n") |
| | | exit(1) |
| | | |
| | | |
| | | def setTape(self, string): |
| | | self.config=configobj.ConfigObj(io.StringIO(string)) |
| | |
| | | def getValue(self,key): |
| | | return self.config[key] |
| | | |
| | | def __str__(self): |
| | | retval="" |
| | | for key,val in self.config.iteritems(): |
| | | retval=retval+str(key)+" = "+str(val)+"\n" |
| | | return retval |
| | | |
| | | |
| | | |
| | | class Directory: |
| | | def __init__(self, maindir=".", simdir=""): |
| | | self.maindir=maindir |
| | | self.simdir=simdir |
| | | return |
| | | |
| | | def fullpath(self): |
| | | return os.path.join(self.maindir,self.simdir) |
| | | |
| | | def exists(self): |
| | | path=self.fullpath() |
| | | if(os.path.exists(path)): |
| | | return 1 |
| | | else: |
| | | return 0 |
| | | |
| | | def make(self): |
| | | try: |
| | | os.makedirs(self.fullpath()) |
| | | except: |
| | | print("Cannot make directory "+self.fullpath()+"\n") |
| | | exit(1) |
| | | return |
| | | |
| | | def makeifnotexist(self): |
| | | if(self.exists()==0): |
| | | self.make() |
| | | return |
| | | |
| | | def remove(self): |
| | | if(self.exists()): |
| | | try: |
| | | os.rmdir(self.fullpath()) |
| | | except: |
| | | print("Cannot remove directory "+self.fullpath()+ "\n") |
| | | exit(1) |
| | | return |
| | | |
| | | def goto(self): |
| | | try: |
| | | os.chdir(self.fullpath()) |
| | | except: |
| | | print("Cannot go to directory "+self.fullpath()+"\n") |
| | | return |
| | | |
| | | |
| | | class Statistics: |
| | | def __init__(self,path,filename="statistics.csv"): |
| | | self.path=path |
| | | self.filename=filename |
| | | self.fullname=os.path.join(path,filename) |
| | | self.fileOK=self.read() |
| | | return |
| | | |
| | | def exists(self): |
| | | if(os.path.isfile(self.fullname)): |
| | | return True |
| | | else: |
| | | return False |
| | | |
| | | def mapcount(self): |
| | | f = open(self.fullname, "r+") |
| | | buf = mmap.mmap(f.fileno(), 0) |
| | | lines = 0 |
| | | readline = buf.readline |
| | | while readline(): |
| | | lines += 1 |
| | | return lines |
| | | |
| | | def read(self): |
| | | if(self.exists()): |
| | | nlines=self.mapcount() |
| | | try: |
| | | with open(self.fullname, "r+") as fin: |
| | | i=0; |
| | | for line in fin: |
| | | if(i==1): |
| | | #print (line) |
| | | fields=shlex.split(line) |
| | | epoch1=fields[0] |
| | | n1=fields[1] |
| | | if(i==nlines-1): |
| | | fields=shlex.split(line) |
| | | epoch2=fields[0] |
| | | n2=fields[1] |
| | | i=i+1 |
| | | except: |
| | | #print("Cannot read statistics file in "+self.fullname+"\n") |
| | | return(False) |
| | | else: |
| | | #print("File "+self.fullname+" does not exists.\n") |
| | | return(False) |
| | | |
| | | self.dT=(int(epoch2)-int(epoch1))/(int(n2)-int(n1)) |
| | | self.last=n2 |
| | | self.startDate=epoch1 |
| | | return(True) |
| | | |
| | | def __str__(self): |
| | | return(str(self.fullname)) |
| | | |
| | | |
| | | |
| | | class Runner: |
| | | ''' |
| | | Class Runner consists of a single running or terminated instance of the trisurf |
| | | ''' |
| | | def __init__(self, subdir='run0', tape='', snapshot=''): |
| | | self.subdir=subdir |
| | | if(tape!=''): |
| | | self.initFromTape(tape) |
| | | if(snapshot!=''): |
| | | self.initFromSnapshot(snapshot) |
| | | return |
| | | |
| | | |
| | | def initFromTape(self, tape): |
| | | self.tape=Tape() |
| | | self.tape.readTape(tape) |
| | |
| | | root = tree.getroot() |
| | | tapetxt=root.find('tape') |
| | | version=root.find('trisurfversion') |
| | | #print("Reading snapshot made from: "+version.text) |
| | | self.tape=Tape() |
| | | #print(tapetxt.text) |
| | | self.tape.setTape(tapetxt.text) |
| | | |
| | | def __init__(self, subdir='run0', tape='', snapshot=''): |
| | | self.subdir=subdir |
| | | if(tape!=''): |
| | | self.initFromTape(tape) |
| | | if(snapshot!=''): |
| | | self.initFromSnapshot(snapshot) |
| | | |
| | | return |
| | | def getPID(self): |
| | | self.Dir=Directory(maindir=self.maindir,simdir=self.subdir) |
| | | self.Dir.makeifnotexist() |
| | | try: |
| | | fp = open(os.path.join(self.Dir.fullpath(),'.lock')) |
| | | except IOError as e: |
| | | return 0 #file probably does not exist. e==2?? |
| | | pid=fp.readline() |
| | | fp.close() |
| | | return pid |
| | | |
| | | def getStatus(self): |
| | | pass |
| | | pid=self.getPID() |
| | | if(pid==0): |
| | | return 0 |
| | | if(psutil.pid_exists(int(pid))): |
| | | if psutil.Process(int(pid)).name=="trisurf": |
| | | return 1 |
| | | else: |
| | | return 0 |
| | | else: |
| | | return 0 |
| | | |
| | | def start(self): |
| | | pass |
| | | if(self.getStatus()==0): |
| | | self.Dir=Directory(maindir=self.maindir,simdir=self.subdir) |
| | | self.Dir.makeifnotexist() |
| | | # self.Dir.goto() |
| | | print("Starting trisurf-ng executable at "+self.Dir.fullpath()+"\n") |
| | | else: |
| | | print("Process already running. Not starting\n") |
| | | return |
| | | |
| | | def stop(self): |
| | | pass |
| | | |
| | | def setMaindir(self,prefix,variables): |
| | | maindir="./" |
| | | for p,v in zip(prefix,variables): |
| | | if(v=="xk0"): |
| | | tv=str(round(float(self.tape.config[v]))) |
| | | else: |
| | | tv=self.tape.config[v] |
| | | maindir=maindir+p+tv |
| | | self.maindir=maindir |
| | | return |
| | | |
| | | def setSubdir(self, subdir="run0"): |
| | | self.subdir=subdir |
| | | return |
| | | |
| | | def getStatistics(self, statfile="statistics.csv"): |
| | | self.Dir=Directory(maindir=self.maindir,simdir=self.subdir) |
| | | self.statistics=Statistics(self.Dir.fullpath(), statfile) |
| | | self.Comment=FileContent(os.path.join(self.Dir.fullpath(),".comment")) |
| | | pid=self.getPID(); |
| | | if(self.getStatus()): |
| | | statustxt="Running" |
| | | else: |
| | | statustxt="Stopped" |
| | | pid="" |
| | | |
| | | if(self.statistics.fileOK): |
| | | # report=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(self.statistics.startDate)))+"\t"+str(datetime.timedelta(microseconds=(int(self.tape.config['iterations'])-int(self.statistics.last))*self.statistics.dT)*1000)+" ETA\t"+"STATUS" |
| | | report=[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(self.statistics.startDate))),str(datetime.timedelta(microseconds=(int(self.tape.config['iterations'])-int(self.statistics.last))*self.statistics.dT)*1000), statustxt, pid, str(self.Dir.fullpath()), self.Comment.getText()] |
| | | else: |
| | | report=["N/A","N/A\t",statustxt, pid, str(self.Dir.fullpath()), self.Comment.getText()] |
| | | return report |
| | | |
| | | def writeComment(self, data): |
| | | self.Dir=Directory(maindir=self.maindir,simdir=self.subdir) |
| | | self.Comment=FileContent(os.path.join(self.Dir.fullpath(),".comment")) |
| | | self.Comment.writefile(data,mode='w') |
| | | |
| | | def __str__(self): |
| | | return("Running instance") |
| | | if(self.getStatus()==0): |
| | | str=" not running." |
| | | else: |
| | | str=" running." |
| | | return(self.Dir.fullpath()+str) |
| | | |
| | | |