Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests: Add GPU direct unit test #1002

Merged
merged 10 commits into from
Oct 29, 2024
Merged
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ mtl_system_status_*
*.mp4
*.pcm
*.wav

# Gpu direct files
gpu_direct/tests/fff.h
gpu_direct/subprojects/*
!gpu_direct/subprojects/gtest.wrap
35 changes: 35 additions & 0 deletions gpu_direct/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# GPU Direct Library

## General Info

This library provides a wrapper for Level Zero API to init GPU and provide functions to allocate shared or device memory.

## Build

Use meson to build the project

## How to use it

1) Use `print_gpu_drivers_and_devices` to list drivers and devices index.
2) Create `GpuContext` and use `init_gpu_device` to init gpu context.
3) Allocate memory with `gpu_allocate_device_buffer` or `gpu_allocate_shared_buffer`.
4) Use `gpu_memcpy` and `gpu_memset` for memcpy and memset operations.
5) Free memory space with `gpu_free_buf` function.
6) Free gpu context with `free_gpu_context`.

## Build MTL GPU-Direct Library

To Build MTL with GPU Direct Library please refer to [doc file](../doc/gpu.md).

## Unit tests

The library contains unit tests.
To run the tests use:

```bash
./run_tests.sh
```

## Links

- [Level Zero Intro](https://www.intel.com/content/www/us/en/developer/articles/technical/using-oneapi-level-zero-interface.html)
29 changes: 16 additions & 13 deletions gpu_direct/gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
/**
* @brief Init level zero lib
* Must be called before calling level zero API.
* @return int - 0 if successfull, < 0 else.
* @return int - 0 if successful, < 0 else.
*/
int init_level_zero_lib() {
ZE_CHECK_ERROR(zeInit(ZE_INIT_FLAG_GPU_ONLY));
Expand All @@ -47,7 +47,7 @@ int init_level_zero_lib() {
/**
* @brief Print drivers and devices indexes
*
* @return int - 0 if successfull, < 0 else.
* @return int - 0 if successful, < 0 else.
*/
int print_gpu_drivers_and_devices() {
// init level-zero lib
Expand All @@ -57,6 +57,10 @@ int print_gpu_drivers_and_devices() {
uint32_t driversCount = 0;
ZE_CHECK_ERROR(zeDriverGet(&driversCount, NULL));
printf("Drivers count: %d\n", driversCount);
if (driversCount == 0) {
return 0;
}

ze_driver_handle_t* drivers = calloc(driversCount, sizeof(ze_driver_handle_t));
if (!drivers) {
fprintf(stderr, "Memory allocation for drivers failed\n");
Expand Down Expand Up @@ -105,7 +109,7 @@ int print_gpu_drivers_and_devices() {
* initialization.
* @param driverIndex - [in] driver index.
* @param deviceIndex - [in] device index.
* @return int. 0 if successfull, < 0 else.
* @return int. 0 if successful, < 0 else.
*/
int init_gpu_device(GpuContext* ctx, unsigned driverIndex, unsigned deviceIndex) {
if (ctx->initialized) {
Expand Down Expand Up @@ -137,7 +141,7 @@ int init_gpu_device(GpuContext* ctx, unsigned driverIndex, unsigned deviceIndex)
ze_context_desc_t ctxDesc = {.stype = ZE_STRUCTURE_TYPE_CONTEXT_DESC};
ZE_CHECK_ERROR(zeContextCreate(ctx->driverHandle, &ctxDesc, &ctx->deviceContext));

// Get decive count
// Get device count
ZE_CHECK_ERROR(zeDeviceGet(ctx->driverHandle, &ctx->deviceCount, NULL));
printf("Number of devices: %d\n", ctx->deviceCount);
if (deviceIndex >= ctx->deviceCount) {
Expand All @@ -147,20 +151,19 @@ int init_gpu_device(GpuContext* ctx, unsigned driverIndex, unsigned deviceIndex)

// Allocate and retrieve device handlers
ctx->devices = calloc(ctx->deviceCount, sizeof(ze_device_handle_t));

if (!ctx->devices) {
fprintf(stderr, "Can't allocate memory for devices handlers\n");
free(ctx->drivers);
return -ENOMEM;
}
ZE_CHECK_ERROR(zeDeviceGet(ctx->driverHandle, &ctx->deviceCount, ctx->devices));
ctx->currectDeviceIndex = deviceIndex;
ctx->currentDeviceIndex = deviceIndex;
ctx->deviceHandler = ctx->devices[deviceIndex];

// Get properties of the selected device
ZE_CHECK_ERROR(zeDeviceGetProperties(ctx->deviceHandler, &ctx->deviceProperties));
printf("Devicie initialized: Index: %d, Name: %s, Type: %d, VendorID: %x\n",
deviceIndex, ctx->deviceProperties.name, ctx->deviceProperties.type,
printf("Device initialized: Index: %d, Name: %s, Type: %d, VendorID: %x\n", deviceIndex,
ctx->deviceProperties.name, ctx->deviceProperties.type,
ctx->deviceProperties.vendorId);

// Create device command queue
Expand Down Expand Up @@ -193,7 +196,7 @@ int init_gpu_device(GpuContext* ctx, unsigned driverIndex, unsigned deviceIndex)
* @param ctx - GPU context of the device.
* @param buf in/out - buf pointer to be filled
* @param size
* @return int. 0 if successfull, < 0 else.
* @return int. 0 if successful, < 0 else.
*/
int gpu_allocate_shared_buffer(GpuContext* ctx, void** buf, size_t size) {
// check if ctx is initialized
Expand Down Expand Up @@ -221,7 +224,7 @@ int gpu_allocate_shared_buffer(GpuContext* ctx, void** buf, size_t size) {
* @param ctx [in].GPU context of the device.
* @param buf [in/out] - buf pointer to be filled
* @param size [in]. Buf size
* @return int. 0 if successfull, < 0 else.
* @return int. 0 if successful, < 0 else.
*/
int gpu_allocate_device_buffer(GpuContext* ctx, void** buf, size_t size) {
// check if ctx is initialized
Expand All @@ -248,7 +251,7 @@ int gpu_allocate_device_buffer(GpuContext* ctx, void** buf, size_t size) {
* @param dst
* @param src
* @param sz
* @return int. 0 if succefull. -1 if error occured
* @return int. 0 if successful. -1 if error occurred
*/
int gpu_memcpy(GpuContext* ctx, void* dst, const void* src, size_t sz) {
// check if ctx is initialized
Expand All @@ -267,7 +270,7 @@ int gpu_memcpy(GpuContext* ctx, void* dst, const void* src, size_t sz) {
}

/**
* @brief GPU memstet
* @brief GPU memset
*
* @param ctx
* @param dst
Expand Down Expand Up @@ -307,7 +310,7 @@ void gpu_free_buf(GpuContext* ctx, void* buf) {
* @brief Free Gpu Context.
*
* @param ctx
* @return int. 0 if succesffull, < 0 else.
* @return int. 0 if successful, < 0 else.
*/
int free_gpu_context(GpuContext* ctx) {
if (ctx == NULL) {
Expand Down
2 changes: 1 addition & 1 deletion gpu_direct/gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ typedef struct GpuContext {

// handlers for the current device and drivers
int currentDriverIndex;
int currectDeviceIndex;
int currentDeviceIndex;

// level zero api structs
ze_driver_handle_t driverHandle;
Expand Down
32 changes: 26 additions & 6 deletions gpu_direct/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ exec_env = host_machine.system()
set_variable('is_windows', exec_env == 'windows')
libze_loader_dep = cc.find_library('libze_loader', required : true)


if is_windows
message('not supported on Windows')
subdir_done()
error('not supported on Windows')
endif

# gpu_direct dependencies check


mtl_gpu_direct_c_args = []
if get_option('buildtype') != 'debug'
mtl_gpu_direct_c_args += ['-Werror']
Expand All @@ -34,7 +30,6 @@ mtl_gpu_direct_header_file = files('gpu.h')
install_headers(mtl_gpu_direct_header_file, subdir: meson.project_name())

mtl_gpu_direct_sources = files('gpu.c')

mtl_gpu_direct_lib = shared_library(
meson.project_name(),
mtl_gpu_direct_sources,
Expand All @@ -51,3 +46,28 @@ pkg.generate(
filebase: meson.project_name(),
description: 'Media Transport Library - gpu_direct',
)

## Tests
if get_option('enable_tests')
gtest_proj = subproject('gtest')
gtest_dep = gtest_proj.get_variable('gtest_dep')
gtest_main_dep = gtest_proj.get_variable('gtest_main_dep')
gmock_dep = gtest_proj.get_variable('gmock_dep')

tests_src = [
'tests/negative_tests.cpp',
'tests/gpu_tests.cpp'
]

gtest_e = executable(
'gtest-all',
tests_src,
dependencies : [
gtest_dep,
gtest_main_dep,
gmock_dep,
],
link_with: mtl_gpu_direct_lib
)
test('gtest tests', gtest_e)
endif
2 changes: 2 additions & 0 deletions gpu_direct/meson_options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Add a new option for running unit tests
option('enable_tests', type: 'boolean', value: false, description: 'Enable running unit tests')
10 changes: 10 additions & 0 deletions gpu_direct/run_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

echo "Downloading fff.library"
wget https://raw.githubusercontent.com/meekrosoft/fff/refs/heads/master/fff.h -O ./tests/fff.h

echo "Compiling the library"
meson setup build -Denable_tests=true && cd build || exit

echo "Running the tests"
meson test
16 changes: 16 additions & 0 deletions gpu_direct/subprojects/gtest.wrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[wrap-file]
directory = googletest-1.15.0
source_url = https://github.com/google/googletest/archive/refs/tags/v1.15.0.tar.gz
source_filename = gtest-1.15.0.tar.gz
source_hash = 7315acb6bf10e99f332c8a43f00d5fbb1ee6ca48c52f6b936991b216c586aaad
patch_filename = gtest_1.15.0-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.15.0-1/get_patch
patch_hash = 5f8e484c48fdc1029c7fd08807bd2615f8c9d16f90df6d81984f4f292752c925
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/gtest_1.15.0-1/gtest-1.15.0.tar.gz
wrapdb_version = 1.15.0-1

[provide]
gtest = gtest_dep
gtest_main = gtest_main_dep
gmock = gmock_dep
gmock_main = gmock_main_dep
Loading