def ask()

in nevergrad/optimization/base.py [0:0]


    def ask(self) -> p.Parameter:
        """Provides a point to explore.
        This function can be called multiple times to explore several points in parallel

        Returns
        -------
        p.Parameter:
            The candidate to try on the objective function. :code:`p.Parameter` have field :code:`args` and :code:`kwargs`
            which can be directly used on the function (:code:`objective_function(*candidate.args, **candidate.kwargs)`).
        """
        # call callbacks for logging etc...
        for callback in self._callbacks.get("ask", []):
            callback(self)
        current_num_ask = self.num_ask
        # tentatives if a cheap constraint is available
        max_trials = max(1, self._constraints_manager.max_trials // 2)
        # half will be used for sub-optimization --- if the optimization method does not need/use a budget.
        # TODO(oteytaud): actually we could do this even when the budget is known, if we are sure that
        # exceeding the budget is not a problem.
        # Very simple constraint solver:
        # - we use a simple algorithm.
        # - no memory of previous iterations.
        # - just projection to constraint satisfaction.
        # We try using the normal tool during half constraint budget, in order to reduce the impact on the normal run.
        for _ in range(max_trials):
            is_suggestion = False
            if self._suggestions:  # use suggestions if available
                is_suggestion = True
                candidate = self._suggestions.pop()
            else:
                try:  # Sometimes we have a limited budget so that
                    candidate = self._internal_ask_candidate()
                except AssertionError as e:
                    assert (
                        self.parametrization._constraint_checkers
                    ), f"Error: {e}"  # This should not happen without constraint issues.
                    candidate = self.parametrization.spawn_child()
            if candidate.satisfies_constraints():
                break  # good to go!
            if self._penalize_cheap_violations or self.no_parallelization:
                # Warning! This might be a tell not asked.
                self._internal_tell_candidate(candidate, float("Inf"))  # DE requires a tell
            # updating num_ask  is necessary for some algorithms which need new num to ask another point
            self._num_ask += 1
        satisfies = candidate.satisfies_constraints()
        if not satisfies:
            # still not solving, let's run sub-optimization
            candidate = _constraint_solver(candidate, budget=max_trials)
        if not (satisfies or candidate.satisfies_constraints()):
            self._warn(
                f"Could not bypass the constraint after {max_trials} tentatives, "
                "sending candidate anyway.",
                errors.FailedConstraintWarning,
            )
        if not is_suggestion:
            if candidate.uid in self._asked:
                raise RuntimeError(
                    "Cannot submit the same candidate twice: please recreate a new candidate from data.\n"
                    "This is to make sure that stochastic parametrizations are resampled."
                )
            self._asked.add(candidate.uid)
        self._num_ask = current_num_ask + 1
        assert (
            candidate is not None
        ), f"{self.__class__.__name__}._internal_ask method returned None instead of a point."
        # make sure to call value getter which may update the value, before we freeze the paremeter
        candidate.value  # pylint: disable=pointless-statement
        candidate.freeze()  # make sure it is not modified somewhere
        return candidate