Skip to content

Commit

Permalink
Merge branch 'main' into line-search
Browse files Browse the repository at this point in the history
  • Loading branch information
teseoch committed Jul 17, 2024
2 parents 58acb9d + fdd346e commit 676f094
Show file tree
Hide file tree
Showing 16 changed files with 328 additions and 257 deletions.
86 changes: 27 additions & 59 deletions cmake/recipes/mkl.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ set_property(CACHE MKL_LINKING PROPERTY STRINGS ${MKL_LINKINK_CHOICES})
message(STATUS "MKL linking strategy: ${MKL_LINKING}")

# MKL version
set(MKL_VERSION "2021.3.0" CACHE STRING "MKL version to use (2020.4 or 2021.3.0)")
set(MKL_VERSION_CHOICES 2020.4 2021.3.0)
set(MKL_VERSION "2022.2.1" CACHE STRING "MKL version to use (2022.2.1)")
set(MKL_VERSION_CHOICES 2022.2.1)
set_property(CACHE MKL_VERSION PROPERTY STRINGS ${MKL_VERSION_CHOICES})
message(STATUS "MKL version: ${MKL_VERSION}")

Expand Down Expand Up @@ -78,66 +78,34 @@ elseif(UNIX)
set(MKL_PLATFORM linux-64)
endif()

if(MKL_VERSION VERSION_EQUAL 2020.4)
# To compute the md5 checksums for each lib, use the following bash script (replace the target version number):
# for f in mkl mkl-include mkl-static mkl-devel; do for os in linux osx win; do cat <(printf "$f-$os-64-md5") <(conda search --override-channel --channel intel $f=2020.4 --platform $os-64 -i | grep md5 | cut -d : -f 2); done; done
set(mkl-linux-64-md5 f85891f97a04c7b2fbf619d1b903d7f5)
set(mkl-osx-64-md5 735d7f93c7fbcffe658f1ccf67418cb3)
set(mkl-win-64-md5 37ade09cace5cd73053b16574a3ee3c3)
set(mkl-include-linux-64-md5 8b2bf0e42bd95dd700d9877add1ca6de)
set(mkl-include-osx-64-md5 26043328553952cdb064c5aab8b50c78)
set(mkl-include-win-64-md5 87e9a73a6e6757a8ed0dbc87d50d7f60)
set(mkl-static-linux-64-md5 9f589a1508fb083c3e73427db459ca4c)
set(mkl-static-osx-64-md5 2f9e1b8b6d6b0903e81a573084e4494f)
set(mkl-static-win-64-md5 5ae780c06edd0be62966c6d8ab47d5fb)
set(mkl-devel-linux-64-md5 b571698ef237c0e61abe15b7d300f157)
set(mkl-devel-osx-64-md5 ee58da0463676d910eeab9aec0470f0e)
set(mkl-devel-win-64-md5 8a7736b81b9bc2d5c044b88d6ac8af6e)

