Skip to content
Draft
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,45 @@ jobs:
# doesn't work in case of CMake + VS (https://github.com/fortran-lang/setup-fortran/issues/45)
run: python buildall.py --force_bits 64 -ft ${{ matrix.optional_args }}

refcol_smoke:
name: Reference collector smoke test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
lib: build_linux/64/bin/libittnotify_refcol.so
exe: build_linux/64/bin/refcol_smoke_test
- os: windows-latest
lib: build_win/64/bin/libittnotify_refcol.dll
exe: build_win/64/bin/refcol_smoke_test.exe
defaults:
run:
shell: bash
steps:
- name: Checkout sources
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Build reference collector library and smoke test
run: python buildall.py --force_bits 64 --smoke ${{ runner.os == 'Windows' && '--cmake_gen ninja' || '' }}
- name: Run smoke test
run: |
mkdir -p "$RUNNER_TEMP/refcol_logs"
Comment thread
alexey-kireev marked this conversation as resolved.
Outdated
lib_path=$(cygpath -w "$(pwd)/${{ matrix.lib }}" 2>/dev/null || echo "$(pwd)/${{ matrix.lib }}")
log_dir=$(cygpath -w "$RUNNER_TEMP/refcol_logs" 2>/dev/null || echo "$RUNNER_TEMP/refcol_logs")
export INTEL_LIBITTNOTIFY64="$lib_path"
export INTEL_LIBITTNOTIFY_LOG_DIR="$log_dir"
./${{ matrix.exe }}
- name: Verify log output
run: |
log=$(ls "$RUNNER_TEMP/refcol_logs"/libittnotify_refcol_*.log 2>/dev/null | head -1)
if [ -z "$log" ]; then echo "ERROR: no log file found"; exit 1; fi
echo "Log file: $log"
grep -q "__itt_task_begin" "$log" || { echo "ERROR: __itt_task_begin not found"; exit 1; }
grep -q "__itt_task_end" "$log" || { echo "ERROR: __itt_task_end not found"; exit 1; }
grep -q "__itt_metadata_add" "$log" || { echo "ERROR: __itt_metadata_add not found"; exit 1; }
echo "Smoke test passed."

cpp_wrapper:
name: Check C++ wrapper
runs-on: ${{ matrix.os }}
Expand Down
37 changes: 37 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ option(FORCE_32 "Force a 32-bit compile on 64-bit" OFF)
option(ITT_API_IPT_SUPPORT "ptmarks support" OFF)
option(ITT_API_FORTRAN_SUPPORT "fortran support" OFF)
option(ITT_API_CPP_SUPPORT "C++ wrapper support" OFF)
option(ITT_API_REFERENCE_COLLECTOR "Build reference collector shared library" OFF)
option(ITT_API_INSTALL "Enable ITT API installation rules" ON)

if(FORCE_32 AND UNIX)
Expand Down Expand Up @@ -141,6 +142,42 @@ add_library(ittapi::ittnotify ALIAS ittnotify)
set(JITPROFILING_SRC "src/ittnotify/jitprofiling.c")
add_library(jitprofiling STATIC ${JITPROFILING_SRC})

if(ITT_API_REFERENCE_COLLECTOR)
Comment thread
alexey-kireev marked this conversation as resolved.
add_library(ittnotify_refcol SHARED src/ittnotify_refcol/itt_refcol_impl.c)

target_include_directories(ittnotify_refcol
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE src/ittnotify
)

target_link_libraries(ittnotify_refcol PRIVATE ${CMAKE_DL_LIBS})
set_target_properties(ittnotify_refcol PROPERTIES
LINKER_LANGUAGE C
RUNTIME_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH})

if(WIN32)
set_target_properties(ittnotify_refcol PROPERTIES
OUTPUT_NAME libittnotify_refcol
PREFIX ""
WINDOWS_EXPORT_ALL_SYMBOLS ON)
else()
set_target_properties(ittnotify_refcol PROPERTIES OUTPUT_NAME ittnotify_refcol)
endif()

option(ITT_API_REFCOL_SMOKE_TESTS "Build reference collector smoke tests" OFF)
if(ITT_API_REFCOL_SMOKE_TESTS)
add_executable(refcol_smoke_test src/ittnotify_refcol/tests/smoke_test.c)
target_include_directories(refcol_smoke_test
PRIVATE include
src/ittnotify
)
target_link_libraries(refcol_smoke_test PRIVATE ittnotify ${CMAKE_DL_LIBS})
set_target_properties(refcol_smoke_test PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH})
endif()
endif()

