From 64afa49193fafcd5c6c45e906b51846dd073bab6 Mon Sep 17 00:00:00 2001 From: "Jonathan R. Madsen" Date: Mon, 12 Sep 2022 17:44:27 -0500 Subject: [PATCH] GOTCHA wrappers for NUMA functions (#152) - GOTCHA wrappers for: - mbind - migrate_pages - move_pages - numa_migrate_pages - numa_move_pages - numa_alloc - numa_alloc_local - numa_alloc_interleaved - numa_alloc_onnode - numa_realloc - numa_free - bumped version to 1.6.0 - updated categories - hardware_counters -> kernel_hardware_counters and thread_hardware_counters - simplified mapping category structs to perfetto category names - updated timemory submodule --- .github/workflows/ubuntu-focal.yml | 2 +- VERSION | 2 +- docker/Dockerfile.ubuntu | 2 +- external/timemory | 2 +- source/bin/omnitrace/details.cpp | 5 +- source/lib/omnitrace/library/categories.hpp | 195 +++++++++-------- .../library/components/CMakeLists.txt | 2 + .../library/components/backtrace_metrics.cpp | 4 +- .../library/components/category_region.hpp | 4 - .../omnitrace/library/components/cpu_freq.hpp | 2 - .../library/components/numa_gotcha.cpp | 196 ++++++++++++++++++ .../library/components/numa_gotcha.hpp | 81 ++++++++ source/lib/omnitrace/library/cpu_freq.cpp | 62 +++--- source/lib/omnitrace/library/rocprofiler.cpp | 4 +- source/lib/omnitrace/library/runtime.hpp | 3 +- 15 files changed, 422 insertions(+), 144 deletions(-) create mode 100644 source/lib/omnitrace/library/components/numa_gotcha.cpp create mode 100644 source/lib/omnitrace/library/components/numa_gotcha.hpp diff --git a/.github/workflows/ubuntu-focal.yml b/.github/workflows/ubuntu-focal.yml index 438fee0944..73510327f8 100644 --- a/.github/workflows/ubuntu-focal.yml +++ b/.github/workflows/ubuntu-focal.yml @@ -214,7 +214,7 @@ jobs: wget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - && echo "deb [arch=amd64] https://repo.radeon.com/rocm/apt/${{ matrix.rocm_version }}/ ubuntu main" | tee /etc/apt/sources.list.d/rocm.list && apt-get update && - apt-get install -y build-essential m4 autoconf libtool python3-pip clang libomp-dev ${{ matrix.compiler }} libudev-dev libnuma-dev rocm-dev rocm-utils rocm-smi-lib roctracer-dev rocprofiler-dev hip-base hsa-amd-aqlprofile hsa-rocr-dev hsakmt-roct-dev libpapi-dev curl libopenmpi-dev openmpi-bin libfabric-dev && + apt-get install -y build-essential m4 autoconf libtool python3-pip clang libomp-dev ${{ matrix.compiler }} libudev-dev libnuma1 rocm-dev rocm-utils rocm-smi-lib roctracer-dev rocprofiler-dev hip-base hsa-amd-aqlprofile hsa-rocr-dev hsakmt-roct-dev libpapi-dev curl libopenmpi-dev openmpi-bin libfabric-dev && python3 -m pip install --upgrade pip && python3 -m pip install 'cmake==3.21.4' && for i in 6 7 8 9 10; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done diff --git a/VERSION b/VERSION index bc80560fad..dc1e644a10 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.0 +1.6.0 diff --git a/docker/Dockerfile.ubuntu b/docker/Dockerfile.ubuntu index 2fedac199f..e59197003c 100644 --- a/docker/Dockerfile.ubuntu +++ b/docker/Dockerfile.ubuntu @@ -22,7 +22,7 @@ ENV PATH ${HOME}/.local/bin:${PATH} RUN apt-get update && \ apt-get dist-upgrade -y && \ - apt-get install -y build-essential cmake libnuma-dev wget gnupg2 m4 bash-completion git-core autoconf libtool autotools-dev python3-pip lsb-release libpapi-dev libpfm4-dev libudev-dev libopenmpi-dev rpm librpm-dev curl && \ + apt-get install -y build-essential cmake libnuma1 wget gnupg2 m4 bash-completion git-core autoconf libtool autotools-dev python3-pip lsb-release libpapi-dev libpfm4-dev libudev-dev libopenmpi-dev rpm librpm-dev curl && \ python3 -m pip install 'cmake==3.21.4' && \ wget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - && \ echo "deb [arch=amd64] https://repo.radeon.com/rocm/apt/${ROCM_REPO_VERSION}/ ${ROCM_REPO_DIST} main" | tee /etc/apt/sources.list.d/rocm.list && \ diff --git a/external/timemory b/external/timemory index e3cc1e622a..69a6c7ad9d 160000 --- a/external/timemory +++ b/external/timemory @@ -1 +1 @@ -Subproject commit e3cc1e622a1c5699429d8167a37e55e9598918c3 +Subproject commit 69a6c7ad9df7c7fc6a1d275a506d6c0a71692c66 diff --git a/source/bin/omnitrace/details.cpp b/source/bin/omnitrace/details.cpp index 249a7819be..9596bd0c65 100644 --- a/source/bin/omnitrace/details.cpp +++ b/source/bin/omnitrace/details.cpp @@ -45,7 +45,10 @@ get_whole_function_names() "sigandset", "sigdelset", "sigemptyset", "sigfillset", "sighold", "sigisemptyset", "sigismember", "sigorset", "sigrelse", "sigvec", "strtok", "strstr", "sbrk", "strxfrm", "atexit", "ompt_start_tool", "nanosleep", "cfree", "tolower", - "toupper", "fileno", "fileno_unlocked", "exit", "quick_exit", "abort", + "toupper", "fileno", "fileno_unlocked", "exit", "quick_exit", "abort", "mbind", + "migrate_pages", "move_pages", "numa_migrate_pages", "numa_move_pages", + "numa_alloc", "numa_alloc_local", "numa_alloc_interleaved", "numa_alloc_onnode", + "numa_realloc", "numa_free", // below are functions which never terminate "rocr::core::Signal::WaitAny", "rocr::core::Runtime::AsyncEventsLoop", "rocr::core::BusyWaitSignal::WaitAcquire", diff --git a/source/lib/omnitrace/library/categories.hpp b/source/lib/omnitrace/library/categories.hpp index 2d43d11c52..cc590479fc 100644 --- a/source/lib/omnitrace/library/categories.hpp +++ b/source/lib/omnitrace/library/categories.hpp @@ -34,7 +34,7 @@ #include #include -#define OMNITRACE_DEFINE_NAME_TRAIT(NAME, ...) \ +#define OMNITRACE_DEFINE_NAME_TRAIT(NAME, DESC, ...) \ namespace tim \ { \ namespace trait \ @@ -42,49 +42,64 @@ template <> \ struct perfetto_category<__VA_ARGS__> \ { \ - static constexpr auto value = NAME; \ + static constexpr auto value = NAME; \ + static constexpr auto description = DESC; \ }; \ } \ } -#define OMNITRACE_DECLARE_CATEGORY(NS, VALUE, NAME) \ +#define OMNITRACE_DECLARE_CATEGORY(NS, VALUE, NAME, DESC) \ TIMEMORY_DECLARE_NS_API(NS, VALUE) \ - OMNITRACE_DEFINE_NAME_TRAIT(NAME, NS::VALUE) -#define OMNITRACE_DEFINE_CATEGORY(NS, VALUE, NAME) \ + OMNITRACE_DEFINE_NAME_TRAIT(NAME, DESC, NS::VALUE) +#define OMNITRACE_DEFINE_CATEGORY(NS, VALUE, NAME, DESC) \ TIMEMORY_DEFINE_NS_API(NS, VALUE) \ - OMNITRACE_DEFINE_NAME_TRAIT(NAME, NS::VALUE) + OMNITRACE_DEFINE_NAME_TRAIT(NAME, DESC, NS::VALUE) +// clang-format off // these are defined by omnitrace -OMNITRACE_DEFINE_CATEGORY(project, omnitrace, "omnitrace") -OMNITRACE_DEFINE_CATEGORY(category, host, "host") -OMNITRACE_DEFINE_CATEGORY(category, user, "user") -OMNITRACE_DEFINE_CATEGORY(category, device, "device") -OMNITRACE_DEFINE_CATEGORY(category, device_hip, "device_hip") -OMNITRACE_DEFINE_CATEGORY(category, device_hsa, "device_hsa") -OMNITRACE_DEFINE_CATEGORY(category, rocm_hip, "rocm_hip") -OMNITRACE_DEFINE_CATEGORY(category, rocm_hsa, "rocm_hsa") -OMNITRACE_DEFINE_CATEGORY(category, rocm_roctx, "rocm_roctx") -OMNITRACE_DEFINE_CATEGORY(category, rocm_smi, "rocm_smi") -OMNITRACE_DEFINE_CATEGORY(category, rocm_rccl, "rccl") -OMNITRACE_DEFINE_CATEGORY(category, roctracer, "roctracer") -OMNITRACE_DEFINE_CATEGORY(category, rocprofiler, "rocprofiler") -OMNITRACE_DEFINE_CATEGORY(category, pthread, "pthread") -OMNITRACE_DEFINE_CATEGORY(category, kokkos, "kokkos") -OMNITRACE_DEFINE_CATEGORY(category, mpi, "mpi") -OMNITRACE_DEFINE_CATEGORY(category, ompt, "ompt") -OMNITRACE_DEFINE_CATEGORY(category, process_sampling, "process_sampling") -OMNITRACE_DEFINE_CATEGORY(category, critical_trace, "critical-trace") -OMNITRACE_DEFINE_CATEGORY(category, host_critical_trace, "host-critical-trace") -OMNITRACE_DEFINE_CATEGORY(category, device_critical_trace, "device-critical-trace") -OMNITRACE_DEFINE_CATEGORY(cpu_freq, cpu_page, "process_page_fault") -OMNITRACE_DEFINE_CATEGORY(cpu_freq, cpu_virt, "process_virtual_memory") -OMNITRACE_DEFINE_CATEGORY(cpu_freq, cpu_peak, "process_memory_hwm") -OMNITRACE_DEFINE_CATEGORY(cpu_freq, cpu_context_switch, "process_context_switch") -OMNITRACE_DEFINE_CATEGORY(cpu_freq, cpu_page_fault, "process_page_fault") -OMNITRACE_DEFINE_CATEGORY(cpu_freq, cpu_user_mode_time, "process_user_cpu_time") -OMNITRACE_DEFINE_CATEGORY(cpu_freq, cpu_kernel_mode_time, "process_kernel_cpu_time") +OMNITRACE_DEFINE_CATEGORY(project, omnitrace, "omnitrace", "Omnitrace project") +OMNITRACE_DEFINE_CATEGORY(category, host, "host", "Host-side function tracing") +OMNITRACE_DEFINE_CATEGORY(category, user, "user", "User-defined regions") +OMNITRACE_DEFINE_CATEGORY(category, device_hip, "device_hip", "Device-side functions submitted via HIP API") +OMNITRACE_DEFINE_CATEGORY(category, device_hsa, "device_hsa", "Device-side functions submitted via HSA API") +OMNITRACE_DEFINE_CATEGORY(category, rocm_hip, "rocm_hip", "Host-side HIP functions") +OMNITRACE_DEFINE_CATEGORY(category, rocm_hsa, "rocm_hsa", "Host-side HSA functions") +OMNITRACE_DEFINE_CATEGORY(category, rocm_roctx, "rocm_roctx", "ROCTx labels") +OMNITRACE_DEFINE_CATEGORY(category, rocm_smi, "rocm_smi", "rocm-smi data") +OMNITRACE_DEFINE_CATEGORY(category, rocm_smi_busy, "device_busy", "Busy percentage of a GPU device") +OMNITRACE_DEFINE_CATEGORY(category, rocm_smi_temp, "device_temp", "Temperature of a GPU device") +OMNITRACE_DEFINE_CATEGORY(category, rocm_smi_power, "device_power", "Power consumption of a GPU device") +OMNITRACE_DEFINE_CATEGORY(category, rocm_smi_memory_usage, "device_memory_usage", "Memory usage of a GPU device") +OMNITRACE_DEFINE_CATEGORY(category, rocm_rccl, "rccl", "ROCm Communication Collectives Library (RCCL) regions") +OMNITRACE_DEFINE_CATEGORY(category, roctracer, "roctracer", "Kernel tracing provided by roctracer") +OMNITRACE_DEFINE_CATEGORY(category, rocprofiler, "rocprofiler", "HW counter data provided by rocprofiler") +OMNITRACE_DEFINE_CATEGORY(category, pthread, "pthread", "POSIX threading functions") +OMNITRACE_DEFINE_CATEGORY(category, kokkos, "kokkos", "KokkosTools regions") +OMNITRACE_DEFINE_CATEGORY(category, mpi, "mpi", "MPI regions") +OMNITRACE_DEFINE_CATEGORY(category, ompt, "ompt", "OpenMP tools regions") +OMNITRACE_DEFINE_CATEGORY(category, process_sampling, "process_sampling", "Process-level data") +OMNITRACE_DEFINE_CATEGORY(category, comm_data, "comm_data", "MPI/RCCL counters for tracking amount of data sent or received") +OMNITRACE_DEFINE_CATEGORY(category, critical_trace, "critical-trace", "Critical trace data") +OMNITRACE_DEFINE_CATEGORY(category, host_critical_trace, "host-critical-trace", "Host-side critical trace data") +OMNITRACE_DEFINE_CATEGORY(category, device_critical_trace, "device-critical-trace", "Device-side critical trace data") +OMNITRACE_DEFINE_CATEGORY(category, causal, "causal", "Causal profiling data") +OMNITRACE_DEFINE_CATEGORY(category, cpu_freq, "cpu_frequency", "CPU frequency (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, process_page, "process_page_fault", "Memory page faults in process (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, process_virt, "process_virtual_memory", "Virtual memory usage in process in MB (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, process_peak, "process_memory_hwm", "Memory High-Water Mark i.e. peak memory usage (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, process_context_switch, "process_context_switch", "Context switches in process (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, process_page_fault, "process_page_fault", "Memory page faults in process (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, process_user_mode_time, "process_user_cpu_time", "CPU time of functions executing in user-space in process in seconds (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, process_kernel_mode_time, "process_kernel_cpu_time", "CPU time of functions executing in kernel-space in process in seconds (collected in background thread)") +OMNITRACE_DEFINE_CATEGORY(category, thread_page_fault, "thread_page_fault", "Memory page faults on thread (derived from sampling)") +OMNITRACE_DEFINE_CATEGORY(category, thread_peak_memory, "thread_peak_memory", "Peak memory usage on thread in MB (derived from sampling)") +OMNITRACE_DEFINE_CATEGORY(category, thread_context_switch, "thread_context_switch", "Context switches on thread (derived from sampling)") +OMNITRACE_DEFINE_CATEGORY(category, thread_hardware_counter, "thread_hardware_counter", "Hardware counter value on thread (derived from sampling)") +OMNITRACE_DEFINE_CATEGORY(category, kernel_hardware_counter, "kernel_hardware_counter", "Hardware counter value for kernel (deterministic)") +OMNITRACE_DEFINE_CATEGORY(category, numa, "numa", "Non-unified memory architecture") -OMNITRACE_DECLARE_CATEGORY(category, sampling, "sampling") +OMNITRACE_DECLARE_CATEGORY(category, sampling, "sampling", "Host-side call-stack sampling") +// clang-format on namespace tim { @@ -95,72 +110,52 @@ using name = perfetto_category; } } // namespace tim +#define OMNITRACE_PERFETTO_CATEGORY(TYPE) \ + ::perfetto::Category(::tim::trait::perfetto_category<::tim::TYPE>::value) \ + .SetDescription(::tim::trait::perfetto_category<::tim::TYPE>::description) + #define OMNITRACE_PERFETTO_CATEGORIES \ - perfetto::Category(tim::trait::name::value) \ - .SetDescription("Host-side function tracing"), \ - perfetto::Category("user").SetDescription("User-defined regions"), \ - perfetto::Category("sampling").SetDescription("Host-side function sampling"), \ - perfetto::Category("device_hip") \ - .SetDescription("Device-side functions submitted via HSA API"), \ - perfetto::Category("device_hsa") \ - .SetDescription("Device-side functions submitted via HIP API"), \ - perfetto::Category("rocm_hip").SetDescription("Host-side HIP functions"), \ - perfetto::Category("rocm_hsa").SetDescription("Host-side HSA functions"), \ - perfetto::Category("rocm_roctx").SetDescription("Host-side ROCTX labels"), \ - perfetto::Category("device_busy") \ - .SetDescription("Busy percentage of a GPU device"), \ - perfetto::Category("device_temp") \ - .SetDescription("Temperature of GPU device in degC"), \ - perfetto::Category("device_power") \ - .SetDescription("Power consumption of GPU device in watts"), \ - perfetto::Category("device_memory_usage") \ - .SetDescription("Memory usage of GPU device in MB"), \ - perfetto::Category("thread_peak_memory") \ - .SetDescription( \ - "Peak memory usage on thread in MB (derived from sampling)"), \ - perfetto::Category("thread_context_switch") \ - .SetDescription("Context switches on thread (derived from sampling)"), \ - perfetto::Category("thread_page_fault") \ - .SetDescription("Memory page faults on thread (derived from sampling)"), \ - perfetto::Category("hardware_counter") \ - .SetDescription("Hardware counter value on thread (derived from sampling)"), \ - perfetto::Category("cpu_freq") \ - .SetDescription("CPU frequency in MHz (collected in background thread)"), \ - perfetto::Category("process_page_fault") \ - .SetDescription( \ - "Memory page faults in process (collected in background thread)"), \ - perfetto::Category("process_memory_hwm") \ - .SetDescription("Memory High-Water Mark i.e. peak memory usage (collected " \ - "in background thread)"), \ - perfetto::Category("process_virtual_memory") \ - .SetDescription("Virtual memory usage in process in MB (collected in " \ - "background thread)"), \ - perfetto::Category("process_context_switch") \ - .SetDescription( \ - "Context switches in process (collected in background thread)"), \ - perfetto::Category("process_page_fault") \ - .SetDescription( \ - "Memory page faults in process (collected in background thread)"), \ - perfetto::Category("process_user_cpu_time") \ - .SetDescription("CPU time of functions executing in user-space in process " \ - "in seconds (collected in background thread)"), \ - perfetto::Category("process_kernel_cpu_time") \ - .SetDescription("CPU time of functions executing in kernel-space in " \ - "process in seconds (collected in background thread)"), \ - perfetto::Category("pthread").SetDescription("Pthread functions"), \ - perfetto::Category("kokkos").SetDescription("Kokkos regions"), \ - perfetto::Category("mpi").SetDescription("MPI regions"), \ - perfetto::Category("ompt").SetDescription("OpenMP Tools regions"), \ - perfetto::Category("rccl").SetDescription( \ - "ROCm Communication Collectives Library (RCCL) regions"), \ - perfetto::Category("comm_data") \ - .SetDescription( \ - "MPI/RCCL counters for tracking amount of data sent or received"), \ - perfetto::Category("critical-trace").SetDescription("Combined critical traces"), \ - perfetto::Category("host-critical-trace") \ - .SetDescription("Host-side critical traces"), \ - perfetto::Category("device-critical-trace") \ - .SetDescription("Device-side critical traces"), \ + OMNITRACE_PERFETTO_CATEGORY(category::host), \ + OMNITRACE_PERFETTO_CATEGORY(category::user), \ + OMNITRACE_PERFETTO_CATEGORY(category::sampling), \ + OMNITRACE_PERFETTO_CATEGORY(category::device_hip), \ + OMNITRACE_PERFETTO_CATEGORY(category::device_hsa), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_hip), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_hsa), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_roctx), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_smi), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_smi_busy), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_smi_temp), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_smi_power), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_smi_memory_usage), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocm_rccl), \ + OMNITRACE_PERFETTO_CATEGORY(category::roctracer), \ + OMNITRACE_PERFETTO_CATEGORY(category::rocprofiler), \ + OMNITRACE_PERFETTO_CATEGORY(category::pthread), \ + OMNITRACE_PERFETTO_CATEGORY(category::kokkos), \ + OMNITRACE_PERFETTO_CATEGORY(category::mpi), \ + OMNITRACE_PERFETTO_CATEGORY(category::ompt), \ + OMNITRACE_PERFETTO_CATEGORY(category::sampling), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_sampling), \ + OMNITRACE_PERFETTO_CATEGORY(category::comm_data), \ + OMNITRACE_PERFETTO_CATEGORY(category::critical_trace), \ + OMNITRACE_PERFETTO_CATEGORY(category::host_critical_trace), \ + OMNITRACE_PERFETTO_CATEGORY(category::device_critical_trace), \ + OMNITRACE_PERFETTO_CATEGORY(category::causal), \ + OMNITRACE_PERFETTO_CATEGORY(category::cpu_freq), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_page), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_virt), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_peak), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_context_switch), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_page_fault), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_user_mode_time), \ + OMNITRACE_PERFETTO_CATEGORY(category::process_kernel_mode_time), \ + OMNITRACE_PERFETTO_CATEGORY(category::thread_page_fault), \ + OMNITRACE_PERFETTO_CATEGORY(category::thread_peak_memory), \ + OMNITRACE_PERFETTO_CATEGORY(category::thread_context_switch), \ + OMNITRACE_PERFETTO_CATEGORY(category::thread_hardware_counter), \ + OMNITRACE_PERFETTO_CATEGORY(category::kernel_hardware_counter), \ + OMNITRACE_PERFETTO_CATEGORY(category::numa), \ perfetto::Category("timemory").SetDescription("Events from the timemory API") #if defined(TIMEMORY_USE_PERFETTO) diff --git a/source/lib/omnitrace/library/components/CMakeLists.txt b/source/lib/omnitrace/library/components/CMakeLists.txt index 3f87c8ad3d..fdd5183adb 100644 --- a/source/lib/omnitrace/library/components/CMakeLists.txt +++ b/source/lib/omnitrace/library/components/CMakeLists.txt @@ -8,6 +8,7 @@ set(component_sources ${CMAKE_CURRENT_LIST_DIR}/exit_gotcha.cpp ${CMAKE_CURRENT_LIST_DIR}/fork_gotcha.cpp ${CMAKE_CURRENT_LIST_DIR}/mpi_gotcha.cpp + ${CMAKE_CURRENT_LIST_DIR}/numa_gotcha.cpp ${CMAKE_CURRENT_LIST_DIR}/pthread_gotcha.cpp ${CMAKE_CURRENT_LIST_DIR}/pthread_create_gotcha.cpp ${CMAKE_CURRENT_LIST_DIR}/pthread_mutex_gotcha.cpp) @@ -24,6 +25,7 @@ set(component_headers ${CMAKE_CURRENT_LIST_DIR}/exit_gotcha.hpp ${CMAKE_CURRENT_LIST_DIR}/fork_gotcha.hpp ${CMAKE_CURRENT_LIST_DIR}/mpi_gotcha.hpp + ${CMAKE_CURRENT_LIST_DIR}/numa_gotcha.hpp ${CMAKE_CURRENT_LIST_DIR}/rcclp.hpp ${CMAKE_CURRENT_LIST_DIR}/rocprofiler.hpp ${CMAKE_CURRENT_LIST_DIR}/roctracer.hpp diff --git a/source/lib/omnitrace/library/components/backtrace_metrics.cpp b/source/lib/omnitrace/library/components/backtrace_metrics.cpp index 192edaf75f..952ff8ad75 100644 --- a/source/lib/omnitrace/library/components/backtrace_metrics.cpp +++ b/source/lib/omnitrace/library/components/backtrace_metrics.cpp @@ -265,7 +265,7 @@ backtrace_metrics::fini_perfetto(int64_t _tid) { if(i < _hw_cnt_labels.size()) { - TRACE_COUNTER("hardware_counter", + TRACE_COUNTER("thread_hardware_counter", perfetto_counter_track::at(_tid, i), _ts, 0.0); } } @@ -291,7 +291,7 @@ backtrace_metrics::post_process_perfetto(int64_t _tid, uint64_t _ts) const { if(i < m_hw_counter.size()) { - TRACE_COUNTER("hardware_counter", + TRACE_COUNTER("thread_hardware_counter", perfetto_counter_track::at(_tid, i), _ts, m_hw_counter.at(i)); } diff --git a/source/lib/omnitrace/library/components/category_region.hpp b/source/lib/omnitrace/library/components/category_region.hpp index ad94af9e07..b7c6699c09 100644 --- a/source/lib/omnitrace/library/components/category_region.hpp +++ b/source/lib/omnitrace/library/components/category_region.hpp @@ -248,7 +248,6 @@ void category_region::audit(const gotcha_data_t& _data, audit::incoming, Args&&... _args) { - OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); start( _data.tool_id.c_str(), "args", JOIN(", ", @@ -261,7 +260,6 @@ void category_region::audit(const gotcha_data_t& _data, audit::outgoing, Args&&... _args) { - OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); stop(_data.tool_id.c_str(), "return", JOIN(", ", _args...)); } @@ -271,7 +269,6 @@ void category_region::audit(std::string_view _name, audit::incoming, Args&&... _args) { - OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); start( _name.data(), "args", JOIN(", ", @@ -284,7 +281,6 @@ void category_region::audit(std::string_view _name, audit::outgoing, Args&&... _args) { - OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); stop(_name.data(), "return", JOIN(", ", _args...)); } diff --git a/source/lib/omnitrace/library/components/cpu_freq.hpp b/source/lib/omnitrace/library/components/cpu_freq.hpp index 16c21d7a20..e128fca17b 100644 --- a/source/lib/omnitrace/library/components/cpu_freq.hpp +++ b/source/lib/omnitrace/library/components/cpu_freq.hpp @@ -109,5 +109,3 @@ private: }; } // namespace component } // namespace omnitrace - -OMNITRACE_DEFINE_NAME_TRAIT("cpu_freq", omnitrace::component::cpu_freq); diff --git a/source/lib/omnitrace/library/components/numa_gotcha.cpp b/source/lib/omnitrace/library/components/numa_gotcha.cpp new file mode 100644 index 0000000000..ff6ba680b3 --- /dev/null +++ b/source/lib/omnitrace/library/components/numa_gotcha.cpp @@ -0,0 +1,196 @@ +// MIT License +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "library/components/numa_gotcha.hpp" +#include "library/common.hpp" +#include "library/components/category_region.hpp" +#include "library/config.hpp" +#include "library/debug.hpp" +#include "library/runtime.hpp" +#include "library/state.hpp" +#include "library/timemory.hpp" + +#include +#include +#include + +#include +#include + +// int +// numa_migrate_pages(int pid, struct bitmask* from, struct bitmask* to); + +// int +// numa_move_pages(int pid, unsigned long count, void** pages, const int* nodes, int* +// status, +// int flags); + +namespace omnitrace +{ +namespace component +{ +namespace +{ +auto& +get_numa_gotcha() +{ + static auto _v = tim::lightweight_tuple{}; + return _v; +} +} // namespace + +void +numa_gotcha::configure() +{ + numa_gotcha_t::get_initializer() = []() { + numa_gotcha_t::configure<0, long, void*, unsigned long, int, const unsigned long*, + unsigned long, unsigned>("mbind"); + numa_gotcha_t::configure<1, long, int, unsigned long, const unsigned long*, + const unsigned long*>("migrate_pages"); + numa_gotcha_t::configure<2, long, int, unsigned long, void**, const int*, int*, + int>("move_pages"); + numa_gotcha_t::configure<3, int, int, struct bitmask*, struct bitmask*>( + "numa_migrate_pages"); + numa_gotcha_t::configure<4, int, int, unsigned long, void**, const int*, int*, + int>("numa_move_pages"); + numa_gotcha_t::configure<5, void*, size_t>("numa_alloc"); + numa_gotcha_t::configure<6, void*, size_t>("numa_alloc_local"); + numa_gotcha_t::configure<6, void*, size_t>("numa_alloc_interleaved"); + numa_gotcha_t::configure<7, void*, size_t, int>("numa_alloc_onnode"); + numa_gotcha_t::configure<8, void*, void*, size_t, size_t>("numa_realloc"); + numa_gotcha_t::configure<9, void, void*, size_t>("numa_free"); + }; +} + +void +numa_gotcha::shutdown() +{ + numa_gotcha_t::disable(); +} + +void +numa_gotcha::start() +{ + if(!get_numa_gotcha().get()->get_is_running()) + { + configure(); + get_numa_gotcha().start(); + } +} + +void +numa_gotcha::stop() +{ + // get_numa_gotcha().stop(); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, void* start, + unsigned long len, int mode, const unsigned long* nmask, + unsigned long maxnode, unsigned flags) +{ + category_region::start(std::string_view{ _data.tool_id }, "start", + start, "len", len, "mode", mode, "nmask", + nmask, "maxnode", maxnode, "flags", flags); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, int pid, + unsigned long maxnode, const unsigned long* frommask, + const unsigned long* tomask) +{ + category_region::start(std::string_view{ _data.tool_id }, "pid", pid, + "maxnode", maxnode, "frommask", frommask, + "tomask", tomask); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, int pid, + unsigned long count, void** pages, const int* nodes, int* status, + int flags) +{ + category_region::start(std::string_view{ _data.tool_id }, "pid", pid, + "count", count, "pages", pages, "nodes", nodes, + "status", status, "flags", flags); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, int pid, + struct bitmask* from, struct bitmask* to) +{ + category_region::start(std::string_view{ _data.tool_id }, "pid", pid, + "from", JOIN("", from).c_str(), "to", + JOIN("", to).c_str()); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, size_t _size) +{ + category_region::start(std::string_view{ _data.tool_id }, "size", + _size); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, size_t _size, int _node) +{ + category_region::start(std::string_view{ _data.tool_id }, "size", + _size, "node", _node); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, void* _addr, size_t _size) +{ + category_region::start(std::string_view{ _data.tool_id }, "address", + _addr, "size", _size); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::incoming, void* _old_addr, + size_t _old_size, size_t _new_size) +{ + category_region::start(std::string_view{ _data.tool_id }, + "old_address", _old_addr, "old_size", + _old_size, "new_size", _new_size); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::outgoing, int ret) +{ + category_region::stop(std::string_view{ _data.tool_id }, "return", + ret); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::outgoing, long ret) +{ + category_region::stop(std::string_view{ _data.tool_id }, "return", + ret); +} + +void +numa_gotcha::audit(const gotcha_data& _data, audit::outgoing, void* ret) +{ + category_region::stop(std::string_view{ _data.tool_id }, "return", + ret); +} +} // namespace component +} // namespace omnitrace diff --git a/source/lib/omnitrace/library/components/numa_gotcha.hpp b/source/lib/omnitrace/library/components/numa_gotcha.hpp new file mode 100644 index 0000000000..78af096f75 --- /dev/null +++ b/source/lib/omnitrace/library/components/numa_gotcha.hpp @@ -0,0 +1,81 @@ +// MIT License +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include "library/common.hpp" +#include "library/defines.hpp" +#include "library/timemory.hpp" + +#include +#include + +#include +#include + +namespace omnitrace +{ +namespace component +{ +struct numa_gotcha : tim::component::base +{ + static constexpr size_t gotcha_capacity = 10; + + using gotcha_data = tim::component::gotcha_data; + using exit_func_t = void (*)(int); + using abort_func_t = void (*)(); + + TIMEMORY_DEFAULT_OBJECT(numa_gotcha) + + // string id for component + static std::string label() { return "numa_gotcha"; } + + // generate the gotcha wrappers + static void configure(); + static void shutdown(); + + static void start(); + static void stop(); + + static void audit(const gotcha_data&, audit::incoming, void* start, unsigned long len, + int mode, const unsigned long* nmask, unsigned long maxnode, + unsigned flags); + static void audit(const gotcha_data&, audit::incoming, int pid, unsigned long maxnode, + const unsigned long* frommask, const unsigned long* tomask); + static void audit(const gotcha_data&, audit::incoming, int pid, unsigned long count, + void** pages, const int* nodes, int* status, int flags); + static void audit(const gotcha_data&, audit::incoming, int pid, struct bitmask* from, + struct bitmask* to); + static void audit(const gotcha_data&, audit::incoming, size_t); + static void audit(const gotcha_data&, audit::incoming, size_t, int); + static void audit(const gotcha_data&, audit::incoming, void*, size_t); + static void audit(const gotcha_data&, audit::incoming, void*, size_t, size_t); + static void audit(const gotcha_data&, audit::outgoing, int); + static void audit(const gotcha_data&, audit::outgoing, long); + static void audit(const gotcha_data&, audit::outgoing, void*); +}; +} // namespace component + +using numa_bundle_t = tim::component_bundle; +using numa_gotcha_t = tim::component::gotcha; +} // namespace omnitrace diff --git a/source/lib/omnitrace/library/cpu_freq.cpp b/source/lib/omnitrace/library/cpu_freq.cpp index 9171935158..00d741aa79 100644 --- a/source/lib/omnitrace/library/cpu_freq.cpp +++ b/source/lib/omnitrace/library/cpu_freq.cpp @@ -50,16 +50,13 @@ namespace omnitrace { namespace cpu_freq { -using namespace ::tim::cpu_freq; -using cpu_freq_component = component::cpu_freq; - template using type_list = tim::type_list; namespace { using cpu_data_tuple_t = std::tuple; + int64_t, int64_t, component::cpu_freq>; std::deque cpu_data = {}; template @@ -79,14 +76,16 @@ void setup() { init_perfetto_counter_tracks( - type_list{}); + type_list{}); } void config() { - cpu_freq_component::configure(); + component::cpu_freq::configure(); } void @@ -95,7 +94,7 @@ sample() auto _ts = tim::get_clock_real_now(); auto _rcache = tim::rusage_cache{ RUSAGE_SELF }; - auto _freqs = cpu_freq_component{}.sample(); + auto _freqs = component::cpu_freq{}.sample(); // user and kernel mode times are in microseconds cpu_data.emplace_back( @@ -164,7 +163,7 @@ post_process() "Post-processing %zu cpu frequency and memory usage entries...\n", cpu_data.size()); auto _process_frequencies = [](size_t _idx, size_t _offset) { - using freq_track = perfetto_counter_track; + using freq_track = perfetto_counter_track; const auto& _thread_info = thread_info::get(0, LookupTID); OMNITRACE_CI_THROW(!_thread_info, "Missing thread info for thread 0"); @@ -183,17 +182,19 @@ post_process() uint64_t _ts = std::get<0>(itr); double _freq = std::get<8>(itr).at(_offset); if(!_thread_info->is_valid_time(_ts)) continue; - write_perfetto_counter_track(index{ _idx }, _ts, _freq); + write_perfetto_counter_track(index{ _idx }, _ts, _freq); } auto _end_ts = _thread_info->get_stop(); - write_perfetto_counter_track(index{ _idx }, _end_ts, 0); + write_perfetto_counter_track(index{ _idx }, _end_ts, 0); }; auto _process_cpu_rusage = []() { config_perfetto_counter_tracks( - type_list{}, + type_list{}, { "Memory Usage", "Virtual Memory Usage", "Peak Memory", "Context Switches", "Page Faults", "User Time", "Kernel Time" }, { "MB", "MB", "MB", "", "", "sec", "sec" }); @@ -214,28 +215,33 @@ post_process() uint64_t _flts = std::get<5>(itr); double _user = std::get<6>(itr); double _kern = std::get<7>(itr); - write_perfetto_counter_track(_ts, _page / units::megabyte); - write_perfetto_counter_track(_ts, _virt / units::megabyte); - write_perfetto_counter_track(_ts, _peak / units::megabyte); - write_perfetto_counter_track(_ts, _cntx); - write_perfetto_counter_track(_ts, _flts); - write_perfetto_counter_track(_ts, _user / units::sec); - write_perfetto_counter_track(_ts, _kern / units::sec); + write_perfetto_counter_track(_ts, + _page / units::megabyte); + write_perfetto_counter_track(_ts, + _virt / units::megabyte); + write_perfetto_counter_track(_ts, + _peak / units::megabyte); + write_perfetto_counter_track(_ts, _cntx); + write_perfetto_counter_track(_ts, _flts); + write_perfetto_counter_track( + _ts, _user / units::sec); + write_perfetto_counter_track( + _ts, _kern / units::sec); } auto _end_ts = _thread_info->get_stop(); - write_perfetto_counter_track(_end_ts, 0.0); - write_perfetto_counter_track(_end_ts, 0.0); - write_perfetto_counter_track(_end_ts, 0.0); - write_perfetto_counter_track(_end_ts, 0); - write_perfetto_counter_track(_end_ts, 0); - write_perfetto_counter_track(_end_ts, 0.0); - write_perfetto_counter_track(_end_ts, 0.0); + write_perfetto_counter_track(_end_ts, 0.0); + write_perfetto_counter_track(_end_ts, 0.0); + write_perfetto_counter_track(_end_ts, 0.0); + write_perfetto_counter_track(_end_ts, 0); + write_perfetto_counter_track(_end_ts, 0); + write_perfetto_counter_track(_end_ts, 0.0); + write_perfetto_counter_track(_end_ts, 0.0); }; _process_cpu_rusage(); - auto& enabled_cpu_freqs = cpu_freq_component::get_enabled_cpus(); + auto& enabled_cpu_freqs = component::cpu_freq::get_enabled_cpus(); for(auto itr = enabled_cpu_freqs.begin(); itr != enabled_cpu_freqs.end(); ++itr) { auto _idx = *itr; diff --git a/source/lib/omnitrace/library/rocprofiler.cpp b/source/lib/omnitrace/library/rocprofiler.cpp index fbacd4c2c7..e4f99ed733 100644 --- a/source/lib/omnitrace/library/rocprofiler.cpp +++ b/source/lib/omnitrace/library/rocprofiler.cpp @@ -583,8 +583,8 @@ post_process_perfetto() for(size_t i = 0; i < _values.size(); ++i) { auto _trace_counter = [_dev_id, i, _ts](auto&& _v) { - TRACE_COUNTER("hardware_counter", counter_track::at(_dev_id, i), _ts, - _v); + TRACE_COUNTER("kernel_hardware_counter", + counter_track::at(_dev_id, i), _ts, _v); }; std::visit(_trace_counter, _values.at(i)); } diff --git a/source/lib/omnitrace/library/runtime.hpp b/source/lib/omnitrace/library/runtime.hpp index 1cfd7313b6..ca9c8a3cc9 100644 --- a/source/lib/omnitrace/library/runtime.hpp +++ b/source/lib/omnitrace/library/runtime.hpp @@ -27,6 +27,7 @@ #include "library/components/exit_gotcha.hpp" #include "library/components/fork_gotcha.hpp" #include "library/components/mpi_gotcha.hpp" +#include "library/components/numa_gotcha.hpp" #include "library/components/pthread_gotcha.hpp" #include "library/components/roctracer.hpp" #include "library/defines.hpp" @@ -50,7 +51,7 @@ using preinit_bundle_t = tim::lightweight_tuple; // started during init phase -using init_bundle_t = tim::lightweight_tuple; +using init_bundle_t = tim::lightweight_tuple; // bundle of components around omnitrace_init and omnitrace_finalize using main_bundle_t =