/
oidn_ispc.cmake
245 lines (206 loc) · 9.21 KB
/
oidn_ispc.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
## Copyright 2009 Intel Corporation
## SPDX-License-Identifier: Apache-2.0
# ISPC versions to look for, in descending order (newest first)
set(ISPC_VERSION_WORKING "1.23.0" "1.22.0" "1.21.1" "1.21.0")
if(WIN32 AND OIDN_ARCH STREQUAL "ARM64")
list(REMOVE_ITEM ISPC_VERSION_WORKING "1.22.0")
endif()
list(GET ISPC_VERSION_WORKING -1 ISPC_VERSION_REQUIRED)
list(GET ISPC_VERSION_WORKING 0 ISPC_VERSION_LATEST)
if(NOT ISPC_EXECUTABLE)
# try sibling folder as hint for path of ISPC
if(APPLE)
set(ISPC_DIR_SUFFIX "macOS" "macOS.universal" "macOS.x86_64" "macOS.arm64" "osx" "Darwin")
elseif(WIN32)
set(ISPC_DIR_SUFFIX "windows" "win32")
if(MSVC_VERSION LESS 1900)
message(WARNING "MSVC 12 2013 is not supported anymore.")
else()
list(APPEND ISPC_DIR_SUFFIX "windows-vs2015")
endif()
else()
set(ISPC_DIR_SUFFIX "linux" "linux.aarch64" "Linux")
endif()
foreach(ver ${ISPC_VERSION_WORKING})
foreach(v "" "v")
foreach(suffix ${ISPC_DIR_SUFFIX})
foreach(d "" "/bin")
list(APPEND ISPC_DIR_HINT ${PROJECT_SOURCE_DIR}/../ispc-${v}${ver}-${suffix}${d})
endforeach()
endforeach()
endforeach()
endforeach()
find_program(ISPC_EXECUTABLE ispc HINTS ${ISPC_DIR_HINT} DOC "Path to the ISPC executable.")
if(NOT ISPC_EXECUTABLE)
message("********************************************")
message("Could not find ISPC (looked in PATH and ${ISPC_DIR_HINT})")
message("")
message("This version of Intel(R) Open Image Denoise expects you to have a binary install of ISPC minimum version ${ISPC_VERSION_REQUIRED}, and expects it to be found in 'PATH' or in the sibling directory to where the Intel Open Image Denoise sources are located. Please go to https://ispc.github.io/downloads.html, select the binary release for your particular platform, and unpack it to ${PROJECT_SOURCE_DIR}/../")
message("")
message("If you insist on using your own custom install of ISPC, please make sure that the 'ISPC_EXECUTABLE' variable is properly set in CMake.")
message("********************************************")
message(FATAL_ERROR "Could not find ISPC. Exiting.")
else()
message(STATUS "Found Intel SPMD Compiler (ISPC): ${ISPC_EXECUTABLE}")
endif()
endif()
if(NOT ISPC_VERSION)
execute_process(COMMAND ${ISPC_EXECUTABLE} --version OUTPUT_VARIABLE ISPC_OUTPUT)
string(REGEX MATCH " ([0-9]+[.][0-9]+[.][0-9]+)(dev|knl|rc[0-9])? " DUMMY "${ISPC_OUTPUT}")
set(ISPC_VERSION ${CMAKE_MATCH_1})
if(ISPC_VERSION VERSION_LESS ISPC_VERSION_REQUIRED)
message(FATAL_ERROR "Need at least version ${ISPC_VERSION_REQUIRED} of Intel SPMD Compiler (ISPC).")
endif()
set(ISPC_VERSION ${ISPC_VERSION} CACHE STRING "ISPC Version")
mark_as_advanced(ISPC_VERSION)
mark_as_advanced(ISPC_EXECUTABLE)
endif()
if(WIN32 AND OIDN_ARCH STREQUAL "ARM64" AND ${ISPC_VERSION} VERSION_EQUAL "1.22.0")
message(FATAL_ERROR "ISPC v1.22.0 is not supported on Windows ARM64. Please use v${ISPC_VERSION_LATEST}.")
endif()
get_filename_component(ISPC_DIR ${ISPC_EXECUTABLE} PATH)
## -----------------------------------------------------------------------------
## Macro to specify global-scope ISPC include directories
## -----------------------------------------------------------------------------
set(ISPC_INCLUDE_DIR "")
macro(ispc_include_directories)
set(ISPC_INCLUDE_DIR ${ISPC_INCLUDE_DIR} ${ARGN})
endmacro()
## -----------------------------------------------------------------------------
## Macro to specify global-scope ISPC definitions
## -----------------------------------------------------------------------------
set(ISPC_DEFINITIONS "")
macro(ispc_add_definitions)
set(ISPC_DEFINITIONS ${ISPC_DEFINITIONS} ${ARGN})
endmacro()
## -----------------------------------------------------------------------------
## Macro to compile ISPC source into an object file for linking
## -----------------------------------------------------------------------------
macro(ispc_compile)
set(ISPC_ADDITIONAL_ARGS "")
set(ISPC_TARGETS ${OIDN_ISPC_TARGET_LIST})
set(ISPC_TARGET_EXT ${CMAKE_CXX_OUTPUT_EXTENSION})
string(REPLACE ";" "," ISPC_TARGET_ARGS "${ISPC_TARGETS}")
if(OIDN_ARCH STREQUAL "X64")
set(ISPC_ARCHITECTURE "x86-64")
elseif(OIDN_ARCH STREQUAL "ARM64")
set(ISPC_ARCHITECTURE "aarch64")
if(APPLE AND ISPC_VERSION VERSION_LESS "1.16.0")
set(ISPC_TARGET_OS "--target-os=ios")
endif()
endif()
set(ISPC_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
include_directories(${ISPC_TARGET_DIR})
if(ISPC_INCLUDE_DIR)
string(REPLACE ";" ";-I;" ISPC_INCLUDE_DIR_PARMS "${ISPC_INCLUDE_DIR}")
set(ISPC_INCLUDE_DIR_PARMS "-I" ${ISPC_INCLUDE_DIR_PARMS})
endif()
#CAUTION: -O0/1 -g with ispc seg faults
set(ISPC_FLAGS_DEBUG "-g" CACHE STRING "ISPC Debug flags")
mark_as_advanced(ISPC_FLAGS_DEBUG)
set(ISPC_FLAGS_RELEASE "-O3" CACHE STRING "ISPC Release flags")
mark_as_advanced(ISPC_FLAGS_RELEASE)
set(ISPC_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "ISPC Release with Debug symbols flags")
mark_as_advanced(ISPC_FLAGS_RELWITHDEBINFO)
if(WIN32 OR "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
set(ISPC_OPT_FLAGS ${ISPC_FLAGS_RELEASE})
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(ISPC_OPT_FLAGS ${ISPC_FLAGS_DEBUG})
else()
set(ISPC_OPT_FLAGS ${ISPC_FLAGS_RELWITHDEBINFO})
endif()
# turn space sparated list into ';' separated list
string(REPLACE " " ";" ISPC_OPT_FLAGS "${ISPC_OPT_FLAGS}")
if(NOT WIN32)
set(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --pic)
endif()
if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --opt=disable-assertions)
endif()
foreach(src ${ARGN})
get_filename_component(input ${src} ABSOLUTE)
get_filename_component(fname ${src} NAME_WE)
get_filename_component(dir ${input} DIRECTORY)
oidn_get_build_path(outdir ${dir})
set(outdir ${outdir}/CMakeFiles/${target}.dir)
set(deps "")
if(EXISTS ${outdir}/${fname}.dev.idep)
file(READ ${outdir}/${fname}.dev.idep contents)
string(REPLACE " " ";" contents "${contents}")
string(REPLACE ";" "\\\\;" contents "${contents}")
string(REPLACE "\n" ";" contents "${contents}")
foreach(dep ${contents})
if(EXISTS ${dep})
set(deps ${deps} ${dep})
endif(EXISTS ${dep})
endforeach(dep ${contents})
endif()
set(results "${outdir}/${fname}.dev${ISPC_TARGET_EXT}")
# if we have multiple targets add additional object files
list(LENGTH ISPC_TARGETS NUM_TARGETS)
if(NUM_TARGETS GREATER 1)
foreach(target ${ISPC_TARGETS})
string(REPLACE "sse4.1-" "sse4-" target ${target}) # strip sse4 minor version
string(REPLACE "sse4.2-" "sse4-" target ${target}) # strip sse4 minor version
string(REPLACE "-i32x4" "" target ${target}) # strip sse2-i32x4
string(REPLACE "-i32x8" "" target ${target}) # strip (sse4|avx|avx2)-i32x8
string(REPLACE "-i32x16" "" target ${target}) # strip avx512(knl|skx)-i32x16
string(REPLACE "-x16" "" target ${target}) # strip avx512spr-x16
set(results ${results} "${outdir}/${fname}.dev_${target}${ISPC_TARGET_EXT}")
endforeach()
endif()
set(output ${outdir}/${fname}.dev${ISPC_TARGET_EXT})
file(RELATIVE_PATH output_rel ${CMAKE_BINARY_DIR} ${output})
add_custom_command(
OUTPUT ${results} ${ISPC_TARGET_DIR}/${fname}_ispc.h
COMMAND ${CMAKE_COMMAND} -E make_directory ${outdir}
COMMAND ${ISPC_EXECUTABLE}
${ISPC_DEFINITIONS}
-I ${CMAKE_CURRENT_SOURCE_DIR}
${ISPC_INCLUDE_DIR_PARMS}
--arch=${ISPC_ARCHITECTURE}
--addressing=${OIDN_ISPC_ADDRESSING}
${ISPC_OPT_FLAGS}
--target=${ISPC_TARGET_ARGS}
--woff
${ISPC_ADDITIONAL_ARGS}
-h ${ISPC_TARGET_DIR}/${fname}_ispc.h
-MMM ${outdir}/${fname}.dev.idep
-o ${output}
${ISPC_TARGET_OS}
${input}
DEPENDS ${input} ${deps}
COMMENT "Building ISPC object ${output_rel}"
)
list(APPEND ISPC_OBJECTS ${results})
endforeach()
endmacro()
## -----------------------------------------------------------------------------
## Macro to add both C/C++ and ISPC sources to a given target
## -----------------------------------------------------------------------------
function(ispc_target_add_sources target)
# Split-out C/C++ from ISPC files
set(ISPC_SOURCES "")
set(OTHER_SOURCES "")
foreach(src ${ARGN})
get_filename_component(ext ${src} EXT)
if(ext STREQUAL ".ispc")
set(ISPC_SOURCES ${ISPC_SOURCES} ${src})
else()
set(OTHER_SOURCES ${OTHER_SOURCES} ${src})
endif()
endforeach()
# Get existing target definitions and include dirs
# NOTE(jda) - This needs work: BUILD_INTERFACE vs. INSTALL_INTERFACE isn't
# handled automatically.
#get_property(TARGET_DEFINITIONS TARGET ${target} PROPERTY COMPILE_DEFINITIONS)
#get_property(TARGET_INCLUDES TARGET ${target} PROPERTY INCLUDE_DIRECTORIES)
#set(ISPC_DEFINITIONS ${TARGET_DEFINITIONS})
#set(ISPC_INCLUDE_DIR ${TARGET_INCLUDES})
# Compile ISPC files
ispc_compile(${ISPC_SOURCES})
# Set final sources on target
get_property(TARGET_SOURCES TARGET ${target} PROPERTY SOURCES)
list(APPEND TARGET_SOURCES ${ISPC_OBJECTS} ${OTHER_SOURCES})
set_target_properties(${target} PROPERTIES SOURCES "${TARGET_SOURCES}")
endfunction()