Skip to content
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ conda activate ./.cuopt_env
pinnings are changed.

- A `build.sh` script is provided in `$CUOPT_HOME`. Running the script with no additional arguments
will install the `libcuopt`, `cuopt`, `cuopt-server`, `cuopt-sh-client` libraries and build the`documentation`. By default, the libraries are
installed to the `$CONDA_PREFIX` directory. To install into a different location, set the location
in `$INSTALL_PREFIX`. Finally, note that the script depends on the `nvcc` executable being on your
path, or defined in `$CUDACXX`.
will build the `libcuopt`, `cuopt`, `cuopt-server`, and `cuopt-sh-client` libraries without
installing them into the conda environment. Pass `--install` to also install `libcuopt` into the
active conda environment (`$CONDA_PREFIX`, or a custom location via `$PREFIX`). Note that
the script depends on the `nvcc` executable being on your path, or defined in `$CUDACXX`.

```bash
cd $CUOPT_HOME
Expand Down
38 changes: 27 additions & 11 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ARGS=$*
REPODIR=$(cd "$(dirname "$0")"; pwd)
LIBCUOPT_BUILD_DIR=${LIBCUOPT_BUILD_DIR:=${REPODIR}/cpp/build}

VALIDARGS="clean codegen libcuopt cuopt_grpc_server cuopt cuopt_server cuopt_sh_client docs deb -a -b -g -fsanitize -tsan -msan -v -l= --verbose-pdlp --build-lp-only --no-fetch-rapids --skip-c-python-adapters --skip-tests-build --skip-routing-build --skip-grpc-build --skip-fatbin-write --host-lineinfo [--cmake-args=\\\"<args>\\\"] [--cache-tool=<tool>] -n --allgpuarch --ci-only-arch --show_depr_warn -h --help"
VALIDARGS="clean codegen libcuopt cuopt_grpc_server cuopt cuopt_server cuopt_sh_client docs deb -a -b -g -fsanitize -tsan -msan -v -l= --verbose-pdlp --build-lp-only --no-fetch-rapids --skip-c-python-adapters --skip-tests-build --skip-routing-build --skip-grpc-build --skip-fatbin-write --host-lineinfo [--cmake-args=\\\"<args>\\\"] [--cache-tool=<tool>] --install --allgpuarch --ci-only-arch --show_depr_warn -h --help"
HELP="$0 [<target> ...] [<flag> ...]
where <target> is:
clean - remove all existing build artifacts and configuration (start over)
Expand All @@ -34,7 +34,7 @@ HELP="$0 [<target> ...] [<flag> ...]
-fsanitize - Build with AddressSanitizer and UndefinedBehaviorSanitizer
-tsan - Build with ThreadSanitizer (cannot be used with -fsanitize or -msan)
-msan - Build with MemorySanitizer (cannot be used with -fsanitize or -tsan)
-n - no install step
--install - install built libraries into the active conda environment (default: build only, no install)
--no-fetch-rapids - don't fetch rapids dependencies
-l= - log level. Options are: TRACE | DEBUG | INFO | WARN | ERROR | CRITICAL | OFF. Default=INFO
--verbose-pdlp - verbose mode for pdlp solver
Expand All @@ -53,7 +53,7 @@ HELP="$0 [<target> ...] [<flag> ...]
--show_depr_warn - show cmake deprecation warnings
-h - print this text

default action (no args) is to build and install 'libcuopt', 'cuopt', 'cuopt_server', and 'cuopt_sh_client' targets (pass 'docs' explicitly to build documentation)
default action (no args) is to build 'libcuopt', 'cuopt', 'cuopt_server', and 'cuopt_sh_client' targets without installing into the conda environment (pass --install to also install libcuopt into the active conda environment; pass 'docs' explicitly to build documentation)

libcuopt build dir is: ${LIBCUOPT_BUILD_DIR}

Expand All @@ -71,7 +71,7 @@ VERBOSE_FLAG=""
BUILD_TYPE=Release
DEFINE_ASSERT=False
DEFINE_PDLP_VERBOSE_MODE=False
INSTALL_TARGET=install
INSTALL_TARGET=""
BUILD_DISABLE_DEPRECATION_WARNING=ON
BUILD_ALL_GPU_ARCH=0
BUILD_CI_ONLY=0
Expand Down Expand Up @@ -213,8 +213,8 @@ fi
if hasArg --verbose-pdlp; then
DEFINE_PDLP_VERBOSE_MODE=true
fi
if hasArg -n; then
INSTALL_TARGET=""
if hasArg --install; then
INSTALL_TARGET=install
fi
if hasArg --no-fetch-rapids; then
FETCH_RAPIDS=OFF
Expand Down Expand Up @@ -355,6 +355,22 @@ if hasArg codegen; then
echo "Done. Remember to commit the generated files."
fi

################################################################################
# When not installing and rebuilding the C++ library, remove any stale
# libcuopt.so from the conda prefix. conda's $LDFLAGS injects
# -rpath,$CONDA_PREFIX/lib into every binary, so a previously installed copy
# would shadow the freshly compiled build-dir one.
# Only done when actually building libcuopt (not Python-only builds) to avoid
# removing a legitimately conda-installed libcuopt that Python packages depend on.
if [ -z "${INSTALL_TARGET}" ] && [ -n "${INSTALL_PREFIX}" ]; then
if buildAll || hasArg libcuopt || hasArg cuopt_grpc_server; then
if compgen -G "${INSTALL_PREFIX}/lib/libcuopt*.so*" > /dev/null 2>&1; then
echo "Removing stale libcuopt from ${INSTALL_PREFIX}/lib to prevent shadowing the build-dir library..."
rm -f "${INSTALL_PREFIX}"/lib/libcuopt*.so*
fi
fi
fi

################################################################################
# Configure and build libcuopt (and optionally just the gRPC server)
if buildAll || hasArg libcuopt || hasArg cuopt_grpc_server; then
Expand Down Expand Up @@ -387,12 +403,12 @@ if buildAll || hasArg libcuopt || hasArg cuopt_grpc_server; then
JFLAG="${PARALLEL_LEVEL:+-j${PARALLEL_LEVEL}}"
if hasArg cuopt_grpc_server && ! hasArg libcuopt && ! buildAll; then
# Build only the gRPC server (ninja resolves libcuopt as a dependency)
cmake --build "${LIBCUOPT_BUILD_DIR}" --target cuopt_grpc_server ${VERBOSE_FLAG} ${JFLAG}
elif hasArg -n; then
# Manual make invocation to start its jobserver
make ${JFLAG} -C "${REPODIR}/cpp" LIBCUOPT_BUILD_DIR="${LIBCUOPT_BUILD_DIR}" VERBOSE_FLAG="${VERBOSE_FLAG}" PARALLEL_LEVEL="${PARALLEL_LEVEL}" ninja-build
cmake --build "${LIBCUOPT_BUILD_DIR}" --target cuopt_grpc_server ${VERBOSE_FLAG} "${JFLAG}"
elif hasArg --install; then
cmake --build "${LIBCUOPT_BUILD_DIR}" --target "${INSTALL_TARGET}" ${VERBOSE_FLAG} "${JFLAG}"
else
cmake --build "${LIBCUOPT_BUILD_DIR}" --target ${INSTALL_TARGET} ${VERBOSE_FLAG} ${JFLAG}
# Manual make invocation to start its jobserver
make "${JFLAG}" -C "${REPODIR}/cpp" LIBCUOPT_BUILD_DIR="${LIBCUOPT_BUILD_DIR}" VERBOSE_FLAG="${VERBOSE_FLAG}" PARALLEL_LEVEL="${PARALLEL_LEVEL}" ninja-build
fi
fi

Expand Down
2 changes: 1 addition & 1 deletion conda/recipes/libcuopt/recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cache:
export CXXFLAGS=$(echo $CXXFLAGS | sed -E 's@\-fdebug\-prefix\-map[^ ]*@@g')
set +x

./build.sh -n -v ${BUILD_EXTRA_FLAGS} libcuopt deb --allgpuarch --cmake-args=\"-DCMAKE_INSTALL_LIBDIR=lib -DBUILD_LP_BENCHMARKS=ON -DBUILD_MIP_BENCHMARKS=ON\"
./build.sh -v ${BUILD_EXTRA_FLAGS} libcuopt deb --allgpuarch --cmake-args=\"-DCMAKE_INSTALL_LIBDIR=lib -DBUILD_LP_BENCHMARKS=ON -DBUILD_MIP_BENCHMARKS=ON\"
secrets:
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
Expand Down
8 changes: 7 additions & 1 deletion skills/cuopt-developer/references/build_and_test.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,17 @@ cat "$CG/cpu.max" # "<quota> <period>"; effective cores = quota / period
./build.sh
```

By default, `build.sh` builds without installing `libcuopt` into the conda environment. This prevents stale installed libraries from shadowing freshly compiled code. Pass `--install` to explicitly install into the active conda environment:

```bash
./build.sh --install # build and install libcuopt into conda env
```

## Build Specific Components

```bash
./build.sh --help # Lists build options
./build.sh libcuopt # C++ library
./build.sh libcuopt # C++ library (no conda install)
./build.sh libcuopt --skip-routing-build --skip-tests-build --skip-c-python-adapters --cache-tool=ccache # native LP/MIP-focused build without routing/tests/adapters
./build.sh cuopt # Python package
./build.sh cuopt_server # Server
Expand Down
Loading