Skip to content

Commit

Permalink
Merge branch 'google:main' into GFXSW-22729
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexDemydenko authored Oct 7, 2024
2 parents 9b46613 + 40c590a commit 5bdac9d
Show file tree
Hide file tree
Showing 139 changed files with 2,347 additions and 385 deletions.
30 changes: 30 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ if (${EXTERNAL_LLVM} EQUAL 1)
if (NOT DEFINED CLSPV_LLVM_BINARY_DIR)
message(FATAL_ERROR "External LLVM requires CLSPV_LLVM_BINARY_DIR to be specified")
endif()
if (NOT DEFINED CLSPV_EXTERNAL_LIBCLC_DIR)
if (NOT DEFINED CLSPV_LIBCLC_SOURCE_DIR)
message(FATAL_ERROR "External LLVM requires CLSPV_LIBCLC_SOURCE_DIR to be specified")
endif()
if (NOT DEFINED CLSPV_LLVM_CMAKE_MODULES_DIR)
message(FATAL_ERROR "External LLVM requires CLSPV_LLVM_CMAKE_MODULES_DIR to be specified")
endif()
endif()
else()
# Setup to use the LLVM monorepo.
if (NOT DEFINED CLSPV_LLVM_SOURCE_DIR)
Expand All @@ -120,6 +128,16 @@ else()
set(CLSPV_CLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm/clang)
endif()

if (NOT DEFINED CLSPV_EXTERNAL_LIBCLC_DIR)
if (NOT DEFINED CLSPV_LIBCLC_SOURCE_DIR)
set(CLSPV_LIBCLC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm/libclc)
endif()

if (NOT DEFINED CLSPV_LLVM_CMAKE_MODULES_DIR)
set(CLSPV_LLVM_CMAKE_MODULES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm/cmake/Modules)
endif()
endif()

use_component(${CLSPV_LLVM_SOURCE_DIR})
use_component(${CLSPV_CLANG_SOURCE_DIR})

Expand All @@ -129,6 +147,7 @@ else()

# First tell LLVM where to find clang.
set(LLVM_EXTERNAL_CLANG_SOURCE_DIR ${CLSPV_CLANG_SOURCE_DIR})
set(LLVM_ENABLE_PROJECTS clang)

# Tell LLVM not to build any targets.
set(LLVM_TARGETS_TO_BUILD ""
Expand All @@ -142,6 +161,11 @@ else()
include(HandleLLVMOptions)
endif()

if (NOT DEFINED CLSPV_EXTERNAL_LIBCLC_DIR)
include(${CLSPV_LLVM_CMAKE_MODULES_DIR}/LLVMVersion.cmake)
set(LLVM_VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH})
endif()

set(CLSPV_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})

set(CLSPV_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include
Expand Down Expand Up @@ -176,6 +200,12 @@ elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror-unused-variable -Werror-switch")
endif()

if (NOT DEFINED CLSPV_EXTERNAL_LIBCLC_DIR)
set(LIBCLC_TARGETS_TO_BUILD clspv--;clspv64--)
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" CLSPV_LIBCLC_SUFFIX "${CLSPV_LIBCLC_SOURCE_DIR}")
add_subdirectory(${CLSPV_LIBCLC_SOURCE_DIR} EXCLUDE_FROM_ALL)
endif()

# Bring in our cmake folder
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/cmake)

Expand Down
48 changes: 13 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# clspv [![Discord Shield](https://discordapp.com/api/guilds/1002628585250631681/widget.png?style=shield)](https://discord.gg/xsVdjmhFM9)

**Clspv** is a prototype compiler for a subset of OpenCL C to Vulkan
compute shaders.
**Clspv** is a compiler for OpenCL C targeting Vulkan compute shaders.

It consists of:
* A set of LLVM Module passes to transform a dialect of LLVM IR into
Expand All @@ -10,7 +9,7 @@ It consists of:
OpenCL C into a Vulkan compute shader.

Clspv depends on external projects:
* Top-of-tree versions of [Clang][Clang] and [LLVM][LLVM]
* Top-of-tree versions of [Clang][Clang], [LLVM][LLVM] and [libclc][libclc]
* [SPIRV-Tools][SPIRV-Tools]
* [SPIRV-Headers][SPIRV-Headers]

