Skip to content
Closed
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
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
cc_library(
name = "spirv_llvm_translator",
srcs = glob([
"lib/SPIRV/libSPIRV/*.cpp",
"lib/SPIRV/libSPIRV/*.hpp",
"lib/SPIRV/libSPIRV/*.h",
"lib/SPIRV/Mangler/*.cpp",
"lib/SPIRV/Mangler/*.h",
"lib/SPIRV/*.cpp",
"lib/SPIRV/*.hpp",
"lib/SPIRV/*.h",
]),
hdrs = glob(["include/*"]),
includes = [
"include/",
"lib/SPIRV/",
"lib/SPIRV/Mangler/",
"lib/SPIRV/libSPIRV/",
],
visibility = ["//visibility:public"],
deps = [
"@llvm-project//llvm:Analysis",
"@llvm-project//llvm:BitWriter",
"@llvm-project//llvm:CodeGen",
"@llvm-project//llvm:Core",
"@llvm-project//llvm:Demangle",
"@llvm-project//llvm:IRReader",
"@llvm-project//llvm:Linker",
"@llvm-project//llvm:Passes",
"@llvm-project//llvm:Support",
"@llvm-project//llvm:TransformUtils",
"@spirv_headers//:spirv_cpp_headers",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
diff --git a/lib/SPIRV/SPIRVInternal.h b/lib/SPIRV/SPIRVInternal.h
index a828add8..924e13b4 100644

Spir backend uses different addrspace representations link with nvptx backend link.
We reorder the enum value here so that we can make XLA LLVM codegen simple(avoiding
changing addrspace based on device backend everywhere)

--- a/lib/SPIRV/SPIRVInternal.h
+++ b/lib/SPIRV/SPIRVInternal.h
@@ -179,11 +179,12 @@ typedef SPIRVMap<Op, Op, IntBoolOpMapId> IntBoolOpMap;
"-v512:512:512-v1024:1024:1024"

enum SPIRAddressSpace {
- SPIRAS_Private,
+ SPIRAS_Generic,
SPIRAS_Global,
- SPIRAS_Constant,
+ SPIRAS_Internal,
SPIRAS_Local,
- SPIRAS_Generic,
+ SPIRAS_Constant,
+ SPIRAS_Private,
Comment on lines +14 to +22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, why do we need to reorder them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spir backend uses different addrspace representations link with nvptx backend link. We reorder the enum value here so that we can make xla llvm codegen simple(avoiding changing addrspace based on device backend everywhere)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is useful context for people who are unfamiliar with the backend.

Could you please add this explanation in this patch file (between line 2 and 3)? I believe the patch tool will ignore anything above the --- a/lib/SPIRV/SPIRVInternal.h line. E.g.,

diff --git a/lib/SPIRV/SPIRVInternal.h b/lib/SPIRV/SPIRVInternal.h
index a828add8..924e13b4 100644

<Explanation here>

--- a/lib/SPIRV/SPIRVInternal.h

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

SPIRAS_GlobalDevice,
SPIRAS_GlobalHost,
SPIRAS_Input,
16 changes: 16 additions & 0 deletions third_party/tsl/workspace2.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,22 @@ def _tf_repositories():
urls = tf_mirror_urls("https://github.com/google/glog/archive/refs/tags/v0.4.0.tar.gz"),
)

tf_http_archive(
name = "spirv_headers",
sha256 = "11d835c60297b26532c05c3f3b581ba7a2787b5ae7399e94f72c392169216f11",
strip_prefix = "SPIRV-Headers-b73e168ca5e123dcf3dea8a34b19a5130f421ae1",
urls = tf_mirror_urls("https://github.com/KhronosGroup/SPIRV-Headers/archive/b73e168ca5e123dcf3dea8a34b19a5130f421ae1.tar.gz"),
)

tf_http_archive(
name = "spirv_llvm_translator",
sha256 = "d499769f4fd1e0ce9d4dbd3622ee7e3e641b5623dcdf811521e3e7c0bdb1e6c2",
strip_prefix = "SPIRV-LLVM-Translator-dad1f0eaab8047a4f73c50ed5f3d1694b78aae97",
build_file = "//third_party/spirv_llvm_translator:spirv_llvm_translator.BUILD",
patch_file = ["//third_party/spirv_llvm_translator:spirv_llvm_translator.patch"],
urls = tf_mirror_urls("https://github.com/KhronosGroup/SPIRV-LLVM-Translator/archive/dad1f0eaab8047a4f73c50ed5f3d1694b78aae97.tar.gz"),
)

# buildifier: disable=unnamed-macro
def workspace():
# Check the bazel version before executing any repository rules, in case
Expand Down
6 changes: 6 additions & 0 deletions xla/service/gpu/llvm_gpu_backend/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ load(
"@local_config_rocm//rocm:build_defs.bzl",
"if_rocm_is_configured",
)
load(
"@local_config_sycl//sycl:build_defs.bzl",
"if_sycl_is_configured",
)
load(
"@tsl//tsl/platform/default:cuda_build_defs.bzl",
"if_cuda_is_configured",
Expand Down Expand Up @@ -88,6 +92,8 @@ cc_library(
"@local_config_rocm//rocm:rocm_headers",
"@llvm-project//llvm:AMDGPUCodeGen",
"@llvm-project//llvm:AMDGPUAsmParser",
]) + if_sycl_is_configured([
"@spirv_llvm_translator//:spirv_llvm_translator",
]),
)

Expand Down
99 changes: 98 additions & 1 deletion xla/service/gpu/llvm_gpu_backend/gpu_backend_lib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ limitations under the License.
#include "xla/stream_executor/cuda/cuda_asm_compiler.h"
#endif

#if TENSORFLOW_USE_SYCL
#include "LLVMSPIRVLib.h"
#include "LLVMSPIRVOpts.h"
#endif // TENSORFLOW_USE_SYCL

namespace xla {
namespace gpu {
namespace {
Expand Down Expand Up @@ -452,7 +457,9 @@ absl::Status LinkAndOptimizeModule(
llvm::CGSCCAnalysisManager cgam;
llvm::ModuleAnalysisManager mam;

fam.registerPass([&] { return target_machine->getTargetIRAnalysis(); });
if (target_machine) {
fam.registerPass([&] { return target_machine->getTargetIRAnalysis(); });
}

llvm::PipelineTuningOptions pto;
pto.SLPVectorization = true;
Expand Down Expand Up @@ -1132,5 +1139,95 @@ absl::StatusOr<std::vector<uint8_t>> CompileToHsaco(

} // namespace amdgpu

namespace {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please add a blank line after this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


std::unique_ptr<llvm::TargetMachine> SPIRGetTargetMachine(
llvm::Triple target_triple, se::GpuComputeCapability gpu_version,
const DebugOptions& debug_options) {
return nullptr;
}

absl::Status SPIRTargetModuleLinker(
llvm::Module* module, se::GpuComputeCapability gpu_version,
const DebugOptions& debug_options,
const std::string& device_bitcode_dir_path) {
return absl::OkStatus();
}

absl::StatusOr<std::string> EmitModuleToSpir(
llvm::Module* module, se::GpuComputeCapability gpu_version,
const DebugOptions& debug_options) {
#if TENSORFLOW_USE_SYCL
SPIRV::TranslatorOpts::ExtensionsStatusMap ExtensionsStatus;
SPIRV::TranslatorOpts opts(SPIRV::VersionNumber::MaximumVersion,
ExtensionsStatus);
opts.enableAllExtensions(); // enable all SPIR-V extension first

std::ostringstream oss;
std::string err;
bool success = llvm::writeSpirv(module, opts, oss, err);
if (!success) {
return xla::Internal("Fails to convert LLVM as SPIR-V: %s", err);
}
return oss.str();
#else
return absl::UnimplementedError("Not implemented for SYCL");
#endif
}

void SPIRBackendInit(const DebugOptions& debug_options) {
FeedLLVMWithFlags({
"-slp-vectorize-hor=false",
"-slp-min-reg-size=64",
"-slp-max-reg-size=64",
});

llvm_ir::InitializeLLVMCommandLineOptions(
debug_options.xla_backend_extra_options());

llvm::PassRegistry* registry = llvm::PassRegistry::getPassRegistry();
InitializePasses(registry);
}

} // namespace
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please add a blank line before this.
Please do the same for namespace spir.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


namespace spir {

absl::StatusOr<std::vector<uint8_t>> CompileToSpir(
llvm::Module* module, se::GpuComputeCapability gpu_version,
const DebugOptions& debug_options) {
std::string libdevice_dir_path;
static absl::once_flag backend_init_flag;
absl::call_once(backend_init_flag, SPIRBackendInit, debug_options);

std::string spir;
{
XLA_SCOPED_LOGGING_TIMER("Compile module " + module->getName().str());

// If the module has no functions or globals, there's nothing to compile.
if (module->empty() && module->global_empty()) {
VLOG(2) << "Module '" << module->getName().str()
<< "' is empty. Skipping compilation.";
return std::vector<uint8_t>();
}

llvm::Triple default_target_triple("spir64-unknown-unknown");
std::unique_ptr<llvm::TargetMachine> target_machine =
SPIRGetTargetMachine(default_target_triple, gpu_version, debug_options);

TF_RETURN_IF_ERROR(LinkAndOptimizeModule(
module, gpu_version, debug_options, libdevice_dir_path,
SPIRTargetModuleLinker, default_target_triple, target_machine.get(),
kDefaultInlineThreshold));

// Lower optimized LLVM module to SPIR.
TF_ASSIGN_OR_RETURN(spir,
EmitModuleToSpir(module, gpu_version, debug_options));
}
return std::vector<uint8_t>(spir.begin(), spir.end());
}

} // namespace spir

} // namespace gpu
} // namespace xla
7 changes: 7 additions & 0 deletions xla/service/gpu/llvm_gpu_backend/gpu_backend_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ absl::StatusOr<std::vector<uint8_t>> CompileToHsaco(
const std::string& module_config_cache_key);
} // namespace amdgpu

namespace spir {
// Compiles the argument module and returns it.
absl::StatusOr<std::vector<uint8_t>> CompileToSpir(
llvm::Module* module, se::GpuComputeCapability gpu_version,
const DebugOptions& debug_options);
} // namespace spir

} // namespace gpu
} // namespace xla

Expand Down