Add TAMPI model with subsystems view
This commit is contained in:
		
							parent
							
								
									9269dd7202
								
							
						
					
					
						commit
						276afd5479
					
				| @ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||||||
| - Add `ovni_version_get()` function. | - Add `ovni_version_get()` function. | ||||||
| - Add the `ovniver` program to report the libovni version and commit. | - Add the `ovniver` program to report the libovni version and commit. | ||||||
| - Add nOS-V API subsystem events for `nosv_create()` and `nosv_destroy()`. | - Add nOS-V API subsystem events for `nosv_create()` and `nosv_destroy()`. | ||||||
|  | - Add TAMPI model with `T` code. | ||||||
|  | - Add subsytem events and cfgs for TAMPI model. | ||||||
| 
 | 
 | ||||||
| ## [1.2.2] - 2022-07-26 | ## [1.2.2] - 2022-07-26 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										42
									
								
								cfg/cpu/tampi/subsystem.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								cfg/cpu/tampi/subsystem.cfg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | #ParaverCFG | ||||||
|  | ConfigFile.Version: 3.4 | ||||||
|  | ConfigFile.NumWindows: 1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ################################################################################ | ||||||
|  | < NEW DISPLAYING WINDOW CPU: TAMPI subsystem of the RUNNING thread > | ||||||
|  | ################################################################################ | ||||||
|  | window_name CPU: TAMPI subsystem of the RUNNING thread | ||||||
|  | window_type single | ||||||
|  | window_id 1 | ||||||
|  | window_position_x 0 | ||||||
|  | window_position_y 0 | ||||||
|  | window_width 600 | ||||||
|  | window_height 150 | ||||||
|  | window_comm_lines_enabled true | ||||||
|  | window_flags_enabled false | ||||||
|  | window_noncolor_mode true | ||||||
|  | window_logical_filtered true | ||||||
|  | window_physical_filtered false | ||||||
|  | window_comm_fromto true | ||||||
|  | window_comm_tagsize true | ||||||
|  | window_comm_typeval true | ||||||
|  | window_units Microseconds | ||||||
|  | window_maximum_y 1000.0 | ||||||
|  | window_minimum_y 1.0 | ||||||
|  | window_compute_y_max true | ||||||
|  | window_level thread | ||||||
|  | window_scale_relative 1.000000000000 | ||||||
|  | window_end_time_relative 1.000000000000 | ||||||
|  | window_object appl { 1, { All } } | ||||||
|  | window_begin_time_relative 0.000000000000 | ||||||
|  | window_open true | ||||||
|  | window_drawmode draw_randnotzero | ||||||
|  | window_drawmode_rows draw_randnotzero | ||||||
|  | window_pixel_size 1 | ||||||
|  | window_labels_to_draw 1 | ||||||
|  | window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } | ||||||
|  | window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } | ||||||
|  | window_filter_module evt_type 1 20 | ||||||
|  | window_filter_module evt_type_label 1 "CPU: TAMPI subsystem of the RUNNING thread" | ||||||
|  | 
 | ||||||
							
								
								
									
										42
									
								
								cfg/thread/tampi/subsystem.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								cfg/thread/tampi/subsystem.cfg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | #ParaverCFG | ||||||
|  | ConfigFile.Version: 3.4 | ||||||
|  | ConfigFile.NumWindows: 1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ################################################################################ | ||||||
|  | < NEW DISPLAYING WINDOW Thread: TAMPI subsystem of the ACTIVE thread > | ||||||
|  | ################################################################################ | ||||||
|  | window_name Thread: TAMPI subsystem of the ACTIVE thread | ||||||
|  | window_type single | ||||||
|  | window_id 1 | ||||||
|  | window_position_x 0 | ||||||
|  | window_position_y 0 | ||||||
|  | window_width 600 | ||||||
|  | window_height 150 | ||||||
|  | window_comm_lines_enabled true | ||||||
|  | window_flags_enabled false | ||||||
|  | window_noncolor_mode true | ||||||
|  | window_logical_filtered true | ||||||
|  | window_physical_filtered false | ||||||
|  | window_comm_fromto true | ||||||
|  | window_comm_tagsize true | ||||||
|  | window_comm_typeval true | ||||||
|  | window_units Microseconds | ||||||
|  | window_maximum_y 1000.0 | ||||||
|  | window_minimum_y 1.0 | ||||||
|  | window_compute_y_max true | ||||||
|  | window_level thread | ||||||
|  | window_scale_relative 1.000000000000 | ||||||
|  | window_end_time_relative 1.000000000000 | ||||||
|  | window_object appl { 1, { All } } | ||||||
|  | window_begin_time_relative 0.000000000000 | ||||||
|  | window_open true | ||||||
|  | window_drawmode draw_randnotzero | ||||||
|  | window_drawmode_rows draw_randnotzero | ||||||
|  | window_pixel_size 1 | ||||||
|  | window_labels_to_draw 1 | ||||||
|  | window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } | ||||||
|  | window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } | ||||||
|  | window_filter_module evt_type 1 20 | ||||||
|  | window_filter_module evt_type_label 1 "Thread: TAMPI subsystem of the ACTIVE thread" | ||||||
|  | 
 | ||||||
