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 Jul 19, 2023
1 parent 9b5b8b9 commit e1e279c
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 0 deletions.
63 changes: 63 additions & 0 deletions source/adapters/null/ur_null.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,68 @@ context_t::context_t() {
}
return UR_RESULT_SUCCESS;
};

//////////////////////////////////////////////////////////////////////////
urDdiTable.USM.pfnHostAlloc =
[](ur_context_handle_t hContext, const ur_usm_desc_t *pUSMDesc,
ur_usm_pool_handle_t pool, size_t size, void **ppMem) {
if (size == 0) {
*ppMem = nullptr;
return UR_RESULT_ERROR_UNSUPPORTED_SIZE;
}
*ppMem = malloc(size);
if (ppMem == nullptr) {
return UR_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}
return UR_RESULT_SUCCESS;
};

//////////////////////////////////////////////////////////////////////////
urDdiTable.USM.pfnDeviceAlloc =
[](ur_context_handle_t hContext, ur_device_handle_t hDevice,
const ur_usm_desc_t *pUSMDesc, ur_usm_pool_handle_t pool,
size_t size, void **ppMem) {
if (size == 0) {
*ppMem = nullptr;
return UR_RESULT_ERROR_UNSUPPORTED_SIZE;
}
*ppMem = malloc(size);
if (ppMem == nullptr) {
return UR_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}
return UR_RESULT_SUCCESS;
};

//////////////////////////////////////////////////////////////////////////
urDdiTable.USM.pfnFree = [](ur_context_handle_t hContext, void *pMem) {
free(pMem);
return UR_RESULT_SUCCESS;
};

//////////////////////////////////////////////////////////////////////////
urDdiTable.USM.pfnGetMemAllocInfo =
[](ur_context_handle_t hContext, const void *pMem,
ur_usm_alloc_info_t propName, size_t propSize, void *pPropValue,
size_t *pPropSizeRet) {
switch (propName) {
case UR_USM_ALLOC_INFO_TYPE:
*reinterpret_cast<ur_usm_type_t *>(pPropValue) =
pMem ? UR_USM_TYPE_DEVICE : UR_USM_TYPE_UNKNOWN;
if (pPropSizeRet != nullptr) {
*pPropSizeRet = sizeof(ur_usm_type_t);
}
break;
case UR_USM_ALLOC_INFO_SIZE:
*reinterpret_cast<size_t *>(pPropValue) = pMem ? SIZE_MAX : 0;
if (pPropSizeRet != nullptr) {
*pPropSizeRet = sizeof(size_t);
}
break;
default:
pPropValue = nullptr;
break;
}
return UR_RESULT_SUCCESS;
};
}
} // namespace driver
21 changes: 21 additions & 0 deletions test/conformance/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ function(add_conformance_test_with_platform_environment name)
target_compile_definitions("test-${name}" PRIVATE PLATFORM_ENVIRONMENT)
endfunction()

function(add_fuzz_test name)
set(TEST_TARGET_NAME fuzztest-${name})
add_executable(${TEST_TARGET_NAME}
${ARGN})
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} -max_total_time=10 -seed=1 -shrink=1
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(${TEST_TARGET_NAME} PROPERTIES LABELS "fuzz")
target_compile_options(${TEST_TARGET_NAME} PRIVATE -g -fsanitize=fuzzer)
endfunction()

add_subdirectory(testing)

add_subdirectory(platform)
Expand Down Expand Up @@ -74,3 +91,7 @@ if(DEFINED UR_DPCXX)
add_subdirectory(program)
add_subdirectory(enqueue)
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_subdirectory(fuzz)
endif()
7 changes: 7 additions & 0 deletions test/conformance/fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (C) 2023 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

add_fuzz_test(conformance
urConformanceFuzz.cpp)
126 changes: 126 additions & 0 deletions test/conformance/fuzz/urConformanceFuzz.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright (C) 2023 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
#include <map>
#include <random>
#include <vector>

