Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions devops/dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
"root": "{DEPS_ROOT}/opencl/runtime/linux/oclgpu"
},
"level_zero": {
"github_tag": "v1.24.3",
"version": "v1.24.3",
"url": "https://github.com/oneapi-src/level-zero/releases/tag/v1.24.3",
"github_tag": "5187acd1c0f34097658f6ed890f1e5a65bdc35b9",
"version": "v1.24.2",
"url": "https://github.com/oneapi-src/level-zero/commit/5187acd1c0f34097658f6ed890f1e5a65bdc35b9",
"root": "{DEPS_ROOT}/opencl/runtime/linux/oclgpu"
},
"tbb": {
Expand Down Expand Up @@ -56,4 +56,4 @@
"root": "{DEPS_ROOT}/opencl/runtime/linux/oclcpu"
}
}
}
}
149 changes: 132 additions & 17 deletions devops/scripts/install_drivers.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/bin/bash

set -e
set -x
set -o pipefail
Expand Down Expand Up @@ -52,8 +51,62 @@ function get_pre_release_igfx() {
if [ "$GITHUB_TOKEN" != "" ]; then
HEADER="Authorization: Bearer $GITHUB_TOKEN"
fi
curl -L -H "$HEADER" -H "Accept: application/vnd.github.v3+json" $URL -o $HASH.zip
unzip $HASH.zip && rm $HASH.zip

WORK_DIR="/tmp/igc-download"
mkdir -p "$WORK_DIR"
cd "$WORK_DIR"

curl -L -H "$HEADER" -H "Accept: application/vnd.github.v3+json" "$URL" -o "$HASH.zip"

unzip "$HASH.zip"
rm "$HASH.zip"

# Move deb files back to the calling directory if any exist
if ls *.deb 1> /dev/null 2>&1; then
mv *.deb /tmp/
cd /tmp/
fi

# Clean up work directory
rm -rf "$WORK_DIR"
}

