Skip to content

Initialization

Felix Uhl edited this page Dec 1, 2022 · 7 revisions

The first time the function entry hook __cyg_profile_func_enter is called vftrace is initialized by calling vftr_initialize.

Read Configuration

The first action is obtaining the runtime controlling parameters (see Runtime Control) in vftr_read_config. Before any outside information is obtained the default values are created by vftr_set_config_default. This way the config parser can overwrite only supplied values and does not need to fill in missing parameters. Parsing of the config file is done with the external cJSON library. The vftr_parse_config function extracts the options from the JSON tree and overwrites the default values where necessary. Next the whole JSON tree is scanned by vftr_config_advisor and each element is compared to a preset list of valid options. This is done by computing the levenshtein distance (a form of lexicographical similarity metric) from the JSON entry and all list entries. If no list entry matches the JSON entry the list entry with the smallest levenshtein distance is suggested to the user as a replacement. The element with the smallest distance. If the config was parsed without issues and vftrace is active the configuration values are checked for validity and consistency. vftr_config_assert expands every range list, compiles every regex, checks given paths for existence and permissions, and column_sort strings for validity. If new options are introduced they must be implementend thoroughly in the following locations:

  • src/configuration_types.h: The option must be part of the config_t type.
  • src/configuration_defaults.c: A function returning the default value of the option must exist and used to assign the default value to the option in config_t.
  • src/configuration_parse.c: The option must be parsed and if given the default value must be overwritten.
  • src/configuration_advisor.c: The option must be included in the advisor, either by adding it to the appropriate string list, or by adding a new section advisor function.
  • src/configuration_assert.c: A function asserting the value of the option must be implemented and executed.
  • src/configuration_print.c: The option must be added to the printing routines in order to appear in the config_tools and the used-config section in the logfiles.
  • src/vftrace_state.c: The option must be included in the size estimation of the vftrace state.
  • test/config/: The option must be (if suitable) checked by a unit test.
  • test/config/ref_output/defaults.out: The option an it's default value must be added to the reference output of the default-config test.
  • Runtime-Control#Config File: The option must be documented and explained in the wiki.
  • share_src/man/man1/vftrace.1: The option must be documented and explained in the man-page.

Read Symboltable

The symbol table matches addresses with function names in order to build human readable stack trees. The symbols are extracted from the ELF header of the profiled application. This is a very delicate process and should not be tempered with, without a good reason.

Sampling Files

If sampling was activated (see Runtime Control#Config File) the vftr_new_sampling function will create a file with filename <basename>_<pid>.tmpvfd. The final will be renamed <basename>_<rank>.vfd in the finalization step, because a possible rank is no known until MPI_Init, or MPI_Init_thread was called. This would eliminate sampling of functions executed before MPI-initialization. The function vftr_write_incomplete_vfd_header writes the first section of the vfd-files. It contains mostly zeroes and its purpose it mainly to reserve space for when the header information is actually known.

Symbol Linking Tricks

Some features, which rely on callback functionalities (e.g. OMP) are never called within Vftrace, but handled by runtime libraries. Therefore the linker deems those functions not important and ignores them during linking the binary. In order to include the function into the binary they are called once during the initialization with dummy arguments that do nothing.

      // trick the linker into including extra symbols
#ifdef _OMP
      // omp callback symbols
      (void) ompt_start_tool(0, NULL);
#endif

Preparing Finalization

Vftrace needs to update its data structures, write logfiles, finish and rename vfdfiles, at the end of the profiled program (see Finalization). In order to execute vftr_finalize right before the program terminates, the function is registered by the atexit system routine

atexit(vftr_finalize);

Executing Entry Hook

The last action in the initialization is to run the appropriate input hook (see Function Hooks#Function Hooks in Vftrace).

MPI_Init/MPI_Init_thread

MPI_Init or MPI_Init_thread are the last instances where initialization is happening. Before one of these two functions is run, the processes rank and the number of ranks is unknown. These functions determine both quantities and fill in the last spots of missing information.

      PMPI_Comm_size(MPI_COMM_WORLD, &vftrace.process.nprocesses);
      PMPI_Comm_rank(MPI_COMM_WORLD, &vftrace.process.processID);