brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.8 KiB · 3c4f357 Raw
470 lines · python
1from __future__ import print_function2import ompdModule3from ompd_handles import ompd_thread, ompd_task, ompd_parallel4import gdb5import sys6import traceback7from enum import Enum8 9 10class ompd_scope(Enum):11    ompd_scope_global = 112    ompd_scope_address_space = 213    ompd_scope_thread = 314    ompd_scope_parallel = 415    ompd_scope_implicit_task = 516    ompd_scope_task = 617 18 19class ompd_address_space(object):20    def __init__(self):21        """Initializes an ompd_address_space object by calling ompd_initialize22        in ompdModule.c23        """24        self.addr_space = ompdModule.call_ompd_initialize()25        # maps thread_num (thread id given by gdb) to ompd_thread object with thread handle26        self.threads = {}27        self.states = None28        self.icv_map = None29        self.ompd_tool_test_bp = None30        self.scope_map = {31            1: "global",32            2: "address_space",33            3: "thread",34            4: "parallel",35            5: "implicit_task",36            6: "task",37        }38        self.sched_map = {1: "static", 2: "dynamic", 3: "guided", 4: "auto"}39        gdb.events.stop.connect(self.handle_stop_event)40        self.new_thread_breakpoint = gdb.Breakpoint(41            "ompd_bp_thread_begin", internal=True42        )43        tool_break_symbol = gdb.lookup_global_symbol("ompd_tool_break")44        if tool_break_symbol is not None:45            self.ompd_tool_test_bp = gdb.Breakpoint("ompd_tool_break", internal=True)46 47    def handle_stop_event(self, event):48        """Sets a breakpoint at different events, e.g. when a new OpenMP49        thread is created.50        """51        if isinstance(event, gdb.BreakpointEvent):52            # check if breakpoint has already been hit53            if self.new_thread_breakpoint in event.breakpoints:54                self.add_thread()55                gdb.execute("continue")56                return57            elif (58                self.ompd_tool_test_bp is not None59                and self.ompd_tool_test_bp in event.breakpoints60            ):61                try:62                    self.compare_ompt_data()63                    gdb.execute("continue")64                except ():65                    traceback.print_exc()66        elif isinstance(event, gdb.SignalEvent):67            # TODO: what do we need to do on SIGNALS?68            pass69        else:70            # TODO: probably not possible?71            pass72 73    def get_icv_map(self):74        """Fills ICV map."""75        self.icv_map = {}76        current = 077        more = 178        while more > 0:79            tup = ompdModule.call_ompd_enumerate_icvs(self.addr_space, current)80            (current, next_icv, next_scope, more) = tup81            self.icv_map[next_icv] = (current, next_scope, self.scope_map[next_scope])82        print("Initialized ICV map successfully for checking OMP API values.")83 84    def compare_ompt_data(self):85        """Compares OMPT tool data about parallel region to data returned by OMPD functions."""86        # make sure all threads and states are set87        self.list_threads(False)88 89        thread_id = gdb.selected_thread().ptid[1]90        curr_thread = self.get_curr_thread()91 92        # check if current thread is LWP thread; return if "ompd_rc_unavailable"93        thread_handle = ompdModule.get_thread_handle(thread_id, self.addr_space)94        if thread_handle == -1:95            print("Skipping OMPT-OMPD checks for non-LWP thread.")96            return97 98        print("Comparing OMPT data to OMPD data...")99        field_names = [i.name for i in gdb.parse_and_eval("thread_data").type.fields()]100        thread_data = gdb.parse_and_eval("thread_data")101 102        if self.icv_map is None:103            self.get_icv_map()104 105        # compare state values106        if "ompt_state" in field_names:107            if self.states is None:108                self.enumerate_states()109            ompt_state = str(thread_data["ompt_state"])110            ompd_state = str(self.states[curr_thread.get_state()[0]])111            if ompt_state != ompd_state:112                print(113                    "OMPT-OMPD mismatch: ompt_state (%s) does not match OMPD state (%s)!"114                    % (ompt_state, ompd_state)115                )116 117        # compare wait_id values118        if "ompt_wait_id" in field_names:119            ompt_wait_id = thread_data["ompt_wait_id"]120            ompd_wait_id = curr_thread.get_state()[1]121            if ompt_wait_id != ompd_wait_id:122                print(123                    "OMPT-OMPD mismatch: ompt_wait_id (%d) does not match OMPD wait id (%d)!"124                    % (ompt_wait_id, ompd_wait_id)125                )126 127        # compare thread id128        if "omp_thread_num" in field_names and "thread-num-var" in self.icv_map:129            ompt_thread_num = thread_data["omp_thread_num"]130            icv_value = ompdModule.call_ompd_get_icv_from_scope(131                curr_thread.thread_handle,132                self.icv_map["thread-num-var"][1],133                self.icv_map["thread-num-var"][0],134            )135            if ompt_thread_num != icv_value:136                print(137                    "OMPT-OMPD mismatch: omp_thread_num (%d) does not match OMPD thread num according to ICVs (%d)!"138                    % (ompt_thread_num, icv_value)139                )140 141        # compare thread data142        if "ompt_thread_data" in field_names:143            ompt_thread_data = thread_data["ompt_thread_data"].dereference()["value"]144            ompd_value = ompdModule.call_ompd_get_tool_data(145                3, curr_thread.thread_handle146            )[0]147            if ompt_thread_data != ompd_value:148                print(149                    "OMPT-OMPD mismatch: value of ompt_thread_data (%d) does not match that of OMPD data union (%d)!"150                    % (ompt_thread_data, ompd_value)151                )152 153        # compare number of threads154        if "omp_num_threads" in field_names and "team-size-var" in self.icv_map:155            ompt_num_threads = thread_data["omp_num_threads"]156            icv_value = ompdModule.call_ompd_get_icv_from_scope(157                curr_thread.get_current_parallel_handle(),158                self.icv_map["team-size-var"][1],159                self.icv_map["team-size-var"][0],160            )161            if ompt_num_threads != icv_value:162                print(163                    "OMPT-OMPD mismatch: omp_num_threads (%d) does not match OMPD num threads according to ICVs (%d)!"164                    % (ompt_num_threads, icv_value)165                )166 167        # compare omp level168        if "omp_level" in field_names and "levels-var" in self.icv_map:169            ompt_levels = thread_data["omp_level"]170            icv_value = ompdModule.call_ompd_get_icv_from_scope(171                curr_thread.get_current_parallel_handle(),172                self.icv_map["levels-var"][1],173                self.icv_map["levels-var"][0],174            )175            if ompt_levels != icv_value:176                print(177                    "OMPT-OMPD mismatch: omp_level (%d) does not match OMPD levels according to ICVs (%d)!"178                    % (ompt_levels, icv_value)179                )180 181        # compare active level182        if "omp_active_level" in field_names and "active-levels-var" in self.icv_map:183            ompt_active_levels = thread_data["omp_active_level"]184            icv_value = ompdModule.call_ompd_get_icv_from_scope(185                curr_thread.get_current_parallel_handle(),186                self.icv_map["active-levels-var"][1],187                self.icv_map["active-levels-var"][0],188            )189            if ompt_active_levels != icv_value:190                print(191                    "OMPT-OMPD mismatch: active levels (%d) do not match active levels according to ICVs (%d)!"192                    % (ompt_active_levels, icv_value)193                )194 195        # compare parallel data196        if "ompt_parallel_data" in field_names:197            ompt_parallel_data = thread_data["ompt_parallel_data"].dereference()[198                "value"199            ]200            current_parallel_handle = curr_thread.get_current_parallel_handle()201            ompd_value = ompdModule.call_ompd_get_tool_data(4, current_parallel_handle)[202                0203            ]204            if ompt_parallel_data != ompd_value:205                print(206                    "OMPT-OMPD mismatch: value of ompt_parallel_data (%d) does not match that of OMPD data union (%d)!"207                    % (ompt_parallel_data, ompd_value)208                )209 210        # compare max threads211        if "omp_max_threads" in field_names and "nthreads-var" in self.icv_map:212            ompt_max_threads = thread_data["omp_max_threads"]213            icv_value = ompdModule.call_ompd_get_icv_from_scope(214                curr_thread.thread_handle,215                self.icv_map["nthreads-var"][1],216                self.icv_map["nthreads-var"][0],217            )218            if icv_value is None:219                icv_string = ompdModule.call_ompd_get_icv_string_from_scope(220                    curr_thread.thread_handle,221                    self.icv_map["nthreads-var"][1],222                    self.icv_map["nthreads-var"][0],223                )224                if icv_string is None:225                    print(226                        "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (None Object)"227                        % (ompt_max_threads)228                    )229                else:230                    if ompt_max_threads != int(icv_string.split(",")[0]):231                        print(232                            "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!"233                            % (ompt_max_threads, int(icv_string.split(",")[0]))234                        )235            else:236                if ompt_max_threads != icv_value:237                    print(238                        "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!"239                        % (ompt_max_threads, icv_value)240                    )241 242        # compare omp_parallel243        # NOTE: omp_parallel = true if active-levels-var > 0244        if "omp_parallel" in field_names:245            ompt_parallel = thread_data["omp_parallel"]246            icv_value = ompdModule.call_ompd_get_icv_from_scope(247                curr_thread.get_current_parallel_handle(),248                self.icv_map["active-levels-var"][1],249                self.icv_map["active-levels-var"][0],250            )251            if (252                ompt_parallel == 1253                and icv_value <= 0254                or ompt_parallel == 0255                and icv_value > 0256            ):257                print(258                    "OMPT-OMPD mismatch: ompt_parallel (%d) does not match OMPD parallel according to ICVs (%d)!"259                    % (ompt_parallel, icv_value)260                )261 262        # compare omp_final263        if "omp_final" in field_names and "final-task-var" in self.icv_map:264            ompt_final = thread_data["omp_final"]265            current_task_handle = curr_thread.get_current_task_handle()266            icv_value = ompdModule.call_ompd_get_icv_from_scope(267                current_task_handle,268                self.icv_map["final-task-var"][1],269                self.icv_map["final-task-var"][0],270            )271            if icv_value != ompt_final:272                print(273                    "OMPT-OMPD mismatch: omp_final (%d) does not match OMPD final according to ICVs (%d)!"274                    % (ompt_final, icv_value)275                )276 277        # compare omp_dynamic278        if "omp_dynamic" in field_names and "dyn-var" in self.icv_map:279            ompt_dynamic = thread_data["omp_dynamic"]280            icv_value = ompdModule.call_ompd_get_icv_from_scope(281                curr_thread.thread_handle,282                self.icv_map["dyn-var"][1],283                self.icv_map["dyn-var"][0],284            )285            if icv_value != ompt_dynamic:286                print(287                    "OMPT-OMPD mismatch: omp_dynamic (%d) does not match OMPD dynamic according to ICVs (%d)!"288                    % (ompt_dynamic, icv_value)289                )290 291        # compare omp_max_active_levels292        if (293            "omp_max_active_levels" in field_names294            and "max-active-levels-var" in self.icv_map295        ):296            ompt_max_active_levels = thread_data["omp_max_active_levels"]297            icv_value = ompdModule.call_ompd_get_icv_from_scope(298                curr_thread.get_current_task_handle(),299                self.icv_map["max-active-levels-var"][1],300                self.icv_map["max-active-levels-var"][0],301            )302            if ompt_max_active_levels != icv_value:303                print(304                    "OMPT-OMPD mismatch: omp_max_active_levels (%d) does not match OMPD max active levels (%d)!"305                    % (ompt_max_active_levels, icv_value)306                )307 308                # compare omp_kind: TODO: Add the test for monotonic/nonmonotonic modifier309        if "omp_kind" in field_names and "run-sched-var" in self.icv_map:310            ompt_sched_kind = thread_data["omp_kind"]311            icv_value = ompdModule.call_ompd_get_icv_string_from_scope(312                curr_thread.get_current_task_handle(),313                self.icv_map["run-sched-var"][1],314                self.icv_map["run-sched-var"][0],315            )316            ompd_sched_kind = icv_value.split(",")[0]317            if self.sched_map.get(int(ompt_sched_kind)) != ompd_sched_kind:318                print(319                    "OMPT-OMPD mismatch: omp_kind kind (%s) does not match OMPD schedule kind according to ICVs (%s)!"320                    % (self.sched_map.get(int(ompt_sched_kind)), ompd_sched_kind)321                )322 323        # compare omp_modifier324        if "omp_modifier" in field_names and "run-sched-var" in self.icv_map:325            ompt_sched_mod = thread_data["omp_modifier"]326            icv_value = ompdModule.call_ompd_get_icv_string_from_scope(327                curr_thread.get_current_task_handle(),328                self.icv_map["run-sched-var"][1],329                self.icv_map["run-sched-var"][0],330            )331            token = icv_value.split(",")[1]332            if token is not None:333                ompd_sched_mod = int(token)334            else:335                ompd_sched_mod = 0336            if ompt_sched_mod != ompd_sched_mod:337                print(338                    "OMPT-OMPD mismatch: omp_kind modifier does not match OMPD schedule modifier according to ICVs!"339                )340 341        # compare omp_proc_bind342        if "omp_proc_bind" in field_names and "bind-var" in self.icv_map:343            ompt_proc_bind = thread_data["omp_proc_bind"]344            icv_value = ompdModule.call_ompd_get_icv_from_scope(345                curr_thread.get_current_task_handle(),346                self.icv_map["bind-var"][1],347                self.icv_map["bind-var"][0],348            )349            if icv_value is None:350                icv_string = ompdModule.call_ompd_get_icv_string_from_scope(351                    curr_thread.get_current_task_handle(),352                    self.icv_map["bind-var"][1],353                    self.icv_map["bind-var"][0],354                )355                if icv_string is None:356                    print(357                        "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (None Object)"358                        % (ompt_proc_bind)359                    )360                else:361                    if ompt_proc_bind != int(icv_string.split(",")[0]):362                        print(363                            "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!"364                            % (ompt_proc_bind, int(icv_string.split(",")[0]))365                        )366            else:367                if ompt_proc_bind != icv_value:368                    print(369                        "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!"370                        % (ompt_proc_bind, icv_value)371                    )372 373        # compare enter and exit frames374        if "ompt_frame_list" in field_names:375            ompt_task_frame_dict = thread_data["ompt_frame_list"].dereference()376            ompt_task_frames = (377                int(ompt_task_frame_dict["enter_frame"].cast(gdb.lookup_type("long"))),378                int(ompt_task_frame_dict["exit_frame"].cast(gdb.lookup_type("long"))),379            )380            current_task = curr_thread.get_current_task()381            ompd_task_frames = current_task.get_task_frame()382            if ompt_task_frames != ompd_task_frames:383                print(384                    "OMPT-OMPD mismatch: ompt_task_frames (%s) do not match OMPD task frames (%s)!"385                    % (ompt_task_frames, ompd_task_frames)386                )387 388        # compare task data389        if "ompt_task_data" in field_names:390            ompt_task_data = thread_data["ompt_task_data"].dereference()["value"]391            current_task_handle = curr_thread.get_current_task_handle()392            ompd_value = ompdModule.call_ompd_get_tool_data(6, current_task_handle)[0]393            if ompt_task_data != ompd_value:394                print(395                    "OMPT-OMPD mismatch: value of ompt_task_data (%d) does not match that of OMPD data union (%d)!"396                    % (ompt_task_data, ompd_value)397                )398 399    def save_thread_object(self, thread_num, thread_id, addr_space):400        """Saves thread object for thread_num inside threads dictionary."""401        thread_handle = ompdModule.get_thread_handle(thread_id, addr_space)402        self.threads[int(thread_num)] = ompd_thread(thread_handle)403 404    def get_thread(self, thread_num):405        """Get thread object from map."""406        return self.threads[int(thread_num)]407 408    def get_curr_thread(self):409        """Get current thread object from map or add new one to map, if missing."""410        thread_num = int(gdb.selected_thread().num)411        if thread_num not in self.threads:412            self.add_thread()413        return self.threads[thread_num]414 415    def add_thread(self):416        """Add currently selected (*) thread to dictionary threads."""417        inf_thread = gdb.selected_thread()418        try:419            self.save_thread_object(inf_thread.num, inf_thread.ptid[1], self.addr_space)420        except:421            traceback.print_exc()422 423    def list_threads(self, verbose):424        """Prints OpenMP threads only that are being tracking inside the "threads" dictionary.425        See handle_stop_event and add_thread.426        """427        list_tids = []428        curr_inferior = gdb.selected_inferior()429 430        for inf_thread in curr_inferior.threads():431            list_tids.append((inf_thread.num, inf_thread.ptid))432        if verbose:433            if self.states is None:434                self.enumerate_states()435            for (thread_num, thread_ptid) in sorted(list_tids):436                if thread_num in self.threads:437                    try:438                        print(439                            "Thread %i (%i) is an OpenMP thread; state: %s"440                            % (441                                thread_num,442                                thread_ptid[1],443                                self.states[self.threads[thread_num].get_state()[0]],444                            )445                        )446                    except:447                        traceback.print_exc()448                else:449                    print(450                        "Thread %i (%i) is no OpenMP thread"451                        % (thread_num, thread_ptid[1])452                    )453 454    def enumerate_states(self):455        """Helper function for list_threads: initializes map of OMPD states for output of456        'ompd threads'.457        """458        if self.states is None:459            self.states = {}460            current = int("0x102", 0)461            count = 0462            more = 1463 464            while more > 0:465                tup = ompdModule.call_ompd_enumerate_states(self.addr_space, current)466                (next_state, next_state_name, more) = tup467 468                self.states[next_state] = next_state_name469                current = next_state470