function build_level_zero_from_source() {
COMMIT=$1

apt-get update -qq
apt-get install -y build-essential cmake git libc6-dev linux-libc-dev

BUILD_DIR="/tmp/level-zero-build"
INSTALL_DIR="/tmp/level-zero-install"
rm -rf $BUILD_DIR $INSTALL_DIR
mkdir -p $BUILD_DIR $INSTALL_DIR
cd $BUILD_DIR

git clone https://github.com/oneapi-src/level-zero.git

cd level-zero
git checkout $COMMIT

mkdir build
cd build

cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DLEVEL_ZERO_BUILD_TESTS=OFF \
-DLEVEL_ZERO_BUILD_SAMPLES=OFF

make -j$(nproc)
make install DESTDIR=$INSTALL_DIR

cp -r $INSTALL_DIR/usr/local/* /usr/local/

ldconfig

rm -rf $BUILD_DIR $INSTALL_DIR

echo "Level Zero built and installed successfully from commit $COMMIT"
}

TBB_INSTALLED=false
Expand Down Expand Up @@ -96,6 +149,15 @@ CheckIGCdevTag() {
fi
}

CheckIfCommitHash() {
local arg="$1"
if [[ $arg =~ ^[a-f0-9]{40}$ ]]; then
echo "Yes"
else
echo "No"
fi
}

InstallIGFX () {
echo "Installing Intel Graphics driver..."
echo "Compute Runtime version $CR_TAG"
Expand All @@ -122,10 +184,28 @@ InstallIGFX () {
| grep ".*deb" \
| grep -v "u18" \
| wget -qi -
get_release oneapi-src/level-zero $L0_TAG \
| grep ".*$UBUNTU_VER.*deb$" \
| wget -qi -
dpkg -i --force-all *.deb && rm *.deb *.sum

# Check if L0_TAG is a commit hash or a regular tag
IS_L0_COMMIT=$(CheckIfCommitHash $L0_TAG)
if [ "$IS_L0_COMMIT" == "Yes" ]; then
echo "Level Zero is using commit hash, building from source..."
if ! build_level_zero_from_source $L0_TAG; then
exit 1
fi
# Install other packages (Level Zero was already installed from source)
if ls *.deb 1> /dev/null 2>&1; then
dpkg -i --force-all *.deb && rm *.deb
fi
if ls *.sum 1> /dev/null 2>&1; then
rm *.sum
fi
else
get_release oneapi-src/level-zero $L0_TAG \
| grep ".*$UBUNTU_VER.*deb$" \
| wget -qi -
# Install all packages including Level Zero
dpkg -i --force-all *.deb && rm *.deb *.sum
fi
mkdir -p /usr/local/lib/igc/
echo "$IGC_TAG" > /usr/local/lib/igc/IGCTAG.txt
if [ "$IS_IGC_DEV" == "Yes" ]; then
Expand All @@ -134,22 +214,56 @@ InstallIGFX () {
# Backup and install it from release igc as a temporarily workaround
# while we working to resolve the issue.
echo "Backup libopencl-clang"
cp -d /usr/local/lib/libopencl-clang2.so.15* .

# Ensure we're in a writable directory for backup operations
BACKUP_DIR="/tmp/igc-backup"
mkdir -p "$BACKUP_DIR"
cd "$BACKUP_DIR"
echo "Working in backup directory: $BACKUP_DIR"

if ls /usr/local/lib/libopencl-clang2.so.15* 1> /dev/null 2>&1; then
cp -d /usr/local/lib/libopencl-clang2.so.15* .
LIBOPENCL_BACKED_UP=true
echo "Successfully backed up libopencl-clang files"
else
echo "Warning: libopencl-clang2.so.15* not found, skipping backup"
LIBOPENCL_BACKED_UP=false
fi
echo "Download IGC dev git hash $IGC_DEV_VER"
get_pre_release_igfx $IGC_DEV_URL $IGC_DEV_VER
if ! get_pre_release_igfx $IGC_DEV_URL $IGC_DEV_VER; then
echo "ERROR: Failed to download IGC dev package"
exit 1
fi
echo "Install IGC dev git hash $IGC_DEV_VER"
# New dev IGC packaged iga64 conflicting with iga64 from intel-igc-media
# force overwrite to workaround it first.
dpkg -i --force-all *.deb
echo "Install libopencl-clang"
# Workaround only, will download deb and install with dpkg once fixed.
cp -d libopencl-clang2.so.15* /usr/local/lib/
rm /usr/local/lib/libigc.so /usr/local/lib/libigc.so.1* && \
ln -s /usr/local/lib/libigc.so.2 /usr/local/lib/libigc.so && \
ln -s /usr/local/lib/libigc.so.2 /usr/local/lib/libigc.so.1
if ls *.deb 1> /dev/null 2>&1; then
dpkg -i --force-all *.deb
else
echo "Warning: No IGC dev deb files found after download"
fi
if [ "$LIBOPENCL_BACKED_UP" == "true" ]; then
echo "Install libopencl-clang"
# Workaround only, will download deb and install with dpkg once fixed.
echo "Copying backed up libopencl-clang files from $BACKUP_DIR"
cp -d "$BACKUP_DIR"/libopencl-clang2.so.15* /usr/local/lib/
fi
if [ -f /usr/local/lib/libigc.so.2 ]; then
rm -f /usr/local/lib/libigc.so /usr/local/lib/libigc.so.1* && \
ln -s /usr/local/lib/libigc.so.2 /usr/local/lib/libigc.so && \
ln -s /usr/local/lib/libigc.so.2 /usr/local/lib/libigc.so.1
fi
echo "Clean up"
rm *.deb libopencl-clang2.so.15*
if ls *.deb 1> /dev/null 2>&1; then
rm *.deb
fi
echo "$IGC_DEV_TAG" > /usr/local/lib/igc/IGCTAG.txt

# Clean up backup directory (this also removes the backed up libopencl-clang files)
if [ -d "$BACKUP_DIR" ]; then
echo "Cleaning up backup directory: $BACKUP_DIR"
rm -rf "$BACKUP_DIR"
fi
fi
}

Expand All @@ -169,6 +283,7 @@ InstallCPURT () {
if [ -e $INSTALL_LOCATION/oclcpu/install.sh ]; then \
bash -x $INSTALL_LOCATION/oclcpu/install.sh
else
mkdir -p /etc/OpenCL/vendors
echo $INSTALL_LOCATION/oclcpu/x64/libintelocl.so > /etc/OpenCL/vendors/intel_oclcpu.icd
fi
}
Expand Down
4 changes: 2 additions & 2 deletions sycl/test-e2e/Adapters/level_zero/queue_profiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
// clang-format off
// Check the expected output when queue::enable_profiling is not specified
//
// WITHOUT: ze_event_pool_desc_t flags set to: 1
// WITHOUT: {{ze_event_pool_desc_t flags set to: 1|zex_counter_based_event_desc_t flags set to: 5}}
// WITHOUT: SYCL exception caught: Profiling information is unavailable as the queue associated with the event does not have the 'enable_profiling' property.

// Check the expected output when queue::enable_profiling is specified
//
// WITH: ze_event_pool_desc_t flags set to: 5
// WITH: {{ze_event_pool_desc_t flags set to: 5|zex_counter_based_event_desc_t flags set to: 21}}
// WITH: Device kernel time:
// clang-format on
//
Expand Down
11 changes: 8 additions & 3 deletions unified-runtime/cmake/FetchLevelZero.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ find_package(PkgConfig QUIET)
# LevelZero doesn't install a CMake config target, just PkgConfig,
# so try using that to find the install and if it's not available
# just try to search for the path.
if(PkgConfig_FOUND)
pkg_check_modules(level-zero level-zero>=1.24.3)
string(LENGTH "${UR_LEVEL_ZERO_LOADER_TAG}" TAG_LENGTH)
string(REGEX MATCH "^[0-9a-fA-F]+$" IS_HEX "${UR_LEVEL_ZERO_LOADER_TAG}")

if(PkgConfig_FOUND AND NOT (TAG_LENGTH EQUAL 40 AND IS_HEX))
pkg_check_modules(level-zero level-zero>1.24.3)
if(level-zero_FOUND)
set(LEVEL_ZERO_INCLUDE_DIR "${level-zero_INCLUDEDIR}/level_zero")
set(LEVEL_ZERO_LIBRARY_SRC "${level-zero_LIBDIR}")
Expand Down Expand Up @@ -50,7 +53,9 @@ if(NOT LEVEL_ZERO_LIB_NAME AND NOT LEVEL_ZERO_LIBRARY)
set(UR_LEVEL_ZERO_LOADER_REPO "https://github.com/oneapi-src/level-zero.git")
# Remember to update the pkg_check_modules minimum version above when updating the
# clone tag
set(UR_LEVEL_ZERO_LOADER_TAG v1.24.3)
# set(UR_LEVEL_ZERO_LOADER_TAG v1.24.3)
# commit of updated leak checker (PR#376)
set(UR_LEVEL_ZERO_LOADER_TAG 5187acd1c0f34097658f6ed890f1e5a65bdc35b9)

# Disable due to a bug https://github.com/oneapi-src/level-zero/issues/104
set(CMAKE_INCLUDE_CURRENT_DIR OFF)
Expand Down
2 changes: 2 additions & 0 deletions unified-runtime/source/adapters/level_zero/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,8 @@ ur_result_t urDeviceCreateWithNativeHandle(
ur_device_handle_t Dev = nullptr;
for (const auto &p : GlobalAdapter->Platforms) {
Dev = p->getDeviceFromNativeHandle(ZeDevice);
if (Dev)
break;
}

if (Dev == nullptr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,26 @@ ur_result_t ur_command_list_manager::appendGenericFillUnlocked(
hDevice.get(), ur_mem_buffer_t::device_access_mode_t::read_only, offset,
size, zeCommandList.get(), waitListView));

// Store pattern in event if this is an async operation
// This prevents use-after-return bug when pPattern points to stack memory
const void *patternPtr = pPattern;
if (phEvent && zeSignalEvent) {
phEvent->retainFillPattern(pPattern, patternSize);
patternPtr = phEvent->getFillPattern();
}

// PatternSize must be a power of two for zeCommandListAppendMemoryFill.
// When it's not, the fill is emulated with zeCommandListAppendMemoryCopy.
if (isPowerOf2(patternSize)) {
// WORKAROUND: Level Zero driver rejects zeCommandListAppendMemoryFill when
// patternSize == size, returning ZE_RESULT_ERROR_INVALID_SIZE (0x78000008).
if (isPowerOf2(patternSize) && patternSize != size) {
ZE2UR_CALL(zeCommandListAppendMemoryFill,
(zeCommandList.get(), pDst, pPattern, patternSize, size,
(zeCommandList.get(), pDst, patternPtr, patternSize, size,
zeSignalEvent, waitListView.num, waitListView.handles));
} else {
// Copy pattern into every entry in memory array pointed by Ptr.
uint32_t numOfCopySteps = size / patternSize;
const void *src = pPattern;
const void *src = patternPtr;

for (uint32_t step = 0; step < numOfCopySteps; ++step) {
void *dst = reinterpret_cast<void *>(reinterpret_cast<uint8_t *>(pDst) +
Expand Down
17 changes: 13 additions & 4 deletions unified-runtime/source/adapters/level_zero/v2/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,20 @@ ur_context_handle_t_::ur_context_handle_t_(ze_context_handle_t hContext,
phDevices[0]->Platform->ZeMutableCmdListExt.Supported}),
eventPoolCacheImmediate(
this, phDevices[0]->Platform->getNumDevices(),
[context = this](DeviceId /* deviceId*/, v2::event_flags_t flags)
-> std::unique_ptr<v2::event_provider> {
[context = this, platform = phDevices[0]->Platform](
DeviceId deviceId,
v2::event_flags_t flags) -> std::unique_ptr<v2::event_provider> {
auto device = platform->getDeviceById(deviceId);

// TODO: just use per-context id?
return std::make_unique<v2::provider_normal>(
context, v2::QUEUE_IMMEDIATE, flags);
// Use counter-based events only if the extension is available
if (platform->ZeDriverEventPoolCountingEventsExtensionFound) {
return std::make_unique<v2::provider_counter>(
platform, context, v2::QUEUE_IMMEDIATE, device, flags);
} else {
return std::make_unique<v2::provider_normal>(
context, v2::QUEUE_IMMEDIATE, flags);
}
}),
eventPoolCacheRegular(this, phDevices[0]->Platform->getNumDevices(),
[context = this, platform = phDevices[0]->Platform](
Expand Down
29 changes: 29 additions & 0 deletions unified-runtime/source/adapters/level_zero/v2/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,41 @@ uint64_t ur_event_handle_t_::getEventEndTimestamp() {
return profilingData.getEventEndTimestamp();
}

void ur_event_handle_t_::retainFillPattern(const void *pPattern, size_t patternSize) {
if (!fillPattern) {
fillPattern.emplace();
}

auto &storage = fillPattern.value();
storage.size = patternSize;

// Small buffer optimization: use inline buffer for patterns <= 16 bytes
if (patternSize <= FillPatternStorage::INLINE_SIZE) {
std::memcpy(storage.inlineBuffer.data(), pPattern, patternSize);
storage.useHeap = false;
} else {
// Use heap buffer for larger patterns
storage.heapBuffer.resize(patternSize);
std::memcpy(storage.heapBuffer.data(), pPattern, patternSize);
storage.useHeap = true;
}
}

const void *ur_event_handle_t_::getFillPattern() const {
if (!fillPattern) {
return nullptr;
}
return fillPattern->data();
}

void ur_event_handle_t_::reset() {
// consider make an abstraction for regular/counter based
// events if there's more of this type of conditions
if (!(flags & v2::EVENT_FLAGS_COUNTER)) {
zeEventHostReset(getZeEvent());
}
// Clear the fill pattern to avoid memory leak when event is reused from pool
fillPattern.reset();
}

ze_event_handle_t ur_event_handle_t_::getZeEvent() const {
Expand Down
Loading
Loading