Skip to content

Commit

Permalink
Merge pull request #1427 from PatKamin/fix-fuzztest-kernel
Browse files Browse the repository at this point in the history
[CI] Fix kernel execution in fuzztests and run fuzztests on L0 in CI
  • Loading branch information
kbenzie committed Jul 5, 2024
2 parents 731376d + d5a90ad commit fa06e95
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 127 deletions.
75 changes: 75 additions & 0 deletions .github/workflows/build-fuzz-reusable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
name: Build - Fuzztests on L0 HW - Reusable

on:
workflow_call:
inputs:
test_label:
required: true
type: string

permissions:
contents: read

jobs:
fuzztest-build-hw:
name: Build and run fuzz tests on L0 HW
if: github.repository == 'oneapi-src/unified-runtime' # run only on upstream; forks won't have the HW
strategy:
matrix:
build_type: [Debug, Release]
compiler: [{c: clang, cxx: clang++}]

runs-on: 'FUZZTESTS'
# In order to use sanitizers, vm.mmap_rnd_bits=28 must be set in the system,
# otherwise random SEGV at the start of the test occurs.
# Alternatively, clang 18.1.0 onwards with fixed sanitizers behavior can be used,
# if available.
# TODO: Remove this advice once clang 18.1.0 is available in the system (like ie. as an apt package).

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Install pip packages
run: pip install -r third_party/requirements.txt

- name: Download DPC++
run: |
wget -O ${{github.workspace}}/dpcpp_compiler.tar.gz https://github.com/intel/llvm/releases/download/nightly-2024-01-29/sycl_linux.tar.gz
mkdir dpcpp_compiler
tar -xvf ${{github.workspace}}/dpcpp_compiler.tar.gz -C dpcpp_compiler
- name: Build level zero with gcc
run: |
git clone -b v1.17.6 --depth=1 https://github.com/oneapi-src/level-zero.git ${{github.workspace}}/level-zero
cd ${{github.workspace}}/level-zero
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
cmake --build build -j $(nproc)
- name: Configure CMake
run: >
cmake
-B${{github.workspace}}/build
-DCMAKE_C_COMPILER=${{matrix.compiler.c}}
-DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}}
-DUR_ENABLE_TRACING=ON
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
-DUR_BUILD_TESTS=ON
-DUR_USE_ASAN=ON
-DUR_USE_UBSAN=ON
-DUR_BUILD_ADAPTER_L0=ON
-DUR_LEVEL_ZERO_LOADER_LIBRARY=${{github.workspace}}/level-zero/build/lib/libze_loader.so
-DUR_LEVEL_ZERO_INCLUDE_DIR=${{github.workspace}}/level-zero/include/
-DUR_DPCXX=${{github.workspace}}/dpcpp_compiler/bin/clang++
-DUR_SYCL_LIBRARY_DIR=${{github.workspace}}/dpcpp_compiler/lib
- name: Build
run: cmake --build ${{github.workspace}}/build -j $(nproc)

- name: Fuzz test
working-directory: ${{github.workspace}}/build
run: ctest -C ${{matrix.build_type}} --output-on-failure -L "${{inputs.test_label}}" --verbose

- name: Get information about platform
if: ${{ always() }}
run: .github/scripts/get_system_info.sh
51 changes: 6 additions & 45 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,51 +116,12 @@ jobs:
working-directory: ${{github.workspace}}/build
run: ctest -C ${{matrix.build_type}} --output-on-failure -L "umf|loader|validation|tracing|unit|urtrace"

fuzztest-build:
name: Build and run quick fuzztest scenarios
strategy:
matrix:
build_type: [Debug, Release]
compiler: [{c: clang, cxx: clang++}]

runs-on: 'ubuntu-22.04'

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Install pip packages
run: pip install -r third_party/requirements.txt

