diff --git a/.github/workflows/run_tests_osx_win.yml b/.github/workflows/run_tests_osx_win.yml index f0c3a51cd..3fd534a4c 100644 --- a/.github/workflows/run_tests_osx_win.yml +++ b/.github/workflows/run_tests_osx_win.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Set prefix osx run: | - echo "PREFIX=${{ env.PREFIX_macOS }}" >> $GITHUB_ENV + echo "PREFIX=${{ env.PREFIX_MACOS }}" >> $GITHUB_ENV if: matrix.os == 'macos-latest' - name: Set prefix windows diff --git a/bioptim/dynamics/configure_new_variable.py b/bioptim/dynamics/configure_new_variable.py index dcc2ced85..a0cfc201a 100644 --- a/bioptim/dynamics/configure_new_variable.py +++ b/bioptim/dynamics/configure_new_variable.py @@ -223,7 +223,7 @@ def check_variable_copy_condition( and name in getattr(nlp[use_from_phase_idx], decision_variable_attribute) ) - def define_cx_scaled(self, n_col: int, n_shooting: int, initial_node) -> list[MX | SX, ...]: + def define_cx_scaled(self, n_col: int, n_shooting: int, initial_node) -> list[MX | SX]: """ This function defines the decision variables, either MX or SX, scaled to the physical world, they mean something according to the physical model considered. @@ -259,7 +259,7 @@ def define_cx_scaled(self, n_col: int, n_shooting: int, initial_node) -> list[MX ) return _cx - def define_cx_unscaled(self, _cx_scaled: list[MX | SX, ...], scaling: np.ndarray) -> list[MX | SX, ...]: + def define_cx_unscaled(self, _cx_scaled: list[MX | SX], scaling: np.ndarray) -> list[MX | SX]: """ This function defines the decision variables, either MX or SX, unscaled means here the decision variable doesn't correspond to physical quantity. @@ -269,7 +269,7 @@ def define_cx_unscaled(self, _cx_scaled: list[MX | SX, ...], scaling: np.ndarray Parameters --------- - _cx_scaled: list[MX | SX, ...] + _cx_scaled: list[MX | SX] Decision variables scaled to the physical world scaling: np.ndarray The scaling factors associated to the decision variable diff --git a/bioptim/examples/getting_started/example_multinode_constraints.py b/bioptim/examples/getting_started/example_multinode_constraints.py index defec33fb..f3be926e4 100644 --- a/bioptim/examples/getting_started/example_multinode_constraints.py +++ b/bioptim/examples/getting_started/example_multinode_constraints.py @@ -31,7 +31,7 @@ def custom_multinode_constraint( - controllers: list[PenaltyController, ...], coef: float, states_mapping: BiMapping = None + controllers: list[PenaltyController], coef: float, states_mapping: BiMapping = None ) -> MX: """ The constraint of the transition. The values from the end of the phase to the next are multiplied by coef to @@ -42,7 +42,7 @@ def custom_multinode_constraint( Parameters ---------- - controllers: list[PenaltyController, ...] + controllers: list[PenaltyController] All the controller for the penalties coef: float The coefficient of the phase transition (makes no physical sens) diff --git a/bioptim/gui/plot.py b/bioptim/gui/plot.py index 66a61781b..bd9bbc286 100644 --- a/bioptim/gui/plot.py +++ b/bioptim/gui/plot.py @@ -778,7 +778,7 @@ def _compute_y_from_plot_func( The custom plot to compute phase_idx: int The index of the current phase - time_stepwise: list[list[DM], ...] + time_stepwise: list[list[DM]] The time vector of each phase dt The delta times of the current phase diff --git a/bioptim/interfaces/acados_interface.py b/bioptim/interfaces/acados_interface.py index e39ebe3eb..c3d4ea2aa 100644 --- a/bioptim/interfaces/acados_interface.py +++ b/bioptim/interfaces/acados_interface.py @@ -851,9 +851,9 @@ def get_optimized_value(self) -> list | dict: out = { "x": [], "u": acados_u, - "solver_time_to_optimize": self.ocp_solver.get_stats("time_tot")[0], + "solver_time_to_optimize": self.ocp_solver.get_stats("time_tot"), "real_time_to_optimize": self.real_time_to_optimize, - "iter": self.ocp_solver.get_stats("sqp_iter")[0], + "iter": self.ocp_solver.get_stats("sqp_iter"), "status": self.status, "solver": SolverType.ACADOS, } diff --git a/bioptim/limits/constraints.py b/bioptim/limits/constraints.py index 6fcc3483c..e3d9314a4 100644 --- a/bioptim/limits/constraints.py +++ b/bioptim/limits/constraints.py @@ -103,7 +103,7 @@ def add_or_replace_to_penalty_pool(self, ocp, nlp): elif self.bounds.shape[0] != len(self.rows): raise RuntimeError(f"bounds rows is {self.bounds.shape[0]} but should be {self.rows} or empty") - def _add_penalty_to_pool(self, controller: list[PenaltyController, ...]): + def _add_penalty_to_pool(self, controller: list[PenaltyController]): controller = controller[0] # This is a special case of Node.TRANSITION if self.penalty_type == PenaltyType.INTERNAL: @@ -1222,7 +1222,7 @@ def add_or_replace_to_penalty_pool(self, ocp, nlp): elif self.bounds.shape[0] != len(self.rows): raise RuntimeError(f"bounds rows is {self.bounds.shape[0]} but should be {self.rows} or empty") - def _add_penalty_to_pool(self, controller: list[PenaltyController, ...]): + def _add_penalty_to_pool(self, controller: list[PenaltyController]): controller = controller[0] # This is a special case of Node.TRANSITION if self.penalty_type == PenaltyType.INTERNAL: diff --git a/bioptim/limits/multinode_penalty.py b/bioptim/limits/multinode_penalty.py index 554872724..ae1dba68c 100644 --- a/bioptim/limits/multinode_penalty.py +++ b/bioptim/limits/multinode_penalty.py @@ -85,7 +85,7 @@ def __init__( def _get_pool_to_add_penalty(self, ocp, nlp): raise NotImplementedError("This is an abstract method and should be implemented by child") - def _add_penalty_to_pool(self, controller: list[PenaltyController, ...]): + def _add_penalty_to_pool(self, controller: list[PenaltyController]): controller = controller[0] # This is a special case of Node.TRANSITION @@ -124,9 +124,9 @@ class Functions: @staticmethod def states_equality( penalty, - controllers: list[PenaltyController, ...], + controllers: list[PenaltyController], key: str = "all", - states_mapping: list[BiMapping, ...] = None, + states_mapping: list[BiMapping] = None, ): """ The most common continuity function, that is state before equals state after @@ -171,7 +171,7 @@ def states_equality( return out @staticmethod - def controls_equality(penalty, controllers: list[PenaltyController, ...], key: str = "all"): + def controls_equality(penalty, controllers: list[PenaltyController], key: str = "all"): """ The controls before equals controls after @@ -179,7 +179,7 @@ def controls_equality(penalty, controllers: list[PenaltyController, ...], key: s ---------- penalty : MultinodePenalty A reference to the penalty - controllers: list[PenaltyController, ...] + controllers: list[PenaltyController] The penalty node elements Returns @@ -210,7 +210,7 @@ def controls_equality(penalty, controllers: list[PenaltyController, ...], key: s @staticmethod def algebraic_states_equality( penalty, - controllers: list[PenaltyController, ...], + controllers: list[PenaltyController], key: str = "all", ): """ @@ -249,7 +249,7 @@ def algebraic_states_equality( return out @staticmethod - def com_equality(penalty, controllers: list[PenaltyController, ...]): + def com_equality(penalty, controllers: list[PenaltyController]): """ The centers of mass are equals for the specified phases and the specified nodes @@ -257,7 +257,7 @@ def com_equality(penalty, controllers: list[PenaltyController, ...]): ---------- penalty : MultinodePenalty A reference to the penalty - controllers: list[PenaltyController, ...] + controllers: list[PenaltyController] The penalty node elements Returns @@ -277,7 +277,7 @@ def com_equality(penalty, controllers: list[PenaltyController, ...]): return out @staticmethod - def com_velocity_equality(penalty, controllers: list[PenaltyController, ...]): + def com_velocity_equality(penalty, controllers: list[PenaltyController]): """ The centers of mass velocity are equals for the specified phases and the specified nodes @@ -285,7 +285,7 @@ def com_velocity_equality(penalty, controllers: list[PenaltyController, ...]): ---------- penalty : MultinodePenalty A reference to the penalty - controllers: list[PenaltyController, ...] + controllers: list[PenaltyController] The penalty node elements Returns @@ -651,7 +651,7 @@ def custom(penalty, controllers: list[PenaltyController, PenaltyController], **e return penalty.custom_function(controllers, **extra_parameters) @staticmethod - def _prepare_controller_cx(penalty, controllers: list[PenaltyController, ...]): + def _prepare_controller_cx(penalty, controllers: list[PenaltyController]): """ This calls the _compute_controller_cx function for each of the controller then dispatch the cx appropriately to the controllers @@ -667,7 +667,7 @@ def _prepare_controller_cx(penalty, controllers: list[PenaltyController, ...]): c.cx_index_to_get = index @staticmethod - def _prepare_states_mapping(controllers: list[PenaltyController, ...], states_mapping: list[BiMapping, ...]): + def _prepare_states_mapping(controllers: list[PenaltyController], states_mapping: list[BiMapping]): """ Prepare a new state_mappings if None is sent. Otherwise, it simply returns the current states_mapping diff --git a/bioptim/limits/penalty_option.py b/bioptim/limits/penalty_option.py index cf904c450..f89f3033d 100644 --- a/bioptim/limits/penalty_option.py +++ b/bioptim/limits/penalty_option.py @@ -67,7 +67,7 @@ class PenaltyOption(OptionGeneric): _check_target_dimensions(self, controller: PenaltyController, n_frames: int) Checks if the variable index is consistent with the requested variable. If the function returns, all is okay - _set_penalty_function(self, controller: list[PenaltyController, ...], fcn: MX | SX) + _set_penalty_function(self, controller: list[PenaltyController], fcn: MX | SX) Finalize the preparation of the penalty (setting function and weighted_function) add_target_to_plot(self, controller: PenaltyController, combine_to: str) Interface to the plot so it can be properly added to the proper plot @@ -75,7 +75,7 @@ class PenaltyOption(OptionGeneric): Internal interface to add (after having check the target dimensions) the target to the plot if needed add_or_replace_to_penalty_pool(self, ocp, nlp) Doing some configuration on the penalty and add it to the list of penalty - _add_penalty_to_pool(self, controller: list[PenaltyController, ...]) + _add_penalty_to_pool(self, controller: list[PenaltyController]) Return the penalty pool for the specified penalty (abstract) ensure_penalty_sanity(self, ocp, nlp) Resets a penalty. A negative penalty index creates a new empty penalty (abstract) @@ -332,7 +332,7 @@ def transform_penalty_to_stochastic(self, controller: PenaltyController, fcn, st return diag(fcn_variation) - def _set_phase_dynamics(self, controllers: list[PenaltyController, ...]): + def _set_phase_dynamics(self, controllers: list[PenaltyController]): phase_dynamics = [c.get_nlp.phase_dynamics for c in controllers] if self.phase_dynamics: # If it was already set (e.g. for multinode), we want to make sure it is consistent diff --git a/bioptim/limits/phase_transition.py b/bioptim/limits/phase_transition.py index 07aec502f..5d3d9572a 100644 --- a/bioptim/limits/phase_transition.py +++ b/bioptim/limits/phase_transition.py @@ -142,7 +142,7 @@ class Functions: def continuous( transition, controllers: list[PenaltyController, PenaltyController], - states_mapping: list[BiMapping, ...] = None, + states_mapping: list[BiMapping] = None, ): """ The most common continuity function, that is state before equals state after @@ -173,7 +173,7 @@ def continuous( def continuous_controls( transition, controllers: list[PenaltyController, PenaltyController], - controls_mapping: list[BiMapping, ...] = None, + controls_mapping: list[BiMapping] = None, ): """ This continuity function is only relevant for ControlType.LINEAR_CONTINUOUS otherwise don't use it. diff --git a/bioptim/models/biorbd/multi_biorbd_model.py b/bioptim/models/biorbd/multi_biorbd_model.py index 1ae1bdc9e..e682dfa87 100644 --- a/bioptim/models/biorbd/multi_biorbd_model.py +++ b/bioptim/models/biorbd/multi_biorbd_model.py @@ -725,7 +725,7 @@ def ligament_joint_torque(self, q, qdot) -> MX: def ranges_from_model(self, variable: str): return [the_range for model in self.models for the_range in model.ranges_from_model(variable)] - def bounds_from_ranges(self, variables: str | list[str, ...], mapping: BiMapping | BiMappingList = None) -> Bounds: + def bounds_from_ranges(self, variables: str | list[str], mapping: BiMapping | BiMappingList = None) -> Bounds: return bounds_from_ranges(self, variables, mapping) def _var_mapping(self, key: str, range_for_mapping: int | list | tuple | range, mapping: BiMapping = None) -> dict: diff --git a/bioptim/models/protocols/biomodel.py b/bioptim/models/protocols/biomodel.py index 13b457ac2..8106984f1 100644 --- a/bioptim/models/protocols/biomodel.py +++ b/bioptim/models/protocols/biomodel.py @@ -260,7 +260,7 @@ def passive_joint_torque(self, q, qdot) -> MX: def ligament_joint_torque(self, q, qdot) -> MX: """Get the ligament joint torque""" - def bounds_from_ranges(self, variables: str | list[str, ...], mapping: BiMapping | BiMappingList = None) -> Bounds: + def bounds_from_ranges(self, variables: str | list[str], mapping: BiMapping | BiMappingList = None) -> Bounds: """ Create bounds from ranges of the model depending on the variable chosen, such as q, qdot, qddot @@ -325,11 +325,7 @@ def partitioned_forward_dynamics( @staticmethod def animate( - ocp, - solution: "SolutionData", - show_now: bool = True, - tracked_markers: list[np.ndarray, ...] = None, - **kwargs: Any + ocp, solution: "SolutionData", show_now: bool = True, tracked_markers: list[np.ndarray] = None, **kwargs: Any ) -> None | list: """ Animate a solution @@ -340,7 +336,7 @@ def animate( The solution to animate show_now: bool If the animation should be shown immediately or not - tracked_markers: list[np.ndarray, ...] + tracked_markers: list[np.ndarray] The tracked markers (3, n_markers, n_frames) kwargs: dict The options to pass to the animator diff --git a/bioptim/models/utils.py b/bioptim/models/utils.py index 696e06aff..1577d5c3a 100644 --- a/bioptim/models/utils.py +++ b/bioptim/models/utils.py @@ -62,7 +62,7 @@ def bounds_from_ranges(model, key: str, mapping: BiMapping | BiMappingList = Non ---------- model: bio_model such as BiorbdModel or MultiBiorbdModel - key: str | list[str, ...] + key: str | list[str] The variables to generate the bounds from, such as "q", "qdot", "qddot", or ["q", "qdot"], mapping: BiMapping | BiMappingList The mapping to use to generate the bounds. If None, the default mapping is built diff --git a/bioptim/optimization/optimization_variable.py b/bioptim/optimization/optimization_variable.py index 1c4a6898c..a9a7a8578 100644 --- a/bioptim/optimization/optimization_variable.py +++ b/bioptim/optimization/optimization_variable.py @@ -39,7 +39,7 @@ def __init__( name: str, mx: MX, cx_start: list | None, - index: [range, list], + index: range | list, mapping: BiMapping = None, parent_list=None, ): @@ -50,7 +50,7 @@ def __init__( The name of the variable mx: MX The MX variable associated with this variable - index: [range, list] + index: range | list The indices to find this variable parent_list: OptimizationVariableList The list the OptimizationVariable is in @@ -58,7 +58,7 @@ def __init__( self.name: str = name self.mx: MX = mx self.original_cx: list = cx_start - self.index: [range, list] = index + self.index: range | list = index self.mapping: BiMapping = mapping self.parent_list: OptimizationVariableList = parent_list @@ -494,8 +494,8 @@ def __init__(self, phase_dynamics: PhaseDynamics): user sets it to something else) """ self.cx_constructor = None - self._unscaled: list[OptimizationVariableList, ...] = [] - self._scaled: list[OptimizationVariableList, ...] = [] + self._unscaled: list[OptimizationVariableList] = [] + self._scaled: list[OptimizationVariableList] = [] self._node_index = 0 # TODO: [0] to [node_index] self.phase_dynamics = phase_dynamics diff --git a/bioptim/optimization/solution/solution.py b/bioptim/optimization/solution/solution.py index 8e28c8540..ab1c90f69 100644 --- a/bioptim/optimization/solution/solution.py +++ b/bioptim/optimization/solution/solution.py @@ -373,7 +373,7 @@ def decision_time( Parameters ---------- - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. It is often useful to merge NODES, but is completely useless to merge KEYS time_alignment: TimeAlignment @@ -404,7 +404,7 @@ def stepwise_time( Parameters ---------- - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. It is often useful to merge NODES, but is completely useless to merge KEYS time_alignment: TimeAlignment @@ -533,7 +533,7 @@ def decision_states(self, scaled: bool = False, to_merge: SolutionMerge | list[S scaled: bool If the decision states should be scaled or not (note that scaled is as Ipopt received them, while unscaled is as the model needs temps). If you don't know what it means, you probably want the unscaled version. - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. Returns @@ -555,7 +555,7 @@ def stepwise_states(self, scaled: bool = False, to_merge: SolutionMerge | list[S scaled: bool If the states should be scaled or not (note that scaled is as Ipopt received them, while unscaled is as the model needs temps). If you don't know what it means, you probably want the unscaled version. - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. Returns @@ -580,7 +580,7 @@ def decision_controls(self, scaled: bool = False, to_merge: SolutionMerge | list scaled : bool If the decision controls should be scaled or not (note that scaled is as Ipopt received them, while unscaled is as the model needs temps). If you don't know what it means, you probably want the unscaled version. - to_merge : SolutionMerge | list[SolutionMerge, ...] + to_merge : SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. """ return self.stepwise_controls(scaled=scaled, to_merge=to_merge) @@ -594,7 +594,7 @@ def stepwise_controls(self, scaled: bool = False, to_merge: SolutionMerge | list scaled: bool If the controls should be scaled or not (note that scaled is as Ipopt received them, while unscaled is as the model needs temps). If you don't know what it means, you probably want the unscaled version. - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. Returns @@ -660,7 +660,7 @@ def decision_algebraic_states(self, scaled: bool = False, to_merge: SolutionMerg scaled: bool If the decision states should be scaled or not (note that scaled is as Ipopt received them, while unscaled is as the model needs temps). If you don't know what it means, you probably want the unscaled version. - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. Returns @@ -769,7 +769,7 @@ def integrate( The integration shooting type to use integrator: SolutionIntegrator The type of integrator to use - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The type of merge to perform. If None, then no merge is performed. duplicated_times: bool If the times should be duplicated for each node. @@ -1096,7 +1096,7 @@ def _return_time_vector(self, to_merge: SolutionMerge | list[SolutionMerge], dup Returns the time vector at each node that matches stepwise_states or stepwise_controls Parameters ---------- - to_merge: SolutionMerge | list[SolutionMerge, ...] + to_merge: SolutionMerge | list[SolutionMerge] The merge type to perform. If None, then no merge is performed. duplicated_times: bool If the times should be duplicated for each node. diff --git a/environment.yml b/environment.yml index 7b356fde4..1c89ee207 100644 --- a/environment.yml +++ b/environment.yml @@ -3,8 +3,8 @@ name: bioptim channels: - conda-forge dependencies: -- biorbd >=1.9.9 -- bioviz -- python-graphviz +- biorbd >=1.11.1 +- matplotlib +- pyqt - pyqtgraph -- gitpython +- python-graphviz \ No newline at end of file diff --git a/external/acados b/external/acados index 568e46c64..285d382b6 160000 --- a/external/acados +++ b/external/acados @@ -1 +1 @@ -Subproject commit 568e46c6482c371a897c398af0a500286f3ee3aa +Subproject commit 285d382b6c6d59c0983644caf6ed2924ed2153cb diff --git a/external/acados_install_linux.sh b/external/acados_install_linux.sh index a817f3a37..bdacda8ff 100755 --- a/external/acados_install_linux.sh +++ b/external/acados_install_linux.sh @@ -9,25 +9,18 @@ if [ ! -f acados/CMakeLists.txt ]; then git submodule update --recursive --init fi - # Check if everything required by the script is present echo "Processing arguments" echo "" -NB_CPU=`cat /proc/cpuinfo | grep processor | wc -l` - # Check if there are a number of CPUs for Acados multiprocessing -ARG1=${1:-$NB_CPU} +NB_CPU_MAX=`cat /proc/cpuinfo | grep processor | wc -l` +ARG1=${1:-$NB_CPU_MAX} if [ -z "$1" ]; then - echo " Argument 1 (NB_CPU) not provided, falling back on maximum number of CPUs ($ARG1)." - echo "" -fi - -if [ "$1" ]; then - echo " Number of threads for acados with openMP asked : NB_CPU=$1" - echo "" + echo " Argument 1 (NB_CPU) not provided, falling back on maximum number of CPUs ($NB_CPU_MAX)." fi - +echo " Number of threads for acados with openMP: NB_CPU=$ARG1" +echo "" ARG2=${2:-$CONDA_PREFIX} if [ -z "$ARG2" ]; then @@ -35,12 +28,11 @@ if [ -z "$ARG2" ]; then echo " Please provide a path for installation" exit 1 fi - if [ -z "$2" ]; then echo " Argument 2 (CMAKE_INSTALL_PREFIX) not provided, falling back on CONDA_PREFIX" - echo " CONDA_PREFIX=$CONDA_PREFIX" - echo "" fi +echo " set CMAKE_INSTALL_PREFIX=$ARG2" +echo "" ARG3=${3:-X64_AUTOMATIC} if [ -z "$3" ]; then @@ -61,17 +53,17 @@ mkdir acados/build cd acados/build # Run cmake -cmake . .. \ - -DACADOS_INSTALL_DIR="$ARG2"\ - -DACADOS_PYTHON=ON\ - -DACADOS_WITH_QPOASES=ON\ - -DACADOS_WITH_OSQP=ON\ - -DACADOS_WITH_QPDUNES=ON\ - -DBLASFEO_TARGET="$ARG3"\ - -DCMAKE_INSTALL_PREFIX="$ARG2"\ - -DACADOS_WITH_OPENMP=ON\ - -DACADOS_NUM_THREADS="$ARG1" -make install -j$NB_CPU +cmake .. \ + -DCMAKE_INSTALL_PREFIX="$ARG2" \ + -DACADOS_INSTALL_DIR="$ARG2" \ + -DACADOS_PYTHON=ON \ + -DACADOS_WITH_QPOASES=ON \ + -DACADOS_WITH_OSQP=ON \ + -DACADOS_WITH_QPDUNES=ON \ + -DBLASFEO_TARGET="$ARG3" \ + -DACADOS_WITH_OPENMP=ON \ + -DACADOS_NUM_THREADS=$ARG1 +make install -j$NB_CPU_MAX diff --git a/external/acados_install_mac.sh b/external/acados_install_mac.sh index b9a7eb127..21c25f84f 100755 --- a/external/acados_install_mac.sh +++ b/external/acados_install_mac.sh @@ -14,17 +14,13 @@ echo "Processing arguments" echo "" # Check if there are a number of CPUs for Acados multiprocessing -ARG1=${1:NB_CPU} -if [ -z "$ARG1" ]; then - ARG1=$CPU_COUNT - echo " Argument 1 (NB_CPU) not provided, falling back on maximum number of CPUs ($ARG1)." - echo "" -fi - -if [ "$1" ]; then - echo " Number of threads for acados with openMP asked : NB_CPU=$1" - echo "" +NB_CPU_MAX=`getconf _NPROCESSORS_ONLN` +ARG1=${1:-$NB_CPU_MAX} +if [ -z "$1" ]; then + echo " Argument 1 (NB_CPU) not provided, falling back on maximum number of CPUs ($NB_CPU_MAX)." fi +echo " Number of threads for acados with openMP: NB_CPU=$ARG1" +echo "" ARG2=${2:-$CONDA_PREFIX} if [ -z "$ARG2" ]; then @@ -32,18 +28,19 @@ if [ -z "$ARG2" ]; then echo " Please provide a path for installation" exit 1 fi - -if [ -z "$1" ]; then +if [ -z "$2" ]; then echo " Argument 2 (CMAKE_INSTALL_PREFIX) not provided, falling back on CONDA_PREFIX" - echo " CONDA_PREFIX=$CONDA_PREFIX" - echo "" fi +echo " set CMAKE_INSTALL_PREFIX=$ARG2" +echo "" ARG3=${3:-X64_AUTOMATIC} if [ -z "$3" ]; then echo " Argument 3 (BLASFEO_TARGET) not provided, falling back on X64_AUTOMATIC" - echo "" fi +echo " set BLASFEO_TARGET=$ARG3" +echo "" + # Preparing environment if [ "$CONDA_PREFIX" ]; then @@ -58,18 +55,18 @@ mkdir acados/build cd acados/build # Run cmake -cmake . .. \ - -DACADOS_INSTALL_DIR="$ARG2"\ - -DACADOS_PYTHON=ON\ - -DACADOS_WITH_QPOASES=ON\ - -DACADOS_WITH_OSQP=ON\ - -DBLASFEO_TARGET="$ARG3"\ - -DCMAKE_INSTALL_PREFIX="$ARG2"\ - -DACADOS_WITH_OPENMP=ON\ - -DACADOS_NUM_THREADS="$ARG1" -make install -j$CPU_COUNT - - +cmake .. \ + -DCMAKE_INSTALL_PREFIX="$ARG2" \ + -DACADOS_INSTALL_DIR="$ARG2" \ + -DACADOS_PYTHON=ON \ + -DACADOS_WITH_OSQP=ON \ + -DBLASFEO_TARGET="$ARG3" \ + -DACADOS_WITH_OPENMP=ON \ + -DACADOS_NUM_THREADS=$ARG1 + # The following two won't compile on Mac + # -DACADOS_WITH_QPOASES=ON \ + # -DACADOS_WITH_QPDUNES=ON \ +make install -j$NB_CPU_MAX # Prepare the Python interface cd ../interfaces/acados_template