#!/usr/bin/env python
#************************************************************************
# Codelet Tuning Infrastructure
# Copyright (C) 2010-2015 Intel Corporation, CEA, GENCI, and UVSQ
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#************************************************************************

# Authors: Franck Talbart, Mathieu Bordet, Nicolas Petit
import cti, ctr

from cti_hapi import entry, plugin, alias, util

import copy, sys, os, numpy, glob, tempfile, datetime, csv, time, subprocess

#constants & global
csv_loop_ID = "Loop ID"
csv_fct_name = "Function Name"
csv_source_infos = "Source Info"
csv_level = "Level"
csv_time_coverage = "Time %"
csv_time_sec = "Time (s)"
csv_CPI_ratio = "CPI ratio"
MAQAO_OUTPUT = "maqao_output"
LOOP_FILENAME_DEFAULT = "loop.txt"
message = ""
message_daemon = ""

def create_loop(repository,
                compiled_application,
                loop_id,
                first_line,
                last_line,
                fct_name,
                coverage,
                stability,
                time_sec,
                nb_sample,
                cpi_ratio,
                loop_type,
                file_name,
                loop_group,
                loop_plugin_uid,
                username,
                password,
                loop_parents = [],
                loop_children = []
               ):
    global message_daemon
            
    # loop language
    if file_name is None:
        loop_language = None
    elif ".c" in file_name.lower():
        loop_language = "c"
    else:
        loop_language = "fortran"
            
    loop_filename = None
    loop_filename_path = None
    if compiled_application:
        # search the source file
        if first_line is not None and \
            last_line is not None and \
            file_name is not None:
            for cur_dir in os.walk("."):
                if file_name in cur_dir[2]:
                    loop_filename_path = os.path.join(cur_dir[0], file_name)
                    break
                    
            # get the loop source code
            if loop_filename_path:
                loop_filename = LOOP_FILENAME_DEFAULT
                f = open(loop_filename_path, 'r')
                lines_filename  = f.readlines()
                loop_lines = lines_filename[first_line - 1:last_line + 1]
                f.close()
                
                loop_file = open(loop_filename, "w")
                loop_file.writelines(loop_lines)
                loop_file.close()
            else:
                message = "Error: file %s does not exist!\n" % file_name
                util.cti_plugin_print_error(message)
                message_daemon += message
            
    # creation of loop
    json = \
    {
        "init":
        {
            "attributes" : {cti.META_ATTRIBUTE_NAME : "init", cti.META_ATTRIBUTE_REP : repository},
            "params": 
            [
                {cti.META_ATTRIBUTE_NAME : "loop_id",cti.META_ATTRIBUTE_VALUE : loop_id},
                {cti.META_ATTRIBUTE_NAME : "first_line",cti.META_ATTRIBUTE_VALUE : first_line},
                {cti.META_ATTRIBUTE_NAME : "end_line",cti.META_ATTRIBUTE_VALUE : last_line},
                {cti.META_ATTRIBUTE_NAME : "language",cti.META_ATTRIBUTE_VALUE : loop_language},
                {cti.META_ATTRIBUTE_NAME : "source_function_name",cti.META_ATTRIBUTE_VALUE : fct_name},
                {cti.META_ATTRIBUTE_NAME : "coverage_maqao",cti.META_ATTRIBUTE_VALUE : coverage},
                {cti.META_ATTRIBUTE_NAME : "status_maqao_perf",cti.META_ATTRIBUTE_VALUE : stability},
                {cti.META_ATTRIBUTE_NAME : "time_sec",cti.META_ATTRIBUTE_VALUE : time_sec},
                {cti.META_ATTRIBUTE_NAME : "nb_sample",cti.META_ATTRIBUTE_VALUE : nb_sample},
                {cti.META_ATTRIBUTE_NAME : "cpi_ratio",cti.META_ATTRIBUTE_VALUE : cpi_ratio},
                {cti.META_ATTRIBUTE_NAME : "loop_files",cti.META_ATTRIBUTE_VALUE : [loop_filename]},
                {cti.META_ATTRIBUTE_NAME : "original_file",cti.META_ATTRIBUTE_VALUE : loop_filename_path},
                {cti.META_ATTRIBUTE_NAME : "loop_type",cti.META_ATTRIBUTE_VALUE : loop_type},
                {cti.META_ATTRIBUTE_NAME : "loop_group",cti.META_ATTRIBUTE_VALUE : loop_group},
                {cti.META_ATTRIBUTE_NAME : "loop_parents",cti.META_ATTRIBUTE_VALUE : loop_parents},
                {cti.META_ATTRIBUTE_NAME : "loop_children",cti.META_ATTRIBUTE_VALUE : loop_children}
            ]
        }
    }
            
    output = ""
    try:
        output = plugin.execute_plugin_by_file(loop_plugin_uid, json, username, password)
    except :
        print sys.exc_info()[1]
        exit(cti.CTI_PLUGIN_ERROR_UNEXPECTED)
         
    loop_uid = plugin.get_output_data_uid(output)
    return loop_uid

