Skip to content

Commit 479f764

Browse files
committed
Merge branch 'main' into cl_khr_unified_svm
2 parents b35286f + c9db413 commit 479f764

File tree

12 files changed

+626
-11
lines changed

12 files changed

+626
-11
lines changed

.github/workflows/codeql.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3333

3434
- name: Initialize CodeQL
35-
uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
35+
uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
3636
with:
3737
languages: cpp
3838

@@ -50,4 +50,4 @@ jobs:
5050
run: cmake --build . --parallel 4 --config $BUILD_TYPE
5151

5252
- name: Perform CodeQL Analysis
53-
uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
53+
uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
if: |
5454
startsWith(github.ref, 'refs/tags/') &&
5555
matrix.os == 'windows-latest'
56-
uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
56+
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
5757
with:
5858
draft: true
5959
files: |
@@ -63,7 +63,7 @@ jobs:
6363
if: |
6464
startsWith(github.ref, 'refs/tags/') &&
6565
matrix.os == 'ubuntu-latest'
66-
uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
66+
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
6767
with:
6868
draft: true
6969
files: |

docs/controls.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,16 @@ This is the list of options that is implicitly passed to CLANG to build a non-Op
525525

526526
This is the list of options that is implicitly passed to CLANG to build an OpenCL 2.0 SPIR-V module. Any application-provided build options will be appended to these build options.
527527

528+
### Controls for Dumping Command Buffers
529+
530+
##### `OmitCommandBufferNumber` (bool)
531+
532+
If set to a nonzero value, the Intercept Layer for OpenCL Applications will omit the command buffer number from dumped file names and hash tracking. This can produce deterministic results even if command buffers are creatd and finalized in a non-deterministic order (say, by multiple threads).
533+
534+
##### `DumpCommandBuffers` (bool)
535+
536+
If set to a nonzero value, the Intercept Layer for OpenCL Applications will dump the commands and dependencies in a command buffer to a file when the command buffer is successfully finalized. The file name will have the form "CLI\_\<Command BufferNumber\>\_\<Uniqueue Command BufferHash Code\>\_cmdbuf.dot". The command buffer is described using the DOT graph description language.
537+
528538
### Controls for Dumping and Injecting Buffers and Images
529539

530540
##### `DumpBufferHashes` (bool)