# To compute file names, we use the following bash script:
# for f in mkl mkl-include mkl-static mkl-devel; do for os in linux osx win; do cat <(printf "$f-$os-64-file") <(conda search --override-channel --channel intel $f=2020.4 --platform $os-64 -i | grep file | cut -d : -f 2); done; done
set(mkl-linux-64-file mkl-2020.4-intel_304.tar.bz2)
set(mkl-osx-64-file mkl-2020.4-intel_301.tar.bz2)
set(mkl-win-64-file mkl-2020.4-intel_311.tar.bz2)
set(mkl-include-linux-64-file mkl-include-2020.4-intel_304.tar.bz2)
set(mkl-include-osx-64-file mkl-include-2020.4-intel_301.tar.bz2)
set(mkl-include-win-64-file mkl-include-2020.4-intel_311.tar.bz2)
set(mkl-static-linux-64-file mkl-static-2020.4-intel_304.tar.bz2)
set(mkl-static-osx-64-file mkl-static-2020.4-intel_301.tar.bz2)
set(mkl-static-win-64-file mkl-static-2020.4-intel_311.tar.bz2)
set(mkl-devel-linux-64-file mkl-devel-2020.4-intel_304.tar.bz2)
set(mkl-devel-osx-64-file mkl-devel-2020.4-intel_301.tar.bz2)
set(mkl-devel-win-64-file mkl-devel-2020.4-intel_311.tar.bz2)
elseif(MKL_VERSION VERSION_EQUAL 2021.3.0)
if(MKL_VERSION VERSION_EQUAL 2022.2.1)
# To compute the md5 checksums for each lib, use the following bash script (replace the target version number):
# for f in mkl mkl-include mkl-static mkl-devel; do for os in linux osx win; do cat <(printf "$f-$os-64-md5") <(conda search --override-channel --channel intel $f=2021.3.0 --platform $os-64 -i | grep md5 | cut -d : -f 2); done; done
set(mkl-linux-64-md5 2501643729c00b24fddb9530b339aea7)
set(mkl-osx-64-md5 d6129ae9dfba58671667a65c160d0776)
set(mkl-win-64-md5 264213ea4c5cb6b6d81ea97f59e757ab)
set(mkl-include-linux-64-md5 70b4f9a53401a3d11ce27d7ddb0e2511)
set(mkl-include-osx-64-md5 6da50c06992b78c4127a1881d39c1804)
set(mkl-include-win-64-md5 28d785eb22d28512d4e40e5890a817dc)
set(mkl-static-linux-64-md5 1469ad60a34269d4d0c5666bc131b82a)
set(mkl-static-osx-64-md5 4a099581ba95cc50bb538598b26389e4)
set(mkl-static-win-64-md5 69aef10428893314bc486e81397e1b25)
set(mkl-devel-linux-64-md5 2432ad963e3f7e4619ffc7f896178fbe)
set(mkl-devel-osx-64-md5 61b84a60715a3855a2097a3b619a00c8)
set(mkl-devel-win-64-md5 6128dee67d2b20ff534cf54757f623e0)
# set(mkl-linux-64-md5 2501643729c00b24fddb9530b339aea7)
# set(mkl-win-64-md5 264213ea4c5cb6b6d81ea97f59e757ab)

# set(mkl-include-linux-64-md5 70b4f9a53401a3d11ce27d7ddb0e2511)
# set(mkl-include-win-64-md5 28d785eb22d28512d4e40e5890a817dc)

# set(mkl-static-linux-64-md5 1469ad60a34269d4d0c5666bc131b82a)
# set(mkl-static-win-64-md5 69aef10428893314bc486e81397e1b25)

# set(mkl-devel-linux-64-md5 2432ad963e3f7e4619ffc7f896178fbe)
# set(mkl-devel-win-64-md5 6128dee67d2b20ff534cf54757f623e0)

# To compute file names, we use the following bash script:
# for f in mkl mkl-include mkl-static mkl-devel; do for os in linux osx win; do cat <(printf "$f-$os-64-file") <(conda search --override-channel --channel intel $f=2021.3.0 --platform $os-64 -i | grep file | cut -d : -f 2); done; done
set(mkl-linux-64-file mkl-2021.3.0-intel_520.tar.bz2)
set(mkl-osx-64-file mkl-2021.3.0-intel_517.tar.bz2)
set(mkl-win-64-file mkl-2021.3.0-intel_524.tar.bz2)
set(mkl-include-linux-64-file mkl-include-2021.3.0-intel_520.tar.bz2)
set(mkl-include-osx-64-file mkl-include-2021.3.0-intel_517.tar.bz2)
set(mkl-include-win-64-file mkl-include-2021.3.0-intel_524.tar.bz2)
set(mkl-static-linux-64-file mkl-static-2021.3.0-intel_520.tar.bz2)
set(mkl-static-osx-64-file mkl-static-2021.3.0-intel_517.tar.bz2)
set(mkl-static-win-64-file mkl-static-2021.3.0-intel_524.tar.bz2)
set(mkl-devel-linux-64-file mkl-devel-2021.3.0-intel_520.tar.bz2)
set(mkl-devel-osx-64-file mkl-devel-2021.3.0-intel_517.tar.bz2)
set(mkl-devel-win-64-file mkl-devel-2021.3.0-intel_524.tar.bz2)
set(mkl-linux-64-file mkl-2022.2.1-h6508926_16999.tar.bz2)
set(mkl-win-64-file mkl-2022.2.1-h4060db9_19760.tar.bz2)

set(mkl-include-linux-64-file mkl-include-2022.2.1-ha957f24_16999.tar.bz2)
set(mkl-include-win-64-file mkl-include-2022.2.1-h66d3029_19760.tar.bz2)

set(mkl-static-linux-64-file mkl-static-2022.2.1-h6508926_16999.tar.bz2)
set(mkl-static-win-64-file mkl-static-2022.2.1-h4060db9_19760.tar.bz2)

