Skip to content
Open
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
63 changes: 63 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,70 @@
# This project is only buildable as a subproject of LLVM.
cmake_minimum_required(VERSION 3.31.0)

project(OffloadTest)

# If we are not building as a part of LLVM, build Clang as an
# standalone project, using LLVM as an external library:
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(OFFLOADTEST_BUILT_STANDALONE TRUE)
endif()

if (OFFLOADTEST_BUILT_STANDALONE)
find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}")

include(AddLLVM)

find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION} REQUIRED
COMPONENTS Interpreter)

set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)

# They are used as destination of target generators.
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
if(WIN32 OR CYGWIN)
# DLL platform -- put DLLs into bin.
set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
else()
set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
endif()

set(LLVM_TOOLS_DIR ${LLVM_TOOLS_BINARY_DIR})
include_directories(${LLVM_INCLUDE_DIRS})
link_directories("${LLVM_LIBRARY_DIR}")

if (NOT LLVM_MAIN_SRC_DIR OR NOT EXISTS "${LLVM_MAIN_SRC_DIR}")
message(FATAL_ERROR "LLVM_MAIN_SRC_DIR is not set or invalid. Please set it to the root of the LLVM source tree.")
endif()

# Seek installed Lit.
find_program(LLVM_LIT
NAMES llvm-lit lit.py lit
PATHS "${LLVM_MAIN_SRC_DIR}/utils/lit"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we add an if guard to verify that this main_src variable is set correctly?

DOC "Path to lit.py")

if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
# Note: path not really used, except for checking if lit was found
if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/llvm-lit)
add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit utils/llvm-lit)
endif()
endif()

if (NOT LLVM_THIRD_PARTY_DIR)
set(LLVM_THIRD_PARTY_DIR "${LLVM_MAIN_SRC_DIR}/../third-party")
endif()
if (NOT TARGET llvm_gtest)
add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest ${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest)
endif()
endif()

# Setting this allows the offload-test-suite to have a separate tools directory
# from the llvm-provided tools.
set(OFFLOADTEST_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})

