Add documentation
authorOlivier Dion <odion@efficios.com>
Fri, 15 Mar 2024 15:03:43 +0000 (11:03 -0400)
committerOlivier Dion <odion@efficios.com>
Fri, 15 Mar 2024 15:09:14 +0000 (11:09 -0400)
Signed-off-by: Olivier Dion <odion@efficios.com>
Makefile
README.md [new file with mode: 0644]
scripts/check
scripts/gen-hip-wrappers
scripts/gen-hsa-wrappers
scripts/lttng-ust-auto-api
src/lttng-ust-exatracer.cpp

index f7c1fb206a2d8fee86247457508ee25acf8b7980..0ee9d010afc961cfaa6f1b6755fa8e36d944235c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,14 +6,18 @@ CXX?=g++
 builddir?=$(CURDIR)/build
 
 # Do not touch below.
+
+# HIP C compiler.
 HIPCC=$(ROCM)/bin/hipcc
+
+# This is used in some of the HIP headers.
 PLATFORM=__HIP_PLATFORM_$(VENDOR)__
 
-# LTTng-UST
+# LTTng-UST flags.
 LTTNG_UST_CFLAGS=$(shell pkg-config --cflags lttng-ust)
 LTTNG_UST_LIBS=$(shell pkg-config --libs lttng-ust)
 
-# Rocprofiler-sdk
+# Rocprofiler-sdk flags.  There is not rocprofiler-sdk.pc for pkg-config.
 ROCPROFILER_SDK_CFLAGS=-I $(ROCM)/include -L $(ROCM)/lib -Wl,-rpath=$(ROCM)/lib
 ROCPROFILER_SDK_LIBS=-lrocprofiler-sdk
 
@@ -21,7 +25,6 @@ ROCPROFILER_SDK_LIBS=-lrocprofiler-sdk
 DEPS_CFLAGS=$(LTTNG_UST_CFLAGS) $(ROCPROFILER_SDK_CFLAGS)
 DEPS_LIBS=$(LTTNG_UST_LIBS) $(ROCPROFILER_SDK_LIBS)
 
-
 # HIP stuff.
 AUTOGEN_HIP_API=$(builddir)/lttng-ust-hip-defs.h    \
                 $(builddir)/lttng-ust-hip.h         \
@@ -84,7 +87,7 @@ check: $(builddir)/hello
        scripts/check $(TARGET) $^
 
 clean:
-       rm -rf ./build
+       rm -rf $(builddir)
        rm -rf ./traces
 
 dist:
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..987ce73
--- /dev/null
+++ b/README.md
@@ -0,0 +1,49 @@
+# Exatracer
+
+The Exatracer is powered by the LTTng ecosystem and can instrument the HIP and
+HSA runtimes and ROC-TX.
+
+## Usage
+
+Link program against `libexatracer.so` or `LD_PRELOAD` it.
+
+```sh
+TRACE_OUTPUT="$(pwd)/my-application-trace"
+lttng create --output $TRACE_OUTPUT
+lttng enable-event --userspace 'hip:*'
+lttng enable-event --userspace 'hsa:*'
+lttng enable-event --userspace 'roctx:*'
+lttng start
+LD_PRELOAD=libexatracer.so ./my-application
+lttng destroy
+babeltrace2 $TRACE_OUTPUT
+```
+
+## Dependencies
+
+### Runtime
+
+- lttng-ust
+- rocprofiler-sdk
+
+### Development
+
+- babeltrace2
+- coreutils
+- clang-toolchain
+- g++
+- lttng-tools
+- make
+- pkg-config
+- python3 >= 3.8
+- python3-clang
+- sed
+
+## Compilation
+
+See top of `Makefile` for configuration.
+
+- `make ROCM_VERSION=VERSION`
+- `make check`
+
+
index 20a42d89eab62e7ebb5c1b196f6d92986a313e13..b4795ba958f84d9f514de692a0fb539a25a99362 100755 (executable)
@@ -15,6 +15,8 @@ lttng enable-event --userspace 'roctx:*'
 
 lttng start
 