set(mkl-devel-linux-64-file mkl-devel-2022.2.1-ha957f24_16999.tar.bz2)
set(mkl-devel-win-64-file mkl-devel-2022.2.1-h66d3029_19760.tar.bz2)
endif()

# On Windows, `mkl-devel` contains the .lib files (needed at link time),
Expand All @@ -153,8 +121,8 @@ include(CPM)
foreach(name IN ITEMS ${MKL_REMOTES})
CPMAddPackage(
NAME ${name}
URL https://anaconda.org/intel/${name}/${MKL_VERSION}/download/${MKL_PLATFORM}/${${name}-${MKL_PLATFORM}-file}
URL_MD5 ${${name}-${MKL_PLATFORM}-md5}
URL https://anaconda.org/conda-forge/${name}/${MKL_VERSION}/download/${MKL_PLATFORM}/${${name}-${MKL_PLATFORM}-file}
# URL_MD5 ${${name}-${MKL_PLATFORM}-md5}
)
endforeach()

Expand Down
67 changes: 34 additions & 33 deletions src/polysolve/linear/Solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,22 @@ namespace polysolve::linear
/// Selects the correct solver based on params using the fallback or the list of solvers if necessary
static void select_valid_solver(json &params, spdlog::logger &logger);

// Static constructor
//
// @param[in] params Parameter of the solver, including name and preconditioner
// @param[in] logger Logger used for error
// @param[in] strict_validation strict validation of the input paraams
// @param[out] a pointer to a linear solver
/// @brief Static constructor
///
/// @param[in] params Parameter of the solver, including name and preconditioner
/// @param[in] logger Logger used for error
/// @param[in] strict_validation strict validation of the input paraams
/// @return a pointer to a linear solver
//
static std::unique_ptr<Solver> create(const json &params,
spdlog::logger &logger,
const bool strict_validation = true);

// Static constructor
//
// @param[in] solver Solver type
// @param[in] precond Preconditioner for iterative solvers
//
/// @brief Static constructor
///
/// @param[in] solver Solver type
/// @param[in] precond Preconditioner for iterative solvers
///
static std::unique_ptr<Solver> create(const std::string &solver, const std::string &precond);

// List available solvers
Expand All @@ -86,44 +86,45 @@ namespace polysolve::linear
// Public interface //
//////////////////////

// Set solver parameters
/// Set solver parameters
virtual void set_parameters(const json &params) {}

// Get info on the last solve step
/// Get info on the last solve step
virtual void get_info(json &params) const {};

// Analyze sparsity pattern
/// Analyze sparsity pattern
virtual void analyze_pattern(const StiffnessMatrix &A, const int precond_num) {}

// Factorize system matrix
/// Factorize system matrix
virtual void factorize(const StiffnessMatrix &A) {}

// Analyze sparsity pattern of a dense matrix
/// Analyze sparsity pattern of a dense matrix
virtual void analyze_pattern_dense(const Eigen::MatrixXd &A, const int precond_num) {}

// Factorize system matrix of a dense matrix
/// Factorize system matrix of a dense matrix
virtual void factorize_dense(const Eigen::MatrixXd &A) {}

// If solver uses dense matrices
/// If solver uses dense matrices
virtual bool is_dense() const { return false; }

//
// @brief { Solve the linear system Ax = b }
//
// @param[in] b { Right-hand side. }
// @param[in,out] x { Unknown to compute. When using an iterative
// solver, the input unknown vector is used as an
// initial guess, and must thus be properly allocated
// and initialized. }
//
/// Set block size for multigrid solvers
virtual void set_block_size(int block_size) {}

/// If the problem is nullspace for multigrid solvers
virtual void set_is_nullspace(const VectorXd &x) {}

///
/// @brief { Solve the linear system Ax = b }
///
/// @param[in] b { Right-hand side. }
/// @param[in,out] x { Unknown to compute. When using an iterative
/// solver, the input unknown vector is used as an
/// initial guess, and must thus be properly allocated
/// and initialized. }
///
virtual void solve(const Ref<const VectorXd> b, Ref<VectorXd> x) = 0;

public:
///////////
// Debug //
///////////

// Name of the solver type (for debugging purposes)
/// @brief Name of the solver type (for debugging purposes)
virtual std::string name() const { return ""; }
};

Expand Down
47 changes: 24 additions & 23 deletions src/polysolve/nonlinear/Criteria.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// License: MIT
#include "Criteria.hpp"

#include <spdlog/fmt/fmt.h>

