Skip to content

Commit

Permalink
Merge pull request #1 from occ-ai/roy.add_clblast_build
Browse files Browse the repository at this point in the history
Add support for CLBlast library and clbast::clblast target
  • Loading branch information
royshil authored Apr 17, 2024
2 parents a8edb95 + 025fd77 commit 4f88391
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 24 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
matrix:
config:
- "Release"
cublas: [cpu, 12.2.0, 11.8.0]
cublas: [cpu, 12.2.0, 11.8.0, clblast]

steps:
- name: "Get version"
Expand All @@ -110,14 +110,14 @@ jobs:
uses: "actions/checkout@v4"

- name: Install CUDA Toolkit
if: ${{ matrix.cublas != 'cpu' }}
if: ${{ matrix.cublas != 'cpu' && matrix.cublas != 'clblast' }}
id: cuda-toolkit
uses: Jimver/[email protected]
with:
cuda: '${{ matrix.cublas }}'

- name: Set CUDA_TOOLKIT_ROOT_DIR if CUDA is installed
if: ${{ matrix.cublas != 'cpu' }}
if: ${{ matrix.cublas != 'cpu' && matrix.cublas != 'clblast' }}
run: |
"CUDA_TOOLKIT_ROOT_DIR=$env:CUDA_PATH" >> $env:GITHUB_ENV
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
release/
100 changes: 81 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ cmake_minimum_required(VERSION 3.21)
project(Whispercpp_prebuilt)

include(ExternalProject)
include(FetchContent)

option(WHISPERCPP_WITH_CUDA "Build Whisper with CUDA support" OFF)
option(WHISPERCPP_WITH_CLBLAST "Build Whisper with CLBlast support" OFF)

set(CMAKE_OSX_ARCHITECTURES_ "$ENV{MACOS_ARCH}")

set(Whispercpp_Build_GIT_TAG "f22d27a385d34b1e544031efe8aa2e3d73922791")
set(Whispercpp_Build_GIT_TAG "v1.5.5")

