app_profiler.py 6.16 KB
Newer Older
German Leon's avatar
German Leon committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python3
import argparse
import os
import re
import time
import common_functions as cf
import common_parameters as cp


def generate_dict(sm_version, input_file_name):
    with open(input_file_name, "r") as f:
        # dictionary to store the number of allocated registers per static
        kernel_reg = {}

        kernel_name = ""  # temporary variable to store the kernel_name
        check_for_register_count = False

        # process the input file created by capturing the stderr while compiling the
        # application using -Xptxas -v options
        for line in f:  # for each line in the file
            m = re.match(r".*Compiling entry function.*'(\S+)'.*for.*'{}'.*".format(sm_version), line)
            if m:
                kernel_name = m.group(1)
                check_for_register_count = True

            m = re.match(r".*Used[ ]+(\d+)[ ]+registers.*", line)
            if check_for_register_count and m:
                reg_num = m.group(1)  # extract register number
                if kernel_name not in kernel_reg:
                    # associate the extracted register number with the kernel name
                    kernel_reg[kernel_name] = int(reg_num.strip())
                else:
                    print("Warning: {} exists in the kernel_reg dictionary. "
                          "Skipping this register count.".format(kernel_name))
                check_for_register_count = False

    return kernel_reg


"""
Function that calls the profiler based on the injection mode
"""


def profiler_caller(gdb_exec, kernel, benchmark_binary, benchmark_args,device,section,kernel_end):
    acc_time = 0
    acc_time_profiler=0
    script = 'env CUDA_VISIBLE_DEVICES={} {} -ex \'py arg0 = {}\' -n -batch -x {}'
    benchmark_args_striped = benchmark_args.replace('\\n', '').replace('\\', '')
    print ("KERNEL"+kernel)
    #init_string = '"file {}; set args {}"'.format(benchmark_binary, benchmark_args_striped)
    init_string = '"{};{};file {}; set args {}; break {}"'.format(section,kernel_end,benchmark_binary, benchmark_args_striped,kernel)
    profiler_cmd = script.format(device, gdb_exec, init_string, cp.PROFILER_SCRIPT)
    print ("Profiler caller")
    if cp.DEBUG:
        print("PROFILER CMD: {}".format(profiler_cmd))

    for i in range(0, cp.MAX_TIMES_TO_PROFILE):
        start = time.time()
        os.system(profiler_cmd)
        end = time.time()
        ret_profiler = cf.load_config_file("tmpxxx_return_profiler.conf")
        acc_time_profiler+=float(ret_profiler.get('DEFAULT', 'Tiempo'))
        acc_time += end - start
        cf.kill_all("killall -9 {}; killall -9 {}".format(
            os.path.basename(gdb_exec), os.path.basename(benchmark_binary)))
    return acc_time_profiler / cp.MAX_TIMES_TO_PROFILE, acc_time / cp.MAX_TIMES_TO_PROFILE




"""
Function to generate the gold execution
"""


def generate_gold(gdb_exec, benchmark_binary, benchmark_args,device):
    # Create tmp path and clean it if it exists
    tmp_path = os.path.dirname(os.path.realpath(__file__)) + "/" + cp.LOGS_PATH + "/tmp"
    os.system("mkdir -p " + tmp_path)
    os.system("rm -rf " + tmp_path + "/*")

    script = 'env CUDA_VISIBLE_DEVICES={} {} -ex \'py arg0 = {}\' -n -batch -x {} > {} 2> {}'
    init_string = '"file {}; set args {}"'.format(benchmark_binary, benchmark_args)
    profiler_cmd = script.format(device, gdb_exec, init_string, cp.PROFILER_SCRIPT, cp.GOLD_OUTPUT_PATH, cp.GOLD_ERR_PATH)
    if cp.DEBUG:
        print("PROFILER CMD: {}".format(profiler_cmd))

    # Execute and save gold file
    return os.system(profiler_cmd)


def main():
    os.system("rm -f {}".format(cp.KERNEL_INFO_DIR))
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--conf', dest="config_file", help='Configuration file', required=True)
    parser.add_argument('-d', '--device', dest="device", help="The GPU to perform FI."
                                                              " Default is 0.", required=False, default=0, type=int)
    args = parser.parse_args()

    # Read the configuration file with data for all the apps that will be executed
    conf = cf.load_config_file(args.config_file)

    # First set env vars
    cf.set_python_env()

    ########################################################################
    # Profiler step
    # Max time will be obtained by running
    # it will also get app output for golden copy
    # that is,
    print("###################################################\n1 - Profiling application")
    if 'benchmarkBinary_noverificar' in conf['DEFAULT']:
        benchmark_binary = conf.get('DEFAULT', 'benchmarkBinary_noverificar')
    else:
        benchmark_binary = conf.get('DEFAULT', 'benchmarkBinary')
    if 'benchmarkArgs_noverificar' in conf['DEFAULT']:
      benchmark_args = conf.get('DEFAULT', 'benchmarkArgs_noverificar')
    else:
      benchmark_args = conf.get('DEFAULT', 'benchmarkArgs')
    section= 'kernel_end' in conf['DEFAULT']
    kernel_end=''
    if (section):
       kernel_end=conf.get('DEFAULT','kernel_end')
    gdb_exec = conf.get("DEFAULT", "gdbExecName")
    kernel=conf.get('DEFAULT', 'kernel')
    [max_time_kernel,max_time_app] = profiler_caller(gdb_exec=gdb_exec,kernel=kernel, benchmark_binary=benchmark_binary, benchmark_args=benchmark_args,device=args.device,section=section,kernel_end=kernel_end)
    print ("Time kernel= "+str(max_time_kernel)+ "Time app "+str(max_time_app))
    # saving gold
    print ("Saving gold");
German Leon's avatar
German Leon committed
131
132
    #generate_gold_result = generate_gold(gdb_exec=gdb_exec,
    #                                     benchmark_binary=benchmark_binary, benchmark_args=benchmark_args,device=args.device)
German Leon's avatar
German Leon committed
133

German Leon's avatar
German Leon committed
134
135
    #if generate_gold_result != 0:
    #   raise EnvironmentError("Gold generation did not finish well, the fault injection will not work")
German Leon's avatar
German Leon committed
136
137
138
139
140
141
142
143
144
145
146
147
148

    # Remove trash GDB info from the std output and the err output
    cf.remove_useless_information_from_output(cp.GOLD_OUTPUT_PATH)
    cf.remove_useless_information_from_output(cp.GOLD_ERR_PATH)

    # Save the kernel configuration txt file
    cf.save_file(file_path=cp.KERNEL_INFO_DIR, data={'max_time': max_time_app,'max_time_kernel': max_time_kernel})

    print("1 - Profile finished\n###################################################")


if __name__ == '__main__':
    main()