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
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 \
scripts/check $(TARGET) $^
clean:
- rm -rf ./build
+ rm -rf $(builddir)
rm -rf ./traces
dist:
--- /dev/null
+# 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`
+
+
lttng start
+# $1 = path to libextracer.so
+# $2 = program to execute
LD_PRELOAD=$1 $2
lttng destroy
#
# Author: Olivier Dion <odion@efficios.com>
#
-# Auto-generate lttng-ust tracepoints for HIP.
+# Auto-generate lttng-ust wrappers for HIP.
#
# Require: python-clang (libclang)
import clang.cindex
def list_function_declarations(root):
+ """Return all function declarations under ROOT."""
return [
child
for child in root.get_children()
]
def get_system_include_paths():
-
+ """Get default system include paths from Clang."""
clang_args = ["clang", "-v", "-c", "-xc", "-o", "/dev/null", "/dev/null"]
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:
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)
]
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()
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",
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():
}
""")
+ # Void function are special because they do not return anything ..
void_fn_tpl = Template("""
static void lttng_${fn_name}(${fn_arguments})
{
}
""")
+ # Because C++ does not support designated initializer.
epilogue_tpl = Template("""
static void lttng_hip_install_wrappers(void)
{
#
# 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)
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",
#
# 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)
# 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):]
for fn in function_declarations
])))
-
def generate_tracepoint_implementations(namespace, defs, impls):
tpl = Template("""/* Auto-generated !*/
#define LTTNG_UST_TRACEPOINT_CREATE_PROBES
if (num_tables < 1) {
return;
}
-
+
/*
* This could be done at compile time in some way if C++ could support
* designated initializers.
if (num_tables < 1) {
return;
}
-
+
/*
* This could be done at compile time in some way if C++ could support
* designated initializers.
* designated initializers.
*/
lttng_roctx_install_wrappers();
-
+
auto original_roctx_core_table = static_cast<roctxCoreApiTable_t*>(tables[0]);
/* Swap tables. */
(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:
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 {