- name: Download DPC++
run: |
sudo apt install libncurses5
wget -O ${{github.workspace}}/dpcpp_compiler.tar.gz https://github.com/intel/llvm/releases/download/sycl-nightly%2F20230626/dpcpp-compiler.tar.gz
tar -xvf ${{github.workspace}}/dpcpp_compiler.tar.gz
- name: Setup DPC++
run: |
source ${{github.workspace}}/dpcpp_compiler/startup.sh
- name: Configure CMake
run: >
cmake
-B${{github.workspace}}/build
-DCMAKE_C_COMPILER=${{matrix.compiler.c}}
-DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}}
-DUR_ENABLE_TRACING=ON
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
-DUR_BUILD_TESTS=ON
-DUR_USE_ASAN=ON
-DUR_USE_UBSAN=ON
-DUR_DPCXX=${{github.workspace}}/dpcpp_compiler/bin/clang++
- name: Build
run: cmake --build ${{github.workspace}}/build -j $(nproc)

- name: Fuzz test
working-directory: ${{github.workspace}}/build
run: ctest -C ${{matrix.build_type}} --output-on-failure -L "fuzz-short" --verbose

fuzztest:
name: Fuzz tests short
uses: ./.github/workflows/build-fuzz-reusable.yml
with:
test_label: "fuzz-short"

level-zero:
name: Level Zero
uses: ./.github/workflows/build-hw-reusable.yml
Expand Down
47 changes: 5 additions & 42 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,8 @@ permissions:
contents: read

jobs:
long-fuzz-test:
name: Run long fuzz tests
strategy:
matrix:
build_type: [Debug, Release]
compiler: [{c: clang, cxx: clang++}]

runs-on: 'ubuntu-22.04'

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Install pip packages
run: pip install -r third_party/requirements.txt

- name: Download DPC++
run: |
wget -O ${{github.workspace}}/dpcpp_compiler.tar.gz https://github.com/intel/llvm/releases/download/nightly-2024-01-29/sycl_linux.tar.gz
mkdir dpcpp_compiler
tar -xvf ${{github.workspace}}/dpcpp_compiler.tar.gz -C dpcpp_compiler
- name: Configure CMake
run: >
cmake
-B${{github.workspace}}/build
-DCMAKE_C_COMPILER=${{matrix.compiler.c}}
-DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}}
-DUR_ENABLE_TRACING=ON
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
-DUR_BUILD_TESTS=ON
-DUR_USE_ASAN=ON
-DUR_USE_UBSAN=ON
-DUR_DPCXX=${{github.workspace}}/dpcpp_compiler/bin/clang++
- name: Build
run: >
LD_LIBRARY_PATH=${{github.workspace}}/dpcpp_compiler/lib
cmake --build ${{github.workspace}}/build -j $(nproc)
- name: Fuzz long test
working-directory: ${{github.workspace}}/build
run: ctest -C ${{matrix.build_type}} --output-on-failure -L "fuzz-long"
fuzztest:
name: Fuzz tests long
uses: ./.github/workflows/build-fuzz-reusable.yml
with:
test_label: "fuzz-long"
4 changes: 2 additions & 2 deletions source/adapters/level_zero/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ if (NOT UR_LEVEL_ZERO_LOADER_LIBRARY STREQUAL "")
file(COPY ${UR_LEVEL_ZERO_LOADER_LIBRARY} DESTINATION ${LEVEL_ZERO_COPY_DIR} FOLLOW_SYMLINK_CHAIN)
endif()
if (NOT UR_LEVEL_ZERO_INCLUDE_DIR STREQUAL "")
set(LEVEL_ZERO_INCLUDE_DIR ${LEVEL_ZERO_COPY_DIR}/level_zero)
set(LEVEL_ZERO_INCLUDE_DIR ${LEVEL_ZERO_COPY_DIR})

This comment has been minimized.

Copy link
@jsji

jsji Jul 14, 2024

Contributor

LEVEL_ZERO_INCLUDE_DIR is INTERFACE (line 93 below), changing this break the interface when UR_LEVEL_ZERO_INCLUDE_DIR is set.
This change breaks our internal build, which sets UR_LEVEL_ZERO_INCLUDE_DIR.

It is OK, we have updated our internal build now, but please consider similar INTERFACE change carefully next time and notify pulldown team if we do decide to change interfaces . Thanks.