intercept/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ source_group(Resources FILES
6060
set(CLINTERCEPT_SOURCE_FILES
6161
src/chrometracer.h
6262
src/chrometracer.cpp
63+
src/cmdbufrecorder.h
6364
src/clIntercept.def
6465
src/clIntercept.map
6566
src/cli_ext.h

intercept/src/cli_ext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extern "C" {
1313
///////////////////////////////////////////////////////////////////////////////
1414
// cl_khr_command_buffer
1515

16-
// Note: This implements the provisional extension v0.9.5.
16+
// Note: This implements the provisional extension v0.9.6.
1717

1818
typedef cl_bitfield cl_device_command_buffer_capabilities_khr;
1919
typedef struct _cl_command_buffer_khr* cl_command_buffer_khr;
@@ -26,12 +26,12 @@ typedef cl_properties cl_command_properties_khr;
2626
typedef struct _cl_mutable_command_khr* cl_mutable_command_khr;
2727

2828
#define CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR 0x12A9
29+
#define CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR 0x129A
2930
#define CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR 0x12AA
3031

3132
#define CL_COMMAND_BUFFER_CAPABILITY_KERNEL_PRINTF_KHR (1 << 0)
3233
#define CL_COMMAND_BUFFER_CAPABILITY_DEVICE_SIDE_ENQUEUE_KHR (1 << 1)
3334
#define CL_COMMAND_BUFFER_CAPABILITY_SIMULTANEOUS_USE_KHR (1 << 2)
34-
#define CL_COMMAND_BUFFER_CAPABILITY_OUT_OF_ORDER_KHR (1 << 3)
3535

3636
#define CL_COMMAND_BUFFER_FLAGS_KHR 0x1293
3737
#define CL_COMMAND_BUFFER_SIMULTANEOUS_USE_KHR (1 << 0)

intercept/src/cmdbufrecorder.h

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
// Copyright (c) 2025 Intel Corporation
3+
//
4+
// SPDX-License-Identifier: MIT
5+
*/
6+
#pragma once
7+
8+
#include <atomic>
9+
#include <cinttypes>
10+
#include <map>
11+
#include <vector>
12+
#include <sstream>
13+
14+
#include <stdint.h>
15+
16+
#include "common.h"
17+
18+
struct SCommandBufferRecord
19+
{
20+
void recordCreate(
21+
cl_command_buffer_khr cmdbuf,
22+
bool isInOrder)
23+
{
24+
queueIsInOrder = isInOrder;
25+
dotstring << "digraph {\n";
26+
dotstring << " // " << (queueIsInOrder ? "in-order" : "out-of-order") << " command-buffer\n";
27+
}
28+
29+
void recordCommand(
30+
cl_command_queue queue,
31+
const char* cmd,
32+
const std::string& tag,
33+
cl_uint num_sync_points_in_wait_list,
34+
const cl_sync_point_khr* sync_point_wait_list,
35+
cl_sync_point_khr* sync_point)
36+
{
37+
SCommandBufferId id =
38+
sync_point == nullptr ?
39+
makeInternalId() :
40+
makeSyncPointId(*sync_point);
41+
42+
dotstring << " " << (id.isInternal ? "internal" : "syncpoint") << id.id
43+
<< " [shape=oval, label=\"" << cmd;
44+
if( !tag.empty() )
45+
{
46+
dotstring << "( " << tag << " )";
47+
}
48+
dotstring << "\"]\n";
49+
50+
for( cl_uint s = 0; s < num_sync_points_in_wait_list; s++ )
51+
{
52+
dotstring << " syncpoint" << sync_point_wait_list[s]
53+
<< " -> "
54+
<< (id.isInternal ? "internal" : "syncpoint") << id.id
55+
<< " // explicit dependency\n";
56+
}
57+
58+
for( const auto& dep : implicitDeps )
59+
{
60+
dotstring << " " << (dep.isInternal ? "internal" : "syncpoint") << dep.id
61+
<< " -> "
62+
<< (id.isInternal ? "internal" : "syncpoint") << id.id
63+
<< " [style=dashed] // implicit dependency\n";
64+
}
65+
66+
if( queueIsInOrder )
67+
{
68+
implicitDeps.clear();
69+
implicitDeps.push_back(id);
70+
}
71+
else
72+
{
73+
outstandingIds.push_back(id);
74+
}
75+
}
76+
77+
void recordBarrier(
78+
cl_command_queue queue,
79+
const char* cmd,
80+
cl_uint num_sync_points_in_wait_list,
81+
const cl_sync_point_khr* sync_point_wait_list,
82+
cl_sync_point_khr* sync_point)
83+
{
84+
SCommandBufferId id =
85+
sync_point == nullptr ?
86+
makeInternalId() :
87+
makeSyncPointId(*sync_point);
88+
89+
dotstring << " " << (id.isInternal ? "internal" : "syncpoint") << id.id
90+
<< " [shape=octagon, label=\"" << cmd << "\"]\n";
91+
92+
// If there is a sync point wait list, then the barrier depends on all
93+
// of the commands in the sync point wait list. Otherwise, the barrier
94+
// depends on all of the outstanding ids.
95+
if( num_sync_points_in_wait_list > 0 )
96+
{
97+
for( cl_uint s = 0; s < num_sync_points_in_wait_list; s++ )
98+
{
99+
dotstring << " syncpoint" << sync_point_wait_list[s]
100+
<< " -> "
101+
<< (id.isInternal ? "internal" : "syncpoint") << id.id
102+
<< " // explicit dependency\n";
103+
}
104+
}
105+
else
106+
{
107+
for( const auto& dep : outstandingIds )
108+
{
109+
dotstring << " " << (dep.isInternal ? "internal" : "syncpoint") << dep.id
110+
<< " -> "
111+
<< (id.isInternal ? "internal" : "syncpoint") << id.id
112+
<< " [style=dotted] // barrier dependency\n";
113+
}
114+
outstandingIds.clear();
115+
}
116+
117+
// Add the implicit dependencies.
118+
for( const auto& dep : implicitDeps )
119+
{
120+
dotstring << " " << (dep.isInternal ? "internal" : "syncpoint") << dep.id
121+
<< " -> "
122+
<< (id.isInternal ? "internal" : "syncpoint") << id.id
123+
<< " [style=dashed] // implicit dependency\n";
124+
}
125+
126+
// Now, the only implicit dependency that remains is this barrier.
127+
implicitDeps.clear();
128+
implicitDeps.push_back(id);
129+
}
130+
131+
void recordFinalize()
132+
{
133+
dotstring << "}\n";
134+
}
135+
136+
// Note: this cannot return a reference, because the underlying string is a
137+
// temporary object.
138+
const std::string getRecording() const
139+
{
140+
return dotstring.str();
141+
}
142+
143+
private:
144+
struct SCommandBufferId
145+
{
146+
bool isInternal = false;
147+
uint32_t id = 0;
148+
};
149+
150+
std::ostringstream dotstring;
151+
152+
std::atomic<uint32_t> nextInternalId;
153+
154+
bool queueIsInOrder;
155+
156+
std::vector<SCommandBufferId> implicitDeps;
157+
std::vector<SCommandBufferId> outstandingIds;
158+
159+
SCommandBufferId makeInternalId()
160+
{
161+
SCommandBufferId id;
162+
id.isInternal = true;
163+
id.id = nextInternalId.fetch_add(1, std::memory_order_relaxed);
164+
return id;
165+
}
166+
167+
SCommandBufferId makeSyncPointId(
168+
cl_sync_point_khr sync_point)
169+
{
170+
SCommandBufferId id;
171+
id.isInternal = false;
172+
id.id = sync_point;
173+
return id;
174+
}
175+
};

intercept/src/controls.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ CLI_CONTROL( std::string, SPIRVDis, "spirv-dis",
120120
CLI_CONTROL( std::string, DefaultOptions, "-cc1 -x cl -cl-std=CL1.2 -D__OPENCL_C_VERSION__=120 -D__OPENCL_VERSION__=120 -emit-spirv -triple=spir", "This is the list of options that is implicitly passed to CLANG to build a non-OpenCL 2.0 SPIR-V module. Any application-provided build options will be appended to these build options." )
121121
CLI_CONTROL( std::string, OpenCL2Options, "-cc1 -x cl -cl-std=CL2.0 -D__OPENCL_C_VERSION__=200 -D__OPENCL_VERSION__=200 -emit-spirv -triple=spir", "This is the list of options that is implicitly passed to CLANG to build an OpenCL 2.0 SPIR-V module. Any application-provided build options will be appended to these build options." )
122122

123+
CLI_CONTROL_SEPARATOR( Controls for Dumping Command Buffers: )
124+
CLI_CONTROL( bool, OmitCommandBufferNumber, false, "If set to a nonzero value, the Intercept Layer for OpenCL Applications will omit the command buffer number from dumped file names and hash tracking. This can produce deterministic results even if command buffers are creatd and finalized in a non-deterministic order (say, by multiple threads)." )
125+
CLI_CONTROL( bool, DumpCommandBuffers, false, "If set to a nonzero value, the Intercept Layer for OpenCL Applications will dump the commands and dependencies in a command buffer to a file when the command buffer is successfully finalized. The file name will have the form \"CLI_<Command BufferNumber>_<Uniqueue Command BufferHash Code>_cmdbuf.dot\". The command buffer is described using the DOT graph description language." )
126+
123127
CLI_CONTROL_SEPARATOR( Controls for Dumping and Injecting Buffers and Images: )
124128
CLI_CONTROL( bool, DumpBufferHashes, false, "If set to a nonzero value, the Intercept Layer for OpenCL Applications will dump hashes of a buffer, SVM, or USM allocation rather than the full contents of the buffer. This can be useful to identify which kernel enqueues generate different results without requiring a large amount of disk space." )
125129
CLI_CONTROL( bool, DumpImageHashes, false, "If set to a nonzero value, the Intercept Layer for OpenCL Applications will dump hashes of an image rather than the full contents of the image. This can be useful to identify which kernel enqueues generate different results without requiring a large amount of disk space." )

0 commit comments

Comments
 (0)