Skip to content

Commit

Permalink
support llvm-spirv (uxlfoundation#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
gglin001 authored Dec 24, 2024
1 parent 5f04a13 commit b123420
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "llvm-spirv"]
path = llvm-spirv
url = git@github.com:nuway-ai/llvm-spirv.git
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,15 @@ ca_option(CA_USE_SPLIT_DWARF BOOL
ON)

# options for private usage
ca_option(CA_LLVM_IS_DPCPP BOOL "building with llvm-dpcpp" OFF)
ca_option(CA_BUILD_SPIRV_TOOLS BOOL "build spirv-tools from src" OFF)
ca_option(CA_BUILD_LLVM_SPIRV BOOL "build llvm-spirv" ON)
ca_option(CA_TRACY_ENABLE BOOL "Enable tracy profiler" OFF)

if(CA_LLVM_IS_DPCPP AND CA_BUILD_LLVM_SPIRV)
message(FATAL_ERROR "`CA_LLVM_IS_DPCPP` cannot works with `CA_BUILD_LLVM_SPIRV`")
endif()

if(CMAKE_MAKE_PROGRAM MATCHES ninja)
ca_option(CA_PARALLEL_LINK_JOBS STRING
"Number of parallel link jobs (Ninja only)." "2")
Expand Down
1 change: 1 addition & 0 deletions llvm-spirv
Submodule llvm-spirv added at eb4cdb
10 changes: 9 additions & 1 deletion modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ if(NOT (OCK_IN_LLVM_TREE AND "llvm-spirv" IN_LIST LLVM_ENABLE_PROJECTS))
FetchContent_Declare(
SPIRV-Headers
GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Headers.git
GIT_TAG 1c6bb2743599e6eb6f37b2969acc0aef812e32e3
GIT_TAG 3f17b2af6784bfa2c5aa5dbb8e0e74a607dd8b3b
)
FetchContent_MakeAvailable(SPIRV-Headers)

Expand All @@ -65,6 +65,14 @@ if(NOT (OCK_IN_LLVM_TREE AND "llvm-spirv" IN_LIST LLVM_ENABLE_PROJECTS))
endif()
endif()

if(CA_BUILD_LLVM_SPIRV)
# TODO: latest llvm-spirv requires llvm 20.x
set(LLVM_EXTERNAL_SPIRV_HEADERS_SOURCE_DIR "${spirv-headers_SOURCE_DIR}")
set(LLVM_SPIRV_BUILD_EXTERNAL ON)
set(LLVM_SPIRV_INCLUDE_TESTS OFF)
add_subdirectory(${CMAKE_SOURCE_DIR}/llvm-spirv ${CMAKE_CURRENT_BINARY_DIR}/llvm-spirv)
endif()

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/mux)
# compiler/builtins requires capabilities from ComputeMux targets.
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/compiler)
Expand Down
4 changes: 4 additions & 0 deletions modules/compiler/multi_llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ target_include_directories(multi_llvm INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)

# No need to append interface libraries to MODULES_LIBRARIES variable

if(CA_LLVM_IS_DPCPP)
target_link_libraries(multi_llvm INTERFACE LLVMSYCLNativeCPUUtils)
endif()
14 changes: 13 additions & 1 deletion modules/compiler/source/base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ set(COMPILER_BASE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/include/base/software_division_pass.h
${CMAKE_CURRENT_SOURCE_DIR}/include/base/program_metadata.h
${CMAKE_CURRENT_SOURCE_DIR}/include/base/target.h
${CMAKE_CURRENT_SOURCE_DIR}/source/base_module_pass_machinery.cpp
${CMAKE_CURRENT_SOURCE_DIR}/source/base_module_pass_machinery.cpp
${CMAKE_CURRENT_SOURCE_DIR}/source/context.cpp
${CMAKE_CURRENT_SOURCE_DIR}/source/module.cpp
${CMAKE_CURRENT_SOURCE_DIR}/source/bit_shift_fixup_pass.cpp
Expand Down Expand Up @@ -118,6 +118,18 @@ target_link_libraries(compiler-base PUBLIC
"${LLVM_LIBS}"
)

if(CA_BUILD_LLVM_SPIRV)
target_compile_definitions(compiler-base PUBLIC CA_BUILD_LLVM_SPIRV)
target_include_directories(compiler-base SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/llvm-spirv/include")
target_link_libraries(compiler-base PUBLIC LLVMSPIRVLib)
endif()

if(CA_LLVM_IS_DPCPP)
target_compile_definitions(compiler-base PUBLIC CA_BUILD_LLVM_SPIRV)
target_include_directories(compiler-base SYSTEM PRIVATE "${CA_LLVM_INSTALL_DIR}/include/LLVMSPIRVLib")
target_link_libraries(compiler-base PUBLIC LLVMSPIRVLib)
endif()

target_compile_definitions(compiler-base PRIVATE
# Abacus builtins are only included as part of the .cpp files, so these
# defines can also be kept PRIVATE.
Expand Down
2 changes: 2 additions & 0 deletions modules/compiler/source/base/include/base/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class BaseContext : public Context {
compiler::utils::DebugLogging llvm_debug_passes =
compiler::utils::DebugLogging::None;

// use `llvm-spirv` instead of `spirv-ll`
bool using_llvm_spirv = false;
}; // class ContextImpl
/// @}
} // namespace compiler
Expand Down
3 changes: 3 additions & 0 deletions modules/compiler/source/base/include/base/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@ class BaseModule : public Module {
// between creating kernels and scheduled kernels those are locked directly.
std::mutex kernel_mutex;
std::map<std::string, std::unique_ptr<Kernel>> kernel_map;

// use `llvm-spirv` instead of `spirv-ll`
bool using_llvm_spirv = false;
}; // class Module

/// @}
Expand Down
41 changes: 41 additions & 0 deletions modules/compiler/source/base/source/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
#include <spirv-ll/context.h>
#include <spirv-ll/module.h>

#if defined(CA_BUILD_LLVM_SPIRV)
#include <LLVMSPIRVLib.h>
#include <LLVMSPIRVOpts.h>
#endif

#if !defined(NDEBUG) || defined(CA_ENABLE_LLVM_OPTIONS_IN_RELEASE)
#include <compiler/utils/llvm_global_mutex.h>
#include <llvm/Support/CommandLine.h>
Expand Down Expand Up @@ -55,6 +60,13 @@ BaseContext::BaseContext() {
}
});
#endif
#if defined(CA_BUILD_LLVM_SPIRV)
// TODO: make it default to use `llvm-spirv`
const auto *env = std::getenv("CA_USE_LLVM_SPIRV");
if (env && std::strcmp(env, "1") == 0) {
using_llvm_spirv = true;
}
#endif
}

