Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 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
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,6 @@ SYCL/BFloat16 @AlexeySotkin @MrSidims

# Deprecated features
SYCL/DeprecatedFeatures @intel/llvm-reviewers-runtime

# XPTI and XPTI Framework
SYCL/XPTI @tovinkere @andykaylor @alexbatashev
138 changes: 138 additions & 0 deletions SYCL/XPTI/Inputs/test_collector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "xpti/xpti_trace_framework.hpp"

#include <iostream>
#include <mutex>
#include <string_view>

std::mutex GMutex;

XPTI_CALLBACK_API void syclCallback(uint16_t, xpti::trace_event_data_t *,
xpti::trace_event_data_t *, uint64_t,
const void *);
XPTI_CALLBACK_API void syclPiCallback(uint16_t, xpti::trace_event_data_t *,
xpti::trace_event_data_t *, uint64_t,
const void *);

XPTI_CALLBACK_API void xptiTraceInit(unsigned int MajorVersion,
unsigned int MinorVersion,
const char *VersionStr,
const char *StreamName) {
std::cout << "xptiTraceInit: Stream Name = " << StreamName << "\n";
std::string_view NameView{StreamName};

if (NameView == "sycl.pi") {
uint8_t StreamID = xptiRegisterStream(StreamName);
xptiRegisterCallback(
StreamID,
static_cast<uint16_t>(xpti::trace_point_type_t::function_begin),
syclPiCallback);
xptiRegisterCallback(
StreamID,
static_cast<uint16_t>(xpti::trace_point_type_t::function_with_args_end),
syclPiCallback);
}
if (NameView == "sycl") {
uint8_t StreamID = xptiRegisterStream(StreamName);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::graph_create),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::node_create),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::edge_create),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::task_begin),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::task_end),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::signal),
syclCallback);
xptiRegisterCallback(
StreamID,
static_cast<uint16_t>(xpti::trace_point_type_t::barrier_begin),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::barrier_end),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::wait_begin),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::wait_end),
syclCallback);
xptiRegisterCallback(
StreamID, static_cast<uint16_t>(xpti::trace_point_type_t::signal),
syclCallback);
}
}

XPTI_CALLBACK_API void xptiTraceFinish(const char *streamName) {
std::cout << "xptiTraceFinish: Stream Name = " << streamName << "\n";
}

XPTI_CALLBACK_API void syclPiCallback(uint16_t TraceType,
xpti::trace_event_data_t *,
xpti::trace_event_data_t *, uint64_t,
const void *UserData) {
std::lock_guard Lock{GMutex};
auto Type = static_cast<xpti::trace_point_type_t>(TraceType);
const char *funcName = static_cast<const char *>(UserData);
if (Type == xpti::trace_point_type_t::function_begin) {
std::cout << "PI Call Begin : ";
} else if (Type == xpti::trace_point_type_t::function_end) {
std::cout << "PI Call End : ";
}
std::cout << funcName << "\n";
}

XPTI_CALLBACK_API void syclCallback(uint16_t TraceType,
xpti::trace_event_data_t *,
xpti::trace_event_data_t *Event, uint64_t,
const void *UserData) {
std::lock_guard Lock{GMutex};
auto Type = static_cast<xpti::trace_point_type_t>(TraceType);
switch (Type) {
case xpti::trace_point_type_t::graph_create:
std::cout << "Graph create\n";
break;
case xpti::trace_point_type_t::node_create:
std::cout << "Node create\n";
break;
case xpti::trace_point_type_t::edge_create:
std::cout << "Edge create\n";
break;
case xpti::trace_point_type_t::task_begin:
std::cout << "Task begin\n";
break;
case xpti::trace_point_type_t::task_end:
std::cout << "Task end\n";
break;
case xpti::trace_point_type_t::signal:
std::cout << "Signal\n";
break;
case xpti::trace_point_type_t::wait_begin:
std::cout << "Wait begin\n";
break;
case xpti::trace_point_type_t::wait_end:
std::cout << "Wait end\n";
break;
case xpti::trace_point_type_t::barrier_begin:
std::cout << "Barrier begin\n";
break;
case xpti::trace_point_type_t::barrier_end:
std::cout << "Barrier end\n";
break;
default:
std::cout << "Unknown tracepoint\n";
}

xpti::metadata_t *Metadata = xptiQueryMetadata(Event);
for (auto &Item : *Metadata) {
std::cout << " " << xptiLookupString(Item.first) << " : "
<< xptiLookupString(Item.second) << "\n";
}
}
125 changes: 125 additions & 0 deletions SYCL/XPTI/basic_event_collection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// REQUIRES: xptifw, opencl
// RUN: %clangxx %s -DXPTI_COLLECTOR -L%xptifw_lib -I%xptifw_includes -shared -fPIC -std=c++17 -o %t_collector.dll -lxptifw

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the command line will not work is clang-cl is used (-std=c++17 and -fPIC will not work).

There ar substitutions for such a case: https://github.com/intel/llvm-test-suite/blob/intel/SYCL/lit.cfg.py#L139

// RUN: %clangxx -fsycl -fsycl-unnamed-lambda -fsycl-targets=%sycl_triple %s -o %t.out
// RUN: env XPTI_TRACE_ENABLE=1 env XPTI_FRAMEWORK_DISPATCHER=%xptifw_dispatcher env XPTI_SUBSCRIBERS=%t_collector.dll env SYCL_DEVICE_FILTER=opencl %t.out | FileCheck %s 2>&1

#ifdef XPTI_COLLECTOR

#include "Inputs/test_collector.cpp"

#else

#include <sycl/sycl.hpp>