| @ -193,4 +193,36 @@ KCI	Is back in the CPU due to a context switch | |||||||
| 6MA	Ends allocating memory | 6MA	Ends allocating memory | ||||||
| 6Mf	Begins freeing memory | 6Mf	Begins freeing memory | ||||||
| 6MF	Ends freeing memory | 6MF	Ends freeing memory | ||||||
|  | 
 | ||||||
|  | -------------------- TAMPI (model=T) ---------------------- | ||||||
|  | 
 | ||||||
|  | TCi Begins to issue a non-blocking communication operation | ||||||
|  | TCI Ends issuing a non-blocking communication operation | ||||||
|  | 
 | ||||||
|  | TGc Begins to check pending requests from the global array | ||||||
|  | TGC Ends checking pending requests from the global array | ||||||
|  | 
 | ||||||
|  | TLi Begins the library code at an API function | ||||||
|  | TLI Ends the library code at an API function | ||||||
|  | TLp Begins the library code at a polling function | ||||||
|  | TLP Ends the library code at a polling function | ||||||
|  | 
 | ||||||
|  | TQa Begins to add a ticket/requests to a queue | ||||||
|  | TQA Ends adding a ticket/requests to a queue | ||||||
|  | TQt Begins to transfer tickets/requests from queues to global array | ||||||
|  | TQT Ends transfering tickets/requests from queues to global array | ||||||
|  | 
 | ||||||
|  | TRc Begins to process a completed request | ||||||
|  | TRC Ends processing a completed request | ||||||
|  | TRt Begins to test a single request with MPI_Test | ||||||
|  | TRT Ends testing a single request with MPI_Test | ||||||
|  | TRa Begins to test several requests with MPI_Testall | ||||||
|  | TRA Ends testing several requests with MPI_Testall | ||||||
|  | TRs Begins to test several requests with MPI_Testsome | ||||||
|  | TRS Ends testing several requests with MPI_Testsome | ||||||
|  | 
 | ||||||
|  | TTc Begins to create a ticket linked to a set of requests and a task | ||||||
|  | TTC Ends creating a ticket linked to a set of requests and a task | ||||||
|  | TTw Begins to wait a ticket completion | ||||||
|  | TTW Ends waiting a ticket completion | ||||||
| ``` | ``` | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								doc/user/emulation/fig/tampi-subsystem.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/user/emulation/fig/tampi-subsystem.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 12 KiB | 
							
								
								
									
										144
									
								
								doc/user/emulation/tampi.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								doc/user/emulation/tampi.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,144 @@ | |||||||
|  | # TAMPI model | ||||||
|  | 
 | ||||||
|  | The Task-Aware MPI (TAMPI) library extends the functionality of standard MPI | ||||||
|  | libraries by providing new mechanisms for improving the interoperability between | ||||||
|  | parallel task-based programming models, such as OpenMP and OmpSs-2, and MPI | ||||||
|  | communications. This library allows the safe and efficient execution of MPI | ||||||
|  | operations from concurrent tasks and guarantees the transparent management and | ||||||
|  | progress of these communications. | ||||||
|  | 
 | ||||||
|  | [tampi repo]: https://github.com/bsc-pm/tampi | ||||||
|  | [tampi docs]: https://github.com/bsc-pm/tampi#readme | ||||||
|  | [tampi blk]: https://github.com/bsc-pm/tampi#blocking-mode-ompss-2 | ||||||
|  | [tampi nonblk]: https://github.com/bsc-pm/tampi#non-blocking-mode-openmp--ompss-2 | ||||||
|  | 
 | ||||||