if(WIN32)
set_target_properties(ittnotify PROPERTIES OUTPUT_NAME libittnotify)
set_target_properties(jitprofiling PROPERTIES OUTPUT_NAME libjitprofiling)
Expand Down
8 changes: 7 additions & 1 deletion buildall.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ def main():
"-ft", "--fortran", help="enable fortran support", action="store_true")
parser.add_argument(
"-cpp", "--cpp", help="enable C++ wrapper support", action="store_true")
parser.add_argument(
"--refcol", help="enable reference collector build", action="store_true")
parser.add_argument(
"--smoke", help="enable reference collector smoke tests", action="store_true")
Comment thread
alexey-kireev marked this conversation as resolved.
Outdated
parser.add_argument(
"--force_bits", choices=["32", "64"], help="specify bit version for the target")
if sys.platform == 'win32' and vs_versions:
Expand Down Expand Up @@ -180,7 +184,9 @@ def main():
('-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON' if args.verbose else ''),
("-DITT_API_IPT_SUPPORT=1" if args.ptmark else ""),
("-DITT_API_FORTRAN_SUPPORT=1" if args.fortran else ""),
("-DITT_API_CPP_SUPPORT=ON" if args.cpp else "")
("-DITT_API_CPP_SUPPORT=ON" if args.cpp else ""),
("-DITT_API_REFERENCE_COLLECTOR=ON" if (args.refcol or args.smoke) else ""),
("-DITT_API_REFCOL_SMOKE_TESTS=ON" if args.smoke else "")
])))

if sys.platform == 'win32':
Expand Down
47 changes: 40 additions & 7 deletions src/ittnotify_refcol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,52 @@ performs tracing data from ITT API function calls to log files.

To use this solution, build the collector as a shared library and point the
full library path to the `INTEL_LIBITTNOTIFY64` or `INTEL_LIBITTNOTIFY32`
environment variable:
environment variable.

**On Linux**
## Building

### CMake (all platforms, recommended)

```
cmake <repo_root> -DITT_API_REFERENCE_COLLECTOR=ON
cmake --build .
```

The shared library is placed in the `bin/` subdirectory of the CMake build
directory. Alternatively, use the provided `buildall.py` script:

```
python buildall.py --refcol
```

### Make (Linux / FreeBSD)

```
make
export INTEL_LIBITTNOTIFY64=<build_dir>/libittnotify_refcol.so
```

## Usage

**On Linux**

```
export INTEL_LIBITTNOTIFY64=<build_dir>/bin/libittnotify_refcol.so
```

**On FreeBSD**

```
make
setenv INTEL_LIBITTNOTIFY64 <build_dir>/libittnotify_refcol.so
setenv INTEL_LIBITTNOTIFY64 <build_dir>/bin/libittnotify_refcol.so
```

**On Windows**

```
set INTEL_LIBITTNOTIFY64=<build_dir>\bin\libittnotify_refcol.dll
```

By default, log files save in the `tmp` directory. To change the location,
use the `INTEL_LIBITTNOTIFY_LOG_DIR` environment variable:
By default, log files are saved in the system temporary directory. To change
the location, use the `INTEL_LIBITTNOTIFY_LOG_DIR` environment variable:

**On Linux**