BaseContext::~BaseContext() {}
Expand All @@ -71,6 +83,35 @@ bool BaseContext::isValidSPIRV(cargo::array_view<const uint32_t> code) {

cargo::expected<spirv::SpecializableConstantsMap, std::string>
BaseContext::getSpecializableConstants(cargo::array_view<const uint32_t> code) {
if (using_llvm_spirv) {
#if defined(CA_BUILD_LLVM_SPIRV)
std::istringstream iss(
std::string(reinterpret_cast<const char *>(code.data()),
code.size() * sizeof(uint32_t)),
std::ios_base::binary);
std::vector<llvm::SpecConstInfoTy> SpecConstInfo;
if (!llvm::getSpecConstInfo(iss, SpecConstInfo)) {
return cargo::make_unexpected("failed in getSpecConstInfo()");
}

spirv::SpecializableConstantsMap constants_map;
for (const auto &entry : SpecConstInfo) {
auto &constant = constants_map[entry.ID];
if (entry.Type == "i1") {
constant.constant_type = spirv::SpecializationType::BOOL;
} else if (entry.Type == "i32") {
constant.constant_type = spirv::SpecializationType::INT;
} else if (entry.Type == "f32") {
constant.constant_type = spirv::SpecializationType::FLOAT;
} else {
return cargo::make_unexpected("unknown `SpecializationType`");
}
constant.size_in_bits = entry.Size;
}
return {std::move(constants_map)};
#endif
}

auto specializable =
spirv_ll::Context{}.getSpecializableConstants({code.data(), code.size()});
if (!specializable) {
Expand Down
34 changes: 32 additions & 2 deletions modules/compiler/source/base/source/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@
#include <mux/mux.hpp>
#include <spirv-ll/module.h>

#if defined(CA_BUILD_LLVM_SPIRV)
#include <LLVMSPIRVLib.h>
#include <LLVMSPIRVOpts.h>
#endif

#include <cassert>
#include <cstdlib>
#include <fstream>
Expand Down Expand Up @@ -338,7 +343,15 @@ BaseModule::BaseModule(compiler::BaseTarget &target,
context(context),
state(ModuleState::NONE),
num_errors(num_errors),
log(log) {}
log(log) {
#if defined(CA_BUILD_LLVM_SPIRV)
// TODO: make it default to use `llvm-spirv`
const auto *env = std::getenv("CA_USE_LLVM_SPIRV");
if (env && std::strcmp(env, "1") == 0) {
using_llvm_spirv = true;
}
#endif
}

BaseModule::~BaseModule() {}

Expand Down Expand Up @@ -806,7 +819,24 @@ cargo::expected<spirv::ModuleInfo, Result> BaseModule::compileSPIRV(

spirv::ModuleInfo module_info;

{
if (using_llvm_spirv) {
#if defined(CA_BUILD_LLVM_SPIRV)
std::string err;
// TODO: can memcopy be reduced ?
std::istringstream iss(
std::string(reinterpret_cast<const char *>(buffer.data()),
buffer.size() * sizeof(uint32_t)),
std::ios_base::binary);

// TODO: use `SPIRV::TranslatorOpts` ?
llvm::readSpirv(target.getLLVMContext(), iss, (llvm::Module *&)llvm_module,
err);
if (!llvm_module) {
log.append(err + "\n");
return cargo::make_unexpected(Result::COMPILE_PROGRAM_FAILURE);
}
#endif
} else {
spirv_ll::Context spvContext(&target.getLLVMContext());

// Convert SPIR-V inputs to SPIRV-LL data structures.
Expand Down

0 comments on commit b123420

Please sign in to comment.