message(STATUS "Level Zero Adapter: Copying Level Zero headers to local build tree")
file(COPY ${UR_LEVEL_ZERO_INCLUDE_DIR}/level_zero DESTINATION ${LEVEL_ZERO_COPY_DIR})
file(COPY ${UR_LEVEL_ZERO_INCLUDE_DIR}/ DESTINATION ${LEVEL_ZERO_COPY_DIR})
endif()

if (NOT DEFINED LEVEL_ZERO_LIBRARY OR NOT DEFINED LEVEL_ZERO_INCLUDE_DIR)
Expand Down
60 changes: 35 additions & 25 deletions test/fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
# Copyright (C) 2023 Intel Corporation
# Copyright (C) 2023-2024 Intel Corporation
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

function(add_fuzz_test name label)
set(TEST_TARGET_NAME fuzztest-${name})
add_ur_executable(${TEST_TARGET_NAME}
urFuzz.cpp)
target_link_libraries(${TEST_TARGET_NAME}
PRIVATE
${PROJECT_NAME}::loader
${PROJECT_NAME}::headers
${PROJECT_NAME}::common
-fsanitize=fuzzer)
add_test(NAME ${TEST_TARGET_NAME}
COMMAND ${TEST_TARGET_NAME} ${ARGN} -verbosity=1
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

set(ENV_VARS UR_ENABLE_LAYERS=UR_LAYER_FULL_VALIDATION)
if(UR_BUILD_ADAPTER_L0 OR UR_BUILD_ADAPTER_ALL)
set(ENV_VARS "")
if(UR_USE_UBSAN)
list(APPEND ENV_VARS
UR_ADAPTERS_FORCE_LOAD=\"$<TARGET_FILE:ur_adapter_level_zero>\"
NEOReadDebugKeys=1
DisableDeepBind=1)
else()
list(APPEND ENV_VARS UR_ADAPTERS_FORCE_LOAD=\"$<TARGET_FILE:ur_adapter_null>\")
UBSAN_OPTIONS=print_stacktrace=1)
endif()
if(UR_ENABLE_TRACING)
list(APPEND ENV_VARS
Expand All @@ -33,17 +18,42 @@ function(add_fuzz_test name label)
XPTI_SUBSCRIBERS=$<TARGET_FILE:collector>
UR_ENABLE_LAYERS=UR_LAYER_TRACING)
endif()

if(UR_BUILD_ADAPTER_L0 OR UR_BUILD_ADAPTER_ALL)
list(APPEND ENV_VARS
UR_ADAPTERS_FORCE_LOAD=\"$<TARGET_FILE:ur_adapter_level_zero>\")
if(UR_USE_ASAN)
list(APPEND ENV_VARS
NEOReadDebugKeys=1
DisableDeepBind=1)
endif()
else()
list(APPEND ENV_VARS UR_ADAPTERS_FORCE_LOAD=\"$<TARGET_FILE:ur_adapter_null>\")
endif()

add_test(NAME ${TEST_TARGET_NAME}
COMMAND fuzztest-base ${ARGN} -verbosity=1 -detect_leaks=0
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

set_tests_properties(${TEST_TARGET_NAME} PROPERTIES
LABELS ${label}
ENVIRONMENT "${ENV_VARS}")
# TODO: Should we check if this sanitizer flag is available?
target_compile_options(${TEST_TARGET_NAME} PRIVATE -g -fsanitize=fuzzer)
target_compile_definitions(${TEST_TARGET_NAME} PRIVATE -DKERNEL_IL_PATH="${UR_CONFORMANCE_DEVICE_BINARIES_DIR}/bar/sycl_spir641.spv")
target_include_directories(${TEST_TARGET_NAME} PRIVATE ${UR_CONFORMANCE_DEVICE_BINARIES_DIR})

add_dependencies(${TEST_TARGET_NAME} generate_device_binaries)
endfunction()

# Create a single binary
add_ur_executable(fuzztest-base
urFuzz.cpp)
target_link_libraries(fuzztest-base
PRIVATE
${PROJECT_NAME}::loader
${PROJECT_NAME}::headers
${PROJECT_NAME}::common
-fsanitize=fuzzer)
target_compile_options(fuzztest-base PRIVATE -g -fsanitize=fuzzer)
target_compile_definitions(fuzztest-base PRIVATE -DKERNEL_IL_PATH="${UR_CONFORMANCE_DEVICE_BINARIES_DIR}/fill/spir64.bin.0")
target_include_directories(fuzztest-base PRIVATE ${UR_CONFORMANCE_DEVICE_BINARIES_DIR})
add_dependencies(fuzztest-base generate_device_binaries)

# Add long test
add_fuzz_test(base fuzz-long -max_total_time=600 -seed=1)

Expand Down
40 changes: 29 additions & 11 deletions test/fuzz/urFuzz.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2023 Intel Corporation
// Copyright (C) 2023-2024 Intel Corporation
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand Down Expand Up @@ -353,36 +353,54 @@ int ur_program_create_with_il(TestState &state) {
}

std::vector<char> il_bin;
ur_program_handle_t program = nullptr;
ur_kernel_handle_t kernel = nullptr;
ur_queue_handle_t queue = nullptr;
ur_event_handle_t event = nullptr;
ur_program_handle_t program;
ur_kernel_handle_t kernel;
ur_queue_handle_t queue;
ur_event_handle_t event;
auto &context = state.contexts[state.context_num]->handle;
auto &device = state.devices[state.device_num];
// TODO: Use some generic utility to retrieve/use kernels
std::string kernel_name =
uur::device_binaries::program_kernel_map["bar"][0];
uur::device_binaries::program_kernel_map["fill"][0];

il_bin = state.load_kernel_source();
if (il_bin.empty()) {
return -1;
}

constexpr int vec_size = 64;
std::vector<int> vec(vec_size, 0);

urProgramCreateWithIL(context, il_bin.data(), il_bin.size(), nullptr,
&program);
urProgramBuild(context, program, nullptr);

ur_mem_handle_t memory_buffer;
urMemBufferCreate(context, UR_MEM_FLAG_READ_WRITE, vec_size * sizeof(int),
nullptr, &memory_buffer);
urKernelCreate(program, kernel_name.data(), &kernel);
urKernelSetArgMemObj(kernel, 0, nullptr, memory_buffer);

urQueueCreate(context, device, nullptr, &queue);

const uint32_t nDim = 3;
const size_t gWorkOffset[] = {0, 0, 0};
const size_t gWorkSize[] = {128, 128, 128};
urEnqueueMemBufferWrite(queue, memory_buffer, true, 0,
vec_size * sizeof(int), vec.data(), 0, nullptr,
&event);
urEventWait(1, &event);
urEventRelease(event);

urEnqueueKernelLaunch(queue, kernel, nDim, gWorkOffset, gWorkSize, nullptr,
0, nullptr, &event);
constexpr uint32_t nDim = 3;
const size_t gWorkOffset[] = {0, 0, 0};
const size_t gWorkSize[] = {vec_size * 4, 1, 1};
const size_t lWorkSize[] = {1, 1, 1};

urEnqueueKernelLaunch(queue, kernel, nDim, gWorkOffset, gWorkSize,
lWorkSize, 0, nullptr, &event);
urEventWait(1, &event);
urEventRelease(event);

urQueueFinish(queue);
urMemRelease(memory_buffer);
urQueueRelease(queue);
urKernelRelease(kernel);
urProgramRelease(program);
Expand Down
8 changes: 6 additions & 2 deletions test/fuzz/utils.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2023 Intel Corporation
// Copyright (C) 2023-2024 Intel Corporation
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand Down Expand Up @@ -105,7 +105,11 @@ struct TestState {
uint8_t context_num;

TestState(std::unique_ptr<FuzzedDataProvider> data_provider)
: data_provider(std::move(data_provider)) {}
: data_provider(std::move(data_provider)) {
num_adapters = 0;
num_platforms = 0;
num_devices = 0;
}

template <typename IntType> int get_next_input_data(IntType *data) {
if (data_provider->remaining_bytes() < sizeof(IntType)) {
Expand Down

0 comments on commit fa06e95

Please sign in to comment.