#include "ur_api.h"

extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
enum FuncPtr {
UR_PLATFORM_GET,
UR_DEVICE_GET,
UR_CONTEXT_CREATE,
UR_USM_POOL_CREATE,
UR_USM_POOL_RELEASE,
UR_USM_HOST_ALLOC,
UR_USM_DEVICE_ALLOC,
UR_USM_FREE,
};

std::vector<ur_platform_handle_t> platforms;
std::vector<ur_device_handle_t> devices;
std::map<ur_usm_pool_handle_t, std::vector<void *>> pool_host_allocs;
std::vector<void *> no_pool_host_allocs;
ur_platform_handle_t platform = nullptr;
ur_context_handle_t context = nullptr;
constexpr ur_device_type_t device_type = UR_DEVICE_TYPE_ALL;
constexpr uint32_t num_entries = 5;
uint32_t num_platforms = 0;
uint32_t num_devices = 0;

std::random_device rand_device;
std::mt19937 generator(rand_device());

ur_result_t ret = urInit(0);
if (ret != UR_RESULT_SUCCESS) {
return -1;
}

uint8_t *data_ptr = data;
while (data_ptr != data + size) {
switch (*data_ptr++) {
case UR_PLATFORM_GET:
urPlatformGet(num_entries, platforms.data(), &num_platforms);
platforms.resize(num_platforms);
break;
case UR_DEVICE_GET:
if (!platforms.empty()) {
std::uniform_int_distribution<unsigned> distrib(
0, platforms.size() - 1);
platform = platforms[distrib(generator)];
}
urDeviceGet(platform, device_type, num_entries, devices.data(),
&num_devices);
devices.resize(num_devices);
break;
case UR_CONTEXT_CREATE:
if (!devices.empty()) {
urContextCreate(devices.size(), devices.data(), nullptr,
&context);
}
break;
case UR_USM_POOL_CREATE:
ur_usm_pool_handle_t pool;
urUSMPoolCreate(context, nullptr, &pool);
pool_host_allocs[pool] = {};
break;
case UR_USM_POOL_RELEASE:
if (!pool_host_allocs.empty()) {
auto &[pool, allocs] = *pool_host_allocs.begin();
if (!allocs.empty()) {
for (auto &ptr : allocs) {
urUSMFree(context, ptr);
}
}
urUSMPoolRelease(pool);
pool_host_allocs.erase(pool);
}
break;
case UR_USM_HOST_ALLOC:
void *ptr;
if (!pool_host_allocs.empty()) {
auto &[pool, allocs] = *pool_host_allocs.end();
urUSMHostAlloc(context, nullptr, pool, 100, &ptr);
pool_host_allocs[pool].push_back(ptr);
} else {
urUSMHostAlloc(context, nullptr, nullptr, 100, &ptr);
no_pool_host_allocs.push_back(ptr);
}
break;
case UR_USM_FREE:
if (!no_pool_host_allocs.empty()) {
urUSMFree(context, no_pool_host_allocs.back());
no_pool_host_allocs.pop_back();
} else if (!pool_host_allocs.empty()) {
for (auto pool_it = pool_host_allocs.rbegin();
pool_it != pool_host_allocs.rend(); ++pool_it) {
auto &[pool, allocs] = *pool_it;
if (!allocs.empty()) {
urUSMFree(context, allocs.back());
allocs.pop_back();
break;
}
}
}
break;
}
}

for (const auto &[pool, allocs] : pool_host_allocs) {
for (auto &alloc : allocs) {
urUSMFree(context, alloc);
}
urUSMPoolRelease(pool);
}
for (auto &alloc : no_pool_host_allocs) {
urUSMFree(context, alloc);
}
for (auto &device : devices) {
urDeviceRelease(device);
}
urContextRelease(context);
return 0;
}

0 comments on commit e1e279c

Please sign in to comment.