Skip to content

Commit bded1be

Browse files
karmachoicheolhochoi
andauthored
fix: configure OpenTrustRegion BLAS fallback (#134)
Co-authored-by: cheolhochoi <cheolhochoi@ultra.tailbd750b.ts.net>
1 parent e6a46d1 commit bded1be

4 files changed

Lines changed: 155 additions & 51 deletions

File tree

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ if(APPLE)
165165
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
166166
endif()
167167

168+
if(${LINALG_LIB} STREQUAL none)
169+
message(FATAL_ERROR "LINALG_LIB=none is not supported because OpenQP builds and links OpenTrustRegion, which requires BLAS/LAPACK. Use LINALG_LIB=auto, a concrete BLAS/LAPACK vendor, or netlib.")
170+
endif()
171+
172+
# Resolve BLAS/LAPACK before configuring external projects. OpenTrustRegion
173+
# needs the same BLAS integer-size decision as OpenQP; early resolution also
174+
# lets a failed system BLAS search fall back to the bundled NetLib target before
175+
# the external project graph is generated. Linking to oqp happens when
176+
# findLinearAlgebra() is called again after the oqp target exists.
177+
findLinearAlgebra()
178+
168179
add_subdirectory(external)
169180

170181
add_definitions(-DOQP)

cmake/oqp_functions.cmake

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,25 @@ macro(findLinearAlgebra)
106106

107107
if(linalg_lib STREQUAL netlib)
108108
set(_LINALG_LIB_TYPE "NetLib" CACHE INTERNAL "_LIANLG_LIB_TYPE")
109-
add_dependencies(oqp LAPACK)
110-
target_link_libraries(oqp ${LIBLAPACK} ${LIBBLAS})
109+
if(TARGET oqp)
110+
add_dependencies(oqp LAPACK)
111+
target_link_libraries(oqp ${LIBLAPACK} ${LIBBLAS})
112+
endif()
111113
elseif(linalg_lib STREQUAL Intel10_64_dyn)
112114
set(_LINALG_LIB_TYPE "MKL_RT" CACHE INTERNAL "_LIANLG_LIB_TYPE")
113-
target_link_libraries(oqp ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
115+
if(TARGET oqp)
116+
target_link_libraries(oqp ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
117+
endif()
114118
if(LINALG_LIB_INT64)
115119
set(_MKL_INTERFACE_LAYER "ILP64" CACHE INTERNAL "_MKL_INTERFACE_LAYER")
116120
else()
117121
set(_MKL_INTERFACE_LAYER "LP64" CACHE INTERNAL "_MKL_INTERFACE_LAYER")
118122
endif()
119123
else()
120124
set(_LINALG_LIB_TYPE "other" CACHE INTERNAL "_LIANLG_LIB_TYPE")
121-
target_link_libraries(oqp ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
125+
if(TARGET oqp)
126+
target_link_libraries(oqp ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
127+
endif()
122128
endif()
123129
unset(linalg_lib)
124130
endmacro()

external/CMakeLists.txt

Lines changed: 84 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,101 @@ ExternalProject_Add(libecpint
103103
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
104104
INSTALL_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target install
105105
)
106+
if(_LINALG_LIB_TYPE STREQUAL NetLib)
107+
if(LINALG_LIB_INT64)
108+
set(BLA_LIB_SUFFIX "64")
109+
else()
110+
set(BLA_LIB_SUFFIX "")
111+
endif()
112+
if(BUILD_SHARED_LIBS)
113+
set(la_fortran_flags "${CMAKE_Fortran_FLAGS} -fpic")
114+
else()
115+
set(la_fortran_flags ${CMAKE_Fortran_FLAGS})
116+
endif()
117+
set(LAPACK_PREFIX ${CMAKE_BINARY_DIR}/external/lapack CACHE INTERNAL "LAPACK_PREFIX")
118+
set(LIBLAPACK ${LAPACK_PREFIX}/src/lapack-build/lib/liblapack${BLA_LIB_SUFFIX}.a CACHE INTERNAL "LIBLAPACK")
119+
120+
set(LIBBLAS ${LAPACK_PREFIX}/src/lapack-build/lib/libblas${BLA_LIB_SUFFIX}.a CACHE INTERNAL "LIBBLAS")
121+
message(STATUS "BLAS_SUFFIX = ${BLA_LIB_SUFFIX}")
122+
123+
124+
ExternalProject_Add(LAPACK
125+
PREFIX ${CMAKE_SOURCE_DIR}/external/lapack
126+
URL https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.10.0.tar.gz
127+
URL_HASH SHA256=328c1bea493a32cac5257d84157dc686cc3ab0b004e2bea22044e0a59f6f8a19
128+
BINARY_DIR ${CMAKE_BINARY_DIR}/external/lapack/src/lapack-build
129+
STAMP_DIR ${CMAKE_BINARY_DIR}/external/lapack/src/lapack-stamp
130+
BUILD_BYPRODUCTS ${LAPACK_PREFIX}/src/lapack-build/lib/liblapack${BLA_LIB_SUFFIX}.a
131+
${LAPACK_PREFIX}/src/lapack-build/lib/libblas${BLA_LIB_SUFFIX}.a
132+
UPDATE_COMMAND ""
133+
PATCH_COMMAND /usr/bin/perl -0pi -e "s/cmake_minimum_required\\(VERSION 3\\.2\\)/cmake_minimum_required(VERSION 3.5)/g" <SOURCE_DIR>/CMakeLists.txt <SOURCE_DIR>/INSTALL/CMakeLists.txt
134+
INSTALL_COMMAND ""
135+
CMAKE_ARGS -DBUILD_INDEX64=${LINALG_LIB_INT64}
136+
-DBUILD_SINGLE=OFF
137+
-DBUILD_DOUBLE=ON
138+
-DBUILD_COMPLEX=OFF
139+
-DBUILD_COMPLEX16=OFF
140+
-DUSE_OPTIMIZED_BLAS=OFF
141+
-DUSE_OPTIMIZED_LAPACK=OFF
142+
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
143+
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
144+
-DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}
145+
-DCMAKE_Fortran_FLAGS=${la_fortran_flags}
146+
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
147+
-DCMAKE_TRY_COMPILE_PLATFORM_VARIABLES=CMAKE_POLICY_VERSION_MINIMUM
148+
-DCMAKE_GENERATOR:INTERNAL=${CMAKE_GENERATOR}
149+
)
150+
endif()
151+
set(otr_integer_flags "")
152+
if(LINALG_LIB_INT64)
153+
if("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU")
154+
set(otr_integer_flags "-fdefault-integer-8")
155+
elseif("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "Flang")
156+
set(otr_integer_flags "-fdefault-integer-8")
157+
elseif("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "Intel" OR "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "IntelLLVM")
158+
set(otr_integer_flags "-i8")
159+
endif()
160+
endif()
161+
set(otr_fortran_flags "${CMAKE_Fortran_FLAGS} ${OTR_DEFS} ${otr_integer_flags}")
162+
if("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER 10.0)
163+
set(otr_fortran_flags "${otr_fortran_flags} -fallow-argument-mismatch")
164+
endif()
165+
set(OTR_CMAKE_ARGS
166+
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external/install/opentrustregion
167+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
168+
-DBLA_SIZEOF_INTEGER=${BLA_SIZEOF_INTEGER}
169+
-DINTEGER_SIZE=${BLA_SIZEOF_INTEGER}
170+
-DBUILD_SHARED_LIBS=OFF
171+
-DBUILD_TESTS=OFF
172+
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
173+
-DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}
174+
-DCMAKE_Fortran_FLAGS=${otr_fortran_flags}
175+
-DCMAKE_GENERATOR:INTERNAL=${CMAKE_GENERATOR}
176+
)
177+
if(_LINALG_LIB_TYPE STREQUAL NetLib)
178+
list(APPEND OTR_CMAKE_ARGS
179+
-DBLAS_LIBRARIES=${LIBBLAS}
180+
-DLAPACK_LIBRARIES=${LIBLAPACK}
181+
)
182+
elseif(DEFINED BLA_VENDOR)
183+
list(APPEND OTR_CMAKE_ARGS -DBLA_VENDOR=${BLA_VENDOR})
184+
endif()
185+
106186
ExternalProject_Add(libopentrustregion
107187
PREFIX ${CMAKE_SOURCE_DIR}/external/opentrustregion
108188
URL https://github.com/eriksen-lab/opentrustregion/archive/refs/tags/v2.0.0.tar.gz
109189
URL_HASH SHA256=682201cc9cc850a892d132e5e5fc11f6d87f8cd843fdbad88dafbf7277407f1c
110190
UPDATE_COMMAND ""
111191
PATCH_COMMAND
112192
UPDATE_COMMAND ""
113-
CMAKE_ARGS
114-
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external/install/opentrustregion
115-
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
116-
-DBLA_SIZEOF_INTEGER=${BLA_SIZEOF_INTEGER}
117-
-DBUILD_SHARED_LIBS=OFF
118-
-DBUILD_TESTS=OFF
193+
CMAKE_ARGS ${OTR_CMAKE_ARGS}
119194
BINARY_DIR ${CMAKE_BINARY_DIR}/external/opentrustregion/src/libopentrustregion-build-${CMAKE_Fortran_COMPILER_ID}
120195
# INSTALL_DIR ${CMAKE_BINARY_DIR}/external/install/opentrustregion
121196
# STEP_TARGETS build install
122197
)
198+
if(_LINALG_LIB_TYPE STREQUAL NetLib)
199+
add_dependencies(libopentrustregion LAPACK)
200+
endif()
123201

124202
set(OTR_LIB_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}opentrustregion${OTR_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
125203
if(ENABLE_Formatter)
@@ -161,47 +239,6 @@ if(ENABLE_Formatter)
161239
)
162240
endif()
163241

164-
if(_LINALG_LIB_TYPE STREQUAL NetLib)
165-
if(LINALG_LIB_INT64)
166-
set(BLA_LIB_SUFFIX "64")
167-
else()
168-
set(BLA_LIB_SUFFIX "")
169-
endif()
170-
if(BUILD_SHARED_LIBS)
171-
set(la_fortran_flags "${CMAKE_Fortran_FLAGS} -fpic")
172-
else()
173-
set(la_fortran_flags ${CMAKE_Fortran_FLAGS})
174-
endif()
175-
set(LAPACK_PREFIX ${CMAKE_BINARY_DIR}/external/lapack CACHE INTERNAL "LAPACK_PREFIX")
176-
set(LIBLAPACK ${LAPACK_PREFIX}/src/lapack-build/lib/liblapack${BLA_LIB_SUFFIX}.a CACHE INTERNAL "LIBLAPACK")
177-
178-
set(LIBBLAS ${LAPACK_PREFIX}/src/lapack-build/lib/libblas${BLA_LIB_SUFFIX}.a CACHE INTERNAL "LIBBLAS")
179-
message(STATUS "BLAS_SUFFIX = ${BLA_LIB_SUFFIX}")
180-
181242

182-
ExternalProject_Add(LAPACK
183-
PREFIX ${CMAKE_SOURCE_DIR}/external/lapack
184-
URL https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.10.0.tar.gz
185-
URL_HASH SHA256=328c1bea493a32cac5257d84157dc686cc3ab0b004e2bea22044e0a59f6f8a19
186-
BINARY_DIR ${CMAKE_BINARY_DIR}/external/lapack/src/lapack-build
187-
STAMP_DIR ${CMAKE_BINARY_DIR}/external/lapack/src/lapack-stamp
188-
BUILD_BYPRODUCTS ${LAPACK_PREFIX}/src/lapack-build/lib/liblapack${BLA_LIB_SUFFIX}.a
189-
${LAPACK_PREFIX}/src/lapack-build/lib/libblas${BLA_LIB_SUFFIX}.a
190-
UPDATE_COMMAND ""
191-
INSTALL_COMMAND ""
192-
CMAKE_ARGS -DBUILD_INDEX64=${LINALG_LIB_INT64}
193-
-DBUILD_SINGLE=OFF
194-
-DBUILD_DOUBLE=ON
195-
-DBUILD_COMPLEX=OFF
196-
-DBUILD_COMPLEX16=OFF
197-
-DUSE_OPTIMIZED_BLAS=OFF
198-
-DUSE_OPTIMIZED_LAPACK=OFF
199-
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
200-
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
201-
-DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}
202-
-DCMAKE_Fortran_FLAGS=${la_fortran_flags}
203-
-DCMAKE_GENERATOR:INTERNAL=${CMAKE_GENERATOR}
204-
)
205-
endif()
206243

207244
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM 1)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import unittest
2+
from pathlib import Path
3+
4+
5+
ROOT = Path(__file__).resolve().parents[1]
6+
7+
8+
class OpenTrustRegionLinalgConfigTests(unittest.TestCase):
9+
def test_linalg_none_is_rejected_before_external_build(self):
10+
top_cmake = (ROOT / "CMakeLists.txt").read_text()
11+
12+
self.assertIn("LINALG_LIB=none is not supported", top_cmake)
13+
self.assertIn("OpenTrustRegion", top_cmake)
14+
self.assertIn("findLinearAlgebra()", top_cmake)
15+
self.assertLess(
16+
top_cmake.index("findLinearAlgebra()"),
17+
top_cmake.index("add_subdirectory(external)"),
18+
)
19+
20+
def test_opentrustregion_receives_resolved_linalg_configuration(self):
21+
external_cmake = (ROOT / "external" / "CMakeLists.txt").read_text()
22+
23+
self.assertIn("OTR_CMAKE_ARGS", external_cmake)
24+
self.assertIn("INTEGER_SIZE=${BLA_SIZEOF_INTEGER}", external_cmake)
25+
self.assertIn("OTR_DEFS", external_cmake)
26+
self.assertIn("otr_integer_flags", external_cmake)
27+
self.assertIn("fdefault-integer-8", external_cmake)
28+
self.assertIn("fallow-argument-mismatch", external_cmake)
29+
self.assertIn("CMAKE_Fortran_FLAGS=${otr_fortran_flags}", external_cmake)
30+
self.assertIn("BLAS_LIBRARIES=${LIBBLAS}", external_cmake)
31+
self.assertIn("LAPACK_LIBRARIES=${LIBLAPACK}", external_cmake)
32+
self.assertIn("add_dependencies(libopentrustregion LAPACK)", external_cmake)
33+
self.assertIn("CMAKE_POLICY_VERSION_MINIMUM=3.5", external_cmake)
34+
self.assertIn("PATCH_COMMAND /usr/bin/perl", external_cmake)
35+
self.assertIn("cmake_minimum_required(VERSION 3.5)", external_cmake)
36+
self.assertLess(
37+
external_cmake.index("ExternalProject_Add(LAPACK"),
38+
external_cmake.index("ExternalProject_Add(libopentrustregion"),
39+
)
40+
41+
def test_find_linalg_can_run_before_oqp_target_exists(self):
42+
functions_cmake = (ROOT / "cmake" / "oqp_functions.cmake").read_text()
43+
44+
self.assertIn("if(TARGET oqp)", functions_cmake)
45+
self.assertIn("add_dependencies(oqp LAPACK)", functions_cmake)
46+
self.assertIn("target_link_libraries(oqp ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})", functions_cmake)
47+
48+
49+
if __name__ == "__main__":
50+
unittest.main()

0 commit comments

Comments
 (0)