Expand All @@ -28,12 +27,15 @@ Clspv is not an official Google product.

## Status

The compiler is an incomplete prototype, with many rough edges.
Clspv has passed OpenCL3.0 conformance with:
- [clvk][clvk] as the runtime driver ([submission 419](https://www.khronos.org/conformance/adopters/conformant-products/opencl#submission_419))
using the following tags:
- clvk: [khronos-submission-419](https://github.com/kpet/clvk/releases/tag/khronos-submission-419)
- clspv: [clvk-khronos-submission-419](https://github.com/google/clspv/releases/tag/clvk-khronos-submission-419)

The input language is a subset of OpenCL C version 1.2.
The [OpenCL C on Vulkan Specification](docs/OpenCLCOnVulkan.md)
describes the specific subset, and also the mapping into Vulkan compute
shaders.
The input language is OpenCL C version 1.2.
Read the [OpenCL C on Vulkan Specification](docs/OpenCLCOnVulkan.md) for more
information on the support and the mapping into Vulkan compute shaders.

## Examples

Expand All @@ -44,7 +46,7 @@ Compile a set of kernels into a SPIR-V binary module:
Emit the binary as a C initializer list, for easy embedding of a shader in
in a C or C++ program source:

clspv -mfmt=c foo.cl -o -
clspv --output-format=c foo.cl -o -

Predefine some preprocessor symbols:

Expand Down Expand Up @@ -128,35 +130,11 @@ Or if you are using Ninja:
ninja check-spirv

[Clang]: http://clang.llvm.org
[clvk]: https://github.com/kpet/clvk
[CMake-doc]: https://cmake.org/documentation
[CMake]: https://cmake.org
[libclc] https://libclc.llvm.org
[LLVM]: http://llvm.org
[Ninja]: https://ninja-build.org
[SPIRV-Headers]: https://github.com/KhronosGroup/SPIRV-Headers
[SPIRV-Tools]: https://github.com/KhronosGroup/SPIRV-Tools

## Builtin Libraries

Clspv includes two LLVM IR libraries (cmake/clspv--.bc, cmake/clspv64--.bc)
containing implementations of some OpenCL builtin functions, for the spir and
spir64 targets respectively. These files are distributed under the LLVM license
(included in LICENSE) as they are generated from the LLVM sub-project
[libclc](https://libclc.llvm.org). Refer to the source for the relevant
copyrights.

### Rebuilding the Library

#### Required Tools

You will need a pre-built version of [LLVM](https://github.com/llvm/llvm-project) for
your system, CMake, and (optionally) Ninja.

#### Build

To rebuild the library run the following commands:

cmake -GNinja <libclc dir> -DLIBCLC_TARGETS_TO_BUILD="clspv--;clspv64--" -DLLVM_CMAKE_DIR=</path/to/llvm_installation/lib/cmake/>
ninja

Copy the resulting `clspv--.bc` and `clspv64--.bc` files into the cmake/
directory and rebuild clspv.
18 changes: 14 additions & 4 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,10 @@ add_custom_command(
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS ${SPIRV_REFLECTION_INPUT_FILE} ${SPIRV_REFLECTION_PYTHON_FILE})

set(CLSPV_LIBRARY_INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/clspv--.bc)
set(CLSPV_LIBRARY_OUTPUT_FILE ${CLSPV_GENERATED_INCLUDES_DIR}/clspv_builtin_library.h)
set(CLSPV_LIBRARY_DATA_VAR_NAME clspv_builtin_library_data)
set(CLSPV_LIBRARY_SIZE_VAR_NAME clspv_builtin_library_size)

set(CLSPV64_LIBRARY_INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/clspv64--.bc)
set(CLSPV64_LIBRARY_OUTPUT_FILE ${CLSPV_GENERATED_INCLUDES_DIR}/clspv64_builtin_library.h)
set(CLSPV64_LIBRARY_DATA_VAR_NAME clspv64_builtin_library_data)
set(CLSPV64_LIBRARY_SIZE_VAR_NAME clspv64_builtin_library_size)
Expand All @@ -117,6 +115,18 @@ add_custom_target(clspv_builtin_library
add_custom_target(clspv64_builtin_library
DEPENDS ${CLSPV64_LIBRARY_OUTPUT_FILE})

if (NOT DEFINED CLSPV_EXTERNAL_LIBCLC_DIR)
set(CLSPV_LIBRARY_INPUT_FILE ${CLSPV_BINARY_DIR}/${CLSPV_LIBCLC_SUFFIX}/clspv--.bc)
set(CLSPV64_LIBRARY_INPUT_FILE ${CLSPV_BINARY_DIR}/${CLSPV_LIBCLC_SUFFIX}/clspv64--.bc)
set(CLSPV_LIBRARY_INPUT_DEP prepare-clspv--.bc)
set(CLSPV64_LIBRARY_INPUT_DEP prepare-clspv64--.bc)
else()
set(CLSPV_LIBRARY_INPUT_FILE ${CLSPV_EXTERNAL_LIBCLC_DIR}/clspv--.bc)
set(CLSPV64_LIBRARY_INPUT_FILE ${CLSPV_EXTERNAL_LIBCLC_DIR}/clspv64--.bc)
set(CLSPV_LIBRARY_INPUT_DEP ${CLSPV_LIBRARY_INPUT_FILE})
set(CLSPV64_LIBRARY_INPUT_DEP ${CLSPV64_LIBRARY_INPUT_FILE})
endif()

add_custom_command(
OUTPUT ${CLSPV_LIBRARY_OUTPUT_FILE}
COMMAND ${Python3_EXECUTABLE} ${BAKE_FILE_PYTHON_FILE}
Expand All @@ -125,7 +135,7 @@ add_custom_command(
--header-var=${CLSPV_LIBRARY_DATA_VAR_NAME}
--header-size=${CLSPV_LIBRARY_SIZE_VAR_NAME}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS ${BAKE_FILE_PYTHON_FILE} ${CLSPV_LIBRARY_INPUT_FILE}
DEPENDS ${BAKE_FILE_PYTHON_FILE} ${CLSPV_LIBRARY_INPUT_DEP} ${CLSPV_LIBRARY_INPUT_FILE}
)

add_custom_command(
Expand All @@ -136,5 +146,5 @@ add_custom_command(
--header-var=${CLSPV64_LIBRARY_DATA_VAR_NAME}
--header-size=${CLSPV64_LIBRARY_SIZE_VAR_NAME}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS ${BAKE_FILE_PYTHON_FILE} ${CLSPV64_LIBRARY_INPUT_FILE}
DEPENDS ${BAKE_FILE_PYTHON_FILE} ${CLSPV64_LIBRARY_INPUT_DEP} ${CLSPV64_LIBRARY_INPUT_FILE}
)
Binary file removed cmake/clspv--.bc
Binary file not shown.
Binary file removed cmake/clspv64--.bc
Binary file not shown.
6 changes: 3 additions & 3 deletions deps.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@
"subrepo" : "llvm/llvm-project",
"branch" : "main",
"subdir" : "third_party/llvm",
"commit" : "0f1847cb2c5462a09d65a9b5ac24904ac3c15a0f"
"commit" : "125aa10b3d645bd26523a1bc321bb2e6b1cf04e1"
},
{
"name" : "SPIRV-Headers",
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Headers",
"branch" : "main",
"subdir" : "third_party/SPIRV-Headers",
"commit" : "4183b260f4cccae52a89efdfcdd43c4897989f42"
"commit" : "4f7b471f1a66b6d06462cd4ba57628cc0cd087d7"
},
{
"name" : "SPIRV-Tools",
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Tools",
"branch" : "main",
"subdir" : "third_party/SPIRV-Tools",
"commit" : "a996591b1c67e789e88e99ae3881272f5fc47374"
"commit" : "02470f606fe1571de808cb773d8c521ab201aaff"
}
]
}
73 changes: 22 additions & 51 deletions docs/OpenCLCOnVulkan.md
Original file line number Diff line number Diff line change
Expand Up @@ -666,12 +666,6 @@ The OpenCL C work-item functions map to Vulkan SPIR-V as follows:
Some OpenCL C language features that have no expressible equivalents in Vulkan's
variant of SPIR-V are restricted.

### Kernels

OpenCL C language kernels **must not** be called from other kernels.

Pointers of type `half` **must not** be used as kernel arguments.

### Types
#### Boolean

Expand All @@ -691,10 +685,6 @@ can be used. To disable general support for these types, use `-int8=0`.

The `double`, `double2`, `double3` and `double4` types **must not** be used.

#### Events

The `event_t` type **must not** be used.

#### Pointers

Pointers are an abstract type - they have no known compile-time size.
Expand Down Expand Up @@ -730,11 +720,6 @@ some builtin functions, clspv also provides the `--cl-native-math` option. This
option goes beyond fast-relaxed math and provides no precision guarantees
(similar to the native_ functions in OpenCL).

#### Atomic Functions

The `atomic_xchg()` built-in function that takes a floating-point argument
**must not** be used.

##### OpenCL 2.0 Atomic Functions

The OpenCL 2.0 atomic functions are supported with the following exceptions:
Expand Down Expand Up @@ -887,51 +872,37 @@ These extension built-in functions are not supported:

### Numerical Compliance

Clspv is not able to reach full accuracy requirements on the supported builtin
functions in all cases. Instead, currently, it is able to meet the requirements
tested by OpenCL CTS under relaxed precision requirements. In order to achieve
this goal, some functions are implemented using the GLSL.std.450 extended or
core instructions, some are implemented in the builtin library and some are
emulated by the compiler.

Note: Clspv has been tested against five Vulkan implementations from different
vendors and is able to achieve the relaxed accuracy requirements broadly.
Clspv is not able to reach full accuracy requirements on all builtin functions
using the GLSL.std.450 extended or core instructions or compiler emulation.
In order to achieve this goal, some functions are implemented using a builtin
library (from [libclc](https://libclc.llvm.org/)).

#### Implementations Using Core and Extended Instructions
#### Implementations Using Builtin Library

`add`, `subtract`, `divide`, `multiply`, `assignment`, `not`, `acos`, `asin`,
`ceil`, `cos`, `cosh`, `exp`, `exp2`, `exp10`, `fabs`, `floor`, `fmax`, `fmin`,
`log`, `log2`, `log10`, `mad`, `pow`, `powr`, `rint`, `rsqrt`, `sin`, `sinh`,
`tan`, `trunc`, `half_cos`, `half_exp`, `half_exp2`, `half_exp10`, `half_log`,
`half_log2`, `half_log10`, `half_powr`, `half_rsqrt`, `half_sin`, `half_tan`,
`clamp`, `degrees`, `mix`, `radians`, `sign`, `smoothstep`, `step`, `cross`,
`dot`, `normalize`, `fast_distance`, `fast_length`, `fast_normalize`.
Find the latest list in clspv's libclc [SOURCES file](https://github.com/llvm/llvm-project/blob/main/libclc/clspv/lib/SOURCES).

#### Implementations Using Builtin Library
Here is the list as of March 2024:

`acosh`, `asinh`, `atanh`, `cbrt`, `erfc`, `erf`, `fma`, `fmod`, `fract`,
`frexp`, `hypot`, `ilogb`, `ldexp`, `lgamma`, `lgamma_r`, `logb`, `maxmag`,
`modf`, `nan`, `nextafter`, `remainder`, `remquo`, `rootn`, `sqrt`, `tanh`,
`tgamma`, `half_divide`, `half_recip`, `half_sqrt`, `distance`, `length`,
`atan`, `atan2pi`, `atanpi`, `atan2`.
`acos`, `acosh`, `acospi`, `asin`, `asinh`, `asinh`, `asinpi`, `atan`, `atan2`,
`atan2pi`, `atanh`, `atanpi`, `cbrt`, `cos`, `cosh`, `cospi`, `distance`,
`erf`, `erfc`, `exp`, `exp10`, `exp2`, `exp_helper`, `expm1`, `fdim`, `fma`,
`fmod`, `fract`, `frexp`, `half_cos`, `half_divide`, `half_exp`, `half_exp10`,
`half_exp2`, `half_log`, `half_log10`, `half_log2`, `half_powr`, `half_recip`,
`half_sin`, `half_sqrt`, `half_tan`, `hypot`, `ilogb`, `ldexp`, `length`,
`lgamma`, `lgamma_r`, `log`, `log10`, `log1p`, `log2`, `logb`, `maxmag`,
`minmag`, `modf`, `nan`, `nextafter`, `pow`, `pown`, `powr`, `remainder`,
`remquo`, `rootn`, `sin`, `sincos`, `sincos_helpers`, `sinh`, `sinpi`,
`tables`, `tan`, `tanh`, `tanpi`, `tanpi`, `tgamma`, `vstore_half`.

Note: `fma` has a very high runtime cost unless compiling with
`-cl-native-math`. Its accuracy requirements are not relaxed by
`-cl-fast-relaxed-math` and the library implementation emulates it using
integers.

Note: `acosh`, `asinh`, `atanh`, `atan`, `atan2`, `atanpi` and `atan2pi`,
`fma`, `fmod`, `fract`, `frexp`, `ldexp`, `rsqrt`, `half_sqrt`, `sqrt`, `tanh`,
`distance`, and `length` are all implemented using core or extended
instructions when compiling with `-cl-native-math`.

#### Implementations Using Emulation

`acospi`, `asinpi`, `copysign`, `cospi`, `expm1`, `fdim`, `log1p`, `pown`,
`round`, `sincos`, `sinpi`, `tanpi`.

#### Known Conformance Issues
Note: if a builtin also has a core or extended instructions or an emulated
implementations, clspv can be force to use it with `-cl-native-math` or
`-use-native-builtins`.

* `frexp` fails using Swiftshader as an implementation due to an internal error.
* `ldexp` and `rsqrt` fail to meet accuracy requirements on some Adreno GPUs.
#### Implementations Using core or extended instructions or emulation

The list can be found in [ReplaceOpenCLBuiltinPass.cpp](https://github.com/google/clspv/blob/main/lib/ReplaceOpenCLBuiltinPass.cpp)
18 changes: 13 additions & 5 deletions include/clspv/FeatureMacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,19 @@ enum class FeatureMacro {
__opencl_c_atomic_scope_device,
__opencl_c_atomic_scope_all_devices,
__opencl_c_generic_address_space,
__opencl_c_work_group_collective_functions
__opencl_c_work_group_collective_functions,
// dot product
__opencl_c_integer_dot_product_input_4x8bit,
__opencl_c_integer_dot_product_input_4x8bit_packed,
};

#define FeatureStr(f) std::make_pair(FeatureMacro::f, #f)
constexpr std::array<std::pair<FeatureMacro, const char *>, 15>
constexpr std::array<std::pair<FeatureMacro, const char *>, 17>
FeatureMacroList{
FeatureStr(__opencl_c_3d_image_writes),
FeatureStr(__opencl_c_atomic_order_acq_rel),
FeatureStr(__opencl_c_fp64), FeatureStr(__opencl_c_images),
FeatureStr(__opencl_c_fp64),
FeatureStr(__opencl_c_images),
FeatureStr(__opencl_c_generic_address_space),
FeatureStr(__opencl_c_subgroups),
// following items are always enabled by clang
Expand All @@ -63,8 +67,12 @@ constexpr std::array<std::pair<FeatureMacro, const char *>, 15>
FeatureStr(__opencl_c_atomic_scope_all_devices),
FeatureStr(__opencl_c_work_group_collective_functions),
// following items cannot be enabled so are automatically disabled
FeatureStr(__opencl_c_device_enqueue), FeatureStr(__opencl_c_pipes),
FeatureStr(__opencl_c_program_scope_global_variables)};
FeatureStr(__opencl_c_device_enqueue),
FeatureStr(__opencl_c_pipes),
FeatureStr(__opencl_c_program_scope_global_variables),
FeatureStr(__opencl_c_integer_dot_product_input_4x8bit),
FeatureStr(__opencl_c_integer_dot_product_input_4x8bit_packed),
};
#undef FeatureStr

FeatureMacro FeatureMacroLookup(const std::string &name);
Expand Down
Loading

0 comments on commit 5bdac9d

Please sign in to comment.