diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2fdd3a8..c8fb24f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: DFTracer Build and Test on: pull_request: - branches: [ main, dev ] + branches: [ main, develop ] push: jobs: build-and-test: @@ -79,9 +79,9 @@ jobs: mkdir coverage FILE=$PWD/coverage/coverage.json cd build - COVERALLS_REPO_TOKEN=${{ secrets.GITHUB_TOKEN }} gcovr -r ../ . --coveralls $FILE -e ../test/ -e ../src/example + COVERALLS_REPO_TOKEN=${{ secrets.COVERALLS }} gcovr -r ../ . --coveralls $FILE -e ../test/ -e ../src/example if [ -e '$FILE' ]; then sed -i'' -e 's/"service_name": "github-actions-ci"/"service_name": "github"/' '$FILE' fi cat $FILE - curl -v -F json_file=@$FILE https://coveralls.io/api/v1/jobs \ No newline at end of file + curl -v -F json_file=@$FILE https://coveralls.io/api/v1/jobs diff --git a/.gitignore b/.gitignore index 76b27b5f..97c8184b 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ # Environment and Dependency venv* +.venv* dependency/.spack-env dependency/spack.lock /build_env/ @@ -70,9 +71,11 @@ logs/*.log install __pycache__ dftracer/__pycache__ +*.log +examples/dfanalyzer/test-trace.pfw.gz.zindex # Install files -dftracer_py.egg-info +pydftracer.egg-info /dist/ /output/ @@ -83,3 +86,7 @@ dftracer_py.egg-info # Debug files /*.core +dfanalyzer/dask/run_dir +dfanalyzer/dask/logs +dfanalyzer/dask/scripts/STDIN.* +*.zindex \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 436b1b59..a1b87217 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,87 @@ "cmake.configureEnvironment": { "DARSHAN_PRELOAD_LIB": "/usr/WS2/haridev/spack/opt/spack/linux-rhel8-zen2/gcc-10.3.1/darshan-runtime-3.4.4-vckxthkq2hzzxnwmk4owtzcnfmjwl23s/lib/libdarshan.so", "DFTRACER_TEST_MACHINE": "corona" + }, + "files.associations": { + "any": "cpp", + "functional": "cpp", + "optional": "cpp", + "sstream": "cpp", + "array": "cpp", + "atomic": "cpp", + "hash_map": "cpp", + "hash_set": "cpp", + "strstream": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 0900d1ab..658e2bd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,8 @@ set(DFTRACER_PACKAGE_VERSION_MINOR "${DFTRACER_VERSION_PATCH}") set(DFTRACER_PACKAGE_STRING "${DFTRACER_PACKAGE_NAME} ${DFTRACER_PACKAGE_VERSION}") set(DFTRACER_PACKAGE_TARNAME "${DFTRACER_PACKAGE}") +set(DFTRACER_VERSION "(1, 0, 3)") + project(dftracer LANGUAGES C CXX) @@ -40,11 +42,14 @@ if (CMAKE_INSTALL_LIBDIR) ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}) set(DFTRACER_INSTALL_SYSCONFDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_SYSCONFDIR}/modulefiles) + set(DFTRACER_INSTALL_BINFDIR + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) else () set(DFTRACER_LIBDIR "lib") set(DFTRACER_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include") set(DFTRACER_INSTALL_DOCDIR "${CMAKE_INSTALL_PREFIX}/doc") set(DFTRACER_INSTALL_SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc/modulefiles") + set(DFTRACER_INSTALL_BINARYDIR "${CMAKE_INSTALL_PREFIX}/bin") message(STATUS "DFTRACER_LIBDIR set to ${DFTRACER_LIBDIR}") endif () @@ -130,6 +135,7 @@ option (DFTRACER_INSTALL_DEPENDENCIES "Install DFTracer dependencies" OFF) option (DFTRACER_ENABLE_TESTS "Enable tests for DFTRACER." OFF) option (DFTRACER_ENABLE_DLIO_BENCHMARK_TESTS "Enable dlio_benchmark tests" OFF) option (DFTRACER_ENABLE_PAPER_TESTS "Enable paper tests" OFF) +set (DFTRACER_TEST_LD_LIBRARY_PATH "" CACHE STRING "Additional LD_LIBRARY_PATH to be included on testing") #------------------------------------------------------------------------------ # Compiler setup @@ -325,6 +331,22 @@ if (DFTRACER_BUILD_PYTHON_BINDINGS) . ${CMAKE_BINARY_DIR}/symlink.sh \")") endif() +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/script/dftracer_compact.sh ${EXECUTABLE_OUTPUT_PATH}/dftracer_compact COPYONLY) +install( + FILES + ${EXECUTABLE_OUTPUT_PATH}/dftracer_compact + DESTINATION + bin +) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/script/merge_pfw.sh ${EXECUTABLE_OUTPUT_PATH}/merge_pfw COPYONLY) +install( + FILES + ${EXECUTABLE_OUTPUT_PATH}/merge_pfw + DESTINATION + bin +) + #cmake_policy(SET CMP0079 NEW) # In case that we need more control over the target building order if(DFTRACER_ENABLE_TESTS) @@ -346,21 +368,28 @@ endif() #----------------------------------------------------------------------------- # Configure the config.cmake file for the build directory #----------------------------------------------------------------------------- -configure_file( +include(CMakePackageConfigHelpers) +configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/configure_files/${PROJECT_NAME}-config.cmake.build.in - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake @ONLY + "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.cmake" + INSTALL_DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake + PATH_VARS CMAKE_BINARY_DIR ) -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/configure_files/${PROJECT_NAME}-config.cmake.install.in - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cmake/${PROJECT_NAME}/install/${PROJECT_NAME}-config.cmake @ONLY +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/configure_files/${PROJECT_NAME}-config.cmake.install.in + "${CMAKE_BINARY_DIR}/install/${PROJECT_NAME}-config.cmake" + INSTALL_DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cmake/${PROJECT_NAME}/install/${PROJECT_NAME}-config.cmake + PATH_VARS CMAKE_BINARY_DIR ) install( FILES - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cmake/${PROJECT_NAME}/install/${PROJECT_NAME}-config.cmake + ${CMAKE_BINARY_DIR}/install/${PROJECT_NAME}-config.cmake DESTINATION ${DFTRACER_LIBDIR}/cmake/${PROJECT_NAME} ) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/dftracer-utils.cmake" + DESTINATION "${DFTRACER_LIBDIR}/cmake/dftracer") #----------------------------------------------------------------------------- # Configure the ${PROJECT_NAME}-config-version .cmake file for the install directory #----------------------------------------------------------------------------- diff --git a/README.md b/README.md index def0a23b..db0d6104 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,13 @@ [![Coverage Status](https://coveralls.io/repos/github/hariharan-devarajan/dftracer/badge.svg?branch=feature/apis)](https://coveralls.io/github/hariharan-devarajan/dftracer?branch=dev) [![Documentation Status](https://readthedocs.org/projects/dftracer/badge/?version=latest)](https://dftracer.readthedocs.io/en/latest/?badge=latest) -# DFTracer v1.0.2 +# DFTracer v1.0.3 A multi-level profiler for capturing application functions and low-level system I/O calls from deep learning workloads. Requirements for profiler 1. Python > 3.7 2. pybind11 - Requirements for analyzer 1. bokeh>=2.4.2 2. pybind11 @@ -23,20 +22,15 @@ Requirements for analyzer 10. python-intervals>=1.10.0.post1 11. matplotlib>=3.7.3 -## Build DFTracer with pip +## Installation -Users can easily install DFTracer using pip. This is the way most python packages are installed. -This method would work for both native python environments and conda environments. +Users can easily install DFTracer using pip. This is the way most Python packages are installed. +This method would work for both native Python environments and Conda environments. -### From source +### From PyPI ```bash - git clone git@github.com:hariharan-devarajan/dftracer.git - cd dftracer - # You can skip this for installing the dev branch. - # for latest stable version use master branch. - git checkout tags/ -b - pip install . +pip install pydftracer ``` ### From Github @@ -46,70 +40,77 @@ DFT_VERSION=dev pip install git+https://github.com/hariharan-devarajan/dftracer.git@${DFT_VERSION} ``` -For more build instructions check [here](https://dftracer.readthedocs.io/en/latest/build.html) - -Usage +### From source +```bash +git clone git@github.com:hariharan-devarajan/dftracer.git +cd dftracer +# You can skip this for installing the dev branch. +# for latest stable version use master branch. +git checkout tags/ -b +pip install . ``` - from dftracer.logger import dftracer, dft_fn - log_inst = dftracer.initialize_log(logfile=None, data_dir=None, process_id=-1) - dft_fn = dft_fn("COMPUTE") - - # Example of using function decorators - @dft_fn.log - def log_events(index): - sleep(1) - - # Example of function spawning and implicit I/O calls - def posix_calls(val): - index, is_spawn = val - path = f"{cwd}/data/demofile{index}.txt" - f = open(path, "w+") - f.write("Now the file has more content!") - f.close() - if is_spawn: - print(f"Calling spawn on {index} with pid {os.getpid()}") - log_inst.finalize() # This need to be called to correctly finalize DFTracer. - else: - print(f"Not calling spawn on {index} with pid {os.getpid()}") - - # NPZ calls internally calls POSIX calls. - def npz_calls(index): - # print(f"{cwd}/data/demofile2.npz") - path = f"{cwd}/data/demofile{index}.npz" - if os.path.exists(path): - os.remove(path) - records = np.random.randint(255, size=(8, 8, 1024), dtype=np.uint8) - record_labels = [0] * 1024 - np.savez(path, x=records, y=record_labels) - - def main(): - log_events(0) - npz_calls(1) - with get_context('spawn').Pool(1, initializer=init) as pool: - pool.map(posix_calls, ((2, True),)) - log_inst.finalize() - - - if __name__ == "__main__": - main() +For more build instructions check [here](https://dftracer.readthedocs.io/en/latest/build.html). + +## Usage + +```python +from dftracer.logger import dftracer, dft_fn +log_inst = dftracer.initialize_log(logfile=None, data_dir=None, process_id=-1) +dft_fn = dft_fn("COMPUTE") + +# Example of using function decorators +@dft_fn.log +def log_events(index): + sleep(1) + +# Example of function spawning and implicit I/O calls +def posix_calls(val): + index, is_spawn = val + path = f"{cwd}/data/demofile{index}.txt" + f = open(path, "w+") + f.write("Now the file has more content!") + f.close() + if is_spawn: + print(f"Calling spawn on {index} with pid {os.getpid()}") + log_inst.finalize() # This need to be called to correctly finalize DFTracer. + else: + print(f"Not calling spawn on {index} with pid {os.getpid()}") + +# NPZ calls internally calls POSIX calls. +def npz_calls(index): + # print(f"{cwd}/data/demofile2.npz") + path = f"{cwd}/data/demofile{index}.npz" + if os.path.exists(path): + os.remove(path) + records = np.random.randint(255, size=(8, 8, 1024), dtype=np.uint8) + record_labels = [0] * 1024 + np.savez(path, x=records, y=record_labels) + +def main(): + log_events(0) + npz_calls(1) + with get_context('spawn').Pool(1, initializer=init) as pool: + pool.map(posix_calls, ((2, True),)) + log_inst.finalize() + +if __name__ == "__main__": + main() ``` -For this example, as the DFTRACER_CPP_INIT do not pass log file or data dir, we need to set ``DFTRACER_LOG_FILE`` and ``DFTRACER_DATA_DIR``. -By default the DFTracer mode is set to FUNCTION. +For this example, as the `dftracer.initialize_log` do not pass `logfile` or `data_dir`, we need to set `DFTRACER_LOG_FILE` and `DFTRACER_DATA_DIR`. +By default the DFTracer mode is set to `FUNCTION`. Example of running this configurations are: -``` - - # the process id, app_name and .pfw will be appended by the profiler for each app and process. - # name of final log file is ~/log_file--.pfw - DFTRACER_LOG_FILE=~/log_file - # Colon separated paths for including for profiler - DFTRACER_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset:$PWD/data - # Enable profiler - DFTRACER_ENABLE=1 +```bash +# The process id, app_name and .pfw will be appended by the profiler for each app and process. +# The name of the final log file is ~/log_file--.pfw +DFTRACER_LOG_FILE=~/log_file +# Colon separated paths for including for profiler +DFTRACER_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset:$PWD/data +# Enable profiler +DFTRACER_ENABLE=1 ``` For more example check [Examples](https://dftracer.readthedocs.io/en/latest/examples.html). - diff --git a/cmake/configure_files/dftracer-config.cmake.build.in b/cmake/configure_files/dftracer-config.cmake.build.in index 043fbc95..d6911931 100644 --- a/cmake/configure_files/dftracer-config.cmake.build.in +++ b/cmake/configure_files/dftracer-config.cmake.build.in @@ -1,8 +1,7 @@ -# This will create IMPORTED targets for DFTRACER. The executables will be -# dftracer::-bin (e.g., dftracer::dftracer-bin) and the library will -# be dftracer::dftracer. +# This will create IMPORTED targets for dftracer. The executables will be +# the library will be dftracer::dftracer. -include("${CMAKE_CURRENT_LIST_DIR}/DFTRACERConfigVersion.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/dftracer-config-version.cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules") @@ -10,7 +9,7 @@ list(APPEND CMAKE_MODULE_PATH "@EXTRA_CMAKE_MODULE_DIR@") #include(GNUInstallDirs) include(ExternalProject) -include(DFTRACERCMakeUtilities) +include(dftracer-utils) include(CMakePackageConfigHelpers) @@ -52,10 +51,30 @@ foreach (_DIR ${_TMP_LIBRARY_DIRS}) list(APPEND DFTRACER_LIBRARY_DIRS "${_LIBRARY_DIR}") endforeach (_DIR ${_TMP_LIBRARY_DIRS}) -if (NOT TARGET dftracer::dftracer) - include(${CMAKE_CURRENT_LIST_DIR}/DFTRACERTargets.cmake) -endif (NOT TARGET dftracer::dftracer) - -check_required_components(DFTRACER) - -set(DFTRACER_LIBRARIES dftracer::dftracer) \ No newline at end of file +if (NOT TARGET dftracer) + include(${CMAKE_CURRENT_LIST_DIR}/dftracer-targets.cmake) +endif (NOT TARGET dftracer) + + +find_package(brahma REQUIRED) +if (${brahma_FOUND}) + message(STATUS "[DFTRACER] found brahma at ${BRAHMA_INCLUDE_DIRS}") + include_directories(${BRAHMA_INCLUDE_DIRS}) + target_link_libraries(dftracer INTERFACE ${BRAHMA_LIBRARIES}) +else () + message(FATAL_ERROR "-- [DFTRACER] brahma is needed for ${PROJECT_NAME} build") +endif () + +find_package(yaml-cpp REQUIRED) +if (${yaml-cpp_FOUND}) + message(STATUS "[DFTRACER] found yaml-cpp at ${YAML_CPP_INCLUDE_DIR}") + include_directories(${YAML_CPP_INCLUDE_DIR}) + set(YAML_CPP_LIBRARY_DIR "${YAML_CPP_CMAKE_DIR}/../../") + target_link_libraries(dftracer INTERFACE -L${YAML_CPP_LIBRARY_DIR} ${YAML_CPP_LIBRARIES}) +else () + message(FATAL_ERROR "-- [DFTRACER] yaml-cpp is needed for ${PROJECT_NAME} build") +endif () + +check_required_components(dftracer) + +set(DFTRACER_LIBRARIES dftracer) \ No newline at end of file diff --git a/cmake/configure_files/dftracer-config.cmake.install.in b/cmake/configure_files/dftracer-config.cmake.install.in index 8fb0a4dd..e5acd910 100644 --- a/cmake/configure_files/dftracer-config.cmake.install.in +++ b/cmake/configure_files/dftracer-config.cmake.install.in @@ -1,8 +1,7 @@ -# This will create IMPORTED targets for DFTRACER. The executables will be -# DFTRACER::-bin (e.g., DFTRACER::dftracer-bin) and the library will -# be DFTRACER::dftracer. +# This will create IMPORTED targets for dftracer. The executables will be +# the library will be dftracer. -include("${CMAKE_CURRENT_LIST_DIR}/DFTRACERConfigVersion.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/dftracer-config-version.cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules") @@ -10,7 +9,7 @@ list(APPEND CMAKE_MODULE_PATH "@EXTRA_CMAKE_MODULE_DIR@") #include(GNUInstallDirs) include(ExternalProject) -include(DFTRACERCMakeUtilities) +include(dftracer-utils) include(CMakePackageConfigHelpers) @@ -40,22 +39,41 @@ set(DFTRACER_HAS_STD_FSTREAM_FD @DFTRACER_HAS_STD_FSTREAM_FD@) @PACKAGE_INIT@ # Now actually import the DFTRACER target -set(_TMP_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIRS@") +set(_TMP_INCLUDE_DIRS "@DFTRACER_INSTALL_INCLUDE_DIR@") foreach (_DIR ${_TMP_INCLUDE_DIRS}) set_and_check(_INCLUDE_DIR "${_DIR}") list(APPEND DFTRACER_INCLUDE_DIRS "${_INCLUDE_DIR}") endforeach (_DIR "${_TMP_INCLUDE_DIRS}") -set(_TMP_LIBRARY_DIRS "@PACKAGE_LIB_INSTALL_DIR@") +set(_TMP_LIBRARY_DIRS "@DFTRACER_INSTALL_LIB_DIR@") foreach (_DIR ${_TMP_LIBRARY_DIRS}) set_and_check(_LIBRARY_DIR "${_DIR}") list(APPEND DFTRACER_LIBRARY_DIRS "${_LIBRARY_DIR}") endforeach (_DIR ${_TMP_LIBRARY_DIRS}) -if (NOT TARGET DFTRACER::dftracer) - include(${CMAKE_CURRENT_LIST_DIR}/DFTRACERTargets.cmake) -endif (NOT TARGET DFTRACER::dftracer) - -check_required_components(DFTRACER) - -set(DFTRACER_LIBRARIES DFTRACER::dftracer) \ No newline at end of file +if (NOT TARGET dftracer) + include(${CMAKE_CURRENT_LIST_DIR}/dftracer-targets.cmake) +endif (NOT TARGET dftracer) + +find_package(brahma REQUIRED) +if (${brahma_FOUND}) + message(STATUS "[DFTRACER] found brahma at ${BRAHMA_INCLUDE_DIRS}") + include_directories(${BRAHMA_INCLUDE_DIRS}) + target_link_libraries(dftracer INTERFACE ${BRAHMA_LIBRARIES}) +else () + message(FATAL_ERROR "-- [DFTRACER] brahma is needed for ${PROJECT_NAME} build") +endif () + +find_package(yaml-cpp REQUIRED) +if (${yaml-cpp_FOUND}) + message(STATUS "[DFTRACER] found yaml-cpp at ${YAML_CPP_INCLUDE_DIR}") + include_directories(${YAML_CPP_INCLUDE_DIR}) + set(YAML_CPP_LIBRARY_DIR "${YAML_CPP_CMAKE_DIR}/../../") + target_link_libraries(dftracer INTERFACE -L${YAML_CPP_LIBRARY_DIR} ${YAML_CPP_LIBRARIES}) +else () + message(FATAL_ERROR "-- [DFTRACER] yaml-cpp is needed for ${PROJECT_NAME} build") +endif () + +check_required_components(dftracer) + +set(DFTRACER_LIBRARIES dftracer) \ No newline at end of file diff --git a/cmake/configure_files/dftracer_config.hpp.in b/cmake/configure_files/dftracer_config.hpp.in index e3179997..acbfd186 100644 --- a/cmake/configure_files/dftracer_config.hpp.in +++ b/cmake/configure_files/dftracer_config.hpp.in @@ -5,6 +5,12 @@ #define DFTRACER_PACKAGE_VERSION @DFTRACER_PACKAGE_VERSION@ #cmakedefine DFTRACER_GIT_VERSION @DFTRACER_GIT_VERSION@ +#define DFTRACER_GET_VERSION(MAJOR, MINOR, PATCH) (MAJOR * 100000 + MINOR * 100 + PATCH) +#define DFTRACER_VERSION (DFTRACER_GET_VERSION @DFTRACER_VERSION@) +#define DFTRACER_VERSION_MAJOR (DFTRACER_VERSION / 100000) +#define DFTRACER_VERSION_MINOR ((DFTRACER_VERSION / 100) % 1000) +#define DFTRACER_VERSION_PATCH (DFTRACER_VERSION % 100) + /* Compiler used */ #cmakedefine CMAKE_BUILD_TYPE "@CMAKE_BUILD_TYPE@" diff --git a/dfanalyzer/dask/conf/corona.yaml b/dfanalyzer/dask/conf/corona.yaml index 19be2209..80e97829 100644 --- a/dfanalyzer/dask/conf/corona.yaml +++ b/dfanalyzer/dask/conf/corona.yaml @@ -3,6 +3,9 @@ config: conf_dir: ${DFTRACER_APP}/dfanalyzer/dask/conf run_dir: ${DFTRACER_APP}/dfanalyzer/dask/run_dir log_dir: ${DFTRACER_APP}/dfanalyzer/dask/logs +dask: + scheduler: dask scheduler + worker: dask worker job: num_nodes: 1 wall_time_min: 60 diff --git a/dfanalyzer/dask/conf/polaris.yaml b/dfanalyzer/dask/conf/polaris.yaml new file mode 100644 index 00000000..8dbbd9f8 --- /dev/null +++ b/dfanalyzer/dask/conf/polaris.yaml @@ -0,0 +1,26 @@ +config: + script_dir: ${DFTRACER_APP}/dfanalyzer/dask/scripts + conf_dir: ${DFTRACER_APP}/dfanalyzer/dask/conf + run_dir: ${DFTRACER_APP}/dfanalyzer/dask/run_dir + log_dir: ${DFTRACER_APP}/dfanalyzer/dask/logs +dask: + scheduler: dask-scheduler + worker: dask-worker +job: + num_nodes: 1 + wall_time_min: 01:00:00 + env_id: PBS_JOBID + queue: debug +scheduler: + cmd: qsub -l select=${DFTRACER_JOB_NUM_NODES} -l walltime=${DFTRACER_JOB_WALL_TIME_MIN} -l filesystems=home:eagle:grand -q ${DFTRACER_JOB_QUEUE} -A ${DFTRACER_ACCOUNT} -- + port: 11000 + kill: qdel +worker: + total_tasks: 16 + ppn: 16 + cmd: /opt/cray/pals/1.3.4/bin/mpiexec -n ${DFTRACER_WORKER_TOTAL_TASKS} --ppn ${DFTRACER_WORKER_PPN} + per_core: 1 + threads: 1 + local_dir: /dev/shm/$USER/dask-workspace + kill: qdel + connection_string: tcp://${DFTRACER_SCHEDULER_HOSTNAME}:${DFTRACER_SCHEDULER_PORT} diff --git a/dfanalyzer/dask/conf/quartz.yaml b/dfanalyzer/dask/conf/quartz.yaml new file mode 100644 index 00000000..a79dc1b4 --- /dev/null +++ b/dfanalyzer/dask/conf/quartz.yaml @@ -0,0 +1,23 @@ +config: + script_dir: ${DFTRACER_APP}/dfanalyzer/dask/scripts + conf_dir: ${DFTRACER_APP}/dfanalyzer/dask/conf + run_dir: ${DFTRACER_APP}/dfanalyzer/dask/run_dir + log_dir: ${DFTRACER_APP}/dfanalyzer/dask/logs +dask: + scheduler: dask scheduler + worker: dask worker +job: + num_nodes: 4 + wall_time_min: 60 + env_id: SLURM_JOB_ID +scheduler: + cmd: srun -N ${DFTRACER_JOB_NUM_NODES} -t ${DFTRACER_JOB_WALL_TIME_MIN} + port: 12005 + kill: scancel ${SLURM_JOB_ID} +worker: + ppn: 16 + cmd: srun -N ${DFTRACER_JOB_NUM_NODES} --ntasks-per-node=${DFTRACER_WORKER_PPN} + per_core: 1 + threads: 1 + local_dir: /dev/shm/dask-workspace + kill: scancel ${SLURM_JOB_ID} \ No newline at end of file diff --git a/dfanalyzer/dask/conf/ruby.yaml b/dfanalyzer/dask/conf/ruby.yaml index 1b1752f3..f3232b1f 100644 --- a/dfanalyzer/dask/conf/ruby.yaml +++ b/dfanalyzer/dask/conf/ruby.yaml @@ -3,6 +3,9 @@ config: conf_dir: ${DFTRACER_APP}/dfanalyzer/dask/conf run_dir: ${DFTRACER_APP}/dfanalyzer/dask/run_dir log_dir: ${DFTRACER_APP}/dfanalyzer/dask/logs +dask: + scheduler: dask scheduler + worker: dask worker job: num_nodes: 1 wall_time_min: 60 diff --git a/dfanalyzer/dask/scripts/start_dask_distributed.sh b/dfanalyzer/dask/scripts/start_dask_distributed.sh index 6072323f..73a35531 100755 --- a/dfanalyzer/dask/scripts/start_dask_distributed.sh +++ b/dfanalyzer/dask/scripts/start_dask_distributed.sh @@ -12,6 +12,12 @@ case $hostname in *"ruby"*) DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/ruby.yaml ;; + "quartz"*) + DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/quartz.yaml + ;; + "polaris"*) + DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/polaris.yaml + ;; esac if [[ "$DFTRACER_DASK_CONF_NAME" == "UNSET" ]]; then @@ -27,9 +33,33 @@ source ${DFTRACER_APP}/dfanalyzer/dask/scripts/utils.sh eval $(parse_yaml $DFTRACER_DASK_CONF_NAME DFTRACER_) source ${DFTRACER_ENV}/bin/activate +mkdir -p ${DFTRACER_CONFIG_LOG_DIR} +mkdir -p ${DFTRACER_CONFIG_RUN_DIR} + +rm -rf ${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.json -dask scheduler --scheduler-file ${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.json --port ${DFTRACER_SCHEDULER_PORT} > ${DFTRACER_CONFIG_LOG_DIR}/scheduler_${USER}.log 2>&1 & +${DFTRACER_DASK_SCHEDULER} --scheduler-file ${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.json --port ${DFTRACER_SCHEDULER_PORT} > ${DFTRACER_CONFIG_LOG_DIR}/scheduler_${USER}.log 2>&1 & scheduler_pid=$! echo $scheduler_pid > ${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.pid -${DFTRACER_SCHEDULER_CMD} ${DFTRACER_CONFIG_SCRIPT_DIR}/start_dask_worker.sh ${DFTRACER_DASK_CONF_NAME} +file=${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.json +timeout=30 # seconds to wait for timeout +SECONDS=0 # initialize bash's builtin counter + +until [ -s "$file" ] || (( SECONDS >= timeout )); do sleep 1; done + + +if test -f $file; +then + echo "Scheduler with $scheduler_pid is running" + # Do something knowing the pid exists, i.e. the process with $PID is running +else + echo "Scheduler with $scheduler_pid failed. Check the ${DFTRACER_CONFIG_LOG_DIR}/scheduler_${USER}.log file" + exit 1 +fi + +rm ${DFTRACER_CONFIG_RUN_DIR}/job_id_${USER}.pid + +${DFTRACER_SCHEDULER_CMD} ${DFTRACER_CONFIG_SCRIPT_DIR}/start_dask_worker.sh ${DFTRACER_DASK_CONF_NAME} ${hostname} + + diff --git a/dfanalyzer/dask/scripts/start_dask_worker.sh b/dfanalyzer/dask/scripts/start_dask_worker.sh index 6d3b689c..12c08299 100755 --- a/dfanalyzer/dask/scripts/start_dask_worker.sh +++ b/dfanalyzer/dask/scripts/start_dask_worker.sh @@ -1,6 +1,9 @@ #!/bin/bash +set -x + DFTRACER_DASK_CONF_NAME=$1 +DFTRACER_SCHEDULER_HOSTNAME=$2 source $HOME/.dftracer/configuration.sh export PYTHONPATH=${DFTRACER_APP}:${PYTHONPATH} @@ -9,13 +12,24 @@ export PYTHONPATH=${DFTRACER_APP}:${PYTHONPATH} source ${DFTRACER_APP}/dfanalyzer/dask/scripts/utils.sh eval $(parse_yaml $DFTRACER_DASK_CONF_NAME DFTRACER_) DFTRACER_JOB_ID=${!DFTRACER_JOB_ENV_ID} + +echo -n $DFTRACER_JOB_ID > ${DFTRACER_CONFIG_RUN_DIR}/job_id_${USER}.pid + source ${DFTRACER_ENV}/bin/activate echo "Activated Env" + +if [ "x${DFTRACER_WORKER_CONNECTION_STRING}" != "x" ]; then + dask_scheduler_conn=${DFTRACER_WORKER_CONNECTION_STRING} +else + dask_scheduler_conn="--scheduler-file ${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.json" +fi + while : do -${DFTRACER_WORKER_CMD} dask worker --scheduler-file ${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.json \ +${DFTRACER_WORKER_CMD} ${DFTRACER_DASK_WORKER} ${dask_scheduler_conn} \ --local-directory ${DFTRACER_WORKER_LOCAL_DIR} \ --nworkers ${DFTRACER_WORKER_PER_CORE} --nthreads ${DFTRACER_WORKER_THREADS} > ${DFTRACER_CONFIG_LOG_DIR}/worker_${DFTRACER_JOB_ID}.log 2>&1 echo "Workers existed. Restarting in 1 second" sleep 1 done + diff --git a/dfanalyzer/dask/scripts/stop_dask_distributed.sh b/dfanalyzer/dask/scripts/stop_dask_distributed.sh index b72d207b..91932f08 100755 --- a/dfanalyzer/dask/scripts/stop_dask_distributed.sh +++ b/dfanalyzer/dask/scripts/stop_dask_distributed.sh @@ -3,11 +3,35 @@ set -x source $HOME/.dftracer/configuration.sh export PYTHONPATH=${DFTRACER_APP}:${PYTHONPATH} # This can be set using env variable or arguments to script. -DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/ruby.yaml + +hostname=`hostname` +DFTRACER_DASK_CONF_NAME="UNSET" + +case $hostname in + *"corona"*) + DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/corona.yaml + ;; + *"ruby"*) + DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/ruby.yaml + ;; + "quartz"*) + DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/quartz.yaml + ;; + "polaris"*) + DFTRACER_DASK_CONF_NAME=${DFTRACER_APP}/dfanalyzer/dask/conf/polaris.yaml + ;; +esac + +if [[ "$DFTRACER_DASK_CONF_NAME" == "UNSET" ]]; then + echo "UNSUPPORTED $hostname" + exit 1 +fi # This is start of every script. source ${DFTRACER_APP}/dfanalyzer/dask/scripts/utils.sh eval $(parse_yaml $DFTRACER_DASK_CONF_NAME DFTRACER_) -$DFTRACER_SCHEDULER_KILL -$DFTRACER_WORKER_KILL +kill -9 `cat ${DFTRACER_CONFIG_RUN_DIR}/scheduler_${USER}.pid` +export DFTRACER_JOB_ID=`cat ${DFTRACER_CONFIG_RUN_DIR}/job_id_${USER}.pid` +$DFTRACER_SCHEDULER_KILL $DFTRACER_JOB_ID +$DFTRACER_WORKER_KILL $DFTRACER_JOB_ID diff --git a/dfanalyzer/graph.py b/dfanalyzer/graph.py new file mode 100644 index 00000000..4c59948e --- /dev/null +++ b/dfanalyzer/graph.py @@ -0,0 +1,211 @@ + +import dask.dataframe as dd +import re +import os +import glob +import pandas as pd + + +class DFGrepInterference: + """ + This class provides methods to manage the graph based representation of IO traces for interference computation. + init parameters: + ddf (dask dataframe): dask dataframe (analyzer.events) for computing the metrices. + app_name (str): Application identifier. Used for reading/writing the checkpoint files. + cp_dir (str): Checkpoint directory path + existing (bool): If true, computation can be avoided and the instance can be loaded from checkpoint files for downstream analysis + """ + + def __init__(self, ddf=None, app_name="", cp_dir="", existing=False): + self.ddf = ddf + self.ddf_deg = None + self.inter = None + self.correlation = None + self.app_name = app_name + self.cp_dir = cp_dir + self.meta = { + 'id': str, + 'name': str, + 'pid': int, + 'size': int, + 'ts': int, + 'te': int, + 'mount_point': str, + 'dur': int, + 'trange': int, + 'deg': int + } + if existing: + self.read_checkpoint(id="inter", cp_dir=cp_dir) + self.read_checkpoint(id='deg_ddf', cp_dir=cp_dir) + else: + self.ddf = self.select_data_cols( + cols=['id', 'name', 'pid', 'size', 'ts', 'te', 'mount_point', 'dur', 'trange']) + + def select_data_cols(self, cols=[]): + ''' + returns the data with size > 0 and with selected columns + ''' + return self.ddf.query('size > 0')[cols] + + def get_degree(self): + """ + Calculates the degree for each event. The degree calculation is done on group of events with same mount point and within same timerange. + + get_deg calculates the degree for each group. It first sort the events according to start time, and for each events, look forward to determine if any events have overlapping time. If so, increase the degree by 1 for both events. + """ + + def get_deg(df_group): + df_group = df_group.sort_values(by='ts').reset_index( + drop=True) # check drop true + group_length = len(df_group) + degrees = [1]*group_length + # update degrees by looping throught the group + for row in range(group_length): + current_stop_time = df_group.at[row, 'te'] + # look for neighbors + for neigh in range(row+1, group_length): + neigh_start_time = df_group.at[neigh, 'ts'] + if (neigh_start_time < current_stop_time): + degrees[row] += 1 + degrees[neigh] += 1 + else: + break + # Add a new column 'deg' representing the count of overlaps + df_group['deg'] = degrees + return df_group + + self.ddf_deg = self.ddf.groupby(['mount_point', 'trange']).apply(get_deg, meta=self.meta).reset_index( + drop=True) # multiple trange column error while writing so had to drop + # self.ddf_deg.set_index(['id']) + + def get_interference(self): + ''' + calculate the interference factor for each events. + step1: calculate the duration of minimum degree for all size and mount point combination. + step2: calculate the Interference factor based on duration of the event and the duration of min degree event. + ''' + def dur_of_min_deg(ddf): + ''' + calculate the duration of minimum degree for all size and mount point combination. + ''' + ddf1 = ddf.copy() + list_deg = ddf1.groupby(["mount_point", "size"])[ + "deg"].min().compute() + agg_dict = {} + for deg in list_deg: + agg_dict[str(deg)] = min + ddf1[str(deg)] = 9223372036854775807 + ddf1[str(deg)] = ddf1[str(deg)].mask( + ddf1['deg'] == deg, ddf1['dur']) + return ddf1, agg_dict, list_deg + + def calculate_interference(ddf, agg_dict, list_deg): + ''' + calculate the Interference factor based on duration of the event and the duration of min degree event. + ''' + agg_dict["deg"] = min + val = ddf.groupby(['size', 'mount_point']).agg(agg_dict) + val['min_dur'] = 0 + for deg in list_deg: + val['min_dur'] = val['min_dur'].mask( + val['deg'].eq(deg), val[str(deg)]) + ddf2 = val.reset_index() + merge = ddf.merge(ddf2, on=['size', 'mount_point'], how='left', suffixes=('_caller', '_other'))[ + ['name', 'pid', 'size', 'ts', 'te', 'mount_point', 'dur', 'trange', 'deg_caller', 'deg_other', 'min_dur']] + merge['interference'] = merge['min_dur']/merge['dur'] + return merge + + dft1, agg_dict, list_deg = dur_of_min_deg(self.ddf_deg) + self.inter = calculate_interference( + dft1, agg_dict=agg_dict, list_deg=list_deg) + + def write_checkpoint(self, id, cp_dir): + ''' + write the datafame as parquet files + ''' + write_df = getattr(self, id) + # print(write_df.compute()) + # schema = {'id': int, 'name': str, 'pid': int, 'size': int, 'ts': int, 'te': int, 'mount_point': str, 'dur': int, 'trange': int, 'deg':int} + write_df.to_parquet(f"{cp_dir}/{self.app_name}", + name_function=lambda i: f'{id}-{i}.parquet') + + def read_checkpoint(self, id, cp_dir): + ''' + read the dataframe from checkpoint files + ''' + read_df = dd.read_parquet(f"{cp_dir}/{self.app_name}/{id}*.parquet") + setattr(self, id, read_df) + + +class DFGrepWorkflow: + """ + This class provides methods to represent the IO traces as workflow graphs. + init parameters: + """ + + def __init__(self, ddf=None, app_name="", trace_path=""): + self.ddf = ddf + self.app_name = app_name + self.trace_path = trace_path + + def select_cols(self, cols=[]): + return self.ddf[cols] + + def get_pid_map(self): + ''' + This function is designed for mummi traces to map pid with the application based on the filename + ''' + all_files = glob.glob(self.trace_path) + pid_map = {} + for file in all_files: + slices = os.path.basename(file).split('.') + if (len(slices) > 4): + pid_map[slices[3]] = slices[1] + return pid_map + + def create_workflow(self): + ''' + 1. Find number of times each file is prod/cons. And select the files that are both prod & cons atleast once + 2. Get the list of the files which are both produced and consumed and select only the events with these files + ''' + prod_cons = self.ddf.groupby('filename')['prod', 'cons'].sum() + prod_cons = prod_cons.query('prod > 0 and cons > 0').reset_index() + filelist = prod_cons.filename.unique().compute() + selected_events = self.ddf[self.ddf.filename.isin(filelist)] + selected_events_sum = selected_events.groupby(['filename', 'pid']).agg( + {'prod': 'sum', 'cons': 'sum', 'ts': 'min'}).reset_index() + merged = selected_events_sum.merge( + prod_cons, on=["filename"], how='left', suffixes=['_pid', '_fid']) + final = merged.query( + 'not (prod_pid == prod_fid and cons_pid == cons_fid)') + return final + + def create_graph_df(self, df, pid_map): + ''' + Function creates soruce and destination data for plotting the graph. This version is currently designed for mummi workflow + ''' + def get_base_filename(path): + return os.path.basename(path) + + def process_row(row): + filename = re.sub("\d+", "x", row['filename']) + filename = "f_"+get_base_filename(filename) + # filename = row['filename'] + pid = pid_map[str(row['pid'])] if str( + row['pid']) in pid_map else str(row['pid']) + pid = "p_"+pid + prod = row['prod_pid'] + cons = row['cons_pid'] + + if prod == 0: + return [{'src': filename, 'dest': pid, 'wt': row['ts']}] + + elif cons == 0: + return [{'src': pid, 'dest': filename, 'wt': row['ts']}] + elif prod > 0 and cons > 0: + return [{'src': filename, 'dest': pid, 'wt': row['ts']}, {'src': pid, 'dest': filename, 'wt': row['ts']}] + + graph_df = pd.DataFrame([item for sublist in df.apply( + process_row, axis=1) for item in sublist]) + return graph_df diff --git a/dfanalyzer/graph_visualization/cystyles.json b/dfanalyzer/graph_visualization/cystyles.json new file mode 100644 index 00000000..a8317b7a --- /dev/null +++ b/dfanalyzer/graph_visualization/cystyles.json @@ -0,0 +1,139 @@ +{ + "default": [ + { + "selector": "nodes", + "style": { + "font-family": "helvetica", + "width": "70px", + "height": "70px", + "label": "data(id)", + "font-size": "15px", + "font-color": "brown", + "text-valign": "center", + "text-halign": "center", + "background-color": "purple" + } + }, + { + "selector": "edges", + "style": { + "font-family": "helvetica", + "font-size": "2px", + "line-color": "pink" + } + }, + { + "selector": "node[degree>2]", + "style": { + "width": "70px", + "height": "70px", + "font-size": "15px", + "font-family": "helvetica", + "background-color": "red" + } + }, + { + "selector": "node[bipartite=0]", + "style": { + "width": "70px", + "height": "70px", + "font-family": "helvetica", + "background-color": "blue" + } + }, + { + "selector": "node[degree<4]", + "style": { + "width": "70px", + "height": "70px", + "font-size": "15px", + "color": "white", + "font-family": "helvetica" + } + }, + { + "selector": "edge[weight>5000]", + "style": { + "font-family": "helvetica", + "line-color": "green" + } + } + ], + "direct": [ + { + "selector": "node", + "style": { + "content": "data(label)", + "text-opacity": 0.8, + "text-valign": "center", + "text-halign": "center", + "background-color": "pink" + } + }, + { + "selector": "edge", + "style": { + "curve-style": "bezier", + "target-arrow-shape": "triangle", + "line-color": "#9dbaea", + "target-arrow-color": "#9dbaea", + "width": 2 + } + }, + { + "selector": "node[id ^= \"f\"]", + "style": { + "shape": "rectangle" + } + }, + { + "selector": "edge.bidirectional", + "style": { + "curve-style": "unbundled-bezier", + "control-point-distances": [ + 20 + ], + "control-point-weights": [ + 0.5 + ], + "target-arrow-shape": "triangle", + "source-arrow-shape": "triangle", + "line-color": "#ff0000", + "target-arrow-color": "#ff0000", + "source-arrow-color": "#ff0000", + "width": 2 + } + } + ], + "directed": [ + { + "selector": "nodes", + "style": { + "font-family": "helvetica", + "width": "50px", + "height": "50px", + "label": "data(id)", + "font-size": "10px", + "font-color": "white", + "text-valign": "center", + "text-halign": "center", + "background-color": "pink" + } + }, + { + "selector": "edge", + "style": { + "curve-style": "bezier", + "target-arrow-shape": "triangle", + "target-arrow-color": "#9dbaea" + } + }, + { + "selector": "edge[back]", + "style": { + "line-color": "red", + "target-arrow-color": "red" + } + } + ] +} \ No newline at end of file diff --git a/dfanalyzer/graph_visualization/cytoscape.py b/dfanalyzer/graph_visualization/cytoscape.py new file mode 100644 index 00000000..6f2bd37a --- /dev/null +++ b/dfanalyzer/graph_visualization/cytoscape.py @@ -0,0 +1,176 @@ +import json +import networkx as nx +import ipycytoscape +import ipywidgets as widgets +from IPython.display import display +import os +# import ipycytoscape +# import networkx as nx + + +class CytoGraph: + + def get_json(self, graph, degree_dict = {}): + ''' + Input: networkx graph, dict (key = node_id and value = degree) + Returns: json_data (format needed for ipycytoscape visualization) + ''' + # for pid_tid -> file bipartite graphs + json_data = { + 'nodes': [{'data': {'id': str(node[0]), 'degree': int(degree_dict[node[0]])}} for node in graph.nodes(data=True)], + 'edges': [{'data': {'source': str(edge[0]), 'target': str(edge[1]), 'directed': True}} for edge in graph.edges(data=True)]} + + return json_data + + + def get_rich_json(self, graph, degree_dict = {}): + ''' + Get json with Nodes and Edges attributes + Input: networkx graph, dict (key = node_id and value = degree) + Returns: json_data (format needed for ipycytoscape visualization) + ''' + # for pid_tid -> file bipartite graphs + # json_data = { + # 'nodes': [{'data': {'id': str(node[0]),'degree': int(degree_dict[str(node[0])]), 'bipartite': int(node[1]['bipartite'])}} for node in graph.nodes(data=True)], + # 'edges': [{'data': {'source': str(edge[0]), 'target': str(edge[1]), 'weight': int(edge[2]['weight'])}} for edge in graph.edges(data=True)]} + + # # for unweighted unipartite graphs + # json_data = { + # 'nodes': [{'data': {'id': str(node[0]), 'degree': int(degree_dict[node[0]])}} for node in graph.nodes(data=True)], + # 'edges': [{'data': {'source': str(edge[0]), 'target': str(edge[1]), 'directed': True}} for edge in graph.edges(data=True)]} + + # for directed + # Prepare nodes and edges data + nodes = [{'data': {'id': str(node), 'label': str(node), 'outdegree': int(graph.out_degree(node))}} for node in graph.nodes()] + edges = [] + for edge in graph.edges(data=True): + u , v, t = edge[0], edge[1], edge[2]['wt'] + edge_data = {'data': {'source': str(u), 'target': str(v), 'wt': int(t)}} + if graph.has_edge(v, u): + edge_data['classes'] = 'bidirectional' + edges.append(edge_data) + + json_data = {'nodes': nodes, 'edges': edges} + + return json_data + + def get_style(self, style_name): + current_dir = os.path.dirname(os.path.abspath(__file__)) + styles_file = os.path.join(current_dir, 'cystyles.json') + with open(styles_file, 'r') as f: + styles = json.load(f) + return styles.get(style_name, []) + + def temporal_view(self,df): + ''' + Create ipywidget visualization for visualizing prev and next timestamp graphs using trange as tiemstamp + ''' + def get_graphs(df, each): + g_data = df.query(f'trange <= {each}') + G = nx.from_pandas_edgelist(g_data, source='src', target='dest', edge_attr= 'wt', create_using=nx.DiGraph()) + json_data = self.get_rich_json(G) + return json_data + + views_t = sorted(df.trange.unique()) + views = [get_graphs(df,each) for each in views_t] + + # Initialize ipycytoscape graph widgets with the first views + graph1 = ipycytoscape.CytoscapeWidget() + graph1.graph.add_graph_from_json(views[0]) + graph1.set_layout(name = 'dagre') + graph1.set_style(self.get_style('direct')) + + graph2 = ipycytoscape.CytoscapeWidget() + graph2.graph.add_graph_from_json(views[1]) + graph2.set_layout(name = 'dagre') + graph2.set_style(self.get_style('direct')) + + # Navigation buttons + button_selected = widgets.Button(description="Prev") + button_next = widgets.Button(description="Next") + output = widgets.Output() + + # Index to keep track of current view + current_view = 0 + + def update_graph_views(): + nonlocal current_view + graph1.graph.clear() + graph1.graph.add_graph_from_json(views[current_view]) + graph1.set_layout(name = 'dagre') + graph1.set_style(self.get_style('direct')) + + next_view = (current_view + 1) % len(views) + graph2.graph.clear() + graph2.graph.add_graph_from_json(views[next_view]) + graph2.set_layout(name = 'dagre') + graph2.set_style(self.get_style('direct')) + + with output: + output.clear_output() + print(f"View {current_view + 1} / {len(views)}") + + def on_prev_clicked(b): + # update_graph_views() + nonlocal current_view + current_view = (current_view - 1) % len(views) + update_graph_views() + + def on_next_clicked(b): + nonlocal current_view + current_view = (current_view + 1) % len(views) + update_graph_views() + + button_selected.on_click(on_prev_clicked) + button_next.on_click(on_next_clicked) + + # Display widgets side by side + buttons_box = widgets.HBox([button_selected, button_next]) + graphs_box = widgets.HBox([graph1, graph2]) + display(widgets.VBox([buttons_box, graphs_box, output])) + + + +class GraphFunctions: + def create_nx_graph(self, events): + ''' + Input: dataframe to create graph from + Returns: networkx graph with node as each row in in df, and edge between two nodes exists if there exists any overlapping time. + ''' + graph = nx.Graph() + df = events.sort_values('ts').reset_index() + event_size = len(events) + for row in range(event_size): + current_stop_time = df.at[row, 'te'] + for neigh in range(row+1, event_size): + neigh_start_time = df.at[neigh, 'ts'] + if (neigh_start_time <= current_stop_time): + graph.add_edge(df.at[row, 'id'], df.at[neigh, 'id']) + else: + break + return graph + + def visualize_graph(self, nx_graph, cyto_obj): + ''' + Input: networkx graph and cytoscape + Visualize graph using json data + ''' + app_view = ipycytoscape.CytoscapeWidget() + degree_dict = dict(nx_graph.degree) + json_g = cyto_obj.get_json(nx_graph, degree_dict) + app_view.graph.add_graph_from_json(json_g) + # graph_view.set_layout(name="circle") + # app_view.set_layout(name="concentric") + app_view.set_layout(name="dagre",spacingFactor= 1.5,rankDir= "LR", fit=True) + app_view.set_style(cyto_obj.get_style('default')) + return app_view + + def visualize_nxgraph(self, nx_graph, cyto_obj): + ''' + Visualize from networkx graph + ''' + app_view = ipycytoscape.CytoscapeWidget() + app_view.graph.add_graph_from_networkx(nx_graph, directed=True) + app_view.set_layout(name="dagre") + app_view.set_style(cyto_obj.get_style('directed')) + return app_view diff --git a/dfanalyzer/main.py b/dfanalyzer/main.py index 396d78aa..909c6fb0 100644 --- a/dfanalyzer/main.py +++ b/dfanalyzer/main.py @@ -43,10 +43,10 @@ def __init__(self): self.log_file = "dfanalyzer.log" self.dask_scheduler = None self.index_dir = None - self.time_approximate = False + self.time_approximate = True self.slope_threshold = 45 - self.time_granularity = 1e3 - self.skip_hostname = False + self.time_granularity = 1e6 + self.skip_hostname = True self.conditions = None dft_configuration = DFTConfiguration() @@ -158,12 +158,13 @@ def load_indexed_gzip_files(filename, start, end): logging.debug(f"Read {len(json_lines)} json lines for [{start}, {end}]") return json_lines -def load_objects(line, fn, time_granularity, time_approximate, condition_fn): +def load_objects(line, fn, time_granularity, time_approximate, condition_fn, load_data): d = {} if line is not None and line !="" and len(line) > 0 and "[" != line[0] and line != "\n" : val = {} try: - val = json.loads(line) + unicode_line = ''.join([i if ord(i) < 128 else '#' for i in line]) + val = json.loads(unicode_line) logging.debug(f"Loading dict {val}") if "name" in val: d["name"] = val["name"] @@ -180,7 +181,7 @@ def load_objects(line, fn, time_granularity, time_approximate, condition_fn): d["trange"] = int(((val["ts"] + val["dur"])/2.0) / time_granularity) d.update(io_function(val, d, time_approximate,condition_fn)) if fn: - d.update(fn(val, d, time_approximate,condition_fn)) + d.update(fn(val, d, time_approximate,condition_fn, load_data)) logging.debug(f"built an dictionary for line {d}") except ValueError as error: logging.error(f"Processing {line} failed with {error}") @@ -229,10 +230,22 @@ def io_function(json_object, current_dict, time_approximate,condition_fn): d["hostname"] = json_object["args"]["hostname"] if "POSIX" == json_object["cat"] and "ret" in json_object["args"]: - if "write" in json_object["name"]: + if json_object["name"] == "write": d["size"] = int(json_object["args"]["ret"]) - elif "read" in json_object["name"] and "readdir" not in json_object["name"]: + elif json_object["name"] == "read": d["size"] = int(json_object["args"]["ret"]) + elif json_object["name"] == "fwrite": + d["size"] = 1 + if "ret" in json_object["args"]: + d["size"] *= int(json_object["args"]["ret"]) + if "size" in json_object["args"]: + d["size"] *= int(json_object["args"]["size"]) + elif json_object["name"] == "fread": + d["size"] = 1 + if "ret" in json_object["args"]: + d["size"] *= int(json_object["args"]["ret"]) + if "size" in json_object["args"]: + d["size"] *= int(json_object["args"]["size"]) else: if "image_size" in json_object["args"]: d["size"] = int(json_object["args"]["image_size"]) @@ -340,8 +353,13 @@ def human_format_time(num): class DFAnalyzer: - def __init__(self, file_pattern, load_fn=None, load_cols={}): + def __init__(self, file_pattern, load_fn=None, load_cols={}, load_data = {}): + self.conf = get_dft_configuration() + if self.conf.dask_scheduler: + client = Client.current() + if len(load_data)>0: + client.scatter(load_data) file_pattern = glob(file_pattern) all_files = [] pfw_pattern = [] @@ -386,13 +404,15 @@ def __init__(self, file_pattern, load_fn=None, load_cols={}): gz_bag = json_lines.map(load_objects, fn=load_fn, time_granularity=self.conf.time_granularity, time_approximate=self.conf.time_approximate, - condition_fn=self.conf.conditions).filter(lambda x: "name" in x) + condition_fn=self.conf.conditions, + load_data=load_data).filter(lambda x: "name" in x) main_bag = None if len(pfw_pattern) > 0: pfw_bag = dask.bag.read_text(pfw_pattern).map(load_objects, fn=load_fn, time_granularity=self.conf.time_granularity, time_approximate=self.conf.time_approximate, - condition_fn=self.conf.conditions).filter(lambda x: "name" in x) + condition_fn=self.conf.conditions, + load_data=load_data).filter(lambda x: "name" in x) if len(pfw_gz_pattern) > 0 and len(pfw_pattern) > 0: main_bag = dask.bag.concat([pfw_bag, gz_bag]) elif len(pfw_gz_pattern) > 0: @@ -411,10 +431,11 @@ def __init__(self, file_pattern, load_fn=None, load_cols={}): logging.debug(f"Number of partitions used are {self.n_partition}") self.events = events.repartition(npartitions=self.n_partition).persist() _ = wait(self.events) - self.events['ts'] = self.events['ts'] - self.events['ts'].min() - self.events['te'] = self.events['ts'] + self.events['dur'] - self.events['trange'] = self.events['ts'] // self.conf.time_granularity + self.events['ts'] = (self.events['ts'] - self.events['ts'].min()).astype('uint64[pyarrow]') + self.events['te'] = (self.events['ts'] + self.events['dur']).astype('uint64[pyarrow]') + self.events['trange'] = (self.events['ts'] // self.conf.time_granularity).astype('uint16[pyarrow]') self.events = self.events.persist() + _ = wait(self.events) else: logging.error(f"Unable to load Traces") @@ -471,7 +492,7 @@ def _calculate_time(self): grouped_df[["only_app_io"]].apply(size_portion, col="only_app_io", axis=1).sum(), grouped_df[["only_app_compute"]].apply(size_portion, col="only_app_compute", axis=1).sum(), ) - logging.info(f"Approximate {self.conf.time_approximate} {total_time}, {total_io_time}, {total_compute_time}, {total_app_io_time}, \ + logging.debug(f"Approximate {self.conf.time_approximate} total_time:{total_time}, {total_io_time}, {total_compute_time}, {total_app_io_time}, \ {only_io}, {only_compute}, {only_app_io}, {only_app_compute}") return total_time, total_io_time, total_compute_time, total_app_io_time, \ only_io, only_compute, only_app_io, only_app_compute @@ -667,6 +688,7 @@ def setup_dask_cluster(): client = Client(cluster) # Connect to distributed cluster and override default logging.info(f"Initialized Client with {conf.workers} workers and link {client.dashboard_link}") + def main(): args = parse_args() setup_logging() diff --git a/dfanalyzer/plots.py b/dfanalyzer/plots.py index 1a0f92f7..b8d2e732 100644 --- a/dfanalyzer/plots.py +++ b/dfanalyzer/plots.py @@ -5,6 +5,7 @@ import pandas as pd from matplotlib import ticker from typing import Literal, Tuple +import seaborn as sns TIME_COLS = ['io_time', 'app_io_time'] @@ -28,6 +29,7 @@ def time_bw_timeline( y2label: str = 'Bandwidth', x_num_ticks: int = 10, y_num_ticks: int = 5, + y_axis_formatter = ticker.FuncFormatter(lambda x, pos: '{:.0f}'.format(x)), ): size_denom = 1024 y2label_suffix = 'KB/s' @@ -52,7 +54,8 @@ def _set_bw(df: pd.DataFrame): .reset_index() \ .map_partitions(_set_bw) \ .compute() \ - .assign(seconds=self._assign_seconds) + .assign(seconds=self._assign_seconds) \ + .sort_values("seconds") fig, ax1 = plt.subplots(figsize=figsize) if time_col == "io_time": @@ -81,12 +84,11 @@ def _set_bw(df: pd.DataFrame): ax1.yaxis.set_major_formatter(ticker.FuncFormatter( - lambda x, pos: '{:.0f}'.format(x/1e6))) + lambda x, pos: '{:.1f}'.format(x/1e6))) ax1.set_xlabel(xlabel) ax1.set_ylabel(y1label) - ax2.yaxis.set_major_formatter(ticker.FuncFormatter( - lambda x, pos: '{:.1f}'.format(x))) + ax2.yaxis.set_major_formatter(y_axis_formatter) if has_y2: ax2.set_ylabel(f"{y2label} ({y2label_suffix})") @@ -131,6 +133,7 @@ def xfer_size_timeline( ylabel: str = 'Transfer Size', x_num_ticks: int = 10, y_num_ticks: int = 5, + y_axis_formatter = ticker.FuncFormatter(lambda x, pos: '{:.0f}'.format(x)), ): xfer_col = 'xfer' @@ -152,7 +155,8 @@ def _set_xfer_size(df: pd.DataFrame): .query("phase == 2") \ .map_partitions(_set_xfer_size) \ .compute() \ - .assign(seconds=self._assign_seconds) + .assign(seconds=self._assign_seconds) \ + .sort_values("seconds") fig, ax = plt.subplots(figsize=figsize) @@ -166,8 +170,7 @@ def _set_xfer_size(df: pd.DataFrame): ax.yaxis.set_major_locator(ticker.LinearLocator(y_num_ticks)) # ax1.yaxis.set_major_formatter(ticker.FuncFormatter( # lambda x, pos: '{:.0f}'.format(x/1e6))) - ax.yaxis.set_major_formatter(ticker.FuncFormatter( - lambda x, pos: '{:.1f}'.format(x))) + ax.yaxis.set_major_formatter(y_axis_formatter) # ax.get_legend().remove() ax.minorticks_on() @@ -223,3 +226,128 @@ def _create_timeline(events: dd.DataFrame): }).reset_index().set_index("trange", sorted=True) return timeline + + +# plots used for graph based methods +class GrepIOPlots: + def histogram(self,data,x_label): + # Create the plot with logarithmic y-axis and linear x-axis + plt.hist(data, bins=23, color='skyblue', edgecolor='black') + plt.yscale('log') # Set logarithmic scale for the y-axis + # Add labels and title + plt.xlabel(x_label) + plt.ylabel('Frequency (log scale)') # Adjust the label for the y-axis + plt.title('Histogram of '+x_label) + # Show the plot + plt.show() + + def bar_graph(self,data,xlabel): + ''' + Example: + value_counts = analyzer_mummi1.events['Name'].value_counts().compute() + bar_graph(value_counts,"Name") + ''' + # Extract values and counts + values = data.index.tolist() + counts = data.values.tolist() + # Create a bar graph + plt.figure(figsize=(10, 6)) + plt.bar(values, counts) + # Add numerical values on the bars + for i, (xi, yi) in enumerate(zip(values, counts)): + plt.text(xi, yi, f'{yi:.2f}', ha='center', va='bottom',fontsize=6) + # Add labels and title + plt.xlabel('Values') + plt.ylabel('Counts') + plt.title("Bar Graph of "+xlabel+" counts") + # Rotate x-axis labels if needed + plt.xticks(rotation=45) + # Show the plot + plt.show() + + def line_plot(self, ddf): + ''' + Function: line_graph (Divides the sorted dataframe into 10) + Usage: + line_plot(sorted_events) + ''' + idx = np.linspace(0, len(ddf)-1,10, dtype=int) + ts = [ddf.compute().iloc[k]['ts'] for k in idx] + + plt.plot(ts,idx, linestyle='--',marker= 'o') + # Set logarithmic scales for both axes + # plt.xscale('log') + # plt.yscale('log') + # Add labels and title + plt.xlabel('Time (ts)') + plt.ylabel('Index in Dataframe') + plt.title('Index vs Time') + plt.show() + + def hmap(self, mp=None, df=None, size_bins=[], size_labels=[], degree_bins=[], degree_labels = []): + # df= inter.compute() + if mp: + df= df[df['mount_point']==mp] + else: + mp = "All Mount Points" + # size_bins, size_labels, degree_bins, degree_labels = binned_category() + df['size_category'] = pd.cut(df['size'], bins=size_bins, labels=size_labels, right=False) + df['deg_category'] = pd.cut(df['deg_caller'], bins=degree_bins, labels=degree_labels, right=False) + + df['interference'] = df['interference'].astype(float) + + all_combinations = pd.MultiIndex.from_product([df['size_category'].unique(), df['deg_category'].unique()], names=['size_category', 'deg_category']) + merged = pd.merge(df, pd.DataFrame(index=all_combinations).reset_index(), on=['size_category', 'deg_category'], how='left') + grouped = merged.groupby(['size_category', 'deg_category']).agg({'interference': 'mean'}).reset_index() + + pivot_table = grouped.pivot(index='size_category', columns='deg_category', values='interference').fillna(-0.5) + # Create heatmap using seaborn + plt.figure(figsize=(8, 6)) + pivot_table = 1/pivot_table + sns.heatmap(pivot_table, annot=True, cmap='YlGnBu', fmt='.1f', linewidths=.5) + plt.title(f'Average Interference Heatmap {mp}') + plt.xlabel('Degrees') + plt.ylabel('Sizes') + plt.show() + + def correlation(self, ddf, group_col = '', col_a = '', col_b = '' ): + grouped = ddf.groupby(group_col).apply( + lambda x: x[col_a].corr(x[col_b]), + meta=('correlation', 'f8') + ).compute() + # grouped = ddf.groupby('trange').apply( + # lambda x: x['dur'].corr(x['interference']), + # meta=('correlation', 'f8') + # ).compute() + # 1. Binning the trange values + bin_size = 50 # Adjust this value as needed + grouped_binned = grouped.groupby(grouped.index // bin_size).mean() + plt.figure(figsize=(15, 6)) + plt.plot(grouped_binned.index * bin_size, grouped_binned.values, marker='o') + plt.title('Average Correlation ({col_a} and {col_b})') + plt.xlabel(f'{group_col} (binned)') + plt.ylabel('Correlation') + plt.grid(True, linestyle='--', alpha=0.7) + plt.tight_layout() + plt.show() + + def correlation_plot(self, grouped, bin_size = 50, group_col = '', col_a = '', col_b = '' ): + # grouped = ddf.groupby(group_col).apply( + # lambda x: x[col_a].corr(x[col_b]), + # meta=('correlation', 'f8') + # ).compute() + # grouped = ddf.groupby('trange').apply( + # lambda x: x['dur'].corr(x['interference']), + # meta=('correlation', 'f8') + # ).compute() + # 1. Binning the trange values + # bin_size = 50 # Adjust this value as needed + grouped_binned = grouped.groupby(grouped.index // bin_size).mean() + plt.figure(figsize=(15, 6)) + plt.plot(grouped_binned.index * bin_size, grouped_binned.values, marker='o') + plt.title(f'Average Correlation ({col_a} and {col_b})') + plt.xlabel(f'{group_col} (binned)') + plt.ylabel('Correlation') + plt.grid(True, linestyle='--', alpha=0.7) + plt.tight_layout() + plt.show() \ No newline at end of file diff --git a/dftracer/logger.py b/dftracer/logger.py index 1f7c4ec2..4a0163cd 100644 --- a/dftracer/logger.py +++ b/dftracer/logger.py @@ -105,6 +105,13 @@ def finalize(self): logging.debug(f"logger.finalize") self.logger.finalize() +def get_default_args(func): + signature = inspect.signature(func) + return { + k: v.default + for k, v in signature.parameters.items() + if v.default is not inspect.Parameter.empty + } class dft_fn(object): @@ -182,17 +189,19 @@ def wrapper(*args, **kwargs): self._arguments["image_size"] = str(args[0].image_size) if hasattr(args[0], "image_idx"): self._arguments["image_idx"] = str(args[0].image_idx) - for name, value in zip(arg_names[1:], kwargs): - if hasattr(args, name): - setattr(args, name, value) - if name == "epoch": - self._arguments["epoch"] = str(value) - elif name == "image_idx": - self._arguments["image_idx"] = str(value) - elif name == "image_size": - self._arguments["image_size"] = str(value) - elif name == "step": - self._arguments["image_size"] = str(value) + full_args = dict(zip(arg_names[1:], args[1:])) + full_args.update(kwargs) + full_args.update(get_default_args(func)) + + for name, value in full_args.items(): + if name == "epoch": + self._arguments["epoch"] = str(value) + elif name == "image_idx": + self._arguments["image_idx"] = str(value) + elif name == "image_size": + self._arguments["image_size"] = str(value) + elif name == "step": + self._arguments["image_size"] = str(value) start = dftracer.get_instance().get_time() dftracer.get_instance().enter_event() @@ -261,6 +270,7 @@ def new_init(*args, **kwargs): if DFTRACER_ENABLE: arg_values = dict(zip(arg_names[1:], args)) arg_values.update(kwargs) + arg_values.update(get_default_args(init)) if "epoch" in arg_values: self._arguments["epoch"] = str(arg_values["epoch"]) elif "image_idx" in arg_values: diff --git a/docs/api.rst b/docs/api.rst index 8f50098d..6f764b38 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -56,23 +56,23 @@ ENV Variables supported ================================ ====== =========================================================================== Environment Variable Type Description ================================ ====== =========================================================================== - DFTRACER_CONFIGURATION STRING PATH to the yaml configuration - DFTRACER_ENABLE INT Enable or Disable DFTracer (default 0). - DFTRACER_INIT STRING DFTracer Mode FUNCTION/PRELOAD (default FUNCTION). - For Hybrid use PRELOAD mode. - DFTRACER_LOG_FILE STRING PATH To log file. In this case process id and app name is appended to file. - DFTRACER_DATA_DIR STRING Colon separated paths that will be traced for I/O accesses by profiler. - For tracing all directories use the string "all" (not recommended). - DFTRACER_INC_METADATA INT Include or exclude metadata (default 0) - DFTRACER_SET_CORE_AFFINITY INT Include or exclude core affinity (default 0). - DFTRACER_INC_METADATA needs to be enabled. - DFTRACER_GOTCHA_PRIORITY INT PRIORITY of DFTracer in GOTCHA (default: 1). - DFTRACER_LOG_LEVEL STRING Logging level within DFTracer ERROR/WARN/INFO/DEBUG (default ERROR). - DFTRACER_DISABLE_IO STRING Disable automatic binding of all I/O calls. - DFTRACER_DISABLE_POSIX STRING Disable automatic binding of POSIX I/O calls. - DFTRACER_DISABLE_STDIO STRING Disable automatic binding of STDIO I/O calls. - DFTRACER_TRACE_COMPRESSION INT Enable trace compression (default 1) - DFTRACER_DISABLE_TIDS INT Disable tracing of thread ids (default 0). + DFTRACER_CONFIGURATION STRING PATH to the yaml configuration + DFTRACER_ENABLE INT Enable or Disable DFTracer (default 0). + DFTRACER_INIT STRING DFTracer Mode FUNCTION/PRELOAD (default FUNCTION). + For Hybrid use PRELOAD mode. + DFTRACER_LOG_FILE STRING PATH To log file. In this case process id and app name is appended to file. + DFTRACER_DATA_DIR STRING Colon separated paths that will be traced for I/O accesses by profiler. + For tracing all directories use the string "all" (not recommended). + DFTRACER_INC_METADATA INT Include or exclude metadata (default 0) + DFTRACER_SET_CORE_AFFINITY INT Include or exclude core affinity (default 0). + DFTRACER_INC_METADATA needs to be enabled. + DFTRACER_GOTCHA_PRIORITY INT PRIORITY of DFTracer in GOTCHA (default: 1). + DFTRACER_LOG_LEVEL STRING Logging level within DFTracer ERROR/WARN/INFO/DEBUG (default ERROR). + DFTRACER_DISABLE_IO STRING Disable automatic binding of all I/O calls. + DFTRACER_DISABLE_POSIX STRING Disable automatic binding of POSIX I/O calls. + DFTRACER_DISABLE_STDIO STRING Disable automatic binding of STDIO I/O calls. + DFTRACER_TRACE_COMPRESSION INT Enable trace compression (default 1) + DFTRACER_DISABLE_TIDS INT Disable tracing of thread ids (default 0). ================================ ====== =========================================================================== ---------------------------------------- @@ -126,6 +126,7 @@ Function Profiling To profile a function, add the wrapper ``DFTRACER_CPP_FUNCTION`` at the start of the function .. code-block:: c + void foo() { DFTRACER_CPP_FUNCTION(); sleep(1); diff --git a/docs/bash_utilities.rst b/docs/bash_utilities.rst new file mode 100644 index 00000000..c5ec4edb --- /dev/null +++ b/docs/bash_utilities.rst @@ -0,0 +1,90 @@ +======================== +Bash Utility scripts +======================== + +This section describes the bash utilities that are compatible with DFTracer logs + +---------- + +------------------ +Handling .pfw files +------------------ + +The DFTracer format with extension .pfw is uncompressed file which can be viewed using the following utilities. + +1. `vim` : Edit .pfw files +2. `cat`, `head`, or `tail`: view portion of the pfw files + + +---------------------- +Handling .pfw.gz files +---------------------- + +The DFtracer compressed format with .pfw extension can be first decompressed using gzip and then piped to the above .pfw utilities. + +.. code-block:: bash + + gzip -c -d `echo *.gz` | head + +-------------------- +Extracting JSON data +-------------------- + +Once the uncompressed data is parsed. The JSON utility `jq` can be used to parse args. + +In each case we have to remove the first `[` which has been added to support perfetto ui. + +For uncompressed files +.. code-block:: bash + + cat *.pfw | grep -i "[^#[]" | jq -c '.' + + +For compressed files +.. code-block:: bash + + gzip -c -d `echo *.gz` | grep -i "[^#[]" | jq -c '.' + +We can extract specific fields from these JSON lines as follows + +1. `jq -c '.name'`: extracts all the names of events +2. `jq -c '.cat'`: extracts all the category of events +3. `jq -c '.args.hostname'`: extracts the fields from extra args like hostname in this case. + +Useful querying using jq +************************ + +Extract unique functions with their counts from traces. + +.. code-block:: bash + + cat *.pfw | grep -i "[^#[]" | jq -c '.name' | sort | uniq -c + +Extract unique categories with their counts from traces. + +.. code-block:: bash + + cat *.pfw | grep -i "[^#[]" | jq -c '.cat' | sort | uniq -c + +Extract unique process id and thread id combination with their counts from traces. + +.. code-block:: bash + + cat *.pfw | grep -i "[^#[]" | jq -c '"\(.pid) \(.tid)"' | sort | uniq -c + +Extract min timestamp + +.. code-block:: bash + + cat *.pfw | grep -i "[^#[]" | jq -c '.ts | tonumber' | sort -n | tail -1 + +Extract max timestamp + +.. code-block:: bash + + cat *.pfw | grep -i "[^#[]" | jq -c '.ts | tonumber' | sort -n | tail -n 1 + + +For more commands on `jq` refer to `JQ Manual +`_. + diff --git a/docs/build.rst b/docs/build.rst index f70256fe..8840ef43 100644 --- a/docs/build.rst +++ b/docs/build.rst @@ -36,7 +36,7 @@ From Github .. code-block:: Bash - DFT_VERSION=v1.0.2 + DFT_VERSION=v1.0.3 pip install git+https://github.com/hariharan-devarajan/dftracer.git@${DFT_VERSION} .. attention:: diff --git a/docs/conf.py b/docs/conf.py index ded7eddf..caf4c0a3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ # The short X.Y version version = u'0.0' # The full version, including alpha/beta/rc tags -release = u'1.0.2' +release = u'1.0.3' # -- General configuration --------------------------------------------------- diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst index e69de29b..0e270238 100644 --- a/docs/developer-guide.rst +++ b/docs/developer-guide.rst @@ -0,0 +1,69 @@ +====================== +Developer Guide +====================== + +------------------------------------------ +ALCF Polaris +------------------------------------------ + +These are steps that are needed to compile :code:`dftracer` on `ALCF Polaris `_ + +First, make sure you have set up the environment variable and source it as shown `here `_. Then, you can modify the :code:`dftracer` codebase and compile the codebase by running commands below: + +.. code-block:: bash + + module use /soft/modulefiles + module load conda + module unload darshan + conda activate base + source + + export CC=cc + export CXX=CC + export CMAKE_BUILD_TYPE=PROFILE + export DFTRACER_ENABLE_TESTS=On + export DFTRACER_LOGGER_USER=1 + export DFTRACER_DISABLE_HWLOC=On + export DFTRACER_TEST_LD_LIBRARY_PATH=/opt/cray/libfabric/1.15.2.0/lib64 + pip install -v ".[dfanalyzer]" + +.. note:: + + We need to disable :code:`darshan` here because it will give you a lot of :code:`segfault` on Polaris machine due to POSIX API interceptor done by Darshan + +Then, to run the the test, you need to run commands below: + +.. code-block:: bash + + module use /soft/modulefiles + module load conda + module unload darshan + conda activate base + source + + pip install -r test/py/requirements.txt + pushd build/temp*/*pydftracer*/ + ctest -E dlio -VV --debug --stop-on-failure + popd + + +Updating Docs +============= + +For updating the docs we need to install additional dependency :code:`Sphinx` + +.. code-block:: bash + + module use /soft/modulefiles + module load conda + module unload darshan + conda activate base + source + + pip install "Sphinx<7" + + cd /docs + make html + + +Then open :code:`_build/html/index.html` diff --git a/docs/dfanalyzer_alcf_polaris.rst b/docs/dfanalyzer_alcf_polaris.rst new file mode 100644 index 00000000..eaac7f8f --- /dev/null +++ b/docs/dfanalyzer_alcf_polaris.rst @@ -0,0 +1,187 @@ +=========================== +ALCF Polaris +=========================== + +This section describes how to run DFAnalyzer on `ALCF Polaris `_. + +---------- + +Make sure you already did the necessary steps to build the :code:`dfanalyzer` :doc:`here `. + +.. warning:: + + All the steps below should be run in the Polaris login node! + +---------------------------------------- +Logging in to Polaris Login Node +---------------------------------------- + +.. code-block:: bash + + ssh @polaris.alcf.anl.gov # and type password from MobilePass/other auth + +.. note:: + + We recommend you to use VSCode to connect to the Polaris login node as it supports opening Jupyter Notebook and do port forwarding natively + +---------------------------------------- +Initializing Dask Configurations +---------------------------------------- + +.. code-block:: bash + + cd /dfanalyzer/dask/conf + ./install_dask_env.sh + +.. note:: + + This will create new directory :code:`$HOME/.dftracer/` with files: :code:`$HOME/.dftracer/configuration.sh` and :code:`$HOME/.dftracer/configuration.yaml` + +---------------------------------------- +Changing :code:`$HOME/.dftracer/configuration.yaml` +---------------------------------------- + +.. code-block:: bash + + cd $HOME/.dftracer + configuration.yaml + +By default, :code:`$HOME/.dftracer/configuration.yaml` will contain this entry + +.. code-block:: yaml + + app: /usr/WS2/haridev/dftracer + env: ${DFTRACER_APP}/venv + +Please modify the :code:`app` your cloned :code:`` directory and :code:`env` to Python virtual environment that you used to install :code:`dfanalyzer` code :doc:`here `. + +Specifically, for ALCF Polaris, we should add one more entry to :code:`$HOME/.dftracer/configuration.yaml` + +.. code-block:: yaml + + account: + +.. note:: + + This account will be used to reserve compute node for Dask distributed workers + +---------------------------------------- +Changing :code:`polaris.yaml` config +---------------------------------------- + +.. code-block:: bash + + cd /dfanalyzer/dask/conf + polaris.yaml + +.. note:: + + Please change the :code:`polaris.yaml` configuration accordingly based on your needs. For example, if you need more nodes, you can change :code:`num_nodes` under :code:`job` key or maybe change :code:`wall_time_min`, etc. For more information regarding ALCF Polaris queue, please look here at `Running Jobs on Polaris `_ + + +---------------------------------------- +Executing scheduler +---------------------------------------- + +.. code-block:: bash + + cd /dfanalyzer/dask/scripts + ./start_dask_distributed.sh + +.. note:: + + Wait for several seconds because this script will try to reserve the compute nodes for you using PBS Job Scheduler + +.. warning:: + + If you got error with message "port" is used, you may try changing the port in :code:`` + +If it runs successfully, you should message below + +.. image:: images/dfanalyzer/polaris/run-scheduler.png + :width: 800 + :alt: Running Dask Scheduler on ALCF Polaris + +.. note:: + + Please check the file `/dfanalyzer/dask/logs/worker_.log` in case there are some problems when running the workers on compute node + +---------------------------------------- +Forwarding the Port +---------------------------------------- + +We recommend you running notebook inside VSCode because it supports port forwarding natively. In the VSCode, navigate to the bottom bar (where the terminal is). Now, click on the :code:`PORTS` tab as you can see in below screenshot + +.. image:: images/dfanalyzer/polaris/vscode-ports-tab.png + :width: 800 + :alt: VSCode Ports Tab + +--------- + +Then, click :code:`Add Port` below + +.. image:: images/dfanalyzer/polaris/vscode-add-port-button.png + :width: 800 + :alt: VSCode Add Port Button + +to add new port and type :code:`8787` since that port is used as :code:`Dask` monitoring webpage. If you type it correctly, you should show the port is added as new entry + +.. image:: images/dfanalyzer/polaris/vscode-added-port.png + :width: 800 + :alt: VSCode Added Port + +--------- + +Now, try connecting to `http://localhost:8787 `_ and, voila, you will see the :code:`Dask` scheduler monitoring! + +.. image:: images/dfanalyzer/polaris/dask-scheduler-monitoring.png + :width: 800 + :alt: Dask Scheduler Monitoring + +---------------------------------------- +Opening Notebook File +---------------------------------------- + +In your VSCode, navigate to + +.. code-block:: bash + + /examples/dfanalyzer/dfanalyzer-distributed.ipynb + +And just run each cells as usual. + +.. note:: + + Please use this as the starting point to analyze your traces. Feel free to copy and adjust it if needed! + +---------------------------------------- +Stopping Dask Distributed Workers +---------------------------------------- + +.. code-block:: bash + + cd /dfanalyzer/dask/scripts + ./stop_dask_distributed.sh + +.. note:: + + Wait for several seconds because this script will try to kill the workers and deallocate the compute nodes + +---------------------------------------- +Tips and Tricks +---------------------------------------- + +#. Add additional scripts to be executed in compute node + + Sometimes we need to execute scripts before executing worker, e.g. setup additional environment variables such as adding :code:`LD_LIBRARY_PATH` or other variables. + For this purpose, :code:`dftracer` supports this by editing :code:`$HOME/.dftracer/configuration.sh`. + + .. code-block:: bash + + $HOME/.dftracer/configuration.sh + # + # add new line at the end of the file + # e.g. + # export LD_LIBRARY_PATH=/opt/cray/libfabric/1.15.2.0/lib64:${LD_LIBRARY_PATH} + + diff --git a/docs/dfanalyzer_build.rst b/docs/dfanalyzer_build.rst new file mode 100644 index 00000000..ea4813e1 --- /dev/null +++ b/docs/dfanalyzer_build.rst @@ -0,0 +1,37 @@ +=========================== +Build +=========================== + +------------------------------------------ +From source (Recommended) +------------------------------------------ + +.. code-block:: Bash + + git clone git@github.com:hariharan-devarajan/dftracer.git + cd dftracer + pip install ".[dfanalyzer]" + +------------------------------------------ +From pip +------------------------------------------ + +.. code-block:: Bash + + pip install pydftracer[dfanalyzer] + +=============================== +Getting Started with DFAnalyzer +=============================== + +The most user-friendly way to utilize DFAnalyzer to analyze traces from DFTracer is to use Jupyter Notebooks. +To run the notebook you will have to install Jupyter. We have a simple requirement.txt file for that as well. + + +.. code-block:: Bash + + cd dftracer + pip install -r examples/dfanalyzer/requirements.txt + + +A simple example of loading DFAnalyzer and quick recommended queries are available on Navigate to :code:`/examples/dfanalyzer/dfanalyzer_distributed.ipynb` and run your notebook. \ No newline at end of file diff --git a/docs/dfanalyzer_conf.rst b/docs/dfanalyzer_conf.rst new file mode 100644 index 00000000..b256ba5e --- /dev/null +++ b/docs/dfanalyzer_conf.rst @@ -0,0 +1,107 @@ +====================================== +Running Dask Distributed in a new system +====================================== + +This section describes how to configure DFAnalyzer to run on your cluster. + +---------- + +Make sure you have already completed the necessary steps to build the :code:`dfanalyzer`. See the :doc:`build` documentation for details. + +---------------------------------------- +Initializing Dask Configurations +---------------------------------------- + +.. code-block:: bash + + cd /dfanalyzer/dask/conf + ./install_dask_env.sh + +.. note:: + + This will create a new directory :code:`$HOME/.dftracer/` with files: :code:`$HOME/.dftracer/configuration.sh` and :code:`$HOME/.dftracer/configuration.yaml` + +---------------------------------------- +Editing :code:`$HOME/.dftracer/configuration.yaml` +---------------------------------------- + +.. code-block:: bash + + cd $HOME/.dftracer + configuration.yaml + +By default, :code:`$HOME/.dftracer/configuration.yaml` will contain this entry: + +.. code-block:: yaml + + app: /usr/WS2/haridev/dftracer + env: ${DFTRACER_APP}/venv + +Please modify the :code:`app` to your cloned :code:`` directory and :code:`env` to the Python virtual environment that you used to install the :code:`dfanalyzer` code. Refer to the :doc:`build` documentation for details. + +---------------------------------------- +Editing Dask Configurations depending on your System +---------------------------------------- + +In the `/dfanalyzer/dask/conf/` folder create a new `.yaml` file for the system you want to use. The `.yaml` file should consist of the following fields: + +- config: this fiels contains locations for the directories containing files for the dask distributed cluster. + - script_dir: the scripts to run dask distributed + - conf_dir: the `.yaml` configuration files + - run_dir: the folder which will contain the :code:`scheduler_{$USER}.pid` and :code:`scheduler_{$USER}.json` file used to store information for the scheduler. + - log_dir: the folder which will contain the logs for the dask distributed scheduler and workers. +- job: information about the job you want to run to create the dask distributed cluster. + - num_nodes: number of nodes which are going to be used to run the dask distributed cluster. + - wall_time_min: time (in minutes) which the dask distributed cluster is going to run for. + - env_id: the name of the job which will run. + - queue: the queue which the job will run for. +- scheduler: information used to run the scheduler of the dask distributed cluster. + - cmd: command used to run the scheduler. Depending on the system you are using you might need to use FLUX, SLURM or other scheduler. + Examples can look like this: :code:`srun -N ${DFTRACER_JOB_NUM_NODES} -t ${DFTRACER_JOB_WALL_TIME_MIN}` for SLURM scheduler or :code:`flux run -N ${DFTRACER_JOB_NUM_NODES} -t ${DFTRACER_JOB_WALL_TIME_MIN}` for FLUX scheduler. + - port: :code:``` used to run dask distributed. + - kill: command used to kill the cluster. + Examples can look like this: :code:`scancel ${SLURM_JOB_ID}` for SLURM scheduler or `flux cancel --all` for FLUX scheduler. +- worker: information used to run the workers of the dask distributed cluster. + - ppn: processes per node for the dask distributed cluster. + - cmd: command used to run the worker. Depending on the system you are using you might need to use FLUX, SLURM or other scheduler. + Examples can look like this: :code:`srun -N ${DFTRACER_JOB_NUM_NODES} --ntasks-per-node=${DFTRACER_WORKER_PPN}` for SLURM scheduler or :code:`srun -N ${DFTRACER_JOB_NUM_NODES} --ntasks-per-node=${DFTRACER_WORKER_PPN}` for FLUX scheduler. + - per_core: number of processes per code + - threads: number of threads used. + - local_dir: a location for a local directory used from dask to cache data frames. It can be set to local storage or shared memory. + - kill: command used to kill the cluster. + Examples can look like this: :code:`scancel ${SLURM_JOB_ID}` for SLURM scheduler or :code:`flux cancel --all` for FLUX scheduler. + +.. code-block:: bash + + cd /dfanalyzer/dask/conf + .yaml + +Bellow is an example of a `.yaml` taht can used for LC Ruby: + +.. code-block:: bash + config: + script_dir: ${DFTRACER_APP}/dfanalyzer/dask/scripts + conf_dir: ${DFTRACER_APP}/dfanalyzer/dask/conf + run_dir: ${DFTRACER_APP}/dfanalyzer/dask/run_dir + log_dir: ${DFTRACER_APP}/dfanalyzer/dask/logs + job: + num_nodes: 1 + wall_time_min: 60 + env_id: SLURM_JOB_ID + worker: + ppn: 16 + cmd: srun -N ${DFTRACER_JOB_NUM_NODES} -t ${DFTRACER_JOB_WALL_TIME_MIN} + per_core: 1 + threads: 1 + local_dir: /dev/shm/dask-workspace + kill: scancel ${SLURM_JOB_ID} + scheduler: + cmd: srun -N ${DFTRACER_JOB_NUM_NODES} -t ${DFTRACER_JOB_WALL_TIME_MIN} --ntasks-per-node=${DFTRACER_WORKER_PPN} + port: 12001 + kill: scancel ${SLURM_JOB_ID} + +---------------------------------------- +Run DFAnalyzer +---------------------------------------- + +Navigate to :code:`/examples/dfanalyzer/dfanalyzer_distributed.ipynb` and run your notebook. diff --git a/docs/dfanalyzer_distributed.rst b/docs/dfanalyzer_distributed.rst new file mode 100644 index 00000000..b7cf7dc9 --- /dev/null +++ b/docs/dfanalyzer_distributed.rst @@ -0,0 +1,87 @@ +=================================== +Running DFAnalyzer with Dask Distributed +=================================== + +----------------------------------- +Getting Started +----------------------------------- + +1. Create a Python virtual environment (Python version>3.7). +2. Source the Python virtual environment. +3. Git clone the GitHub repo to get the source code of DFTracer. +4. Navigate into :code:`/path/to/dftracer/dfanalyzer/examples/dfanalyzer`. +5. Build DFTracer as recommended in :doc:`build`. +6. Get all of the requirements as follows in the terminal: + +.. code-block:: bash + + pip install -r requirements.txt + +7. Create a `.yaml` file in :code:`/path/to/dftracer/dfanalyzer/dask/conf` if this is a new system. Please refer to :doc:`dfanalyzer_conf`. + +----------------------------------- +Starting a Dask Distributed Cluster +----------------------------------- + +In the terminal: + +.. code-block:: bash + + cd /path/to/dftracer/dfanalyzer/dask/conf + ./install_dask_env.sh + +This will create the `configuration.yaml` in :code:`~/.dftracer`. Update the application and environment path in `configuration.yaml`. You may need to create `run_dir` and `logs` folders if they aren't there already. + +.. code-block:: bash + + cd /path/to/dftracer/dfanalyzer/dask/ + # if logs folder is not present + mkdir logs + # if run_dir is not present + mkdir run_dir + install + ./scripts/start_dask_distributed.sh + +.. note:: + + Wait for several seconds as this script will reserve the compute nodes for you using the job scheduler. + +.. note:: + + Please check the log file :code:`/path/to/dftracer/dfanalyzer/dask/logs/worker_.log` for any issues with running the workers on the compute nodes. + +.. warning:: + + For errors related to port usage, please check if you already have any Dask distributed instances running. You can do so by checking the jobs already running in your scheduler queue or by running the following command in the terminal: + + .. code-block:: bash + + ps -aef | grep dask + + Then kill those jobs/processes using :code:`kill -9 `. You may also need to change the port number in the `.yaml` files located at `/path/to/dftracer/dfanalyzer/dask/conf`. For more details about these configurations refer to :doc:`here `. + + +----------------------------------- +Use DFAnalyzer +----------------------------------- + +To use the Jupyter notebook of DFAnalyzer, navigate to :code:`/path/to/dftracer/examples` and find the `dfanalyzer_distributed.ipynb`. + +---------------------------------------- +Acessing the Dask Dashboard +---------------------------------------- + +It is recommended to run the notebook inside VSCode because it supports port forwarding natively. In VSCode, navigate to the bottom bar (where the terminal is), and click on the :code:`PORTS` tab. Click :code:`Forward Port` to add a new port and type the port that was used when :code:`setup_dask_cluster()` was run in your `dfanalyzer.ipynb` notebook. Connect to `http://localhost:PORT `_ to see the :code:`Dask` scheduler monitoring. + +---------------------------------------- +Stopping Dask Distributed Workers +---------------------------------------- + +.. code-block:: bash + + cd /path/to/dftracer/dfanalyzer/dask/scripts + ./stop_dask_distributed.sh + +.. note:: + + Wait for several seconds as this script will terminate the workers and deallocate the compute nodes. diff --git a/docs/examples.rst b/docs/examples.rst index a94d98cc..afafa7d4 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -1,10 +1,6 @@ ================ Example Programs -================ - - ------------ - +================` ------------ C++ Example diff --git a/docs/images/dfanalyzer/polaris/dask-scheduler-monitoring.png b/docs/images/dfanalyzer/polaris/dask-scheduler-monitoring.png new file mode 100644 index 00000000..7310ddcc Binary files /dev/null and b/docs/images/dfanalyzer/polaris/dask-scheduler-monitoring.png differ diff --git a/docs/images/dfanalyzer/polaris/run-scheduler.png b/docs/images/dfanalyzer/polaris/run-scheduler.png new file mode 100644 index 00000000..0aa09460 Binary files /dev/null and b/docs/images/dfanalyzer/polaris/run-scheduler.png differ diff --git a/docs/images/dfanalyzer/polaris/vscode-add-port-button.png b/docs/images/dfanalyzer/polaris/vscode-add-port-button.png new file mode 100644 index 00000000..dad8ce27 Binary files /dev/null and b/docs/images/dfanalyzer/polaris/vscode-add-port-button.png differ diff --git a/docs/images/dfanalyzer/polaris/vscode-added-port.png b/docs/images/dfanalyzer/polaris/vscode-added-port.png new file mode 100644 index 00000000..83977c8d Binary files /dev/null and b/docs/images/dfanalyzer/polaris/vscode-added-port.png differ diff --git a/docs/images/dfanalyzer/polaris/vscode-ports-tab.png b/docs/images/dfanalyzer/polaris/vscode-ports-tab.png new file mode 100644 index 00000000..668b4b80 Binary files /dev/null and b/docs/images/dfanalyzer/polaris/vscode-ports-tab.png differ diff --git a/docs/images/tracing/1000genome.png b/docs/images/tracing/1000genome.png new file mode 100644 index 00000000..3bf4b560 Binary files /dev/null and b/docs/images/tracing/1000genome.png differ diff --git a/docs/images/tracing/Montage_dur.png b/docs/images/tracing/Montage_dur.png new file mode 100644 index 00000000..8970d962 Binary files /dev/null and b/docs/images/tracing/Montage_dur.png differ diff --git a/docs/images/tracing/Montage_graph.png b/docs/images/tracing/Montage_graph.png new file mode 100644 index 00000000..a8299012 Binary files /dev/null and b/docs/images/tracing/Montage_graph.png differ diff --git a/docs/images/tracing/Montage_summary.png b/docs/images/tracing/Montage_summary.png new file mode 100644 index 00000000..cd014e2a Binary files /dev/null and b/docs/images/tracing/Montage_summary.png differ diff --git a/docs/index.rst b/docs/index.rst index 5a9bde2f..9e457141 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,11 +18,35 @@ DFTracer: is a library for profiling I/O calls and application functions. building_applications api +.. toctree:: + :maxdepth: 2 + :caption: DFAnalyzer + + dfanalyzer_build + dfanalyzer_distributed + dfanalyzer_conf + dfanalyzer_alcf_polaris + +.. toctree:: + :maxdepth: 2 + :caption: Utilities + + utilities + bash_utilities + .. toctree:: :maxdepth: 2 :caption: Reference examples + migration + +.. toctree:: + :maxdepth: 2 + :caption: Applications + + pegasus_montage + pegasus_genome .. toctree:: :maxdepth: 2 diff --git a/docs/migration.rst b/docs/migration.rst new file mode 100644 index 00000000..eaab9d26 --- /dev/null +++ b/docs/migration.rst @@ -0,0 +1,473 @@ +================================================ +Migration from DLIO Profiler to DFTracer +================================================ + +This section provides information to DLIO Profiler users on how to migrate their work from DLIO profiler to DFTracer. + +------------------------------------------------ +Installation +------------------------------------------------ + +------------------------------------------------ +Application building migration +------------------------------------------------ +To migrate your Makefile projects from using DLIO Profiler to DFTracer, you will need to update your compilation flags, specifically `CFLAGS` or `CXXFLAGS`, and `LDFLAGS`. +Replace the DLIO Profiler flags with DFTracer flags as shown below: + +.. code-block:: make + :linenos: + :caption: Modifying Makefile to use DFTracer + + # DLIO Profiler Flags (old) + DLIO_CFLAGS = -I/usr/workspace/iopp/kogiou1/venvs/pegasus-env/lib/python3.9/site-packages/dlio_profiler/include + DLIO_LDFLAGS = -L/usr/workspace/iopp/kogiou1/venvs/pegasus-env/lib/python3.9/site-packages/dlio_profiler/lib64 -ldlio_profiler + CFLAGS += $(DLIO_CFLAGS) + LIBS += $(DLIO_LDFLAGS) + + # Replace with DFTracer Flags (new) + # Add DFTracer include and library paths + DFTRACER_CFLAGS = -I/path/to/dftracer/include + DFTRACER_LDFLAGS = -L/path/to/dftracer/lib64 -ldftracer + + # Append to existing CFLAGS and LDFLAGS + CFLAGS += $(DFTRACER_CFLAGS) + LDFLAGS += $(DFTRACER_LDFLAGS) + +------------------------------------------------ +C++ API Changes +------------------------------------------------ + +This section guides you through the necessary changes to migrate your application-level tracing for C++ projects from DLIO Profiler to DFTracer. The transition requires updating API names and includes directives to use the DFTracer's new API. +Please see `examples.rst` for more information on how to use DFTracer APIs. + +Updating Includes +--------------------- + +Replace the old DLIO Profiler include header with the new DFTracer header. This change points your application to the new tracing API. + +.. code-block:: cpp + :linenos: + + // Old include + #include + + // Replace with new include + #include + +Initializing +------------------------ + +Initialization now uses the DFTracer API, which can seamlessly integrate into your existing codebase where DLIO Profiler was previously initialized. + +.. code-block:: cpp + :linenos: + + // Old initialization + DLIO_PROFILER_CPP_INIT(log_file, data_dirs, process_id); + + // Replace with new initialization + DFTRACER_CPP_INIT(log_file, data_dirs, process_id); + +This will configure the DFTracer environment, setting up the log file, data directories, and process ID exactly like the DLIO Profiler did. +To migrate these configurations from DLIO Profile to DFTracer please replace your old enviromental variable configurations as shown bellow. + +.. code-block:: bash + :linenos: + # Old environment variable configurations for DLIO Profiler + DLIO_LOG_FILE=~/dlio_log + DLIO_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset + export DLIO_INIT=PRELOAD + export DLIO_ENABLE=1 + + +.. code-block:: bash + :linenos: + # Updated environment variable configurations for DFTracer + DFTRACER_LOG_FILE=~/log_file # Changes the log file path variable name + DFTRACER_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset # Consistent data directory path + export DFTRACER_INIT=PRELOAD # Standardizing to PRELOAD mode + export DFTRACER_ENABLE=1 # Enabling the profiler + + +Finalizing +---------------------- + +The finalization process ensures that all tracing data are correctly finalized and saved. Replace the DLIO Profiler finalization call with the DFTracer finalization. + +.. code-block:: cpp + :linenos: + + // Old finalization + DLIO_PROFILER_CPP_FINI(); + + // Replace with new finalization + DFTRACER_CPP_FINI(); + +This function call is crucial for ensuring that your profiling data is not corrupted and is properly written to the log file. + +Function and Region Profiling +----------------------------------- + +For function and code block profiling, replace the old DLIO Profiler functions with their DFTracer counterparts. + +.. code-block:: cpp + :linenos: + + // Old function and region profiling + DLIO_PROFILER_CPP_FUNCTION(); + DLIO_PROFILER_CPP_REGION_(CUSTOM); + + // Replace with new function and region profiling + DFTRACER_CPP_FUNCTION(); + DFTRACER_CPP_REGION_(CUSTOM); + + +------------------------------------------------ +C API Changes +------------------------------------------------ + +This section guides you through the necessary changes to migrate your application-level tracing for C projects from DLIO Profiler to DFTracer. The transition requires updating API names and includes directives to use the DFTracer's new API. +Please see `examples.rst` for more information on how to use DFTracer APIs. + +Updating Includes +--------------------- + +To transition your C projects to DFTracer, begin by updating the include directive to point to the new DFTracer API. + +.. code-block:: c + :linenos: + + // Old include + #include + + // Replace with new include + #include + +Initializing +------------------------ + +For C applications, DFTracer initialization replaces the older DLIO Profiler calls. + +.. code-block:: c + :linenos: + + // Old initialization + DLIO_PROFILER_C_INIT(log_file, data_dirs, process_id); + + // Replace with new initialization + DFTRACER_C_INIT(log_file, data_dirs, process_id); + +This command configures DFTracer with the necessary parameters for logging and directory monitoring, similarly to how DLIO Profiler was configured. +To migrate these configurations from DLIO Profile to DFTracer please replace your old enviromental variable configurations as shown bellow. + +.. code-block:: bash + :linenos: + + # Old environment variable configurations for DLIO Profiler + DLIO_LOG_FILE=~/dlio_log + DLIO_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset + export DLIO_INIT=PRELOAD + export DLIO_ENABLE=1 + + +.. code-block:: bash + :linenos: + + # Updated environment variable configurations for DFTracer + DFTRACER_LOG_FILE=~/log_file # Changes the log file path variable name + DFTRACER_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset # Consistent data directory path + export DFTRACER_INIT=PRELOAD # Standardizing to PRELOAD mode + export DFTRACER_ENABLE=1 # Enabling the profiler + + +Finalizing +---------------------- + +Finalize the DFTracer setup to ensure all tracing data are correctly captured and saved. + +.. code-block:: c + :linenos: + + // Old finalization + DLIO_PROFILER_C_FINI(); + + // Replace with new finalization + DFTRACER_C_FINI(); + + +Function and Region Profiling +----------------------------------- + +Transition function and region profiling in your C code to use DFTracer's updated API methods. + +.. code-block:: c + :linenos: + + // Old function and region profiling + DLIO_PROFILER_C_FUNCTION_START(); + DLIO_PROFILER_C_FUNCTION_END(); + + // Replace with new function and region profiling + DFTRACER_C_FUNCTION_START(); + DFTRACER_C_FUNCTION_END(); + + +------------------------------------------------ +Python API changes +------------------------------------------------ + +------------------------------------------------ +Application building migration +------------------------------------------------ +To migrate your Makefile projects from using DLIO Profiler to DFTracer, you will need to update your compilation flags, specifically `CFLAGS` or `CXXFLAGS`, and `LDFLAGS`. +Replace the DLIO Profiler flags with DFTracer flags as shown below: + +.. code-block:: make + :linenos: + :caption: Modifying Makefile to use DFTracer + + # DLIO Profiler Flags (old) + DLIO_CFLAGS = -I/usr/workspace/iopp/kogiou1/venvs/pegasus-env/lib/python3.9/site-packages/dlio_profiler/include + DLIO_LDFLAGS = -L/usr/workspace/iopp/kogiou1/venvs/pegasus-env/lib/python3.9/site-packages/dlio_profiler/lib64 -ldlio_profiler + CFLAGS += $(DLIO_CFLAGS) + LIBS += $(DLIO_LDFLAGS) + + # Replace with DFTracer Flags (new) + # Add DFTracer include and library paths + DFTRACER_CFLAGS = -I/path/to/dftracer/include + DFTRACER_LDFLAGS = -L/path/to/dftracer/lib64 -ldftracer + + # Append to existing CFLAGS and LDFLAGS + CFLAGS += $(DFTRACER_CFLAGS) + LDFLAGS += $(DFTRACER_LDFLAGS) + +------------------------------------------------ +C++ API Changes +------------------------------------------------ + +This section guides you through the necessary changes to migrate your application-level tracing for C++ projects from DLIO Profiler to DFTracer. The transition requires updating API names and includes directives to use the DFTracer's new API. +Please see `examples.rst` for more information on how to use DFTracer APIs. + +Updating Includes +--------------------- + +Replace the old DLIO Profiler include header with the new DFTracer header. This change points your application to the new tracing API. + +.. code-block:: cpp + :linenos: + + // Old include + #include + + // Replace with new include + #include + +Initializing +------------------------ + +Initialization now uses the DFTracer API, which can seamlessly integrate into your existing codebase where DLIO Profiler was previously initialized. + +.. code-block:: cpp + :linenos: + + // Old initialization + DLIO_PROFILER_CPP_INIT(log_file, data_dirs, process_id); + + // Replace with new initialization + DFTRACER_CPP_INIT(log_file, data_dirs, process_id); + +This will configure the DFTracer environment, setting up the log file, data directories, and process ID exactly like the DLIO Profiler did. +To migrate these configurations from DLIO Profile to DFTracer please replace your old enviromental variable configurations as shown bellow. + + +.. code-block:: bash + :linenos: + + # Old environment variable configurations for DLIO Profiler + DLIO_LOG_FILE=~/dlio_log + DLIO_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset + export DLIO_INIT=PRELOAD + export DLIO_ENABLE=1 + + +.. code-block:: bash + :linenos: + + # Updated environment variable configurations for DFTracer + DFTRACER_LOG_FILE=~/log_file # Changes the log file path variable name + DFTRACER_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset # Consistent data directory path + export DFTRACER_INIT=PRELOAD # Standardizing to PRELOAD mode + export DFTRACER_ENABLE=1 # Enabling the profiler + + +Finalizing +---------------------- + +The finalization process ensures that all tracing data are correctly finalized and saved. Replace the DLIO Profiler finalization call with the DFTracer finalization. + +.. code-block:: cpp + :linenos: + + // Old finalization + DLIO_PROFILER_CPP_FINI(); + + // Replace with new finalization + DFTRACER_CPP_FINI(); + +This function call is crucial for ensuring that your profiling data is not corrupted and is properly written to the log file. + +Function and Region Profiling +----------------------------------- + +For function and code block profiling, replace the old DLIO Profiler functions with their DFTracer counterparts. + +.. code-block:: cpp + :linenos: + + // Old function and region profiling + DLIO_PROFILER_CPP_FUNCTION(); + DLIO_PROFILER_CPP_REGION_(CUSTOM); + + // Replace with new function and region profiling + DFTRACER_CPP_FUNCTION(); + DFTRACER_CPP_REGION_(CUSTOM); + + +------------------------------------------------ +C API Changes +------------------------------------------------ + +This section guides you through the necessary changes to migrate your application-level tracing for C projects from DLIO Profiler to DFTracer. The transition requires updating API names and includes directives to use the DFTracer's new API. +Please see `examples.rst` for more information on how to use DFTracer APIs. + +Updating Includes +--------------------- + +To transition your C projects to DFTracer, begin by updating the include directive to point to the new DFTracer API. + +.. code-block:: c + :linenos: + + // Old include + #include + + // Replace with new include + #include + +Initializing +------------------------ + +For C applications, DFTracer initialization replaces the older DLIO Profiler calls. + +.. code-block:: c + :linenos: + + // Old initialization + DLIO_PROFILER_C_INIT(log_file, data_dirs, process_id); + + // Replace with new initialization + DFTRACER_C_INIT(log_file, data_dirs, process_id); + +This command configures DFTracer with the necessary parameters for logging and directory monitoring, similarly to how DLIO Profiler was configured. +To migrate these configurations from DLIO Profile to DFTracer please replace your old enviromental variable configurations as shown bellow. + +.. code-block:: bash + :linenos: + + # Old environment variable configurations for DLIO Profiler + DLIO_LOG_FILE=~/dlio_log + DLIO_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset + export DLIO_INIT=PRELOAD + export DLIO_ENABLE=1 + + +.. code-block:: bash + :linenos: + + # Updated environment variable configurations for DFTracer + DFTRACER_LOG_FILE=~/log_file # Changes the log file path variable name + DFTRACER_DATA_DIR=/dev/shm/:/p/gpfs1/$USER/dataset # Consistent data directory path + export DFTRACER_INIT=PRELOAD # Standardizing to PRELOAD mode + export DFTRACER_ENABLE=1 # Enabling the profiler + + +Finalizing +---------------------- + +Finalize the DFTracer setup to ensure all tracing data are correctly captured and saved. + +.. code-block:: c + :linenos: + + // Old finalization + DLIO_PROFILER_C_FINI(); + + // Replace with new finalization + DFTRACER_C_FINI(); + + +Function and Region Profiling +----------------------------------- + +Transition function and region profiling in your C code to use DFTracer's updated API methods. + +.. code-block:: c + :linenos: + + // Old function and region profiling + DLIO_PROFILER_C_FUNCTION_START(); + DLIO_PROFILER_C_FUNCTION_END(); + + // Replace with new function and region profiling + DFTRACER_C_FUNCTION_START(); + DFTRACER_C_FUNCTION_END(); + + +------------------------------------------------ +Python API changes +------------------------------------------------ + + +------------------------------------------------ +Analyzer Changes +------------------------------------------------ + +Migration of the DLP Analyzer jupyter notebook to DFAnalyzer involves configuring the YAML for Dask and renaming the imports and function calls in jupyter notebook cells. + + +Dask Configuration: +************************** + + +1. ``cd`` to ``dftracer/dfanalyzer/dask/conf`` and run ``install_dask_env.sh`` to create configuration.yaml in ``~/.dftracer``. +2. update the app and environment path in ``configuration.yaml``. + +Jupyter Notebook Update: +************************** + + +1. update ``app_root`` variable by updating path of new ``configuration.yaml``. +2. replace ``dlp_analyzer`` with ``dfanalyzer`` and update the imports form ``dfanalyzer.main`` + +.. code-block:: python + :linenos: + + ... + import dfanalyzer + from dfanalyzer.main import DFAnalyzer,get_dft_configuration,update_dft_configuration,setup_logging,setup_dask_cluster, reset_dask_cluster, get_dft_configuration + ... + +3. update the ``dask_run_dir`` to use dfanalyzer instead of dlp_analyzer. +4. rename update and get configuration functions by calling DFtracer equivalent functions. + +.. code-block:: python + :linenos: + + ... + conf = update_dft_configuration(dask_scheduler=dask_scheduler, verbose=True, + log_file=f"./dft_{os.getenv('USER')}.log", rebuild_index=False, time_approximate=False, + host_pattern=r'lassen(\d+)', time_granularity=30e6, skip_hostname=True, conditions=condition_fn) + conf = get_dft_configuration() + ... + + diff --git a/docs/pegasus_genome.rst b/docs/pegasus_genome.rst new file mode 100644 index 00000000..fdec3031 --- /dev/null +++ b/docs/pegasus_genome.rst @@ -0,0 +1,197 @@ +=================================== +Pegasus 1000-Genome with DFTracer +=================================== + +Instructions for tracing Pegasus 1000 Genome with DFTracer on LC Corona. These instructions can be used for any Workflow but you'll need to change the version of the tar files depending on the architecture of your machine and the workflow you are interested in. +For more information, visit the `workflows repository `_. + +To follow this tutorial you will need the following requirements: +- Installed Condor. +- Installed Pegasus Workflow Manager. +- Python Virtual Environment with DFTracer installed. + +Please refer to :doc:`pegasus_montage` for completing these requirements. + +Step 1: Activate Environment +---------------------------- + +Source the Python Virtual Environmnet that has DFTracer. + +1.1 Create and activate Virtual Environment: + +.. code-block:: bash + + python3 -m venv /path/to/pegasus-env + source /path/to/pegasus-env/bin/activate + +1.2 Get the dependencies: + +.. code-block:: bash + + pip install git+https://github.com/hariharan-devarajan/dftracer.git + +Step 2: Get the 1000genome-workflow +----------------------------------- + +Get the code: + +.. code-block:: bash + + git clone https://github.com/pegasus-isi/1000genome-workflow.git + +Step 3: Prepare software for Pegasus-1000Genome +------------------------------------ + +3.1 Save to PATH: + +.. code-block:: bash + + export PATH=/path/to/pegasus/install/bin:$PATH + export PATH=/path/to/pegasus/install/sbin:$PATH + export LD_LIBRARY_PATH=/path/to/pegasus/install//lib:$LD_LIBRARY_PATH + source ~/.bashrc + +3.2 Run Condor: + +.. code-block:: bash + + chmod 777 /path/to/pegasus/install/condor.sh + . /path/to/pegasus/install/condor.sh + condor_master + condor_status # it should show the activity + condor_q # it should show the jobs running + +.. note:: + + If errors occur, echo the `LD_LIBRARY_PATH` and the `PATH` and make sure :code:`/pegasus/install` is there. + +To check if condor_shedd and all other condor processes are running: + +.. code-block:: bash + + ps aux | grep condor + +If Condor throws errors while trying to connect to another node: + +1. Exit the flux allocation: + +.. code-block:: bash + + exit + +2. Check your processes: + +.. code-block:: bash + + ps -u ${USER} + +3. Kill all your processes (or those related to Condor if any): + +.. code-block:: bash + + killall -u ${USER} + +4. Repeat steps 6.3, 6.4, 5.2, 6.5 + +5. If the problem persists: + +.. code-block:: bash + + condor_restart + +3.3 Test Pegasus: + +.. code-block:: bash + + pegasus-version # should show 5.0.7 + +.. note:: + +If error "Cannot find file with permissions" occurs, touch that file and make sure it has those permissions. + +3.4 Configure the Condor/SLURM interface: + +.. code-block:: bash + + pegasus-configure-glite + +.. note:: + + If error "Cannot find file with permissions" occurs, touch that file and make sure it has those permissions. + +3.5 Configure the DFTracer flags: + +.. code-block:: bash + + export DFTRACER_INSTALLED=/path/to/pegasus-env/lib/python3.9/site-packages/dftracer/ + export LD_LIBRARY_PATH=$DFTRACER_INSTALLED/lib:$DFTRACER_INSTALLED/lib64:$LD_LIBRARY_PATH + export DFTRACER_LOG_FILE=/path/to/traces/trace + # export DFTRACER_DATA_DIR=all (optional) + export DFTRACER_ENABLE=1 + export DFTRACER_INC_METADATA=1 + # export DFTRACER_INIT=PRELOAD (optional) + export DFTRACER_BIND_SIGNALS=0 + # export DFTRACER_LOG_LEVEL=ERROR (optional) + export DFTRACER_TRACE_COMPRESSION=1 + # dftracer=$DFTRACER_INSTALLED/lib64/libdftracer_preload.so (optional) + +You would only need to use the preload version of DFTracer if you have not annotated the application code you are running. +For more information on the flags and their functionalities please turn to :docs:`examples`. + +Step 4: Annotate 1000-Genome +--------------------------- + +4.1 Configure the DFTracer flags: + +.. code-block:: bash + + export DFTRACER_INSTALLED=/path/to/pegasus-env/lib/python3.9/site-packages/dftracer/ + export LD_LIBRARY_PATH=$DFTRACER_INSTALLED/lib:$DFTRACER_INSTALLED/lib64:$LD_LIBRARY_PATH + export DFTRACER_LOG_FILE=/path/to/traces/trace + # export DFTRACER_DATA_DIR=all (optional) + export DFTRACER_ENABLE=1 + export DFTRACER_INC_METADATA=1 + # export DFTRACER_INIT=PRELOAD (optional) + export DFTRACER_BIND_SIGNALS=0 + # export DFTRACER_LOG_LEVEL=ERROR (optional) + export DFTRACER_TRACE_COMPRESSION=1 + # dftracer=$DFTRACER_INSTALLED/lib64/libdftracer_preload.so (optional) + + +4.2 Navigate to the :code:`/path/to/1000genome-workflow` directory. The source code that is useful to annotate and "time" for Monatge is in the `/bin` folder. As an example we use the `frequency.py` application which is located in :code:`/path/to/1000genome-workflow/bin` folder. We annotate the code as follows: + +.. code-block:: python + + from dftracer.logger import dftracer, dft_fn + log_inst = dftracer.initialize_log(logfile=None, data_dir=None, process_id=-1) + + CAT = "PY_APP" + + df_log = dft_fn(CAT) + + ... + + class ... + ... + if __name__ == '__main__': + with dft_fn(name=f"frequency", cat=CAT): + (code...) + log_inst.finalize() + +The idea is to annotate the application so that we capture all the calls that occur during the running of the main fuction. These application calls will appear on the traces as events with "CAT:PY_APP" and their name will be "frequency". We can annotate further, by creating regions. For more details please refer to :doc:`examples.rst`. + +4.3 After the annotation with DFTracer, we can run the workflow with pegasus after first creating the data, planning the workflow and executing with `pegasus-run`: + +.. code-block:: bash + + ./prepare_input.sh + ./daxgen.py + ./daxgen.py -D 20130502 -f data.csv -i 1 + +For more information please visit `https://github.com/pegasus-isi/1000genome-workflow/tree/master`. + +4.4 After the workflow finishes we navigate into :code:`/path/to/traces/` that we set earlier with the DFTracer flags. We then load those traces on DFAnalyzer. The application calls will also have "CAT: PY_APP" as this is a Python code workflow. Here is the result of tracing 1000 Genome on LC Corona with 32 nodes and 48 processes per node using DFTracer and analyzing the tracing using DFAnalyzer: + +.. image:: images/tracing/1000genome.png + :width: 800 + :alt: Aggregate duration of 1000 Genome applications. \ No newline at end of file diff --git a/docs/pegasus_montage.rst b/docs/pegasus_montage.rst new file mode 100644 index 00000000..b36a7685 --- /dev/null +++ b/docs/pegasus_montage.rst @@ -0,0 +1,371 @@ +=================================== +Pegasus Montage with DFTracer +=================================== + +Instructions for tracing Pegasus Montage with DFTracer on LC Corona. These instructions can be used for any Workflow but you'll need to change the version of the tar files depending on the architecture of your machine and the workflow you are interested in. +For more information, visit the `workflows repository `_. + +Step 1: Install Condor +---------------------- + +1.1 Get the zip: + +.. code-block:: bash + + wget https://research.cs.wisc.edu/htcondor/tarball/10.x/current/condor-x86_64_CentOS8-stripped.tar.gz + +1.2 Untar to your condor folder: + +.. code-block:: bash + + tar -x -f condor*.tar.gz + mkdir condor + cd condor-*stripped + mv * ../condor + cd .. + rm -rf condor-*stripped + rm condor-stripped.tar.gz + +1.3 Configure: + +.. code-block:: bash + + cd condor + ./bin/make-personal-from-tarball + +Step 2: Install Pegasus +----------------------- + +2.1 Get the zip from Tarballs: + +.. code-block:: bash + + wget https://download.pegasus.isi.edu/pegasus/5.0.7/pegasus-binary-5.0.7-x86_64_rhel_7.tar.gz + wget https://download.pegasus.isi.edu/pegasus/5.0.7/pegasus-worker-5.0.7-x86_64_rhel_7.tar.gz + +2.2 Untar to your Pegasus folder (both for pegasus and pegasus-worker): + +.. code-block:: bash + + tar zxf pegasus-*.tar.gz + rm pegasus-*.tar.gz + +Step 3: Install and compile Montage +----------------------------------- + +3.1 Get the code: + +.. code-block:: bash + + git clone https://github.com/Caltech-IPAC/Montage.git + +3.2 Compile: + +.. code-block:: bash + + cd Montage + make + +.. note:: + + Make sure there are no errors. By cloning the GitHub repo, you get the most recent version, likely with no compiler errors. :code:`cd Montage/bin` and make sure it is not empty. + +3.3 Save in Paths: + +.. code-block:: bash + + export PATH=/path/to/Montage/bin:$PATH + +Step 4: Get the montage-pegasus-v3 +---------------------------------- + +4.1 Create and activate Virtual Environment: + +.. code-block:: bash + + python3 -m venv /path/to/pegasus-env + source /path/to/pegasus-env/bin/activate + +4.2 Install dependencies: + +.. code-block:: bash + + pip install astropy + pip install pegasus-wms + pip install git+https://github.com/hariharan-devarajan/dftracer.git + +4.3 Get the code: + +.. code-block:: bash + + git clone https://github.com/pegasus-isi/montage-workflow-v3.git + +Step 5: Compile the pegasus-mpi-cluster from source +--------------------------------------------------- + +5.1 Get the code: + +.. code-block:: bash + + git clone https://github.com/pegasus-isi/pegasus.git + +5.2 Make sure you’re in the virtual environment for Pegasus: + +.. code-block:: bash + + source /path/to/pegasus-env/bin/activate + +5.3 Make sure you have the prerequisites: + +1. Git +2. Java 8 or higher +3. Python 3.5 or higher +4. R +5. Ant +6. gcc +7. g++ +8. make +9. tox 3.14.5 or higher +10. mysql (optional, required to access MySQL databases) +11. postgresql (optional, required to access PostgreSQL databases) +12. Python pyyaml +13. Python GitPython + +5.4 Compile: + +.. code-block:: bash + + cd pegasus + ant compile-pegasus-mpi-cluster + +5.5 Copy it to your Pegasus folder: + +.. code-block:: bash + + cd packages/pegasus-mpi-cluster/ + cp pegasus-mpi-cluster/ /path/to/pegasus-5.0.7/bin + +.. note:: + + If errors occur while compiling, make sure that `MVAPICH` is loaded: + +.. code-block:: bash + + module load mvapich2-tce/2.3.7 + echo $LD_LIBRARY_PATH + +Step 6: Create a single “install” directory for all Pegasus software +-------------------------------------------------------------------- + +This will help in resolving errors like “cannot find .. in your path”. + +6.1 Move into the Pegasus directory (the one you compiled from source) and make a directory called install: + +.. code-block:: bash + + cd pegasus + mkdir install + +6.2 Copy all components from pegasus-5.0.7 and condor into the :code:`pegasus/install` folder: + +.. code-block:: bash + + cd ../condor + cp * ../pegasus/install + cp -r * ../pegasus/install + cd ../pegasus-5.0.7 + cp * ../pegasus/install + cp -r * ../pegasus/install + +.. note:: + + If you encounter errors about overwriting :code:`/bin` or :code:`/lib` folders, you have to do it manually by cd into those folders and copying everything to :code:`/pegasus/install/bin` or :code:`/pegasus/install/lib`. Make sure all components are there, otherwise Pegasus and Condor cannot run. + +Step 7: Prepare software for Pegasus-Montage +---------------------------------- + +7.1 Make sure you are in the virtual environment still. If not, source it again by repeating 5.2. + +7.2 Save to PATH: + +.. code-block:: bash + + export PATH=/path/to/pegasus/install/bin:$PATH + export PATH=/path/to/pegasus/install/sbin:$PATH + export LD_LIBRARY_PATH=/path/to/pegasus/install//lib:$LD_LIBRARY_PATH + source ~/.bashrc + +7.3 Run Condor: + +.. code-block:: bash + + chmod 777 /path/to/pegasus/install/condor.sh + . /path/to/pegasus/install/condor.sh + condor_master + condor_status # it should show the activity + condor_q # it should show the jobs running + +.. note:: + + If errors occur, echo the `LD_LIBRARY_PATH` and the `PATH` and make sure :code:`/pegasus/install` is there. + +To check if condor_shedd and all other condor processes are running: + +.. code-block:: bash + + ps aux | grep condor + +If Condor throws errors while trying to connect to another node: + +1. Exit the flux allocation: + +.. code-block:: bash + + exit + +2. Check your processes: + +.. code-block:: bash + + ps -u ${USER} + +3. Kill all your processes (or those related to Condor if any): + +.. code-block:: bash + + killall -u ${USER} + +4. Repeat steps 6.3, 6.4, 5.2, 6.5 + +5. If the problem persists: + +.. code-block:: bash + + condor_restart + +7.4 Test Pegasus: + +.. code-block:: bash + + pegasus-version # should show 5.0.7 + +.. note:: + +If error "Cannot find file with permissions" occurs, touch that file and make sure it has those permissions. + +7.5 Configure the Condor/SLURM interface: + +.. code-block:: bash + + pegasus-configure-glite + +.. note:: + + If error "Cannot find file with permissions" occurs, touch that file and make sure it has those permissions. + +7.6 Configure the DFTracer flags: + +.. code-block:: bash + + export DFTRACER_INSTALLED=/path/to/pegasus-env/lib/python3.9/site-packages/dftracer/ + export LD_LIBRARY_PATH=$DFTRACER_INSTALLED/lib:$DFTRACER_INSTALLED/lib64:$LD_LIBRARY_PATH + export DFTRACER_LOG_FILE=/path/to/traces/trace + # export DFTRACER_DATA_DIR=all (optional) + export DFTRACER_ENABLE=1 + export DFTRACER_INC_METADATA=1 + # export DFTRACER_INIT=PRELOAD (optional) + export DFTRACER_BIND_SIGNALS=0 + # export DFTRACER_LOG_LEVEL=ERROR (optional) + export DFTRACER_TRACE_COMPRESSION=1 + # dftracer=$DFTRACER_INSTALLED/lib64/libdftracer_preload.so (optional) + +You would only need to use the preload version of DFTracer if you have not annotated the application code you are running. +For more information on the flags and their functionalities please turn to :docs:`examples`. + +Step 8: Annotate Montage +---------------------------------- + +8.1 Navigate to the :code:`/path/to/Monatge` directory. Most of the source code that is useful to annotate and "time" for Monatge is in the `/Monatge` and `/MoantgeLb` folder. As an example we use the `mDiff.c` application which is located in :code:`/path/to/Monatge/Monatge` folder. The first step is to link the source code with DFTracer. For that we edit the `Makefile` located in the same folder as following: + +.. code-block:: make + + .SUFFIXES: + .SUFFIXES: .c .o + + CC = gcc + MPICC = + CFLAGS = -g -O2 -I. -I../lib/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -std=c99 + LIBS = -L../lib -lwcs -lcfitsio -lcoord -lmtbl -lsvc \ + -lwww -lboundaries -lpixbounds -ltwoplane -lm + + # Define flags + DF_CFLAGS = -I/usr/workspace/iopp/kogiou1/venvs/pegasus-env/lib/python3.9/site-packages/dftracer/include + DF_LDFLAGS = -L/usr/workspace/iopp/kogiou1/venvs/pegasus-env/lib/python3.9/site-packages/dftracer/lib64 -ldftracer + + # Add flags to CFLAGS and LIBS + CFLAGS += $(DF_CFLAGS) + LIBS += $(DF_LDFLAGS) + + + SBINS = mConvert mFlattenExec mHdrCheck mHdrtbl mTblSort mTileHdr mTileImage + MBINS = mProjExecMPI mFitExecMPI mDiffExecMPI mBgExecMPI mAddMPI mAddExecMPI + + BINS = $(SBINS) + + + # uncomment the next two lines to build MPI modules + MPICC = mpicc + BINS = $(SBINS) $(MBINS) + + + .c.o: + $(CC) $(CFLAGS) -c $*.c + + mDiff: mDiff.o debugCheck.o checkHdr.o checkWCS.o + $(CC) -o mDiff mDiff.o debugCheck.o checkHdr.o checkWCS.o \ + $(LIBS) + +8.2 Edit the :code:`/path/to/Monatge/mDiff.c` file as follows: + +.. code-block:: c + + #include + ... + int main(int argc, char **argv) + { + DFTRACER_C_INIT(NULL, NULL, NULL); + ... + if (MPI_err != 0) { + printf("[struct stat=\"ERROR\", msg=\"MPI initialization failed\"]\n"); + DFTRACER_C_FINI(); + exit(1); + } + ... + DFTRACER_C_FINI(); + exit(1); + } + +The idea is to initialize DFTracer at the start of the `main` function and then finilize DFTracer before we exit the function so that we can capture the time, as well as the application and the system calls with DFTracer that take place while mDiff application is running. We can annotate further, by creating regions. For more details please refer to :doc:`examples.rst`. + +8.3 After annotating the code we need to compile Montage using DFTracer. For that we need to source the Python environment that we have used to install DFTracer in and install it from source too (to access DFAnalyzer Jupyter Notebook). For details on that please refer to :doc:`build`. We then compile Montage as normal: + +.. code-block:: bash + + cd /path/to/Montage/ + make + +8.4 After the compilation with DFTracer, we can run Montage with pegasus after navigating to :code:`/path/to/montage-pegasus-v3/example-2mass.sh`. The steps are that we ceate the data by running `montage-workflow.py`, then plan the workflow and then run it with `pegasus-run`. For more information please visit ``. + +8.5 After the workflow finishes we navigate into :code:`/path/to/traces/` that we set earlier with the DFTracer flags. We then load those traces on DFAnalyzer. Depending on which application or system call was first, the traces will contain information regarding the "Level" of the call and "args:p_idx". The application calls will also have "CAT: C_APP" as this is a C code workflow. These can be used to further create a graph of calls. Here is the result of tracing Montage on LC Corona with 2 nodes and 55 processes using DFTracer and analyzing the tracing using DFAnalyzer: + +.. image:: images/tracing/Montage_summary.png + :width: 800 + :alt: Summary generated by DFAnalyzer for Montage. + +.. image:: images/tracing/Montage_graph.png + :width: 800 + :alt: Two-level graph of application calls for Monatge. + +.. image:: images/tracing/Montage_dur.png + :width: 800 + :alt: Aggreagte duration of traced calls for Montage. \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index 4170c03e..70b23e3d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,2 @@ -sphinx-rtd-theme \ No newline at end of file +sphinx-rtd-theme +Sphinx<7 \ No newline at end of file diff --git a/docs/utilities.rst b/docs/utilities.rst new file mode 100644 index 00000000..4db5650b --- /dev/null +++ b/docs/utilities.rst @@ -0,0 +1,50 @@ +======================== +DFTracer Utility scripts +======================== + +This section describes the utilities provided by DFTracer to assist users with logs. + +---------- + +All scripts are installed with DFTracer in the installation's directories bin folder. + +------------------ +Merge Trace script +------------------ + +This script allows users to combine all pfw format into one. +This has the following signature. + +.. code-block:: bash + + /bin/merge_pfw [-fcv] [-d input_directory] [-o output_file] + +Arguments for this script are + +1. **-d input_directory** folder containing all trace files. Default `PWD`. +2. **-o output_file** file for storing merged file. Default `combined.pfw`. +3. **-f** override output file. +4. **-c** compress output file. +5. **-v** enable verbose mode. +6. **-h** display help + +------------------ +Compaction script +------------------ + +The script compacts all trace file and then divides the trace into equal file pieces. + +.. code-block:: bash + + /bin/dftracer_compact [-fcv] [-d input_directory] [-o output_directory] [-l num_lines] [-p prefix] + +Arguments for this script are + +1. **-d input_directory** specify input directories. Should contain .pfw or .pfw.gz files. Default `PWD`. +2. **-o output_file** specify output directory. Default `combined.pfw`. +3. **-l num_lines** lines per trace. +4. **-p prefix** prefix to be used for compact files. +5. **-f** override output directory. +6. **-c** compress output file. +7. **-v** enable verbose mode. +8. **-h** display help diff --git a/examples/dfanalyzer/dfanalyzer-distributed.ipynb b/examples/dfanalyzer/dfanalyzer-distributed.ipynb new file mode 100644 index 00000000..4fd0dee3 --- /dev/null +++ b/examples/dfanalyzer/dfanalyzer-distributed.ipynb @@ -0,0 +1,699 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b4470223", + "metadata": {}, + "source": [ + "# DFAnalyzer Simple Example\n", + "\n", + "This notebook will guide you to load a trace file generated by DFTracer and analyze the trace events using Dask." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "86ed50dc-d4d6-4e78-be69-1d55b8362a46", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "markdown", + "id": "16132659", + "metadata": {}, + "source": [ + "## System imports for the notebook" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "432c079e", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from pathlib import Path\n", + "import sys\n", + "import yaml\n", + "import json" + ] + }, + { + "cell_type": "markdown", + "id": "9ece9f90", + "metadata": {}, + "source": [ + "## We add the analysis code to path so that we can run this in dev mode." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4a5811b8", + "metadata": {}, + "outputs": [], + "source": [ + "home = os.environ[\"HOME\"]\n", + "\n", + "with open(f\"{home}/.dftracer/configuration.yaml\", \"r\") as file:\n", + " dft_yaml = yaml.safe_load(file)\n", + " app_root = dft_yaml[\"app\"]\n", + "sys.path.insert(0, app_root)" + ] + }, + { + "cell_type": "markdown", + "id": "446ebe05", + "metadata": {}, + "source": [ + "## Imports for the notebook\n", + "\n", + "This may take some time as it initializes Dask." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4a47492d-40d0-4dea-b1a2-aa1f083239e3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/__init__.py\n" + ] + } + ], + "source": [ + "# Importing DFAnalyzer\n", + "import dfanalyzer\n", + "\n", + "print(dfanalyzer.__file__)\n", + "from dfanalyzer.main import (\n", + " DFAnalyzer,\n", + " update_dft_configuration,\n", + " setup_logging,\n", + " setup_dask_cluster,\n", + " reset_dask_cluster,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "0e236854", + "metadata": {}, + "source": [ + "## Initialize DFAnalyzer Configuration\n", + "\n", + "In this function, we can tune DFAnalyzer for the analysis. For example, we can tune number of workers, connect to existing dask cluster, etc." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f1aff029", + "metadata": {}, + "outputs": [], + "source": [ + "def get_conditions_stormer(json_object):\n", + " app_io_cond = (\n", + " \"__getitem__\" in json_object[\"name\"]\n", + " ) # I/O has that application is issuing\n", + " compute_cond = \"compute\" in json_object[\"cat\"]\n", + " io_cond = json_object[\"cat\"] in [\"POSIX\", \"STDIO\"]\n", + " return app_io_cond, compute_cond, io_cond" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "cc5aee73", + "metadata": {}, + "outputs": [], + "source": [ + "dask_run_dir = os.path.join(app_root, \"dfanalyzer\", \"dask\", \"run_dir\")\n", + "with open(os.path.join(dask_run_dir, f\"scheduler_{os.getenv('USER')}.json\"), \"r\") as f:\n", + " dask_scheduler = json.load(f)[\"address\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d3a7cf5b-fbbc-4eee-9ed5-ce869f4541e6", + "metadata": {}, + "outputs": [], + "source": [ + "conf = update_dft_configuration(\n", + " dask_scheduler=dask_scheduler,\n", + " verbose=True,\n", + " workers=4,\n", + " time_granularity=80e6,\n", + " log_file=f\"./df_{os.getenv('USER')}.log\",\n", + " conditions=get_conditions_stormer,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8478828a", + "metadata": {}, + "source": [ + "## This methods sets up logging for DFAnalyzer.\n", + "\n", + "This is needed for debugging and progress tracking. All prints seen in the following cells are configured in this method." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "04428959-820f-4466-8ceb-778bcce93bf0", + "metadata": {}, + "outputs": [], + "source": [ + "setup_logging()" + ] + }, + { + "cell_type": "markdown", + "id": "252225e3", + "metadata": {}, + "source": [ + "## Setup dask cluster.\n", + "\n", + "In this example, we use Dask Local cluster which will use multiprocessing on the same node where the notebook is running to run its workers.\n", + "\n", + "**NOTE:** If your running on Remote VSCode on a cluster, you can tunnel the port and open it locally." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "68e813b7-6b95-4f31-b223-1fb50774db50", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [21:08:40] Initialized Client with 16 workers and link http://140.221.112.12:8787/status [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:665]\n" + ] + } + ], + "source": [ + "setup_dask_cluster()" + ] + }, + { + "cell_type": "markdown", + "id": "237d458d", + "metadata": {}, + "source": [ + "On clicking the link, you will see a daskboard like this. [Dask Daskboard Image](images/dask-dashboard-load.png)" + ] + }, + { + "cell_type": "markdown", + "id": "6207690f", + "metadata": {}, + "source": [ + "## Reset Dask Cluster\n", + "\n", + "In case you have an error and want to clean the cluster for fresh analysis. You can run this." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "236e50a4-03b6-4895-a0a5-d473f5e391b5", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [21:08:47] Restarting all workers [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:657]\n" + ] + } + ], + "source": [ + "reset_dask_cluster()" + ] + }, + { + "cell_type": "markdown", + "id": "07951b56", + "metadata": {}, + "source": [ + "## Load the DFAnalyzer Trace\n", + "\n", + "The DFAnalyzer class take a regex string as input. For example, \"{app_root}/examples/dfanalyzer/*.pfw.gz\"" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b37727ee-a221-43ab-81e1-cdf98c2cf314", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [21:08:49] Created index for 16 files [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:366]\n", + "[INFO] [21:08:49] Total size of all files are bytes [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:368]\n", + "[INFO] [21:08:49] Loading 64 batches out of 16 files and has 848888 lines overall [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:381]\n", + "[INFO] [21:08:52] Loaded events [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:423]\n", + "[INFO] [21:08:52] Loaded plots with slope threshold: 45 [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:429]\n" + ] + } + ], + "source": [ + "analyzer = DFAnalyzer(f\"{app_root}/examples/dfanalyzer/test-trace-distributed/*.pfw.gz\")" + ] + }, + { + "cell_type": "markdown", + "id": "23d520b4", + "metadata": {}, + "source": [ + "## Analyze the events\n", + "\n", + "1. The dask dataframe is stored at `analyzer.events`. \n", + "2. We can run dask queries on this dataframe." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "4c0ffe10", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namecatpidtidtstedurtintervaltrangehostnamecompute_timeio_timeapp_io_timetotal_timefilenamephasesize
0openPOSIX10757412151482917891868<NA>0.0x3012c0s7b0n0<NA>8<NA>8/dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-...2<NA>
1openPOSIX1075741215148210815108216<NA>0.0x3012c0s7b0n0<NA>6<NA>6/dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-...2<NA>
2__fxstatPOSIX1075741215148210849108501<NA>0.0x3012c0s7b0n0<NA>1<NA>1/dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-...2<NA>
3mmapPOSIX1075741215148210868108768<NA>0.0x3012c0s7b0n0<NA>8<NA>8/dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-...2<NA>
4closePOSIX1075741215148210902109031<NA>0.0x3012c0s7b0n0<NA>1<NA>1/dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-...2<NA>
\n", + "
" + ], + "text/plain": [ + " name cat pid tid ts te dur tinterval trange \\\n", + "0 open POSIX 1075741 2151482 9178 9186 8 0.0 \n", + "1 open POSIX 1075741 2151482 10815 10821 6 0.0 \n", + "2 __fxstat POSIX 1075741 2151482 10849 10850 1 0.0 \n", + "3 mmap POSIX 1075741 2151482 10868 10876 8 0.0 \n", + "4 close POSIX 1075741 2151482 10902 10903 1 0.0 \n", + "\n", + " hostname compute_time io_time app_io_time total_time \\\n", + "0 x3012c0s7b0n0 8 8 \n", + "1 x3012c0s7b0n0 6 6 \n", + "2 x3012c0s7b0n0 1 1 \n", + "3 x3012c0s7b0n0 8 8 \n", + "4 x3012c0s7b0n0 1 1 \n", + "\n", + " filename phase size \n", + "0 /dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-... 2 \n", + "1 /dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-... 2 \n", + "2 /dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-... 2 \n", + "3 /dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-... 2 \n", + "4 /dev/shm/shared_memory.PMI.e6389e0f-f55b-400a-... 2 " + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "analyzer.events.head()" + ] + }, + { + "cell_type": "markdown", + "id": "006bfab2", + "metadata": {}, + "source": [ + "### Summary \n", + "\n", + "DFAnalyzer supports a summary utility that gives a brief summary of the job and its I/O access behavior." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "9350218f", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [21:08:55] Total number of events in the workload are 848856 [/eagle/MDClimSim/rayandrew/dftracer/dfanalyzer/main.py:521]\n" + ] + }, + { + "data": { + "text/html": [ + "
╭──────────────────────────────────────────────────── Summary ────────────────────────────────────────────────────╮\n",
+                            "│  Allocation    Scheduler Allocation Details                                                                     │\n",
+                            "│                ├── Nodes: 2                                                                                     │\n",
+                            "│                ├── Processes: 8                                                                                 │\n",
+                            "│                ├── Thread allocations across nodes (includes dynamically created threads)                       │\n",
+                            "│                │   ├── Compute: 8                                                                               │\n",
+                            "│                │   └── I/O: 813                                                                                 │\n",
+                            "│                └── Events Recorded: 849K                                                                        │\n",
+                            "│  Dataset       Description of Dataset Used                                                                      │\n",
+                            "│                └── Files: 13810                                                                                 │\n",
+                            "│  I/O Behavior  Behavior of Application                                                                          │\n",
+                            "│                ├── Split of Time in application                                                                 │\n",
+                            "│                │   ├── Total Time: 381.544 sec                                                                  │\n",
+                            "│                │   ├── Overall App Level I/O: 162.443 sec                                                       │\n",
+                            "│                │   ├── Unoverlapped App I/O: 15.205 sec                                                         │\n",
+                            "│                │   ├── Unoverlapped App Compute: 116.012 sec                                                    │\n",
+                            "│                │   ├── Compute: 263.250 sec                                                                     │\n",
+                            "│                │   ├── Overall I/O: 126.725 sec                                                                 │\n",
+                            "│                │   ├── Unoverlapped I/O: 10.598 sec                                                             │\n",
+                            "│                │   └── Unoverlapped Compute: 147.122 sec                                                        │\n",
+                            "│                └── Metrics by function                                                                          │\n",
+                            "│                    ├── Function       |count |                  size                   |                        │\n",
+                            "│                    ├──                |      |min   |25    |mean  |median|75    |max   |                        │\n",
+                            "│                    ├── open           |10K   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── __fxstat       |3K    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── mmap           |16    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── close          |10K   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── unlink         |11K   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── open64         |24    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── __fxstat64     |19K   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── lseek64        |25K   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── read           |144   |NA    |22    |13KB  |5KB   |36KB  |36KB  |                        │\n",
+                            "│                    ├── opendir        |24    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── __xstat64      |2K    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── link           |2K    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── pread          |717K  |8     |512   |1MB   |512   |4MB   |4MB   |                        │\n",
+                            "│                    ├── __lxstat       |3K    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── write          |6K    |1     |1     |1     |1     |1     |1     |                        │\n",
+                            "│                    ├── mmap64         |6K    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── fcntl          |6K    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    └── ftruncate      |12    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+                            "
\n" + ], + "text/plain": [ + "╭──────────────────────────────────────────────────── Summary ────────────────────────────────────────────────────╮\n", + "│ \u001b[36m \u001b[0m\u001b[36mAllocation \u001b[0m\u001b[36m \u001b[0m Scheduler Allocation Details │\n", + "│ \u001b[36m \u001b[0m ├── Nodes: 2 │\n", + "│ \u001b[36m \u001b[0m ├── Processes: 8 │\n", + "│ \u001b[36m \u001b[0m ├── Thread allocations across nodes (includes dynamically created threads) │\n", + "│ \u001b[36m \u001b[0m │ ├── Compute: 8 │\n", + "│ \u001b[36m \u001b[0m │ └── I/O: 813 │\n", + "│ \u001b[36m \u001b[0m └── Events Recorded: 849K │\n", + "│ \u001b[36m \u001b[0m\u001b[36mDataset \u001b[0m\u001b[36m \u001b[0m Description of Dataset Used │\n", + "│ \u001b[36m \u001b[0m └── Files: 13810 │\n", + "│ \u001b[36m \u001b[0m\u001b[36mI/O Behavior\u001b[0m\u001b[36m \u001b[0m Behavior of Application │\n", + "│ \u001b[36m \u001b[0m ├── Split of Time in application │\n", + "│ \u001b[36m \u001b[0m │ ├── Total Time: 381.544 sec │\n", + "│ \u001b[36m \u001b[0m │ ├── Overall App Level I/O: 162.443 sec │\n", + "│ \u001b[36m \u001b[0m │ ├── Unoverlapped App I/O: 15.205 sec │\n", + "│ \u001b[36m \u001b[0m │ ├── Unoverlapped App Compute: 116.012 sec │\n", + "│ \u001b[36m \u001b[0m │ ├── Compute: 263.250 sec │\n", + "│ \u001b[36m \u001b[0m │ ├── Overall I/O: 126.725 sec │\n", + "│ \u001b[36m \u001b[0m │ ├── Unoverlapped I/O: 10.598 sec │\n", + "│ \u001b[36m \u001b[0m │ └── Unoverlapped Compute: 147.122 sec │\n", + "│ \u001b[36m \u001b[0m └── Metrics by function │\n", + "│ \u001b[36m \u001b[0m ├── Function |count | size | │\n", + "│ \u001b[36m \u001b[0m ├── | |min |25 |mean |median|75 |max | │\n", + "│ \u001b[36m \u001b[0m ├── open |10K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── __fxstat |3K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── mmap |16 |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── close |10K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── unlink |11K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── open64 |24 |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── __fxstat64 |19K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── lseek64 |25K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── read |144 |NA |22 |13KB |5KB |36KB |36KB | │\n", + "│ \u001b[36m \u001b[0m ├── opendir |24 |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── __xstat64 |2K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── link |2K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── pread |717K |8 |512 |1MB |512 |4MB |4MB | │\n", + "│ \u001b[36m \u001b[0m ├── __lxstat |3K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── write |6K |1 |1 |1 |1 |1 |1 | │\n", + "│ \u001b[36m \u001b[0m ├── mmap64 |6K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── fcntl |6K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m └── ftruncate |12 |NA |nan |nan |NA |nan |NA | │\n", + "╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "items = analyzer.summary()\n", + "items" + ] + }, + { + "cell_type": "markdown", + "id": "2ab18972", + "metadata": {}, + "source": [ + "### Timeline plots\n", + "\n", + "We support two timeline plots:\n", + "1. how I/O time and I/O bandwidth changes over time.\n", + "2. how transfer size changes over time." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "b9185f98", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvMAAAErCAYAAABTgAwIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAACJ4UlEQVR4nOzdeVhU1RvA8e/MsO+LrIqAgiIquOQC7rv+TDErLc2ltLLINLPSyq1NyzQrScvKtLLUyiUr933J3PcVcUFRFJVVtpn7+2NkFAEFBIaB9/M88zBz77nnvveyvffcc89RKYqiIIQQQgghhDA5amMHIIQQQgghhCgeSeaFEEIIIYQwUZLMCyGEEEIIYaIkmRdCCCGEEMJESTIvhBBCCCGEiZJkXgghhBBCCBMlybwQQgghhBAmSpJ5IYQQQgghTJQk80IIIYQQQpgoSeaFEEIIIYQwUUZN5idOnIhKpcr1CgoKAuD69esMHz6c2rVrY21tTfXq1Xn11VdJTEw0ZshCCCGEEMLINm/eTI8ePfD29kalUrF06dJc6ydOnEhQUBC2trY4OzvTsWNHdu7cmavMyZMniYiIoEqVKjg4ONCyZUs2bNhQ6BiGDRuGSqVixowZJXBExWf0lvm6desSFxdneG3duhWAS5cucenSJT799FMOHz7MDz/8wMqVKxkyZIiRIxZCCCGEEMaUmppKaGgoUVFR+a6vVasWM2fO5NChQ2zduhU/Pz86d+7M1atXDWUeffRRsrOzWb9+PXv27CE0NJRHH32Uy5cvP3D/S5Ys4d9//8Xb27vEjqm4VIqiKMba+cSJE1m6dCn79+8vVPnFixfzzDPPkJqaipmZWekGJ4QQQgghyj2VSsWSJUvo1atXgWWSkpJwdHRk7dq1dOjQgWvXruHm5sbmzZtp1aoVAMnJyTg4OLBmzRo6duxYYF0XL16kWbNmrFq1iu7duzNy5EhGjhxZwkdVeEbPiE+dOoW3tzdWVlaEhYUxefJkqlevnm/ZxMREHBwc7pvIZ2RkkJGRYficnZ3NsWPH8PHxQa02+o0IIYQQQghxD51Ox/nz5wkODs6V51laWmJpaflQdWdmZvLNN9/g6OhIaGgoAK6urtSuXZv58+fTqFEjLC0t+frrr3F3d6dx48b3jXPAgAG88cYb1K1b96HiKjGKEf3999/KokWLlAMHDigrV65UwsLClOrVqytJSUl5yl69elWpXr268vbbb9+3zgkTJiiAvOQlL3nJS17ykpe8TPw1YcKEB+aTgLJkyZI8y//880/F1tZWUalUire3t/Lff//lWn/hwgWlcePGikqlUjQajeLl5aXs3bv3vvv66KOPlE6dOik6nU5RFEXx9fVVPvvsswfGWJqM2s3mXjdv3sTX15fp06fn6huflJREp06dcHFxYfny5ZibmxdYx70t8xcuXKBevXps374dLy+vUo1fGJ864QTm57eR0eBZUKkA0Fzejyo9EZs9XwFqkjtMQXHyNW6gQgghhDCIi4sjPDycw4cP4+PjY1hemJb5grrZpKamEhcXx7Vr15gzZw7r169n586duLu7oygKvXr1Iisri3feeQdra2u+/fZbli9fzq5du/LNGffs2UP37t3Zu3evoa+8n5+fdLO5m5OTE7Vq1eL06dOGZcnJyXTt2hV7e3uWLFly30Qe8n7THR0dAfDx8aFatWqlE7gwvitHYc9cuPCf/rOqM/i11L/389N/zTwNMZtxOf87hH5uSPaFEEIIYVw5XWscHR1xcHAokTptbW0JCAggICCA5s2bExgYyHfffcfYsWNZv349K1as4MaNG4b9ffXVV6xZs4Z58+YxZsyYPPVt2bKF+Pj4XN3BtVotr7/+OjNmzODs2bMlEndRlatkPiUlhejoaAYMGADoW+S7dOmCpaUly5cvx8rKysgRinIn/hjsngsXbg83pdZArW7gGpC3bFikvlzcAYheDwEdyjZWIYQQQhiNTqcz9N5IS0sDyPM8pVqtRqfT5bv9gAED8jwY26VLFwYMGMCzzz5bChEXjlGT+dGjR9OjRw98fX25dOkSEyZMQKPR8PTTT5OUlETnzp1JS0vjp59+IikpiaSkJADc3NzQaDTGDF0YW3oSbPgIzu/Qf1apoVZXaDQAHAoYJsreExr0g3M7wKFq2cUqhBBCiBKVkpKSqydHTEwM+/fvx8XFBVdXVz788EN69uyJl5cX165dIyoqiosXL/Lkk08CEBYWhrOzM4MGDWL8+PFYW1szZ84cYmJi6N69u6HeoKAgJk+ezGOPPYarqyuurq654jA3N8fT05PatWuXzYHnw6jJfGxsLE8//TQJCQm4ubnRsmVL/v33X9zc3Ni4caNhcP+AgNytrDExMfjldJ0QlZOFHaRevZ3Ed4GG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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax1, ax2 = analyzer.plots.time_bw_timeline(\n", + " bw_unit=\"gb\",\n", + " figsize=(8, 3),\n", + " line1_label=\"POSIX I/O Time\",\n", + " line2_label=\"POSIX I/O Bandwidth\",\n", + " time_col=\"io_time\",\n", + " x_num_ticks=8,\n", + " y_num_ticks=5,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "08b58161", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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REREhkbqjFat3k+cOIFx48aV2u7h4YH09PRnLoqIiIiISCrVCsDm5uZQKpWltl++fBnOzs7PXBQRERERkVSqFYD79euHuXPnoqioCAAgk8mQmpqKmTNnYuDAgTotkIiIiIhIl6oVgL/66ivk5OTAxcUFDx8+hL+/Pxo3bgxbW1t89tlnuq6RiIiIiEhnqvUhOHt7e+zZswdHjhzBmTNnkJOTg7Zt2yIgIEDX9RERERER6VSlA7CjoyMuX74MJycnhIaGYvHixejSpQu6dOkiZX1ERERERDpV6SkQhYWFmg++rVmzhg+RICIiIqJaqdJ3gP38/BAcHIx27dpBCIHJkyfD0tKyzLY//vijzgokIiIiItKlSgfg//znP/j666+RnJwMmUyGrKws3gUmIiIiolqnWo9C9vb2xsmTJ1GvXj0papJUyaOQpXq0HhERERE9G6nzWrVWgUhJSSm17cGDB6hbt+6z1lNj1Go11Gq1vssgIiIioidIndGqFYA///xzeHl5YciQIQCAwYMHY+PGjXBzc8OOHTvQqlUrnRapCwqFAgqFAiqVCgCQkZHBKRxEREREBig7O1vS/qs9BWLt2rXo3Lkz9uzZg8GDByMuLg7r169Hamoqdu/eLUWtOlFySz0zM5NTIIiIiIgMkFKphIODg2FNgUhPT4enpycA4Ndff8XgwYPRu3dveHl5oWPHjjotUCpyuRxyebUehEdEREREEpI6o1WrdwcHB9y8eRMAsGvXLs0T4IQQmikGRERERESGqFp3gAcMGIBhw4ahSZMmuHfvHvr27QsASEhIQOPGjXVaIBERERGRLlUrAH/99dfw8vLCzZs38cUXX8DGxgYAkJaWhn//+986LZCIiIiISJeq9SG42ozrABMREREZNoNcBxgArly5gv379+POnTul1mqbM2fOMxdGRERERCSFagXgFStW4P3334eTkxPq168PmUym2SeTyRiAiYiIiMhgVSsAf/rpp/jss88wc+ZMXddDRERERCSpai2DlpmZiUGDBum6FiIiIiIiyVUrAA8aNMign/ZGRERERFSeak2BaNy4MWbPno1jx46hZcuWMDU11do/efJknRRHRERERKRr1VoGzdvbu/wOZTJcu3btmYqSEpdBIyIiIjJsBrkMWkpKiq7rqHFqtbrU8m1EREREpH9SZ7RqrwNc2ygUCigUCqhUKgBARkYG8vPz9VwVERERET0pOztb0v6r/SS4v//+G7/88gtSU1NRWFiotW/RokU6KU4KJbfUMzMzOQWCiIiIyAAplUo4ODgY1hSIvXv3ol+/fmjUqBEuXbqEl19+GdevX4cQAm3bttV1jZKQy+WQy6u1CAYRERERSUjqjFat3sPDwzF9+nScO3cOFhYW2LRpE27evAl/f3+uD0xEREREBq1aAfivv/7CqFGjAAB16tTBw4cPYWNjg7lz5+Lzzz/XaYFERERERLpUrQBsbW2tmffr5uaG5ORkzb67d+/qpjIiIiIiIglUaw5wp06dcPjwYfj4+OD111/HBx98gHPnzmHz5s3o1KmTrmskIiIiItKZagXgRYsWIScnBwAQGRmJnJwcxMXFoUmTJga9AgQRERERUZUDsEqlwt9//w1fX18Aj6ZDLF++XOeFERERERFJocpzgE1MTNC7d29kZmZKUQ8RERERkaSq9SG4l19+GdeuXdNZEQqFAl5eXrCwsEDHjh1x/PjxCts/ePAAEyZMgJubG8zNzdG0aVPs2LFDZ/UQERER0fOrWgH4008/xfTp0/Hrr78iLS0NSqVS66sq4uLiEBYWhoiICJw+fRqtWrVCYGAg7ty5U2b7wsJC9OrVC9evX8fGjRuRlJSEFStWwMPDozqXQkRERERGpkqPQp47dy4++OAD2Nra/q8DmUzzvRACMpkMKpWq0gV07NgR7du3x9KlSwEAarUanp6emDRpEmbNmlWq/fLly/Hll1/i0qVLMDU1rfR5SpQ8ClmqR+sRERER0bOROq9VKQCbmJggLS0Nf/31V4Xt/P39K9VfYWEhrKyssHHjRgQHB2u2h4SE4MGDB9i2bVupY15//XU4OjrCysoK27Ztg7OzM4YNG4aZM2fCxMSkVPuCggIUFBRoXiuVSnh6euLu3bsMwEREREQGSKlUwsnJSbIAXKVVIEqycmUD7tPcvXsXKpUKrq6uWttdXV1x6dKlMo+5du0a9u3bh+HDh2PHjh24evUq/v3vf6OoqAgRERGl2kdFRSEyMrLU9t27d8PKykon10FEREREupOXlydp/1VeBu3xKQ/6oFar4eLigh9++AEmJiZo164dbt26hS+//LLMABweHo6wsDDN65I7wL179+YdYCIiIiIDVNXPlFVVlQNw06ZNnxqC79+/X6m+nJycYGJigtu3b2ttv337NurXr1/mMW5ubjA1NdWa7uDj44P09HQUFhbCzMxMq725uTnMzc1L9WNqalqtOcREREREJC2pM1qVA3BkZCTs7e11cnIzMzO0a9cOe/fu1cwBVqvV2Lt3LyZOnFjmMV26dMG6deugVqshlz9axOLy5ctwc3MrFX6JiIiIiJ5U5QD89ttvw8XFRWcFhIWFISQkBK+88go6dOiAb775Brm5uXjnnXcAAKNGjYKHhweioqIAAO+//z6WLl2KKVOmYNKkSbhy5Qrmz5+PyZMn66wmIiIiInp+VSkASzH/d8iQIcjIyMCcOXOQnp6O1q1bY9euXZoPxqWmpmru9AKAp6cnfvvtN0ybNg2+vr7w8PDAlClTMHPmTJ3XRkRERETPnyotgyaXy5Genq7TO8A1jesAExERERk2qfNale4Aq9VqnRdARERERFSTqvUoZCIiIiKi2ooBmIiIiIiMCgMwERERERkVBmAiIiIiMioMwERERERkVKr8IIznhVqt5qoWRERERAZI6oxmNAFYoVBAoVBApVIBADIyMpCfn6/nqoiIiIjoSdnZ2ZL2X6UHYTwPShZWzszM5IMwiIiIiAyQUqmEg4ODYTwI43kil8u1HrFMRERERIZB6ozGBEhERERERoUBmIiIiIiMCgMwERERERkVBmAiIiIiMioMwERERERkVBiAiYiIiMioMAATERERkVFhACYiIiIio8IATERERERGhQGYiIiIiIwKAzARERERGZU6+i5AX9RqNdRqtb7LICIiIqInSJ3RjCYAKxQKKBQKqFQqAEBGRgby8/P1XBURERERPSk7O1vS/mVCCCHpGQyMUqmEvb09MjMzYWdnp+9yiIiIiOgJSqUSDg4OyMrKkiSvGc0d4CfJ5XLI5ZwCTURERGRopM5oTIBEREREZFQYgImIiIjIqDAAExEREZFRYQAmIiIiIqPCAExERERERoUBmIiIiIiMCgMwERERERkVBmAiIiIiMioMwERERERkVBiAiYiIiMioGO2jkNVqNdRqtb7LICIiIqInSJ3RjCYAKxQKKBQKqFQqAEBGRgby8/P1XBURERERPSk7O1vS/mVCCCHpGQyMUqmEvb09MjMzYWdnp+9yiIiIiOgJSqUSDg4OyMrKkiSvGc0d4CfJ5XLI5ZwCTURERGRopM5oTIBEREREZFQYgImIiIjIqDAA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mqJFixZVukYiomfBD8EREdWgCRMm4P79+xg6dChOnDiB5ORk/Pbbb3jnnXegUqn0dg5nZ2e0bdsWhw8f1mz79ddf8e233yIxMRE3btxATEwM1Go1mjVrBltbW0yfPh3Tpk3DmjVrkJycjNOnT2PJkiVYs2YNAGDixIlQKpV4++23cfLkSVy5cgU//fST1vJyhw4dQteuXSt1t5iISFcYgImIapC7uzuOHDkClUqF3r17o2XLlpg6dSrq1q0LuVw3v5Kre46xY8di7dq1mtd169bF5s2b0bNnT/j4+GD58uX4+eefNXdr582bh9mzZyMqKgo+Pj7o06cPtm/fDm9vbwBAvXr1sG/fPuTk5MDf3x/t2rXDihUrtO4Gx8bG4t1339XJdRMRVRafBEdERAAefRCuWbNmiIuLg5+fn+Tn27lzJz744AOcPXtWsukgRERl4R1gIiIC8OhDazExMRU+MEOXcnNzER0dzfBLRDWOd4CJiIiIyKjwDjARERERGRUGYCIiIiIyKgzARERERGRUGICJiIiIyKgwABMRERGRUWEAJiIiIiKjwgBMREREREaFAZiIiIiIjAoDMBEREREZlf8P+527ID0cQTwAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = analyzer.plots.xfer_size_timeline(\n", + " figsize=(8, 3),\n", + " unit=\"mb\",\n", + " x_num_ticks=8,\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.8" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/dfanalyzer/dlp_analyzer.ipynb b/examples/dfanalyzer/dfanalyzer-ideas.ipynb similarity index 99% rename from examples/dfanalyzer/dlp_analyzer.ipynb rename to examples/dfanalyzer/dfanalyzer-ideas.ipynb index 925b7a3e..0dc731c7 100644 --- a/examples/dfanalyzer/dlp_analyzer.ipynb +++ b/examples/dfanalyzer/dfanalyzer-ideas.ipynb @@ -109,7 +109,7 @@ "source": [ "import dfanalyzer\n", "print(dfanalyzer.__file__)\n", - "from dfanalyzer.main import DFAnalyzer,get_df_configuration,update_df_configuration,setup_logging,setup_dask_cluster, reset_dask_cluster, get_df_configuration" + "from dfanalyzer.main import DFAnalyzer,get_dft_configuration,update_dft_configuration,setup_logging,setup_dask_cluster, reset_dask_cluster, get_dft_configuration" ] }, { @@ -207,7 +207,7 @@ "metadata": {}, "outputs": [], "source": [ - "conf = update_df_configuration(dask_scheduler=dask_scheduler, verbose=True, workers=16,\n", + "conf = update_dft_configuration(dask_scheduler=dask_scheduler, verbose=True, workers=16,\n", " log_file=f\"./df_{os.getenv('USER')}.log\", rebuild_index=False, time_approximate=True, \n", " host_pattern=r'lassen(\\d+)', time_granularity=30e6, skip_hostname=True, conditions=condition_fn)\n" ] @@ -232,7 +232,7 @@ } ], "source": [ - "conf = get_df_configuration()\n", + "conf = get_dft_configuration()\n", "conf.time_approximate" ] }, @@ -1740,7 +1740,7 @@ }, { "data": { - "image/png": "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WNHUlNTa3XMGhVD9+jRgx49Kl7MeM0119RKQHVFsZqgRR/o/yj4trJ3OEIIIYQQDZ6LowOBHk6cyS7iRGoeXUrrxLPi7RtYPcnOzrZ9/9prr/HUU0/x6quv0rlz50ora3p4eFR7/ItKxGfPns1jjz2G0Wi84LFbtmwhNTW1wSXmhf2mQN+boRbqeYQQQgghmotIP9dyiXiItrGZLHPv5eVVoRZcVVWGDRtW4RhVVVEUBYvFUu3xL6pryv79+2nZsiUPP/wwf/zxBykpKbZ9ZrOZ3bt38+6779K/f39uvfVW3N0vruRj/fr1jB49mhYtWqAoCj///HOlYw4cOMB1112Hp6cnrq6u9OrVq0YtYixh/SUJF0IIIYSopkg/bfX04yl5ENgZhkzX2j03ADExMURERODs7EyfPn3YunXrOY/dt28fN954IxERESiKwvz58y84/po1a1i9erXtdvb98ttq4qJmxD///HP+/fdf3nnnHe644w6ys7PR6/U4OTmRn58PwOWXX869997LhAkTLrp7Sl5eHl27duWee+7hhhtuqLT/2LFjXHHFFUyaNIkXX3wRDw8P9u3b1zi6swghhBBCNAERfuV6ibu1hXaj7ByRZtGiRUyZMoUFCxbQp08f5s+fz8iRIzl06BABAQGVjs/PzycqKoqbb76Z//znPxd1jsGDyxYuOnXqFGFhYZW6paiqSlxcXI2eQ7WXuLdarezevZvY2FgKCgrw8/OjW7du+Pn51SgAWyCKwk8//cTYsWNt22677TYMBgNffPFFjcctXeK+uS2ZKoQQQghRG5KyCrnv82046BW+f6AfDvraXwWzJvlanz596NWrF++88w6g5ahhYWFMnjyZadOmnfexERERPP744zz++OMXHaNerycxMbFSkp+WlkZAQECNSlOqfbGmTqejW7dudOvWrdonqw6r1cpvv/3GU089xciRI9m5cyeRkZFMnz69QrJ+tqKiIoqKimz3c3JyAK2Epri4uE5jFkIIIYRoaryddTg5KBQWWzmZkkO4Go+SegjVvz34tqmVc5jNZkDL28pfIOnk5ISTk1Ol400mE9u3b2f69Om2bTqdjuHDh7N58+ZaielspbXgZ8vNza1xtUaDXUIyOTmZ3NxcZs+ezX//+19ee+01li1bxg033MCaNWsqfFRQ3qxZs3jxxRcrbV+1atUlz9oLI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qS0bRPNWmn7woiICPl3IIQQwi7i4+MJDw+X9oVNlU6nq7QEuU6nQ1EU202I5qj097+qfyNCCCFEfWiu//80z2ctRB1QFIWff/65Ro8dMmQIjz/++HmPiYiIYP78+ec95oUXXqBbt241ikEIIYQQ9UsS8UZowoQJtllMR0dHWrduzUsvvVShzt1isTBv3jw6d+6Ms7Mz3t7eXH311WzcuLHCWBaLhdmzZ9O+fXuMRiM+Pj706dOHjz76qML5xo4dazu+f//+3HDDDRXGycrKIiwsjGefffaccZ8r2Rw6dGiF83322Wf06tULFxcX3N3dGTx4MEuXLr3g6xIREWF7XfR6PS1atGDSpElkZGRc8LH2tnjxYl5++eVqPeZSEn8hhBBC2J8k4o3UqFGjSExM5MiRIzzxxBO88MILzJkzB9C6YNx222289NJLPPbYYxw4cIC1a9cSFhbGkCFDKiRvL774IvPmzePll19m//79rFmzhvvvv5/MzMwqz6vX6/n0009ZtmwZX331lW375MmT8fHxqfZCPenp6WzcuJHRo0cDMHXqVB544AFuvfVWdu/ezdatW7niiisYM2YM77zzzgXHe+mll0hMTOTUqVN89dVXrF+/nkcffbRaMdmDj48P7u7u9g5DCCGEEPVIEvFzKS44981sqsaxRRc+tgacnJwICgoiPDychx56iOHDh7NkyRIAvvvuO3744Qc+//xz7r33XiIjI+natSsffPAB1113Hffeey95eXkALFmyhIcffpibb77ZdtykSZOYOnXqOc/dtm1bZs+ezeTJk0lMTOSXX37h22+/5fPPP6/UmeZCfvvtN7p3705gYCB///03b775JnPmzGHq1Km0bt2aDh068Morr/D4448zZcoU4uLizjueu7s7QUFBhISEMHToUMaPH8+OHTts+9PS0rj99tsJCQnBxcWFzp07880331QYY8iQITz66KM89dRT+Pj4EBQUxAsvvFDhmCNHjjBo0CCcnZ3p2LEjK1asqLD/pptu4pFHHrHdf/zxx1EUhYMHDwJgMplwdXVl5cqVtnOW/7QgOTmZ0aNHYzQaiYyMrPCmB7TZf4Drr78eRVFs90t98cUXRERE4OnpyW233UZOTs55XzchhBBC1L9mc7FmtX0y6tz7WvaFq18ru//5WDAXVn1scFe47u2y+1/fCoVZFY95YF2NwyxlNBptrX++/vpr2rZta5tlLu+JJ55g8eLFrFixgrFjxxIUFMTq1at5+OGH8ff3v+jzTZ48mZ9++om7776bPXv2MGPGDLp27VrtuJcsWcKYMWMA+Oabb3Bzc+OBBx6oMu65c+fy448/XrCWulRCQgK//vorffr0sW0rLCykR48ePP3003h4ePDbb79x991306pVK3r37m077rPPPmPKlCls2bKFzZs3M2HCBAYMGMBVV12F1WrlhhtuIDAwkC1btpCVlVUppsGDB/P+++/b7q9btw4/Pz/Wrl1L+/bt+eeffyguLqZ///5Vxj5hwgROnz7NmjVrMBgMPProoyQnJ9v2//PPPwQEBLBw4UJGjRqFXq+37Tt27Bg///wzS5cuJSMjg1tuuYXZs2fzyiuvXNTrJoQQQoj6ITPijZyqqqxcuZLly5dz5ZVXAnD48GE6dOhQ5fGl2w8fPgzA3LlzSUlJISgoiC5duvDggw/yxx9/XPC8iqLw3nvvsWrVKgIDA5k2bVq1Yy8qKmLZsmVcd911tphatWpV5ax6ixYt8PDwsMV9Lk8//TRubm4YjUZCQ0NRFIW5c+fa9oeEhDB16lS6detGVFQUkydPZtSoUXz33XcVxunSpQszZ86kTZs2jBs3jp49e7Jq1SoAVq5cycGDB/n888/p2rUrgwYN4tVXX63w+CFDhrB//35SUlLIyMhg//79PPbYY6xduxaAtWvX2urgz3b48GH++OMPPvzwQ/r27UuPHj34+OOPKSgo+/Sk9E2Tl5cXQUFBFd5EWa1WPv30Uzp16sTAgQO5++67bbELIYQQouGQGfFzuWfZufcp+or3x/18nmPPeq9zx6Iah1Te0qVLcXNzsy1KdMcdd1Qon7jY9vAdO3Zk7969bN++nY0bN7J+/XpGjx7NhAkTKlxAWZVPPvkEFxcXTpw4QXx8fKXyiAtZvXo1AQEBXHbZZdWO+1yefPJJJkyYgKqqxMXF8cwzz3DNNdewfv169Ho9FouFV199le+++46EhARMJhNFRUWVEuIuXbpUuB8cHGybkT5w4ABhYWG0aNHCtr9fv34Vju/UqRM+Pj6sW7cOR0dHLr/8cq699lpiYmIAbYZ8yJAhVT6HAwcO4ODgQI8ePWzb2rdvj5eX10W9BhERERXqzcvHLoQQQoiGQ2bEz8VgPPfNwbEaxzpd+NgaGDp0KLt27eLIkSMUFBTw2Wef4erqCmg13AcOHKjycaXb27Zta9um0+no1asXjz/+OIsXL+bTTz/l448/5sSJE+c8/6ZNm5g3bx5Lly6ld+/eTJo0qdpJ9JIlS2yz4aUxHT9+3LYaanmnT58mOzu7QtxV8fPzo3Xr1rRp04Yrr7yS+fPns2nTJtasWQPAnDlzeOutt3j66adZs2YNu3btYuTIkZXOefYKk4qiVGv5XUVRGDRoEGvXrrUl3V26dKGoqIi9e/eyadMmBg8efNHjVcelxi6EEEKI+iGJeCPl6upK69atadmyJQ4OFT/YuO222zhy5Ai//vprpce9+eab+Pr6ctVVV51z7I4dOwLYLug8W35+PhMmTOChhx5i6NChfPzxx2zdupUFCxZcdPyqqvLrr7/a6sNL487Nza1QW13qjTfewGAwcOONN170OQBb7XRpWcfGjRsZM2YMd911F127diUqKuqC5S5n69ChA3FxcSQmJtq2/f3335WOGzx4MGvXrmXt2rUMGTIEnU7HoEGDmDNnDkVFRQwYMKDK8du3b4/ZbGb79u22bYcOHarUycZgMGCxWKoVuxBCCCEaDknEm6DbbruN66+/nvHjx/Pxxx9z8uRJdu/ezQMPPMCSJUv46KOPbLPnN910E/PmzWPLli3Exsaydu1aoqOjadu2Le3bt69y/OnTp6OqKrNnzwa0Uog33niDp556ipMnT15UjNu3byc/P58rrrjCtq1fv3489thjPPnkk7z55pscO3aMgwcP8txzz/HWW2/x5ptvEhYWdt5xc3JySEpKIjExka1bt/Lkk0/i7+9vuyiyTZs2rFixgk2bNnHgwAEeeOABzpw5c1Exlxo+fDht27Zl/Pjx/Pvvv/z1119V9k8vrRPft2+f7XkOGTKEr776ip49e9p+Bmdr164do0aN4oEHHmDLli1s376de++9F6Ox4qcnERERrFq1iqSkpEbRK10IIYQQFTWbGnGr1Vrp43mr1YqqqrZbY3O+mBctWsT8+fOZN28eDz/8MM7OzvTr1481a9YwYMAA22NHjBjBt99+y6xZs8jKyiIoKIgrr7ySmTNnotfrK5xDVVXWrVtHTEwMa9aswWg02vbff//9LF68mEmTJrFixQoURTlnzKqq8vPPP/N///d/lc5RugjRe++9x3PPPYder6d79+789NNPjB49+oI/p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i6bds2ddq0aaqfn5+6b9++CsdkZWWpvXv3VkeNGqWaTCbb9ldeeUUF1OXLl9u2JScnqzqdTl22bFm9PYeG6tSpU2pAQID677//2rZVVZqSmZmpHj58WF23bp06evRotXv37mpBQYGqqqr6n//8R7311lttx15sGVZzlZGRoXp4eKgfffSR+ssvv6itW7dWc3JybPvP/ltdKjExUT1w4ID6yy+/qB07dlQfeuiheoy64TIYDGq/fv0qbJs8ebLat2/fcz7m2LFjKlBlyVp8fLzaqlUrddKkSbUea1MwYsQI9dprr7XdL80lpk+fXuG4zp07q9OmTav0eClNaWT8/PzQ6/WcOXOmwvYzZ85c1Ed44txKX7/zvbarV69m6dKlfPvttwwYMIDu3bvz7rvvYjQaK8w2NHePPPIIS5cuZc2aNZc0k71w4UJ8fX257rrrajG6xs/R0ZHWrVvTo0cPZs2aRdeuXXnrrbds+3Nychg1ahTu7u789NNPGAwG277g4GCACjPo/v7++Pn5VSgPaK62b99OcnIy3bt3x8HBAQcHB9atW8fbb7+Ng4ODbcbQ09OTNm3aMGjQIH744QcOHjzITz/9BGh/J77//nvb44cNGwZof79nzpxpt+fWUHl5edG2bVuOHj3K6tWrOXbsGF5eXrbXD+DGG29kyJAhFR4XFBRE+/btue6663j//fd57733SExMtMMzaFiCg4MrfULWoUOH8/77joqKws/Pj6NHj1bYfvr0aYYOHUr//v354IMP6iTexiw2NpaVK1dy77332rZV9TcWLvwzaGqabCLu6OhIjx49WLVqlW2b1Wpl1apV56wRFRcnMjKSoKCgCq9tdnY2W7Zssb22+fn5AJVqPnU6HVartf6CbaBUVeWRRx7hp59+YvXq1URGRl7SWAsXLmTcuHEVEklRmdVqpaioCNB+Z0eMGIGjoyNLlizB2dm5wrEDBgwAqNBWMj09ndTUVMLDw+sv6AZq2LBh7Nmzh127dtluPXv25M4772TXrl3o9fpKj1FVFVVVbT+DH3/8kX///df2+NKSib/++kvaRFYhNzeXY8eOERwczLRp09i9e3eF1x9g3rx5LFy48JxjlP79Lf0ZNGcDBgyo1Db28OHD5/33HR8fT1pami2JBK0F4pAhQ2xdguRah8oWLlxIQEAA11xzjW1bREQELVq0qPbPoM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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAuIAAAErCAYAAACb7ObeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAACPZUlEQVR4nOzdd3hTZfvA8e9Jmrbp3oO2dLCRJXvIEgT8KYJ7M8RdUV9EBQc4XgVFAX2t4sStOFARFWQjQ5Ale0NpS0v3HmmS8/vjtGlLy2hpm477c1252pxz8pw7aSl3ntznfhRVVVWEEEIIIYQQ9Upn7wCEEEIIIYRojiQRF0IIIYQQwg4kERdCCCGEEMIOJBEXQgghhBDCDiQRF0IIIYQQwg4kERdCCCGEEMIOJBEXQgghhBDCDiQRF0IIIYQQwg4kERdCCCGEEMIOJBEXQgghhBDCDuyaiL/33nt06dIFDw8PPDw86NevH3/88Ydt/wMPPECrVq0wGo34+/szZswYDh48aMeIhRBCCCFEQxETE0NERATOzs706dOHrVu3nvPYxYsX07NnT7y8vHB1daVbt2588cUX9RhtZXZNxENDQ5k9ezbbt29n27ZtXHnllYwZM4Z9+/YB0KNHDxYuXMiBAwdYvnw5qqoyYsQILBaLPcMWQgghhBB2tmjRIqZMmcLMmTPZsWMHXbt2ZeTIkSQnJ1d5vI+PD88++yybN29m9+7dTJw4kYkTJ7J8+fJ6jryMoqqqarezV8HHx4c5c+YwadKkSvt2795N165dOXr0KK1atbJDdEIIIYQQoiHo06cPvXr14p133gHAarUSFhbG5MmTmTZt2kWN0b17d6655hpefvnlugz1nBzsctYqWCwWvv/+e/Ly8ujXr1+l/Xl5eSxcuJDIyEjCwsLOOU5RURFFRUW2+2azmQMHDhAWFoZOJyXxQgghhBANjdVq5dSpU3Ts2BEHh7L01MnJCScnp0rHm0wmtm/fzvTp023bdDodw4cPZ/PmzRc8n6qqrF69mkOHDvHaa6/VzpOoCdXOdu/erbq6uqp6vV719PRUf/vttwr7Y2JiVFdXVxVQ27Vrpx49evS8482cOVMF5CY3uclNbnKTm9zk1shvM2fOrDLfS0hIUAF106ZNFbY/+eSTau/evc+ZJ2ZmZqqurq6qg4OD6uTkpH788ccXl7DWEbuXpphMJk6dOkVWVhY//PADH330EevWraNjx44AZGVlkZycTGJiIm+88QYJCQls3LgRZ2fnKsc7e0Y8Li6OTp06sWnTJoKDg+vlOQkhhBDCDlQrjvu/x/ngYgCKQ/pQ0DMaHJzQn96OcdfH5Pf9D1afNnYOVJwtMTGR/v37s3fv3gqVD+eaET99+jQhISFs2rSpQiXFU089xbp169iyZUuV57FarRw/fpzc3FxWrVrFyy+/zM8//8yQIUNq/TldDLsn4mcbPnw4rVq14v3336+0z2Qy4e3tzUcffcTtt99+UePFx8cTFhZGXFwcoaGhtR2uEEIIIRoCswnWzoJjq7X7l98FPSeBTgeqCr88Amf2gt4AAx6HDtfaNVxRUXXzNZPJhIuLCz/88ANjx461bR8/fjyZmZn88ssvF3Xee++9l7i4OLtdsNngiqatVmuFGe3yVFVFVdVz7hdCCCFEM5SfDkv/oyXhOj0Mfhp636cl4QCKAv/3OkQOBEsxrJ8D69/QknfRKDk6OtKjRw9WrVpl22a1Wlm1alWV1xqey/nyzvpg14s1p0+fztVXX03Lli3Jycnh66+/Zu3atSxfvpzjx4+zaNEiRowYgb+/P/Hx8cyePRuj0cj//d//2TNsIYQQQjQk2ach9RA4ucNVL0FI98rHOLrC8Jdg11ew7WM48CukH4fhL4Kbf/3HLC7ZlClTGD9+PD179qR3797Mnz+fvLw8Jk6cCMC4ceMICQlh1qxZAMyaNYuePXvSqlUrioqK+P333/niiy9477337PYc7JqIJycnM27cOBITE/H09KRLly4sX76cq666itOnT/PXX38xf/58MjIyCAwMZNCgQWzatImAgAB7hi2EEEKIhiSoEwybCd7h4NXy3MfpdND9bvBrC6tfhjP7YPF9cNMn4OJTf/FWx76fIC8Vuo8Dh8q10s3ZrbfeSkpKCjNmzCApKYlu3bqxbNkyAgMDATh16lSFjnl5eXk8/PDDxMfHYzQaad++PV9++SW33nqrvZ5Cw6sRr21SIy6EEEI0QQeWgn978Gtds8dnJcCfz0FQZxg4pXZjq037l8Bfb4J/O2223z3I3hHVieaarzW4GnEhhBBCiHOyWmHzu1qd97JpUJhds3E8Q2Dsu9B/ctm2wmww2/E6NLMJdn8Px9eVbQvprtW4pxyCxfdDwnb7xSdqnSTiQgghhGgcigtgxfOwe5F2v+N1Wl14TRmMWhcVAKsFVs7UuqvkJF16rNVhMWs169/eAZvfgb/f0y4qBfAMhdu/1cppCrPgt6nw7yKtE4xo9CQRF0IIIUTDl5sCSx6FkxtA7wjDZmh104pSO+Nnn4a0Y5B6WKsbj6+HmWerFY6shO/GaV1c8lLA1V9rvaiUS9Hcg2DMO9B2JKhW+PtdWPWS9sZENGoNZol7IYQQQogqpR7VylDyUsDoBSNe0S7QrE1eYXDDh7BiBqQchN+nQu/7oetttZfsl5f4L2yYr3VuAe15XX43dLgOHBwrH+/gBEOma3Xxm9+B0zuhKFeb1ReNliTiQgghGpbiAojfBm6B4NembpKgxkpVtQ4aqYch/RhYTODoBgYXrT1fi8vLun8UF2jlDY6uWm/txmzHp1oS7h0Oo2aDR4u6OY97IFz3P9gwDw79DlsWaG0RBz0Fji61ey5V1ZJwRzct2e9044XPoSjQ6QbwbQ2o0naxCZBEXAghmhKzSeuwENQZ2l/T+JLY9OOwYiZkntLut/s/GPK0fWOyF6sVsuO1UoXSWc/tn2q3cxn9VlkifugP2PiW9r3BWJKsu4DBVUvOe98PAe21/WnHtDc/ji4lx7lp3zt7aTXK9v49GjwNjN5azJdSE34xHBxh8FNal5JN/4Nja7Q3NCNfubRxk/ZCVjy0G6Xdb9FNO0/EQHD2qN5YwV0q3j++DjJOajPqOqk6bkyaTSJutVqxWq32DkMIIeqWzgHCB6CsfgliN6EOehKcPe0d1cU59AfKxvnaLK+TB1hMqIGXaQkpQFYcyoZ5qC37Qlhf8Ayzf4JYWywmSD8BaUch7QhK2lEtOTYXol79OoT20o7zDENRdOAVDr6tUR1dUUx5UJwPxXmozl5lr1dxAbZXp7hAu+Wn2U6pmvLLjk3cjfL3u1XH5uKLOnAqtOxbF8+8alYLnFgHUUO1n7HBBQb8p2RfPf1f3uE68IlCWTsbtcc9NT9v2lGUbZ/Aqc3g4Iwa2kt7UwHQ9mrt66U8p/w0lLWztJ9vyiHUIdO1N1qNTHPN0ZpsH/GYmBhiYmIwmUwcO3aMHTt2EBwcbO+whBCizjmeWofbthgU1YzV2Zec3o9j9r/M3mGdm7kI110f4hy7GgBTQDdyez2Kaij5mF6v1cs6H16C655PbQ+zuAZhCupBcXAPiv062o5r6JTifFQU2yy3Y/xm3LbORVEtlY5VdY7kdX+AovCh2gZLyZLsF/tcLSYUcyFKcQGKOU/7WpyPUpxPcWBXLXEHDGf+xenU2pJ9BShm7auuIA3FaiJz2JtYvCK1Y5N2YEjZhymwK2bf9rX+uivFebhtmYvjmZ3kdZlIYZvRtTp+tVktFUp79OlHsXhHVbyYsgq6nNO47P8Wp/gNAKjoKAofQn6nO1GdvWs1RKcTK3Hd9SGKtRiLWwg5/Z7C4hFWq+eoa4mJiXTv3p3WrVtjMBiIjo4mOjra3mHVuSabiJcqbRAfGxvbrBrECyGaEVXVlu1uPbxssY/UIyirX4asOFAU1G53QffxDbNW+NAfKOtfB0WH2mMCdLuz6iQnJxFObkCJ+xsSd4PVXLbPwRn12nnahWwNSX46pB3Rfh5pR7QZ7+zTqAMeh45jtGNSDqH8/KBWcuHbGtW3jVYD7NdGWyXyAglfnbKYIGmPVnteEoey5lU4ukLbr3eEFt1QQ3pqs/Ze4Zf2KUVOIsryZ7QyCwcn1KHPQcQVl/48akvSHpSl/4GwPqhDp2slPGfLT4Ntn6AcXqZ1OAGIGqr9bp9v1c9LlXwAZeUM7RoCgxF18HSIHFh356tl8fHxhIeHN7sFfZpNIt7cfrBCiGZk51ew9QOtlviWz8su+CougI1vaxedAQR2guEzwS3AfrFWRVVhw1ytDCGk+8U9xpQPCdvg1N/arSgHxv8KBmdtf+my4C37QsBldVM3ay7SLiDMS9W+eoRAYEdtX2Yc/PqolohXpett0Pch7XuLGfJTtYtTG0OpzYm/4ORfEP9P5efn6g+3flGzTh5n9sPyZ6AgA1z9YOQs8G9bOzHXlqOrYO1s7Q2KZ6hWN+4dUfGYnDOw6E6trjy8P/ScVPPVP6srPx1WvqB1ZAGtDWKvexvF71VzzdeaTY24EEI0SUdXaUk4QLc7KnZdMBi1Cx1De2oXcGYnaDXk9mYugh2fl8TrqiUJA5+o3hiOLhA5SLupqtYDujQJB21Z8PTjsPNLbaY5rI+WlIf1vnDNvNUKhZnazKbBRVuBEbQ+1utfL0u+i3IqPu6y68sScSd3LSlSFK2W3a8N+LbRFmXxbaW1qiuld2hcy5ZHDtRupV0/4rdpSXniv9prWz4J3zBfew1De2pvBKtqywdwbDWsmaUluL6ttc4oDbEjSOth2huuFc9rF17+9BBcUVK73naE9tU9UFut06dV7bdYvBAXH7hmrtbtZc/32r+1RpCEN2cyIy6EEI1V4m74bYo289b5Zuj/yLmPzU7UZl2DOpdtsxSXrSpYXzJPaV1R0o9rSc2wGbV/DlWFoyshdpOWIJZPmBWdNktZ2gGjMAt2fKG9Nrkp2te81LKyl8uuhyseLzv2s+sqnsvBWZu9dfXXSig631QWQ8pBrVSjttveNVSlnxB4lvxfW1wIn11btkKkg7PWKSS0l5aYl5axZJ+Gb+/UyjjCB8CVzzX81yw/HVa9CKd3lW27/v2yLjQNwaktENJDe6MH2u9kA07Km2u+1gCmRoQQQlRbZpz2Mb6lWJud7Pvw+Y/3CNZupY6u0trgDZtZfx+bH10J69/UOnwYvaHdNXVzHkWBNldpN6sFzuwrKWHZXNK3+ayOEnu+r3oco3fFNypOHjBkGrj4lSTfflqNcFXJjaJAQIfae06NgYNTWRIO2msw6CntzVD8P1rJSWkpEWg/nyuf03qC94vWlpXv+3DjaL9XOvP893va749PJFiL7R1VRS37lH1vMWt/L9qO1N4AiwZDZsSFEKKxKciAn6O1UpOADnDt/IplGRditcIPE7UL4vQGrVb5shvqbrbMbIJNb8OBX7X7LbrBlTPA1bduznc+ucnam5fSchNVhS3vg4tv2cy2q592v74/LWjKbGUsJUl54m6tJ3iXm+0d2aUryAAnz4b9BmLfz9oiRQBdboE+Dza4C7eba74mibgQQjQ2eWnact9FOTD23bIFXKqjIBPWvQ6xG7X74QO0xUXK1y7XhuxE+PM5rVuIomgXj/WY2OCSAFHPzEXapxUNvQSlqbBaYdvH2jUToHXBGT6zrJ95A9Bc87UG/PZNCCFElVx9tRUUr51bsyQctIR75Csw4DGtBV3sRvjhHkjYXquh4uCkzRg6e8LVc7QODpKECwcnScLrk04Hve+Dq17SLp49vRMW3w8ph+wdWbMnibgQQjQWqUfLvnd00WprL4WiQKcbYOx7Wn/j/DT4bapWf34prOUWpnHxgZGvwo0fQ1ivSxtXCHFpogZrn6J5hmplWr88AsfX2TuqZk0ScSGEaAz2/QQ/TtI6fNQ2v9ZwwwfQ4VrodCN4XcKKfNmn4eeH4MjKsm0B7RtmKzohmiOfSK3DS/gArZ3p2X3QRb2SrilCCNHQxW7WFuapSwYjDHpSqyUtlXMGzuy9+C4LJ9bD2tfAlAv/fKjNvskFj0I0PE5uMOK/kHUKvMPtHU2zJom4EEI0ZCmHtX7FqhXa/Z92sWNdKu38YLXA6pe15c3jt2kLlJyrptdSXLKAyA/a/dIVPCUJF6Lh0ulkNrwBkNIUIYRoqHLOwLKntaXqQ3poq0/W54IcLS7Xznfod1h8H6QeqXxMdiIsmVyWhHe9TbuQ1C2g/uIUQtRcymH4+WH4rZqr24pa0WxmxK1WK9byH7kKIURDZspF+eMpbQU/70jU4S9oq0LW298xRWszGHw5ytpXbMt5q73vg043aQl6YRbK4vu0NopO7qiDn9bqTqEe4xRCXBKdA8qZfWAwolosdlt9s7nmaE02EY+JiSEmJgaTyQRAWloajo6Odo5KCCEujtPJ1bilHMHq7E1WzyewZuYD+fUfiEMLlIGzcdvxLo6nt8CGtzAd+Yvc3o+jOrrhEjIIQ8o+cvo8gdUYAMnJ9R+jEKLmLA74ms1gziY97giqs5ddwkhLSwNg6NChGAwGoqOjiY6Otkss9anZLOgTGxvbrBrEC9Ek5SRq9cpGb3AvWbLd0IR7ER/8DfzagF9be0eirYx4YAnK3zHgGYo6doHWf9xq1vZJPbgQjZbyzW2QewZ19NsQ1NkuMcTHxxMeHt7sFvRpsjPiZ9PpdOga8vKzQojzKy6Anx7QyiDKM3qBewvwjdK6fpQqyAQnj4a97HRVrNaymDuOtm8sZ+t0PbToCooexeCsbdPJJ41CNHqeoZB7BiU7Qfs3bgfNNUdrNom4EKIRUtWyekWDETrfpLXyA8g5DYXZWsJdkAkWU8XHLn1cW5jGPUhb+MY9uOyrZyj4tqrHJ3KRjqyA/T/DiFdqf6n52uITZe8IhBC1zTNUW1U3O8HekTQ7kogLIRqm1KOw6S3odR8Ed9G2XX43dB9flpwX5UJOkvafh1JuNkVVIS9VK5vIitdu5flEwc0Ly+7/vUBbdr203MW3DTh71O3zO9vpXbB2thbzwd/g8jvr9/xCiObLs2QRr6xLXFVXVJsk4kKIhqUgE7Z9DAeWar2zt74PY2K0fTp9xWOd3MCptbYyZHmKAuOWQF6KNnOenagl6zmJ2vflF7BQVW0Wurig4uP92kFoT2jZt+5rJjNOwp/PaUl41GDoenvdnk8IIcrzaqlNRBi97R1JsyOJuBCiYbBaYP8vsO2TsjrwVldC34dqNp5OB+6B2q3F5ec/b897tKXZs09rs+fZCZByULulHoH/e73s+Mw47WPc2mrxlZ8Of0zTnnNgJxj6bOOraxdCNG4t+8Ad39o7imZJEnEhhP0l7oYN8yD9uHbftxX0fxRadKv7c+sdoMstFbflpmj1kgnboEX3itsX3QWufhDSU5sxD+kBLj41O3dxISx/Rpup9wiBkf8FB6eaPxchhBCNiiTiQgj7y0nSknAnd+h1L3QYXbkMpT65+UO7UdqtvPTjWsu+vFQ4vEy7Afi21pLytiOrdzHjxrcg+YD2vK9+TT4WFkLYX/mL5EWdk0RcCFH/zEVaiUdpbXebqyA/DdpfU/8XSVZHyz4w4TdI2gPx/2gz5qlHIO2odvNvV5aI56ZAYZZ2/1ylJt3ugOT9MGgqeIXV3/MQQoizbY7ROjf1vk/7WyzqhSTiQoj6o6pwYj38/S5YiuHWL8HRRZt96dZILlB0cITQHtoNtBrv0zu0hYZCepQdd/gP+OdjrQ1hSA8I7aWVs7j5lx3jFQY3LZSacCGE/VmKoSCjcpcpUackERdC1I/047Dpf5CwQ7vvFqBdHHl2x5PGxsUHWg/XbuWZi7Te5wWZcHSVdgNtJdCBU7RPAUCScCFEw+BZspqlJOL1ShJxIUTdKsyG7Qth389aO0K9ozb73fUOKF2dsSnqfR/0mABn9pWUsWyHlENQnA9rXtXeiATbZwU7IYSoRBJxu2g2ibjVasVqtdo7DCGal8IslO/Ha7XSABEDUfs+pPWrBW0596ZM0UNQF+3WcxIUZWsL9xTlgH/Hpv/8hRCNh3swCkBWPKrFXHGRtHrQXHO0JpuIx8TEEBMTg8mkLXudfaGo6OjnaMSovlx8+6APvMk+V0nURzYBQqAgmR7h2U/ru3BFUhNs3ckQghRxqrHx2xBMeeRceoQVqNvvZ4+LU37mzh06FAMBgPR0dFER0fXawz2oKiqqto7iLoUHx9PWFgYsbGxhIaG2jscIZouSzHkJKLs+hq1xwRwD9K2m3LBwRl0TfZ9vxBCNAnKorsgOwH1mnn1s45DOfHx8YSHhxMXF9es8rVm8z+jTqdDJxdFCVF9qgqmPFAt4OypbSvMhn8+hLw0bRn5vBQozNSOBRRLEVz1onZsQ25HKIQQokxwV3APRNE71PuF5M01R2s2ibgQ4gKKC+DQH9piNXkpkF/yNS9V29dhtNbvGrTFdvYvqTyG3qAt097tzvqNXQghxKUb8rS9I2h2JBGvJ6qqoqqgAlbb9yVfy31vVVVUSraVzC5aVXB00OFi0KPTyWpXooZyk2Hvj5CdUJJsp0J4f62VHmi/dBvfOvfji3LKvnd0hZ4TweijLffu6q99dfKUdnxCCCHERZJE/BKtOZTMh+uPU2yxYi1JnrVkGyiXVNcGnQIujg64OTvg7qR9dXM6+74BNycH3J0dcC356ubkgJODDkWWrG2+kg/AsunaYg3l5Z4p+97RBVoP08pPXP3Bxa9ikm0wVnxsjwl1HrYQQgg7MBeBg5O9o2gWJBG/BPEZ+cSsPkqRuW5b7igKJbPlkFtkJrfITFI1x3DQK2UJeqVk3oCrkx4XRwdcHPU4G/S4OGo3o0GPseSrg15mOhul4+tg9X/BYgLfVtD+2pIEO0DrZV3esBn2iVEIIYT95aXB4vu0T0DvWS6fcNYDScRrqNhi5c0/D1NkttIl1JPJV7ZBpwAK6EpmnnWKgoKWSCsoKDpK7ivoSreVTFKXPabse0XBNottMlu1JLzQTE5RMbmFZltSnltkJqfQTF7J19LjcovM5BSZsVpVzBaVzPxiMvOLa/ycDXoFF0cHW6JemqRXSNgr3HfAWC6pD/Y0YnTU1/j89lJssXIsJZeTqXkEeRrpGOyBo0Mj+uOUn6Yl4S37wrCZ2sy3EEIIcTajl3bhvdWiXSPkHmjviJo8ScRr6Ku/YzmanIubkwP/uaotfm51+xGOo4MOHwdHfFyr1wtdVVUKi60Vk/fCcsm7qSyJzzdZKCy2kG+ylPveTLFFq60ptqhkFRSTVVCzZF5RoKWPCx2CPWgb6E77IHdCvIwNru49p7CYQ0k5HEjMZn9iNoeScmyvAWg/i8taeNAtzItuYV5E+rk27LKfTjeAiy9EXKFdZCmEEEJURafXFlzLitdukojXOUnEa2B3fCaLdyYAMHlY6zpPwi+Foii2meoA95qNYbZYKSi2UGCyUFApUde2FZos5JnMtu9LtxeUfJ9nMpOZX0xsWj6xafks26sV17g5OdAuyF1LzIO1r25O9fdrqaoqyTlF7D+tJd37E7OJS8+vVNfv7uxAlL8rp9ILyMgzsfNUJjtPZQLg5WKga6iWlHdr6WX/34eiHNjyPvS+v6x1YNRg+8YkhBCicfAM05Lw7High72jafIkEa+mnMJi5q44jKrCiI6B9G/lZ++Q6pyDXoe7Xoe7s+GSxknPM3EoKYeDSdkcPpPD4TO55BaZ2R6bwfZY7SJCRYEwbxdbYt4+yJ0wb5damzW3WFVOpOayPzGH/aezOZCYTXqeqdJxLbyc6RDsQcdgDzoEexDqbURRFFRVJS69gJ1xGew8lcnehCwy84tZdziFdYdTAAjzMZbMlnvTOcSzfstxshNh2dOQEQv56TDq1fo7txBCiMbPs2Qxnax4+8bRTNg1EZ81axaLFy/m4MGDGI1G+vfvz2uvvUa7du1sxwwZMoR169ZVeNwDDzzAggUL6jtcVFXlnTVHScs10cLLmXsHRtV7DI2Zj6sj/Vr50q+Vtmyu2WLlZFoeB5NyShL0HJKyCjmVns+p9HxWHtA6ehgd9bQNdKN9kAcdSmbNL/ZNQYHJwsEkbab7QEmZSWFxxYtrdTqF1v5udAh2p2MLLfn2cqm6BEhRFFr6utDS14Ux3UIotlg5lJTDzlMZ7IzL5FhyLnHpBcSlF/Drv4nodAodgtxts+VtAtzR11UpTtJe+PNZKMjUOp30vKduziOEEKLp8gzRvmYl2DeOixQTE8OcOXNISkqia9eu/O9//6N3795VHvvhhx/y+eefs3fvXgB69OjBq6++es7j64NdE/F169YRHR1Nr169MJvNPPPMM4wYMYL9+/fj6upqO+6+++7jpZdest13cbHPxWarDiSz6WgaOp3C1BHtGuWFhw2Jg15H6wB3Wge4c20XbVtmvjZrfuiMlpgfOZNDgcnCv3FZ/BuXZXtsiJeRdkHutsQ8wtcVnU4hNbeszORAYjYnU/O0VpLluDjqbbPdHVt40DrADWdDzX6WBr2OTiGedArx5O5+2icme+Kz2Bmnla6cyS5k3+ls9p3O5qstp3Bx1NO1pLa8W5gXwZ7OtVNffnQVrJ2tXZTp1xZGzdI6owghhBDV4Rmmfc2Ks28cF2HRokVMmTKFBQsW0KdPH+bPn8/IkSM5dOgQAQEBlY5fu3Ytt99+O/3798fZ2ZnXXnuNESNGsG/fPkJCQuzwDEBR1drqcn3pUlJSCAgIYN26dQwaNAjQZsS7devG/PnzL2qMoqIiioqKbPcTEhLo2LEjJ06cuKQXOTGrkCnf76aw2MqdfcK4qbt9fmDNjcWqcio9n0NncksS9FwSsworHeds0OHq6EBaFWUmAe5OdCgpc+kQ5E6Yd/1dIJqUXci/cVnsis9iT0IWeUWWSrF1DfWka5gnXUI8Ks30q6qKxapSbFEptli1m1X73mxRKTZbcD/4Hb4Hv0RVIdO/J0cue5wiHDFZrBRbVMzWkq8WK2arqvWid9KXtbAs15NeFo0SQohmLjcZ/bpZqD6RWPs9Wm+nTUhIIDIykv3791fI15ycnHByqvraqz59+tCrVy/eeecdAKxWK2FhYUyePJlp06Zd8JwWiwVvb2/eeecdxo0bVztPpJoaVI14VpY24+nj41Nh+1dffcWXX35JUFAQo0eP5vnnnz/nrPisWbN48cUXK21ftWoVfn41myG0qPDNMR1n8hVCXVWcE9P5/fd/azSWqLk2QBsvKHCDxHw4na9wOl8hKV8hq6TaRAECjCohriotXCDEVcXdABQlYo2FfbGwzw6xdwYuC4QzBRCbq3AyR4s9KwuOxCfzw9/acW4GFasKFlXBbNV+987HqBYw07qIfPJYoQzg+8xhqEdr/gwVwEmv4qwHZwcw6tG+16s4lXxvdNDuO9v2aTdpMy+EEE2EchVkAL//Xm+nTE1NBaBjx44Vts+cOZMXXnih0vEmk4nt27czffp02zadTsfw4cPZvHnzRZ0zPz+f4uLiSnnnuRQVFbFlyxZiY2PJz8/H39+fyy+/nMjIyIt6fFUaTCJutVp5/PHHGTBgAJ06dbJtv+OOOwgPD6dFixbs3r2bp59+mkOHDrF48eIqx5k+fTpTpkyx3S+dER82bFiNZ8S/2hpHwakEWgTomXtLF/t3xRAVWK0qcRkF5BaZifJzbTQlQwUmC/sTs/k3PotdcVnEZRQAoAfOVQGvU7RyGINewaHk61LLf4i0HOeYx2D6OJTs02lfS4816HU46BX0ikK+yVLWg76w7PvyC1OpQEHJDRUwl9zOw9mgw9XJAT83R8J9XLSbrwstfYyXfKGvEEKIpi0hQatJr2pGvCqpqalYLBYCAyu2WAwMDOTgwYMXdc6nn36aFi1aMHz48PMet3HjRt566y1+/fVXiouL8fT0xGg0kp6eTlFREVFRUdx///08+OCDuLtXr0Vdg0nEo6Oj2bt3Lxs2bKiw/f7777d937lzZ4KDgxk2bBjHjh2jVatWlcY5+yOM7OxsABwcHDAYqp8M7E3I4qedp1EUhUeubEOwt1u1xxB1r3VQ9fqrNwQGg4G+rZ3p21qrY0vPM5GWW6Qlzw46DLqyBNqg1+Go12llI1nxkHas1lsSVrVoVE65haG0+8XljtG+5pnMqCoUmVWKzMWk5xVz+ExehbG9XR2J8HWhpY8LEb6uhPu6EObjUuPafCGEEHWsuFC77qi0DW4dc3DQUlJ3d3c8POr+nLNnz+bbb79l7dq1ODs7n/O46667jh07dnDHHXfw559/0rNnT4xGo23/8ePH+euvv/jmm2+YO3cun3/+OVddddVFx9EgEvFHHnmEpUuXsn79ekJDQ897bJ8+fQA4evRolYl4bcotMjN3xWGsKlzZPoCBbfzr9HyiefNxvYgFmxJ3a51RTPlgnAvBXWvt/DVdNMpqVckzlS0SlZhVyKm0PE6m5ROblseZ7CIy8ky2/uulFAWCPZ0JL0nMI3xdaenjQgsvY911lhFCCHFh2xbC9k+h803Qf7K9o6mSn58fer2eM2fOVNh+5swZgoKCzvvYN954g9mzZ7Ny5Uq6dOly3mOvueYafvzxx3NO5kZFRREVFcX48ePZv38/iYmJ1Xoedk3EVVVl8uTJ/PTTT6xdu/aiamx27doFQHBwcB1HBwvWHiMlp4hAD2ceGCytCoWdHVkB614DSzH4ty+7st3OdDoFd2cD7s4Ggj2hbaA7UPamtcBkITY9j5Op+ZxKL0vQswvMnM4s5HRmIZuPpdmON+gVwmylLa5E+GlffV0dG/QKpharWrbwlclCobls4auCcgtcFRRbUFUVTxdHvF0MeLs44u3qiI+LY4MuqyostpBVUExmfjGZ+SYMDjo6BnvIpxpCNEK5RWaOJedyNDmXYym5pOeZuHdgFK0DSj71d9HaDDfkFoaOjo706NGDVatWMXbsWEArc161ahWPPPLIOR/3+uuv88orr7B8+XJ69ux5wfM88MADFx1Tx44dK9W4X4hdE/Ho6Gi+/vprfvnlF9zd3UlK0lZbLK29OXbsGF9//TX/93//h6+vL7t37+Y///kPgwYNuuA7mEu15lAy6w6noFPgiRFtcXFsEB8eiOZIVbWZie2favcjB8HQZ8Fw7o/SGhKjo572QR60Dyr7qFFVVbIKim1J+clU7eup9HyKzFaOp+RxPCUPSLE9xtVJT7iPKyHeRhwddCiAXqegKAo6BXQlX7X7CnodKCjodEq5Y0uPU0ouLlW07WftN5mttkS6qNwKsuVXji00WykwmSkstpJvMlN8oStrL4KzQYeXi5aUe7lqSbpPSaLu7WIo+eqIl9Fwyd1trFaVnCIzWfnFZBaYtAS7oJisfBNZBcVk5BeXJN7a/bP774P2pqlLqBc9wr3pEe5NCy9jFWcS4txyi8wYDfpG+SlYUlYhG4+msisuE3dnB0K9XQjzMRLq7UILL2ecHBrGm9S8IjPHUnI5ckZLuo8mV9197Pc9iTw6rI12x9ZLvGG3MJwyZQrjx4+nZ8+e9O7dm/nz55OXl8fEiRMBGDduHCEhIcyaNQuA1157jRkzZvD1118TERFhyzvd3Nxwc7tw6XFcXByKotiqN7Zu3crXX39Nx44dK5RSV4dds8v33nsP0FoUlrdw4UImTJiAo6MjK1eutL2wYWFh3HjjjTz33HN1GteZ7ELeW3MMgNt6t6RDcP3URwlRidkE61/XZsMBut0Bve4DXeNuUaIoCl4ujnRzcaRbmJdtu9WqciankNjSBD0tn1Np+cRn5JNXpF3cuj8x236BXwS9TsFo0GN01Nu+Oht0uDg64Oygw+jogKJAZn6xVrKTr90Ki60UFltJyiokqYr/JMvTKeBhLEnUXR3xKjez7u1iwMvoSKHZQuZZyXRGvomsAjOZ+SayC4or9di/EINe+7l5GQ1k5JtIzTVVWBm3hZczPcN96B6urSrr6NC4f09F7cvIM7EnQWvnujs+k9OZhbg5OdAzwpvekT50b+mNq1PDnfg6nVnAhqOpbDqayrGUvHMepyhae9pQbxdCvY22r2HeLni61N3F66VJ99HksltVSTdAoIcTrQLcMOh0rDucwsnUcs+n9BPXnESwWkDXMN5UnO3WW28lJSWFGTNmkJSURLdu3Vi2bJntAs5Tp06hK/f/5XvvvYfJZOKmm26qMM65OrOc7Y477uD+++/n7rvvJikpiauuuorLLruMr776iqSkJGbMmFHt59Cg+ojXhfj4eMLCwoiLi7tg/TloHy9P+3E3B5Ny6BDszqwbujTKd+qiiTiwFNbP0f4IXjEFOlxr74jswmS2kpBZwMm0PJKyCrFYVVRVa/VoLfmq3S9p/1iSYVqsapX7rVYVtWS/ahujbL+jXoezoTSR1mE06LX7jnpcHPU4O5Qm2CX3yyXehhr2cSwwWcjIN5Gep81OlyboGXnFtu0ZNUygz8fNyQEvFwNeLgY8jVpS72XU7pcm+54l940Gva08SFVV4tIL2BabzrbYDPadzsZaLjBHBx1dQj3pGe5DzwhvAj3s+wlOkdnCqbR8jqXkcTItj5OpeeSZLCVvjrSfnVPJz9zZoLO9iXIq/VmXO8653O+Ds4MOB+ndeU6Z+aaSpDuLvQlZxJd0hzoXvU6hc4gnfaJ86B3hQ4Cdf28AEjIL2HgklQ1HUzlRLlnVKdA51JO+Ub6YzFbi0guIz8gnvqSL17los+fGCkl6mI+RQHfnan3SdXbSfSwll9OZ50m6/d1oFeBGmwDtq0dJN6uEzAIe/GI7Br3C9w/213IeqxU+GaldrHnb12Uz5HWouvmaPXh7e/P333/Trl073n77bRYtWsTGjRv5888/efDBBzl+/Hi1x2y4bzvt5LttcRxMysHoqOeJEe0kCRf21f4aSD0EkUMgtIe9o7EbRwcdkX6uRPq5XvjgRsroqMfoaLxgeYfVqtpmt7UEXfs+s+T7zHwtkS8tcylNor1KZsq15NqAp1FLtGv6xkFRFFr6utDS14UbuoeSbzKzKy6T7Scz2H4qg7RcE9tOZrDtZAasg1BvIz3CvekZ4UPHYI86my1XVZX0PBMnUvM4nqol3CdS8zidWVCrb2DKM+gV2xu3siRdh5ODHgVs5VEAlJQ/ld5XlJISqnIbFLRjyvZTIUErfYyigKfRQIiXkRZezrTwMtq9jDIrv9g24703IYtT6fkV9isKRPq50jnEk84hnnRo4UF8egFbTqSx9UQ68RkF7IrLZFdcJu+vO06Enyu9I33oG+lDK3+3eltwLC49n03HUtlwNK3CTLFOga5hXvRv5Ue/KN8qZ7dLS+/iM8oS89Lvk3OKyCk0cyAxhwOJORUe56BXaOFlLEvOS76GeBlRUTmWnMfRlBxbicm5ku4AdydalyTbrUtuHudpIRvs4YyTg44is5XTmQWE+bhon7p6hkD6Ca1TVz0k4o1BcXGxrTPfypUrue666wBo3759tS/SLCWJeDkHErP5duspAB4a0sruMziiHqkqmAuhMAsKs8GrZVkNdvx2OPkXmHLBwRmMXuBccjN6aUvK12Z7pzP7wKeVdn5FgYFP1N7YotHT6RStBKWa3W3qmoujA/1b+dG/lR+qqnIyLZ9tJ9PZcSqD/aezbcnIL7tO42zQ0SXUi14R3nQP9ybAvWZ/a4stVuIzCjiZmsexlFxOpmlJd3ZB1bORnkYDEX4uRPm5EenniofRQFGxdmFtgcmqXVhbrF1gW/a91XZtgHacti2/2GL7BEBb+VbrGmRvXi6libmREC8jwV7OhHq5EOTpXCdvfrIKitmXkMXuhCz2xFdOvEFLvLuEetIpxJPLWlReQbhjCwMdW3gwcUAkCZkFbC1JyvefzuZkyZup7/6Jw9vVkT6RPvSO9KFLqGet12CfSstn4zFt5vtUWtnz0OkUuoV6MqC1H31b+Z43qYWy0jsvF0c6hXhW2FdYbOF0ZkGF5Lz0a7FF5VRJOR6kVT34WfzdnbQZbv+yxNvTWL3SF51OIdzXlcNncjiRmqcl4gCeoVoinh0P9KnWmE3VZZddxoIFC7jmmmtYsWIFL7/8MgCnT5/G19e3RmNKIl4i32TmzT8PYVVhcFt/hrYLsHdIoqZUFUx5UJRdllgXZkHLvmUJ89GVWtlH+WMsprIxrl8AAR2079OOwr6fzn2+a+aWzVYf/hO2fVKSrHuWJevOJfdDe4FbSUcRq7VkaqvcDM+hZVopSnh/GP5io68FF82Toii2TzBu7hlGbpGZf+MytRny2HQy84vZeiKdrSfSAWjp41IyW+5Nh2CPKmfpswuLOZGSV2Gm+1R6vq0MqTydAiHeRiJ8XYnydyPSz4VIPze8XQy12nmn2FIueTdZyyXqFvKLLRQVW4HS8ifQCqK0P1Eq2sxp2X3tuPL7VKDkIVhL7pcWk6qoWK0q6XnFnM4s4HRWQUlHG+2273TFaykUBfzdnGhRkqS38HIm1NtIsKeRQA/ni/70N7uwmL0lSfeehCxi0yon3uG+LrbEu1OI5wUT1/JCvIxcf3ko118eSnZhMdtPZrDlRDo7YjPIyDOxbG8Sy/Ym4eSgo1uYF32ifOkV4Y2XS/XfmKqqyqn0fDYeTWPj0dQKbyL0OoVuYV5a8h3lU2uLkjkb9ET5uxHlX/HCQKtVJSW3iPiM/AolLvEZBWQVFANa0t06wI3WpUm3v1ut1ZtH+Zcl4oPalvwfFdobHN3BK7xWztEUvPbaa1x//fXMmTOH8ePH07Wr1kJ4yZIl9O7du0ZjSiJe4v11xzmTXUSAuxMPDqnb/uSijuz5AXZ+qSXXVkvl/WPfA+eStkL56XB6Z+Vj9AZw8qiYlAdeBpffBU7uUFxQkrhnQkGm9r1LuaVx85K1i1tyzvER1TVzyxLxQ7/DhnllSbvBCEl7tX06PVjNoGtYs55C1ISbkwMDWvsxoLUfVqvKibQ8tpck5YeScjiVns+p9Hx+2pmA0aCnW0svOod4kplvstV0p+Waqhzb6Kgnys+VCD9XokqS/5a+LvXSsUJbuVbXYFaOzSsylyTlhSRkFGjfZxaQkFlAvslCck4RyTlF7IrLrPA4nU4hyMOJEC+t24dtRr2kQ9G+hGwt+U7I4mRaHmdfWdbS14XOIZ50CfHkshDPas/InouHs4Gh7QMY2j4Ak9nK3tNZbD2RzpbjaaTmmthyIp0tJ9JRFGgX6E7vSB/6RPoS5mM85xsuVVWJTctnw9FUNh5NrVCzrtcpXN7Siyta+9E7svaS74uh0ykEejgT6OFMj7Py3uzCYlSVWntdq1Ja9le+Bp6O12k3QX5+Pi4uLgwZMoTU1FSys7Px9va27b///vtxcXGp0diSiAPrD6ew+mAyOgWmjGiLWwO+YluUY8rXElaHkpVUVRUKMsr2OziXzEp7aF/15f6IhfUGo0/ZPiePsmT47D/gQZ2028Vo938Q3E1L1AuzSpL1ct+7lfukpTBTS7bzUrVbqcvvgp6TZDZcNEk6naJ9jO7vxi29wsgpLGbnqUy2xWaw81QGmfnFbD6WVqG3fKlAD2ei/F1LZrq1pDvA3alB95evT65ODrQJdKdNYMUltlVVJbvATEJJUp6YVUBCRun3hZjMVltP/4vR0seFTiGedAnVSk1qMhtdXY4OOrq39KZ7S28eGBTFidQ8tpR8qnI0OZeDSTkcTMrh882xBHk620pYOgZ7oNcpnEjNY+NRreyk/PN00Ct0b+nNFa396BXp0yD//6/OJwo1VWUiLmz8/Py48sorue666xgzZoytK0upiIiIGo/d7LumJOcUMvnrneSbLNzaK4y7+spHMA2exQwHf4Xtn2mrfl1+l7Y9P127lSbfpQl6Q2U2aW8cys+we7S4+KRfiCbGalU5lpLL9tgMDibl4OfmWDLT7UaEn4vdL0RsiqxWlbQ8k5aUlyTqCSUz6UnZRVitKqHeRjqHetousKyPxLs6UnOL+Kdkdnx3fGaFnv6uTnrcnAycyS5Lvg0lyfeAkpnvhtwusb4UmCzc8v5mAL6c1Kes5MVsguwE7bqpOm5h2JC7ppw6dYpffvmFX375hQ0bNtC1a1euu+46rrvuOjp37nxJYzebRDw2NrbSD9ZqVXnul33sPZ1Fu0B3Zl3fSdpQNWSqCsfXomz7WPvDAODXBnXsAlDk5yaEELXJbLFSZLY2qkS1wGRhV1wmW0+m88/JDLILtfpqR72OHuHe9G+l1ZTLm7rKHvhiO4nZhbx83WV0DfMCVUX57BooLkC95fM6X805Pj6e8PDwBpmIl5eVlcXvv//OL7/8wrJly/Dx8bEl5YMHD0avr94blib7mxgTE0NMTAwmk1ZXmJaWhqNjxXfxS/elsis2DWeDjvGX+5CellrVUKIBcEjejeveL3HIOAqA1cmLgvY3URh5FaTIz00IIepKYytWaOUOrTp7cmsnD46lFpBbZKFDoCvOBh2gkpuZTq69g2yAAlwU4tLM7DqeSLCTljt5GrxxKMgm++ReioPr9lPmtDStHG3o0KEYDAaio6OJjo6u03PWhKenJ7fffju33347xcXFrFmzhl9//ZWJEyeSk5PD//73P+68886LHq/ZzogfOZPDUz/uwaKqPHZla4Z1CDzPKMKudn2F8s9H2vcGI2rnW6DLLWCo2YURQgghhKjo23/i+HrrKYa29ec/V7UFQFkxA07+hdovGjrddIERLk1jmRE/n507d2I2m+nVq9dFP6bJzoifTafT2ZY5LTBZmLvyCFYVrmjtz/COQXKxT0OjqmUXTUYNgZ1faIvbXH43SvkuJUIIIYS4ZFH+bigonEwvKFsW3ksrR1GyT9d5AwFdI2tQkJeXx6JFiygoKGDEiBG0adOGyy+/vNrjNJtEvLwP/zrO6cxCfN0ciR7aSpLwhqQgA3Z8AZYiGPSkts0rDO78oXYXzRFCCCGETWnnlLj0fIotVq2fv2fJzHRWvB0js79Tp05x9913s2PHDvr27cvHH3/MVVddxZEjRwAwGo388ccfDBo0qNpjN663H7Vg09FUVuw/g6LAE1e1azD9X5s9U77WBeWbO2Dvj3DwN8hKKNsvSbgQQghRZwLcnXBx1GOxqsSVLm7kUbK0fTNPxKdOnYrJZGLBggW4uLgwcuRI2rRpQ2JiImfOnOHqq6/mhRdeqNHYzWpGPDW3iP+t1i72u7F7KJ1DPS/wCFHnyrciLO0B7tcW+jwIniH2jU0IIYRoJkpXxN13OpuTaXna6p+lnVJyz4CluOJ6HM3I+vXrbatnXn311fj5+fHJJ5/Y+ok///zzDBs2rEZjN5tE3GpVmbfiMLlFZloHuHFHn5b2DkmkHYMVM8reaXuEQK9JEDVUFrMRQggh6llpIn48JY8r26OtHN3+GnAPataJeHJyMuHh2jozPj4+uLi4VFjUJygoiIyMjHM9/LyaTSK+fF8Su+OLcHLQ8cSItlrtk7Av9yBtOXqjN3QfBx1GN9t/5EIIIYS9ldaJn0wraVqpKDD4KTtG1HCUv56wNq8tbDaJ+Pfb43Hy9OfegVGEekvbO7tIPQKHl0O/aO0ft6MrjHoNvCPAUX4mQgghhD2VX+peVVVpZlHOjBkzcHHRchWTycQrr7yCp6dW4pyfn1/jcWuUiJ86dYrY2Fjy8/Px9/fnsssuw8mpYS8nbrWq9Gvly8jLpF94nbNaIS8FchIhJ0n7mnYUTm7Q9gd3gciSK4sDO9ovTiGEEELYtPR1QadAdoGZtDwTfm5OWklKTiJYzeATZe8Q7WLQoEEcOnTIdr9///4cP3680jE1cdGJ+MmTJ3nvvff49ttviY+Pp/w6QI6OjgwcOJD777+fG2+8sUH2gvRyMfDIla3l3V1tsFohP7Uk0T4DOachtHdZUh33NyybXvVjWw8H3zb1F6sQQgghLoqTg54QbyNx6QWcTM3TEvGjK2HtbAjpAdfOtXeIdrF27do6G/uiEvFHH32Uzz77jJEjR/Lf//6X3r1706JFC4xGI+np6ezdu5e//vqLGTNm8OKLL7Jw4cJqrSpUH+4bFIWHtCq8OFYr5Kdp9dpGL21b6lH4+11thjv3jPbOuDydoSwRdw8CnYP21S0Q3IO171v2A7/W9fpUhBBCCHHxInxdiUsv4HhqHj0jfKSXeB27qETc1dWV48eP4+vrW2lfQEAAV155JVdeeSUzZ85k2bJlxMXFNbhE/LIW0qqwSqoKcVu0spHSUpLSNkV9HoBud2jHKQokbC97nE5fkmQHgVtQxY+rvCJg0grpfCKEEEI0MpF+rvx1JJWTqSUXbJb2Es9LBrMJHBztF5ydZGZm8s033/DQQw8BcOedd1JQUGDbr9fr+fDDD/Hy8qr22BeViM+aNeuiBxw1alS1g6gPVqsVq9Vq7zAalqw4lBUzIeNE5X2KDrUoR5sdB21We/A0LfF2DwZXP1DOSrTPfn3l9RZCCCEalQhfF1RUjqfkanmTkyeKwQWK81Gz4rUGC3WgIedoH374Ibt27bIl4kuWLGHkyJG4u7sDsHnzZubPn1+jRX2qfbHmiRMnMJvNtGlTsc73yJEjGAwGIiIiqh1EXYiJiSEmJgaTyQRAWloajo7N711cJaqqzW4DWBS8s5NRcKAwfCgWrygsroFYXfyxGn21We/k5LLHel2ufc1HqxEXQgghRJPiphZjLjZzKjWH+NNJODro8HTyw6HgGDkn92AqrpsuZ2lpaQAMHToUg8FAdHQ00dHRdXKu6vrhhx945ZVXKmx7/fXXiYrSqgF++uknXnrppfpJxCdMmMA999xTKRHfsmULH330UZ0WtFdH6Q8wPj6esLAwfH19CQgIsHdY9lOQCfsWo5zegTr67bLZ7Gtmg1c4bk7udg1PCCGEEPbnr6r4eiSQVVBMgd6V0AB3lIBWkHsKL10e1FEuVTpxumbNGkJDQ+vkHDV1/Phx2rVrZ7vfrl27CpO7Xbt25ciRIzUau9qJ+M6dOxkwYECl7X379uWRRx6pURD1QafTNchuLnUu+zTsXgQHfweL9kuuxG+F8P7a/uAudgxOCCGEEA1NpJ8r/8ZlcTK9gHbBnuClLXWv5CTU2fVfDTlHy8vLIysri7Aw7XXYtm1bpf01La2pdiKuKAo5OTmVtmdlZWGxWGoUhKgDqUdg19dwfC2oJb8c/u2h2+0Q1teuoQkhhBCi4Yr0c+PfuCxOlF6wGdpL+yQ9qHlO3kVFRbFjxw46depU5f5t27YRGRlZo7GrnYgPGjSIWbNm8c0336DX6wGwWCzMmjWLK664okZBiFqWchgW31d2P7SXloC36F5WHy6EEEIIUYWo0qXuSxPx4C7N+hP066+/nueee46RI0cSGFhxYcikpCRmzpzJuHHjajR2tRPx1157jUGDBtGuXTsGDhwIwF9//UV2djarV6+uURDiElmtkHmyrIWgXxsIvEzrcNL1du2+EEIIIcRFiChJxI/LUvcAPPXUU/z444+0adOGu+++m7Zt2wJw6NAhvvzyS0JCQnj66adrNHa1E/GOHTuye/du3nnnHf7991+MRiPjxo3jkUcewcfHp0ZBiBoym+DwMq0GvCAD7vgOnNy0We/Rb4O+2j9eIYQQQjRzod5G9DqFApOF5JwiAj2ctWvOMuPAvy0Yve0dYr1yd3dn48aNTJ8+nW+++YbMzEwAvLy8uOOOO3j11VdtrQyrq0aZWosWLXj11VdrdEJRC4pyYP8S2PsD5Kdr25zcIf0YBHfV7ksSLoQQQogaMOh1tPRx4URqHsdT8rREfOWLkHIQrnoJogbbO8R65+3tzYIFC3jvvfdISUkBwN/f/5I/LahRtvbXX3/x/vvvc/z4cb7//ntCQkL44osviIyMbH514jln4ORf4OAMHa4t255xUuvZbXABgxEcXbW+3JeiIAP+XQT7f4HifG2bWwB0vgXaXwOOddPbUwghhBDNS4SfKydS8ziRmke/Vr7aUvcpByE7wd6h2ZWiKLXaDrvaifiPP/7I3XffzZ133smOHTsoKioCtK4pr776Kr///nutBdegmU2w+1vY+SWYi7SEuHwivvY1SN5f8TF6Ry1ZdvGDmz4u277jC21peYNR228ouTm6gKMbtCzpclJcqJWhqFZtZatud0CrYTL7LYQQQohaFeXnyhrgZFrJBZueJb29s+LtFpM9jBo1ihdeeIG+fc/fcS4nJ4d3330XNze3ai1EVO0M7r///S8LFixg3LhxfPvtt7btAwYM4L///W91h2t8VBViN8Hmd7R6KYCAjtrFkeU5uoKzBxQXgKVY22YxQYEJdIaKx57aDGf2VX0+gwvc84f2vUcw9LwHfFtpLQgbcM9NIYQQQjRetgs2U5p3In7zzTdz44034unpyejRo+nZsyctWrTA2dmZjIwM9u/fz4YNG/j999+55pprmDNnTrXGr3YifujQIQYNGlRpu6enp614vcnKToQN8yBui3bf1Q/6PqTNSp9dI3TNG2XfW4q1UhJTvvZVPavp+2XXa7PepfuLC0q+5muz6OV1v7v2n5cQQgghRDmRJYn4mexC8k1mXDxCtB3NrDRl0qRJ3HXXXXz//fcsWrSIDz74gKysLEArU+nYsSMjR47kn3/+oUOHDtUev9qJeFBQEEePHiUiIqLC9g0bNhAVFVXtABoVqxlO7wCdA3S5FS6/6+LqsvUG0HuCs2fV+9tcVbtxCiGEEEJcAk+jAV83R9JyTZxMzaejT8mMeF6qNmFoMNo3wHrk5OTEXXfdxV133QVo5dgFBQX4+vpiMBgu8Ojzq3Ztw3333cdjjz3Gli1bUBSF06dP89VXXzF16lQeeuihSwqmwVFVOFOuztsrDAY9BTd/Cn3ul4sjhRBCCNFkRfhqs+InUvO0clunkhZ9Wc1rVvxsnp6eBAUFXXISDjWYEZ82bRpWq5Vhw4aRn5/PoEGDcHJyYurUqUyePPmSA6orVqsVq9V64QNLpR1F2fQ/OLMHdcy72vLwAK2Hlw5Y+0EKIYQQQjQQEb4ubItN53hKDlZrIPS6DxycwMW31vOgauVoTUi1E3FFUXj22Wd58sknOXr0KLm5uXTs2BE3N7e6iK/GYmJiiImJwWQyAZCWloajo+MFHgWKKReXfV/jdPxPFKyoOkdyT+7BpMpiRUIIIYRoPrwdijEXmzkQn0Zysgf49tF2ZBdBdnKtnistLQ2AoUOHYjAYiI6Orlb3kcZKUVVVvZQBSpe2b9euXY2K1OtafHw8YWFhxMbGEhoaeu4DVSsc/A3ln4+gKFvbFjkYte9D4BZYP8EKIYQQQjQQ8Rn5PPz1Tpz0Ohbd3xedru6Wuo+Pjyc8PJy4uLjz52tNTLVnxG+55RYGDRrEI488QkFBAb169eLEiROoqsq3337LjTfeWBdxXjKdTofufO3+fp9W1g3FOwIGPAohPai7XzkhhBBCiIYr1NsVJwc9JrOVpJwiQl3R2i0X59f66prnzdGasGo/6/Xr1zNw4EAAfvrpJ6xWK5mZmbz99tuNu494xBXa4jn9J8ONH0NID3tHJIQQQghhNzqdQriP1pjiRGoeZJ6C36dqrZybMZPJRHx8PKdOnapwq4lqJ+JZWVn4+Gj10suWLePGG2/ExcWFa665hiNHjtQoiHpnMcPu7+DkxrJt7a+F276EzjfJSpVCCCGEEJT1Ez+Zmle2qE9BBpjy7BiVfRw5coSBAwdiNBoJDw8nMjKSyMhIIiIiiIyMrNGY1c44w8LC2Lx5Mz4+Pixbtsy2umZGRgbOzs41CqJexW+HTW9BRqxW+x3SAwzO2iqVRm97RyeEEEII0WBE+pessJmaB04RYPSCgkythaF/W3uGVu8mTJiAg4MDS5cuJTg4GOXsxRxroNqJ+OOPP86dd96Jm5sb4eHhDBkyBNBKVjp37nzJAdUVJS8F/nwfTqzXNhi9oMf4yitXCiGEEEIIoGxG/ERqyQy4R2hJIh7X7BLxXbt2sX37dtq3b19rY1Y7EX/44Yfp06cPp06d4qqrrrIV10dFRTXoGnHjH4+BUQFFpy0p33NiWWN6IYQQQghRSWkinpZrIqewGHfPUDizt9ktdQ/QsWNHUlNTa3XMGhVD9+jRgx49Kl7MeM0119RKQHVFsZqgRR/o/yj4trJ3OEIIIYQQDZ6LowOBHk6cyS7iRGoeXUrrxLPi7RtYPcnOzrZ9/9prr/HUU0/x6quv0rlz50ora3p4eFR7/ItKxGfPns1jjz2G0Wi84LFbtmwhNTW1wSXmhf2mQN+boRbqeYQQQgghmotIP9dyiXiItrGZLHPv5eVVoRZcVVWGDRtW4RhVVVEUBYvFUu3xL6pryv79+2nZsiUPP/wwf/zxBykpKbZ9ZrOZ3bt38+6779K/f39uvfVW3N0vruRj/fr1jB49mhYtWqAoCj///HOlYw4cOMB1112Hp6cnrq6u9OrVq0YtYixh/SUJF0IIIYSopkg/bfX04yl5ENgZhkzX2j03ADExMURERODs7EyfPn3YunXrOY/dt28fN954IxERESiKwvz58y84/po1a1i9erXtdvb98ttq4qJmxD///HP+/fdf3nnnHe644w6ys7PR6/U4OTmRn58PwOWXX869997LhAkTLrp7Sl5eHl27duWee+7hhhtuqLT/2LFjXHHFFUyaNIkXX3wRDw8P9u3b1zi6swghhBBCNAERfuV6ibu1hXaj7ByRZtGiRUyZMoUFCxbQp08f5s+fz8iRIzl06BABAQGVjs/PzycqKoqbb76Z//znPxd1jsGDyxYuOnXqFGFhYZW6paiqSlxcXI2eQ7WXuLdarezevZvY2FgKCgrw8/OjW7du+Pn51SgAWyCKwk8//cTYsWNt22677TYMBgNffPFFjcctXeK+uS2ZKoQQQghRG5KyCrnv82046BW+f6AfDvraXwWzJvlanz596NWrF++88w6g5ahhYWFMnjyZadOmnfexERERPP744zz++OMXHaNerycxMbFSkp+WlkZAQECNSlOqfbGmTqejW7dudOvWrdonqw6r1cpvv/3GU089xciRI9m5cyeRkZFMnz69QrJ+tqKiIoqKimz3c3JyAK2Epri4uE5jFkIIIYRoaryddTg5KBQWWzmZkkO4Go+SegjVvz34tqmVc5jNZkDL28pfIOnk5ISTk1Ol400mE9u3b2f69Om2bTqdjuHDh7N58+ZaielspbXgZ8vNza1xtUaDXUIyOTmZ3NxcZs+ezX//+19ee+01li1bxg033MCaNWsqfFRQ3qxZs3jxxRcrbV+1atUlz9oLI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qS0bRPNWmn7woiICPl3IIQQwi7i4+MJDw+X9oVNlU6nq7QEuU6nQ1EU202I5qj097+qfyNCCCFEfWiu//80z2ctRB1QFIWff/65Ro8dMmQIjz/++HmPiYiIYP78+ec95oUXXqBbt241ikEIIYQQ9UsS8UZowoQJtllMR0dHWrduzUsvvVShzt1isTBv3jw6d+6Ms7Mz3t7eXH311WzcuLHCWBaLhdmzZ9O+fXuMRiM+Pj706dOHjz76qML5xo4dazu+f//+3HDDDRXGycrKIiwsjGefffaccZ8r2Rw6dGiF83322Wf06tULFxcX3N3dGTx4MEuXLr3g6xIREWF7XfR6PS1atGDSpElkZGRc8LH2tnjxYl5++eVqPeZSEn8hhBBC2J8k4o3UqFGjSExM5MiRIzzxxBO88MILzJkzB9C6YNx222289NJLPPbYYxw4cIC1a9cSFhbGkCFDKiRvL774IvPmzePll19m//79rFmzhvvvv5/MzMwqz6vX6/n0009ZtmwZX331lW375MmT8fHxqfZCPenp6WzcuJHRo0cDMHXqVB544AFuvfVWdu/ezdatW7niiisYM2YM77zzzgXHe+mll0hMTOTUqVN89dVXrF+/nkcffbRaMdmDj48P7u7u9g5DCCGEEPVIEvFzKS44981sqsaxRRc+tgacnJwICgoiPDychx56iOHDh7NkyRIAvvvuO3744Qc+//xz7r33XiIjI+natSsffPAB1113Hffeey95eXkALFmyhIcffpibb77ZdtykSZOYOnXqOc/dtm1bZs+ezeTJk0lMTOSXX37h22+/5fPPP6/UmeZCfvvtN7p3705gYCB///03b775JnPmzGHq1Km0bt2aDh068Morr/D4448zZcoU4uLizjueu7s7QUFBhISEMHToUMaPH8+OHTts+9PS0rj99tsJCQnBxcWFzp07880331QYY8iQITz66KM89dRT+Pj4EBQUxAsvvFDhmCNHjjBo0CCcnZ3p2LEjK1asqLD/pptu4pFHHrHdf/zxx1EUhYMHDwJgMplwdXVl5cqVtnOW/7QgOTmZ0aNHYzQaiYyMrPCmB7TZf4Drr78eRVFs90t98cUXRERE4OnpyW233UZOTs55XzchhBBC1L9mc7FmtX0y6tz7WvaFq18ru//5WDAXVn1scFe47u2y+1/fCoVZFY95YF2NwyxlNBptrX++/vpr2rZta5tlLu+JJ55g8eLFrFixgrFjxxIUFMTq1at5+OGH8ff3v+jzTZ48mZ9++om7776bPXv2MGPGDLp27VrtuJcsWcKYMWMA+Oabb3Bzc+OBBx6oMu65c+fy448/XrCWulRCQgK//vorffr0sW0rLCykR48ePP3003h4ePDbb79x991306pVK3r37m077rPPPmPKlCls2bKFzZs3M2HCBAYMGMBVV12F1WrlhhtuIDAwkC1btpCVlVUppsGDB/P+++/b7q9btw4/Pz/Wrl1L+/bt+eeffyguLqZ///5Vxj5hwgROnz7NmjVrMBgMPProoyQnJ9v2//PPPwQEBLBw4UJGjRqFXq+37Tt27Bg///wzS5cuJSMjg1tuuYXZs2fzyiuvXNTrJoQQQoj6ITPijZyqqqxcuZLly5dz5ZVXAnD48GE6dOhQ5fGl2w8fPgzA3LlzSUlJISgoiC5duvDggw/yxx9/XPC8iqLw3nvvsWrVKgIDA5k2bVq1Yy8qKmLZsmVcd911tphatWpV5ax6ixYt8PDwsMV9Lk8//TRubm4YjUZCQ0NRFIW5c+fa9oeEhDB16lS6detGVFQUkydPZtSoUXz33XcVxunSpQszZ86kTZs2jBs3jp49e7Jq1SoAVq5cycGDB/n888/p2rUrgwYN4tVXX63w+CFDhrB//35SUlLIyMhg//79PPbYY6xduxaAtWvX2urgz3b48GH++OMPPvzwQ/r27UuPHj34+OOPKSgo+/Sk9E2Tl5cXQUFBFd5EWa1WPv30Uzp16sTAgQO5++67bbELIYQQouGQGfFzuWfZufcp+or3x/18nmPPeq9zx6Iah1Te0qVLcXNzsy1KdMcdd1Qon7jY9vAdO3Zk7969bN++nY0bN7J+/XpGjx7NhAkTKlxAWZVPPvkEFxcXTpw4QXx8fKXyiAtZvXo1AQEBXHbZZdWO+1yefPJJJkyYgKqqxMXF8cwzz3DNNdewfv169Ho9FouFV199le+++46EhARMJhNFRUWVEuIuXbpUuB8cHGybkT5w4ABhYWG0aNHCtr9fv34Vju/UqRM+Pj6sW7cOR0dHLr/8cq699lpiYmIAbYZ8yJAhVT6HAwcO4ODgQI8ePWzb2rdvj5eX10W9BhERERXqzcvHLoQQQoiGQ2bEz8VgPPfNwbEaxzpd+NgaGDp0KLt27eLIkSMUFBTw2Wef4erqCmg13AcOHKjycaXb27Zta9um0+no1asXjz/+OIsXL+bTTz/l448/5sSJE+c8/6ZNm5g3bx5Lly6ld+/eTJo0qdpJ9JIlS2yz4aUxHT9+3LYaanmnT58mOzu7QtxV8fPzo3Xr1rRp04Yrr7yS+fPns2nTJtasWQPAnDlzeOutt3j66adZs2YNu3btYuTIkZXOefYKk4qiVGv5XUVRGDRoEGvXrrUl3V26dKGoqIi9e/eyadMmBg8efNHjVcelxi6EEEKI+iGJeCPl6upK69atadmyJQ4OFT/YuO222zhy5Ai//vprpce9+eab+Pr6ctVVV51z7I4dOwLYLug8W35+PhMmTOChhx5i6NChfPzxx2zdupUFCxZcdPyqqvLrr7/a6sNL487Nza1QW13qjTfewGAwcOONN170OQBb7XRpWcfGjRsZM2YMd911F127diUqKuqC5S5n69ChA3FxcSQmJtq2/f3335WOGzx4MGvXrmXt2rUMGTIEnU7HoEGDmDNnDkVFRQwYMKDK8du3b4/ZbGb79u22bYcOHarUycZgMGCxWKoVuxBCCCEaDknEm6DbbruN66+/nvHjx/Pxxx9z8uRJdu/ezQMPPMCSJUv46KOPbLPnN910E/PmzWPLli3Exsaydu1aoqOjadu2Le3bt69y/OnTp6OqKrNnzwa0Uog33niDp556ipMnT15UjNu3byc/P58rrrjCtq1fv3489thjPPnkk7z55pscO3aMgwcP8txzz/HWW2/x5ptvEhYWdt5xc3JySEpKIjExka1bt/Lkk0/i7+9vuyiyTZs2rFixgk2bNnHgwAEeeOABzpw5c1Exlxo+fDht27Zl/Pjx/Pvvv/z1119V9k8vrRPft2+f7XkOGTKEr776ip49e9p+Bmdr164do0aN4oEHHmDLli1s376de++9F6Ox4qcnERERrFq1iqSkpEbRK10IIYQQFTWbGnGr1Vrp43mr1YqqqrZbY3O+mBctWsT8+fOZN28eDz/8MM7OzvTr1481a9YwYMAA22NHjBjBt99+y6xZs8jKyiIoKIgrr7ySmTNnotfrK5xDVVXWrVtHTEwMa9aswWg02vbff//9LF68mEmTJrFixQoURTlnzKqq8vPPP/N///d/lc5RugjRe++9x3PPPYder6d79+789NNPjB49+oI/p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i6bds2ddq0aaqfn5+6b9++CsdkZWWpvXv3VkeNGqWaTCbb9ldeeUUF1OXLl9u2JScnqzqdTl22bFm9PYeG6tSpU2pAQID677//2rZVVZqSmZmpHj58WF23bp06evRotXv37mpBQYGqqqr6n//8R7311lttx15sGVZzlZGRoXp4eKgfffSR+ssvv6itW7dWc3JybPvP/ltdKjExUT1w4ID6yy+/qB07dlQfeuiheoy64TIYDGq/fv0qbJs8ebLat2/fcz7m2LFjKlBlyVp8fLzaqlUrddKkSbUea1MwYsQI9dprr7XdL80lpk+fXuG4zp07q9OmTav0eClNaWT8/PzQ6/WcOXOmwvYzZ85c1Ed44txKX7/zvbarV69m6dKlfPvttwwYMIDu3bvz7rvvYjQaK8w2NHePPPIIS5cuZc2aNZc0k71w4UJ8fX257rrrajG6xs/R0ZHWrVvTo0cPZs2aRdeuXXnrrbds+3Nychg1ahTu7u789NNPGAwG277g4GCACjPo/v7++Pn5VSgPaK62b99OcnIy3bt3x8HBAQcHB9atW8fbb7+Ng4ODbcbQ09OTNm3aMGjQIH744QcOHjzITz/9BGh/J77//nvb44cNGwZof79nzpxpt+fWUHl5edG2bVuOHj3K6tWrOXbsGF5eXrbXD+DGG29kyJAhFR4XFBRE+/btue6663j//fd57733SExMtMMzaFiCg4MrfULWoUOH8/77joqKws/Pj6NHj1bYfvr0aYYOHUr//v354IMP6iTexiw2NpaVK1dy77332rZV9TcWLvwzaGqabCLu6OhIjx49WLVqlW2b1Wpl1apV56wRFRcnMjKSoKCgCq9tdnY2W7Zssb22+fn5AJVqPnU6HVartf6CbaBUVeWRRx7hp59+YvXq1URGRl7SWAsXLmTcuHEVEklRmdVqpaioCNB+Z0eMGIGjoyNLlizB2dm5wrEDBgwAqNBWMj09ndTUVMLDw+sv6AZq2LBh7Nmzh127dtluPXv25M4772TXrl3o9fpKj1FVFVVVbT+DH3/8kX///df2+NKSib/++kvaRFYhNzeXY8eOERwczLRp09i9e3eF1x9g3rx5LFy48JxjlP79Lf0ZNGcDBgyo1Db28OHD5/33HR8fT1pami2JBK0F4pAhQ2xdguRah8oWLlxIQEAA11xzjW1bREQELVq0qPbPoM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", "text/plain": [ "
" ] @@ -2159,4 +2159,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} \ No newline at end of file +} diff --git a/examples/dfanalyzer/dfanalyzer.ipynb b/examples/dfanalyzer/dfanalyzer.ipynb new file mode 100644 index 00000000..b521ea4a --- /dev/null +++ b/examples/dfanalyzer/dfanalyzer.ipynb @@ -0,0 +1,628 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b4470223", + "metadata": {}, + "source": [ + "# DFAnalyzer Simple Example\n", + "\n", + "This notebook will guide you to load a trace file generated by DFTracer and analyze the trace events using Dask." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "86ed50dc-d4d6-4e78-be69-1d55b8362a46", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "markdown", + "id": "16132659", + "metadata": {}, + "source": [ + "## System imports for the notebook" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "432c079e", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import os\n", + "from pathlib import Path\n", + "import sys" + ] + }, + { + "cell_type": "markdown", + "id": "9ece9f90", + "metadata": {}, + "source": [ + "## We add the analysis code to path so that we can run this in dev mode." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "4a5811b8", + "metadata": {}, + "outputs": [], + "source": [ + "app_root = str(Path(os.getcwd()).parent.parent)\n", + "sys.path.insert(0, app_root)" + ] + }, + { + "cell_type": "markdown", + "id": "446ebe05", + "metadata": {}, + "source": [ + "## Imports for the notebook\n", + "\n", + "This may take some time as it initializes Dask." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4a47492d-40d0-4dea-b1a2-aa1f083239e3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/usr/WS2/haridev/dftracer/dfanalyzer/__init__.py\n" + ] + } + ], + "source": [ + "# Importing DFAnalyzer\n", + "import dfanalyzer\n", + "print(dfanalyzer.__file__)\n", + "from dfanalyzer.main import DFAnalyzer, update_dft_configuration, setup_logging, setup_dask_cluster, reset_dask_cluster" + ] + }, + { + "cell_type": "markdown", + "id": "0e236854", + "metadata": {}, + "source": [ + "## Initialize DFAnalyzer Configuration\n", + "\n", + "In this function, we can tune DFAnalyzer for the analysis. For example, we can tune number of workers, connect to existing dask cluster, etc." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d3a7cf5b-fbbc-4eee-9ed5-ce869f4541e6", + "metadata": {}, + "outputs": [], + "source": [ + "conf = update_dft_configuration(verbose=True, workers=4, log_file=f\"./df_{os.getenv('USER')}.log\")" + ] + }, + { + "cell_type": "markdown", + "id": "8478828a", + "metadata": {}, + "source": [ + "## This methods sets up logging for DFAnalyzer.\n", + "\n", + "This is needed for debugging and progress tracking. All prints seen in the following cells are configured in this method." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "04428959-820f-4466-8ceb-778bcce93bf0", + "metadata": {}, + "outputs": [], + "source": [ + "setup_logging()" + ] + }, + { + "cell_type": "markdown", + "id": "252225e3", + "metadata": {}, + "source": [ + "## Setup dask cluster.\n", + "\n", + "In this example, we use Dask Local cluster which will use multiprocessing on the same node where the notebook is running to run its workers.\n", + "\n", + "**NOTE:** If your running on Remote VSCode on a cluster, you can tunnel the port and open it locally." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "68e813b7-6b95-4f31-b223-1fb50774db50", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [10:11:57] Initialized Client with 4 workers and link http://127.0.0.1:8787/status [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:669]\n" + ] + } + ], + "source": [ + "setup_dask_cluster()" + ] + }, + { + "cell_type": "markdown", + "id": "237d458d", + "metadata": {}, + "source": [ + "On clicking the link, you will see a daskboard like this. [Dask Daskboard Image](images/dask-dashboard-load.png)" + ] + }, + { + "cell_type": "markdown", + "id": "6207690f", + "metadata": {}, + "source": [ + "## Reset Dask Cluster\n", + "\n", + "In case you have an error and want to clean the cluster for fresh analysis. You can run this." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "236e50a4-03b6-4895-a0a5-d473f5e391b5", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-07-10 10:11:57,752 - distributed.nanny - WARNING - Restarting worker\n", + "2024-07-10 10:11:57,768 - distributed.nanny - WARNING - Restarting worker\n", + "2024-07-10 10:11:57,797 - distributed.nanny - WARNING - Restarting worker\n", + "2024-07-10 10:11:57,815 - distributed.nanny - WARNING - Restarting worker\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [10:11:59] Restarting all workers [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:657]\n" + ] + } + ], + "source": [ + "reset_dask_cluster()" + ] + }, + { + "cell_type": "markdown", + "id": "07951b56", + "metadata": {}, + "source": [ + "## Load the DFAnalyzer Trace\n", + "\n", + "The DFAnalyzer class take a regex string as input. For example, \"{app_root}/examples/dfanalyzer/*.pfw.gz\"" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b37727ee-a221-43ab-81e1-cdf98c2cf314", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [10:12:00] Created index for 1 files [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:366]\n", + "[INFO] [10:12:00] Total size of all files are bytes [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:368]\n", + "[INFO] [10:12:00] Loading 6 batches out of 1 files and has 93895 lines overall [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:381]\n", + "[INFO] [10:12:03] Loaded events [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:423]\n", + "[INFO] [10:12:03] Loaded plots with slope threshold: 45 [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:429]\n" + ] + } + ], + "source": [ + "analyzer = DFAnalyzer(f\"{app_root}/examples/dfanalyzer/test-trace.pfw.gz\")" + ] + }, + { + "cell_type": "markdown", + "id": "23d520b4", + "metadata": {}, + "source": [ + "## Analyze the events\n", + "\n", + "1. The dask dataframe is stored at `analyzer.events`. \n", + "2. We can run dask queries on this dataframe." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "4c0ffe10", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namecatpidtidtstedurtintervaltrangehostnamecompute_timeio_timeapp_io_timetotal_timefilenamephasesize
0TorchFramework.__init__ai_framework0338684620525862052668<NA>6.0ruby165<NA><NA><NA>0<NA>0<NA>
1TorchFramework.is_nativeio_availableai_framework0338684620529362052941<NA>6.0ruby165<NA><NA><NA>0<NA>0<NA>
2FileStorage.__init__storage03386841962053096205290<NA>0.0ruby165<NA><NA><NA>0<NA>0<NA>
3FileStorage.create_namespacestorage03386846205338620536527<NA>6.0ruby165<NA><NA><NA>0<NA>0<NA>
4DLIOBenchmark.__init__dlio_benchmark0338684074845737484573<NA>0.0ruby165<NA><NA><NA>0<NA>0<NA>
\n", + "
" + ], + "text/plain": [ + " name cat pid tid ts \\\n", + "0 TorchFramework.__init__ ai_framework 0 338684 6205258 \n", + "1 TorchFramework.is_nativeio_available ai_framework 0 338684 6205293 \n", + "2 FileStorage.__init__ storage 0 338684 19 \n", + "3 FileStorage.create_namespace storage 0 338684 6205338 \n", + "4 DLIOBenchmark.__init__ dlio_benchmark 0 338684 0 \n", + "\n", + " te dur tinterval trange hostname compute_time io_time \\\n", + "0 6205266 8 6.0 ruby165 \n", + "1 6205294 1 6.0 ruby165 \n", + "2 6205309 6205290 0.0 ruby165 \n", + "3 6205365 27 6.0 ruby165 \n", + "4 7484573 7484573 0.0 ruby165 \n", + "\n", + " app_io_time total_time filename phase size \n", + "0 0 0 \n", + "1 0 0 \n", + "2 0 0 \n", + "3 0 0 \n", + "4 0 0 " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "analyzer.events.head()" + ] + }, + { + "cell_type": "markdown", + "id": "006bfab2", + "metadata": {}, + "source": [ + "### Summary \n", + "\n", + "DFAnalyzer supports a summary utility that gives a brief summary of the job and its I/O access behavior." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "9350218f", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [10:12:07] Total number of events in the workload are 93893 [/usr/WS2/haridev/dftracer/dfanalyzer/main.py:521]\n" + ] + }, + { + "data": { + "text/html": [ + "
╭──────────────────────────────────────────────────── Summary ────────────────────────────────────────────────────╮\n",
+                            "│  Allocation    Scheduler Allocation Details                                                                     │\n",
+                            "│                ├── Nodes: 1                                                                                     │\n",
+                            "│                ├── Processes: 1                                                                                 │\n",
+                            "│                ├── Thread allocations across nodes (includes dynamically created threads)                       │\n",
+                            "│                │   ├── Compute: 0                                                                               │\n",
+                            "│                │   └── I/O: 21                                                                                  │\n",
+                            "│                └── Events Recorded: 94K                                                                         │\n",
+                            "│  Dataset       Description of Dataset Used                                                                      │\n",
+                            "│                └── Files: 103                                                                                   │\n",
+                            "│  I/O Behavior  Behavior of Application                                                                          │\n",
+                            "│                ├── Split of Time in application                                                                 │\n",
+                            "│                │   ├── Total Time: 105.211 sec                                                                  │\n",
+                            "│                │   └── Overall I/O: 54.896 sec                                                                  │\n",
+                            "│                └── Metrics by function                                                                          │\n",
+                            "│                    ├── Function       |count |                  size                   |                        │\n",
+                            "│                    ├──                |      |min   |25    |mean  |median|75    |max   |                        │\n",
+                            "│                    ├── opendir        |42    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── __xstat64      |42    |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── open64         |139   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── __fxstat64     |278   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── lseek64        |82K   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "│                    ├── read           |6K    |NA    |4MB   |4MB   |4MB   |4MB   |4MB   |                        │\n",
+                            "│                    └── close          |119   |NA    |nan   |nan   |NA    |nan   |NA    |                        │\n",
+                            "╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+                            "
\n" + ], + "text/plain": [ + "╭──────────────────────────────────────────────────── Summary ────────────────────────────────────────────────────╮\n", + "│ \u001b[36m \u001b[0m\u001b[36mAllocation \u001b[0m\u001b[36m \u001b[0m Scheduler Allocation Details │\n", + "│ \u001b[36m \u001b[0m ├── Nodes: 1 │\n", + "│ \u001b[36m \u001b[0m ├── Processes: 1 │\n", + "│ \u001b[36m \u001b[0m ├── Thread allocations across nodes (includes dynamically created threads) │\n", + "│ \u001b[36m \u001b[0m │ ├── Compute: 0 │\n", + "│ \u001b[36m \u001b[0m │ └── I/O: 21 │\n", + "│ \u001b[36m \u001b[0m └── Events Recorded: 94K │\n", + "│ \u001b[36m \u001b[0m\u001b[36mDataset \u001b[0m\u001b[36m \u001b[0m Description of Dataset Used │\n", + "│ \u001b[36m \u001b[0m └── Files: 103 │\n", + "│ \u001b[36m \u001b[0m\u001b[36mI/O Behavior\u001b[0m\u001b[36m \u001b[0m Behavior of Application │\n", + "│ \u001b[36m \u001b[0m ├── Split of Time in application │\n", + "│ \u001b[36m \u001b[0m │ ├── Total Time: 105.211 sec │\n", + "│ \u001b[36m \u001b[0m │ └── Overall I/O: 54.896 sec │\n", + "│ \u001b[36m \u001b[0m └── Metrics by function │\n", + "│ \u001b[36m \u001b[0m ├── Function |count | size | │\n", + "│ \u001b[36m \u001b[0m ├── | |min |25 |mean |median|75 |max | │\n", + "│ \u001b[36m \u001b[0m ├── opendir |42 |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── __xstat64 |42 |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── open64 |139 |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── __fxstat64 |278 |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── lseek64 |82K |NA |nan |nan |NA |nan |NA | │\n", + "│ \u001b[36m \u001b[0m ├── read |6K |NA |4MB |4MB |4MB |4MB |4MB | │\n", + "│ \u001b[36m \u001b[0m └── close |119 |NA |nan |nan |NA |nan |NA | │\n", + "╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "items = analyzer.summary()\n", + "items" + ] + }, + { + "cell_type": "markdown", + "id": "2ab18972", + "metadata": {}, + "source": [ + "### Timeline plots\n", + "\n", + "We support two timeline plots:\n", + "1. how I/O time and I/O bandwidth changes over time.\n", + "2. how transfer size changes over time." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "b9185f98", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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wccff0zfvn3t+/nuu+9YsmQJaWlpxMfHc9NNN/HYY495/WTNFbbXo7m/EUEQeghrg46Ppmok8b9A6GA99f2n60UN7WAwW7n6rR0dftwv7piAWqXCbLHWBdnO78PPz8/+ccunn37KgAEDGgXYNg888ABff/01P//8M3PmzCE2Npb169dz1113ERUV1WT7lixatIhvvvmGefPmsX//fp588klGjBjh9LhXrFjBZZddBsDy5csJDAzk9ttvb3bcS5cu5auvvnJrTvUzzzzD0qVLWbp0KQ8//DA33HADffr04dFHH6VXr178+c9/5u677+ann34CYMuWLdx444288cYbTJ48mePHj3PbbbcBdKpWrYIgCA4THR8FwSt65qmFF7haxk+WZdauXcvq1as599xzATh69CiDBw9udnvb7UePHgVg6dKlFBYWEhsby/Dhw7njjjvsAWVrJEnizTffZN26dcTExPDII484NW4Ag8HAqlWruPTSS+1j6tu3b7NpHfHx8QQHB9vH7S4333wz11xzDQMGDODhhx/m5MmTzJ07l1mzZjF48GDuvfdeNm7caN9+yZIlPPLII9x000306dOHmTNn8swzz/D222+7dVyCIAgdxtJgJlsE2YLQYXrUTLaPRsUXd0zwynHVKltDGsfSVX744QcCAwPtCzhvuOEGnnrqKfvPHa1SkpqayoEDB9i9ezfbtm1j8+bNzJ49m/nz5/Pvf/+71fu+//77+Pv7k5GRQXZ2NsnJyQ4d02b9+vVER0czZMgQp8ftLsOHD7d/HRMTA8CwYcMa3abX66moqCA4OJjff/+dbdu28dxzz9m3sVgs6PV6ampqvN49VBAEwWmhvaC6ULmYasBqhR768b0gdKQeFWRLkoSvK7kablBfxs+xIHP69Om8+eab6HQ64uPjG+UDDxgwgEOHDjV7P9vtAwYMsN+mUqkYO3YsY8eO5b777uO///0v8+bN47HHHiMlJaXZ/Wzfvp1XX32VNWvW8Oyzz7JgwQLWrl3bKN+6LStWrLDPYtvGtHXrVoxGY5PZ7NOnT1NRUdFo3O7QsKKGbezN3WYrL1RVVcWSJUu44oormuxLLBwUBKFLmv6oMpv9x+egCwBEKVlB6AjiVLaD1M9kO/bPLSAggH79+tGrV68mC+6uu+460tPT+f7775vc75VXXiEiIqLVknepqakAVFc3/7FhTU0N8+fP584772T69Om89957/Prrr7z11lsOjR2UGevvv//eno9tG3dVVVWzqRf/+Mc/0Gq1XHnllQ4fwxPOOussjhw5Qr9+/ZpceurCDUEQugG1FkbNhSFzQOWdySZB6Gl61Ey2N2nU7mutft111/HFF19w00038fLLLzcq4bdixQq++OILAgICALjqqquYNGkSEydOJDY2loyMDB599FEGDBjAoEGDmt2/rUzgiy++CChVO/7xj3/w4IMPcuGFFzqUNrJ7925qamo455xz7LdNmDCBe++9l7/+9a8YjcZGJfxef/11XnvttSaVRTrak08+ySWXXEKvXr246qqrUKlU/P777xw4cIBnn33Wq2MTBEEQBKHrEFNzHcSdrdUlSeLzzz/nb3/7G6+++ioDBw5k8uTJnDp1io0bN9prZAPMmjWL77//ntmzZzNgwABuuukmBg0axJo1a5otSbdp0yaWLVvGBx980Cj/+Pbbb2fixIksWLDAobzq7777josuuqjJMV577TX+7//+j+XLlzN06FDGjBnD5s2b+fbbbxuV9fOWWbNm8cMPP7BmzRrGjh3L+PHjefXVV+ndu7e3hyYIguCaL+bDp9fByW2Qswf05d4ekSD0CJLchft825rRZGVlNSlurtfrycjIICUlpVPk0upNFrJKatCoVaREBnh7OB43fPhwHn/88Ub1uYWO19n+DgRB8IL3LwBTLfgEgaESLngRend8EQCh52otXuvOxEx2B2lYXaQLn9c4xGg0cuWVV3LhhRd6eyiCIAiCrU62X5hyLcr4CUKHEEF2B9GoJGjQ9bE70+l0LF68mKCgIG8PRRAEoWezWsFqUb62B9lV3huPIPQgIsjuIJIkoZacqzAiCIIgCO3SsNujX6hyLWayBaFDdIvqIlar1V7nuOFtsizbL52BRiVhscqYrTK6TjImoXuz/f439zciCEIPYNZj624g+4YhAbKhUpnhFoQO0lPff7pkkL1s2TKWLVuG0aicoRcXFzdpbmLrlGg2mzGbzd4YZhOSpAQ9BpMJnUoE2YLnmc1mrFYrxcXFjZrwCILQM0j6UsLNJkCixiThbzahLy2guqDA20MTepDi4mJAabSn1WpZuHAhCxcu9PKoPK9LBtm2F8e2WjUiIoLo6OhG2+j1eiorK9FoNM2WqvMGncaC3mRFllSdZkxC96bRaFCpVERERIjqIoLQE9WokaIHAjJBEbFIGi2BOomAM94zBcGTbJOiGzZs6FHVRbpFpKdSqZp041OpVEiSZL90BpoGXR87y5iE7s32+9/c34ggCD1AYBRc/QEAUsFhOPtWiOiHJP4fCB2op77/dIsgu6uwl/GziFQRQRAEoYNFD1IugiB0iJ55auEltplsd7RWFwRBEARBEDovEWR3II3afa3VhY4nSRLffvutS/edNm0a9913X6vbJCcn89prr7W6zVNPPcXIkSNdGoMgCD1QwWH4bC6s+huYjVCUDnkHvD0qQegRRJDdgdQNZrJbKys4f/58ey6tTqejX79+PP30042qpFgsFl599VWGDRuGr68vYWFhXHjhhWzbtq3RviwWCy+++CKDBg3Cz8+P8PBwxo0bx7///e9Gx5szZ459+4kTJ3LFFVc02k95eTlJSUk89thjLY67pUBy+vTpjY73n//8h7Fjx+Lv709QUBBTp07lhx9+aHG/NsnJyfbnRa1WEx8fz4IFCygtLW3zvt729ddf88wzzzh1n/YE9YIgCIBSE7s8GypzoSoPvroFfnrY26MShB5BBNkdyBZky7KMpY062RdccAG5ubmkp6fzwAMP8NRTT/Hyyy/b73/dddfx9NNPc++993Lo0CE2btxIUlIS06ZNaxSYLVmyhFdffZVnnnmGtLQ0NmzYwG233UZZWVnzY1Sr+fDDD1m1ahWffPKJ/fZFixYRHh7O4sWLnXrMJSUlbNu2jdmzZwPw4IMPcvvtt3Pttdfyxx9/8Ouvv3LOOedw2WWX8a9//avN/T399NPk5uaSmZnJJ598wubNm7nnnnucGpM3hIeHiw6YgiB0PFszGrUOdIHK16ZqUSdbEDpAzwyyTbUtX8xGJ7Y1tL1tAypJcnjxo4+PD7GxsfTu3Zs777yT8847jxUrVgDw+eef8+WXX/LRRx9xyy23kJKSwogRI3jnnXe49NJLueWWW6iuVjp6rVixgrvuuourr77avt2CBQt48MEHWzz2gAEDePHFF1m0aBG5ubl89913fPbZZ3z00UdN6pG35ccff+Sss84iJiaGnTt38sorr/Dyyy/z4IMP0q9fPwYPHsxzzz3Hfffdx/33309WVlar+wsKCiI2NpaEhASmT5/OTTfdxJ49e+w/Ly4u5vrrrychIQF/f3+GDRvG8uXLG+1j2rRp3HPPPTz00EOEh4cTGxvLU0891Wib9PR0pkyZgq+vL6mpqfz888+Nfn7VVVdx991327+/7777kCSJw4cPA0q5ooCAANauXWs/ZsNZ/oKCAmbPno2fnx8pKSmNTmhAmbUHuPzyy5Ekyf69zccff0xycjIhISFcd911VFZWtvq8CYLQQ9mDbA3oApSvZRnMtS3fRxAEt+iZ1UXev6Dln/UaDxf+vf77j+aAWd/8tnEj4NI36r//9FrQlzfe5vZNjb5t2PXRx4kh+/n52Yu5f/rppwwYMMA+O9zQAw88wNdff83PP//MnDlziI2NZf369dx1111ERUU5fLxFixbxzTffMG/ePPbv38+TTz7JiBEjnBixYsWKFVx22WUALF++nMDAQG6//fZmx7106VK++uqrNnOXbXJycvj+++8ZN26c/Ta9Xs/o0aN5+OGHCQ4O5scff2TevHn07duXs88+277df/7zH+6//35++eUXduzYwfz585k0aRIzZ87EarVyxRVXEBMTwy+//EJ5eXmTMU2dOpW3337b/v2mTZuIjIxk48aNDBo0iF27dmEymZg4cWKzY58/fz6nT59mw4YNaLVa7rnnHgoaNIfYtWsX0dHRfPDBB1xwwQWo1Wr7z44fP863337LDz/8QGlpKddccw0vvvgizz33nEPPmyAIPYjFpFyrdcpFpQGrWUkjsQXdgiB4RM+cyfYitZOLH2VZZu3ataxevZpzzz0XgKNHjzJ48OBmt7fdfvToUQCWLl1KYWEhsbGxDB8+nDvuuIOffvqpzeNKksSbb77JunXriImJ4ZFHHnFovA0ZDAZWrVrFpZdeah9T3759m50Nj4+PJzg42D7uljz88MMEBgbi5+dHYmIikiSxdOlS+88TEhJ48MEHGTlyJH369GHRokVccMEFfP755432M3z4cBYvXkz//v258cYbGTNmDOvWrQNg7dq1HD58mI8++ogRI0YwZcoUnn/++Ub3nzZtGmlpaRQWFlJaWkpaWhr33nsvGzduBGDjxo32vPMzHT16lJ9++ol3332X8ePHM3r0aN577z1qa+tnlmwnRKGhocTGxjY6QbJarXz44YcMHTqUyZMnM2/ePPvYBUEQGmmYLiJJoKv7n2Ss8t6YBKGH6Jkz2X9e1fLPJHXj72/8tpVtzzhHueF/bR7a0TJ+P/zwA4GBgfb28DfccEOj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rVAoLjpuvfVWrrrqqkHvZ/78+dx3332295GRkbzwwguD3i/AypUrefrpp4ekr4ceeoi77757SPpSKBQKe0FVfFQoFBcUmqadcfuaNWu4//77EULg5eU1qLbMnz+fSZMm2YR1aWkprq6uuLi4DGq/Bw8eZMGCBWRnZ+Pm5jaofQGUlZURHR1NSkoK0dHRg96fQqFQ2AMOw22AQqFQDCSFhYW21++//z6PPfYY6enptjY3N7chEZ7d4e/vPyT9vPTSS1x33XVD9j39/PxYsmQJr7zyCs8+++yQ9KlQKBTnOypcRKFQXFAEBQXZfjw9PdE0rVObm5tbl3CR+fPnc/fdd3Pffffh7e1NYGAgr776KvX19dx22224u7sTGxvLxo0bO/WVlpbGZZddhpubG4GBgaxcuZKysrIebTs9XETTNP71r39x9dVX4+LiQlxcHJ999tk59WGxWPjwww9ZtmxZp/b//d//JS4uDicnJwIDA/nJT35i22a1Wlm7di1RUVE4OzszceJEPvzww06fP3z4MFdeeSUeHh64u7szZ84cMjIybNuXLVvG+vXre7RLoVAoLjaUyFYoFArgjTfewM/Pjz179nD33Xfzy1/+kuuuu45Zs2axf/9+Fi9ezMqVK2loaACgqqqKBQsWMHnyZPbt28emTZsoLi7m+uuv71O/TzzxBNdffz2pqalcfvnl3HzzzVRUVPS7j9TUVKqrq5k2bZqtbd++fdxzzz08+eSTpKens2nTJubOnWvbvnbtWt58803WrVvH4cOHuf/++7nlllvYuXMnAPn5+cydOxej0cj27dtJTk7m9ttvx2w2244xY8YM8vLyyMrK6tP3VygUigsWoVAoFBcor732mvD09OzSvmrVKrF8+XLb+3nz5onZs2fb3pvNZuHq6ipWrlxpayssLBSASEpKEkII8dRTT4nFixd3Om5ubq4ARHp6uu249957r217RESEeP75523vAfHHP/7R9r6urk4AYuPGjb3u43Q2bNgg9Hq9sFqttraPPvpIeHh4iJqami77NzU1CRcXF7F79+5O7T/72c/EihUrhBBCPPzwwyIqKkqYTKZu+xRCiOrqagGIr7/+usd9FAqF4mJCxWQrFAoFEB8fb3ut1+vx9fVlwoQJtrbAwEAASkpKALm4cMeOHd3GPWdkZDBy5Mg+9+vq6oqHh8c59dHY2IjRaOy0APTSSy8lIiKC6Oholi5dytKlS20hKidPnqShoYFLL72003FMJhOTJ08GICUlhTlz5uDo6Njj93B2dgawefoVCoXiYkeJbIVCoYAuAlLTtE5tbaLVarUCUFdXx7Jly/jzn//c5VjBwcHn1O+59OHn50dDQwMmkwmDwQCAu7s7+/fv5+uvv+arr77iscce4/HHH2fv3r3U1dUB8OWXXxIaGtrpWEajEWgX0GeiLcRlqBZ3KhQKxfmOEtkKhULRD6ZMmcJHH31EZGQkDg6DcyrtTx+TJk0C4MiRI7bXAA4ODixatIhFixaxZs0avLy82L59O5deeilGo5GcnBzmzZvX7THj4+N54403aGlp6dGbnZaWhqOjI+PGjevTd1QoFIoLFbXwUaFQKPrB6tWrqaioYMWKFezdu5eMjAw2b97MbbfdhsViGbY+/P39mTJlCt99952t7YsvvuDFF18kJSWF7Oxs3nzzTaxWK6NGjcLd3Z3f/va33H///bzxxhtkZGSwf/9+XnrpJd544w0Afv3rX1NTU8ONN97Ivn37OHHiBG+99Van1Ijffvstc+bM6ZXXW6FQKC4GlMhWKBSKfhASEsKuXbuwWCwsXryYCRMmcN999+Hl5YVONzCn1v72cccdd/DOO+/Y3nt5efHxxx+zYMECxowZw7p163jvvfdsXuennnqKRx99lLVr1zJmzBiWLl3Kl19+SVRUFAC+vr5s376duro65s2bx9SpU3n11Vc7ebXXr1/PnXfeOSDfW6FQKC4EVMVHhUKhuMBobGxk1KhRvP/++yQmJg56fxs3buQ3v/kNqampgxY6o1AoFPaG8mQrFArFBYazszNvvvnmGYvWDCT19fW89tprSmArFApFB5QnW6FQKBQKhUKhGGCUJ1uhUCgUCoVCoRhglMhWKBQKhUKhUCgGGCWyFQqFQqFQKBSKAUaJbIVCoVAoFAqFYoBRIluhUCgUCoVCoRhglMhWKBQKhUKhUCgGGCWyFQqFQqFQKBSKAUaJbIVCoVAoFAqFYoBRIluhUCgUCoVCoRhg/j9Off1kpBW7kAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax1, ax2 = analyzer.plots.time_bw_timeline(\n", + " bw_unit='gb',\n", + " figsize=(8, 3),\n", + " line1_label='POSIX I/O Time',\n", + " line2_label='POSIX I/O Bandwidth',\n", + " time_col='io_time',\n", + " x_num_ticks=8,\n", + " y_num_ticks=5,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "08b58161", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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HvHx8bYxijMzM6HX650cFRERERHdydEji1WoBRgADh06hOXLl2P9+vVo2LAhnn/+eYwcObLWtKayBZiIiIioZnN0C3CFE+BiBQUF+PHHH7FixQocPnwYQ4YMwfLly6FQKOwdo11xGDQiIiKimq1GzQR3O3d3d4wZMwbz589Hx44dsW7dOuh0OnvGRkRERERkd5VKgFNTU7FgwQI0atQII0aMQIcOHXDmzBn4+vraOz4iIiIiIruqUCe4H374AStWrEBCQgL69euHJUuWYODAgZBIJI6Kj4iIiIjIrio8DFq9evUwcuRIBAcHl7netGnT7BKcI7AGmIiIiKhmc3S+VqEEOCIiAiKR6N47FIlw5cqVKgfmKEyAiYiIiGo2R+drFSqBSE5OtnsARERERETVqdKjQBARERER1UblToDXrVtX7p1ev34df//9d6UCIiIiIiJypHInwJ9//jmaNWuGxYsX459//rnreZVKhS1btuDZZ59FTEwMsrOz7RooEREREZE9lLsGOCEhAb/99hs++eQTzJ49G56enggODoabmxtyc3ORnp6OgIAAjBs3DqdPn77nKBFERERERM5SqamQs7KysG/fPly7dg0FBQUICAhAdHQ0oqOjIRbX7LLi4l6Fubm5HAWCiIiIqAZSq9Xw9fWtGaNAFAsICMCQIUPsHIpjxcfHIz4+HmazGQCQmZkJvV7v5KiIiIiI6E4ajcah+69UC3BtxhZgIiIiopqtRrYAPwjEYnGNL9cgIiIickWOztGYARIRERGRS2ECTEREREQupUoJsMFgwPnz52EymewVDxERERGRQ1UqAdbpdHj++efh4eGBFi1aICUlBQAwdepULFq0yK4BEhERERHZU6US4NmzZ+PEiRPYs2cP3NzcbMt79+6N9evX2y04IiIiIiJ7q9QoEBs3bsT69evRuXNniEQi2/IWLVrg8uXLdguOiIiIiMjeKtUCnJmZiaCgoLuW5+fnl0iIiYiIiIhqmkolwO3bt8fmzZttj4uT3q+//hqxsbH2iYyIiIiIyAEqVQKxYMECDBgwAGfPnoXJZMJHH32Es2fPYv/+/UhISLB3jEREREREdlOpFuCHH34YSUlJMJlMaNWqFbZv346goCAcOHAA7dq1s3eMRERERER2IxIEQXB2ENVJrVZDqVQ6bG5pIiIiIqoaR+drlSqB6NmzJ+Li4jBv3rwSy3NzczF06FDs2rXLLsE5ksVigcVicXYYRERERHQHR+dolUqA9+zZg1OnTuH48eNYs2YNPD09AVhnhqupNcDx8fGIj4+H2WwGYB3JQq/XOzkqIiIiIrqTRqNx6P4rVQIhFotx/Phx/Pvf/0Z+fj5+//13RERE4NatWwgLC7MlmTVRcZN6bm4uSyCIiIiIaiC1Wg1fX9+aVQIBAKGhoUhISMBzzz2HDh064Mcff0SzZs3sGZtDicViiMWV6gNIRERERA7k6BytUnsvHvdXoVBg7dq1mD59Ovr374/PPvvMrsEREREREdlbpVqA76yaeP3119GsWTOMHTvWLkERERERETlKpRLgq1evIiAgoMSyoUOHokmTJjh27JhdAiMiIiIicgSOA0xERERENUqNGQf4ySefxLfffgsfHx88+eST91z3l19+qXJgRERERESOUO4EWKlU2jq/KZVKhwVERERERORILIEgIiIiohrF0fmaXQZZS0hIwJYtW5Cbm1vpfSxatAgikQgzZswoc50zZ85g6NChiIiIgEgkwocffljp4xERERGRa6pQAvzuu+9izpw5tseCIKB///545JFH8Nhjj6FZs2Y4c+ZMhYM4cuQIvvjiC7Ru3fqe6+l0OkRFRWHRokUICQmp8HGIiIiIiCqUAK9fvx4tW7a0Pf7pp5/w119/Ye/evcjKykL79u0xf/78CgWg1WoxcuRIfPXVV/D19b3nuh06dMB7772HESNGQKFQVOg4RERERERABccBvnr1aolW2i1btuCpp55C165dAVgnxBg2bFiFApg8eTIGDhyI3r174+23367QtuVRWFiIwsJC22O1Wg0AMBqNMBqNdj8eEREREVWNo3O0CiXAJpOpRMvrgQMHStTshoWFISsrq9z7W7duHRITE3HkyJGKhFEhCxcuLLVVevv27fDw8HDYcWs0kwniwkJYPD2dHUnFmc2Q6HQwe3s7O5J7kmi1MHt4AA6Yy1yWmQmRyVTqcyYfn5rxe7VYIFVrYPL2AiQSZ0dDZREESFVqmJQ+QNEoP/dkMkGi18Ps5eX42Mj+Kvj7ExUWQmQRYHF3c3BgRHfT6XQO3X+FEuAGDRrgr7/+QlRUFFJSUnDhwgV0797d9vyNGzfg7+9frn1dv34d06dPx44dO+Dm5rg/rtmzZ2PmzJm2x2q1GnXr1kXfvn1ddhSIrCVLoD+ehKD5b0DeoIGzw6mQ3JWroN2yBX7TpsKz6M5DTaM7cgTZK1fB54khUI4YYff9p814Aaa0tFKfE7m5IfTDpZDcp5zI0dS//grVr79C5OEBt9at4R4TDbe2bSHhEIo1iuqnn6D+9VfUGTUK3o8PvO/62Z/GQ/f33wh8dTbcWrWqhgjJnrI+WIqCo0cQ9MYbUDRufM91BaMR6TNfhKWgACEfLIHERT8vyXmK79g7SoUS4MmTJ2PKlCnYu3cvDh48iNjYWDRv3tz2/K5duxAdHV2ufR07dgwZGRmIiYmxLTObzfjrr7/w6aeforCwEBI7tBwpFIpS64VlMhlkMlmV91/bCBYLCk+eAkwmaDdsQPDs2c4OqdwEsxkF+/ZBJBJB/f33UHbpApFc7uyw7qLbsQMikQj6xEQEjB5t9/3LAgMgKmX0QrNaBaFAD/3evagzdKjdj1sRhhMnreOGFxRAf+gQ9IcOASIRFA0bwr1dDDzatYM8MtI2tjhVP8ONG9Bs3AiRSIT8P/+E7xND7vn7MKtUKDhwACJBgHbjr/C+7b2baj5Tbi70R49CZBGg27EDXi1a3HN97eHDMGdmAgD0e/Y4/T2FXI+jc7QKJcATJ06ERCLB77//ju7du2PevHklnr958ybGjx9frn316tULp06dKrHsueeeQ9OmTTFr1iy7JL90N1N6OoSimmjd0WMwJCdDHhHh3KDKSX/uHCwaDQDAnJUN9bZtUD7+uJOjKsmUmwv9aetIKMYbqbAUFEDs7m7XY4S+8Uapy7UJCcj8+BNodvwJ5RNPQOSA8ovyECwWFF69AgAImDoFprQ06I4lwnD1KgovXkThxYvIW7ceEl9fuMdEw6Nde7i3bmX380RlEwQB2V98CZjMAADTrVsoPH8ebk2blrlN/v79gNm6vv7MGRRevgxFLbuD5Mry9/0NWCwAAN3BQzBrtZDcoxRCu3OX7f/qbdugHDwYImmFUgaiGq3CV/P48ePLTHI/++yzcu/H29u7xIgSAODp6Ql/f3/b8jFjxiA8PBwLFy4EABgMBpw9e9b2/9TUVCQlJcHLywsNGzas6EtxSYbk5BKP8zZsRNALM+y2f0EQUHjhImQhwXa/3a07bK0Vl9SpA3NeHvJ++hnePXtCXBNqXovc/iEDiwWFV67A/T4tLfbiERsL8fIVMGVmoiApCR52bKErvHIFmUuXwufxx+HTt+891zWlp0Mo0EMkk8GrWzeIJBL4PvMMTNnZ0CUmouBYIgpOnYI5Nxfanbug3bkLIqkUbi2awz2mHTzaxUAWGmq32Olu2oQE6M+ehUguh6JpE+hPnoJ2T8I9E2Dtnj0AALGXFyxaLVS//W7X9w5yLO3ev6z/EYshGI3I37sXPgMGlLquMSMDBSdPWlf38oI5Owf5Bw/B6+GaWXZGVBnOaSIqp5SUFKTdVut48+ZNREdHIzo6GmlpaXj//fcRHR2NCRMmODHK2qWwKAEurv/K378fxjLqSStKsFiQs3Il0l59FTf/bxYs+fl22S9gTax1RZ0l/Z8fD1l4OCxaLfJ+/dVux7CH4g8ZUdGtG8OlS9V2bLFcDq9HegAANNu2222/gsWCrPjPYLyZVq79Fl69CgCQ168H0W13cqT+/vDp0wfBr8xC/RXLETLndfg8OgDS4GAIJhMKTpxEzooVuDFlKm5MnYbsb79FwalTEDhai12ZtVrkrFwJAKgzfDjqPPEEAOt7gWAwlLqNMTUVhZcuA2KxLenN378fxoyMaomZqsaYmgrD5SuAWGwrZdD8uRNlTQSr3b0HEAS4tWoJn0cfBQCoN2+urnCJqkWNSoD37NlTYna3PXv24Ntvv7U9joiIgCAId/3sKWqZoPsrbgH26t4N7u1iAIsFKjskkYLZjKz4z6D+fRMAwJSVhewV31Z5v8WMKSkw3boFkUwG95gY+D77LABAvWkzTFWYgdCebv+Q8RnQHwBQWI0JMAD49OkDANAlJsJUVL9XVZpt22zXjSElBRa9/p7rG64UJcCRUWWuI5LL4d62Lfyffx4PxX+K8I8+gt/YMXBr2RKQSGC8eRPq3zch/Y35uPbcc7j13nvQ7NoNc16eXV6TK8tdvRoWtQayunWhfPwxuLVsCYm/Hyz5+dAlJpa6jSYhAQDgHt0W7m3bwq11K8BigXrzluoMnSpJu3cvAMC9bVv4PDYQIpkMhuRkGK5cuWtdwWKBZtdOAIB3r97w6dcXIqkUhRcuoPDixWqNm0oy5+VBf/68s8N4YNSoBJgcrziRkdev/7+WgN27YcrOrvQ+BYMBGe+9b71FKhZDOXgQIBJBu3s38g8dtkPUsLX+urdpA7GbGzw6dYSicWMIhYXI++knuxyjqrR79wGwfsi4F5UfFF66XK0xyMLDrUmkxQLNzp1V3p85Lw+5a7//3wKLBYWX7/2aDEX1v/KoyHIdQyQSQf5QOJSDBiF0/huov2I5gl6cCa8ePSBR+kAo0EN38BCy4uOR8vwE3Jw1C7nrf0DhpUsQistNHmBmbT4sBQV22Zf+/HlodvwJAAj4978gkkohEovh9XA3AIB2T8Jd2wgWC/L/siZQXt3jAADKxwcBADQ7/4RZa787PVRx9/sbEAQBWtvvrxskXl7w6NQJAKC5rc63WMGJEzBnZUPs5QXPTh0hqVPHNuKOiq3ATmPR6XDztdeR9upr0Oza7exwHghMgF2IWauFOTsHgDUBdmvSBG7NmwMmM1S//V6pfVp0OqS/9TZ0R45AJJMh+P9eht+YMVAOHgwAyP5imV1a7fIPWxNpj44dAFiTJt9RIwEAmh1/2q2Mo7IEQbC1snh17wZFVBQgEsGUkVHtrZbefa2twJo/d0IoY7zg8spZswYWnQ7yyEjbh+a9WoEEQbCVQCiiym4Bvhexpyc8u3RB4NQpqPv11whbtBB1hg2DvGh/hZcuI++HH3Bz1iu4PvFfyIyPR/7Bg3ZLEmsSs0aD1GlTkTrzxSqXFAkmE7KWLQMAePXqCbdmzWzPefWwJra644kwF3U0Lab/5x+YMjMhdne3/f25R7eFrF5dCAV6aP7cUaW4qPLyfvoJ18aMgTbh7i8uxQovXLTePXNzg0cH6+/Pu1dPAED+3r2w3DZRFABod1mTYq/u3Wyj7Pg8Zh0iL3//AZhycuz+OqpCsFhqXEyOkPXVVzClpwMAsr/5BsbUVCdHVPtVOAE2Go2QSqU4ffq0I+IhBzJcTQYASIOCbB3HlE9a6/80O3bAXMEx98x5eUib94a1M427G4LnvG57g/V9ejjk9evBrFIj64svy6w1Kw9TVpa1tEAkgke7drbl7i1awD06GjCbkfv9ukrv3x4KL16EKT0dIoUCHu3bQ+zpCVl4uPW5+7SY2ptnx46QKJUw5+ZCd/RYpfejP38e2qKWBv+JE+DWxFo3Xnih7ATYnJ0Ni1oDiMWQ16tX6WMXE4nFUDRqBN8RTyP8vcWo+/VXCPjvf+DRqRNE7m4w5+VBu2s3Mt57H9fGjUPa/PlQ/b4Jxps3q3zsmiB/716YVWqYMjKQ+/3399/gHlSbNsGYch1ib2/43TE8n7xePcgjIwGTGfl//10yhr+sde0esZ0hLkqIRCKRbQQW9ZYtrNMug2CxoODkSRScOWP3uxWq335D7vfrIBTokf3V12WWguUX9Uvw6NgB4qIx991atoQ0KAgWnQ66gwdt65pVKltjg1fPnrbliqgoKJo1BcxmaLZtq1CcloICZH78CfIPHKjQduVh1mqRNvtVXJ/4L+T9/HOlP2cEoxEFJ05Ad/RojSmpu502IcF6F0YshjwiAoJej4ylH5ZZs29PptxcZK/4FhlLP0TGkg+Q8f77uLX4Pdxa9C5uLVwIVVHZY21U4VEgZDIZ6tWrB3PRcDhUe9jKH24b9sy9bVvIo6JguHIF6i1b4FvOiRsM168jY/FiGG+mQaL0QfDrc6C47Za3SC5HwNSpuPnKK9AdPgxtQgK8e/SoVNzF5Q+KJo0hqVOnxHO+I59FQVIS8v/+G4VDBle61bGq8otafz06drAN56Vo0ADGGzdQeOlyicS9vASjEQVJSXBv165CQ5qJZDJ49eoJ1S8boNm+HZ6dO1X82BYLsr/8CgDg1fMRuDVpYhvdovDCBQiCUOqYsYVFNYXyunUdMkaz1NcX3r16wbtXLwgGA/T//APdsUToEo/BlJYO/clT0J88hZxvv4UsLNQ2qoRbs2a2jom1ye23OtV/bINXXBwUjRrddzvBYoE5JwfGtHQY09NgSkuH+o8/AAB+Y8ZAUspMil5xcci5ehXahL/g099aw24xGJC//0DR8z1Krv/ww8hds9Y6QsD+/fCKi6vsy3zgCAYDNHv2QP377zDetN6dkgT4w6tbd3j1iIP8oYeqtH/Nzp3IWbnKul+lD8wqNXKWL0fQiy+WjMNksg5fB8Cr2/8mrRKJxfDu1RO536+D5s+dtt+d9q+9gMkMeYMoKCJLljApBw5Exj/noNmxA3WGDi3337dm1y5oExKg3bcPoUql9a7jfZRn+EizRoP0+W/CUHTHKXft9zBrNPAbM6Zc75eCyYSCU6eQv38/dIePwKLV2p6T+PlBERUFecMGUDRoCLcWzSEuZT6B6mBMS0PWV9b34jrDh8G7Vy+kvvgiDFevImf1GviPf85hx9afPYuMJR/c8y6m2LP2zgpZqUH9XnvtNbz66qv47rvv4OfnZ++YyEFKS4BFIhHqDH0SGe+9D/WWrVAOGgTxfaaI1u7di6zPl0EoLIQ0IAAh8+ZCFhZ213qKyEj4Dn8auWvXIufrb+DeogWkgYEVjrs4AS5uXb7zGJ7dHkb+X3uRu3oNQubOqfD+q0owm5H/d9GHzG0zIyoaNYQ2IaFCHUcEQYDh8mVo9+yBdt/fsGg0CJk3F+6tW1coJu/efaDasBEFJ07AmJ4OWUhIhbYv7vgm9vSE36hRAGAtQRCLYc7NhTk7G9KAgLu2K77LII8sX/1vVYjkcri3aQP3Nm3gP/45GG/etCXD+jNnYbyZBuPNTVBv2gSRuxvc27SBR7t2cI+OhtTJM+WVR+HVqzBcvQqRVAr36GjojhxB1rIvELb43RKja9zOmJqKzPjPYLhypdRWWbfmzW0jhdzJ8+GuyFm1CoUXLsB48yZkYWHQHTkCi04HaUAA3Jo3K7G+SC6Hz6OPInftWqh++x2e3bu7/MQmZm0+NNu2Qb15M8wqFQDrMGIQBJizsqHasAGqDRsgbxAFr7g4eMXF3XMs3tLkHziArGVfAACUgwfDs9vDuPl/s5C//wB0PY6V+LJdcPIUzCo1JEofuLcp+R7i9cgjyF3/A/Rnz8J48yakoaG2fgPevXrfdVyPjh0hDQiAKSsL2n374H1bC/G96Ir7gZjNyHh/CcLefw/SMvIGQRCQu3oNVBs3wqN9e/hPeL7UzwyzSmVNfq9dg0TpA68ej0D1669Q/74JFm0+Av4zqdS/EUEQoD97FtqEBOgOHS6Z9CqVEPv4wJiaCnNODnQ5OdAdPQoAkIWFIXTBO6V+cSwP63XxBxRNm8KtefNy/50IRiMyP/wQQoEebs2bW794iMUInDIFtxYshHrzZri3bgWP9u0rFVeZxxUEqDdtQs6q7wCLBbK6deHdqxdEEjEgFgMiMSAWQSQWQ1rBz5aapFIJ8KeffopLly4hLCwM9evXh+cd47AmltGTmJzr9g5wt/Po2BGysDBrz/vt21FnyJBStxcMBuSsWgX1VmtLklvrVgiaPv2uVtnbKYcMhu7oURReuIDM+HiEzJ0LwFo+YcrKgjknB2a1Gp6dOpU6brBZm4+CooklPDt2LPUYviOeQf7+/Sg4cQIZH30Ev9Gj7/kGW5CUhLx162HKybHe2mvcCIpGjSCPagCJV8XHFC44eRJmlQpiH+8SiWpxS13hpUtltpgWM2VlQfvXXmgTEmC8ccO2XFKnDsxqTZnblUUWHAT3tm1RcPw4NDv+hN/oUeXe9vaOb77PPmP7vYgVCsgjImC4cgWFFy6UngBfqVgHOHuShYVBGRYG5eOPwaLToeDkSeiOHUPBsUSYVSroDh6C7uAha3wNouAR0w4e7dtBHhXltElD7qW4/MSjYwf4T5iAG//8A0NyMtRbtpQ6AYwxPR1pb8yHubgeUiqBLCgI0pBQyEJCIAsPg1ePHmVeh1JfX7i3aYOC48eh/esv+I4YYSt/8IzrXuo58u7XF3m//AJDcjL0p05V+ItabWfJz4chJQWG5GQUXrmC/AMHIBRYR0mRBPhD+fggePfqCZFEAt2xY9DuSYDu+HEYLl9BzuUryFu3HsonnoDPYwNt5SX3ojt+HBkffghYLPDu0we+o0cVlaM8BtWvvyH7q6/h1qKFrdSheFhGz65d70oIpf7+1veIxERodu2GR4cOMF6/DpFcXup4vyKJBN4D+iP3u9VQb94Cr0ceuW8iZ9ZooP/nH+vxQkJgSk9HxvtLEDr/jbvuyAiCgJyVK20jCemOHkXB6dPwHTECPo8OsMVvzstD2hvzYbx+HRKlEiHz34C8bl3I6j6ErM8+h3b3bljy8xH0wgxbK7VgMiH/wEGofv/NWk5XRKJUwiO2Mzxju8CteTOIxGJY9HrrpD2XLqPwymUUJCXBePMmMpYsQcjrr1dqMpDc1d/ZOp8qGjaAz+OD4Bnbucwvsrbt1q1H4aXLEHt5IXD6NNvfoEe7dvB57DGoN21CZnw8wpcsKfMzr6IsOh0y4+Nt75We3R5GwKRJtmvqQVKpBHhIGQkS1VyCyWRLrOSRESWeE4nFUD7xBLLi46HasBEWjRZuLVrArVlT220oU2YmMt5fYhvWq85TQ1Hn6afvmziIJBIETp2C1Jdehv7UaVyf+C9rJ5s7Smg023cg9J2377rNVHD8OGA2Q/bQQ6W2MgPWZM/3mWeQu3oN8v/aC93hI6gzdCiUjw0scZuu8MpV5Hy3CvqT/5uB8PZv+YB1FAVpUFDRN13J//6VSuDepk2prVzF5Q+eXbqUeHOU16sHkVQKi0YDU0YGZMHBpcavTUhA5iefAkX1ayKZDB6dOsGrRxzcW7e+75tkWbz79rEmM7t3wffp4f/7MDAYoEtMRP6hQxAMBkh9fSEp/qnjC+2ePbaOb953THqhaNwIhitXoL9wAZ5dutx1zOIZ4JxVilJM7OEBz86d4dm5MwSLBYYrV6A7loiCxGMovHQZhstXYLh8BXk//giJUgn3mBh4tIuxjjJynzsg1UEwGKAtSj69HukJiVIJvzGjkfXZ58j9fh08OnWCLCjItr4pMxPp896AOScHsrp1EfzyS5CGhFT42vGK6269ZorKIHTHk6zLu5de3iDx8oJ3z0eg3rIVqt9+L1cCLFgsyPrscxjTrK3MsvBwyMLCIA8PhzQ4uMbPNpZ/8CC0exJguHYNplLGQZbVq4s6Q4ZYk87bXotnbCw8Y2OtdbZ//w31jh0wplxH7po1UP+xFb4jRli/oJTxnqo/dw4Zi98DTGZ4du0K/39NtL0X1Rk+HPl/74cpMxN5P/wIvzGjYdHrbZMHeXbrVuo+vXv1QkFiIrS7d8NcVPvqGRtb5uRC3r17I2/9D9YvPGfP3neSH92Ro4DFAnlEBIJeehE3/28WCs+fR/a33yJg4kTbeoIgIGfFt7axhusMH46CkydQeO48cr79FtqEBARM+jck/v5In/cGjKmpkPj5IfSNeba+Ft6PPAKxpycyP1gK3eHDSH9nAQKnTUX+/v3W4TKzsgBY71x4de8Gz4e7wa1F87vOt9jNDW7Nmtk6iRquXcPN116D/tRpZK9YUSLu8jBrNNAmFI0PL5Wi8NJlZC5ditzVgfB57DF49+pZarlHwcmTUG3cCAAI+M9/7mpw8Bv5LPRnzsBw9SoyP/oYIfPmVvmLvCElBRnvvWct25FK4P/cc/Du1++BvbNTqXeaO6dAro0sFgssLjCEUjHD9euwmEwQu7lB7O9/12v3eLgrpBs3wpiairyNG4GNGyESiyCPjIKiUSPk79tXNHWmJ/ynTIFHu3YQcP8heABAEhIC39GjkP31NzAV1RKJxCJI6vhCEhAA081UFF69isxP4xEwY3qJP7b8w4chAHBv3+6evy+fQYOgaNECOctXoPDCBeSsWQPNn3/Cd9xYyOvXR966dbahgERSKbwH9IdH+/bW1syLl1B46SJMGZkwpKbCUEbvWk3CX3D/ay/8/zPJ9m3bUliI/EPWGD0efrhkjFIpZPXro/DyZegvXICklFt5gsWCnHXrIAgCFI0bw7tXT3h07mxLwsp7jkvjFh0NiZ8fTDk50Py9H5I6SuTv+xu6Q4fKNWKC7/Pj7zq+vGFDCNiGwgsX7/p9mPPyYMrOgUgESOvVq1F/X7KoKCijoqAc9hTMeXkoSEyELjER+hMnYVKpoNm9G5rdu62d7po3h0dMDNxjYiANC3XKm3/+kaMwa7WQ+vlB0boVLBYLPOLioNi9G/p/ziH7668ROGsWRCIRTDk5uDXvDRizsiALDUXw3DmQ1KlTqWvHrX17iNzcYMzIQNY3yyGYzVA0aABpWGiZv0+vRx+F+o8/oDt+HAUXLkBxn1k5NX/uhGa3tXVbf67kmKbWW6rBkIWFFyXHYZCGh0MWHl7hUgFH0OzcheyikTSKSf39Ia9fD7KICGvi1KYNRCJRmedf5O0Nr/794dm3L/L37kPeunUwZWUhM/4zqH77HXWefRay0FCYsjJhysiAKTPTOrvjsURYDAbr+NmT/1ty/3I5fJ9/HhnvvgvV77/B4+GuMF6/DoteD1lwMGQNGpT6+3OLiYZYqYQpLw+aovH0PXs+UubvWuThAc/u3aH580+oNm+GolmzUtcrln/ooPX9u0N7SIKD4T9tKjLffRfqP7ZBHhUFr0cesZY9LF9hq1H3/9dEePfpA5+hT0K7azdyV3+HwqtXcXP2bIi9fWBWqSD190fwvLmQhJa8Lt3bt0fQq7OR8e5iFJw+jZR//dv2nESphHf/fvDu2xcSHx8A5Xt/ldati4Bp05C5eDHUf2yD7KGH4N2v3z23uZ16xw5YDAbII+oj+PXXodm2DZpt22HMzET2ihXI/f57yB4KhzQwEJKAAOu/vr7IWb4cAqxfOtw7drj7dyKVImDGdKT93ywUnD6NnO9Ww71De4gkUohkUkAisX4BE4kAswWC2QRYLBBMJghmM8w5uTClpdn6CBjT0mxlO1I/PwS+9CIUjRrZ5ltwBkd/hoiESr6yvLw8/PTTT7h8+TJefvll+Pn5ITExEcHBwQgv+kZWk8THxyM+Ph5msxkXLlzAhQsX4F3Jep7ayHjwIAqWr4CkYQN4/t//lbqOoNPBmJQE84WLMF+4AEvRN+Zikvr14f7vf0Fcyq3v8jAVjYYg9vODyMfH1jplunABuqVLAbMFiieGQFE0PadgNEL74ksQ9Hp4vvIKJOW4rS4IAkyHDkH/8y8Qiv6YIRbbOnDJOnWCYvCgUl+DRaOBJTkZglZrfVM0m63bmS2wqPJg2LkLMBoh8vSE2zMjIO3QAaajR1Hw1dcQBwTA852370qW9N9/D8PuPZD36Q23YcPuPifnz0O35AOI3N3g9d57du84Vvj77ygspZeuyM8Xsg4dIPbzg0WlglD0Y8lTQdCoIevSBW5FM4TdznLrFrRz5gIyGbw/+ggi6f9aGE1nzkD30ccQBwfD66037fo6HEUwmWC+eBGmU6dgOnUallu3SjwvDgyEtFUrSFu3gqRRo2rrSKf7+GOYTp+B/NEBcLvtjpv55k3kv/U2YDbDfdK/IWnYELr3l8CSng5xQAA8Xn4J4irWNxes+BbG23rsuz39NOS97l3vWbB8OYwHD0ESGQGPWbPKbIkSCgqgnTMXgloNWVx3iH18YElPh+XWLZjTbwH36NUu8vaGODgY4pCQop9gSEJCIPL3r/RdkoowHjqMguXLAUGA7OGHIevUEZKHHoKoilOxC0YjDLv3wLB1K4T7DHUnadgQHtOnQ6Qo/X1C98UXMB1LhCQyEiJPD5hOn4HisYFQDBpU5j71P/8MQ9EMj+LgYHi+Of+eX/rMN28i/435gFgMr7ffKvPzQCgshGbmi4DRCM+5cyAp6vhXuGkTCn/7HZDJ4Pl/L8O4fz8Mu/cAANxGj4a828Ml9mNRq1H4w48wFo1OIfb3h8eLM+/5OWROTobu448haPMhDgmBvE8fyDp3qtLfb+HWP1C4YQMgFsNjxgxImza57zaC2Qzta69ByMmF27ixkBfdNRMMBhgPHoRhx593vefcThwWCs/Zr5b5+wYAw/4D0N82YVhVSVu1hNu4cRDXgPxIo9GgcePGUKlU8Cn60mJPlWoBPnnyJHr37g2lUonk5GRMnDgRfn5++OWXX5CSkoJVq1bZO84qmzx5MiZPngy1Wg2lUonAwECHnNCaKlelglEmg3ezZvC/7dbpXW7rIGfKyoL+zFkUnjsHaUAAfB5/rGoJWlnHDQqCRqdD9ldfw7J5M7xatIBH+/YoSEpCgdkMSVAgQjp2KP/tnUGDYOnTB6pffoF602YIJhPc2rSB76iRUDRocO/47vG8YeBAZH8aj8IrV2BcuQryCxcgUWsglcmg7NUTvqWUOGjbtkXWvr8hT7+FoFJef9aPP8Egk8E7Lg7+VewZXhrTkCFI3bkLgtEIibe3td6t68NQNG1SqdtlQmAgjL51YNbmo06BrsT5VO37GwaZDJ5NmyLwXtdYTRMWBhT1gjempaEgMREFx45Bf/YfCHl5sOzdC8PevRArFHBr3RruMTFwj4m2W83dnUzZ2Si4eBFSmQyhjz1WotQBQUHIfWooVL9sgLBhIyzeXhBnZ0MeHIyQt96E1A7nvWBAf9wqKgsSiUUIHdD/nnX+AGCeNAmpZ/+B5UYqPE6dgnfRjIR3yl2zBpKCAsjq1UPYlCklEhLBYoE5O7uo82IqjDdvwpSaCmPqTes4r3o9cO0ahGvXYAZgBmCEtcxKFhoKaXhYiZIKWVhYmbfyK0p36BAyV38HqVQK7z594Ddxgn3vDIwaCfOQwVBv2AjNtj8AkRjSwEBIAwMgCQqCNDAQsuBguEdH3/M92DR5Mm5OnwFLUbmbVCZDyKOPlryG7mAcNAipRfXmvgP6Q1lGqZZNUBBuxUSj4NRpKI4dg+8dQ+oVyz94EAUApOFhCImOtp0vYdw4ZGZkQHcsEYalH0IwGiGTy+A/aVKJodduPx5enY2CEydRcDwRPgMH3r8zdVAQTJ98AlNaeqXf6+4kjBmNbFUetHv3wbxiOQIXLrxv5+L8AwdRoNFC4u+P8EcfLfm7e+opCE8+aZ3l9LaWflNWFsxZ2RDMJgRMmwZ53Xt/LgiDB0FtsSB/714IZjMEk9E6/rvRZBsHXiSVFJX0Sawtw2IxxEof699NSEiJf+31N2MPbg6uO65UAjxz5kyMGzcOixcvLtGK+uijj+LZoilqazqxWAxxDez44iiG5GSIACgiIsr9uuVBQZAHBQGP9HBkaAAAZf/+MF5LgWb7dmR9/DHCFi5EwdFjEAHwbN8BkgrWBYo9PeE/ejR8+vWDOTcPisaNqvyB5Va/PsIWLkDez78g76efoDtgHT9TBMC7e/dSz6tbo8YQwdo5TCQIJVqqLHo9dIcOWrfv2dMh16M8MBBhC96BRau19j62Q32lolFjFBw/DuOlS3C/bUguY/JV6zXWIKrW/m0pwsOhCA9Hnccfh6WgAAUnTkKXeAwFicdhzs1FwZEjKCgalUQeFWWtG46JgaJhQ7t1pNP9tRewCHBr1hSKUr4U+Q4bBt3+AzClp8OckwNpnToInf9GhUf6KItH69aQ+vvBnJ0Dj5gYyMqR6Iv9/OA7YgRyVqxA3trv4RUba7vNXMx4KwOazVsgAuA3ZjQkdw4rJRZDEhwMeXAwEN22xFOWggIY09JgTE0t+rlp/ffmTQhGI4w3bsB44wbuLOyR1Knzv6T4th9pYEC5f1+6xOPI/PBDwCLAu0cPBPxrokM6TYp9fOA/doy1w6pIVKn3K3lAAPxGjUT2198AsHa4Ku0aup2ibl14x3VH4cWL8OnVq1x/u8rHHoP+1Glod+6C79NPl9pBSn/0qPX9u1MnSG5voReLEThtOm6+MgumtHSIRCIE/Pc/9x1VwjO6LTzvuC7uRe7vD7m/f7nXL4+A//4XprR0FF66hMx3FyNs4YJ79hnQ/rEVIgA+fftAUloyJxZDEhUFVLHPhO9TQ+H71NAq7aMmcvTnSKU+DY8cOYIvvvjiruXh4eFIL5qphGoOQRBgvHYNgDUBrqn8xz8H440b0J89i1vvvgtBb52hyKOM0R/KQxYUdM/Wj4oSSaXwfXo4PNq3Q+Ynn8J4/ToUDRtAXrdu6ccPC4XY3d36AX79eokh6HSHDkEo0EMaGgJFk/vfTqsse3dIUzRqhILjx63DuxWVqwBAYdEQaM7uAGcvYnd3eHbuBM/Onawd6ZKTrT3TjyWi8PJlGK5cgeHKFeT9+JN1mKm20fBo387aka6SrSiCIEC7x9oaV1ZCIJbLEfCviUh/+x2IvTwR8sa8MjuIVoZILEadJ55Azqrv4PN42bfO7+QzoD+0u3fDkJyMnNWrEfjf/5Z4Pnf1aghGI9xatix1SMN7Ebu7W0dsuePaEiwWmDKzrC3GtyXFxtRU63B9eXkw5+VBf/Zsydcok0EWFloyOS76/+0dkgpOnUbG4sXWjmdduiBg8n8dPmJIVffv3a8ftAl/ofDiRXiVc+z1wGnTKnQM95gYSENDYEpLh3ZPAnz6l6yJFUwm2yQ8np3uHodc4uWJ4FdmI3fNGnh1e7jUDrU1kVguR9Ars3Dz/2bBeOMGMj78EMGvvFLq76zwylXoz/4DSCQVqhmm6lOpBFihUEBdyqxhFy5cQGAlxnklxzLn5cGsUgNiMWR2mJ3LUUQymbWn8KxXYEqzfpESubvBveW9exo7g6JBA4Qvfhf5h4/A7R61YCKxGPKGDaA/dRqFly6VSICLOwJ5xcXVql62isZFw7vdNr6xWZtvm6azOsYArm4isdiWgPkOHw5zXp6101diIgqOJ8GsUlsH+09IACQSuDVtam0dbtcOsvDwcv9+C8+dg/FmGkRubvCMjS1zPfc2bRD+wRJI6tSp9Nik9+IzYAB8bvtyUx4iiQT+/5qItFdfg3bnLnj36mWdQAXWEQzy9+8HRCL4jRtrt+tdJBZDFhwEWXAQEB1d4jmLTmdLhg2pqTDdvFn0b5q17vZaCgzXUu7ap8TPD7LwMMhCQqHduxeC0QiP9u1LDENVk4nEYgS/9ioKTpyEZ5eyr6GqHsNnwADkLF8B9ZYt8O7bp8S50Z89C0t+PiRKnzK/3MsfCkfwrNL7o9RkUl9fBM/6P6S9PgcFxxKRu3oN/MbcXQZSPKKFZ2ysw8qlqGoqlQAPGjQIb775Jn744QcA1skUUlJSMGvWLAwd+uA1w9d2xZMTyEJCnDabTXlJlEoEzfo/pL32OoTCQnjcp+bNmcoaL/NOioaNbAmwd2/rAPOmzEzoi8Y3LmuIqZqqeHxj4800mDUaSLy9bWNMSwMCHJKQ1TSSOnXg/cgj8H7kEQgmE/T/nENB4jHojiXCmJoK/Zkz0J85A6z6DtKgIGvLcEwM3Fu0uOf1rNm1CwDg2SX2vjNhlXXXwZncmjSBV89HoN21G9lffoWwxe8CIhFyVqwAAHj36nnXDGOOIvbwgKJhw7tGpbC2GmeWLKUo+jGrVNaxyXNyoD91GoD1y0bQizNr/PBst5N4e5frvakqvB95BLnffw9jaioKTpyAx21fQHRFHdY8OlSg70YtomjYEAFTpiBz6VKofv0Vsnp1S8x0as7LQ/6+fQAAn4GPOilKup9K/UUvWbIETz31FIKCglBQUIC4uDikp6cjNjYW77zzjr1jpCoyFJU/1JaWOUVkJIJenIm8n36GcvBgZ4dTZcUfwIUXL9mWaf/6CxAEuLVoYW29qkUkXl62iVMKL16CR0y0bTpS+QNS/lARIqkU7q1awr1VS/iNHQtjerptAg79mTMwZWRAvWUr1Fu2QqRQwL1VK7i3i4FHu3aQ3lajaCkosE077P3II856OVXmN2oUdIcOw5CcDM22bRB7eqLw0mWI3N1Qp5xTrTuStdU42Doud0xMiefM2vyicgprKQUA1HnqqRr7JdyZxB4e8O7ZC+rNm6HevMWWAAsWC/KLE+AqlK/VdF4Pd4XxegryfvoZ2Z8vgyw01HbHQ71jBwSTCYqGDeHWuLGTI6WyVCoBViqV2LFjB/7++2+cOHECWq0WMTEx6N377ukTyflsyckdM8DVZB7t2pWY0rM2UzSyJsCGlBRYCgshksuhLRpzs6xpaWs6RePG1gT4woWiBNh5M8DVNLKQECgHDoRy4EBrR7pTp6zjDh9LtE6xevQodEePIhvWacmLk2HjjRsQ9EU14fcZX7UmkyiV8H32WWR/9RVy134PUVFLdp0nnqzxU1BLvDwhadyYSUs5+Tw6AOotW6ydYlNTIQsPh+HKFZizc6zla61aOTtEh6rz9NMwXL8B3aFDyHh3McIWvwuJUglN0bByPo8NdHKEdC/lToD9/Pxw4cIFBAQEYPz48fjoo4/QtWtXdO3q2NssVHX/awGOcG4gLkri5weJry/MubnWLyMi0f/qPDt3dnZ4laJo1AjaPXtQeOECAGuHDwDVdnu7thC7u8OzY0d4duwIQRBguJpsK5UovHgRhuRkGJKTofr5F9s23uWYYram8+7bB9rdu1B46TJQUABpYCCUjz/m7LDIzmQhIfBo1w66o0eh3roV/hMmIP+QdQrdmly+Zi8isRiBU6cgLT0dhmvXcGvRu/Dp3w/m3FxIfH1r7fu7qyh3cY7BYLB1fFu5ciX0er3DgiL7sRgMtlt5takF+EEiEolKlEFoiwZ99+zU6b51njWVoqiFrPDSJVj0ehiLZs9zxRKI8hKJRFBERaLOU08hbOEC1PvmawROmwrPLl1sQymJZLJy99yvyURiMfwnTrTOQgXAd9SoBz4ZclXFNa6a3Xtg1ubbpl/26Hj36A8PIrG7O4JemQWJ0geGq1eR9cWXAADvfn2rbeIcqpxytwDHxsZiyJAhaNeuHQRBwLRp0+Bexof38uXL7RYgVY0xJQWwWCD29oaEPVGdRtGoIXRHjkB/9iz0p62da2pr+QMAyOvXg0guhyU/31q3arFAolRCUsNvcdckEqUSXnFx8IqLg2AyofDiRYg9PUvUBddmioYNETh1CswqFTy71o5hrqji3Fq1gqxeXRhTriN39WoYb9wApBJ4xETff+MHhCwoCEH/939ImzcPMJkhkkrhU8ZkMFRzlLsFePXq1Xj00Ueh1WohEomgUqmQm5tb6g/VHLeXP9T226q1WXELsO7wYVh0OkgDAuDWouYN71ZeIokEiobWWeA027YBsLb+8hqrHJFUCrdmzSCvwcMUVoZXXByUgwbxuniAiUQi+Dxa1Aq8YwcAwL1lqxo1o1h1cGvaFAH/ngSIxfDu0/u+syeS85W7BTg4OBiLFi0CAERGRuK7776D/wPSUvEgq40d4B5E8jumWPbqEVfrhwdSNGoM/dl/UHjJOroFO8ARuSav7t2Ru3oNLFotAMCj04M7+sO9ePd8BB4d2rtc8l9bVWoUiKtFSdXt8vLyUKcWfeOxWCywWCzODsPhCpOTIQCQ1a/vEq+3phJ5eEAaGgpjWhoAwKNbt1r/+5A1bADh9scREbX+NRFRJchk8OrVC6pff4VIBLi1a+ey7wUiT08IsA4HR1Xj6GuoUgnwu+++i4iICDz99NMAgOHDh+Onn35CaGgotmzZgjZt2tg1SHuIj49HfHw8zGYzACAzM/OB78gnCALyL16CYDRC4+UFXUaGs0NyaaawUJhSUiBpEIVcqRSo5b8Pi68vTEaj7bHGxwf5tfw1EVHlWDp2gHnnTkgbNUKO0Vjr39/I+TQajUP3LxIEQbj/aiVFRkZizZo16NKlC3bs2IHhw4dj/fr1+OGHH5CSkoLt27c7Ila7UKvVUCqVyM3NhY+Pj7PDcShTRgZuTJ4CkUSCet+tYo9UJ9P/8w+yv/gSfs+Pf2DGx7zx70kw5eRA7OmBuitWsNaTiIjsQq1Ww9fXFyqVyiH5WqVagNPT01G3aBrOTZs2Yfjw4ejbty8iIiLQqVPtGPpELBZDXMtrMO/HmJICEaxTpkpq+BTIrsCjRQt4fPyRs8OwK0XjRjAfPARFZBQkEomzwyEiogeEo3O0Su3d19cX169fBwD88ccfthngBEGwlRiQ8xmSkwGwAxw5jmfRF16PdjH3WZOIiKjmqFQL8JNPPolnn30WjRo1QnZ2NgYMGAAAOH78OBoWDfdEzmdI5gxw5Fie3bpB0aQppIEBzg6FiIio3CqVAC9duhQRERG4fv06Fi9eDC8vLwBAWloa/vvf/9o1QKo8iY8PJAH+bAEmhxGJRJAFBzk7DCIiogqpVCe42qy4E5yjiqprIkEQ2DmJiIiIag1H52uVagEGgIsXL2L37t3IyMi4a6y2uXPnVjkwsh8mv0RERET/U6kE+KuvvsJ//vMfBAQEICQkpESCJRKJmAATERERUY1VqQT47bffxjvvvINZs2bZOx4iIiIiIoeq1DBoubm5GDZsmL1jISIiIiJyuEolwMOGDavRs70REREREZWlUiUQDRs2xJw5c3Dw4EG0atUKsjum2J02bZpdgiMiIiIisrdKDYMWGRlZ9g5FIly5cqVKQTmSKw6DRkRERFSb1Mhh0K5evWrvOKqdxWK5a/g2IiIiInI+R+dolR4HuLaJj49HfHw8zGYzACAzMxN6vd7JURERERHRnTQajUP3X+mZ4G7cuIHffvsNKSkpMBgMJZ774IMP7BKcIxQ3qefm5rIEgoiIiKgGUqvV8PX1rVklEDt37sSgQYMQFRWFc+fOoWXLlkhOToYgCIiJibF3jA4hFoshFldqEAwiIiIiciBH52iV2vvs2bPx0ksv4dSpU3Bzc8PPP/+M69evIy4ujuMDExEREVGNVqkE+J9//sGYMWMAAFKpFAUFBfDy8sKbb76Jd999164BEhERERHZU6USYE9PT1vdb2hoKC5fvmx7Lisryz6RERERERE5QKVqgDt37ox9+/ahWbNmePTRR/Hiiy/i1KlT+OWXX9C5c2d7x0hEREREZDeVSoA/+OADaLVaAMD8+fOh1Wqxfv16NGrUqEaPAEFEREREVOEE2Gw248aNG2jdujUAaznEsmXL7B4YEREREZEjVLgGWCKRoG/fvsjNzXVEPEREREREDlWpTnAtW7bElStXqnzwhQsXokOHDvD29kZQUBCGDBmC8+fP33e7H3/8EU2bNoWbmxtatWqFLVu2VDkWIiIiInINlUqA3377bbz00kvYtGkT0tLSoFarS/yUV0JCAiZPnoyDBw9ix44dMBqN6Nu3L/Lz88vcZv/+/XjmmWfw/PPP4/jx4xgyZAiGDBmC06dPV+alEBEREZGLqdBUyG+++SZefPFFeHt7/28HIpHt/4IgQCQSwWw2VyqYzMxMBAUFISEhAd27dy91naeffhr5+fnYtGmTbVnnzp3Rtm3bctUiF0+F7Kip9YiIiIioahydr1WoE9z8+fMxadIk7N692+6BAIBKpQIA+Pn5lbnOgQMHMHPmzBLL+vXrh40bN5a6fmFhIQoLC22Pi1uojUYjjEZjFSMmIiIiIntzdI5WoQS4uLE4Li7O7oFYLBbMmDEDXbt2RcuWLctcLz09HcHBwSWWBQcHIz09vdT1Fy5ciPnz59+1fPv27fDw8Kha0ERERERkdzqdzqH7r/AwaLeXPNjT5MmTcfr0aezbt8+u+509e3aJFmO1Wo26deuib9++LIEgIiIiqoEq0qesMiqcADdu3Pi+SXBOTk6F9jllyhRs2rQJf/31Fx566KF7rhsSEoJbt26VWHbr1i2EhISUur5CoYBCobhruUwmg0wmq1CcREREROR4js7RKpwAz58/H0ql0i4HFwQBU6dOxYYNG7Bnzx5ERkbed5vY2Fjs3LkTM2bMsC3bsWMHYmNj7RITERERET3YKpwAjxgxAkFBQXY5+OTJk7F27Vr8+uuv8Pb2ttXxKpVKuLu7AwDGjBmD8PBwLFy4EAAwffp0xMXFYcmSJRg4cCDWrVuHo0eP4ssvv7RLTERERET0YKvQOMD2rv/9/PPPoVKp0KNHD4SGhtp+1q9fb1snJSUFaWlptsddunTB2rVr8eWXX6JNmzb46aefsHHjxnt2nCMiIiIiKlahcYDFYjHS09Pt1gLsDBwHmIiIiKhmq1HjAFssFrsHQERERERUnSo1FTIRERERUW3FBJiIiIiIXAoTYCIiIiJyKUyAiYiIiMilMAEmIiIiIpdS4YkwHhQWi4WjWhARERHVQI7O0VwmAY6Pj0d8fDzMZjMAIDMzE3q93slREREREdGdNBqNQ/dfoYkwHgTFAyvn5uZyIgwiIiKiGkitVsPX17dmTITxIBGLxRCLWQJNREREVNM4OkdjBkhERERELoUJMBERERG5FCbARERERORSmAATERERkUthAkxERERELoUJMBERERG5FCbARERERORSmAATERERkUthAkxERERELoUJMBERERG5FCbARERERORSpM4OwFksFgssFouzwyAiIiKiOzg6R3OZBDg+Ph7x8fEwm80AgMzMTOj1eidHRURERER30mg0Dt2/SBAEwaFHqGHUajWUSiVyc3Ph4+Pj7HCIiIiI6A5qtRq+vr5QqVQOyddcpgX4TmKxGGIxS6CJiIiIahpH52jMAImIiIjIpTABJiIiIiKXwgSYiIiIiFwKE2AiIiIicilMgImIiIjIpTABJiIiIiKXwgSYiIiIiFwKE2AiIiIicilMgImIiIjIpTABJiIiIiKX4rJTIVssFlgsFmeHQURERER3cHSO5jIJcHx8POLj42E2mwEAmZmZ0Ov1To6KiIiIiO6k0Wgcun+RIAiCQ49Qw6jVaiiVSuTm5sLHx8fZ4RARERHRHdRqNXx9faFSqRySr7lMC/CdxGIxxGKWQBMRERHVNI7O0ZgBEhEREZFLYQJMRERERC6FCTARERERuRQmwERERETkUpgAExEREZFLYQJMRERERC6FCTARERERuRQmwERERETkUmpEAhwfH4+IiAi4ubmhU6dOOHz48D3X//HHH9G0aVO4ubmhVatW2LJlSzVFSkRERES1ndMT4PXr12PmzJmYN28eEhMT0aZNG/Tr1w8ZGRmlrr9//34888wzeP7553H8+HEMGTIEQ4YMwenTp6s5ciIiIiKqjUSCIAjODKBTp07o0KEDPv30UwCAxWJB3bp1MXXqVLzyyit3rf/0008jPz8fmzZtsi3r3Lkz2rZti2XLlt33eGq1Gkql0mFzSxMRERFR1Tg6X5PafY8VYDAYcOzYMcyePdu2TCwWo3fv3jhw4ECp2xw4cAAzZ84ssaxfv37YuHFjqesXFhaisLDQ9lilUgEAcnJyYDQaq/gKiIiIiMjeNBoNAMBR7bROTYCzsrJgNpsRHBxcYnlwcDDOnTtX6jbp6emlrp+enl7q+gsXLsT8+fPvWh4ZGVnJqImIiIioOmRnZ0OpVNp9v05NgKvD7NmzS7QY5+XloX79+khJSXHICe3QoQOOHDni0vtVq9WoW7curl+/bvfbFrXpPDhyvzzHjt0vz6/j981z7Nj91sbz68h98xzXvv2qVCrUq1cPfn5+dt1vMacmwAEBAZBIJLh161aJ5bdu3UJISEip24SEhFRofYVCAYVCcddypVLpkJoSiUTC/Rbx8fGx+75r23lw5PkFeI4duV+A57c69s1zzPNbHfvmOa6d+wWspbEO2a9D9lpOcrkc7dq1w86dO23LLBYLdu7cidjY2FK3iY2NLbE+AOzYsaPM9avb5MmTuV8Hqm3nobadX6D2nYvado5r43ngOa6d+3WU2nit8RzXzv06ktNHgVi/fj3Gjh2LL774Ah07dsSHH36IH374AefOnUNwcDDGjBmD8PBwLFy4EIB1GLS4uDgsWrQIAwcOxLp167BgwQIkJiaiZcuW9z0eR4FwPJ5jx+M5diyeX8fjOXYsnl/H4zl2rAd6FAjAOqxZZmYm5s6di/T0dLRt2xZ//PGHraNbSkpKiebvLl26YO3atXj99dfx6quvolGjRti4cWO5kl/AWhIxb968UssiyD54jh2P59ixeH4dj+fYsXh+HY/n2LEcfX6d3gJMRERERFSdnD4THBERERFRdWICTEREREQuhQkwEREREbkUJsBERERE5FJcLgGOj49HREQE3Nzc0KlTJxw+fNjZIdVaf/31Fx5//HGEhYVBJBJh48aNJZ4fN24cRCJRiZ/+/fs7J9ha6PPPP0fr1q1tg6zHxsZi69attuf1ej0mT54Mf39/eHl5YejQoXdNEkPlt2jRIohEIsyYMcO2rEePHnddw5MmTXJekLVQamoqRo0aBX9/f7i7u6NVq1Y4evSo7XlBEDB37lyEhobC3d0dvXv3xsWLF50Yce0SERFx1zUqEols47LyGq46jUaDGTNmoH79+nB3d0eXLl1KzHrGa7hi7pc7lOd8lnbdL1q0qEJxuFQCvH79esycORPz5s1DYmIi2rRpg379+iEjI8PZodVK+fn5aNOmDeLj48tcp3///khLS7P9fP/999UYYe320EMPYdGiRTh27BiOHj2Knj17YvDgwThz5gwA4IUXXsDvv/+OH3/8EQkJCbh58yaefPJJJ0ddOx05cgRffPEFWrdufddzEydOLHENL1682AkR1k65ubno2rUrZDIZtm7dirNnz2LJkiXw9fW1rbN48WJ8/PHHWLZsGQ4dOgRPT0/069cPer3eiZHXHkeOHClxfe7YsQMAMGzYMNs6vIarZsKECdixYwe+++47nDp1Cn379kXv3r2RmpoKgNdwRd0vdyjv+XzzzTdLXNdTp06tWCCCC+nYsaMwefJk22Oz2SyEhYUJCxcudGJUDwYAwoYNG0osGzt2rDB48GCnxPOg8vX1Fb7++mshLy9PkMlkwo8//mh77p9//hEACAcOHHBihLWPRqMRGjVqJOzYsUOIi4sTpk+fbnvuzsdUMbNmzRIefvjhMp+3WCxCSEiI8N5779mW5eXlCQqFQvj++++rI8QHzvTp04UGDRoIFotFEARew1Wl0+kEiUQibNq0qcTymJgY4bXXXuM1XEV35g7lPZ/169cXli5dWqVju0wLsMFgwLFjx9C7d2/bMrFYjN69e+PAgQNOjOzBtmfPHgQFBaFJkyb4z3/+g+zsbGeHVCuZzWasW7cO+fn5iI2NxbFjx2A0Gktcz02bNkW9evV4PVfQ5MmTMXDgwBLn8nZr1qxBQEAAWrZsidmzZ0On01VzhLXXb7/9hvbt22PYsGEICgpCdHQ0vvrqK9vzV69eRXp6eolzr1Qq0alTJ17HlWAwGLB69WqMHz8eIpHItpzXcOWZTCaYzWa4ubmVWO7u7o59+/bxGrazipzPRYsWwd/fH9HR0XjvvfdgMpkqdCynzwRXXbKysmA2m20zzBULDg7GuXPnnBTVg61///548sknERkZicuXL+PVV1/FgAEDcODAAUgkEmeHVyucOnUKsbGx0Ov18PLywoYNG9C8eXMkJSVBLpejTp06JdYPDg5Genq6c4KthdatW4fExMQS9Xy3e/bZZ1G/fn2EhYXh5MmTmDVrFs6fP49ffvmlmiOtna5cuYLPP/8cM2fOxKuvvoojR45g2rRpkMvlGDt2rO1aLe19mddxxW3cuBF5eXkYN26cbRmv4arx9vZGbGws3nrrLTRr1gzBwcH4/vvvceDAATRs2JDXsJ2V93xOmzYNMTEx8PPzw/79+zF79mykpaXhgw8+KPexXCYBpuo3YsQI2/9btWqF1q1bo0GDBtizZw969erlxMhqjyZNmiApKQkqlQo//fQTxo4di4SEBGeH9UC4fv06pk+fjh07dtzVulPsX//6l+3/rVq1QmhoKHr16oXLly+jQYMG1RVqrWWxWNC+fXssWLAAABAdHY3Tp09j2bJlGDt2rJOje/B88803GDBgAMLCwmzLeA1X3XfffYfx48cjPDwcEokEMTExeOaZZ3Ds2DFnh+ayZs6caft/69atIZfL8e9//xsLFy4s99TJLlMCERAQAIlEclcv+Vu3biEkJMRJUbmWqKgoBAQE4NKlS84OpdaQy+Vo2LAh2rVrh4ULF6JNmzb46KOPEBISAoPBgLy8vBLr83ouv2PHjiEjIwMxMTGQSqWQSqVISEjAxx9/DKlUCrPZfNc2nTp1AgBew+UUGhqK5s2bl1jWrFkzpKSkAIDtWuX7ctVdu3YNf/75JyZMmHDP9XgNV1yDBg2QkJAArVaL69ev4/DhwzAajYiKiuI1bGeVPZ+dOnWCyWRCcnJyuY/lMgmwXC5Hu3btsHPnTtsyi8WCnTt3IjY21omRuY4bN24gOzsboaGhzg6l1rJYLCgsLES7du0gk8lKXM/nz59HSkoKr+dy6tWrF06dOoWkpCTbT/v27TFy5EgkJSWVWqaTlJQEALyGy6lr1644f/58iWUXLlxA/fr1AQCRkZEICQkpcR2r1WocOnSI13EFrVixAkFBQRg4cOA91+M1XHmenp4IDQ1Fbm4utm3bhsGDB/MatrPKns+kpCSIxWIEBQWV/2BV6kJXy6xbt05QKBTCt99+K5w9e1b417/+JdSpU0dIT093dmi1kkajEY4fPy4cP35cACB88MEHwvHjx4Vr164JGo1GeOmll4QDBw4IV69eFf78808hJiZGaNSokaDX650deq3wyiuvCAkJCcLVq1eFkydPCq+88oogEomE7du3C4IgCJMmTRLq1asn7Nq1Szh69KgQGxsrxMbGOjnq2u32HvOXLl0S3nzzTeHo0aPC1atXhV9//VWIiooSunfv7twga5HDhw8LUqlUeOedd4SLFy8Ka9asETw8PITVq1fb1lm0aJFQp04d4ddffxVOnjwpDB48WIiMjBQKCgqcGHntYjabhXr16gmzZs0qsZzXsH388ccfwtatW4UrV64I27dvF9q0aSN06tRJMBgMgiDwGq6oe+UOgnD/87l//35h6dKlQlJSknD58mVh9erVQmBgoDBmzJgKxeFSCbAgCMInn3wi1KtXT5DL5ULHjh2FgwcPOjukWmv37t0CgLt+xo4dK+h0OqFv375CYGCgIJPJhPr16wsTJ07kl40KGD9+vFC/fn1BLpcLgYGBQq9evWzJryAIQkFBgfDf//5X8PX1FTw8PIQnnnhCSEtLc2LEtd/tCXBKSorQvXt3wc/PT1AoFELDhg2Fl19+WVCpVM4Nspb5/fffhZYtWwoKhUJo2rSp8OWXX5Z43mKxCHPmzBGCg4MFhUIh9OrVSzh//ryToq2dtm3bJgC467zxGraP9evXC1FRUYJcLhdCQkKEyZMnC3l5ebbneQ1XzL1yB0G4//k8duyY0KlTJ0GpVApubm5Cs2bNhAULFlS4cU0kCIJQwRZqIiIiIqJay2VqgImIiIiIACbARERERORimAATERERkUthAkxERERELoUJMBERERG5FCbARERERORSmAATERERkUthAkxERERELoUJMBFROY0bNw5Dhgxx+HF69OiBGTNm2B5HRETgww8/dPhxAWD06NFYsGBBtRzrlVdewdSpU6vlWEREt+NMcEREAEQi0T2fnzdvHl544QUIgoA6deo4NJYePXqgbdu2tqQ3MzMTnp6e8PDwcOhxT5w4gZ49e+LatWvw8vJy6LEAICsrC1FRUUhKSkJUVJTDj0dEVEzq7ACIiGqCtLQ02//Xr1+PuXPn4vz587ZlXl5e1ZIUliYwMLBajvPJJ59g2LBh1fY6AwIC0K9fP3z++ed47733quWYREQASyCIiAAAISEhth+lUgmRSFRimZeX110lED169MDUqVMxY8YM+Pr6Ijg4GF999RXy8/Px3HPPwdvbGw0bNsTWrVtLHOv06dMYMGAAvLy8EBwcjNGjRyMrK6vM2O4sgRCJRPj666/xxBNPwMPDA40aNcJvv/1WpWOYzWb89NNPePzxx0ss/+yzz9CoUSO4ubkhODgYTz31lO05i8WChQsXIjIyEu7u7mjTpg1++umnEtufOXMGjz32GHx8fODt7Y1u3brh8uXLtucff/xxrFu3rsy4iIgcgQkwEVEVrFy5EgEBATh8+DCmTp2K//znPxg2bBi6dOmCxMRE9O3bF6NHj4ZOpwMA5OXloWfPnoiOjsbRo0fxxx9/4NatWxg+fHiFjjt//nwMHz4cJ0+exKOPPoqRI0ciJyen0sc4efIkVCoV2rdvb1t29OhRTJs2DW+++SbOnz+PP/74A927d7c9v3DhQqxatQrLli3DmTNn8MILL2DUqFFISEgAAKSmpqJ79+5QKBTYtWsXjh07hvHjx8NkMtn20bFjR9y4cQPJyckVev1ERFUiEBFRCStWrBCUSuVdy8eOHSsMHjzY9jguLk54+OGHbY9NJpPg6ekpjB492rYsLS1NACAcOHBAEARBeOutt4S+ffuW2O/169cFAML58+dt+50+fbrt+fr16wtLly61PQYgvP7667bHWq1WACBs3bq13Me404YNGwSJRCJYLBbbsp9//lnw8fER1Gr1Xevr9XrBw8ND2L9/f4nlzz//vPDMM88IgiAIs2fPFiIjIwWDwVDqMQVBEFQqlQBA2LNnT5nrEBHZG2uAiYiqoHXr1rb/SyQS+Pv7o1WrVrZlwcHBAICMjAwA1o5mu3fvLrXO9vLly2jcuHGFj+vp6QkfH58qHaOgoAAKhaJEZ8A+ffqgfv36iIqKQv/+/dG/f39b2cWlS5eg0+nQp0+fEvsxGAyIjo4GACQlJaFbt26QyWRlvg53d3cAsLWQExFVBybARERVcGdyJxKJSiwrTigtFgsAQKvV4vHHH8e77757175CQ0OrdNyqHCMgIAA6nQ4GgwFyuRwA4O3tjcTEROzZswfbt2/H3Llz8cYbb+DIkSPQarUAgM2bNyM8PLzEvhQKBYD/Jbf3Uly2UV0d/YiIACbARETVKiYmBj///DMiIiIglTrmLbgyx2jbti0A4OzZs7b/A4BUKkXv3r3Ru3dvzJs3D3Xq1MGuXbvQp08fKBQKpKSkIC4urtR9tm7dGitXroTRaCyzFfj06dOQyWRo0aJFhV4jEVFVsBMcEVE1mjx5MnJycvDMM8/gyJEjuHz5MrZt24bnnnsOZrPZaccIDAxETEwM9u3bZ1u2adMmfPzxx0hKSsK1a9ewatUqWCwWNGnSBN7e3njppZfwwgsvYOXKlbh8+TISExPxySefYOXKlQCAKVOmQK1WY8SIETh69CguXryI7777rsTwcnv37kW3bt3K1VpMRGQvTICJiKpRWFgY/v77b5jNZvTt2xetWrXCjBkzUKdOHYjF9nlLruwxJkyYgDVr1tge16lTB7/88gt69uyJZs2aYdmyZfj+++9trbVvvfUW5syZg4ULF6JZs2bo378/Nm/ejMjISACAv78/du3aBa1Wi7i4OLRr1w5fffVVidbgdevWYeLEiXZ53URE5cWZ4IiICIC1I1yTJk2wfv16xMbGOvx4W7duxYsvvoiTJ086rByEiKg0bAEmIiIA1k5rq1atuueEGfaUn5+PFStWMPklomrHFmAiIiIicilsASYiIiIil8IEmIiIiIhcChNgIiIiInIpTICJiIiIyKUwASYiIiIil8IEmIiIiIhcChNgIiIiInIpTICJiIiIyKUwASYiIiIil/L/B+Nhdy3umA4AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = analyzer.plots.xfer_size_timeline(\n", + " figsize=(8, 3),\n", + " unit='mb',\n", + " x_num_ticks=8,\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/dfanalyzer/images/bw_timeline.png b/examples/dfanalyzer/images/bw_timeline.png new file mode 100644 index 00000000..ab2c7093 Binary files /dev/null and b/examples/dfanalyzer/images/bw_timeline.png differ diff --git a/examples/dfanalyzer/images/dask-dashboard-load.png b/examples/dfanalyzer/images/dask-dashboard-load.png new file mode 100644 index 00000000..89732dac Binary files /dev/null and b/examples/dfanalyzer/images/dask-dashboard-load.png differ diff --git a/examples/dfanalyzer/images/xfer_timeline.png b/examples/dfanalyzer/images/xfer_timeline.png new file mode 100644 index 00000000..6f93447d Binary files /dev/null and b/examples/dfanalyzer/images/xfer_timeline.png differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-0.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-0.pfw.gz new file mode 100644 index 00000000..7c91a5cb Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-0.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-1.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-1.pfw.gz new file mode 100644 index 00000000..127ba8a4 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-1.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-10.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-10.pfw.gz new file mode 100644 index 00000000..82a4f080 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-10.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-11.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-11.pfw.gz new file mode 100644 index 00000000..5fdad7e8 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-11.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-12.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-12.pfw.gz new file mode 100644 index 00000000..59047965 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-12.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-13.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-13.pfw.gz new file mode 100644 index 00000000..a134f477 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-13.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-14.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-14.pfw.gz new file mode 100644 index 00000000..c24ca622 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-14.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-15.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-15.pfw.gz new file mode 100644 index 00000000..aabb1be5 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-15.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-2.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-2.pfw.gz new file mode 100644 index 00000000..16dd6f69 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-2.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-3.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-3.pfw.gz new file mode 100644 index 00000000..3c9f6696 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-3.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-4.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-4.pfw.gz new file mode 100644 index 00000000..b120d7e9 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-4.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-5.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-5.pfw.gz new file mode 100644 index 00000000..59ae000a Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-5.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-5.pfw.gz.zindex b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-5.pfw.gz.zindex new file mode 100644 index 00000000..b138540d Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-5.pfw.gz.zindex differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-6.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-6.pfw.gz new file mode 100644 index 00000000..fb0ffc4b Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-6.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-7.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-7.pfw.gz new file mode 100644 index 00000000..dbf56892 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-7.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-8.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-8.pfw.gz new file mode 100644 index 00000000..72e1bcdf Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-8.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace-distributed/test-trace-dist-9.pfw.gz b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-9.pfw.gz new file mode 100644 index 00000000..5ab644d4 Binary files /dev/null and b/examples/dfanalyzer/test-trace-distributed/test-trace-dist-9.pfw.gz differ diff --git a/examples/dfanalyzer/test-trace.pfw.gz b/examples/dfanalyzer/test-trace.pfw.gz new file mode 100644 index 00000000..edbd9a7c Binary files /dev/null and b/examples/dfanalyzer/test-trace.pfw.gz differ diff --git a/examples/graph_visualization/README.md b/examples/graph_visualization/README.md new file mode 100644 index 00000000..5748c38f --- /dev/null +++ b/examples/graph_visualization/README.md @@ -0,0 +1,49 @@ +# Ipycytoscape visualization for trace graph + +## Overview + +This example demonstrates how to represent traces(DFanalyzer events) as graphs and visualize them using ipycytoscape within a Jupyter Notebook environment. + +## Requirements + +To visualize ipycytoscape graphs in DFanalyzer, the following packages are required: + +- **networkx** +- **ipycytoscape** +- **ipywidgets** + +You can install these packages using pip: +```bash + pip install networkx ipycytoscape ipywidgets +``` + +## Graph creation and styling +We use folloing methods to convert the traces into graph and perform visualization. + +- **create_nx_graph**: + This method from *GraphFunctions* class takes dask dataframe (analyzer.events) and return a networkx graph. In this example, we define nodes as each event in dataframe, and edges between two + events represent the existance of overlapping time between the events. The definition of nodes/edges may be changed within this method for different use cases. + +- **visualize_graph**: + This method takes takes *networkx* graph object and a *CytoGraph* object. Two methods used from *CytoGraph* are + - ***get_json*** is used to convert nx graph into json format requried for ipycytoscape visualization. + - ***get_style*** is used for styling the cytoscape visualization. We can modify this method to insert different filters (different coloring and layouts) during the visualization. + + + +## Usage + +In this example, we used following trace event to represent as graph and visualize using ipycytoscape. Two different colors represent events related with two mount points. + +data + +The trace data is visualized using ipycytoscape, representing each event as a node, with connections indicating overlapping windows. +Nodes with a degree greater than 2 are styled in red; others in purple. + +vis + +## Additional Resource + +- Networkx +- Ipycytoscape + diff --git a/examples/graph_visualization/data.png b/examples/graph_visualization/data.png new file mode 100644 index 00000000..dbf886ca Binary files /dev/null and b/examples/graph_visualization/data.png differ diff --git a/examples/graph_visualization/example.ipynb b/examples/graph_visualization/example.ipynb new file mode 100644 index 00000000..872293b9 --- /dev/null +++ b/examples/graph_visualization/example.ipynb @@ -0,0 +1,643 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#imports \n", + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/workspace/pandey2/DFtracer/envdft/lib/python3.9/site-packages/dask/dataframe/__init__.py:49: FutureWarning: \n", + "Dask dataframe query planning is disabled because dask-expr is not installed.\n", + "\n", + "You can install it with `pip install dask[dataframe]` or `conda install dask`.\n", + "This will raise in a future version.\n", + "\n", + " warnings.warn(msg, FutureWarning)\n" + ] + } + ], + "source": [ + "import json\n", + "import os\n", + "import yaml\n", + "from pathlib import Path\n", + "from dask.distributed import Client\n", + "import dask.dataframe as dd\n", + "import networkx as nx\n", + "import sys\n", + "import pandas as pd\n", + "from IPython.display import Image\n", + "\n", + "import ipycytoscape\n", + "import ipywidgets as widgets\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/usr/WS1/pandey2/DFtracer1/dftracer/dfanalyzer/__init__.py\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [06:59:12] Initialized Client with 4 workers and link http://127.0.0.1:42171/status [/usr/WS1/pandey2/DFtracer1/dftracer/dfanalyzer/main.py:676]\n", + "2024-07-15 06:59:12,321 - distributed.nanny - WARNING - Restarting worker\n", + "2024-07-15 06:59:12,344 - distributed.nanny - WARNING - Restarting worker\n", + "2024-07-15 06:59:12,347 - distributed.nanny - WARNING - Restarting worker\n", + "2024-07-15 06:59:12,386 - distributed.nanny - WARNING - Restarting worker\n", + "[INFO] [06:59:13] Restarting all workers [/usr/WS1/pandey2/DFtracer1/dftracer/dfanalyzer/main.py:664]\n" + ] + } + ], + "source": [ + "\n", + "use_local=True\n", + "if not use_local:\n", + " with open(f'/g/g91/pandey2/.dftracer/configuration.yaml', 'r') as file:\n", + " dlp_yaml = yaml.safe_load(file)\n", + " app_root = dlp_yaml[\"app\"]\n", + "else:\n", + " app_root = str(Path(os.getcwd()).parent.parent)\n", + "sys.path.insert(0, app_root)\n", + "\n", + "\n", + "import dfanalyzer\n", + "print(dfanalyzer.__file__)\n", + "from dfanalyzer.main import DFAnalyzer,get_dft_configuration,update_dft_configuration,setup_logging,setup_dask_cluster, reset_dask_cluster, get_dft_configuration\n", + "\n", + "\n", + "if not use_local:\n", + " dask_run_dir = os.path.join(app_root, \"dfanalyzer\", \"dask\", \"run_dir\")\n", + " with open (os.path.join(dask_run_dir, f\"scheduler_{os.getenv('USER')}.json\"), \"r\") as f:\n", + " dask_scheduler = json.load(f)[\"address\"]\n", + "else:\n", + " dask_scheduler = None\n", + "\n", + "\n", + "\n", + "# Configuration 4 update log file dlp -> df\n", + "conf = update_dft_configuration(dask_scheduler=dask_scheduler, verbose=True, \n", + " log_file=f\"./dft_{os.getenv('USER')}.log\", rebuild_index=False, time_approximate=False, \n", + " host_pattern=r'lassen(\\d+)', time_granularity=30e6, skip_hostname=True)\n", + "conf = get_dft_configuration()\n", + "\n", + "\n", + "# Setup\n", + "setup_logging()\n", + "setup_dask_cluster()\n", + "reset_dask_cluster()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[INFO] [06:59:13] Created index for 0 files [/usr/WS1/pandey2/DFtracer1/dftracer/dfanalyzer/main.py:370]\n", + "[INFO] [06:59:13] Total size of all files are bytes [/usr/WS1/pandey2/DFtracer1/dftracer/dfanalyzer/main.py:372]\n", + "[INFO] [06:59:15] Loaded events [/usr/WS1/pandey2/DFtracer1/dftracer/dfanalyzer/main.py:430]\n", + "[INFO] [06:59:15] Loaded plots with slope threshold: 45 [/usr/WS1/pandey2/DFtracer1/dftracer/dfanalyzer/main.py:436]\n" + ] + } + ], + "source": [ + "filename = \"test_data1.pfw\"\n", + "analyzer = DFAnalyzer(filename)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namecatpidtidtstedurtintervaltrangehostnamecompute_timeio_timeapp_io_timetotal_timefilenamephasesizeid
0readPOSIX01906060[10,70]01d9bd41c01e6<NA>[10,70]<NA>[10,70]<NA>2<NA>0
1readPOSIX019304010[40,50]01d9bd41c01e6<NA>[40,50]<NA>[40,50]<NA>2<NA>1
2readPOSIX01911017060[120,180]01d9bd41c01e6<NA>[120,180]<NA>[120,180]<NA>2<NA>2
3readPOSIX01920024040[210,250]01d9bd41c01e6<NA>[210,250]<NA>[210,250]<NA>2<NA>3
4readPOSIX01922023010[230,240]01d9bd41c01e6<NA>[230,240]<NA>[230,240]<NA>2<NA>4
5readPOSIX01905050[10,60]01d9bd41c01e6<NA>[10,60]<NA>[10,60]/dlio/data12<NA>5
6readPOSIX019308050[40,90]01d9bd41c01e6<NA>[40,90]<NA>[40,90]<NA>2<NA>6
7FreadPOSIX01910018080[110,190]01d9bd41c01e6<NA>[110,190]<NA>[110,190]<NA>2<NA>7
8readPOSIX01913017545[140,185]01d9bd41c01e6<NA>[140,185]<NA>[140,185]/dlio/data1/train/2<NA>8
9readPOSIX01915017020[160,180]01d9bd41c01e6<NA>[160,180]<NA>[160,180]<NA>2<NA>9
10readPOSIX0191791834[189,193]01d9bd41c01e6<NA>[189,193]<NA>[189,193]<NA>2<NA>10
11readPOSIX0192102155[220,225]01d9bd41c01e6<NA>[220,225]<NA>[220,225]/dlio/data1/valid/2<NA>11
\n", + "
" + ], + "text/plain": [ + " name cat pid tid ts te dur tinterval trange hostname \\\n", + "0 read POSIX 0 19 0 60 60 [10,70] 0 1d9bd41c01e6 \n", + "1 read POSIX 0 19 30 40 10 [40,50] 0 1d9bd41c01e6 \n", + "2 read POSIX 0 19 110 170 60 [120,180] 0 1d9bd41c01e6 \n", + "3 read POSIX 0 19 200 240 40 [210,250] 0 1d9bd41c01e6 \n", + "4 read POSIX 0 19 220 230 10 [230,240] 0 1d9bd41c01e6 \n", + "5 read POSIX 0 19 0 50 50 [10,60] 0 1d9bd41c01e6 \n", + "6 read POSIX 0 19 30 80 50 [40,90] 0 1d9bd41c01e6 \n", + "7 Fread POSIX 0 19 100 180 80 [110,190] 0 1d9bd41c01e6 \n", + "8 read POSIX 0 19 130 175 45 [140,185] 0 1d9bd41c01e6 \n", + "9 read POSIX 0 19 150 170 20 [160,180] 0 1d9bd41c01e6 \n", + "10 read POSIX 0 19 179 183 4 [189,193] 0 1d9bd41c01e6 \n", + "11 read POSIX 0 19 210 215 5 [220,225] 0 1d9bd41c01e6 \n", + "\n", + " compute_time io_time app_io_time total_time filename phase \\\n", + "0 [10,70] [10,70] 2 \n", + "1 [40,50] [40,50] 2 \n", + "2 [120,180] [120,180] 2 \n", + "3 [210,250] [210,250] 2 \n", + "4 [230,240] [230,240] 2 \n", + "5 [10,60] [10,60] /dlio/data1 2 \n", + "6 [40,90] [40,90] 2 \n", + "7 [110,190] [110,190] 2 \n", + "8 [140,185] [140,185] /dlio/data1/train/ 2 \n", + "9 [160,180] [160,180] 2 \n", + "10 [189,193] [189,193] 2 \n", + "11 [220,225] [220,225] /dlio/data1/valid/ 2 \n", + "\n", + " size id \n", + "0 0 \n", + "1 1 \n", + "2 2 \n", + "3 3 \n", + "4 4 \n", + "5 5 \n", + "6 6 \n", + "7 7 \n", + "8 8 \n", + "9 9 \n", + "10 10 \n", + "11 11 " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "analyzer.events['id'] = analyzer.events.index\n", + "analyzer.events.compute()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/usr/WS1/pandey2/DFtracer1/dftracer'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "app_root" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8e64b9b680674bd399eb68f945746e57", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "CytoscapeWidget(cytoscape_layout={'name': 'dagre'}, cytoscape_style=[{'selector': 'nodes', 'style': {'font-fam…" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from dfanalyzer.graph_visualization.cytoscape import CytoGraph,GraphFunctions\n", + "graphfunction = GraphFunctions()\n", + "cytograph = CytoGraph()\n", + "graph = graphfunction.create_nx_graph(analyzer.events.compute())\n", + "graphfunction.visualize_graph(graph, cytograph)\n", + "# graphfunction.visualize_nxgraph(graph,cyto_obj=cytograph)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test data visualization\n", + "Data designed for sanity check of the tool. Two different colors represent read/write request to two different mount points." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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MC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MzUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjExOTI8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpVc2VyQ29tbWVudD5TY3JlZW5zaG90PC9leGlmOlVzZXJDb21tZW50PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KLiO+eAAAABxpRE9UAAAAAgAAAAAAAACvAAAAKAAAAK8AAACvAAB4WVWbIgYAAEAASURBVHgB7J0JvE3V+8bfa3bNY8iUJFEyTyGFDCEypAiNokGa/839SqUyNyhRiZJUpCKKBkNkaDJkiFAiMnON+7+e91rHPueec+651z33nuFZn8+1p7XXXvu7j73Wftb7vivBMUmYSIAESIAESIAESIAESIAESIAESIAESIAESCCLCCRQoMoi8rwsCZAACZAACZAACZAACZAACZAACZAACZCAEqBAxR8CCZAACZAACZAACZAACZAACZAACZAACZBAlhKgQJWl+HlxEiABEiABEiABEiABEiABEiABEiABEiABClT8DZAACZAACZAACZAACZAACZAACZAACZAACWQpAQpUWYqfFycBEiABEiABEiABEiABEiABEiABEiABEqBAxd8ACZAACZAACZAACZAACZAACZAACZAACZBAlhKgQJWl+HlxEiABEiABEiABEiABEiABEiABEiABEiABClT8DZAACZAACZAACZAACZAACZAACZAACZAACWQpAQpUWYqfFycBEiABEiABEiABEiABEiABEiABEiABEqBAxd8ACZAACZAACZAACZAACZAACZAACZAACZBAlhKgQJWl+HlxEiABEiABEiABEiABEiABEiABEiABEiABClT8DZAACZAACZAACZAACZAACZAACZAACZAACWQpAQpUWYqfFycBEiABEiABEiABEiABEiABEiABEiABEqBAxd8ACZAACZAACZAACZAACZAACZAACZAACZBAlhKgQJWl+HlxEiABEiABEiABEiABEiABEiABEiABEiABClT8DZAACZAACZAACZAACZAACZAACZAACZAACWQpAQpUWYqfFycBEiABEiABEiABEiABEiABEiABEiABEqBAxd8ACZAACZAACZAACZAACZAACZAACZAACZBAlhKgQJWl+HlxEiABEiABEiABEiABEiABEiABEiABEiABClT8DZAACZAACZAACZAACZAACZAACZAACZAACWQpAQpUWYqfFycBEiABEiABEiABEiABEiABEiABEiABEqBAxd8ACZAACZAACZAACZAACZAACZAACZAACZBAlhKgQJWl+HlxEiABEiABEiABEiABEiABEiABEiABEiABClT8DZAACZAACZAACZAACZAACZAACZAACZAACWQpAQpUWYqfFycBEiABEiABEiABEiABEiABEiABEiABEqBAxd8ACZAACZAACZAACZAACZAACZAACZAACZBAlhKgQJWl+HlxEiABEiABEiABEiABEiABEiABEiABEiABClT8DZAACZAACZAACZAACZAACZAACZAACZAACWQpAQpUWYqfFycBEiABEiABEiABEiABEiCBZALPPPOMrFmzRiZOnKg7sL148WJdT0hIkHPPPVdq1qwpXbt2lXz58qUJ22+//Sbz5s2TAwcOSJ06daRly5aSLVu2NJVx/PhxueGGG+Sqq67SOqTp5HRk/uuvv+Srr76SXbt2SbNmzaRu3bp+Szl58qS8+eabUqhQIbnmmmv85uFOEiCByCdAgSrynxFrSAIkQAIkQAIkQAIkQAIkEAcEKlasKPj75ptv9G6xDlGocePGKiwtXLhQ9u7dKxdeeKFMmzZNBatQsLz11lty8803S/bs2SV//vyye/du6dGjh7z//vuhnO7JA3GrVq1aKlI9/PDDnv3hWHnllVfkjjvukMKFC8uxY8fk0KFDgn39+/dPcbm77rpLRo8eLT179vSIeykycQcJkEDEE6BAFfGPKHgFjx49qqMX7dq1k9tuu03stuM4emKePHm0AWvUqJFcccUVwQvzc/Tnn3/WUYsLLrhALrvsMsmbN6+fXMF3/fTTT/L000/L8OHDpXz58sEzn+FRNFzfffedrFixQqpVqybgkjNnTr+lbt26VT788ENp3ry5NrR+M3EnCZAACZAACZAACZAACWQCgR07dshZZ50l999/v7zwwgviu40qnDhxQqZMmSLXXXedtGnTRmbOnJlqzQ4fPqxCFkQuWBkVKFBA+vXrJ+PG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WWsSiByBF154wbn77rsd/JhHsvtXr171ucCpU6ecjBkzOuXLl9fja9eudapWreoRoLwz79+/37nrrrucvn37eh92Vq1a5UCoCps2btzoPPfcc84DDzzgPPLIIw4GMHj52oQ6WWELA5cSJUr4/GvdurVmRR27du2qItPDDz+s18Fgxqbhw4c7tWrVcv777z97yPP56aefqoC2ZcsWzzEIURjgeAtQ+AGCaxQsWNCpUaOGkyNHDk9+bkRMgD/cI+bDsyQQmwQwmEmfPr1Tv359vY3db9Cggd/bQpCBcIPnYERpw4YN+ux88sknnalTpzrfffedA5EpZ86czsWLF28rismQLFmyOEmSJHGaNWvmbNu2zZPn+PHjKhR98sknnmMHDhxwcuXK5Tz22GMOnvFIw4YN03xFixZ1nnjiCf1XoUIFPTZ69GhP2fA2KleurHl//PFHB4PHEydOOJUqVdL3Fp7xeE+lTZvW6datm17ixo0bDsSsjh07hndJHicBJcD3HL8IJEACJEACsU2AAlVsE+b145VAgQIFdFbaViLsvj2OTwwQcB5pyJAh+gO/c+fOuu/938cff6zn1q9f72Cw0K9fP2fJkiV+Z3vwwz9z5sx67ZkzZzqDBg1ykiVL5hGkIJRhFvutt97SW4wYMcKBmIR/hQsX1vt8/vnnDqy8MLuNgQzuh9n7DBkyOO3atfNU7fHHH9f8v//+u+eY3UDZcuXKqSUZBkf/+9//HMzaeycM6F588UXn/vvvdyDCPfjgg07jxo29s3A7AgL84R4BHJ4igVgmsHPnTn3+DRgwQO9k9z/88MPb7rx161bNCwHpTumpp55y7r33XufkyZOerDNmzNDyeO77S8jbo0cPFarwfLdWqnPmzNFydv/IkSNO/vz5dULAWljheigLy6cvvvjitn/WMsvffe0xWGJlzZrV7uonJjBggYV7wloL/3B9vMP69++v55599lnn119/9SnHHRLwJsD3nDcNbpMACZAACcQGAQpUsUGV1wwKAqdPn9YZY2udZPc7derkt34PPfSQWi7hZHTdJ7xvACskuFzY2fZ3333XI1DBUguDhunTp3sXcb7++mut+/vvv6/H7Yy6dVXEQYhdcDO0CZZQv/32m931fMJCAPew/zAwwTasB7yv9+abb6oFAqys7Ew/xDimyBHgD/fIcWIuEogNAt9++60+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yfXr12XPnj2SP3/+SOWPKNP06dOle/fu8scff0iGDLdcCjds2CA9evTQe1SuXFkGDx4syZMn18vs27dPhg8fLgsWLJDcuXPL0KFDJV8+WntFxJjnSIAESCCYCVCgCubeYd1IgARIgARIgARIgARIIIgJLF++XJo0aSJHjhwJuJYQoTp37iwrVqyQLFmyyOHDh/Va586dkxw5cshrr70mderUkVdffVWqV68uH374oZ6vUaOGClNt2rSRjz/+WC5evCizZs0KuB4sSAIkQAIkEL8EKFDFL3/enQRIgARIgARIgARIgARcSWDy5MnyxhtvyMmTJyVPnjxq+YTtLl26yLp166RYsWLyxRdfSLZs2bR9DRs2FIhK7dq182nvr7/+Kv/++69s375dtmzZIj/88IOenzlzpnTo0EEOHTokd911l0ydOlXef/992bp1q1y6dElGjBiholWKFCnkrbfekl27dgnKMJEACZAACbiTAAUqd/Yba00CJEACJEACJEACJEAC8UoAIhGspx577DHp1KmTpEuXTl39XnnlFRWO+vbtq5ZV33zzjdbz9ddflwoVKmgZfxWvV6+elC1bVrp166anFy5cKHXr1pWdO3dKxowZpWTJkrJt2zaBi6JNuPa4cePk2LFjMm3aNHnooYfsKX6SAAmQAAm4jAAFKpd1GKtLAiRAAiRAAiRAAiRAAsFCIG/evGolVa1aNZk/f77Url1bIETB4mn//v1y4MABWbNmTaSqmzVrVpk4caJUrVpV89+4cUOaNm2qbns27lTx4sVl8eLFnuvNmTNHIFLB1RBWW7gGEwmQAAmQgDsJUKByZ7+x1iRAAiRAAiRAAiRAAiQQrwROnDghmTNnVhc/WE8NGzZMXey6du3qqde9996rVlGeA+FsQMjKbQKdnzp1StKmTeuT68yZMxoYHRZWiEEFt8KRI0dK48aN9f7InD17do1D1axZM5+y3CEBEiABEnAPAQpU7ukr1pQESIAESIAESIAESIAEgoYAVturVauWBjWHhdPs2bMF4tTmzZslceLEUr58eWnfvr20aNFC3e8yZcokVapU8Vt/rODXq1cvjUNlM8Aaq0iRItK/f39144MwhRhVEKMQ1wquhFj1b+3atVKxYkVZuXKlxr2y5flJAiRAAiTgLgIUqNzVX6wtCZAACZAACZAACZAACQQFAVg2Va5cWYOTHz9+XK2cWrVqJXPnzpW7775bXfXGjh2r7n4QkPLlyyfY95feeecdDZQ+YcIEz+nffvtN41WdPn1acuXKpWXLlSun5xEMfcCAASpY3XfffdKxY0ddCdBTmBskQAIkQAKuI0CBynVdxgqTAAmQAAmQAAmQAAmQQPASuHLliiRKlEiSJk3qqeTNmzdVqEJsqqims2fPSpo0afwWO3/+vKRKlcrvOR4kARIgARJwFwEKVO7qL9aWBEiABEiABEiABEiABEiABEiABEiABEKOAAWqkOtSNogESIAESIAESIAESIAESIAESIAESIAE3EWAApW7+ou1JQESIAESIAESIAESIAESIAESIAESIIGQI0CBKuS6lA0iARIgARIgARIgARIgARIgARIgARIgAXcRoEDlrv5ibUmABEiABEiABEiABEiABEiABEiABEgg5AhQoAq5LmWDSIAESIAESIAESIAESIAESIAESIAESMBdBChQuau/WFsSIAESIAESIAESIAEScAWB69evS5IkSVxRV1aSBEiABEgg/glQoIr/PmANSIAESIAESIAESIAESCDkCGTNmlWmTp0qlSpVirG27du3T4YPHy4LFiyQ3Llzy9ChQyVfvnx6/f3798vIkSNl/vz5kjNnThk4cKAUKlQoxu7NC5EACZAACcQuAQpUscuXVycBEiABEiABEiABEiCBBElgz549KhTFpBVVjRo1VJhq06aNfPzxx3Lx4kWZNWuW8q1bt66kT59eWrduLcOGDZOjR4/Kb7/9liDZs9EkQAIk4EYCFKjc2GusMwmQAAmQAAmQAAmQAAkEAYFx48apGHTq1CmBQDR48GBJmjSpLF26VC2Y5s2bJwMGDJAJEyZobR3HkQYNGui56dOna34ISU2bNtVjtkkNGzYUiFHt2rWzh+TSpUsyYsQIefXVVyVFihTy1ltvya5du2TmzJly5swZ6dq1qwwZMkRSp04tY8eO1e0tW7Z4ynODBEiABEgguAlQoAru/mHtSIAESIAESIAESIAESCAoCVy9elXFoCVLlkiBAgWkaNGiKiDVqVNH+vXrJxCHpkyZIufPn1dxafLkyfLBBx/IihUr5NixY1K/fn2ZM2eOli1fvrxaRNWqVUvb+vrrr0uFChWkSZMmt7X9m2++EQhjuMa0adPkoYce8skDsapcuXLyzDPPSM+ePX3OcYcESIAESCB4CVCgCt6+Yc1IgARIgARIgARIgARIIKgJQARatWqVvPfee/L8889LsmTJNDA6rKmqVKkib7zxhtb/xx9/lLZt28ovv/wihQsXlpdfflnd72rXrq3nYWkFCyi4590pQdSCSLV8+XJZt26dINaVTX///bcKX8WLF5evv/5aEiVKZE/xkwRIgARIIMgJUKAK8g5i9UiABEiABEiABEiABEggmAnMnj1bevfuLZkzZxYITUhZsmSR7777TmAZtXDhQnnuuefUWqpUqVJ6HpZSEKpgJWXTo48+Kjly5LC7t30iAHrjxo31PjiZPXt2tbpq1qyZ5oWrH2JTQSzr0qXLbeV5gARIgARIILgJUKAK7v5h7UiABEiABEiABEiABEggKAkgllTJkiVVEELMKbjsnT59WrDSHlbWO3v2rFo4Pf300ypWea/mBwsqBDT/5JNPZPv27SpUwSUQ1lBw28uUKZNaYHk3PFu2bPLKK69I9+7dZe3atVKxYkVZuXKlFClSRLp166YrBsKlsGzZslrsrrvu8i7ObRIgARIggSAnQIEqyDuI1SMBEiABEiABEiABEiCBYCSwbNkygfUSgpJfv35dhaOWLVvKjBkzpH///rJhwwaNL4VA5unSpdMmQFSCpdOhQ4c0qPqJEyc04DlEpxdffNGTBwIXAp17J5RDwHUIWffdd5907NhROnfuLKNHj/YJpm7LYBXBPHny2F1+kgAJkAAJBDkBClRB3kGsHgmQAAmQAAmQAAmQAAkEMwFYTVkBKqr1RAD1VKlS+RS7efOmwPopPAsof2V8LsAdEiABEiABVxKgQOXKbmOlSYAESIAESIAEhkmbTwAAH09JREFUSIAESIAESIAESIAESCB0CFCgCp2+ZEtIgARIgARIgARIgARIgARIgARIgARIwJUEQkKgerRFH4W/adytT1f2BCtNAiTgGgJ85rimq1hREiABEiABEiABEiABEiABlxCgQOWSjmI1SYAEgocABarg6QvWhARIgARIgARIgARIgARIIDQIUKAKjX5kK0iABOKQQKACVaDl4rBpvBUJkAAJkAAJBEyA77mA0bEgCZAACZCAIUCBil8DEiABEogigUB/gAdaLorVY3YSIAESIAESiBcCgbznAikTL43jTUmABEjAJQTc/FwNCYHq5YHjZe1fe2XMuy2kZMHcLvna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", + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "Image(filename =r'data.png')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Visualization of traces as graph with ipycytoscape\n", + "* Nodes: Events\n", + "\n", + "* Edges: If two events have any overlapping time.\n", + "\n", + "* Degree: Count of overlapping events\n", + "\n", + "* Visualization filters: Nodes/Events with degree > 2 are \"Red\". Events with degree <= 2 are colored purple." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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BAgQIECAAAECBKoKGDSrNiMXAQIECBAgQIAAAQIECBAgQIAAAQJJwKCZSBwIECBAgAABAgQIECBAgAABAgQIEKgqYNCs2oxcBAgQIECAAAECBAgQIECAAAECBAgkAYNmInEgQIAAAQIECBAgQIAAAQIECBAgQKCqgEGzajNyESBAgAABAgQIECBAgAABAgQIECCQBAyaicSBAAECBAgQIECAAAECBAgQIECAAIGqAgbNqs3IRYAAAQIECBAgQIAAAQIECBAgQIBAEjBoJhIHAgQIECBAgAABAgQIECBAgAABAgSqChg0qzYjFwECBAgQIECAAAECBAgQIECAAAECScCgmUgcCBAgQIAAAQIECBAgQIAAAQIECBCoKmDQrNqMXAQIECBAgAABAgQIECBAgAABAgQIJAGDZiJxIECAAAECBAgQIECAAAECBAgQIECgqoBBs2ozchEgQIAAAQIECBAgQIAAAQIECBAgkAQMmonEgQABAgQIECBAgAABAgQIECBAgACBqgIGzarNyEWAAAECBAgQIECAAAECBAgQIECAQBIwaCYSBwIECBAgQIAAAQIECBAgQIAAAQIEqgoYNKs2IxcBAgQIECBAgAABAgQIECBAgAABAknAoJlIHAgQIECAAAECBAgQIECAAAECBAgQqCpg0KzajFwECBAgQIAAAQIECBAgQIAAAQIECCQBg2YicSBAgAABAgQIECBAgAABAgQIECBAoKqAQbNqM3IRIECAAAECBAgQIECAAAECBAgQIJAEDJqJxIEAAQIECBAgQIAAAQIECBAgQIAAgaoCBs2qzchFgAABAgQIECBAgAABAgQIECBAgEASMGgmEgcCBAgQIECAAAECBAgQIECAAAECBKoKGDSrNiMXAQIECBAgQIAAAQIECBAgQIAAAQJJwKCZSBwIECBAgAABAgQIECBAgAABAgQIEKgqYNCs2oxcBAgQIECAAAECBAgQIECAAAECBAgkAYNmInEgQIAAAQIECBAgQIAAAQIECBAgQKCqgEGzajNyESBAgAABAgQIECBAgAABAgQIECCQBAyaicSBAAECBAgQIECAAAECBAgQIECAAIGqAgbNqs3IRYAAAQIECBAgQIAAAQIECBAgQIBAEjBoJhIHAgQIECBAgAABAgQIECBAgAABAgSqChg0qzYjFwECBAgQIECAAAECBAgQIECAAAECScCgmUgcCBAgQIAAAQIECBAgQIAAAQIECBCoKmDQrNqMXAQIECBAgAABAgQIECBAgAABAgQIJAGDZiJxIECAAAECBAgQIECAAAECBAgQIECgqoBBs2ozchEgQIAAAQIECBAgQIAAAQIECBAgkAQMmonEgQABAgQIECBAgAABAgQIECBAgACBqgIGzarNyEWAAAECBAgQIECAAAECBAgQIECAQBIwaCYSBwIECBAgQIAAAQIECBAgQIAAAQIEqgoYNKs2IxcBAgQIECBAgAABAgQIECBAgAABAknAoJlIHAgQIECAAAECBAgQIECAAAECBAgQqCpg0KzajFwECBAgQIAAAQIECBAgQIAAAQIECCQBg2YicSBAgAABAgQIECBAgAABAgQIECBAoKqAQbNqM3IRIECAAAECBAgQIECAAAECBAgQIJAEDJqJxIEAAQIECBAgQIAAAQIECBAgQIAAgaoCBs2qzchFgAABAgQIECBAgAABAgQIECBAgEASMGgmEgcCBAgQIECAAAECBAgQIECAAAECBKoKGDSrNiMXAQIECBAgQIAAAQIECBAgQIAAAQJJwKCZSBwIECBAgAABAgQIECBAgAABAgQIEKgqYNCs2oxcBAgQIECAAAECBAgQIECAAAECBAgkAYNmInEgQIAAAQIECBAgQIAAAQIECBAgQKCqgEGzajNyESBAgAABAgQIECBAgAABAgQIECCQBAyaicSBAAECBAgQIECAAAECBAgQIECAAIGqAgbNqs3IRYAAAQIECBAgQIAAAQIECBAgQIBAEjBoJhIHAgQIECBAgAABAgQIECBAgAABAgSqChg0qzYjFwECBAgQIECAAAECBAgQIECAAAECScCgmUgcCBAgQIAAAQIECBAgQIAAAQIECBCoKmDQrNqMXAQIECBAgAABAgQIECBAgAABAgQIJAGDZiJxIECAAAECBAgQIECAAAECBAgQIECgqoBBs2ozchEgQIAAAQIECBAgQIAAAQIECBAgkAQMmonEgQABAgQIECBAgAABAgQIECBAgACBqgIGzarNyEWAAAECBAgQIECAAAECBAgQIECAQBIwaCYSBwIECBAgQIAAAQIECBAgQIAAAQIEqgoYNKs2IxcBAgQIECBAgAABAgQIECBAgAABAknAoJlIHAgQIECAAAECBAgQIECAAAECBAgQqCpg0KzajFwECBAgQIAAAQIECBAgQIAAAQIECCQBg2YicSBAgAABAgQIECBAgAABAgQIECBAoKqAQbNqM3IRIECAAAECBAgQIECAAAECBAgQIJAEDJqJxIEAAQIECBAgQIAAAQIECBAgQIAAgaoCBs2qzchFgAABAgQIECBAgAABAgQIECBAgEASMGgmEgcCBAgQIECAAAECBAgQIECAAAECBKoKGDSrNiMXAQIECBAgQIAAAQIECBAgQIAAAQJJwKCZSBwIECBAgAABAgQIECBAgAABAgQIEKgqYNCs2oxcBAgQIECAAAECBAgQIECAAAECBAgkAYNmInEgQIAAAQIECBAgQIAAAQIECBAgQKCqgEGzajNyESBAgAABAgQIECBAgAABAgQIECCQBAyaicSBAAECBAgQIECAAAECBAgQIECAAIGqAgbNqs3IRYAAAQIECBAgQIAAAQIECBAgQIBAEvgDY7twUWExpg0AAAAASUVORK5CYII=", + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Image(filename =r'vis.png')" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#end" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "envdft", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/graph_visualization/requirement.txt b/examples/graph_visualization/requirement.txt new file mode 100644 index 00000000..85649ea0 --- /dev/null +++ b/examples/graph_visualization/requirement.txt @@ -0,0 +1,3 @@ +ipycytoscape +networkx +ipywidgets \ No newline at end of file diff --git a/examples/graph_visualization/test_data1.pfw b/examples/graph_visualization/test_data1.pfw new file mode 100644 index 00000000..155a5898 --- /dev/null +++ b/examples/graph_visualization/test_data1.pfw @@ -0,0 +1,13 @@ +[ +{"id":"0","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"10","dur":"60","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"1","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"40","dur":"10","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"2","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"120","dur":"60","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"3","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"210","dur":"40","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"4","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"230","dur":"10","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"5","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"10","dur":"50","ph":"X","args":{"hostname":"1d9bd41c01e6","mode":511,"fname":"/dlio/data1"}} +{"id":"6","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"40","dur":"50","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"7","name":"Fread","cat":"POSIX","pid":"0","tid":"19","ts":"110","dur":"80","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"8","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"140","dur":"45","ph":"X","args":{"hostname":"1d9bd41c01e6","mode":511,"fname":"/dlio/data1/train/"}} +{"id":"9","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"160","dur":"20","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"10","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"189","dur":"4","ph":"X","args":{"hostname":"1d9bd41c01e6"}} +{"id":"11","name":"read","cat":"POSIX","pid":"0","tid":"19","ts":"220","dur":"5","ph":"X","args":{"hostname":"1d9bd41c01e6","mode":511,"fname":"/dlio/data1/valid/"}} diff --git a/examples/graph_visualization/vis.png b/examples/graph_visualization/vis.png new file mode 100644 index 00000000..77fa36e7 Binary files /dev/null and b/examples/graph_visualization/vis.png differ diff --git a/script/dftracer_compact.sh b/script/dftracer_compact.sh new file mode 100755 index 00000000..085a479d --- /dev/null +++ b/script/dftracer_compact.sh @@ -0,0 +1,130 @@ +#!/bin/bash +#!/bin/bash + +# The script compacts all trace file and then divides the trace into equal file pieces. +# This has the following signature. +# +# usage: dftracer_compact [-fcv] [-d input_directory] [-o output_directory] [-l num_lines] [-p prefix] +# -f override output directory +# -c compress output file +# -v enable verbose mode +# -h display help +# -d input_directory specify input directories. should contain .pfw or .pfw.gz files. +# -o output_directory specify output directory. +# -l num_lines lines per trace. +# -p prefix prefix to be used for compact files. + + +LOG_DIR=$PWD +OUTPUT_DIR=$PWD/output +LINES=10000 +PREFIX=app +override=0 +compressed=0 + +PPWD=$PWD + + +function usage { + echo "usage: $(basename $0) [-fcv] [-d input_directory] [-o output_directory] [-l num_lines] [-p prefix]" + echo " -f override output directory" + echo " -c compress output file" + echo " -v enable verbose mode" + echo " -h display help" + echo " -d input_directory specify input directories. should contain .pfw or .pfw.gz files." + echo " -o output_directory specify output directory." + echo " -l num_lines lines per trace." + echo " -p prefix prefix to be used for compact files." + exit 1 +} +while getopts ':cvfd:o:l:p:h' opt; do + case "$opt" in + d) + LOG_DIR="${OPTARG}" + ;; + o) + OUTPUT_DIR="${OPTARG}" + ;; + l) + LINES=${OPTARG} + ;; + p) + PREFIX="${OPTARG}" + ;; + f) + override=1 + ;; + v) + set -x + ;; + c) + compressed=1 + ;; + h) + usage + exit 0 + ;; + + :) + echo -e "option requires an argument.\n" + usage + exit 1 + ;; + + ?) + echo -e "Invalid command option.\n" + usage + exit 1 + ;; + esac +done +shift "$(($OPTIND -1))" + +mkdir -p ${OUTPUT_DIR} + +if [ -z "$( ls -A '${OUTPUT_DIR}' )" ] && [ $override -eq 0 ]; then + echo "The directory is not empty. Please pass a clean directory or pass -f flag." + exit 0 +fi + +echo "Setting up output directory" +rm -rf ${OUTPUT_DIR} +mkdir -p ${OUTPUT_DIR} + +pfw_count=`ls -1 $LOG_DIR/*.pfw 2> /dev/null | wc -l` +gz_count=`ls -1 $LOG_DIR/*.gz 2> /dev/null | wc -l` +total=$((pfw_count + gz_count)) +if [ $total == 0 ]; then + echo "The folder does not contain any pfw or pfw.gz files." + exit 0 +fi +dest=${OUTPUT_DIR}/temp +d2=${dest}.bak +shopt -s dotglob +if [[ "$pfw_count" != "0" ]]; then +echo "Parsing pfw files from ${LOG_DIR} folder" +ls ${LOG_DIR}/*.pfw | xargs cat | grep -v "^\[" | jq -c '.' > $d2 +fi + +if [[ "$gz_count" != "0" ]]; then +echo "Parsing pfw.gz files from ${LOG_DIR} folder" +gzip -c -d `echo $folder/*.gz` | grep -v "^\[" | jq -c '.' >> $d2 +fi + +cd ${OUTPUT_DIR} + +echo "Compacting all trace files with ${LINES} per files into ${OUTPUT_DIR} folder." +split -l ${LINES} --numeric-suffixes --additional-suffix=.pfw $d2 ${PREFIX}- +for file in *.pfw; do + echo "[" > $file.$$ + cat $file >> $file.$$ + mv $file.$$ $file +done +rm $d2 +if [ $compressed == 1 ]; then +gzip ${PREFIX}-*.pfw +fi + + +cd $PPWD + diff --git a/script/merge_pfw.sh b/script/merge_pfw.sh old mode 100644 new mode 100755 index 05e07780..473ab10e --- a/script/merge_pfw.sh +++ b/script/merge_pfw.sh @@ -1,12 +1,112 @@ #!/bin/bash -folder=$1 -dest=$2 +# This script allows users to combine all pfw format into one. +# This has the following signature. +# +# usage: merge_pfw.sh [-fcv] [-d input_directory] [-o OUTPUT_FILE] +# -f override output file +# -c compress output file +# -v enable verbose mode +# -h display help +# -d input_directory specify input directories. should contain .pfw or .pfw.gz files. +# -o output_file specify output file. should have extension .pfw + + +override=0 +folder=$PWD +compressed=0 +dest="combined.pfw" + +function usage { + echo "usage: $(basename $0) [-fcv] [-d input_directory] [-o OUTPUT_FILE]" + echo " -f override output file" + echo " -c compress output file" + echo " -v enable verbose mode" + echo " -h display help" + echo " -d input_directory specify input directories. should contain .pfw or .pfw.gz files." + echo " -o output_file specify output file. should have extension .pfw" + exit 1 +} +while getopts ':cvfd:o:h' opt; do + case "$opt" in + d) + folder="${OPTARG}" + ;; + + o) + dest="${OPTARG}" + if [[ $dest != *.pfw ]]; then + echo "output_file should have .pfw extension". + fi + ;; + + f) + override=1 + ;; + v) + set -x + ;; + c) + compressed=1 + ;; + h) + usage + exit 0 + ;; + + :) + echo -e "option requires an argument.\n" + usage + exit 1 + ;; + + ?) + echo -e "Invalid command option.\n" + usage + exit 1 + ;; + esac +done +shift "$(($OPTIND -1))" + +if [[ "$override" == "1" ]]; then +rm -rf $dest ${dest}.gz +fi + +pfw_count=`ls -1 $folder/*.pfw 2> /dev/null | wc -l` +gz_count=`ls -1 $folder/*.gz 2> /dev/null | wc -l` +total=$((pfw_count + gz_count)) +if [ $total == 0 ]; then + echo "The folder does not contain any pfw or pfw.gz files." + exit 0 +fi + + +if [ -f $dest ] && [ -f "$dest.gz" ] && [ "$override" -eq "0" ]; then + echo "The destination file exists. Please delete the file." + exit 0 +fi + + + d2=${dest}.bak shopt -s dotglob +if [[ "$pfw_count" != "0" ]]; then +echo "Parsing pfw files from ${folder} folder" cat `echo $folder/*.pfw` >> $d2 -gzip -c -d `echo $folder/*gz` >> $d2 -grep -i "[^#[]" $d2 > $dest +fi + +if [[ "$gz_count" != "0" ]]; then +echo "Parsing pfw.gz files from ${folder} folder" +gzip -c -d `echo $folder/*.gz` >> $d2 +fi + +echo "Extracting events" +grep -i "[^#[]" $d2 | jq -c > $dest printf '%s\n%s\n' "[" "$(cat ${dest})" > $dest +if [ $compressed == 1 ]; then +echo "Compressing events" gzip $dest +fi +echo "Created output file ${dest}.gz" rm $d2 \ No newline at end of file diff --git a/setup.py b/setup.py index 59168a32..40eaa709 100644 --- a/setup.py +++ b/setup.py @@ -88,6 +88,9 @@ def build_extension(self, ext: CMakeExtension) -> None: enable_dlio_tests = os.environ.get("DFTRACER_ENABLE_PAPER_TESTS", "OFF") cmake_args += [f"-DDFTRACER_ENABLE_PAPER_TESTS={enable_dlio_tests}"] + test_ld_library_path = os.environ.get("DFTRACER_TEST_LD_LIBRARY_PATH", "") + cmake_args += [f"-DDFTRACER_TEST_LD_LIBRARY_PATH={test_ld_library_path}"] + # CMake lets you override the generator - we need to check this. # Can be set with Conda-Build, for example. cmake_generator = os.environ.get("CMAKE_GENERATOR", "") @@ -151,7 +154,7 @@ def build_extension(self, ext: CMakeExtension) -> None: # logic and declaration, and simpler if you include description/version in a file. setup( name="pydftracer", - version="1.0.2", + version="1.0.3", description="I/O profiler for deep learning python apps. Specifically for dlio_benchmark.", long_description=long_description, long_description_content_type="text/markdown", @@ -192,9 +195,10 @@ def build_extension(self, ext: CMakeExtension) -> None: zip_safe=False, extras_require={"test": ["pytest>=6.0"], "dfanalyzer": [ + "seaborn>=0.13.2", "bokeh>=2.4.2", "pybind11", - "zindex_py==0.0.1", + "zindex_py==0.0.2", "pandas>=2.0.3", "dask>=2023.5.0", "distributed", diff --git a/src/dftracer/brahma/posix.cpp b/src/dftracer/brahma/posix.cpp index 391fc29c..9088eec2 100644 --- a/src/dftracer/brahma/posix.cpp +++ b/src/dftracer/brahma/posix.cpp @@ -195,6 +195,7 @@ int brahma::POSIXDFTracer::openat(int dirfd, const char *pathname, int flags, DFT_LOGGER_START(dirfd); DFT_LOGGER_UPDATE(dirfd); DFT_LOGGER_UPDATE(flags); + DFT_LOGGER_UPDATE(pathname); int ret = -1; if (flags & O_CREAT) { va_list args; diff --git a/src/dftracer/brahma/posix.h b/src/dftracer/brahma/posix.h index 2ebd054d..b4c9a259 100644 --- a/src/dftracer/brahma/posix.h +++ b/src/dftracer/brahma/posix.h @@ -79,7 +79,7 @@ class POSIXDFTracer : public POSIX { DFTRACER_LOGDEBUG("Finalizing POSIXDFTracer", ""); stop_trace = true; } - ~POSIXDFTracer() { DFTRACER_LOGDEBUG("Destructing POSIXDFTracer", ""); } + ~POSIXDFTracer() {} static std::shared_ptr get_instance(bool trace_all = false) { DFTRACER_LOGDEBUG("POSIX class get_instance", ""); if (!stop_trace && instance == nullptr) { diff --git a/src/dftracer/brahma/stdio.cpp b/src/dftracer/brahma/stdio.cpp index 164d472c..75966645 100644 --- a/src/dftracer/brahma/stdio.cpp +++ b/src/dftracer/brahma/stdio.cpp @@ -47,6 +47,7 @@ size_t brahma::STDIODFTracer::fread(void *ptr, size_t size, size_t nmemb, DFT_LOGGER_UPDATE(size); DFT_LOGGER_UPDATE(nmemb); size_t ret = __real_fread(ptr, size, nmemb, fp); + DFT_LOGGER_UPDATE(ret); DFT_LOGGER_END(); return ret; } @@ -58,6 +59,7 @@ size_t brahma::STDIODFTracer::fwrite(const void *ptr, size_t size, size_t nmemb, DFT_LOGGER_UPDATE(size); DFT_LOGGER_UPDATE(nmemb); size_t ret = __real_fwrite(ptr, size, nmemb, fp); + DFT_LOGGER_UPDATE(ret); DFT_LOGGER_END(); return ret; } @@ -66,6 +68,7 @@ long brahma::STDIODFTracer::ftell(FILE *fp) { BRAHMA_MAP_OR_FAIL(ftell); DFT_LOGGER_START(fp); long ret = __real_ftell(fp); + DFT_LOGGER_UPDATE(ret); DFT_LOGGER_END(); return ret; } @@ -76,6 +79,7 @@ int brahma::STDIODFTracer::fseek(FILE *fp, long offset, int whence) { DFT_LOGGER_UPDATE(offset); DFT_LOGGER_UPDATE(whence); int ret = __real_fseek(fp, offset, whence); + DFT_LOGGER_UPDATE(ret); DFT_LOGGER_END(); return ret; } \ No newline at end of file diff --git a/src/dftracer/brahma/stdio.h b/src/dftracer/brahma/stdio.h index 63dcb24d..17135b5e 100644 --- a/src/dftracer/brahma/stdio.h +++ b/src/dftracer/brahma/stdio.h @@ -66,7 +66,7 @@ class STDIODFTracer : public STDIO { DFTRACER_LOGDEBUG("Finalizing STDIODFTracer", ""); stop_trace = true; } - ~STDIODFTracer() { DFTRACER_LOGDEBUG("Destructing STDIODFTracer", ""); }; + ~STDIODFTracer() {}; static std::shared_ptr get_instance(bool trace_all = false) { DFTRACER_LOGDEBUG("STDIO class get_instance", ""); diff --git a/src/dftracer/core/dftracer_main.cpp b/src/dftracer/core/dftracer_main.cpp index a85ac9a4..2b5cf20c 100644 --- a/src/dftracer/core/dftracer_main.cpp +++ b/src/dftracer/core/dftracer_main.cpp @@ -137,34 +137,43 @@ void dftracer::DFTracerCore::initialize(bool _bind, const char *_log_file, this->process_id = *_process_id; } DFTRACER_LOGDEBUG("Setting process_id to %d", this->process_id); - if (_log_file == nullptr) { - char cmd[128]; - sprintf(cmd, "/proc/%lu/cmdline", df_getpid()); - int fd = df_open(cmd, O_RDONLY); - std::string exec_name = "DEFAULT"; - - if (fd != -1) { - char exec_file_name[DFT_PATH_MAX]; - ssize_t read_bytes = df_read(fd, exec_file_name, DFT_PATH_MAX); - df_close(fd); - ssize_t index = 0; - while (index < read_bytes - 1) { - if (exec_file_name[index] == '\0') { - exec_file_name[index] = SEPARATOR; + char exec_name[DFT_PATH_MAX] = "DEFAULT"; + char exec_cmd[DFT_PATH_MAX] = "DEFAULT"; + char cmd[128]; + sprintf(cmd, "/proc/%lu/cmdline", df_getpid()); + int fd = df_open(cmd, O_RDONLY); + if (fd != -1) { + ssize_t read_bytes = df_read(fd, exec_cmd, DFT_PATH_MAX); + df_close(fd); + ssize_t index = 0; + size_t parts = 0; + size_t last_index = 0; + bool has_extracted = false; + while (index < read_bytes - 1 && index < DFT_PATH_MAX - 2) { + if (exec_cmd[index] == '\0') { + if (!has_extracted) { + strcpy(exec_name, basename(exec_cmd + last_index)); + if (strcmp(exec_name, "python") != 0) { + has_extracted = true; + } + DFTRACER_LOGINFO("Extracted process_name %s", exec_name); } - index++; + exec_cmd[index] = SEPARATOR; + last_index = index + 1; + parts++; } - DFTRACER_LOGDEBUG("Exec command line %s", exec_file_name); - auto items = split(exec_file_name, SEPARATOR); - for (const auto &item : items) { - if (strstr(item.c_str(), "python") == nullptr) { - exec_name = basename(item.c_str()); - break; - } + if (parts > 1) { + exec_cmd[index] = '\0'; } + index++; } - DFTRACER_LOGINFO("Extracted process_name %s", exec_name.c_str()); + exec_cmd[DFT_PATH_MAX - 1] = '\0'; + DFTRACER_LOGDEBUG("Exec command line %s", exec_cmd); + } + if (_log_file == nullptr) { + DFTRACER_LOGINFO("Extracted process_name %s", exec_name); if (!conf->log_file.empty()) { + DFTRACER_LOGDEBUG("Conf has log file %s", conf->log_file.c_str()); this->log_file = std::string(conf->log_file) + "-" + exec_name + "-" + std::to_string(this->process_id) + "-" + log_file_suffix + ".pfw"; @@ -176,11 +185,12 @@ void dftracer::DFTracerCore::initialize(bool _bind, const char *_log_file, this->log_file = _log_file; } DFTRACER_LOGDEBUG("Setting log file to %s", this->log_file.c_str()); - logger->update_log_file(this->log_file, this->process_id); + logger->update_log_file(this->log_file, exec_name, exec_cmd, + this->process_id); if (bind) { if (conf->io) { auto trie = dftracer::Singleton::get_instance(); - const char *ignore_extensions[3] = {".pfw", ".py",".pfw.gz"}; + const char *ignore_extensions[3] = {".pfw", ".py", ".pfw.gz"}; const char *ignore_prefix[8] = {"/pipe", "/socket", "/proc", "/sys", "/collab", "anon_inode", "socket", "/var/tmp"}; diff --git a/src/dftracer/df_logger.h b/src/dftracer/df_logger.h index 352ef3b8..86baed87 100644 --- a/src/dftracer/df_logger.h +++ b/src/dftracer/df_logger.h @@ -10,13 +10,16 @@ #include #include #include +#include #include +#include #include #include #include #include #include +#include #include typedef std::chrono::high_resolution_clock chrono; @@ -54,12 +57,26 @@ class DFTLogger { index_stack.clear(); DFTRACER_LOGDEBUG("Destructing DFTLogger", ""); } - inline void update_log_file(std::string log_file, ProcessID process_id = -1) { + inline void update_log_file(std::string log_file, std::string exec_name, + std::string cmd, ProcessID process_id = -1) { DFTRACER_LOGDEBUG("DFTLogger.update_log_file %s", log_file.c_str()); this->process_id = process_id; this->writer = dftracer::Singleton::get_instance(); if (this->writer != nullptr) { this->writer->initialize(log_file.data(), this->throw_error); + auto meta = std::unordered_map(); + meta.insert_or_assign("version", DFTRACER_VERSION); + meta.insert_or_assign("exec", exec_name); + meta.insert_or_assign("cmd", cmd); + time_t ltime; /* calendar time */ + ltime = time(NULL); /* get current cal time */ + char timestamp[1024]; + auto size = sprintf(timestamp, "%s", asctime(localtime(<ime))); + timestamp[size - 1] = '\0'; + meta.insert_or_assign("date", std::string(timestamp)); + this->enter_event(); + this->log("start", "dftracer", this->get_time(), 0, &meta); + this->exit_event(); } this->is_init = true; DFTRACER_LOGINFO("Writing trace to %s", log_file.c_str()); @@ -112,6 +129,11 @@ class DFTLogger { inline void finalize() { DFTRACER_LOGDEBUG("DFTLogger.finalize", ""); if (this->writer != nullptr) { + auto meta = std::unordered_map(); + meta.insert_or_assign("num_events", index.load()); + this->enter_event(); + this->log("end", "dftracer", this->get_time(), 0, &meta); + this->exit_event(); writer->finalize(has_entry); DFTRACER_LOGINFO("Released Logger", ""); } else { diff --git a/src/dftracer/utils/utils.h b/src/dftracer/utils/utils.h index 2945183d..6b721fab 100644 --- a/src/dftracer/utils/utils.h +++ b/src/dftracer/utils/utils.h @@ -40,7 +40,9 @@ inline void signal_handler(int sig) { // GCOVR_EXCL_START nptrs = backtrace(buffer, STACK_SIZE); strings = backtrace_symbols(buffer, nptrs); if (strings != NULL) { - for (j = 0; j < nptrs; j++) printf("%s\n", strings[j]); + for (j = 0; j < nptrs; j++) { + DFTRACER_LOGERROR("%s", strings[j]); + } free(strings); } exit(0); diff --git a/src/dftracer/writer/chrome_writer.cpp b/src/dftracer/writer/chrome_writer.cpp index c5a8f4d2..d381d865 100644 --- a/src/dftracer/writer/chrome_writer.cpp +++ b/src/dftracer/writer/chrome_writer.cpp @@ -8,8 +8,10 @@ #include #include +#include #include #include +#include #include #include @@ -41,6 +43,7 @@ void dftracer::ChromeWriter::log( std::unordered_map *metadata, ProcessID process_id, ThreadID thread_id) { DFTRACER_LOGDEBUG("ChromeWriter.log", ""); + if (fh != nullptr) { int size; char data[MAX_LINE_SIZE]; diff --git a/src/dftracer/writer/chrome_writer.h b/src/dftracer/writer/chrome_writer.h index 7bfeb6c0..208fb4cf 100644 --- a/src/dftracer/writer/chrome_writer.h +++ b/src/dftracer/writer/chrome_writer.h @@ -62,9 +62,10 @@ class ChromeWriter { auto written_elements = fwrite(write_buffer, sizeof(char), write_size, fh); funlockfile(fh); if (written_elements != write_size) { // GCOVR_EXCL_START - ERROR(written_elements != write_size, - "unable to log write %s for a+ written only %d of %d with error %s", - filename.c_str(), written_elements, write_size, strerror(errno)); + ERROR( + written_elements != write_size, + "unable to log write for a+ written only %d of %d with error code %d", + written_elements, write_size, errno); } // GCOVR_EXCL_STOP return written_elements; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c41d3a9c..5f4d0a61 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,7 +22,7 @@ add_dependencies(test_c ${PROJECT_NAME}_preload) function(set_common_properties test_name) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_LOG_LEVEL=DEBUG) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_TRACE_COMPRESSION=0) - set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/${DFTRACER_LIBDIR}) + set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/${DFTRACER_LIBDIR}:${DFTRACER_TEST_LD_LIBRARY_PATH}) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_DATA_DIR=${CMAKE_CURRENT_BINARY_DIR}/data) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_LOG_FILE=${CMAKE_CURRENT_BINARY_DIR}/${test_name}) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_ENABLE=1) @@ -125,7 +125,7 @@ set(test_name test_py_both) df_add_test(${test_name} ${DFTRACER_PYTHON_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/py/test.py --format=npz --data_dir=${CMAKE_CURRENT_BINARY_DIR}/data) set_common_properties(${test_name}) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT PYTHONPATH=$ENV{PYTHONPATH}:${CMAKE_SOURCE_DIR}/venv/${DFTRACER_LIBDIR}) -set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/${DFTRACER_LIBDIR}:${CMAKE_SOURCE_DIR}/dependency/.spack-env/view/lib64) +set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/${DFTRACER_LIBDIR}:${CMAKE_SOURCE_DIR}/dependency/.spack-env/view/lib64:${DFTRACER_TEST_LD_LIBRARY_PATH}) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_LOG_FILE=${CMAKE_CURRENT_BINARY_DIR}/${test_name}_app) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT LD_PRELOAD=${CMAKE_BINARY_DIR}/${DFTRACER_LIBDIR}/libdftracer_preload.so) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT DFTRACER_DATA_DIR=${CMAKE_BINARY_DIR}) diff --git a/test/paper/load_darshan.py b/test/paper/load_darshan.py index ac4e7da5..098b04c3 100644 --- a/test/paper/load_darshan.py +++ b/test/paper/load_darshan.py @@ -64,6 +64,13 @@ def get_dict(row): args = parser.parse_args() filename = args.trace_file +cluster = LocalCluster(n_workers=args.workers) # Launches a scheduler and workers locally +client = Client(cluster) # Connect to distributed cluster and override default + +args = parser.parse_args() +filename = args.trace_file + + file_pattern = glob(filename) all_records = [] diff --git a/test/py/test.py b/test/py/test.py index 4e237a31..3932b05c 100644 --- a/test/py/test.py +++ b/test/py/test.py @@ -141,6 +141,11 @@ def init(): """This function is called when new processes start.""" print(f"Initializing process {os.getpid()}") +@dft_fn.log +def with_default_args(step=2): + for i in dft_fn.iter(range(step)): + print(i) + def main(): posix_calls((20, False)) @@ -174,6 +179,8 @@ def main(): for n in range(args.niter): read_data(num_files=args.num_files, data_dir=args.data_dir, format=args.format) + with_default_args() + log_inst.finalize()