#!/usr/bin/env python
# @date   25 August, 2014
# @author cfuguet <cesar.fuguet-tortolero@lip6.fr>

import sys
import os
import subprocess
import arch
import faultyprocs
from parse import parse_ffstend

# define constants
# list of mesh dimensions
configs = []
configs.append([2 , 2 ]) # 4   clusters
configs.append([4 , 2 ]) # 8   clusters
configs.append([4 , 4 ]) # 16  clusters
configs.append([8 , 4 ]) # 32  clusters
configs.append([8 , 8 ]) # 64  clusters
configs.append([16, 8 ]) # 128 clusters
configs.append([16, 16]) # 256 clusters

# list of faulty cores
faultylist = []
faultylist.append([])                           # 0 faulty core
faultylist.append([(0,0,1)])                    # 1 faulty core
faultylist.append([(0,0,1), (0,0,3)])           # 2 faulty cores
faultylist.append([(1,0,0), (1,0,2), (1,0,3)])  # 1 faulty cluster
faultylist.append([(1,0,0), (1,0,2), (1,0,3),
                   (1,1,1), (1,1,2), (1,1,3)])  # 2 faulty cluster

faultynames = []
faultynames.append("0 faulty core")
faultynames.append("1 faulty core")
faultynames.append("2 faulty cores")
faultynames.append("1 faulty cluster")
faultynames.append("2 faulty clusters")

# number of processors per cluster
nprocs = 4

assert len(sys.argv) > 1, "Introduce platform base directory path"

# translate the relative path (if needed) into an absolute path
basedir = os.path.abspath(sys.argv[1])
print "[ run.py ] platform base directory: {0}".format(basedir)

# repeat while configurations is not empty
for f in xrange(len(faultylist)):
    for x,y in configs:
        confname = "conf/config_{0}c{1}f".format(x*y, f)
        confdir  = os.path.join(basedir, confname)
        print "[ run.py ] generating files for {0}".format(confdir)

        # 1. generate configuration and ouput directories
        try:
            os.makedirs(os.path.join(confdir, "config"), 0755)
        except OSError:
            pass # directory already exists => do nothing

        # 2. generate hard_config.h and fault_config.h files
        hardpath  = os.path.join(confdir, "config/hard_config.h")
        xmlpath   = os.path.join(confdir, "config/map.xml")
        faultpath = os.path.join(confdir, "config/fault_config.h") 
        arch.main( x, y, nprocs, hardpath, xmlpath)
        faultyprocs.generate(faultylist[f], faultpath)

        # 3. compile simulator executable
        dst = os.path.join(basedir, "hard_config.h")
        if os.path.lexists(dst): os.unlink(dst)
        os.symlink(hardpath, dst)
        subprocess.call(["make",
            "-C", basedir
            ])

        # 4. compile distributed boot executable
        dst = os.path.join(confdir, "config/boot_config.h")
        if os.path.lexists(dst): os.unlink(dst)
        os.symlink(os.path.join(basedir, "soft/config/boot_config.h"), dst)
        subprocess.call(["make",
            "-C", os.path.join(basedir, "soft"),
            "CONFDIR=" + confdir
            ])

        # 5. execute simulator
        os.environ["DISTRIBUTED_BOOT"] = "1"
        os.environ["SOCLIB_TTY"] = "FILES"

        if   x*y <= 4 : ompthreads = x*y
        elif x*y <= 16: ompthreads = 4
        else:           ompthreads = 8
        with open(os.path.join(confdir, "log"), "w") as logfile:
            print "executing simul.x"
            subprocess.call([os.path.join(basedir, "simul.x"),
                "-SOFT"   , os.path.join(basedir, "soft/build/soft.elf"),
                "-DISK"   , "/dev/null",
                "-THREADS", str(ompthreads),
                "-NCYCLES", "1000000"],
                stdout=logfile,
                stderr=logfile,
                )

        # 6. move simulation terminal output into the target config dir
        os.rename("term0", os.path.join(confdir, "term"))

        # end for each config
    #end for each faulty

# parse terminal logs to obtain statistics
statsdir = os.path.join(basedir, 'stats')
try:
    os.makedirs(statsdir, 0755)
except OSError:
    pass # directory already exists => do nothing

parse_ffstend(configs,
             faultynames,
             os.path.join(basedir, 'conf'),
             os.path.join(statsdir, 'ffst_stats.dat'))

# vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