+# $1 = path to libextracer.so
+# $2 = program to execute
 LD_PRELOAD=$1 $2
 
 lttng destroy
index a43fd2951171f77a311528ebc42b16c4b3266df3..3a0d80b22f8e202075c484294076d0e890112e5d 100755 (executable)
@@ -4,7 +4,7 @@
 #
 # Author: Olivier Dion <odion@efficios.com>
 #
-# Auto-generate lttng-ust tracepoints for HIP.
+# Auto-generate lttng-ust wrappers for HIP.
 #
 # Require: python-clang (libclang)
 
@@ -17,6 +17,7 @@ from string import Template
 import clang.cindex
 
 def list_function_declarations(root):
+    """Return all function declarations under ROOT."""
     return [
         child
         for child in root.get_children()
@@ -24,7 +25,7 @@ def list_function_declarations(root):
     ]
 
 def get_system_include_paths():
-
+    """Get default system include paths from Clang."""
     clang_args = ["clang", "-v", "-c", "-xc", "-o", "/dev/null", "/dev/null"]
     paths = []
 
@@ -42,7 +43,14 @@ def get_system_include_paths():
     return paths
 
 def parse_header(header_file, includes, defines):
-
+    """
+    Parse HEADER_FILE with Clang with INCLUDES (-I) and DEFINES (-D).
+    Return a cursor to root.
+    """
+
+    # For some reason, python-clang does not use all system include paths.
+    # Thus, compiler dependant headers, like stddef.h can not be found without
+    # this.
     args = get_system_include_paths()
 
     if includes:
@@ -63,6 +71,7 @@ def parse_header(header_file, includes, defines):
     return tu.cursor
 
 def list_functions(root):
+    """Return the list of function declarations with `hip' prefix from ROOT."""
     return [
         fn
         for fn in list_function_declarations(root)
@@ -70,7 +79,7 @@ def list_functions(root):
     ]
 
 def exact_definition(arg):
-
+    """Given a cursor ARG that is a function argument, return its exact definition."""
     ct = arg.type.get_canonical()
     if ct.kind == clang.cindex.TypeKind.POINTER:
         pt = ct.get_pointee()
@@ -85,18 +94,26 @@ def exact_definition(arg):
         return f"{arg.type.spelling} {arg.spelling}"
 
 def cast(arg):
+    """
+    Cast argument ARG to something that LTTng-UST can consume.  Typically,
+    this is used to cast any pointer to void * because pointers are not
+    dereferenced anyway.  Furthermore, array are also cast void *.
+    """
     canon = arg.type.get_canonical()
     if canon.kind == clang.cindex.TypeKind.POINTER:
         return "void *"
     return re.sub(r'\[[0-9]*\]', '*', canon.spelling)
 
-forbiden_list = set()
-
-extra_works = {
-}
-
 def main():
 