if(${CMAKE_BUILD_TYPE} STREQUAL Release OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo)
set(Whispercpp_BUILD_TYPE Release)
Expand Down Expand Up @@ -49,30 +51,69 @@ if(WIN32)
set(WHISPER_ADDITIONAL_ENV "CUDAToolkit_ROOT=${CUDA_TOOLKIT_ROOT_DIR}")
set(WHISPER_ADDITIONAL_CMAKE_ARGS -DWHISPER_BLAS=OFF -DWHISPER_CUBLAS=ON -DWHISPER_OPENBLAS=OFF
-DCMAKE_GENERATOR_TOOLSET=cuda=${CUDA_TOOLKIT_ROOT_DIR})
elseif(WHISPERCPP_WITH_CLBLAST)
# Build with CLBlast
set(CLBLAST_URL "https://github.com/CNugteren/CLBlast/releases/download/1.6.2/CLBlast-1.6.2-windows-x64.zip")
set(CLBLAST_SHA256 "09776AFACF89A960C59A0F072FE8595D8F49593B343E25C901F357DAC680018F")
FetchContent_Declare(
CLBlast
DOWNLOAD_EXTRACT_TIMESTAMP true
URL ${CLBLAST_URL}
URL_HASH SHA256=${CLBLAST_SHA256})
FetchContent_MakeAvailable(CLBlast)
find_program(SEVEN_ZIP_EXECUTABLE 7z)
if(NOT SEVEN_ZIP_EXECUTABLE)
message(FATAL_ERROR "7z executable not found!")
endif()
execute_process(
COMMAND ${SEVEN_ZIP_EXECUTABLE} x -y ${clblast_SOURCE_DIR}/CLBlast-1.6.2-windows-x64.7z
WORKING_DIRECTORY ${clblast_SOURCE_DIR}
RESULT_VARIABLE SEVEN_ZIP_RESULT
OUTPUT_QUIET
)
if(NOT SEVEN_ZIP_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to extract CLBlast: ${SEVEN_ZIP_ERROR}")
endif()
set(clblast_SOURCE_DIR ${clblast_SOURCE_DIR}/CLBlast-1.6.2-windows-x64)

set(OPENCL_SDK_URL "https://github.com/KhronosGroup/OpenCL-SDK/releases/download/v2023.12.14/OpenCL-SDK-v2023.12.14-Win-x64.zip")
set(OPENCL_SDK_SHA256 "4C49F37A97B1B6D191B076C1E5D095B180E44BDC72DB32EC8B9748FF6ECFAEB6")
FetchContent_Declare(
OpenCL_SDK
DOWNLOAD_EXTRACT_TIMESTAMP true
URL ${OPENCL_SDK_URL}
URL_HASH SHA256=${OPENCL_SDK_SHA256})
FetchContent_MakeAvailable(OpenCL_SDK)

message(STATUS "clblast_SOURCE_DIR: ${clblast_SOURCE_DIR}")
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
find_package(CLBlast REQUIRED)

set(WHISPER_ADDITIONAL_CMAKE_ARGS -DWHISPER_BLAS=OFF -DWHISPER_CUBLAS=OFF -DWHISPER_OPENBLAS=OFF
-DWHISPER_CLBLAST=ON -Dclblast_SOURCE_DIR=${clblast_SOURCE_DIR} -Dopencl_sdk_SOURCE_DIR=${opencl_sdk_SOURCE_DIR})
else()
# Build with OpenBLAS
set(OpenBLAS_URL "https://github.com/xianyi/OpenBLAS/releases/download/v0.3.24/OpenBLAS-0.3.24-x64.zip")
set(OpenBLAS_SHA256 "6335128ee7117ea2dd2f5f96f76dafc17256c85992637189a2d5f6da0c608163")
ExternalProject_Add(
set(OpenBLAS_URL "https://github.com/OpenMathLib/OpenBLAS/releases/download/v0.3.27/OpenBLAS-0.3.27-x64.zip")
set(OpenBLAS_SHA256 "7B4D7504F274F8E26001AAB4E25EC05032D90B8785B0355DC0D09247858D9F1E")
FetchContent_Declare(
OpenBLAS
URL ${OpenBLAS_URL}
URL_HASH SHA256=${OpenBLAS_SHA256}
DOWNLOAD_NO_PROGRESS true
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR> <INSTALL_DIR>)
ExternalProject_Get_Property(OpenBLAS INSTALL_DIR)
set(OpenBLAS_DIR ${INSTALL_DIR})
set(WHISPER_ADDITIONAL_ENV "OPENBLAS_PATH=${OpenBLAS_DIR}")
set(WHISPER_ADDITIONAL_CMAKE_ARGS -DWHISPER_BLAS=ON -DWHISPER_CUBLAS=OFF)
DOWNLOAD_EXTRACT_TIMESTAMP true
)
FetchContent_MakeAvailable(OpenBLAS)
set(OpenBLAS_DIR ${openblas_SOURCE_DIR})
message(STATUS "OpenBLAS_DIR: ${OpenBLAS_DIR}")
set(WHISPER_ADDITIONAL_ENV "OPENBLAS_PATH=${openblas_SOURCE_DIR}")
set(WHISPER_ADDITIONAL_CMAKE_ARGS -DWHISPER_BLAS=ON -DWHISPER_OPENBLAS=ON -DWHISPER_CUBLAS=OFF)
endif()

ExternalProject_Add(
Whispercpp_Build
DOWNLOAD_EXTRACT_TIMESTAMP true
GIT_REPOSITORY https://github.com/ggerganov/whisper.cpp.git
GIT_TAG ${Whispercpp_Build_GIT_TAG}
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config ${Whispercpp_BUILD_TYPE}
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config ${Whispercpp_BUILD_TYPE} --verbose
BUILD_BYPRODUCTS
<INSTALL_DIR>/lib/static/${CMAKE_STATIC_LIBRARY_PREFIX}whisper${CMAKE_STATIC_LIBRARY_SUFFIX}
<INSTALL_DIR>/bin/${CMAKE_SHARED_LIBRARY_PREFIX}whisper${CMAKE_SHARED_LIBRARY_SUFFIX}
Expand All @@ -88,11 +129,11 @@ if(WIN32)
-DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES_} -DCMAKE_CXX_FLAGS=${WHISPER_EXTRA_CXX_FLAGS}
-DCMAKE_C_FLAGS=${WHISPER_EXTRA_CXX_FLAGS} -DBUILD_SHARED_LIBS=ON -DWHISPER_BUILD_TESTS=OFF
-DWHISPER_BUILD_EXAMPLES=OFF ${WHISPER_ADDITIONAL_CMAKE_ARGS})
-DWHISPER_BUILD_EXAMPLES=OFF -DCMAKE_MODULE_PATH=${CMAKE_SOURCE_DIR}/cmake ${WHISPER_ADDITIONAL_CMAKE_ARGS})

