Skip to content

Commit

Permalink
Test parts of API with libFuzzer.
Browse files Browse the repository at this point in the history
  • Loading branch information
PatKamin committed Aug 10, 2023
1 parent 8b2a8d4 commit 2afa8f8
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 41 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ jobs:
working-directory: ${{github.workspace}}/build
run: ctest -C ${{matrix.build_type}} --output-on-failure -L "python|umf|loader|validation|tracing|unit|urtrace"

- name: Fuzz test
working-directory: ${{github.workspace}}/build
if: matrix.fuzztest == 'ON'
run: ctest -C ${{matrix.build_type}} --output-on-failure -L "fuzz"

adapter-build:
name: Build - Adapters on Ubuntu
strategy:
Expand Down Expand Up @@ -139,11 +144,6 @@ jobs:
- name: Build
run: cmake --build ${{github.workspace}}/build -j $(nproc)

- name: Fuzz test
working-directory: ${{github.workspace}}/build
if: matrix.fuzztest == 'ON'
run: ctest -C ${{matrix.build_type}} --output-on-failure -L "fuzz"

windows-build:
name: Build - Windows
strategy:
Expand Down
2 changes: 1 addition & 1 deletion test/conformance/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ if(DEFINED UR_DPCXX)
add_custom_target(generate_device_binaries)

set(UR_CONFORMANCE_DEVICE_BINARIES_DIR
"${CMAKE_CURRENT_BINARY_DIR}/device_binaries/")
"${CMAKE_CURRENT_BINARY_DIR}/device_binaries" CACHE INTERNAL UR_CONFORMANCE_DEVICE_BINARIES_DIR)
file(MAKE_DIRECTORY ${UR_CONFORMANCE_DEVICE_BINARIES_DIR})

if(DEFINED UR_CONFORMANCE_TARGET_TRIPLES)
Expand Down
7 changes: 5 additions & 2 deletions test/conformance/source/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,15 @@ std::string KernelsEnvironment::getSupportedILPostfix(uint32_t device_index) {

return IL.str();
}