#---------------------------------------------------------------------------
def import_results(dict_opt):
    global message_daemon
    # result_dir does not necessary exist, as the experiment may have failed
    if dict_opt["result_dir"]:
        relevance_threshold_min = (dict_opt["nb_run_maqao_perf"] * 8) / 10
    
       # repository type
        repository = ctr.ctr_plugin_get_repository_by_uid(cti.CTR_ENTRY_DATA, dict_opt["entry"])
        # if the repository is local, we need its UID
        if repository == cti.CTR_REP_LOCAL:
            repository_path = ctr.ctr_plugin_global_index_file_ctr_by_entry_uid(dict_opt["entry"], cti.CTR_DATA_DIR)
            repository = str(ctr.ctr_plugin_global_index_file_get_uid_by_ctr(repository_path))
    
        list_run_loops = {}
        list_loops = {}
        list_total_coverage = []
        log_to_import = []
        # process all csv files Maqao perf produced
        list_csv = glob.glob(os.path.join(dict_opt["result_dir"], "*.csv"))
        for csv_file in list_csv:
            run_total_coverage = 0
            csv_file = os.path.join(dict_opt["result_dir"], csv_file)
            try:
                # import the log file into maqao_perf entry
                maqao_output_f = entry.put_file_in_entry(
                                    dict_opt["entry"], 
                                    csv_file, 
                                    False
                                )
                log_to_import.append(maqao_output_f)
            except IOError:
                message = "CTI error: No such file: '" + csv_file + "' \n"
                util.cti_plugin_print_error(message)
                message_daemon += message
        
            maqao_output_file = open(csv_file, "r")
            output_content = csv.DictReader(maqao_output_file, delimiter=";")
        
            list_run_loops[csv_file] = {}
            for line in output_content:
                loopID = int(line[csv_loop_ID])
                fct_name = line[csv_fct_name]
                if line[csv_source_infos]:
                    print line[csv_source_infos]
                    source_infos = line[csv_source_infos].split("@")
                    print source_infos
                    loop_lines = source_infos[0].split(",")
                    first_line = int(loop_lines[0])
                    last_line = int(loop_lines[1])
                    file_name = source_infos[1]
                else:
                    first_line = None
                    last_line = None
                    file_name = None
            
                tmp_loop_type = line[csv_level].lower()
                coverage_infos = line[csv_time_coverage].split(" ")
                coverage = float(coverage_infos[0])
                nb_sample = int(coverage_infos[1].replace("(", "").replace(")", ""))
                time_sec = float(line[csv_time_sec])
                cpi_ratio = float(line[csv_CPI_ratio])
            
                list_run_loops[csv_file][loopID] = coverage
                if list_loops.has_key(loopID):
                    list_loops[loopID]["coverage"].append(coverage)
                    list_loops[loopID]["nb_sample"].append(nb_sample)
                    list_loops[loopID]["time_sec"].append(time_sec)
                    list_loops[loopID]["CPI_ratio"].append(cpi_ratio)
                else:
                    list_loops[loopID] = {}
                    list_loops[loopID]["fct_name"] = fct_name
                    list_loops[loopID]["first_line"] = first_line
                    list_loops[loopID]["last_line"] = last_line
                    list_loops[loopID]["file_name"] = file_name
                    list_loops[loopID]["coverage"] = [coverage]
                    list_loops[loopID]["nb_sample"] = [nb_sample]
                    list_loops[loopID]["loop_type"] = tmp_loop_type
                    list_loops[loopID]["time_sec"] = [time_sec]
                    list_loops[loopID]["CPI_ratio"] = [cpi_ratio]
                run_total_coverage += coverage
        
            maqao_output_file.close()
            list_total_coverage.append(run_total_coverage)
    
        # creation of loop_group
        json = \
        {
            "init":
            {   
                "attributes" : {cti.META_ATTRIBUTE_NAME : "init", cti.META_ATTRIBUTE_REP : repository},
                "params": 
                [
                    {cti.META_ATTRIBUTE_NAME : "maqao_perf",cti.META_ATTRIBUTE_VALUE : dict_opt["entry"]},
                    {cti.META_ATTRIBUTE_NAME : "nb_loops",cti.META_ATTRIBUTE_VALUE : len(list_loops)},
                    {cti.META_ATTRIBUTE_NAME : "profiler_version",cti.META_ATTRIBUTE_VALUE : dict_opt["maqao_perf_version"]},
                    {cti.META_ATTRIBUTE_NAME : "loops",cti.META_ATTRIBUTE_VALUE : []}
                ]
            }
        }   
    
        output = ""
        try:
            output = plugin.execute_plugin_by_file(dict_opt["loop_group_plugin_uid"], json, dict_opt["username"], dict_opt["password"])
        except :
            print sys.exc_info()[1]
            exit(cti.CTI_PLUGIN_ERROR_UNEXPECTED)
    
        loop_group_uid = plugin.get_output_data_uid(output)
    
        (_, output_param_maqao_perf) = entry.load_data(dict_opt["entry"])
        binary_entry = output_param_maqao_perf["init"].params["binary"][cti.META_ATTRIBUTE_VALUE]
    
        #Alias for loop_group
        bin_name = alias.get_data_alias(binary_entry)
        now = datetime.datetime.now()
        date = now.strftime('%Y_%m_%d_%H:%M:%S:%f')
        if not bin_name:
            alias_loop_group = "Loop_group_{0}".format(date)
        else:
            alias_loop_group = "{0}_Loop_group_{1}".format(bin_name, date)
    
        if alias.set_data_alias(loop_group_uid, alias_loop_group) == 0:
            util.cti_plugin_print_warning("Cannot set the alias %s (already used?)" % (alias_loop_group))
    
        if dict_opt["compiled_application"]:
            tmp_dir = tempfile.mkdtemp()
            os.chdir(tmp_dir)
        
            os.system("cp %s ." % dict_opt["compiled_application_path"])
            os.system("tar xf " + dict_opt["compiled_application"])
            os.remove(dict_opt["compiled_application"])
    
        message = "* List of loops detected by Maqao perf on the application:\n"
        print message,
        message_daemon += message
    
        # create loops entries
        total = len(list_loops) 
        counter = 1.
        for loopID in list_loops.keys():
            util.rewrite_output_line("[" + str(int(counter / total * 100)) + " %]")
            list_loops[loopID]["coverage_median"] = float(numpy.median(list_loops[loopID]["coverage"]))
            list_loops[loopID]["nb_sample_median"] = float(numpy.median(list_loops[loopID]["nb_sample"]))
            list_loops[loopID]["time_sec_median"] = float(numpy.median(list_loops[loopID]["time_sec"]))
            list_loops[loopID]["CPI_ratio_median"] = float(numpy.median(list_loops[loopID]["CPI_ratio"]))
            list_loops[loopID]["parent"] = None
            list_loops[loopID]["children"] = []
            list_loops[loopID]["inclusive_coverage"] = list_loops[loopID]["coverage_median"]
            list_loops[loopID]["inclusive_nb_sample"] = list_loops[loopID]["nb_sample_median"]
                
            message = "\t* Loop %s from %s (function %s), lines: %s-%s, coverage (median): %s, samples (median): %s\n\n" % \
                (loopID, list_loops[loopID]["file_name"], list_loops[loopID]["fct_name"], list_loops[loopID]["first_line"], list_loops[loopID]["last_line"], list_loops[loopID]["coverage_median"], list_loops[loopID]["nb_sample_median"])
            print message,
            message_daemon += message
        
            # stability
            if len(list_loops[loopID]["coverage"]) >= relevance_threshold_min:
                mini = min(list_loops[loopID]["coverage"])
                if mini == 0:
                    list_loops[loopID]["stability"] = "unstable"
                else:
                    s_check = (list_loops[loopID]["coverage_median"] - mini) / mini
                    if s_check <= dict_opt["stability_sanity_check"]:
                        list_loops[loopID]["stability"] = "stable"
                    else:
                        list_loops[loopID]["stability"] = "unstable"
            else:
                list_loops[loopID]["stability"] = "unstable"

            loop_uid = create_loop(
                        repository,
                        dict_opt["compiled_application"],
                        loopID,
                        list_loops[loopID]["first_line"],
                        list_loops[loopID]["last_line"],
                        list_loops[loopID]["fct_name"],
                        list_loops[loopID]["coverage_median"],
                        list_loops[loopID]["stability"],
                        list_loops[loopID]["time_sec_median"],
                        list_loops[loopID]["nb_sample_median"],
                        list_loops[loopID]["CPI_ratio_median"],
                        list_loops[loopID]["loop_type"],
                        list_loops[loopID]["file_name"],
                        loop_group_uid,
                        loop_plugin_uid = dict_opt["loop_plugin_uid"],
                        username = dict_opt["username"],
                        password = dict_opt["password"]
            )
        
            # alias for loop
            now = datetime.datetime.now()
            date = now.strftime('%Y_%m_%d_%H:%M:%S:%f')
            if not bin_name:
                alias_loop = "Loop{0}_{1}".format(loopID, date)
            else:
                alias_loop = "{0}_Loop{1}_{2}".format(bin_name, loopID, date)
            if alias.set_data_alias(loop_uid, alias_loop) == 0:
                util.cti_plugin_print_warning("Cannot set the alias %s (already used?)" % (alias_loop))
            list_loops[loopID]["loop_uid"] = loop_uid
        
            counter = counter + 1
    
        # loop hierarchy
        loop_hierarchy = open(os.path.join(dict_opt["result_dir"], "loop_hierarchy"), "r")
        for line_loop in loop_hierarchy.readlines():
            line_loop = line_loop.split(":")
            loop_id_parent = int(line_loop[0])        
            if list_loops.has_key(loop_id_parent):
                list_loop_uid_child = []
                list_loop_id_child = []
                for loop_child in line_loop[1].split(","):
                    try:
                        loop_id_child = int(loop_child)
                        if list_loops.has_key(loop_id_child):
                            list_loop_uid_child.append(list_loops[loop_id_child]["loop_uid"])
                            list_loop_id_child.append(loop_id_child)
                            # update loop child entry
                            entry.update_entry_parameter(list_loops[loop_id_child]["loop_uid"],
                                                        {
                                                            "loop_parents":
                                                                {
                                                                    "value":
                                                                        [list_loops[loop_id_parent]["loop_uid"]],
                                                                        "append": False
                                                                }
                                                            }
                                                        )
                            list_loops[loop_id_child]['parent'] = loop_id_parent
                    except ValueError:
                        pass
                if list_loop_uid_child:
                    # update loop parent entry
                    entry.update_entry_parameter(list_loops[loop_id_parent]["loop_uid"], {
                                                                                        "loop_children": 
                                                                                            {
                                                                                                "value": list_loop_uid_child,
                                                                                                "append": False
                                                                                            }
                                                                                        }
                                                                                    )
                    list_loops[loop_id_parent]['children'] = list_loop_id_child
        loop_hierarchy.close()
    
        total_coverage_loop = None
        if list_total_coverage:
            total_coverage_loop = float(numpy.median(list_total_coverage))
        
        # update the maqao_perf entry
        entry.update_entry_parameter(dict_opt["entry"], {"total_coverage_loop": {"value": total_coverage_loop},
                                                    "csv_output": {"value": log_to_import, "append": True}
                                                    })
                                                   
        # insert the missing outermost/inbetween: since MAQAO Perf uses an exclusive method, all outermost/inbetween are not necessarily recorded into
        # the repository... 
        # Franck: WARNING: This part burnt my brain. Really. So please make sure you know what you are doing before updating it...!
        def get_missing_loops(id_loop):
            print "Searching parent for id loop %s" % (id_loop)
            sys.stdout.flush()        
            p = loop_parent[id_loop][0]
            try:
                new_id_loop = int(p)
            except:
                return None
            first_l = int(loop_parent[id_loop][1])
            last_l = int(loop_parent[id_loop][2])
            file_l = os.path.basename(loop_parent[id_loop][3])
            if first_l == -1:
                first_l = None
            if last_l == -1:
                last_l = None
            if file_l == "-1":
                file_l = None
            new_parent_loop = get_missing_loops(new_id_loop)
            # Does the loop already exist?
            if new_id_loop in list_loops:
                # Yes!
                # It does not mean the dependencies exist, the loop might have been created artficially 
                # during the process...
                # we don't create the links right now because id_loop does not necessary exist at this step;
                # this will be processed at the end
                missing_link_parents[id_loop] = new_id_loop
                if not missing_link_child.has_key(new_id_loop):
                    missing_link_child[new_id_loop] = []
                missing_link_child[new_id_loop].append(id_loop)
            else:  # the loop does not exist 
                if new_parent_loop is not None:
                    status_loop = "inbetween"
                else:
                    status_loop = "outermost"
                
                # Along with the DB update, the array must be filled as well
                # because it is used for the inclusive coverage computation
                list_loops[new_id_loop] = { \
                                            "first_line" : first_l,
                                            "last_line" : last_l,
                                            "fct_name" : None,
                                            "coverage_median" : 0,
                                            "inclusive_coverage" : 0,
                                            "inclusive_nb_sample" : 0,
                                            "stability" : "unstable/artificial add",
                                            "time_sec_median" : 0,
                                            "nb_sample_median" : 0,
                                            "CPI_ratio_median" : 0,
                                            "file_name" : file_l,
                                            "loop_type" : status_loop,
                                            "parent" : new_parent_loop,
                                            "children" : []
                                        }
            
                if new_parent_loop is None:
                    loop_parents = []
                else:
                    loop_parents = [ list_loops[new_parent_loop]["loop_uid"] ]
                
                # loop_children does not necessary exist at this step
                loop_children = []
                if not missing_link_child.has_key(new_id_loop):
                    missing_link_child[new_id_loop] = []
                missing_link_child[new_id_loop].append(id_loop)
            
                print " Creating missing loop %s" % (new_id_loop)
                print "  First line is %s" % (list_loops[new_id_loop]["first_line"])
                print "  Last line is %s" % (list_loops[new_id_loop]["last_line"])
                print "  Filename is %s" % (list_loops[new_id_loop]["file_name"])
            
                loop_uid = create_loop(
                            repository,
                            dict_opt["compiled_application"],
                            new_id_loop,
                            list_loops[new_id_loop]["first_line"],
                            list_loops[new_id_loop]["last_line"],
                            list_loops[new_id_loop]["fct_name"],
                            list_loops[new_id_loop]["coverage_median"],
                            list_loops[new_id_loop]["stability"],
                            list_loops[new_id_loop]["time_sec_median"],
                            list_loops[new_id_loop]["nb_sample_median"],
                            list_loops[new_id_loop]["CPI_ratio_median"],
                            list_loops[new_id_loop]["loop_type"],
                            list_loops[new_id_loop]["file_name"],
                            loop_group_uid,
                            dict_opt["loop_plugin_uid"],
                            dict_opt["username"],
                            dict_opt["password"],
                            loop_parents,
                            loop_children
                )
                list_loops[new_id_loop]["loop_uid"] = loop_uid

                # As of now, the missing loop is created,
                # and we need to add the dependency between its child and itself
                # but the child does not necessary exist at this step...
                missing_link_parents[id_loop] = new_id_loop
            return new_id_loop
            
        print "Recording the missing outermost / between loops not detected by Maqao Perf..."
        sys.stdout.flush()
        missing_link_child = {}
        missing_link_parents = {}
        parent_hierarchy = open(os.path.join(dict_opt["result_dir"], "parent_hierarchy"), "r")
        loop_parent = {}
        for line_parent in parent_hierarchy.readlines():
            line_parent = line_parent.strip()
            if line_parent:
                line_parent = line_parent.split(";")
                loop_parent[int(line_parent[0])] = line_parent[1:]
        parent_hierarchy.close()
    
        for loopID in list_loops.keys():
            if list_loops[loopID]["loop_type"] in ["innermost"]:
                get_missing_loops(loopID)
    
        print "Creating the missing links..."
        print "* Children..."
        sys.stdout.flush()
        for id in missing_link_child:
            for l in missing_link_child[id]:
                if not l in list_loops[id]["children"]:
                    list_loops[id]["children"].append(l)
                    entry.update_entry_parameter(list_loops[id]["loop_uid"], {"loop_children": {"value": [ list_loops[l]["loop_uid" ]], "append": True}})

        print "* Parents..."
        sys.stdout.flush()
        for id in missing_link_parents:
            if list_loops[id]["parent"] != missing_link_parents[id]:
                list_loops[id]["parent"] = missing_link_parents[id]
                entry.update_entry_parameter(list_loops[id]["loop_uid"], {"loop_parents": {"value": [ list_loops[missing_link_parents[id]]["loop_uid" ]], "append": True}})

        os.chdir(dict_opt["result_dir"])

        print "Adding the ASM source code..."
        sys.stdout.flush()
        maqao_dir = dict_opt["TOOL"][0]
        os.system("tar xf " + dict_opt["binary_path"])
        binary = os.path.basename(dict_opt["binary_path"].replace(".tar.gz", ""))
        asm_script_path = os.path.join(dict_opt["plugin_dir"], "get_asm.lua")
        cmd_asm = [os.path.join(maqao_dir, "maqao"), asm_script_path, binary, "loop=%s"%(",".join(str(x) for x in list_loops.keys()))]

        try:
            child = subprocess.Popen(cmd_asm, shell=False)
            
            output = child.communicate()
            rc = child.returncode
            
            if rc != 0:
                raise Exception("The command " + 
                        str(cmd_asm) + 
                        " encountered the error #" + 
                        str(rc) +
                        " Output: " + 
                        str(output))

        except:
            util.cti_plugin_print_error("Failed to execute command: {0}".format(cmd_asm))
            exit(cti.CTI_PLUGIN_ERROR_UNEXPECTED)

        def add_files(list_add_files):
            for l_uid in list_add_files:
                entry.put_file_in_entry(
                        cti.CTI_UID(l_uid), 
                        list_add_files[l_uid], 
                        False
                        )
                entry.update_entry_parameter(cti.CTI_UID(l_uid),
                                            {"loop_files":
                                                {"value": list_add_files[l_uid], "append": True}
                                            }
                                        )
        list_add_files = {}
        for l in list_loops.keys():
            l_uid = list_loops[l]["loop_uid"]
            if not list_add_files.has_key(str(l_uid)):
                list_add_files[str(l_uid)] = []
            l_file = "loop_%s.asm"%(l)
            if os.path.isfile(l_file):
                list_add_files[str(l_uid)].append(l_file)
            else:
                cpt_l = 1
                l_file = "loop_%s_path_%s.asm" % (l, cpt_l)
                while os.path.isfile(l_file):
                    list_add_files[str(l_uid)].append(l_file)
                    cpt_l +=1
                    l_file = "loop_%s_path_%s.asm" % (l, cpt_l)
        add_files(list_add_files)
 
        waiting_loop_ids = copy.copy(list_loops.keys())
        processed_loop_ids = []

        #Keep cycling until all loops are processed
        print "Computing the inclusive coverage and nb sample..."
        sys.stdout.flush()
        while(waiting_loop_ids):
            #Trying to process the loops
            for loop_id in waiting_loop_ids:
                if loop_id in list_loops[loop_id]["children"]:
                    util.cti_plugin_print_error("ERROR: loop {0} is catalogued as being its own parent/child !".format(loop_id))
                computable = [x in processed_loop_ids for x in list_loops[loop_id]["children"] if x != loop_id]
                #The loop is processed if it has no children or if all the children have already been processed.
                if not computable or False not in computable:
                    #Computing the sum
                    list_loops[loop_id]["inclusive_coverage"] = list_loops[loop_id]["inclusive_coverage"] + sum([list_loops[x]["inclusive_coverage"] for x in list_loops[loop_id]["children"]])
                    list_loops[loop_id]["inclusive_nb_sample"] = list_loops[loop_id]["inclusive_nb_sample"] + sum([list_loops[x]["inclusive_nb_sample"] for x in list_loops[loop_id]["children"]])
                    #Updating the entry
                    entry.update_entry_parameter(list_loops[loop_id]["loop_uid"], {"inclusive_coverage": {"value": list_loops[loop_id]["inclusive_coverage"]}, "inclusive_nb_sample": {"value": list_loops[loop_id]["inclusive_nb_sample"]}})
                    processed_loop_ids.append(loop_id)
        
            #Removing processed ids from the main loop list.
            for processed_id in processed_loop_ids:
                if processed_id in waiting_loop_ids:
                    waiting_loop_ids.remove(processed_id)
        if dict_opt["compiled_application"]:
            os.system("rm -rf " + tmp_dir)
    os.chdir(dict_opt["result_dir"])
    # import exectution log file into maqao_perf
    execution_log_file = ""
    try:
        execution_log_file = entry.put_file_in_entry(
                                                        dict_opt["entry"], 
                                                        dict_opt["execution_log"], 
                                                        False
                                                    )
    except IOError:
        message = "CTI error: No such file: '" + dict_opt["execution_log"] + "' \n"
        util.cti_plugin_print_error(message)
        message_daemon += message

    file_daemon = open(dict_opt["daemon_log"], "a")
    file_daemon.write(message_daemon)
    file_daemon.close()
    # import daemon log file into maqao_perf
    daemon_log_file = ""
    try:
        daemon_log_file = entry.put_file_in_entry(
                            dict_opt["entry"], 
                            dict_opt["daemon_log"], 
                            False
                        )
    except IOError:
        util.cti_plugin_print_error("CTI error: No such file: '" + dict_opt["daemon_log"] + "'")

    entry.update_entry_parameter(dict_opt["entry"], {"logs": {"value": [daemon_log_file, execution_log_file], "append": True},
                                                    "nb_run_maqao_perf": {"value": dict_opt["nb_run_maqao_perf"]}
                                                   })
    time_process = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime())
    print "\n[" + str(time_process) + "] End of process"