int main() {
sycl::queue Q{sycl::default_selector{}};

auto Ptr = sycl::malloc_device<int>(1, Q);

auto Evt1 = Q.single_task([=]() { Ptr[0] = 1; });

auto Evt2 = Q.submit([&](sycl::handler &CGH) {
CGH.depends_on(Evt1);
CGH.single_task([=]() { Ptr[0]++; });
});

Evt2.wait();

int Res = 0;
Q.memcpy(&Res, Ptr, 1);
Q.wait();

assert(Res == 2);

return 0;
}

#endif

// CHECK: xptiTraceInit: Stream Name = sycl
// CHECK-NEXT: Graph create
// CHECK-NEXT: xptiTraceInit: Stream Name = sycl.pi
// CHECK-NEXT: xptiTraceInit: Stream Name = sycl.pi.debug
// CHECK-NEXT: PI Call Begin : piPlatformsGet
// CHECK-NEXT: PI Call Begin : piPlatformsGet
// CHECK: PI Call Begin : piContextCreate
// CHECK-NEXT: PI Call Begin : piQueueCreate
// CHECK-NEXT: PI Call Begin : piextUSMDeviceAlloc
// CHECK-NEXT: PI Call Begin : piextDeviceSelectBinary
// CHECK-NEXT: Node create
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: Task begin
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: PI Call Begin : piextDeviceSelectBinary
// CHECK: PI Call Begin : piProgramCreate
// CHECK-NEXT: PI Call Begin : piProgramBuild
// CHECK: PI Call Begin : piKernelCreate
// CHECK-NEXT: PI Call Begin : piKernelSetExecInfo
// CHECK-NEXT: PI Call Begin : piextKernelSetArgPointer
// CHECK-NEXT: PI Call Begin : piKernelGetGroupInfo
// CHECK-NEXT: PI Call Begin : piEnqueueKernelLaunch
// CHECK-NEXT: Signal
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: Task end
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK: PI Call Begin : piextDeviceSelectBinary
// CHECK-NEXT: Node create
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: Node create
// CHECK-NEXT: kernel_name : virtual_node
// CHECK-NEXT: Edge create
// CHECK-NEXT: event : Event
// CHECK-NEXT: kernel_name : virtual_node
// CHECK-NEXT: Task begin
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: PI Call Begin : piKernelCreate
// CHECK-NEXT: PI Call Begin : piKernelSetExecInfo
// CHECK-NEXT: PI Call Begin : piextKernelSetArgPointer
// CHECK-NEXT: PI Call Begin : piKernelGetGroupInfo
// CHECK-NEXT: PI Call Begin : piEnqueueKernelLaunch
// CHECK-NEXT: Signal
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: Task end
// CHECK-NEXT: from_source : false
// CHECK-NEXT: kernel_name :
// CHECK-NEXT: sycl_device : CPU
// CHECK: Wait begin
// CHECK-NEXT: PI Call Begin : piEventsWait
// CHECK-NEXT: Wait end
// CHECK-NEXT: PI Call Begin : piextUSMEnqueueMemcpy
// CHECK-NEXT: PI Call Begin : piEventRelease
// CHECK-NEXT: Wait begin
// CHECK-NEXT: sym_line_no : 30
// CHECK-NEXT: sym_function_name : main
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: PI Call Begin : piQueueFinish
// CHECK-NEXT: Wait end
// CHECK-NEXT: sym_line_no : 30
// CHECK-NEXT: sym_function_name : main
// CHECK-NEXT: sycl_device : CPU
// CHECK-NEXT: PI Call Begin : piEventRelease
// CHECK-NEXT: PI Call Begin : piEventRelease
// CHECK-NEXT: PI Call Begin : piQueueRelease
// CHECK-NEXT: PI Call Begin : piContextRelease
// CHECK-NEXT: PI Call Begin : piKernelRelease
// CHECK-NEXT: PI Call Begin : piKernelRelease
// CHECK-NEXT: PI Call Begin : piProgramRelease
// CHECK-NEXT: PI Call Begin : piDeviceRelease
// CHECK-NEXT: PI Call Begin : piTearDown
// CHECK-NEXT: xptiTraceFinish: Stream Name = sycl.pi
// CHECK-NEXT: xptiTraceFinish: Stream Name = sycl.pi.debug
// CHECK-NEXT: xptiTraceFinish: Stream Name = sycl
14 changes: 14 additions & 0 deletions SYCL/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,20 @@
if find_executable('sycl-ls'):
config.available_features.add('sycl-ls')

# TODO properly set XPTIFW include and runtime dirs
xptifw_lib = os.path.join(config.dpcpp_root_dir, 'lib')
xptifw_dispatcher = ""
if platform.system() == "Linux":
xptifw_dispatcher = os.path.join(xptifw_lib, 'libxptifw.so')
elif platform.system() == "Windows":
xptifw_dispatcher = os.path.join(config.dpcpp_root_dir, 'bin', 'xptifw.dll')
xptifw_includes = os.path.join(config.dpcpp_root_dir, 'include')
if os.path.exists(xptifw_lib) and os.path.exists(os.path.join(xptifw_includes, 'xpti', 'xpti_trace_framework.h')):
config.available_features.add('xptifw')
config.substitutions.append(('%xptifw_lib', xptifw_lib))
config.substitutions.append(('%xptifw_dispatcher', xptifw_dispatcher))
config.substitutions.append(('%xptifw_includes', xptifw_includes))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need separate substitutions? Are they used separately?
if not we can merge them


llvm_tools = ["llvm-spirv", "llvm-link"]
for llvm_tool in llvm_tools:
llvm_tool_path = find_executable(llvm_tool)
Expand Down