if(NOT WHISPERCPP_WITH_CUDA)
if(NOT WHISPERCPP_WITH_CUDA AND NOT WHISPERCPP_WITH_CLBLAST)
add_dependencies(Whispercpp_Build OpenBLAS)
endif(NOT WHISPERCPP_WITH_CUDA)
endif()
else()
# On Linux and MacOS build a static Whisper library
ExternalProject_Add(
Expand Down Expand Up @@ -123,12 +164,33 @@ if(WIN32)
install(DIRECTORY ${INSTALL_DIR}/include DESTINATION ${CMAKE_SOURCE_DIR}/release)
install(DIRECTORY ${INSTALL_DIR}/bin DESTINATION ${CMAKE_SOURCE_DIR}/release)

if(NOT WHISPERCPP_WITH_CUDA)
if(NOT WHISPERCPP_WITH_CUDA AND NOT WHISPERCPP_WITH_CLBLAST)
# add openblas to the link line
install(DIRECTORY ${OpenBLAS_DIR}/lib DESTINATION ${CMAKE_SOURCE_DIR}/release)
install(DIRECTORY ${OpenBLAS_DIR}/include DESTINATION ${CMAKE_SOURCE_DIR}/release)
install(DIRECTORY ${OpenBLAS_DIR}/bin DESTINATION ${CMAKE_SOURCE_DIR}/release)
else(NOT WHISPERCPP_WITH_CUDA)
elseif(WHISPERCPP_WITH_CLBLAST)
file(TO_CMAKE_PATH ${clblast_SOURCE_DIR} clblast_SOURCE_DIR)
# find the clblast DLLs in the bin directory of the CLBlast installation
file(GLOB CLBLAST_DLLS "${clblast_SOURCE_DIR}/bin/clblast.dll")
# if the files cannot be found, abort
if(NOT CLBLAST_DLLS)
message(FATAL_ERROR "Could not find CLBlast DLLs in ${clblast_SOURCE_DIR}/bin")
endif()
# copy the DLLs to the OBS plugin directory
install(FILES ${CLBLAST_DLLS} DESTINATION ${CMAKE_SOURCE_DIR}/release/bin)
install(DIRECTORY ${clblast_SOURCE_DIR}/include ${opencl_sdk_SOURCE_DIR}/include DESTINATION ${CMAKE_SOURCE_DIR}/release)

file(TO_CMAKE_PATH ${opencl_sdk_SOURCE_DIR} opencl_sdk_SOURCE_DIR)
# find the opencl SDK DLLs in the bin directory of the OpenCL SDK installation
file(GLOB OPENCL_SDK_DLLS "${opencl_sdk_SOURCE_DIR}/bin/OpenCL.dll")
# if the files cannot be found, abort
if(NOT OPENCL_SDK_DLLS)
message(FATAL_ERROR "Could not find OpenCL SDK DLLs in ${opencl_sdk_SOURCE_DIR}/bin")
endif()
# copy the DLLs to the OBS plugin directory
install(FILES ${OPENCL_SDK_DLLS} DESTINATION ${CMAKE_SOURCE_DIR}/release/bin)
else()
# normalize CUDA path with file(TO_CMAKE_PATH)
file(TO_CMAKE_PATH ${CUDA_TOOLKIT_ROOT_DIR} CUDA_TOOLKIT_ROOT_DIR)
# find the CUDA DLLs for cuBLAS in the bin directory of the CUDA installation e.g. cublas64_NN.dll
Expand All @@ -145,7 +207,7 @@ if(WIN32)
endif()
# copy the DLLs to the OBS plugin directory
install(FILES ${CUBLAS_DLLS} ${CUBLASLT_DLLS} ${CUDART_DLLS} DESTINATION ${CMAKE_SOURCE_DIR}/release/bin)
endif(NOT WHISPERCPP_WITH_CUDA)
endif()
else()
# copy lib/ include/ and bin/ from ${INSTALL_DIR} to the release directory in the root of the project
install(DIRECTORY ${INSTALL_DIR}/lib DESTINATION ${CMAKE_SOURCE_DIR}/release)
Expand Down
7 changes: 5 additions & 2 deletions build-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ Param(

# check env var CPU_OR_CUDA
if ($env:CPU_OR_CUDA -eq $null) {
Write-Host "Please set env var CPU_OR_CUDA to 'cpu' or the CUDA version you want to use"
Write-Host "Please set env var CPU_OR_CUDA to 'cpu', 'clblast' or the CUDA version you want to use"
exit
}

$cmakeArgs = @()
if ($env:CPU_OR_CUDA -eq "cpu") {
$cmakeArgs += ("-DWHISPERCPP_WITH_CUDA=OFF")
$zipFileName = "whispercpp-windows-cpu-$Version.zip"
} elseif ($env:CPU_OR_CUDA -eq "clblast") {
$cmakeArgs += ("-DWHISPERCPP_WITH_CUDA=OFF", "-DWHISPERCPP_WITH_CLBLAST=ON")
$zipFileName = "whispercpp-windows-clblast-$Version.zip"
} else {
$cmakeArgs += (
"-DWHISPERCPP_WITH_CUDA=ON",
Expand All @@ -29,4 +32,4 @@ cmake --build build --config Release
cmake --install build

# compress the release folder
Compress-Archive -Path release -DestinationPath $zipFileName
Compress-Archive -Force -Path release -DestinationPath $zipFileName
43 changes: 43 additions & 0 deletions cmake/FindCLBlast.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Assume the library is called libCLBlast.a and the headers are in 'include'
find_path(CLBlast_INCLUDE_DIR NAMES clblast.h
PATHS ${clblast_SOURCE_DIR}/include)

find_library(CLBlast_LIBRARY NAMES clblast
PATHS ${clblast_SOURCE_DIR}/lib)

# find opencl sdk includes
find_path(OPENCL_INCLUDE_DIR NAMES CL/opencl.h
PATHS ${opencl_sdk_SOURCE_DIR}/include)

# find opencl sdk libraries
find_library(OPENCL_LIBRARY NAMES OpenCL
PATHS ${opencl_sdk_SOURCE_DIR}/lib)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CLBlast DEFAULT_MSG
CLBlast_LIBRARY CLBlast_INCLUDE_DIR)

if(CLBlast_FOUND AND NOT TARGET clbast)
add_library(clbast::clblast STATIC IMPORTED)
set_target_properties(clbast::clblast PROPERTIES
IMPORTED_LOCATION "${CLBlast_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${CLBlast_INCLUDE_DIR}")
# add opencl library
add_library(opencl STATIC IMPORTED)
set_target_properties(opencl PROPERTIES
IMPORTED_LOCATION "${OPENCL_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${OPENCL_INCLUDE_DIR}")

# add clblast as an interface for clbast::clblast and opencl both
add_library(clblast INTERFACE)
target_link_libraries(clblast INTERFACE clbast::clblast opencl)

# find the library dir and store in CLBlast_LIBRARY_DIR
get_filename_component(CLBlast_LIBRARY_DIR ${CLBlast_LIBRARY} DIRECTORY)
get_filename_component(OpenCL_LIBRARY_DIR ${OPENCL_LIBRARY} DIRECTORY)

# Add to include directories
include_directories(${CLBlast_INCLUDE_DIR} ${OPENCL_INCLUDE_DIR})
# add the link directories
link_directories(${CLBlast_LIBRARY_DIR} ${OpenCL_LIBRARY_DIR})
endif()

0 comments on commit 4f88391

Please sign in to comment.