diff --git a/examples/codegen/README.md b/examples/codegen/README.md new file mode 100644 index 0000000000..e28b9aa41f --- /dev/null +++ b/examples/codegen/README.md @@ -0,0 +1,35 @@ +## End-to-end code generation example + +This example demonstrates an end-to-end pipeline of code generation and execution that typically occurs in a JIT engine. +It creates a simple function (adding +1 to an array and storing the result in a second one) via llvm API, +converts it to spirv, and submits it to the runtime. + +## Running the example + +The following commands are executed from the project root directory. + +### Using conda environment + +``` +$ conda env create -f third_party/deps.yml +$ conda activate examples +$ mkdir build && cd build +# configure with: +$ cmake .. -DUR_BUILD_ADAPTER_L0=ON -DUR_BUILD_EXAMPLE_CODEGEN=ON +$ make +$ ./bin/codegen +``` + +### Without using conda + +To run the example with llvm 13, you will need to make sure that `llvm-13` and `libllvmspirvlib-13-dev` are installed. + +**NOTE**: The example could be working with other llvm versions but it was tested with version 13. + +``` +$ mkdir build && cd build +# configure with: +$ cmake .. -DUR_BUILD_ADAPTER_L0=ON -DUR_BUILD_EXAMPLE_CODEGEN=ON -DLLVM_DIR=/usr/lib/llvm-13/cmake +$ make +$ ./bin/codegen +``` diff --git a/examples/codegen/codegen.cpp b/examples/codegen/codegen.cpp index 0352ae6e02..179c8c923e 100644 --- a/examples/codegen/codegen.cpp +++ b/examples/codegen/codegen.cpp @@ -20,6 +20,8 @@ #include "helpers.h" #include "ur_api.h" +const unsigned PAGE_SIZE = 4096; + void ur_check(const ur_result_t r) { if (r != UR_RESULT_SUCCESS) { urTearDown(nullptr); @@ -40,6 +42,23 @@ std::vector get_adapters() { return adapters; } +std::vector +get_supported_adapters(std::vector &adapters) { + std::vector supported_adapters; + for (auto adapter : adapters) { + ur_adapter_backend_t backend; + ur_check(urAdapterGetInfo(adapter, UR_ADAPTER_INFO_BACKEND, + sizeof(ur_adapter_backend_t), &backend, + nullptr)); + + if (backend == UR_ADAPTER_BACKEND_LEVEL_ZERO) { + supported_adapters.push_back(adapter); + } + } + + return supported_adapters; +} + std::vector get_platforms(std::vector &adapters) { uint32_t platformCount = 0; @@ -70,7 +89,7 @@ std::vector get_gpus(ur_platform_handle_t p) { return devices; } -template struct alignas(4096) AlignedArray { +template struct alignas(PAGE_SIZE) AlignedArray { T data[N]; }; @@ -79,7 +98,8 @@ int main() { ur_check(urInit(UR_DEVICE_INIT_FLAG_GPU, loader_config)); auto adapters = get_adapters(); - auto platforms = get_platforms(adapters); + auto supported_adapters = get_supported_adapters(adapters); + auto platforms = get_platforms(supported_adapters); auto gpus = get_gpus(platforms.front()); auto spv = generate_plus_one_spv(); @@ -131,10 +151,26 @@ int main() { ur_check(urQueueFinish(queue)); + std::cout << "Input Array: "; + for (int i = 0; i < a_size; ++i) { + std::cout << a.data[i] << " "; + } + std::cout << std::endl; + + bool expectedResult = false; + + std::cout << "Output Array: "; for (int i = 0; i < a_size; ++i) { std::cout << b.data[i] << " "; + expectedResult |= (b.data[i] == a.data[i] + 1); } std::cout << std::endl; - return urTearDown(nullptr) == UR_RESULT_SUCCESS ? 0 : 1; + if (expectedResult) { + std::cout << "Results are correct." << std::endl; + } else { + std::cout << "Results are incorrect." << std::endl; + } + + return urTearDown(nullptr) == UR_RESULT_SUCCESS && expectedResult ? 0 : 1; } diff --git a/scripts/deps.yml b/third_party/deps.yml similarity index 89% rename from scripts/deps.yml rename to third_party/deps.yml index 8c5f5d068b..af9e48ebbb 100644 --- a/scripts/deps.yml +++ b/third_party/deps.yml @@ -1,3 +1,4 @@ +# This file is used to initialize a conda environment to run codegen example. name: examples channels: - conda-forge