# Add path for custom modules
list(INSERT CMAKE_MODULE_PATH 0
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
Expand Down
39 changes: 39 additions & 0 deletions cmake/caches/OffloadDistribution.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Including the native target is important because some of LLVM's tests fail if
# you don't.
set(LLVM_TARGETS_TO_BUILD "Native;SPIRV" CACHE STRING "")

# Include the DirectX target for DXIL code generation.
set(LLVM_EXPERIMENTAL_TARGETS_TO_BUILD "DirectX" CACHE STRING "")

set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra" CACHE STRING "")

set(CLANG_ENABLE_HLSL On CACHE BOOL "")

set(LLVM_INSTALL_UTILS ON CACHE BOOL "")
set(LLVM_INSTALL_TOOLCHAIN_ONLY OFF CACHE BOOL "")
set(LLVM_DISTRIBUTION_COMPONENTS
clang
hlsl-resource-headers
FileCheck
split-file
obj2yaml
not
llvm-headers
LLVMSupport
LLVMDemangle # Dependency of LLVMSupport
LLVMObject
# Dependencies of LLVMObject
LLVMBitReader
LLVMBitstreamReader # Dependency of LLVMBitReader
LLVMCore
LLVMRemarks # Dependency of LLVMCore
LLVMMC
LLVMDebugInfoDWARFLowLevel # Dependency of LLVMMC
LLVMIRReader
LLVMAsmParser # Dependency of LLVMIRReader
LLVMBinaryFormat
LLVMMCParser
LLVMTargetParser
LLVMTextAPI
cmake-exports
CACHE STRING "")
39 changes: 39 additions & 0 deletions cmake/caches/StandaloneDistribution.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Including the native target is important because some of LLVM's tests fail if
# you don't.
set(LLVM_TARGETS_TO_BUILD "Native;SPIRV" CACHE STRING "")

# Include the DirectX target for DXIL code generation.
set(LLVM_EXPERIMENTAL_TARGETS_TO_BUILD "DirectX" CACHE STRING "")

set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra" CACHE STRING "")

set(CLANG_ENABLE_HLSL On CACHE BOOL "")

set(LLVM_INSTALL_UTILS ON CACHE BOOL "")
set(LLVM_INSTALL_TOOLCHAIN_ONLY OFF CACHE BOOL "")
set(LLVM_DISTRIBUTION_COMPONENTS
clang
hlsl-resource-headers
FileCheck
split-file
obj2yaml
not
llvm-headers
LLVMSupport
LLVMDemangle # Dependency of LLVMSupport
LLVMObject
# Dependencies of LLVMObject
LLVMBitReader
LLVMBitstreamReader # Dependency of LLVMBitReader
LLVMCore
LLVMRemarks # Dependency of LLVMCore
LLVMMC
LLVMDebugInfoDWARFLowLevel # Dependency of LLVMMC
LLVMIRReader
LLVMAsmParser # Dependency of LLVMIRReader
LLVMBinaryFormat
LLVMMCParser
LLVMTargetParser
LLVMTextAPI
cmake-exports
CACHE STRING "")
41 changes: 41 additions & 0 deletions docs/offload-distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,44 @@ The reusable workflow `.github/workflows/build-and-test-callable.yaml`
implements this flow when invoked with `SplitBuild=true`. The build job
produces two artifacts (`build-<sku>-<target>` and `dxc-<sku>-<target>`)
and the test job consumes both.

## Standalone Build Distribution

An alternate approach for separating the build and test flow in the offload test
suite is using the "standalone" build mode. With this build flow, LLVM (and
optionally Clang) are built separately from the offload-test suite, and the
offload-test-suite is configured as the top-level CMake entry.

A sample configuration for this flow is provided in the
`cmake/caches/StandaloneDistribution.cmake` cache script. In this build
configuration, the LLVM build contributes Clang, the llvm testing tools, and the
subset of LLVM component libraries that the offload-test-suite's tools depend
on.

Using this flow LLVM and Clang are configured using a command like:

```
cmake -C <offload test>/cmake/caches/StandaloneDistribution.cmake \
-DCMAKE_INSTALL_PREFIX=<path to install to> \
<other cmake options> <path to llvm>
ninja install-distribution
```

Then configure and build the offload test suite with a command like so:

```
cmake -DCMAKE_PREFIX_PATH=<path to llvm install>/lib/cmake/llvm \
-DLLVM_MAIN_SRC_DIR=<path to llvm-project>/llvm \
-DDXC_DIR=<path to folder containing dxc/dxv> \
-DOFFLOAD_TEST_TEST_CLANG=On \
-DGOLDENIMAGE_DIR=<path to images> \
<other cmake options> <path to ofload test suite>
ninja check-hlsl
```

In this configuration the offload-test-suite will build its tools against the
already built LLVM libraries which dramatically reduces build time. This
configuration does still require a checkout of the LLVM source tree to pull LIT
and the third-party unit testing libraries. If clone/checkout time or disk space
is a concern this could be a sparse checkout or future changes could allow this
to use LIT from pip and a stock googletest framework.
File renamed without changes.
3 changes: 1 addition & 2 deletions lib/API/DX/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "API/Encoder.h"
#include "API/FormatConversion.h"
#include "DXFeatures.h"
#include "Support/OffloadMigration.h"
#include "Support/Pipeline.h"
#include "Support/WinError.h"

Expand All @@ -50,8 +51,6 @@

#include "../Util.h"

#include "../Support/OffloadMigration.h"

#include <atomic>
#include <codecvt>
#include <locale>
Expand Down
2 changes: 1 addition & 1 deletion lib/Support/OffloadMigration.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "OffloadMigration.h"
#include "Support/OffloadMigration.h"

#include "API/Device.h"
#include "API/FormatConversion.h"
Expand Down
2 changes: 1 addition & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ list(APPEND OFFLOADTEST_DEPS
obj2yaml
not)

if (OFFLOADTEST_TEST_CLANG)
if (OFFLOADTEST_TEST_CLANG AND NOT OFFLOADTEST_BUILT_STANDALONE)
list(APPEND OFFLOADTEST_DEPS clang)
endif()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I should note that the reason I made this conditional even though it doesn't strictly need to be (because of exported targets being wonderful) is because I wanted to break the connection between OFFLOADTEST_TEST_CLANG and the existence of the Clang target. That way we could build the offload-test-suite, LLVM and Clang all separately if we wanted and just point to different build directories for different bits.


Expand Down
6 changes: 4 additions & 2 deletions test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
# Tweak the PATH to include the tools dir.
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)

tool_dirs = [config.llvm_tools_dir, config.offloadtest_tools_dir]


llvm_config.with_system_environment(
[
Expand Down Expand Up @@ -329,9 +331,9 @@ def setDeviceFeatures(config, device, compiler):

tools.append(ToolSubst("obj2yaml", FindTool("obj2yaml")))

llvm_config.add_tool_substitutions(tools, config.llvm_tools_dir)
llvm_config.add_tool_substitutions(tools, tool_dirs)

api_query = os.path.join(config.llvm_tools_dir, "api-query")
api_query = os.path.join(config.offloadtest_tools_dir, "api-query")
query_string = subprocess.check_output(api_query)
devices = yaml.safe_load(query_string)
target_device = None
Expand Down
1 change: 1 addition & 0 deletions test/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import sys

config.offloadtest_obj_root = path(r"@OFFLOADTEST_BINARY_DIR@")
config.offloadtest_src_root = path(r"@OFFLOADTEST_TEST_ROOT@")
config.offloadtest_tools_dir = lit_config.substitute(path(r"@OFFLOADTEST_TOOLS_DIR@"))
config.llvm_tools_dir = lit_config.substitute(path(r"@LLVM_TOOLS_DIR@"))
config.offloadtest_dxc = '"' + path(r"@DXC_EXECUTABLE@") + '"'
config.offloadtest_supports_spirv = @SUPPORTS_SPIRV@
Expand Down
1 change: 1 addition & 0 deletions utils/configure-test-suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ def main():
# layout it's the install share dir.
"OFFLOADTEST_TEST_ROOT": str(test_src_root.parent),
"LLVM_TOOLS_DIR": str(bin_dir),
"OFFLOADTEST_TOOLS_DIR": str(bin_dir),
"DXC_EXECUTABLE": str(dxc_path) if dxc_path is not None else "",
"SUPPORTS_SPIRV": "True" if vk else "False",
"FORCE_CLANG": "True" if clang else "False",
Expand Down
Loading