Expand All @@ -35,6 +63,11 @@ export INTEL_LIBITTNOTIFY_LOG_DIR=<log_dir>
setenv INTEL_LIBITTNOTIFY_LOG_DIR <log_dir>
```

**On Windows**
```
set INTEL_LIBITTNOTIFY_LOG_DIR=<log_dir>
```

This implementation adds logging of some of the ITT API function calls. Adding
logging of other ITT API function calls is welcome. The solution provides 4
functions with different log levels that take `printf` format for logging:
Expand Down
114 changes: 113 additions & 1 deletion src/ittnotify_refcol/itt_refcol_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
*/

#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
Expand Down Expand Up @@ -45,15 +47,37 @@ static struct ref_collector_global {
__itt_histogram* histogram_list;
} g_ref_collector_global = {MUTEX_INITIALIZER, 0, NULL, NULL, NULL, NULL};

#ifdef _WIN32
#define REFCOL_LOCALTIME(out_tm, in_time) (localtime_s((out_tm), (in_time)) == 0)
#else
#define REFCOL_LOCALTIME(out_tm, in_time) (localtime_r((in_time), (out_tm)) != NULL)
#endif

static char* log_file_name_generate()
{
time_t time_now = time(NULL);
struct tm* time_info = localtime(&time_now);
struct tm* time_info = malloc(sizeof(struct tm));
char* log_file_name = malloc(sizeof(char) * (LOG_BUFFER_MAX_SIZE/2));

if (log_file_name == NULL)
{
printf("ERROR: Failed to allocate memory for log file name\n");
free(time_info);
return NULL;
}

if (!REFCOL_LOCALTIME(time_info, &time_now))
{
printf("ERROR: Failed to get local time for log file name\n");
free(time_info);
free(log_file_name);
return NULL;
}

sprintf(log_file_name,"libittnotify_refcol_%d%d%d%d%d%d.log",
time_info->tm_year+1900, time_info->tm_mon+1, time_info->tm_mday,
time_info->tm_hour, time_info->tm_min, time_info->tm_sec);
free(time_info);
Comment thread
alexey-kireev marked this conversation as resolved.
Outdated
Comment thread
alexey-kireev marked this conversation as resolved.
Outdated

return log_file_name;
}
Expand Down Expand Up @@ -85,6 +109,10 @@ static void ref_collector_init()
{
sprintf(file_name_buffer,"%s\\%s", temp_dir, log_file);
}
else
{
sprintf(file_name_buffer,"%s", log_file);
}
#else
sprintf(file_name_buffer,"/tmp/%s", log_file);
Comment on lines +111 to 114
#endif
Expand Down Expand Up @@ -364,7 +392,45 @@ static char* get_context_metadata_element(__itt_context_type type, void* metadat
return metadata_str;
}

#ifdef _WIN32
static char* wchar2char(const wchar_t* wide_str)
{
if (wide_str == NULL)
{
return NULL;
}

int narrow_size = WideCharToMultiByte(CP_UTF8, 0, wide_str, -1, NULL, 0, NULL, NULL);
if (narrow_size <= 0)
{
return NULL;
}

char* narrow_str = (char*)malloc((size_t)narrow_size);
if (narrow_str == NULL)
{
return NULL;
}

if (!WideCharToMultiByte(CP_UTF8, 0, wide_str, -1, narrow_str, narrow_size, NULL, NULL))
{
free(narrow_str);
return NULL;
}

return narrow_str;
}
#endif

#ifdef _WIN32
ITT_EXTERN_C __itt_domain* ITTAPI __itt_domain_createW(const wchar_t *name)
{
return __itt_domain_createA(wchar2char(name));
Comment thread
alexey-kireev marked this conversation as resolved.
Outdated
}
ITT_EXTERN_C __itt_domain* ITTAPI __itt_domain_createA(const char *name)
#else
ITT_EXTERN_C __itt_domain* ITTAPI __itt_domain_create(const char *name)
#endif
{
if (!g_ref_collector_global.mutex_initialized || name == NULL)
{
Expand Down Expand Up @@ -396,7 +462,15 @@ ITT_EXTERN_C __itt_domain* ITTAPI __itt_domain_create(const char *name)
return h;
}

#ifdef _WIN32
ITT_EXTERN_C __itt_string_handle* ITTAPI __itt_string_handle_createW(const wchar_t* name)
{
return __itt_string_handle_createA(wchar2char(name));
}
Comment thread
alexey-kireev marked this conversation as resolved.
ITT_EXTERN_C __itt_string_handle* ITTAPI __itt_string_handle_createA(const char* name)
#else
ITT_EXTERN_C __itt_string_handle* ITTAPI __itt_string_handle_create(const char* name)
#endif
{
if (!g_ref_collector_global.mutex_initialized || name == NULL)
{
Expand Down Expand Up @@ -428,21 +502,49 @@ ITT_EXTERN_C __itt_string_handle* ITTAPI __itt_string_handle_create(const char*
return h;
}

#ifdef _WIN32
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_createW(const wchar_t *name, const wchar_t *domain)
{
return __itt_counter_createA(wchar2char(name), wchar2char(domain));
}
Comment thread
alexey-kireev marked this conversation as resolved.
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_createA(const char *name, const char *domain)
#else
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_create(const char *name, const char *domain)
#endif
{
LOG_FUNC_CALL_INFO("function call");
return __itt_counter_create_typed(name, domain, __itt_metadata_u64);
}

#ifdef _WIN32
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_createW_v3(
const __itt_domain* domain, const wchar_t* name, __itt_metadata_type type)
{
return __itt_counter_create_typed(wchar2char(name), domain->nameA, type);
}
Comment thread
alexey-kireev marked this conversation as resolved.
Comment on lines +528 to +535
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_createA_v3(
const __itt_domain* domain, const char* name, __itt_metadata_type type)
#else
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_create_v3(
const __itt_domain* domain, const char* name, __itt_metadata_type type)
#endif
{
LOG_FUNC_CALL_INFO("function call");
return __itt_counter_create_typed(name, domain->nameA, type);
}

#ifdef _WIN32
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_create_typedW(
const wchar_t *name, const wchar_t *domain, __itt_metadata_type type)
{
return __itt_counter_create_typedA(wchar2char(name), wchar2char(domain), type);
}
Comment thread
alexey-kireev marked this conversation as resolved.
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_create_typedA(
const char *name, const char *domain, __itt_metadata_type type)
#else
ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_create_typed(
const char *name, const char *domain, __itt_metadata_type type)
#endif
{
if (!g_ref_collector_global.mutex_initialized || name == NULL || domain == NULL)
{
Expand Down Expand Up @@ -478,8 +580,18 @@ ITT_EXTERN_C __itt_counter ITTAPI __itt_counter_create_typed(
return (__itt_counter)h;
}

#ifdef _WIN32
ITT_EXTERN_C __itt_histogram* ITTAPI __itt_histogram_createW(
const __itt_domain* domain, const wchar_t* name, __itt_metadata_type x_type, __itt_metadata_type y_type)
{
return __itt_histogram_createA(domain, wchar2char(name), x_type, y_type);
}
Comment thread
alexey-kireev marked this conversation as resolved.
ITT_EXTERN_C __itt_histogram* ITTAPI __itt_histogram_createA(
const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type)
#else
ITT_EXTERN_C __itt_histogram* ITTAPI __itt_histogram_create(
const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type)
#endif
{
if (!g_ref_collector_global.mutex_initialized || name == NULL || domain == NULL)
{
Expand Down
Loading
Loading