+    # Extra works to do for functions.
+    #
+    # Format:
+    #   key = str: function name ; e.g. hipMalloc
+    #   value = str: C code ; e.g. printf("hello\n");
+    extra_works = {
+    }
+
     parser = argparse.ArgumentParser(prog="gen-hip-wrappers")
 
     parser.add_argument("api",
@@ -125,6 +142,9 @@ def main():
 
     args = parser.parse_args()
 
+    # The set of function to not instrument.
+    forbiden_list = set()
+
     if args.ignores:
         with open(args.ignores, "r") as f:
             for ignore in f.read().splitlines():
@@ -148,6 +168,7 @@ $extra_work
 }
 """)
 
+    # Void function are special because they do not return anything ..
     void_fn_tpl = Template("""
 static void lttng_${fn_name}(${fn_arguments})
 {
@@ -160,6 +181,7 @@ $extra_work
 }
 """)
 
+    # Because C++ does not support designated initializer.
     epilogue_tpl = Template("""
 static void lttng_hip_install_wrappers(void)
 {
index 5009cf06cb0ddd982aab1691d31348c18aee291f..49179dac579154222aedad6fa55507c4652fbdc2 100755 (executable)
@@ -4,7 +4,10 @@
 #
 # Author: Olivier Dion <odion@efficios.com>
 #
-# Auto-generate lttng-ust tracepoints for HSA.
+# Auto-generate lttng-ust wrappers for HSA.
+#
+# Please refer to gen-hip-wrappers.  This is basically the same thing but
+# adapted to HSA.
 #
 # Require: python-clang (libclang)
 
@@ -90,13 +93,15 @@ def cast(arg):
         return "void *"
     return re.sub(r'\[[0-9]*\]', '*', canon.spelling)
 
-forbiden_list = set()
 
-extra_works = {
-}
 
 def main():
 
+    extra_works = {
+    }
+
+    forbiden_list = set()
+
     parser = argparse.ArgumentParser(prog="gen-hsa-wrappers")
 
     parser.add_argument("api",
index ed40675a612ad0105f748b74eff6039dcef5e6da..d26162c064e27c7077a7265e984bbb029579a758 100755 (executable)
@@ -6,7 +6,7 @@
 #
 # Author: Olivier Dion <odion@efficios.com>
 #
-# Auto-generate lttng-ust tracepoints for OpenMPI.
+# Auto-generate lttng-ust tracepoints for a public API.
 #
 # Require: python-clang (libclang)
 
@@ -30,7 +30,7 @@ PROVIDER      = None
 # exception of the IDs -- will be passed through a data structure instead.
 MAX_TP_ARGS_COUNT = 8
 
-# Compatibility layer.
+# Compatibility layer for Python3 < 3.9
 def remove_prefix(string, prefix):
     if string.startswith(prefix):
         return string[len(prefix):]
@@ -686,7 +686,6 @@ static inline void ${fn_name}_exit(const struct ${namespace}_api_state_${fn_name
                                                for fn in function_declarations
                                            ])))
 
-
 def generate_tracepoint_implementations(namespace, defs, impls):
     tpl = Template("""/* Auto-generated !*/
 #define LTTNG_UST_TRACEPOINT_CREATE_PROBES
index 7eb759de046e17e17b863fcf62e50e6514ba2968..6fbaa6fe57100cc74ee8fe1faf838568d15ea248 100644 (file)
@@ -96,7 +96,7 @@ register_hip_table(uint64_t lib_instance, uint64_t num_tables, void **tables)
     if (num_tables < 1) {
         return;
     }
-  
+
     /*
      * This could be done at compile time in some way if C++ could support
      * designated initializers.
@@ -125,7 +125,7 @@ register_hsa_core_table(uint64_t lib_instance, uint64_t num_tables, void **table
     if (num_tables < 1) {
         return;
     }
-  
+
     /*
      * This could be done at compile time in some way if C++ could support
      * designated initializers.
@@ -161,7 +161,7 @@ register_roctx_core_table(uint64_t lib_instance, uint64_t num_tables, void **tab
      * designated initializers.
      */
     lttng_roctx_install_wrappers();
-  
+
     auto original_roctx_core_table = static_cast<roctxCoreApiTable_t*>(tables[0]);
 
     /* Swap tables. */
@@ -184,8 +184,8 @@ api_registration_callback(rocprofiler_intercept_table_t type,
     (void) lib_version;
 
     /*
-     * We only want HIP runtime and HSA tables.  If we get something
-     * else, there is a bug somewhere.
+     * We only want HIP, HSA or ROC-TX tables.  If we get something else, there
+     * is a bug somewhere.
      */
     switch (type) {
     case ROCPROFILER_HIP_RUNTIME_TABLE:
@@ -224,8 +224,7 @@ rocprofiler_tool_configure_result_t *rocprofiler_configure(uint32_t version,
                                                    ROCPROFILER_HSA_TABLE |
                                                    ROCPROFILER_MARKER_CORE_TABLE,
                                                     nullptr)) {
-        die("Trying to register API interception table for HIP runtime: "
-            "NOT IMPLEMENTED");
+        die("Trying to register API interception : " "NOT IMPLEMENTED");
     }
 
     static auto cfg = rocprofiler_tool_configure_result_t {
This page took 0.03332 seconds and 4 git commands to generate.