#include <iostream>
std::string
KernelsEnvironment::getKernelSourcePath(const std::string &kernel_name,
uint32_t device_index) {
std::stringstream path;
path << kernel_options.kernel_directory << "/" << kernel_name;
std::cout << "path=" << path.str() << std::endl;
std::string il_postfix = getSupportedILPostfix(device_index);
std::cout << "il_postfix=" << il_postfix << std::endl;

if (il_postfix.empty()) {
return {};
Expand All @@ -300,6 +302,8 @@ KernelsEnvironment::getKernelSourcePath(const std::string &kernel_name,
std::string binary_name;
for (const auto &entry : filesystem::directory_iterator(path.str())) {
auto file_name = entry.path().filename().string();
std::cout << "file_name=" << file_name << std::endl;

if (file_name.find(il_postfix) != std::string::npos) {
binary_name = file_name;
break;
Expand All @@ -322,7 +326,6 @@ void KernelsEnvironment::LoadSource(
std::shared_ptr<std::vector<char>> &binary_out) {
std::string source_path =
instance->getKernelSourcePath(kernel_name, device_index);

if (source_path.empty()) {
FAIL() << error;
}
Expand Down
11 changes: 8 additions & 3 deletions test/fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@

function(add_fuzz_test name)
set(TEST_TARGET_NAME fuzztest-${name})
add_executable(${TEST_TARGET_NAME}
add_ur_executable(${TEST_TARGET_NAME}
${ARGN})
target_link_libraries(${TEST_TARGET_NAME}
PRIVATE
${PROJECT_NAME}::loader
${PROJECT_NAME}::headers
${PROJECT_NAME}::common
-fsanitize=fuzzer)
-fsanitize=fuzzer -fprofile-instr-generate -fcoverage-mapping)
add_test(NAME ${TEST_TARGET_NAME}
COMMAND ${TEST_TARGET_NAME} -max_total_time=600 -seed=1 -shrink=1 -verbosity=1
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
# TODO: Add validation layer env vars
set_tests_properties(${TEST_TARGET_NAME} PROPERTIES
LABELS "fuzz"
ENVIRONMENT
Expand All @@ -24,7 +25,11 @@ function(add_fuzz_test name)
"XPTI_SUBSCRIBERS=$<TARGET_FILE:collector>"
"UR_ADAPTERS_FORCE_LOAD=\"$<TARGET_FILE:ur_adapter_null>\""
"UR_ENABLE_LAYERS=UR_LAYER_TRACING")
target_compile_options(${TEST_TARGET_NAME} PRIVATE -g -fsanitize=fuzzer)
target_compile_options(${TEST_TARGET_NAME} PRIVATE -g -fsanitize=fuzzer -fprofile-instr-generate -fcoverage-mapping)
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()

add_fuzz_test(base
Expand Down
139 changes: 110 additions & 29 deletions test/fuzz/urFuzz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "kernel_entry_points.h"
#include "ur_api.h"
#include "utils.hpp"

Expand Down Expand Up @@ -35,7 +36,9 @@ int ur_device_get(TestState &state) {
if (res != UR_RESULT_SUCCESS) {
return -1;
}
state.devices.resize(state.num_devices);
if (state.devices.size() != state.num_devices) {
state.devices.resize(state.num_devices);
}

return 0;
}
Expand All @@ -45,8 +48,10 @@ int ur_device_release(TestState &state) {
return -1;
}

urDeviceRelease(state.devices.back());
state.devices.pop_back();
ur_result_t res = urDeviceRelease(state.devices.back());
if (res == UR_RESULT_SUCCESS) {
state.devices.pop_back();
}

return 0;
}
Expand All @@ -57,9 +62,11 @@ int ur_context_create(TestState &state) {
}

ur_context_handle_t context;
urContextCreate(state.devices.size(), state.devices.data(), nullptr,
&context);
state.contexts.push_back(context);
ur_result_t res = urContextCreate(state.devices.size(),
state.devices.data(), nullptr, &context);
if (res == UR_RESULT_SUCCESS) {
state.contexts.push_back(context);
}

return 0;
}
Expand All @@ -69,8 +76,11 @@ int ur_context_release(TestState &state) {
state.contexts[state.context_num] == state.contexts.back()) {
return -1;
}
urContextRelease(state.contexts.back());
state.contexts.pop_back();

ur_result_t res = urContextRelease(state.contexts.back());
if (res == UR_RESULT_SUCCESS) {
state.contexts.pop_back();
}

return 0;
}
Expand All @@ -83,19 +93,24 @@ int ur_usm_pool_create(TestState &state) {
ur_usm_pool_handle_t pool;
ur_usm_pool_desc_t pool_desc{UR_STRUCTURE_TYPE_USM_POOL_DESC, nullptr,
UR_USM_POOL_FLAG_ZERO_INITIALIZE_BLOCK};
urUSMPoolCreate(state.contexts[state.context_num], &pool_desc, &pool);
state.pool_host_allocs[pool] = {};
ur_result_t res =
urUSMPoolCreate(state.contexts[state.context_num], &pool_desc, &pool);
if (res == UR_RESULT_SUCCESS) {
state.pool_host_allocs[pool] = {};
}

return 0;
}

// TODO: Split into host/device pool release
int ur_usm_pool_release(TestState &state) {
if (state.pool_host_allocs.empty() || !check_context_exists(&state)) {
if (!check_context_exists(&state)) {
return -1;
}

uint8_t pool_num;
auto pool_map_ptr = &state.pool_host_allocs;

if (get_next_input_data(&state.input, &pool_num) != 0) {
return -1;
}
Expand All @@ -109,16 +124,18 @@ int ur_usm_pool_release(TestState &state) {

auto &[pool, allocs] = *get_map_item(pool_map_ptr, pool_num);
if (!allocs.empty()) {
for (auto &ptr : allocs) {
urUSMFree(state.contexts[state.context_num], ptr);
}
return -1;
}

ur_result_t res = urUSMPoolRelease(pool);
if (res == UR_RESULT_SUCCESS) {
pool_map_ptr->erase(pool);
}
urUSMPoolRelease(pool);
pool_map_ptr->erase(pool);

return 0;
}

// TODO: Split to pool/no pool host alloc
int ur_usm_host_alloc(TestState &state) {
if (!check_context_exists(&state)) {
return -1;
Expand All @@ -128,9 +145,12 @@ int ur_usm_host_alloc(TestState &state) {
uint16_t alloc_size;
auto &pool_map = state.pool_host_allocs;
auto &context = state.contexts[state.context_num];
ur_result_t res = UR_RESULT_SUCCESS;

if (get_next_input_data(&state.input, &alloc_size) != 0) {
return -1;
}

if (!pool_map.empty()) {
uint8_t pool_num;
if (get_next_input_data(&state.input, &pool_num) != 0) {
Expand All @@ -141,16 +161,21 @@ int ur_usm_host_alloc(TestState &state) {
}

auto &[pool, allocs] = *get_map_item(&pool_map, pool_num);
urUSMHostAlloc(context, nullptr, pool, alloc_size, &ptr);
allocs.push_back(ptr);
res = urUSMHostAlloc(context, nullptr, pool, alloc_size, &ptr);
if (res == UR_RESULT_SUCCESS) {
allocs.push_back(ptr);
}
} else {
urUSMHostAlloc(context, nullptr, nullptr, alloc_size, &ptr);
state.no_pool_host_allocs.push_back(ptr);
res = urUSMHostAlloc(context, nullptr, nullptr, alloc_size, &ptr);
if (res == UR_RESULT_SUCCESS) {
state.no_pool_host_allocs.push_back(ptr);
}
}

return 0;
}

// TODO: Extract same code with host_alloc
int ur_usm_device_alloc(TestState &state) {
if (!check_context_exists(&state)) {
return -1;
Expand All @@ -160,6 +185,7 @@ int ur_usm_device_alloc(TestState &state) {
uint16_t alloc_size;
auto &pool_map = state.pool_device_allocs;
auto &context = state.contexts[state.context_num];
ur_result_t res = UR_RESULT_SUCCESS;

if (get_next_input_data(&state.input, &alloc_size) != 0) {
return -1;
Expand All @@ -180,16 +206,26 @@ int ur_usm_device_alloc(TestState &state) {
}

auto &[pool, allocs] = *get_map_item(&pool_map, pool_num);
urUSMDeviceAlloc(context, device, nullptr, pool, alloc_size, &ptr);
allocs.push_back(ptr);
// TODO: Remove couts
std::cout << "pool_device_alloc" << std::endl;
res =
urUSMDeviceAlloc(context, device, nullptr, pool, alloc_size, &ptr);
if (res == UR_RESULT_SUCCESS) {
allocs.push_back(ptr);
}
} else {
urUSMDeviceAlloc(context, device, nullptr, nullptr, alloc_size, &ptr);
state.no_pool_device_allocs.push_back(ptr);
std::cout << "no_pool_device_alloc(" << alloc_size << ")" << std::endl;
res = urUSMDeviceAlloc(context, device, nullptr, nullptr, alloc_size,
&ptr);
if (res == UR_RESULT_SUCCESS) {
state.no_pool_device_allocs.push_back(ptr);
}
}

return 0;
}

// TODO: Split into pool/no pool free
int ur_usm_free(TestState &state) {
if (!state.no_pool_host_allocs.empty()) {
urUSMFree(state.contexts[state.context_num],
Expand All @@ -216,16 +252,58 @@ int ur_usm_free(TestState &state) {
return 0;
}

// TODO: Extract API calls to separate functions
int ur_program_create_with_il(TestState &state) {
if (!check_context_exists(&state) || !check_device_exists(&state)) {
return -1;
}

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;
auto &context = state.contexts[state.context_num];
auto &device = state.devices[state.device_num];
std::string kernel_name =
uur::device_binaries::program_kernel_map["bar"][0];

load_kernel_source(il_bin);
urProgramCreateWithIL(context, il_bin.data(), il_bin.size(), nullptr,
&program);
urProgramBuild(context, program, nullptr);
urKernelCreate(program, kernel_name.data(), &kernel);
urQueueCreate(context, device, nullptr, &queue);

const uint32_t nDim = 3;
const size_t gWorkOffset[] = {0, 0, 0};
const size_t gWorkSize[] = {128, 128, 128};

urEnqueueKernelLaunch(queue, kernel, nDim, gWorkOffset, gWorkSize, nullptr,
0, nullptr, &event);

urEventWait(1, &event);
urEventRelease(event);
urQueueFinish(queue);
urQueueRelease(queue);
urKernelRelease(kernel);
urProgramRelease(program);

return 0;
}

extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
int next_api_call;
TestState test_state;
int ret = -1;

int (*api_wrappers[])(TestState &) = {
ur_platform_get, ur_device_get, ur_device_release,
ur_context_create, ur_context_release, ur_usm_pool_create,
ur_usm_pool_release, ur_usm_host_alloc, ur_usm_device_alloc,
ur_usm_free,
ur_platform_get, ur_device_get,
ur_device_release, ur_context_create,
ur_context_release, ur_usm_pool_create,
ur_usm_pool_release, ur_usm_host_alloc,
ur_usm_device_alloc, ur_usm_free,
ur_program_create_with_il,
};

test_state.input = {data, size};
Expand All @@ -235,10 +313,13 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
return ret;
}

ur_result_t res = urInit(0, nullptr);
urLoaderConfigCreate(&test_state.config);
urLoaderConfigEnableLayer(test_state.config, "UR_LAYER_FULL_VALIDATION");
ur_result_t res = urInit(0, test_state.config);
if (res != UR_RESULT_SUCCESS) {
return -1;
}

test_state.adapters.resize(test_state.num_entries);
res = urAdapterGet(test_state.num_entries, test_state.adapters.data(),
&test_state.num_adapters);
Expand Down
Loading

0 comments on commit 2afa8f8

Please sign in to comment.