backport main/
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
# Enable output of compile commands during generation.
|
||||
option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" ON)
|
||||
|
||||
include(utils)
|
||||
set_version(VERSION)
|
||||
|
||||
|
||||
75
WORKSPACE
75
WORKSPACE
@@ -75,7 +75,7 @@ git_repository(
|
||||
|
||||
git_repository(
|
||||
name = "rules_python",
|
||||
tag = "0.34.0",
|
||||
tag = "0.36.0",
|
||||
remote = "https://github.com/bazelbuild/rules_python.git",
|
||||
)
|
||||
|
||||
@@ -105,6 +105,43 @@ git_repository(
|
||||
repo_mapping = {"@abseil-cpp": "@com_google_absl"},
|
||||
)
|
||||
|
||||
## Python
|
||||
load("@rules_python//python:repositories.bzl", "py_repositories")
|
||||
py_repositories()
|
||||
|
||||
load("@rules_python//python:repositories.bzl", "python_register_toolchains")
|
||||
DEFAULT_PYTHON = "3.11"
|
||||
python_register_toolchains(
|
||||
name = "python3_11",
|
||||
python_version = DEFAULT_PYTHON,
|
||||
ignore_root_user_error=True,
|
||||
)
|
||||
load("@python3_11//:defs.bzl", "interpreter")
|
||||
|
||||
# Create a central external repo, @pip_deps, that contains Bazel targets for all the
|
||||
# third-party packages specified in the bazel/requirements.txt file.
|
||||
load("@rules_python//python:pip.bzl", "pip_parse")
|
||||
pip_parse(
|
||||
name = "pip_deps",
|
||||
python_interpreter_target = interpreter,
|
||||
requirements_lock = "//bazel:ortools_requirements.txt",
|
||||
)
|
||||
|
||||
load("@pip_deps//:requirements.bzl",
|
||||
install_pip_deps="install_deps")
|
||||
install_pip_deps()
|
||||
|
||||
# Add a second repo @ortools_notebook_deps for jupyter notebooks.
|
||||
pip_parse(
|
||||
name = "ortools_notebook_deps",
|
||||
python_interpreter_target = interpreter,
|
||||
requirements_lock = "//bazel:notebook_requirements.txt",
|
||||
)
|
||||
|
||||
load("@ortools_notebook_deps//:requirements.bzl",
|
||||
install_notebook_deps="install_deps")
|
||||
install_notebook_deps()
|
||||
|
||||
## Protobuf
|
||||
# proto_library, cc_proto_library, and java_proto_library rules implicitly
|
||||
# depend on @com_google_protobuf for protoc and proto runtimes.
|
||||
@@ -205,40 +242,6 @@ new_git_repository(
|
||||
remote = "https://github.com/swig/swig.git",
|
||||
)
|
||||
|
||||
## Python
|
||||
load("@rules_python//python:repositories.bzl", "py_repositories")
|
||||
py_repositories()
|
||||
|
||||
load("@rules_python//python:repositories.bzl", "python_register_toolchains")
|
||||
DEFAULT_PYTHON = "3.12"
|
||||
python_register_toolchains(
|
||||
name = "python3_12",
|
||||
python_version = DEFAULT_PYTHON,
|
||||
ignore_root_user_error=True,
|
||||
)
|
||||
|
||||
# Create a central external repo, @pip_deps, that contains Bazel targets for all the
|
||||
# third-party packages specified in the bazel/requirements.txt file.
|
||||
load("@rules_python//python:pip.bzl", "pip_parse")
|
||||
pip_parse(
|
||||
name = "pip_deps",
|
||||
requirements_lock = "//bazel:ortools_requirements.txt",
|
||||
)
|
||||
|
||||
load("@pip_deps//:requirements.bzl",
|
||||
install_pip_deps="install_deps")
|
||||
install_pip_deps()
|
||||
|
||||
# Add a second repo @ortools_notebook_deps for jupyter notebooks.
|
||||
pip_parse(
|
||||
name = "ortools_notebook_deps",
|
||||
requirements_lock = "//bazel:notebook_requirements.txt",
|
||||
)
|
||||
|
||||
load("@ortools_notebook_deps//:requirements.bzl",
|
||||
install_notebook_deps="install_deps")
|
||||
install_notebook_deps()
|
||||
|
||||
# Protobuf
|
||||
load("@com_google_protobuf//bazel:system_python.bzl", "system_python")
|
||||
system_python(
|
||||
@@ -283,7 +286,7 @@ new_git_repository(
|
||||
|
||||
new_git_repository(
|
||||
name = "pybind11_protobuf",
|
||||
commit = "84653a591aea5df482dc2bde42c19efafbd53a57", # 2024/06/28
|
||||
commit = "ed430af1814a97e4017f2f808d3ba28cc10802f1", # 2024/10/02
|
||||
remote = "https://github.com/pybind/pybind11_protobuf.git",
|
||||
)
|
||||
|
||||
|
||||
@@ -632,7 +632,7 @@ TOOLCHAIN_STAGES := env devel toolchain build test
|
||||
define toolchain-stage-target =
|
||||
#$$(info STAGE: $1)
|
||||
#$$(info Create targets: toolchain_$1 $(addprefix toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))).)
|
||||
targets_toolchain_$1 = $(addprefix toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS)))
|
||||
targets_toolchain_$1 := $(addprefix toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS)))
|
||||
.PHONY: toolchain_$1 $$(targets_toolchain_$1)
|
||||
toolchain_$1: $$(targets_toolchain_$1)
|
||||
$$(targets_toolchain_$1): toolchain_%_$1: docker/toolchain/Dockerfile
|
||||
@@ -645,7 +645,7 @@ $$(targets_toolchain_$1): toolchain_%_$1: docker/toolchain/Dockerfile
|
||||
..
|
||||
|
||||
#$$(info Create targets: save_toolchain_$1 $(addprefix save_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))) (debug).)
|
||||
save_targets_toolchain_$1 = $(addprefix save_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS)))
|
||||
save_targets_toolchain_$1 := $(addprefix save_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS)))
|
||||
.PHONY: save_toolchain_$1 $$(save_targets_toolchain_$1)
|
||||
save_toolchain_$1: $$(save_targets_toolchain_$1)
|
||||
$$(save_targets_toolchain_$1): save_toolchain_%_$1: cache/%/docker_$1.tar
|
||||
@@ -727,7 +727,7 @@ VAGRANT_VMS := \
|
||||
define make-vagrant-target =
|
||||
#$$(info VMS: $1)
|
||||
#$$(info Create target: $1_<LANG>.)
|
||||
$1_targets = $(addprefix $1_, $(LANGUAGES))
|
||||
$1_targets := $(addprefix $1_, $(LANGUAGES))
|
||||
.PHONY: $1 $$($1_targets)
|
||||
$1: $$($1_targets)
|
||||
$$($1_targets): $1_%: vagrant/$1/%/Vagrantfile
|
||||
@@ -736,14 +736,14 @@ $$($1_targets): $1_%: vagrant/$1/%/Vagrantfile
|
||||
cd vagrant/$1/$$* && vagrant up
|
||||
|
||||
#$$(info Create targets: sh_$1_<lang> vagrant machine (debug).)
|
||||
sh_$1_targets = $(addprefix sh_$1_, $(LANGUAGES))
|
||||
sh_$1_targets := $(addprefix sh_$1_, $(LANGUAGES))
|
||||
.PHONY: $$(sh_$1_targets)
|
||||
$$(sh_$1_targets): sh_$1_%:
|
||||
cd vagrant/$1/$$* && vagrant up
|
||||
cd vagrant/$1/$$* && vagrant ssh
|
||||
|
||||
#$$(info Create targets: clean_$1)
|
||||
clean_$1_targets = $(addprefix clean_$1_, $(LANGUAGES))
|
||||
clean_$1_targets := $(addprefix clean_$1_, $(LANGUAGES))
|
||||
.PHONY: clean_$1 $(clean_$1_targets)
|
||||
clean_$1: $$(clean_$1_targets)
|
||||
$$(clean_$1_targets): clean_$1_%:
|
||||
|
||||
@@ -79,12 +79,36 @@ if(USE_COINOR)
|
||||
set(COINOR_DEPS Coin::CbcSolver Coin::OsiCbc Coin::ClpSolver Coin::OsiClp)
|
||||
endif()
|
||||
|
||||
if(USE_CPLEX)
|
||||
if(NOT TARGET CPLEX::CPLEX)
|
||||
message(FATAL_ERROR "Target CPLEX::CPLEX not available.")
|
||||
endif()
|
||||
set(CPLEX_DEPS CPLEX::CPLEX)
|
||||
endif()
|
||||
|
||||
if(USE_GLPK)
|
||||
if(NOT TARGET GLPK::GLPK)
|
||||
message(FATAL_ERROR "Target GLPK::GLPK not available.")
|
||||
endif()
|
||||
set(GLPK_DEPS GLPK::GLPK)
|
||||
endif()
|
||||
|
||||
if(USE_HIGHS)
|
||||
if(NOT TARGET highs::highs)
|
||||
message(FATAL_ERROR "Target highs::highs not available.")
|
||||
endif()
|
||||
set(HIGHS_DEPS highs::highs)
|
||||
endif()
|
||||
|
||||
if(USE_PDLP AND BUILD_PDLP)
|
||||
set(PDLP_DEPS Eigen3::Eigen)
|
||||
endif()
|
||||
|
||||
if(USE_SCIP AND NOT TARGET libscip)
|
||||
message(FATAL_ERROR "Target libscip not available.")
|
||||
if(USE_SCIP)
|
||||
if(NOT TARGET libscip)
|
||||
message(FATAL_ERROR "Target libscip not available.")
|
||||
endif()
|
||||
set(SCIP_DEPS libscip)
|
||||
endif()
|
||||
|
||||
# Check optional Dependencies
|
||||
|
||||
151
cmake/cpp.cmake
151
cmake/cpp.cmake
@@ -147,70 +147,153 @@ endif()
|
||||
# ortools_cxx_test()
|
||||
# CMake function to generate and build C++ test.
|
||||
# Parameters:
|
||||
# FILE_NAME: the C++ filename
|
||||
# COMPONENT_NAME: name of the ortools/ subdir where the test is located
|
||||
# note: automatically determined if located in ortools/<component>/
|
||||
# NAME: CMake target name
|
||||
# SOURCES: List of source files
|
||||
# [COMPILE_DEFINITIONS]: List of private compile definitions
|
||||
# [COMPILE_OPTIONS]: List of private compile options
|
||||
# [LINK_LIBRARIES]: List of private libraries to use when linking
|
||||
# note: ortools::ortools is always linked to the target
|
||||
# [LINK_OPTIONS]: List of private link options
|
||||
# e.g.:
|
||||
# ortools_cxx_test(
|
||||
# FILE_NAME
|
||||
# ${PROJECT_SOURCE_DIR}/ortools/foo/foo_test.cc
|
||||
# COMPONENT_NAME
|
||||
# foo
|
||||
# DEPS
|
||||
# NAME
|
||||
# foo_bar_test
|
||||
# SOURCES
|
||||
# bar_test.cc
|
||||
# ${PROJECT_SOURCE_DIR}/ortools/foo/bar_test.cc
|
||||
# LINK_LIBRARIES
|
||||
# GTest::gmock
|
||||
# GTest::gtest_main
|
||||
# )
|
||||
function(ortools_cxx_test)
|
||||
set(options "")
|
||||
set(oneValueArgs "FILE_NAME;COMPONENT_NAME")
|
||||
set(multiValueArgs "DEPS")
|
||||
set(oneValueArgs "NAME")
|
||||
set(multiValueArgs
|
||||
"SOURCES;COMPILE_DEFINITIONS;COMPILE_OPTIONS;LINK_LIBRARIES;LINK_OPTIONS")
|
||||
cmake_parse_arguments(TEST
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN}
|
||||
)
|
||||
if(NOT TEST_FILE_NAME)
|
||||
message(FATAL_ERROR "no FILE_NAME provided")
|
||||
if(NOT TEST_NAME)
|
||||
message(FATAL_ERROR "no NAME provided")
|
||||
endif()
|
||||
get_filename_component(TEST_NAME ${TEST_FILE_NAME} NAME_WE)
|
||||
|
||||
message(STATUS "Configuring test ${TEST_FILE_NAME} ...")
|
||||
|
||||
if(NOT TEST_COMPONENT_NAME)
|
||||
# test is located in ortools/<component_name>/
|
||||
get_filename_component(COMPONENT_DIR ${TEST_FILE_NAME} DIRECTORY)
|
||||
get_filename_component(COMPONENT_NAME ${COMPONENT_DIR} NAME)
|
||||
else()
|
||||
set(COMPONENT_NAME ${TEST_COMPONENT_NAME})
|
||||
if(NOT TEST_SOURCES)
|
||||
message(FATAL_ERROR "no SOURCES provided")
|
||||
endif()
|
||||
message(STATUS "Configuring test ${TEST_NAME} ...")
|
||||
|
||||
add_executable(${TEST_NAME} ${TEST_FILE_NAME})
|
||||
add_executable(${TEST_NAME} "")
|
||||
target_sources(${TEST_NAME} PRIVATE ${TEST_SOURCES})
|
||||
target_include_directories(${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_definitions(${TEST_NAME} PRIVATE ${TEST_COMPILE_DEFINITIONS})
|
||||
target_compile_features(${TEST_NAME} PRIVATE cxx_std_17)
|
||||
target_compile_options(${TEST_NAME} PRIVATE ${TEST_COMPILE_OPTIONS})
|
||||
target_link_libraries(${TEST_NAME} PRIVATE
|
||||
${PROJECT_NAMESPACE}::ortools
|
||||
${TEST_DEPS}
|
||||
${TEST_LINK_LIBRARIES}
|
||||
)
|
||||
target_link_options(${TEST_NAME} PRIVATE ${TEST_LINK_OPTIONS})
|
||||
|
||||
include(GNUInstallDirs)
|
||||
if(APPLE)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES INSTALL_RPATH
|
||||
"@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
|
||||
set_target_properties(${TEST_NAME} PROPERTIES
|
||||
INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
|
||||
elseif(UNIX)
|
||||
cmake_path(RELATIVE_PATH CMAKE_INSTALL_FULL_LIBDIR
|
||||
BASE_DIRECTORY ${CMAKE_INSTALL_FULL_BINDIR}
|
||||
OUTPUT_VARIABLE libdir_relative_path)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN/${libdir_relative_path}")
|
||||
INSTALL_RPATH "$ORIGIN/${libdir_relative_path}:$ORIGIN")
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test(
|
||||
NAME cxx_${COMPONENT_NAME}_${TEST_NAME}
|
||||
COMMAND ${TEST_NAME})
|
||||
NAME cxx_${TEST_NAME}
|
||||
COMMAND ${TEST_NAME}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
)
|
||||
endif()
|
||||
message(STATUS "Configuring test ${TEST_FILE_NAME} ...DONE")
|
||||
message(STATUS "Configuring test ${TEST_NAME} ...DONE")
|
||||
endfunction()
|
||||
|
||||
###################
|
||||
## C++ Library ##
|
||||
###################
|
||||
# ortools_cxx_library()
|
||||
# CMake function to generate and build C++ library.
|
||||
# Parameters:
|
||||
# NAME: CMake target name
|
||||
# SOURCES: List of source files
|
||||
# [TYPE]: SHARED or STATIC
|
||||
# [COMPILE_DEFINITIONS]: List of private compile definitions
|
||||
# [COMPILE_OPTIONS]: List of private compile options
|
||||
# [LINK_LIBRARIES]: List of **public** libraries to use when linking
|
||||
# note: ortools::ortools is always linked to the target
|
||||
# [LINK_OPTIONS]: List of private link options
|
||||
# e.g.:
|
||||
# ortools_cxx_library(
|
||||
# NAME
|
||||
# foo_bar_library
|
||||
# SOURCES
|
||||
# bar_library.cc
|
||||
# ${PROJECT_SOURCE_DIR}/ortools/foo/bar_library.cc
|
||||
# TYPE
|
||||
# SHARED
|
||||
# LINK_LIBRARIES
|
||||
# GTest::gmock
|
||||
# GTest::gtest_main
|
||||
# TESTING
|
||||
# )
|
||||
function(ortools_cxx_library)
|
||||
set(options "TESTING")
|
||||
set(oneValueArgs "NAME;TYPE")
|
||||
set(multiValueArgs
|
||||
"SOURCES;COMPILE_DEFINITIONS;COMPILE_OPTIONS;LINK_LIBRARIES;LINK_OPTIONS")
|
||||
cmake_parse_arguments(LIBRARY
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN}
|
||||
)
|
||||
if(LIBRARY_TESTING AND NOT BUILD_TESTING)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT LIBRARY_NAME)
|
||||
message(FATAL_ERROR "no NAME provided")
|
||||
endif()
|
||||
if(NOT LIBRARY_SOURCES)
|
||||
message(FATAL_ERROR "no SOURCES provided")
|
||||
endif()
|
||||
message(STATUS "Configuring library ${LIBRARY_NAME} ...")
|
||||
|
||||
add_library(${LIBRARY_NAME} ${LIBRARY_TYPE} "")
|
||||
target_sources(${LIBRARY_NAME} PRIVATE ${LIBRARY_SOURCES})
|
||||
target_include_directories(${LIBRARY_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_definitions(${LIBRARY_NAME} PRIVATE ${LIBRARY_COMPILE_DEFINITIONS})
|
||||
target_compile_features(${LIBRARY_NAME} PRIVATE cxx_std_17)
|
||||
target_compile_options(${LIBRARY_NAME} PRIVATE ${LIBRARY_COMPILE_OPTIONS})
|
||||
target_link_libraries(${LIBRARY_NAME} PUBLIC
|
||||
${PROJECT_NAMESPACE}::ortools
|
||||
${LIBRARY_LINK_LIBRARIES}
|
||||
)
|
||||
target_link_options(${LIBRARY_NAME} PRIVATE ${LIBRARY_LINK_OPTIONS})
|
||||
|
||||
include(GNUInstallDirs)
|
||||
if(APPLE)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
|
||||
elseif(UNIX)
|
||||
cmake_path(RELATIVE_PATH CMAKE_INSTALL_FULL_LIBDIR
|
||||
BASE_DIRECTORY ${CMAKE_INSTALL_FULL_BINDIR}
|
||||
OUTPUT_VARIABLE libdir_relative_path)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN/${libdir_relative_path}:$ORIGIN")
|
||||
endif()
|
||||
add_library(${PROJECT_NAMESPACE}::${LIBRARY_NAME} ALIAS ${LIBRARY_NAME})
|
||||
message(STATUS "Configuring library ${LIBRARY_NAME} ...DONE")
|
||||
endfunction()
|
||||
|
||||
##################
|
||||
@@ -460,11 +543,11 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
protobuf::libprotobuf
|
||||
${RE2_DEPS}
|
||||
${COINOR_DEPS}
|
||||
$<$<BOOL:${USE_CPLEX}>:CPLEX::CPLEX>
|
||||
$<$<BOOL:${USE_GLPK}>:GLPK::GLPK>
|
||||
$<$<BOOL:${USE_HIGHS}>:highs::highs>
|
||||
${CPLEX_DEPS}
|
||||
${GLPK_DEPS}
|
||||
${HIGHS_DEPS}
|
||||
${PDLP_DEPS}
|
||||
$<$<BOOL:${USE_SCIP}>:libscip>
|
||||
${SCIP_DEPS}
|
||||
Threads::Threads)
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC psapi.lib ws2_32.lib)
|
||||
|
||||
@@ -129,7 +129,7 @@ if(BUILD_re2)
|
||||
GIT_REPOSITORY "https://github.com/google/re2.git"
|
||||
GIT_TAG "2024-04-01"
|
||||
GIT_SHALLOW TRUE
|
||||
#PATCH_COMMAND git apply --ignore-whitespace "${CMAKE_CURRENT_LIST_DIR}/../../patches/re2-2024-04-01.patch"
|
||||
PATCH_COMMAND git apply --ignore-whitespace "${CMAKE_CURRENT_LIST_DIR}/../../patches/re2-2024-04-01.patch"
|
||||
)
|
||||
FetchContent_MakeAvailable(re2)
|
||||
list(POP_BACK CMAKE_MESSAGE_INDENT)
|
||||
@@ -300,7 +300,8 @@ if(BUILD_CoinUtils)
|
||||
FetchContent_Declare(
|
||||
CoinUtils
|
||||
GIT_REPOSITORY "https://github.com/Mizux/CoinUtils.git"
|
||||
GIT_TAG "cmake/2.11.6"
|
||||
GIT_TAG "stable/2.11"
|
||||
#GIT_TAG "cmake/2.11.6"
|
||||
GIT_SHALLOW TRUE
|
||||
PATCH_COMMAND git apply --ignore-whitespace
|
||||
"${CMAKE_CURRENT_LIST_DIR}/../../patches/coinutils-2.11.patch")
|
||||
@@ -318,7 +319,8 @@ if(BUILD_Osi)
|
||||
FetchContent_Declare(
|
||||
Osi
|
||||
GIT_REPOSITORY "https://github.com/Mizux/Osi.git"
|
||||
GIT_TAG "cmake/0.108.7"
|
||||
GIT_TAG "stable/0.108"
|
||||
#GIT_TAG "cmake/0.108.7"
|
||||
GIT_SHALLOW TRUE
|
||||
PATCH_COMMAND git apply --ignore-whitespace
|
||||
"${CMAKE_CURRENT_LIST_DIR}/../../patches/osi-0.108.patch")
|
||||
@@ -336,10 +338,11 @@ if(BUILD_Clp)
|
||||
FetchContent_Declare(
|
||||
Clp
|
||||
GIT_REPOSITORY "https://github.com/Mizux/Clp.git"
|
||||
GIT_TAG "cmake/1.17.7"
|
||||
GIT_TAG "stable/1.17"
|
||||
#GIT_TAG "cmake/1.17.7"
|
||||
GIT_SHALLOW TRUE
|
||||
PATCH_COMMAND git apply --ignore-whitespace
|
||||
"${CMAKE_CURRENT_LIST_DIR}/../../patches/clp-1.17.4.patch")
|
||||
"${CMAKE_CURRENT_LIST_DIR}/../../patches/clp-1.17.patch")
|
||||
FetchContent_MakeAvailable(Clp)
|
||||
list(POP_BACK CMAKE_MESSAGE_INDENT)
|
||||
message(CHECK_PASS "fetched")
|
||||
@@ -354,7 +357,8 @@ if(BUILD_Cgl)
|
||||
FetchContent_Declare(
|
||||
Cgl
|
||||
GIT_REPOSITORY "https://github.com/Mizux/Cgl.git"
|
||||
GIT_TAG "cmake/0.60.5"
|
||||
GIT_TAG "stable/0.60"
|
||||
#GIT_TAG "cmake/0.60.5"
|
||||
GIT_SHALLOW TRUE
|
||||
PATCH_COMMAND git apply --ignore-whitespace
|
||||
"${CMAKE_CURRENT_LIST_DIR}/../../patches/cgl-0.60.patch")
|
||||
@@ -372,7 +376,8 @@ if(BUILD_Cbc)
|
||||
FetchContent_Declare(
|
||||
Cbc
|
||||
GIT_REPOSITORY "https://github.com/Mizux/Cbc.git"
|
||||
GIT_TAG "cmake/2.10.7"
|
||||
GIT_TAG "stable/2.10"
|
||||
#GIT_TAG "cmake/2.10.7"
|
||||
GIT_SHALLOW TRUE
|
||||
PATCH_COMMAND git apply --ignore-whitespace
|
||||
"${CMAKE_CURRENT_LIST_DIR}/../../patches/cbc-2.10.patch")
|
||||
@@ -398,6 +403,8 @@ if(BUILD_googletest)
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG v1.15.2
|
||||
GIT_SHALLOW TRUE
|
||||
PATCH_COMMAND git apply --ignore-whitespace
|
||||
"${CMAKE_CURRENT_LIST_DIR}/../../patches/googletest-v1.15.2.patch"
|
||||
#PATCH_COMMAND git apply --ignore-whitespace ""
|
||||
)
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
@@ -463,9 +463,11 @@ add_custom_command(
|
||||
$<TARGET_FILE:pywraplp> ${PYTHON_PROJECT}/linear_solver
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:model_builder_helper_pybind11> ${PYTHON_PROJECT}/linear_solver/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
COMMAND ${CMAKE_COMMAND} -E
|
||||
$<IF:$<BOOL:${BUILD_MATH_OPT}>,copy,true>
|
||||
$<TARGET_FILE:math_opt_pybind11> ${PYTHON_PROJECT}/math_opt/core/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
COMMAND ${CMAKE_COMMAND} -E
|
||||
$<IF:$<BOOL:${BUILD_MATH_OPT}>,copy,true>
|
||||
$<TARGET_FILE:status_py_extension_stub> ${PYTHON_PROJECT}/../pybind11_abseil
|
||||
COMMAND ${CMAKE_COMMAND} -E
|
||||
$<IF:$<TARGET_EXISTS:pdlp_pybind11>,copy,true>
|
||||
|
||||
@@ -17,8 +17,15 @@ endif()
|
||||
|
||||
if(BUILD_CXX_EXAMPLES)
|
||||
file(GLOB CXX_SRCS "*.cc")
|
||||
foreach(FILE_NAME IN LISTS CXX_SRCS)
|
||||
ortools_cxx_test(FILE_NAME ${FILE_NAME})
|
||||
foreach(_FULL_FILE_NAME IN LISTS CXX_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
tests_${_NAME}
|
||||
SOURCES
|
||||
${_FULL_FILE_NAME}
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -385,6 +385,15 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "dense_doubly_linked_list_test",
|
||||
srcs = ["dense_doubly_linked_list_test.cc"],
|
||||
deps = [
|
||||
":dense_doubly_linked_list",
|
||||
"//ortools/base:gmock_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "dynamic_partition",
|
||||
srcs = ["dynamic_partition.cc"],
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
file(GLOB _SRCS "*.h" "*.cc")
|
||||
list(FILTER _SRCS EXCLUDE REGEX "/[^/]*_test\\.cc$")
|
||||
list(FILTER _SRCS EXCLUDE REGEX ".*/.*_test.cc")
|
||||
|
||||
set(NAME ${PROJECT_NAME}_algorithms)
|
||||
|
||||
@@ -31,3 +31,23 @@ target_link_libraries(${NAME} PRIVATE
|
||||
protobuf::libprotobuf
|
||||
${PROJECT_NAMESPACE}::ortools_proto)
|
||||
#add_library(${PROJECT_NAMESPACE}::algorithms ALIAS ${NAME})
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
list(FILTER _TEST_SRCS EXCLUDE REGEX ".*_stress_test.cc")
|
||||
list(FILTER _TEST_SRCS EXCLUDE REGEX "set_cover_test.cc")
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
algorithms_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
// Copyright 2010-2024 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "ortools/algorithms/duplicate_remover.h"
|
||||
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/gmock.h"
|
||||
#include "ortools/base/linked_hash_set.h"
|
||||
#include "ortools/util/random_engine.h"
|
||||
#include "util/tuple/dump_vars.h"
|
||||
|
||||
namespace operations_research {
|
||||
namespace {
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::ElementsAreArray;
|
||||
using ::testing::IsEmpty;
|
||||
|
||||
TEST(DenseIntDuplicateRemoverTest, RemoveDuplicatesEmpty) {
|
||||
std::vector<int> v;
|
||||
DenseIntDuplicateRemover deduper(10);
|
||||
deduper.RemoveDuplicates(&v);
|
||||
EXPECT_THAT(v, IsEmpty());
|
||||
}
|
||||
|
||||
TEST(DenseIntDuplicateRemoverTest, RemoveDuplicatesNZeroAndEmpty) {
|
||||
std::vector<int> v;
|
||||
DenseIntDuplicateRemover deduper(0);
|
||||
deduper.RemoveDuplicates(&v);
|
||||
EXPECT_THAT(v, IsEmpty());
|
||||
}
|
||||
|
||||
TEST(DenseIntDuplicateRemoverTest, RemoveDuplicatesSimpleCaseWithDuplicates) {
|
||||
std::vector<int> v = {1, 8, 2, 2, 8, 4, 1, 2, 7, 0, 2};
|
||||
DenseIntDuplicateRemover deduper(9);
|
||||
deduper.RemoveDuplicates(&v);
|
||||
EXPECT_THAT(v, ElementsAre(1, 8, 2, 4, 7, 0));
|
||||
}
|
||||
|
||||
TEST(DenseIntDuplicateRemoverTest, RemoveDuplicatesSimpleCaseWithNoDuplicates) {
|
||||
std::vector<int> v = {3, 2, 0, 5, 4, 1};
|
||||
const std::vector<int> v_copy = v;
|
||||
DenseIntDuplicateRemover deduper(6);
|
||||
deduper.RemoveDuplicates(&v);
|
||||
EXPECT_THAT(v, ElementsAreArray(v_copy));
|
||||
}
|
||||
|
||||
TEST(DenseIntDuplicateRemoverTest, RemoveDuplicatesWithRepeatedField) {
|
||||
const std::vector<int> v = {1, 0, 1, 2, 1};
|
||||
google::protobuf::RepeatedField<int> r(v.begin(), v.end());
|
||||
DenseIntDuplicateRemover deduper(3);
|
||||
deduper.RemoveDuplicates(&r);
|
||||
EXPECT_THAT(r, ElementsAre(1, 0, 2));
|
||||
}
|
||||
|
||||
std::vector<int> UniqueValues(absl::Span<const int> span) {
|
||||
absl::flat_hash_set<int> set;
|
||||
std::vector<int> out;
|
||||
for (int x : span)
|
||||
if (set.insert(x).second) out.push_back(x);
|
||||
return out;
|
||||
}
|
||||
|
||||
TEST(DenseIntDuplicateRemoverTest, RemoveDuplicatesRandomizedStressTest) {
|
||||
constexpr int kNumValues = 1003;
|
||||
DenseIntDuplicateRemover deduper(kNumValues);
|
||||
constexpr int kNumTests = 1'000'000;
|
||||
absl::BitGen random;
|
||||
for (int t = 0; t < kNumTests; ++t) {
|
||||
const int size = absl::LogUniform(random, 0, 16);
|
||||
const int domain_size =
|
||||
absl::Uniform(absl::IntervalClosed, random, 1, kNumValues);
|
||||
std::vector<int> v(size);
|
||||
for (int& x : v) x = absl::Uniform(random, 0, domain_size);
|
||||
const std::vector<int> v_initial = v;
|
||||
const std::vector<int> unique_values = UniqueValues(v);
|
||||
deduper.RemoveDuplicates(&v);
|
||||
ASSERT_THAT(v, ElementsAreArray(unique_values)) << DUMP_VARS(t, v_initial);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DenseIntDuplicateRemoverTest,
|
||||
AppendAndLazilyRemoveDuplicatesRandomizedStressTest) {
|
||||
constexpr int kNumValues = 103;
|
||||
constexpr int kNumTests = 1'000;
|
||||
std::mt19937 random;
|
||||
gtl::linked_hash_set<int> reference;
|
||||
std::vector<int> v;
|
||||
int64_t num_extra_elements = 0;
|
||||
int64_t num_unique_elements = 0;
|
||||
for (int t = 0; t < kNumTests; ++t) {
|
||||
const int num_inserts = absl::LogUniform(random, 2, 1 << 16);
|
||||
const int domain_size =
|
||||
absl::Uniform(absl::IntervalClosed, random, 1, kNumValues);
|
||||
v.clear();
|
||||
reference.clear();
|
||||
DenseIntDuplicateRemover deduper(domain_size);
|
||||
for (int i = 0; i < num_inserts; ++i) {
|
||||
const int x = absl::Uniform(random, 0, domain_size);
|
||||
deduper.AppendAndLazilyRemoveDuplicates(x, &v);
|
||||
reference.insert(x);
|
||||
}
|
||||
ASSERT_LE(v.size(), domain_size * 2 + 15);
|
||||
const int old_size = v.size();
|
||||
deduper.RemoveDuplicates(&v);
|
||||
num_unique_elements += v.size();
|
||||
num_extra_elements += old_size - v.size();
|
||||
ASSERT_THAT(v, ElementsAreArray(reference))
|
||||
<< DUMP_VARS(t, num_inserts, domain_size, old_size, v.size());
|
||||
}
|
||||
EXPECT_LE(static_cast<double>(num_extra_elements) / num_unique_elements, 0.5);
|
||||
}
|
||||
|
||||
template <bool use_flat_hash_set>
|
||||
void BM_AppendAndLazilyRemoveDuplicates(benchmark::State& state) {
|
||||
const int num_inserts = state.range(0);
|
||||
const int domain_size = state.range(1);
|
||||
std::vector<int> to_insert(num_inserts);
|
||||
random_engine_t random;
|
||||
for (int& x : to_insert) x = absl::Uniform(random, 0, domain_size);
|
||||
DenseIntDuplicateRemover deduper(domain_size);
|
||||
std::vector<int> v;
|
||||
absl::flat_hash_set<int> set;
|
||||
for (auto _ : state) {
|
||||
v.clear();
|
||||
set.clear();
|
||||
for (int x : to_insert) {
|
||||
if (use_flat_hash_set) {
|
||||
set.insert(x);
|
||||
} else {
|
||||
deduper.AppendAndLazilyRemoveDuplicates(x, &v);
|
||||
}
|
||||
}
|
||||
if (!use_flat_hash_set) deduper.RemoveDuplicates(&v);
|
||||
benchmark::DoNotOptimize(v);
|
||||
benchmark::DoNotOptimize(set);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * num_inserts);
|
||||
}
|
||||
|
||||
BENCHMARK(BM_AppendAndLazilyRemoveDuplicates<true>)
|
||||
->ArgPair(1, 10)
|
||||
->ArgPair(10, 2)
|
||||
->ArgPair(10, 10)
|
||||
->ArgPair(100, 100)
|
||||
->ArgPair(100, 10)
|
||||
->ArgPair(10'000, 10'000)
|
||||
->ArgPair(10'000, 1'000)
|
||||
->ArgPair(10'000, 100)
|
||||
->ArgPair(10'000, 10)
|
||||
->ArgPair(1'000'000, 1'000'000)
|
||||
->ArgPair(1'000'000, 10'000)
|
||||
->ArgPair(1'000'000, 100);
|
||||
|
||||
BENCHMARK(BM_AppendAndLazilyRemoveDuplicates<false>)
|
||||
->ArgPair(1, 10)
|
||||
->ArgPair(10, 2)
|
||||
->ArgPair(10, 10)
|
||||
->ArgPair(100, 100)
|
||||
->ArgPair(100, 10)
|
||||
->ArgPair(10'000, 10'000)
|
||||
->ArgPair(10'000, 1'000)
|
||||
->ArgPair(10'000, 100)
|
||||
->ArgPair(10'000, 10)
|
||||
->ArgPair(1'000'000, 1'000'000)
|
||||
->ArgPair(1'000'000, 10'000)
|
||||
->ArgPair(1'000'000, 100);
|
||||
|
||||
} // namespace
|
||||
} // namespace operations_research
|
||||
@@ -1,428 +0,0 @@
|
||||
// Copyright 2010-2024 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/log/check.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/algorithms/set_cover_heuristics.h"
|
||||
#include "ortools/algorithms/set_cover_invariant.h"
|
||||
#include "ortools/algorithms/set_cover_lagrangian.h"
|
||||
#include "ortools/algorithms/set_cover_mip.h"
|
||||
#include "ortools/algorithms/set_cover_model.h"
|
||||
#include "ortools/algorithms/set_cover_reader.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/path.h"
|
||||
#include "ortools/base/timer.h"
|
||||
|
||||
namespace operations_research {
|
||||
|
||||
void LogStats(std::string name, SetCoverModel* model) {
|
||||
LOG(INFO) << ", " << name << ", num_elements, " << model->num_elements()
|
||||
<< ", num_subsets, " << model->num_subsets();
|
||||
LOG(INFO) << ", " << name << ", num_nonzeros, " << model->num_nonzeros()
|
||||
<< ", fill rate, " << model->FillRate();
|
||||
LOG(INFO) << ", " << name << ", cost, "
|
||||
<< model->ComputeCostStats().DebugString();
|
||||
|
||||
LOG(INFO) << ", " << name << ", num_rows, " << model->num_elements()
|
||||
<< ", rows sizes, " << model->ComputeRowStats().DebugString();
|
||||
LOG(INFO) << ", " << name << ", row size deciles, "
|
||||
<< absl::StrJoin(model->ComputeRowDeciles(), ", ");
|
||||
LOG(INFO) << ", " << name << ", num_columns, " << model->num_subsets()
|
||||
<< ", columns sizes, " << model->ComputeColumnStats().DebugString();
|
||||
LOG(INFO) << ", " << name << ", column size deciles, "
|
||||
<< absl::StrJoin(model->ComputeColumnDeciles(), ", ");
|
||||
SetCoverInvariant inv(model);
|
||||
Preprocessor preprocessor(&inv);
|
||||
preprocessor.NextSolution();
|
||||
LOG(INFO) << ", " << name << ", num_columns_fixed_by_singleton_row, "
|
||||
<< preprocessor.num_columns_fixed_by_singleton_row();
|
||||
}
|
||||
|
||||
void LogCostAndTiming(std::string name, std::string algo, double cost,
|
||||
absl::Duration duration) {
|
||||
LOG(INFO) << ", " << name << ", " << algo << "_cost, " << cost << ", "
|
||||
<< absl::ToInt64Microseconds(duration) << "e-6, s";
|
||||
}
|
||||
|
||||
SetCoverInvariant RunChvatalAndSteepest(std::string name,
|
||||
SetCoverModel* model) {
|
||||
SetCoverInvariant inv(model);
|
||||
GreedySolutionGenerator greedy(&inv);
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
CHECK(greedy.NextSolution());
|
||||
DCHECK(inv.CheckConsistency());
|
||||
LogCostAndTiming(name, "GreedySolutionGenerator", inv.cost(),
|
||||
timer.GetDuration());
|
||||
SteepestSearch steepest(&inv);
|
||||
steepest.NextSolution(100000);
|
||||
LogCostAndTiming(name, "GreedySteepestSearch", inv.cost(),
|
||||
timer.GetDuration());
|
||||
DCHECK(inv.CheckConsistency());
|
||||
return inv;
|
||||
}
|
||||
|
||||
SetCoverInvariant RunChvatalAndGLS(std::string name, SetCoverModel* model) {
|
||||
SetCoverInvariant inv(model);
|
||||
GreedySolutionGenerator greedy(&inv);
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
CHECK(greedy.NextSolution());
|
||||
DCHECK(inv.CheckConsistency());
|
||||
LogCostAndTiming(name, "GreedySolutionGenerator", inv.cost(),
|
||||
timer.GetDuration());
|
||||
GuidedLocalSearch gls(&inv);
|
||||
gls.NextSolution(100'000);
|
||||
LogCostAndTiming(name, "GLS", inv.cost(), timer.GetDuration());
|
||||
DCHECK(inv.CheckConsistency());
|
||||
return inv;
|
||||
}
|
||||
|
||||
SetCoverInvariant RunElementDegreeGreedyAndSteepest(std::string name,
|
||||
SetCoverModel* model) {
|
||||
SetCoverInvariant inv(model);
|
||||
ElementDegreeSolutionGenerator element_degree(&inv);
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
CHECK(element_degree.NextSolution());
|
||||
DCHECK(inv.CheckConsistency());
|
||||
LogCostAndTiming(name, "ElementDegreeSolutionGenerator", inv.cost(),
|
||||
timer.GetDuration());
|
||||
SteepestSearch steepest(&inv);
|
||||
steepest.NextSolution(100000);
|
||||
LogCostAndTiming(name, "ElementDegreeSteepestSearch", inv.cost(),
|
||||
timer.GetDuration());
|
||||
DCHECK(inv.CheckConsistency());
|
||||
return inv;
|
||||
}
|
||||
|
||||
void IterateClearAndMip(std::string name, SetCoverInvariant* inv) {
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
std::vector<SubsetIndex> focus = inv->model()->all_subsets();
|
||||
double best_cost = inv->cost();
|
||||
SubsetBoolVector best_choices = inv->is_selected();
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
std::vector<SubsetIndex> range =
|
||||
ClearMostCoveredElements(std::min(100UL, focus.size()), inv);
|
||||
SetCoverMip mip(inv);
|
||||
mip.NextSolution(range, true, 0.02);
|
||||
DCHECK(inv->CheckConsistency());
|
||||
if (inv->cost() < best_cost) {
|
||||
best_cost = inv->cost();
|
||||
best_choices = inv->is_selected();
|
||||
}
|
||||
}
|
||||
timer.Stop();
|
||||
LogCostAndTiming(name, "IterateClearAndMip", best_cost, timer.GetDuration());
|
||||
}
|
||||
|
||||
SetCoverInvariant ComputeLPLowerBound(std::string name, SetCoverModel* model) {
|
||||
SetCoverInvariant inv(model);
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
SetCoverMip mip(&inv, SetCoverMipSolver::SCIP); // Use Gurobi for large pbs.
|
||||
mip.NextSolution(false, .3); // Use 300s or more for large problems.
|
||||
LogCostAndTiming(name, "LPLowerBound", mip.lower_bound(),
|
||||
timer.GetDuration());
|
||||
return inv;
|
||||
}
|
||||
|
||||
void ComputeLagrangianLowerBound(std::string name, SetCoverInvariant* inv) {
|
||||
const SetCoverModel* model = inv->model();
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
SetCoverLagrangian lagrangian(inv, /*num_threads=*/8);
|
||||
const auto [lower_bound, reduced_costs, multipliers] =
|
||||
lagrangian.ComputeLowerBound(model->subset_costs(), inv->cost());
|
||||
LogCostAndTiming(name, "LagrangianLowerBound", lower_bound,
|
||||
timer.GetDuration());
|
||||
}
|
||||
|
||||
SetCoverInvariant RunMip(std::string name, SetCoverModel* model) {
|
||||
SetCoverInvariant inv(model);
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
SetCoverMip mip(&inv, SetCoverMipSolver::SCIP); // Use Gurobi for large pbs.
|
||||
mip.NextSolution(true, .5); // Use 300s or more for large problems.
|
||||
timer.Stop();
|
||||
LogCostAndTiming(name, "MIP", inv.cost(), timer.GetDuration());
|
||||
return inv;
|
||||
}
|
||||
|
||||
void IterateClearElementDegreeAndSteepest(std::string name,
|
||||
SetCoverInvariant* inv) {
|
||||
WallTimer timer;
|
||||
timer.Start();
|
||||
double best_cost = inv->cost();
|
||||
SubsetBoolVector best_choices = inv->is_selected();
|
||||
ElementDegreeSolutionGenerator element_degree(inv);
|
||||
SteepestSearch steepest(inv);
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
std::vector<SubsetIndex> range =
|
||||
ClearRandomSubsets(0.1 * inv->trace().size(), inv);
|
||||
CHECK(element_degree.NextSolution());
|
||||
steepest.NextSolution(range, 100000);
|
||||
DCHECK(inv->CheckConsistency());
|
||||
if (inv->cost() < best_cost) {
|
||||
best_cost = inv->cost();
|
||||
best_choices = inv->is_selected();
|
||||
}
|
||||
}
|
||||
timer.Stop();
|
||||
LogCostAndTiming(name, "IterateClearElementDegreeAndSteepest", best_cost,
|
||||
timer.GetDuration());
|
||||
}
|
||||
|
||||
double RunSolver(std::string name, SetCoverModel* model) {
|
||||
LogStats(name, model);
|
||||
WallTimer global_timer;
|
||||
global_timer.Start();
|
||||
RunChvatalAndSteepest(name, model);
|
||||
// SetCoverInvariant inv = ComputeLPLowerBound(name, model);
|
||||
// RunMip(name, model);
|
||||
RunChvatalAndGLS(name, model);
|
||||
SetCoverInvariant inv = RunElementDegreeGreedyAndSteepest(name, model);
|
||||
ComputeLagrangianLowerBound(name, &inv);
|
||||
// IterateClearAndMip(name, inv);
|
||||
IterateClearElementDegreeAndSteepest(name, &inv);
|
||||
return inv.cost();
|
||||
}
|
||||
|
||||
// We break down the ORLIB set covering problems by their expected runtime with
|
||||
// our solver (as of July 2023).
|
||||
enum ProblemSize {
|
||||
SUBMILLI, // < 1ms
|
||||
FEWMILLIS, // < 3ms
|
||||
SUBHUNDREDTH, // < 10ms
|
||||
FEWHUNDREDTHS, // < 30ms
|
||||
SUBTENTH, // < 100ms
|
||||
FEWTENTHS, // < 300ms
|
||||
SUBSECOND, // < 1s
|
||||
FEWSECONDS, // < 3s
|
||||
MANYSECONDS, // >= 3s
|
||||
UNKNOWN = 999, // Not known (i.e. not benchmarked).
|
||||
};
|
||||
|
||||
// These two macros provide indirection which allows the __LINE__ macro
|
||||
// to be pasted, giving the tests useful names.
|
||||
#define APPEND(x, y) x##y
|
||||
#define APPEND_AND_EVAL(x, y) APPEND(x, y)
|
||||
|
||||
const char data_dir[] =
|
||||
"operations_research_data/operations_research_data/"
|
||||
"SET_COVERING";
|
||||
|
||||
// In the following, the lower bounds are taken from:
|
||||
// [1] Caprara, Alberto, Matteo Fischetti, and Paolo Toth. 1999. “A Heuristic
|
||||
// Method for the Set Covering Problem.” Operations Research 47 (5): 730–43.
|
||||
// https://www.jstor.org/stable/223097 , and
|
||||
// [2] Yagiura, Mutsunori, Masahiro Kishida, and Toshihide Ibaraki. 2006.
|
||||
// “A 3-Flip Neighborhood Local Search for the Set Covering Problem.” European
|
||||
// Journal of Operational Research 172 (2): 472–99.
|
||||
// https://www.sciencedirect.com/science/article/pii/S0377221704008264
|
||||
|
||||
// This macro makes it possible to declare each test below with a one-liner.
|
||||
// 'best_objective' denotes the best objective costs found in literature.
|
||||
// These are the proven optimal values. This can be achieved with MIP.
|
||||
// For the rail instances, they are the best solution found in the literature
|
||||
// [1] and [2]. They are not achievable though local search or MIP or a
|
||||
// combination of the two.
|
||||
// 'expected_objective' are the costs currently reached by the solver.
|
||||
// TODO(user): find and add values for the unit cost (aka unicost) case.
|
||||
|
||||
#define ORLIB_TEST(name, best_objective, expected_objective, size, function) \
|
||||
TEST(OrlibTest, APPEND_AND_EVAL(TestOnLine, __LINE__)) { \
|
||||
auto filespec = \
|
||||
file::JoinPathRespectAbsolute(::testing::SrcDir(), data_dir, name); \
|
||||
LOG(INFO) << "Reading " << name; \
|
||||
operations_research::SetCoverModel model = function(filespec); \
|
||||
double cost = RunSolver(name, &model); \
|
||||
(void)cost; \
|
||||
}
|
||||
|
||||
#define ORLIB_UNICOST_TEST(name, best_objective, expected_objective, size, \
|
||||
function) \
|
||||
TEST(OrlibUnicostTest, APPEND_AND_EVAL(TestOnLine, __LINE__)) { \
|
||||
auto filespec = \
|
||||
file::JoinPathRespectAbsolute(::testing::SrcDir(), data_dir, name); \
|
||||
LOG(INFO) << "Reading " << name; \
|
||||
operations_research::SetCoverModel model = function(filespec); \
|
||||
for (SubsetIndex i : model.SubsetRange()) { \
|
||||
model.SetSubsetCost(i, 1.0); \
|
||||
} \
|
||||
double cost = RunSolver(absl::StrCat(name, "_unicost"), &model); \
|
||||
(void)cost; \
|
||||
}
|
||||
|
||||
#define SCP_TEST(name, best_objective, expected_objective, size) \
|
||||
ORLIB_TEST(name, best_objective, expected_objective, size, \
|
||||
operations_research::ReadBeasleySetCoverProblem) \
|
||||
ORLIB_UNICOST_TEST(name, best_objective, expected_objective, size, \
|
||||
operations_research::ReadBeasleySetCoverProblem)
|
||||
|
||||
#define RAIL_TEST(name, best_objective, expected_objective, size) \
|
||||
ORLIB_TEST(name, best_objective, expected_objective, size, \
|
||||
operations_research::ReadRailSetCoverProblem) \
|
||||
ORLIB_UNICOST_TEST(name, best_objective, expected_objective, size, \
|
||||
operations_research::ReadRailSetCoverProblem)
|
||||
|
||||
#define BASIC_SCP
|
||||
#define EXTRA_SCP
|
||||
#define RAIL
|
||||
|
||||
#ifdef BASIC_SCP
|
||||
SCP_TEST("scp41.txt", 429, 442, FEWMILLIS);
|
||||
SCP_TEST("scp42.txt", 512, 555, FEWMILLIS);
|
||||
SCP_TEST("scp43.txt", 516, 557, FEWMILLIS);
|
||||
SCP_TEST("scp44.txt", 494, 516, FEWMILLIS);
|
||||
SCP_TEST("scp45.txt", 512, 530, FEWMILLIS);
|
||||
SCP_TEST("scp46.txt", 560, 594, FEWMILLIS);
|
||||
SCP_TEST("scp47.txt", 430, 451, FEWMILLIS);
|
||||
SCP_TEST("scp48.txt", 492, 502, FEWMILLIS);
|
||||
SCP_TEST("scp49.txt", 641, 693, FEWMILLIS);
|
||||
SCP_TEST("scp410.txt", 514, 525, FEWMILLIS);
|
||||
|
||||
SCP_TEST("scp51.txt", 253, 274, FEWMILLIS);
|
||||
SCP_TEST("scp52.txt", 302, 329, FEWMILLIS);
|
||||
SCP_TEST("scp53.txt", 226, 233, FEWMILLIS);
|
||||
SCP_TEST("scp54.txt", 242, 255, FEWMILLIS);
|
||||
SCP_TEST("scp55.txt", 211, 222, FEWMILLIS);
|
||||
SCP_TEST("scp56.txt", 213, 234, FEWMILLIS);
|
||||
SCP_TEST("scp57.txt", 293, 313, FEWMILLIS);
|
||||
SCP_TEST("scp58.txt", 288, 309, FEWMILLIS);
|
||||
SCP_TEST("scp59.txt", 279, 292, FEWMILLIS);
|
||||
SCP_TEST("scp510.txt", 265, 276, FEWMILLIS);
|
||||
|
||||
SCP_TEST("scp61.txt", 138, 151, FEWMILLIS);
|
||||
SCP_TEST("scp62.txt", 146, 173, FEWMILLIS);
|
||||
SCP_TEST("scp63.txt", 145, 154, FEWMILLIS);
|
||||
SCP_TEST("scp64.txt", 131, 137, FEWMILLIS);
|
||||
SCP_TEST("scp65.txt", 161, 181, FEWMILLIS);
|
||||
|
||||
SCP_TEST("scpa1.txt", 253, 275, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpa2.txt", 252, 268, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpa3.txt", 232, 244, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpa4.txt", 234, 253, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpa5.txt", 236, 249, FEWHUNDREDTHS);
|
||||
|
||||
SCP_TEST("scpb1.txt", 69, 74, FEWTENTHS);
|
||||
SCP_TEST("scpb2.txt", 76, 78, FEWTENTHS);
|
||||
SCP_TEST("scpb3.txt", 80, 85, FEWTENTHS);
|
||||
SCP_TEST("scpb4.txt", 79, 85, FEWTENTHS);
|
||||
SCP_TEST("scpb5.txt", 72, 77, FEWTENTHS);
|
||||
|
||||
SCP_TEST("scpc1.txt", 227, 251, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpc2.txt", 219, 238, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpc3.txt", 243, 259, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpc4.txt", 219, 246, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpc5.txt", 214, 228, FEWHUNDREDTHS);
|
||||
|
||||
SCP_TEST("scpd1.txt", 60, 68, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpd2.txt", 66, 70, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpd3.txt", 72, 78, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpd4.txt", 62, 67, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpd5.txt", 61, 72, FEWHUNDREDTHS);
|
||||
|
||||
SCP_TEST("scpe1.txt", 5, 5, FEWMILLIS);
|
||||
SCP_TEST("scpe2.txt", 5, 6, FEWMILLIS);
|
||||
SCP_TEST("scpe3.txt", 5, 5, FEWMILLIS);
|
||||
SCP_TEST("scpe4.txt", 5, 6, FEWMILLIS);
|
||||
SCP_TEST("scpe5.txt", 5, 5, FEWMILLIS);
|
||||
|
||||
SCP_TEST("scpnre1.txt", 29, 31, SUBTENTH);
|
||||
SCP_TEST("scpnre2.txt", 30, 34, SUBTENTH);
|
||||
SCP_TEST("scpnre3.txt", 27, 32, SUBTENTH);
|
||||
SCP_TEST("scpnre4.txt", 28, 32, SUBTENTH);
|
||||
SCP_TEST("scpnre5.txt", 28, 31, SUBTENTH);
|
||||
|
||||
SCP_TEST("scpnrf1.txt", 14, 17, SUBTENTH);
|
||||
SCP_TEST("scpnrf2.txt", 15, 16, SUBTENTH);
|
||||
SCP_TEST("scpnrf3.txt", 14, 16, SUBTENTH);
|
||||
SCP_TEST("scpnrf4.txt", 14, 15, SUBTENTH);
|
||||
SCP_TEST("scpnrf5.txt", 13, 15, SUBTENTH);
|
||||
|
||||
SCP_TEST("scpnrg1.txt", 176, 196, SUBTENTH);
|
||||
SCP_TEST("scpnrg2.txt", 154, 171, SUBTENTH);
|
||||
SCP_TEST("scpnrg3.txt", 166, 182, SUBTENTH);
|
||||
SCP_TEST("scpnrg4.txt", 168, 187, SUBTENTH);
|
||||
SCP_TEST("scpnrg5.txt", 168, 183, SUBTENTH);
|
||||
|
||||
SCP_TEST("scpnrh1.txt", 63, 71, FEWTENTHS);
|
||||
SCP_TEST("scpnrh2.txt", 63, 70, FEWTENTHS);
|
||||
SCP_TEST("scpnrh3.txt", 59, 65, FEWTENTHS);
|
||||
SCP_TEST("scpnrh4.txt", 58, 66, FEWTENTHS);
|
||||
SCP_TEST("scpnrh5.txt", 55, 62, FEWTENTHS);
|
||||
#endif
|
||||
|
||||
#ifdef EXTRA_SCP
|
||||
SCP_TEST("scpclr10.txt", 0, 32, FEWMILLIS);
|
||||
SCP_TEST("scpclr11.txt", 0, 30, FEWMILLIS);
|
||||
SCP_TEST("scpclr12.txt", 0, 31, FEWMILLIS);
|
||||
SCP_TEST("scpclr13.txt", 0, 33, FEWMILLIS);
|
||||
|
||||
SCP_TEST("scpcyc06.txt", 0, 60, FEWMILLIS);
|
||||
SCP_TEST("scpcyc07.txt", 0, 144, FEWMILLIS);
|
||||
SCP_TEST("scpcyc08.txt", 0, 360, FEWMILLIS);
|
||||
SCP_TEST("scpcyc09.txt", 0, 816, SUBHUNDREDTH);
|
||||
SCP_TEST("scpcyc10.txt", 0, 1920, FEWHUNDREDTHS);
|
||||
SCP_TEST("scpcyc11.txt", 0, 4284, SUBTENTH);
|
||||
#endif
|
||||
|
||||
#ifdef RAIL
|
||||
RAIL_TEST("rail507.txt", 174, 218, FEWTENTHS);
|
||||
RAIL_TEST("rail516.txt", 182, 204, FEWTENTHS);
|
||||
RAIL_TEST("rail582.txt", 211, 250, FEWTENTHS);
|
||||
RAIL_TEST("rail2536.txt", 691, 889, MANYSECONDS);
|
||||
RAIL_TEST("rail2586.txt", 952, 1139, MANYSECONDS);
|
||||
RAIL_TEST("rail4284.txt", 1065, 1362, MANYSECONDS);
|
||||
RAIL_TEST("rail4872.txt", 1527, 1861, MANYSECONDS); // [2]
|
||||
#endif
|
||||
|
||||
#undef BASIC_SCP
|
||||
#undef EXTRA_SCP
|
||||
#undef RAIL
|
||||
|
||||
#undef ORLIB_TEST
|
||||
#undef ORLIB_UNICOST_TEST
|
||||
#undef APPEND
|
||||
#undef APPEND_AND_EVAL
|
||||
#undef SCP_TEST
|
||||
#undef RAIL_TEST
|
||||
|
||||
TEST(SetCoverHugeTest, GenerateProblem) {
|
||||
SetCoverModel seed_model =
|
||||
ReadRailSetCoverProblem(file::JoinPathRespectAbsolute(
|
||||
::testing::SrcDir(), data_dir, "rail4284.txt"));
|
||||
seed_model.CreateSparseRowView();
|
||||
const BaseInt num_wanted_subsets(100'000'000);
|
||||
const BaseInt num_wanted_elements(40'000);
|
||||
const double row_scale = 1.1;
|
||||
const double column_scale = 1.1;
|
||||
const double cost_scale = 10.0;
|
||||
SetCoverModel model = SetCoverModel::GenerateRandomModelFrom(
|
||||
seed_model, num_wanted_elements, num_wanted_subsets, row_scale,
|
||||
column_scale, cost_scale);
|
||||
SetCoverInvariant inv =
|
||||
RunElementDegreeGreedyAndSteepest("rail4284_huge.txt", &model);
|
||||
LOG(INFO) << "Cost: " << inv.cost();
|
||||
}
|
||||
|
||||
} // namespace operations_research
|
||||
@@ -187,6 +187,10 @@ class RevisedSimplex {
|
||||
double DeterministicTime() const;
|
||||
bool objective_limit_reached() const { return objective_limit_reached_; }
|
||||
|
||||
DenseColumn::ConstView GetDualSquaredNorms() {
|
||||
return dual_edge_norms_.GetEdgeSquaredNorms();
|
||||
}
|
||||
|
||||
const DenseBitRow& GetNotBasicBitRow() const {
|
||||
return variables_info_.GetNotBasicBitRow();
|
||||
}
|
||||
|
||||
@@ -39,3 +39,34 @@ target_link_libraries(${NAME} PRIVATE
|
||||
${PROJECT_NAMESPACE}::ortools_proto
|
||||
$<$<BOOL:${USE_COINOR}>:Coin::Cbc>)
|
||||
#add_library(${PROJECT_NAMESPACE}::graph ALIAS ${NAME})
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
list(FILTER _TEST_SRCS EXCLUDE REGEX "max_flow_test.cc")
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
graph_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
graph_max_flow_test
|
||||
SOURCES
|
||||
"max_flow_test.cc"
|
||||
LINK_LIBRARIES
|
||||
benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
COMPILE_DEFINITIONS
|
||||
-DROOT_DIR="../../"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
#include "ortools/linear_solver/linear_solver.h"
|
||||
#include "ortools/util/file_util.h"
|
||||
|
||||
#if not defined(ROOT_DIR)
|
||||
#define ROOT_DIR "com_google_ortools/"
|
||||
#endif
|
||||
|
||||
namespace operations_research {
|
||||
namespace {
|
||||
|
||||
@@ -402,7 +402,7 @@ PROTO2_RETURN(
|
||||
%rename (suppressOutput) operations_research::MPSolver::SuppressOutput; // no test
|
||||
%rename (lookupConstraintOrNull) operations_research::MPSolver::LookupConstraintOrNull; // no test
|
||||
%rename (lookupVariableOrNull) operations_research::MPSolver::LookupVariableOrNull; // no test
|
||||
%rename (write) operations_research::MPSolver::Write;
|
||||
%rename (write) operations_research::MPSolver::Write; // no test
|
||||
|
||||
// Expose very advanced parts of the MPSolver API. For expert users only.
|
||||
%rename (computeConstraintActivities) operations_research::MPSolver::ComputeConstraintActivities;
|
||||
|
||||
@@ -20,6 +20,7 @@ add_subdirectory(constraints)
|
||||
add_subdirectory(cpp)
|
||||
add_subdirectory(io)
|
||||
add_subdirectory(labs)
|
||||
add_subdirectory(solver_tests)
|
||||
add_subdirectory(solvers)
|
||||
add_subdirectory(storage)
|
||||
add_subdirectory(validators)
|
||||
|
||||
@@ -26,3 +26,21 @@ target_link_libraries(${NAME} PRIVATE
|
||||
absl::strings
|
||||
${PROJECT_NAMESPACE}::math_opt_proto)
|
||||
#install(TARGETS ${NAME} EXPORT ${PROJECT_NAME}Targets)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_constraints_indicator_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
#benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -25,3 +25,21 @@ target_include_directories(${NAME} PUBLIC
|
||||
target_link_libraries(${NAME} PRIVATE
|
||||
absl::strings
|
||||
${PROJECT_NAMESPACE}::math_opt_proto)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_constraints_quadratic_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
#benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -25,3 +25,21 @@ target_include_directories(${NAME} PUBLIC
|
||||
target_link_libraries(${NAME} PRIVATE
|
||||
absl::strings
|
||||
${PROJECT_NAMESPACE}::math_opt_proto)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_constraints_second_order_cone_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
#benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -25,3 +25,21 @@ target_include_directories(${NAME} PUBLIC
|
||||
target_link_libraries(${NAME} PRIVATE
|
||||
absl::strings
|
||||
${PROJECT_NAMESPACE}::math_opt_proto)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_constraints_sos_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
#benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -25,3 +25,21 @@ target_include_directories(${NAME} PUBLIC
|
||||
target_link_libraries(${NAME} PRIVATE
|
||||
absl::strings
|
||||
${PROJECT_NAMESPACE}::math_opt_proto)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_constraints_util_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
#benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -25,3 +25,19 @@ target_include_directories(${NAME} PUBLIC
|
||||
target_link_libraries(${NAME} PRIVATE
|
||||
absl::strings
|
||||
${PROJECT_NAMESPACE}::math_opt_proto)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
math_opt_matchers
|
||||
SOURCES
|
||||
"matchers.cc"
|
||||
"matchers.h"
|
||||
TYPE
|
||||
SHARED
|
||||
LINK_LIBRARIES
|
||||
absl::log
|
||||
absl::status
|
||||
absl::strings
|
||||
GTest::gmock
|
||||
TESTING
|
||||
)
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
cc_binary(
|
||||
name = "basic_example",
|
||||
srcs = ["basic_example.cc"],
|
||||
|
||||
372
ortools/math_opt/solver_tests/CMakeLists.txt
Normal file
372
ortools/math_opt/solver_tests/CMakeLists.txt
Normal file
@@ -0,0 +1,372 @@
|
||||
# Copyright 2010-2024 Google LLC
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(_PREFIX math_opt)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_base_solver_test
|
||||
SOURCES
|
||||
"base_solver_test.cc"
|
||||
"base_solver_test.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_callback_tests
|
||||
SOURCES
|
||||
"callback_tests.cc"
|
||||
"callback_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
absl::status
|
||||
absl::strings
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_base_solver_test
|
||||
ortools::math_opt_test_models
|
||||
TESTING
|
||||
)
|
||||
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_status_tests
|
||||
SOURCES
|
||||
"status_tests.cc"
|
||||
"status_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_test_models
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_lp_tests
|
||||
SOURCES
|
||||
"lp_tests.cc"
|
||||
"lp_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_base_solver_test
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_lp_incomplete_solve_tests
|
||||
SOURCES
|
||||
"lp_incomplete_solve_tests.cc"
|
||||
"lp_incomplete_solve_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_test_models
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_invalid_input_tests
|
||||
SOURCES
|
||||
"invalid_input_tests.cc"
|
||||
"invalid_input_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_base_solver_test
|
||||
TESTING
|
||||
)
|
||||
|
||||
# In CMake or-tools is linked with all enable solvers so this test won't work.
|
||||
#ortools_cxx_test(
|
||||
# NAME
|
||||
# ${_PREFIX}_unregistered_solver_test
|
||||
# SOURCES
|
||||
# "unregistered_solver_test.cc"
|
||||
# LINK_LIBRARIES
|
||||
# GTest::gmock
|
||||
# GTest::gmock_main
|
||||
#)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_mip_tests
|
||||
SOURCES
|
||||
"mip_tests.cc"
|
||||
"mip_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
absl::status
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_base_solver_test
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_ip_model_solve_parameters_tests
|
||||
SOURCES
|
||||
"ip_model_solve_parameters_tests.cc"
|
||||
"ip_model_solve_parameters_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_base_solver_test
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_ip_multiple_solutions_tests
|
||||
SOURCES
|
||||
"ip_multiple_solutions_tests.cc"
|
||||
"ip_multiple_solutions_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::strings
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_lp_model_solve_parameters_tests
|
||||
SOURCES
|
||||
"lp_model_solve_parameters_tests.cc"
|
||||
"lp_model_solve_parameters_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_base_solver_test
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_lp_parameter_tests
|
||||
SOURCES
|
||||
"lp_parameter_tests.cc"
|
||||
"lp_parameter_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
absl::status
|
||||
absl::strings
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_lp_initial_basis_tests
|
||||
SOURCES
|
||||
"lp_initial_basis_tests.cc"
|
||||
"lp_initial_basis_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
absl::status
|
||||
ortools::math_opt_base_solver_test
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_ip_parameter_tests
|
||||
SOURCES
|
||||
"ip_parameter_tests.cc"
|
||||
"ip_parameter_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_test_models
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_multi_objective_tests
|
||||
SOURCES
|
||||
"multi_objective_tests.cc"
|
||||
"multi_objective_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_qp_tests
|
||||
SOURCES
|
||||
"qp_tests.cc"
|
||||
"qp_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_qc_tests
|
||||
SOURCES
|
||||
"qc_tests.cc"
|
||||
"qc_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_second_order_cone_tests
|
||||
SOURCES
|
||||
"second_order_cone_tests.cc"
|
||||
"second_order_cone_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_logical_constraint_tests
|
||||
SOURCES
|
||||
"logical_constraint_tests.cc"
|
||||
"logical_constraint_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_test_models
|
||||
SOURCES
|
||||
"test_models.cc"
|
||||
"test_models.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
absl::log
|
||||
absl::strings
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
${_PREFIX}_test_models_test
|
||||
SOURCES
|
||||
"test_models_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
GTest::gmock_main
|
||||
ortools::math_opt_test_models
|
||||
ortools::math_opt_matchers
|
||||
#ortools::math_opt_glop_solver
|
||||
#ortools::math_opt_gscipt_solver
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_generic_tests
|
||||
SOURCES
|
||||
"generic_tests.cc"
|
||||
"generic_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
ortools::math_opt_matchers
|
||||
ortools::math_opt_test_models
|
||||
TESTING
|
||||
)
|
||||
|
||||
ortools_cxx_library(
|
||||
NAME
|
||||
${_PREFIX}_infeasible_subsystem_tests
|
||||
SOURCES
|
||||
"infeasible_subsystem_tests.cc"
|
||||
"infeasible_subsystem_tests.h"
|
||||
TYPE
|
||||
STATIC
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
absl::log
|
||||
absl::status
|
||||
absl::strings
|
||||
absl::time
|
||||
ortools::math_opt_matchers
|
||||
TESTING
|
||||
)
|
||||
@@ -618,6 +618,7 @@ cc_test(
|
||||
"//ortools/math_opt/solver_tests:lp_parameter_tests",
|
||||
"//ortools/math_opt/solver_tests:lp_tests",
|
||||
"//ortools/math_opt/solver_tests:mip_tests",
|
||||
"//ortools/math_opt/solver_tests:multi_objective_tests",
|
||||
"//ortools/math_opt/solver_tests:status_tests",
|
||||
"//ortools/math_opt/testing:param_name",
|
||||
"@com_google_absl//absl/status",
|
||||
|
||||
@@ -52,3 +52,183 @@ target_link_libraries(${NAME} PRIVATE
|
||||
$<$<BOOL:${USE_PDLP}>:Eigen3::Eigen>
|
||||
$<$<BOOL:${USE_SCIP}>:libscip>
|
||||
${PROJECT_NAMESPACE}::math_opt_proto)
|
||||
|
||||
if(USE_SCIP)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_solvers_gscip_solver_test
|
||||
SOURCES
|
||||
"gscip_solver_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
GTest::gmock_main
|
||||
absl::status
|
||||
ortools::math_opt_matchers
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_callback_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_generic_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_infeasible_subsystem_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_invalid_input_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_multiple_solutions_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_parameter_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_logical_constraint_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_mip_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_multi_objective_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qc_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_second_order_cone_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_status_tests>"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(USE_GLOP)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_solvers_glop_solver_test
|
||||
SOURCES
|
||||
"glop_solver_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
GTest::gmock_main
|
||||
absl::status
|
||||
ortools::math_opt_matchers
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_callback_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_generic_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_infeasible_subsystem_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_invalid_input_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_logical_constraint_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_parameter_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_incomplete_solve_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_initial_basis_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_multi_objective_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qc_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_second_order_cone_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_status_tests>"
|
||||
)
|
||||
endif()
|
||||
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_solvers_cp_sat_solver_test
|
||||
SOURCES
|
||||
"cp_sat_solver_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
GTest::gmock_main
|
||||
absl::status
|
||||
ortools::math_opt_matchers
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_callback_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_generic_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_infeasible_subsystem_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_invalid_input_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_multiple_solutions_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_parameter_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_logical_constraint_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_mip_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_multi_objective_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qc_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_second_order_cone_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_status_tests>"
|
||||
)
|
||||
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_solvers_message_callback_data_test
|
||||
SOURCES
|
||||
"message_callback_data_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock_main
|
||||
absl::cleanup
|
||||
absl::synchronization
|
||||
)
|
||||
|
||||
if(USE_PDLP)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_solvers_pdlp_solver_test
|
||||
SOURCES
|
||||
"pdlp_solver_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
GTest::gmock_main
|
||||
absl::status
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_callback_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_generic_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_infeasible_subsystem_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_invalid_input_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_logical_constraint_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_incomplete_solve_tests>"
|
||||
#"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_initial_basis_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_parameter_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_multi_objective_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qc_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_second_order_cone_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_status_tests>"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(USE_GLPK)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_solvers_glpk_solver_test
|
||||
SOURCES
|
||||
"glpk_solver_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
GTest::gmock_main
|
||||
absl::status
|
||||
absl::time
|
||||
ortools::math_opt_matchers
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_callback_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_generic_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_infeasible_subsystem_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_invalid_input_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_parameter_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_logical_constraint_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_incomplete_solve_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_parameter_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_mip_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_multi_objective_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qc_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_qp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_second_order_cone_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_status_tests>"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(USE_HIGHS)
|
||||
ortools_cxx_test(
|
||||
NAME
|
||||
math_opt_solvers_highs_solver_test
|
||||
SOURCES
|
||||
"highs_solver_test.cc"
|
||||
LINK_LIBRARIES
|
||||
GTest::gmock
|
||||
GTest::gmock_main
|
||||
absl::status
|
||||
ortools::math_opt_matchers
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_callback_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_generic_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_infeasible_subsystem_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_ip_parameter_tests>"
|
||||
#"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_logical_constraint_tests>"
|
||||
#"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_incomplete_solve_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_model_solve_parameters_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_parameter_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_lp_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_mip_tests>"
|
||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,ortools::math_opt_status_tests>"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -42,11 +42,15 @@ target_link_libraries(${NAME} PRIVATE
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
foreach(FILE_NAME IN LISTS _TEST_SRCS)
|
||||
foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS)
|
||||
get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE)
|
||||
get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME)
|
||||
ortools_cxx_test(
|
||||
FILE_NAME
|
||||
${FILE_NAME}
|
||||
DEPS
|
||||
NAME
|
||||
sat_${_NAME}
|
||||
SOURCES
|
||||
${_FILE_NAME}
|
||||
LINK_LIBRARIES
|
||||
benchmark::benchmark
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 22b7a17f..0a5a18dd 100644
|
||||
index be94fca..1529011 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -51,6 +51,7 @@ if(APPLE)
|
||||
@@ -88,6 +88,7 @@ if(APPLE)
|
||||
CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override -Wno-unused-command-line-argument -Wno-unused-result -Wno-exceptions"
|
||||
)
|
||||
+ add_compile_options(-O1)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
|
||||
endif(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 4a70789..d19c2a9 100644
|
||||
index 8c51561..f223f08 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -51,6 +51,7 @@ if(APPLE)
|
||||
@@ -88,6 +88,7 @@ if(APPLE)
|
||||
CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override -Wno-unused-command-line-argument -Wno-unused-result -Wno-exceptions"
|
||||
)
|
||||
+ add_compile_options(-O1)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
|
||||
endif(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index e1d43115..6b2a17ad 100644
|
||||
index bb95c63..7fde473 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -51,6 +51,7 @@ if(APPLE)
|
||||
@@ -88,6 +88,7 @@ if(APPLE)
|
||||
CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override -Wno-unused-command-line-argument -Wno-unused-result -Wno-exceptions"
|
||||
)
|
||||
+ add_compile_options(-O1)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
|
||||
endif(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
endif()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index fcfa658..267ddd9 100644
|
||||
index 3fc9cff..b2423fe 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -51,6 +51,7 @@ if(APPLE)
|
||||
@@ -88,6 +88,7 @@ if(APPLE)
|
||||
CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override -Wno-unused-command-line-argument -Wno-unused-result -Wno-exceptions"
|
||||
)
|
||||
+ add_compile_options(-O1)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
|
||||
endif(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
endif()
|
||||
|
||||
|
||||
18
patches/googletest-v1.15.2.patch
Normal file
18
patches/googletest-v1.15.2.patch
Normal file
@@ -0,0 +1,18 @@
|
||||
diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake
|
||||
index 580ac1c..c6cc44c 100644
|
||||
--- a/googletest/cmake/internal_utils.cmake
|
||||
+++ b/googletest/cmake/internal_utils.cmake
|
||||
@@ -190,6 +190,13 @@ function(cxx_library_with_type name type cxx_flags)
|
||||
COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
|
||||
target_compile_definitions(${name} INTERFACE
|
||||
$<INSTALL_INTERFACE:GTEST_LINKED_AS_SHARED_LIBRARY=1>)
|
||||
+ if(APPLE)
|
||||
+ set_target_properties(${name} PROPERTIES
|
||||
+ INSTALL_RPATH "@loader_path")
|
||||
+ elseif(UNIX)
|
||||
+ set_target_properties(${name} PROPERTIES
|
||||
+ INSTALL_RPATH "$ORIGIN")
|
||||
+ endif()
|
||||
endif()
|
||||
if (DEFINED GTEST_HAS_PTHREAD)
|
||||
target_link_libraries(${name} PUBLIC Threads::Threads)
|
||||
@@ -1,12 +1,12 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 7b3cee2..2ac9c9d 100644
|
||||
index bc22fbd..1c2a604 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -51,6 +51,7 @@ if(APPLE)
|
||||
@@ -88,6 +88,7 @@ if(APPLE)
|
||||
CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override -Wno-unused-command-line-argument -Wno-unused-result -Wno-exceptions"
|
||||
)
|
||||
+ add_compile_options(-O1)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
|
||||
endif(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ index ceb65a8..e142837 100644
|
||||
include_directories(${TOP_LEVEL_DIR} ${pybind11_INCLUDE_DIRS})
|
||||
diff --git a/cmake/dependencies/CMakeLists.txt b/cmake/dependencies/CMakeLists.txt
|
||||
new file mode 100644
|
||||
index 0000000..b67d564
|
||||
index 0000000..cb13e7e
|
||||
--- /dev/null
|
||||
+++ b/cmake/dependencies/CMakeLists.txt
|
||||
@@ -0,0 +1,19 @@
|
||||
@@ -158,7 +158,7 @@ index 791c245..33e614a 100644
|
||||
)
|
||||
|
||||
diff --git a/pybind11_abseil/CMakeLists.txt b/pybind11_abseil/CMakeLists.txt
|
||||
index d1b7483..ce7fd72 100644
|
||||
index d1b7483..74e3443 100644
|
||||
--- a/pybind11_abseil/CMakeLists.txt
|
||||
+++ b/pybind11_abseil/CMakeLists.txt
|
||||
@@ -42,14 +42,19 @@ target_link_libraries(ok_status_singleton_pyinit_google3
|
||||
@@ -184,7 +184,7 @@ index d1b7483..ce7fd72 100644
|
||||
target_link_libraries(ok_status_singleton
|
||||
PUBLIC ok_status_singleton_pyinit_google3)
|
||||
|
||||
@@ -150,14 +155,23 @@ target_link_libraries(status_pyinit_google3 PUBLIC register_status_bindings)
|
||||
@@ -150,14 +155,30 @@ target_link_libraries(status_pyinit_google3 PUBLIC register_status_bindings)
|
||||
|
||||
# status ====================================================================
|
||||
|
||||
@@ -195,25 +195,32 @@ index d1b7483..ce7fd72 100644
|
||||
+set_target_properties(status_py_extension_stub PROPERTIES LIBRARY_OUTPUT_NAME "status")
|
||||
+# note: macOS is APPLE and also UNIX !
|
||||
+if(APPLE)
|
||||
+ set_target_properties(status_py_extension_stub PROPERTIES SUFFIX ".so")
|
||||
+ set_target_properties(status_py_extension_stub PROPERTIES
|
||||
+ SUFFIX ".so"
|
||||
+ INSTALL_RPATH "@loader_path;@loader_path/../ortools/.libs"
|
||||
+ )
|
||||
+ set_property(TARGET status_py_extension_stub APPEND PROPERTY
|
||||
+ LINK_FLAGS "-flat_namespace -undefined suppress")
|
||||
+elseif(UNIX)
|
||||
+ set_target_properties(status_py_extension_stub PROPERTIES
|
||||
+ INSTALL_RPATH "$ORIGIN:$ORIGIN/../ortools/.libs"
|
||||
+ )
|
||||
+endif()
|
||||
+
|
||||
+add_library(pybind11_abseil::status ALIAS status_py_extension_stub)
|
||||
|
||||
-target_include_directories(status INTERFACE $<BUILD_INTERFACE:${TOP_LEVEL_DIR}>)
|
||||
+target_include_directories(status_py_extension_stub INTERFACE $<BUILD_INTERFACE:${TOP_LEVEL_DIR}>)
|
||||
+add_library(pybind11_abseil::status ALIAS status_py_extension_stub)
|
||||
|
||||
-set_target_properties(status PROPERTIES PREFIX "")
|
||||
+set_target_properties(status_py_extension_stub PROPERTIES PREFIX "")
|
||||
+target_include_directories(status_py_extension_stub INTERFACE $<BUILD_INTERFACE:${TOP_LEVEL_DIR}>)
|
||||
|
||||
-target_link_libraries(status PUBLIC status_pyinit_google3 absl::status)
|
||||
+set_target_properties(status_py_extension_stub PROPERTIES PREFIX "")
|
||||
+
|
||||
+target_link_libraries(status_py_extension_stub PUBLIC status_pyinit_google3 absl::status)
|
||||
|
||||
# import_status_module =========================================================
|
||||
|
||||
@@ -167,7 +181,7 @@ add_library(pybind11_abseil::import_status_module ALIAS import_status_module)
|
||||
@@ -167,7 +188,7 @@ add_library(pybind11_abseil::import_status_module ALIAS import_status_module)
|
||||
target_include_directories(import_status_module
|
||||
INTERFACE $<BUILD_INTERFACE:${TOP_LEVEL_DIR}>)
|
||||
|
||||
@@ -222,7 +229,7 @@ index d1b7483..ce7fd72 100644
|
||||
|
||||
# status_casters ===============================================================
|
||||
|
||||
@@ -175,25 +189,27 @@ add_library(status_casters INTERFACE)
|
||||
@@ -175,25 +196,27 @@ add_library(status_casters INTERFACE)
|
||||
add_library(pybind11_abseil::status_casters ALIAS status_casters)
|
||||
|
||||
target_include_directories(status_casters
|
||||
|
||||
18
patches/re2-2024-04-01.patch
Normal file
18
patches/re2-2024-04-01.patch
Normal file
@@ -0,0 +1,18 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index bdac5af..cedaf6e 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -131,6 +131,13 @@ set(RE2_HEADERS
|
||||
|
||||
add_library(re2 ${RE2_SOURCES})
|
||||
target_compile_features(re2 PUBLIC cxx_std_14)
|
||||
+if(APPLE)
|
||||
+ set_target_properties(re2 PROPERTIES
|
||||
+ INSTALL_RPATH "@loader_path")
|
||||
+elseif(UNIX)
|
||||
+ set_target_properties(re2 PROPERTIES
|
||||
+ INSTALL_RPATH "$ORIGIN")
|
||||
+endif()
|
||||
target_include_directories(re2 PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
|
||||
# CMake gives "set_target_properties called with incorrect number of arguments."
|
||||
# errors if we don't quote ${RE2_HEADERS}, so quote it despite prevailing style.
|
||||
Reference in New Issue
Block a user