namespace polysolve::nonlinear
{
bool is_converged_status(const Status s)
Expand All @@ -27,13 +29,9 @@ namespace polysolve::nonlinear

void Criteria::print(std::ostream &os) const
{
os << "Iterations: " << iterations << std::endl;
os << "xDelta: " << xDelta << std::endl;
os << "fDelta: " << fDelta << std::endl;
os << "GradNorm: " << gradNorm << std::endl;
os << "xDeltaDotGrad: " << xDeltaDotGrad << std::endl;
os << "FirstGradNorm: " << firstGradNorm << std::endl;
os << "fDeltaCount: " << fDeltaCount << std::endl;
os << fmt::format(
"iters={:d} Δf={:g} ‖∇f‖={:g} ‖Δx‖={:g} Δx⋅∇f(x)={:g}",
iterations, fDelta, gradNorm, xDelta, xDeltaDotGrad);
}

Status checkConvergence(const Criteria &stop, const Criteria &current)
Expand All @@ -42,6 +40,11 @@ namespace polysolve::nonlinear
{
return Status::IterationLimit;
}
const double stopGradNorm = current.iterations == 0 ? stop.firstGradNorm : stop.gradNorm;
if (stopGradNorm > 0 && current.gradNorm < stopGradNorm)
{
return Status::GradNormTolerance;
}
if (stop.xDelta > 0 && current.xDelta < stop.xDelta)
{
return Status::XDeltaTolerance;
Expand All @@ -50,11 +53,6 @@ namespace polysolve::nonlinear
{
return Status::FDeltaTolerance;
}
const double stopGradNorm = current.iterations == 0 ? stop.firstGradNorm : stop.gradNorm;
if (stopGradNorm > 0 && current.gradNorm < stopGradNorm)
{
return Status::GradNormTolerance;
}
// Δx⋅∇f ≥ 0 means that the search direction is not a descent direction
if (stop.xDeltaDotGrad < 0 && current.xDeltaDotGrad > stop.xDeltaDotGrad)
{
Expand All @@ -68,37 +66,40 @@ namespace polysolve::nonlinear
switch (s)
{
case Status::NotStarted:
os << "Solver not started.";
os << "Solver not started";
break;
case Status::Continue:
os << "Convergence criteria not reached.";
os << "Convergence criteria not reached";
break;
case Status::IterationLimit:
os << "Iteration limit reached.";
os << "Iteration limit reached";
break;
case Status::XDeltaTolerance:
os << "Change in parameter vector too small.";
os << "Change in parameter vector too small";
break;
case Status::FDeltaTolerance:
os << "Change in cost function value too small.";
os << "Change in cost function value too small";
break;
case Status::GradNormTolerance:
os << "Gradient vector norm too small.";
os << "Gradient vector norm too small";
break;
case Status::ObjectiveCustomStop:
os << "Objective function specified to stop.";
os << "Objective function specified to stop";
break;
case Status::NanEncountered:
os << "Objective or gradient function returned NaN.";
os << "Objective or gradient function returned NaN";
break;
case Status::NotDescentDirection:
os << "Search direction not a descent direction.";
os << "Search direction not a descent direction";
break;
case Status::LineSearchFailed:
os << "Line search failed.";
os << "Line search failed";
break;
case Status::UpdateDirectionFailed:
os << "Update direction could not be computed";
break;
default:
os << "Unknown status.";
os << "Unknown status";
break;
}
return os;
Expand Down
7 changes: 4 additions & 3 deletions src/polysolve/nonlinear/Criteria.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ namespace polysolve::nonlinear
GradNormTolerance, ///< The norm of the gradient vector is below the tolerance
ObjectiveCustomStop, ///< The objective function specified to stop
// Failure cases
NanEncountered, ///< The objective function returned NaN
NotDescentDirection, ///< The search direction is not a descent direction
LineSearchFailed, ///< The line search failed
NanEncountered, ///< The objective function returned NaN
NotDescentDirection, ///< The search direction is not a descent direction
LineSearchFailed, ///< The line search failed
UpdateDirectionFailed, ///< The update direction could not be computed
};

bool is_converged_status(const Status s);
Expand Down
1 change: 1 addition & 0 deletions src/polysolve/nonlinear/Problem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace polysolve::nonlinear
{
/// @brief Class defining optimization problem to be solved. To be defined by user code
class Problem
{
public:
Expand Down
Loading

0 comments on commit 676f094

Please sign in to comment.