|  | The TAMPI library has instrumented the execution of its task-aware functions | ||||||
|  | with ovni. To obtain an instrumented library, TAMPI must be built passing the | ||||||
|  | `--with-ovni` configure option and specifying the ovni installation prefix. At | ||||||
|  | run-time, the user can enable the instrumentation by defining the environment | ||||||
|  | variable `TAMPI_INSTRUMENT=ovni`. | ||||||
|  | 
 | ||||||
|  | For more information regarding TAMPI or how to enable its instrumentation see | ||||||
|  | the TAMPI [repository][tampi repo] and [documentation][tampi docs]. | ||||||
|  | 
 | ||||||
|  | TAMPI is instrumented to track the execution path inside the run-time library | ||||||
|  | to identify what is happening at each moment. This information can be used by | ||||||
|  | both users and developers to analyze problems or to better understand the | ||||||
|  | execution behavior of TAMPI communications and its background services. There is | ||||||
|  | one view generated to achieve this goal. | ||||||
|  | 
 | ||||||
|  | ## Subsystem view | ||||||
|  | 
 | ||||||
|  | The subsystem view attempts to provide a general overview of what TAMPI is doing | ||||||
|  | at any point in time. The view shows the state inside the TAMPI library for each | ||||||
|  | thread (and for each CPU, the state of the running thread in that CPU). This | ||||||
|  | subsystem state view sticks to the definition of subsystem states from the | ||||||
|  | [Nanos6](nanos6.md#subsystem_view). | ||||||
|  | 
 | ||||||
|  | The states shown in this view are: | ||||||
|  | 
 | ||||||
|  | - **Library code subsystem**: Indicating whether the running thread is executing | ||||||
|  |   effective TAMPI library code. These subsystem states wrap the rest of | ||||||
|  |   subsystems that are described below. No other TAMPI state can appear outside | ||||||
|  |   of a TAMPI library code subsystem state. | ||||||
|  | 
 | ||||||
|  |     - **Interface function**: Running any TAMPI API function or an intercepted | ||||||
|  |       MPI function which requires task-awareness. When the user application | ||||||
|  |       disables a TAMPI mode, whether the [blocking][tampi blk] or | ||||||
|  |       [non-blocking][tampi nonblk] mode, any call to an interface function | ||||||
|  |       corresponding to the disabled mode will not appear in the view. Operations | ||||||
|  |       that are directly forwarded to MPI (because TAMPI is not asked to apply | ||||||
|  |       task-awareness) will not appear. | ||||||
|  | 
 | ||||||
|  |     - **Polling function**: The TAMPI library can launch internal tasks to | ||||||
|  |       execute polling functions in the background. Currently, TAMPI launches a | ||||||
|  |       polling task that periodically checks and processes the pending MPI | ||||||
|  |       requests generated by task-aware operations. This polling state may not | ||||||
|  |       appear if none of the TAMPI modes are enabled by the user application. | ||||||
|  | 
 | ||||||
|  | - **Communication subsystem**: The running thread is communicating through MPI | ||||||
|  |   or issuing an asynchronous communication operation. | ||||||
|  | 
 | ||||||
|  |   - **Issuing a non-blocking operation**: Issuing a non-blocking MPI operation | ||||||
|  |     that can generate an MPI request. | ||||||
|  | 
 | ||||||
|  | - **Ticket subsystem**: Creation and managing of tickets. A ticket is an | ||||||
|  |   internal object that describes the relation between a set of pending MPI | ||||||
|  |   requests and the user communication task that is *waiting* (synchronous or | ||||||
|  |   asynchronously) on them. A ticket is used for both [blocking][tampi blk] and | ||||||
|  |   [non-blocking][tampi nonblk] operations. | ||||||
|  | 
 | ||||||
|  |     - **Creating a ticket**: Creating a ticket that is linked to a set of MPI | ||||||
|  |       requests and a user task. The user task is the task that is *waiting* for | ||||||
|  |       these requests to complete. Notice that *waiting* does not mean that the | ||||||
|  |       task will synchronously wait for them. The ticket is initialized with a | ||||||
|  |       counter of how many requests are still pending. The ticket is completed, | ||||||
|  |       and thus, the task is notified, when this counter becomes zero. | ||||||
|  | 
 | ||||||
|  |     - **Waiting for the ticket completion**: The user task, during a blocking | ||||||
|  |       TAMPI operation, is waiting a ticket and its requests to complete. The | ||||||
|  |       task may be blocked and yield the CPU meanwhile. Notice that user tasks | ||||||
|  |       calling non-blocking TAMPI operations will not enter in this state. | ||||||
|  | 
 | ||||||
|  | - **Staging queue subsystem**: Queueing and dequeueing requests from the staging | ||||||
|  |   queues before being transferred to the global array of requests and tickets. | ||||||
|  |   These queues are used to optimize and control insertion of these objects into | ||||||
|  |   the global array. | ||||||
|  | 
 | ||||||
|  |     - **Adding to a queue**: A user communication task running a task-aware | ||||||
|  |       TAMPI operation is pushing the corresponding MPI requests and the related | ||||||
|  |       ticket into a staging queue. | ||||||
|  | 
 | ||||||
|  |     - **Transfering from queues to the global array**: The polling task is | ||||||
|  |       transferring the staged requests and tickets from the queues to the global | ||||||
|  |       array. | ||||||
|  | 
 | ||||||
|  | - **Global array subsystem**: Managing the per-process global array of tickets | ||||||
|  |   and MPI requests related to TAMPI operations. | ||||||
|  | 
 | ||||||
|  |     - **Checking pending requests**: Testing all pending MPI requests from the | ||||||
|  |       global array, processing the completed requests, and reorganizing the | ||||||
|  |       array to keep it compacted. | ||||||
|  | 
 | ||||||
|  | - **Request subsystem**: Management and testing of pending MPI requests, and | ||||||
|  |   processing the completed ones. This state considers only the management of MPI | ||||||
|  |   requests concerning task-aware operations, which are exclusively tested by the | ||||||
|  |   TAMPI library. Any testing function call made by the user application or other | ||||||
|  |   libraries is not considered. | ||||||
|  | 
 | ||||||
|  |     - **Testing a request with MPI_Test**: Testing a single MPI request by | ||||||
|  |       calling MPI_Test inside the TAMPI library. | ||||||
|  | 
 | ||||||
|  |     - **Testing requests with MPI_Testall**: Testing multiple MPI requests by | ||||||
|  |       calling MPI_Testall inside the TAMPI library. | ||||||
|  | 
 | ||||||
|  |     - **Testing requests with MPI_Testsome**: Testing multiple MPI requests by | ||||||
|  |       calling MPI_Testsome inside the TAMPI library. | ||||||
|  | 
 | ||||||
|  |     - **Processing a completed request**: Processing a completed MPI request by | ||||||
|  |       decreasing the number of pending requests of the linked ticket. If the | ||||||
|  |       ticket does not have any other request to wait, the ticket is completed | ||||||
|  |       and the *waiting* task is notified. In such a case, a call to the tasking | ||||||
|  |       runtime system will occur. If the operation was [blocking][tampi blk], the | ||||||
|  |       *waiting* task will be unblocked and will eventually resume the execution. | ||||||
|  |       If the operation was [non-blocking][tampi nonblk], the library will | ||||||
|  |       decrease the external events of the *waiting* task. | ||||||
|  | 
 | ||||||
|  | The figure below shows an example of the subsystem view. The program executes a | ||||||
|  | distributed stencil algorithm with MPI and OmpSs-2. There are several MPI | ||||||
|  | processes and each process has OmpSs-2 tasks running exlusively on multiple CPU | ||||||
|  | resources. | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | The view show there are several user tasks running task-aware communication | ||||||
|  | operations. The light blue areas show when a user task is testing a request that | ||||||
|  | was generated by a non-blocking MPI communication function. There is also one | ||||||
|  | polling task per process. The yellow areas show when the polling tasks are | ||||||
|  | calling MPI_Testsome. Just after the testsome call, the violet areas show the | ||||||
|  | moment when the polling task is processing the completed requests. | ||||||
|  | 
 | ||||||
|  | This view shows that most of the time inside the TAMPI library is spent testing | ||||||
|  | requests. This could give us a clue that the underlying MPI library may have | ||||||
|  | concurrency issues (e.g., thread contention) when multiple threads try to test | ||||||
|  | requests in parallel. | ||||||
| @ -32,6 +32,7 @@ nav: | |||||||
|       - user/emulation/ovni.md |       - user/emulation/ovni.md | ||||||
|       - user/emulation/nosv.md |       - user/emulation/nosv.md | ||||||
|       - user/emulation/nanos6.md |       - user/emulation/nanos6.md | ||||||
|  |       - user/emulation/tampi.md | ||||||
|       - user/emulation/events.md |       - user/emulation/events.md | ||||||
|   - 'Developer guide': |   - 'Developer guide': | ||||||
|     - dev/index.md |     - dev/index.md | ||||||
|  | |||||||
| @ -53,6 +53,8 @@ add_library(emu STATIC | |||||||
|   nosv/event.c |   nosv/event.c | ||||||
|   nodes/setup.c |   nodes/setup.c | ||||||
|   nodes/event.c |   nodes/event.c | ||||||
|  |   tampi/setup.c | ||||||
|  |   tampi/event.c | ||||||
|   kernel/setup.c |   kernel/setup.c | ||||||
|   kernel/event.c |   kernel/event.c | ||||||
| ) | ) | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ enum emu_prv_types { | |||||||
| 	PRV_NOSV_APPID       = 12, | 	PRV_NOSV_APPID       = 12, | ||||||
| 	PRV_NOSV_SUBSYSTEM   = 13, | 	PRV_NOSV_SUBSYSTEM   = 13, | ||||||
| 	PRV_NOSV_RANK        = 14, | 	PRV_NOSV_RANK        = 14, | ||||||
|  | 	PRV_TAMPI_SUBSYSTEM  = 20, | ||||||
| 	PRV_NODES_SUBSYSTEM  = 30, | 	PRV_NODES_SUBSYSTEM  = 30, | ||||||
| 	PRV_NANOS6_TASKID    = 35, | 	PRV_NANOS6_TASKID    = 35, | ||||||
| 	PRV_NANOS6_TYPE      = 36, | 	PRV_NANOS6_TYPE      = 36, | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ extern struct model_spec model_ovni; | |||||||
| extern struct model_spec model_nanos6; | extern struct model_spec model_nanos6; | ||||||
| extern struct model_spec model_nosv; | extern struct model_spec model_nosv; | ||||||
| extern struct model_spec model_nodes; | extern struct model_spec model_nodes; | ||||||
|  | extern struct model_spec model_tampi; | ||||||
| extern struct model_spec model_kernel; | extern struct model_spec model_kernel; | ||||||
| 
 | 
 | ||||||
| static struct model_spec *models[] = { | static struct model_spec *models[] = { | ||||||
| @ -18,6 +19,7 @@ static struct model_spec *models[] = { | |||||||
| 	&model_nanos6, | 	&model_nanos6, | ||||||
| 	&model_nosv, | 	&model_nosv, | ||||||
| 	&model_nodes, | 	&model_nodes, | ||||||
|  | 	&model_tampi, | ||||||
| 	&model_kernel, | 	&model_kernel, | ||||||
| 	NULL | 	NULL | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										111
									
								
								src/emu/tampi/event.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/emu/tampi/event.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | |||||||
|  | /* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
 | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
|  | 
 | ||||||
|  | #include "tampi_priv.h" | ||||||
|  | #include "chan.h" | ||||||
|  | #include "common.h" | ||||||
|  | #include "emu.h" | ||||||
|  | #include "emu_ev.h" | ||||||
|  | #include "extend.h" | ||||||
|  | #include "model_thread.h" | ||||||
|  | #include "thread.h" | ||||||
|  | #include "value.h" | ||||||
|  | 
 | ||||||
|  | enum { PUSH = 1, POP = 2, IGN = 3 }; | ||||||
|  | 
 | ||||||
|  | #define CHSS CH_SUBSYSTEM | ||||||
|  | 
 | ||||||
|  | static const int ss_table[256][256][3] = { | ||||||
|  | 	['C'] = { | ||||||
|  | 		['i'] = { CHSS, PUSH, ST_COMM_ISSUE_NONBLOCKING }, | ||||||
|  | 		['I'] = { CHSS, POP,  ST_COMM_ISSUE_NONBLOCKING }, | ||||||
|  | 	}, | ||||||
|  | 	['G'] = { | ||||||
|  | 		['c'] = { CHSS, PUSH, ST_GLOBAL_ARRAY_CHECK }, | ||||||
|  | 		['C'] = { CHSS, POP,  ST_GLOBAL_ARRAY_CHECK }, | ||||||
|  | 	}, | ||||||
|  | 	['L'] = { | ||||||
|  | 		['i'] = { CHSS, PUSH, ST_LIBRARY_INTERFACE }, | ||||||
|  | 		['I'] = { CHSS, POP,  ST_LIBRARY_INTERFACE }, | ||||||
|  | 		['p'] = { CHSS, PUSH, ST_LIBRARY_POLLING }, | ||||||
|  | 		['P'] = { CHSS, POP,  ST_LIBRARY_POLLING }, | ||||||
|  | 	}, | ||||||
|  | 	['Q'] = { | ||||||
|  | 		['a'] = { CHSS, PUSH, ST_QUEUE_ADD }, | ||||||
|  | 		['A'] = { CHSS, POP,  ST_QUEUE_ADD }, | ||||||
|  | 		['t'] = { CHSS, PUSH, ST_QUEUE_TRANSFER }, | ||||||
|  | 		['T'] = { CHSS, POP,  ST_QUEUE_TRANSFER }, | ||||||
|  | 	}, | ||||||
|  | 	['R'] = { | ||||||
|  | 		['c'] = { CHSS, PUSH, ST_REQUEST_COMPLETED }, | ||||||
|  | 		['C'] = { CHSS, POP,  ST_REQUEST_COMPLETED }, | ||||||
|  | 		['t'] = { CHSS, PUSH, ST_REQUEST_TEST }, | ||||||
|  | 		['T'] = { CHSS, POP,  ST_REQUEST_TEST }, | ||||||
|  | 		['a'] = { CHSS, PUSH, ST_REQUEST_TESTALL }, | ||||||
|  | 		['A'] = { CHSS, POP,  ST_REQUEST_TESTALL }, | ||||||
|  | 		['s'] = { CHSS, PUSH, ST_REQUEST_TESTSOME }, | ||||||
|  | 		['S'] = { CHSS, POP,  ST_REQUEST_TESTSOME }, | ||||||
|  | 	}, | ||||||
|  | 	['T'] = { | ||||||
|  | 		['c'] = { CHSS, PUSH, ST_TICKET_CREATE }, | ||||||
|  | 		['C'] = { CHSS, POP,  ST_TICKET_CREATE }, | ||||||
|  | 		['w'] = { CHSS, PUSH, ST_TICKET_WAIT }, | ||||||
|  | 		['W'] = { CHSS, POP,  ST_TICKET_WAIT }, | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | process_ev(struct emu *emu) | ||||||
|  | { | ||||||
|  | 	if (!emu->thread->is_running) { | ||||||
|  | 		err("current thread %d not running", emu->thread->tid); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	const int *entry = ss_table[emu->ev->c][emu->ev->v]; | ||||||
|  | 	int chind = entry[0]; | ||||||
|  | 	int action = entry[1]; | ||||||
|  | 	int st = entry[2]; | ||||||
|  | 
 | ||||||
|  | 	struct tampi_thread *th = EXT(emu->thread, 'T'); | ||||||
|  | 	struct chan *ch = &th->m.ch[chind]; | ||||||
|  | 
 | ||||||
|  | 	if (action == PUSH) { | ||||||
|  | 		return chan_push(ch, value_int64(st)); | ||||||
|  | 	} else if (action == POP) { | ||||||
|  | 		return chan_pop(ch, value_int64(st)); | ||||||
|  | 	} else if (action == IGN) { | ||||||
|  | 		return 0; /* do nothing */ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err("unknown TAMPI subsystem event"); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | model_tampi_event(struct emu *emu) | ||||||
|  | { | ||||||
|  | 	static int enabled = 0; | ||||||
|  | 
 | ||||||
|  | 	if (!enabled) { | ||||||
|  | 		if (model_tampi_connect(emu) != 0) { | ||||||
|  | 			err("tampi_connect failed"); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		enabled = 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dbg("in tampi_event"); | ||||||
|  | 	if (emu->ev->m != 'T') { | ||||||
|  | 		err("unexpected event model %c", emu->ev->m); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dbg("got tampi event %s", emu->ev->mcv); | ||||||
|  | 	if (process_ev(emu) != 0) { | ||||||
|  | 		err("error processing TAMPI event"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
							
								
								
									
										215
									
								
								src/emu/tampi/setup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								src/emu/tampi/setup.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,215 @@ | |||||||
|  | /* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
 | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
|  | 
 | ||||||
|  | #include "tampi_priv.h" | ||||||
|  | #include <stddef.h> | ||||||
|  | #include "chan.h" | ||||||
|  | #include "common.h" | ||||||
|  | #include "emu.h" | ||||||
|  | #include "emu_args.h" | ||||||
|  | #include "emu_prv.h" | ||||||
|  | #include "extend.h" | ||||||
|  | #include "model.h" | ||||||
|  | #include "model_chan.h" | ||||||
|  | #include "model_cpu.h" | ||||||
|  | #include "model_pvt.h" | ||||||
|  | #include "model_thread.h" | ||||||
|  | #include "pv/pcf.h" | ||||||
|  | #include "pv/prv.h" | ||||||
|  | #include "system.h" | ||||||
|  | #include "thread.h" | ||||||
|  | #include "track.h" | ||||||
|  | #include "value.h" | ||||||
|  | 
 | ||||||
|  | static const char model_name[] = "tampi"; | ||||||
|  | enum { model_id = 'T' }; | ||||||
|  | 
 | ||||||
|  | struct model_spec model_tampi = { | ||||||
|  | 	.name = model_name, | ||||||
|  | 	.model = model_id, | ||||||
|  | 	.create  = model_tampi_create, | ||||||
|  | //	.connect = model_tampi_connect,
 | ||||||
|  | 	.event   = model_tampi_event, | ||||||
|  | 	.probe   = model_tampi_probe, | ||||||
|  | 	.finish  = model_tampi_finish, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ----------------- channels ------------------ */ | ||||||
|  | 
 | ||||||
|  | static const char *chan_name[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM] = "subsystem", | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const int chan_stack[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM] = 1, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ----------------- pvt ------------------ */ | ||||||
|  | 
 | ||||||
|  | static const int pvt_type[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM] = PRV_TAMPI_SUBSYSTEM, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const char *pcf_prefix[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM]   = "TAMPI subsystem", | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct pcf_value_label tampi_ss_values[] = { | ||||||
|  | 	{ ST_COMM_ISSUE_NONBLOCKING, "Communication: Issuing a non-blocking operation" }, | ||||||
|  | 	{ ST_GLOBAL_ARRAY_CHECK,     "Global array: Checking pending requests" }, | ||||||
|  | 	{ ST_LIBRARY_INTERFACE,      "Library code: Interface function" }, | ||||||
|  | 	{ ST_LIBRARY_POLLING,        "Library code: Polling function" }, | ||||||
|  | 	{ ST_QUEUE_ADD,              "Queue: Adding to a queue" }, | ||||||
|  | 	{ ST_QUEUE_TRANSFER,         "Queue: Transfering to global array" }, | ||||||
|  | 	{ ST_REQUEST_TEST,           "Request: Testing a request" }, | ||||||
|  | 	{ ST_REQUEST_COMPLETED,      "Request: Processing a completed request" }, | ||||||
|  | 	{ ST_REQUEST_TESTALL,        "Request: Testing all requests" }, | ||||||
|  | 	{ ST_REQUEST_TESTSOME,       "Request: Testing some requests" }, | ||||||
|  | 	{ ST_TICKET_CREATE,          "Ticket: Creating a ticket" }, | ||||||
|  | 	{ ST_TICKET_WAIT,            "Ticket: Waiting a ticket" }, | ||||||
|  | 	{ -1, NULL }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct pcf_value_label *pcf_labels[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM] = tampi_ss_values, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const long prv_flags[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM] = PRV_SKIPDUP, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct model_pvt_spec pvt_spec = { | ||||||
|  | 	.type = pvt_type, | ||||||
|  | 	.prefix = pcf_prefix, | ||||||
|  | 	.label = pcf_labels, | ||||||
|  | 	.flags = prv_flags, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ----------------- tracking ------------------ */ | ||||||
|  | 
 | ||||||
|  | static const int th_track[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM] = TRACK_TH_ACT, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const int cpu_track[CH_MAX] = { | ||||||
|  | 	[CH_SUBSYSTEM] = TRACK_TH_RUN, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ----------------- chan_spec ------------------ */ | ||||||
|  | 
 | ||||||
|  | static const struct model_chan_spec th_chan = { | ||||||
|  | 	.nch = CH_MAX, | ||||||
|  | 	.prefix = model_name, | ||||||
|  | 	.ch_names = chan_name, | ||||||
|  | 	.ch_stack = chan_stack, | ||||||
|  | 	.pvt = &pvt_spec, | ||||||
|  | 	.track = th_track, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct model_chan_spec cpu_chan = { | ||||||
|  | 	.nch = CH_MAX, | ||||||
|  | 	.prefix = model_name, | ||||||
|  | 	.ch_names = chan_name, | ||||||
|  | 	.ch_stack = chan_stack, | ||||||
|  | 	.pvt = &pvt_spec, | ||||||
|  | 	.track = cpu_track, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ----------------- models ------------------ */ | ||||||
|  | 
 | ||||||
|  | static const struct model_cpu_spec cpu_spec = { | ||||||
|  | 	.size = sizeof(struct tampi_cpu), | ||||||
|  | 	.chan = &cpu_chan, | ||||||
|  | 	.model = &model_tampi, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct model_thread_spec th_spec = { | ||||||
|  | 	.size = sizeof(struct tampi_thread), | ||||||
|  | 	.chan = &th_chan, | ||||||
|  | 	.model = &model_tampi, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ----------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | model_tampi_probe(struct emu *emu) | ||||||
|  | { | ||||||
|  | 	if (emu->system.nthreads == 0) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | model_tampi_create(struct emu *emu) | ||||||
|  | { | ||||||
|  | 	if (model_thread_create(emu, &th_spec) != 0) { | ||||||
|  | 		err("model_thread_init failed"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (model_cpu_create(emu, &cpu_spec) != 0) { | ||||||
|  | 		err("model_cpu_init failed"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | model_tampi_connect(struct emu *emu) | ||||||
|  | { | ||||||
|  | 	if (model_thread_connect(emu, &th_spec) != 0) { | ||||||
|  | 		err("model_thread_connect failed"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (model_cpu_connect(emu, &cpu_spec) != 0) { | ||||||
|  | 		err("model_cpu_connect failed"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | end_lint(struct emu *emu) | ||||||
|  | { | ||||||
|  | 	/* Only run the check if we finished the complete trace */ | ||||||
|  | 	if (!emu->finished) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	struct system *sys = &emu->system; | ||||||
|  | 
 | ||||||
|  | 	/* Ensure we run out of subsystem states */ | ||||||
|  | 	for (struct thread *t = sys->threads; t; t = t->gnext) { | ||||||
|  | 		struct tampi_thread *th = EXT(t, model_id); | ||||||
|  | 		struct chan *ch = &th->m.ch[CH_SUBSYSTEM]; | ||||||
|  | 		int stacked = ch->data.stack.n; | ||||||
|  | 		if (stacked > 0) { | ||||||
|  | 			struct value top; | ||||||
|  | 			if (chan_read(ch, &top) != 0) { | ||||||
|  | 				err("chan_read failed for subsystem"); | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			err("thread %d ended with %d stacked tampi subsystems", | ||||||
|  | 					t->tid, stacked); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | model_tampi_finish(struct emu *emu) | ||||||
|  | { | ||||||
|  | 	/* When running in linter mode perform additional checks */ | ||||||
|  | 	if (emu->args.linter_mode && end_lint(emu) != 0) { | ||||||
|  | 		err("end_lint failed"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								src/emu/tampi/tampi_priv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/emu/tampi/tampi_priv.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | /* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
 | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
|  | 
 | ||||||
|  | #ifndef TAMPI_PRIV_H | ||||||
|  | #define TAMPI_PRIV_H | ||||||
|  | 
 | ||||||
|  | #include "emu.h" | ||||||
|  | #include "model_cpu.h" | ||||||
|  | #include "model_thread.h" | ||||||
|  | 
 | ||||||
|  | /* Private enums */ | ||||||
|  | 
 | ||||||
|  | enum tampi_chan { | ||||||
|  | 	CH_SUBSYSTEM = 0, | ||||||
|  | 	CH_MAX, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum tampi_ss_values { | ||||||
|  | 	ST_COMM_ISSUE_NONBLOCKING = 1, | ||||||
|  | 	ST_GLOBAL_ARRAY_CHECK, | ||||||
|  | 	ST_LIBRARY_INTERFACE, | ||||||
|  | 	ST_LIBRARY_POLLING, | ||||||
|  | 	ST_QUEUE_ADD, | ||||||
|  | 	ST_QUEUE_TRANSFER, | ||||||
|  | 	ST_REQUEST_COMPLETED, | ||||||
|  | 	ST_REQUEST_TEST, | ||||||
|  | 	ST_REQUEST_TESTALL, | ||||||
|  | 	ST_REQUEST_TESTSOME, | ||||||
|  | 	ST_TICKET_CREATE, | ||||||
|  | 	ST_TICKET_WAIT, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct tampi_thread { | ||||||
|  | 	struct model_thread m; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct tampi_cpu { | ||||||
|  | 	struct model_cpu m; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | int model_tampi_probe(struct emu *emu); | ||||||
|  | int model_tampi_create(struct emu *emu); | ||||||
|  | int model_tampi_connect(struct emu *emu); | ||||||
|  | int model_tampi_event(struct emu *emu); | ||||||
|  | int model_tampi_finish(struct emu *emu); | ||||||
|  | 
 | ||||||
|  | #endif /* TAMPI_PRIV_H */ | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Kevin Sala
						Kevin Sala