Skip to content

Commit

Permalink
CI env var (#1667)
Browse files Browse the repository at this point in the history
Make CIRCLECI env var checks also apply on github actions

Co-authored-by: bottler <[email protected]>
  • Loading branch information
bottler and bottler authored Dec 3, 2024
1 parent a40a1e4 commit f931d31
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 76 deletions.
41 changes: 24 additions & 17 deletions nevergrad/benchmark/test_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,23 @@
import typing as tp
from pathlib import Path
from unittest import SkipTest
import pytest
import numpy as np
from nevergrad.optimization import registry as optregistry

import nevergrad.functions.base as fbase
from nevergrad.functions.mlda import datasets
from nevergrad.functions import rl
from nevergrad.common import testing
import numpy as np
import pytest

# from nevergrad.common.tools import Selector
from nevergrad.common import tools
from .xpbase import Experiment
from nevergrad.common import testing, tools
from nevergrad.functions import rl
from nevergrad.functions.mlda import datasets
from nevergrad.optimization import registry as optregistry

from . import experiments, optgroups
from .utils import Selector
from . import experiments
from . import optgroups
from .xpbase import Experiment


CI = bool(os.environ.get("CIRCLECI", False)) or bool(os.environ.get("CI", False))


@testing.parametrized(
Expand All @@ -48,17 +51,17 @@ def test_experiments_registry(name: str, maker: tp.Callable[[], tp.Iterator[expe
raise SkipTest("Compiler/emulator stuff too heavy for CircleCI.")

# Our PGAN is not well accepted by circleci.
if "_pgan" in name and os.environ.get("CIRCLECI", False):
raise SkipTest("Too slow in CircleCI")
if "_pgan" in name and CI:
raise SkipTest("Too slow in CI")

if "gym" in name and os.environ.get("CIRCLECI", False):
raise SkipTest("Too slow in CircleCI")
if "gym" in name and CI:
raise SkipTest("Too slow in CI")

if "yawideb" in name or "_quality" in name:
raise SkipTest("I should have a look at this test.")

# mixsimulator is not accepted by circleci pytest.
if "mixsimulator" in name and os.environ.get("CIRCLECI", False):
if "mixsimulator" in name and CI:
raise SkipTest("Sigkill in CircleCI")

# Our IQAs and our ScikitLearn are not well guaranteed on Windows.
Expand All @@ -72,7 +75,7 @@ def test_experiments_registry(name: str, maker: tp.Callable[[], tp.Iterator[expe
check_maker(maker) # this is to extract the function for reuse if other external packages need it

# Some tests are skipped on CircleCI (but they do work well locally, if memory enough).
if os.environ.get("CIRCLECI", False):
if CI:
if any(x in name for x in ["image", "mlda", "realworld", "adversarial_attack"]):
raise SkipTest("Too slow in CircleCI")

Expand Down Expand Up @@ -145,7 +148,11 @@ def check_experiment(maker: tp.Any, short: bool = False, skip_seed: bool = False
xps = list(itertools.islice(maker(seed), 0, 1 if short else 2))
simplified = [
Experiment(
xp.function, algo, budget=2, num_workers=min(2, xp.optimsettings.num_workers), seed=xp.seed
xp.function,
algo,
budget=2,
num_workers=min(2, xp.optimsettings.num_workers),
seed=xp.seed,
)
for xp in xps
]
Expand Down
42 changes: 30 additions & 12 deletions nevergrad/functions/images/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import os
import itertools
import os
from pathlib import Path

import cv2

import nevergrad as ng
import nevergrad.common.typing as tp
import numpy as np
import PIL.Image
import torch.nn as nn
import torch
import torch.nn as nn
import torchvision
from torchvision.models import resnet50
import torchvision.transforms as tr

import nevergrad as ng
import nevergrad.common.typing as tp
from nevergrad.common import errors
from torchvision.models import resnet50

from .. import base
from . import imagelosses

Expand Down Expand Up @@ -102,7 +103,8 @@ def _generate_images(self, x: np.ndarray) -> np.ndarray:
.numpy()[:, :, :, [2, 1, 0]]
)

def interpolate(self, base_image: np.ndarray, target: np.ndarray, k: int, num_images: int) -> np.ndarray:
@staticmethod
def interpolate(base_image: np.ndarray, target: np.ndarray, k: int, num_images: int) -> np.ndarray:
if num_images == 1:
return target
coef1 = k / (num_images - 1)
Expand Down Expand Up @@ -132,7 +134,10 @@ def _loss_with_pgan(self, x: np.ndarray, export_string: str = "") -> float:
image = self._generate_images(base_image).squeeze(0)
image = cv2.resize(image, dsize=(226, 226), interpolation=cv2.INTER_NEAREST)
if export_string:
cv2.imwrite(f"{export_string}_image{i}_{num_total_images}_{self.num_images}.jpg", image)
cv2.imwrite(
f"{export_string}_image{i}_{num_total_images}_{self.num_images}.jpg",
image,
)
assert image.shape == (226, 226, 3), f"{x.shape} != {(226, 226, 3)}"
loss += self.loss_function(image)
return loss
Expand Down Expand Up @@ -202,7 +207,12 @@ def __init__(
mutable_sigma=True,
).set_name("")
array.set_mutation(sigma=self.epsilon / 10)
array.set_bounds(lower=-self.epsilon, upper=self.epsilon, method="clipping", full_range_sampling=True)
array.set_bounds(
lower=-self.epsilon,
upper=self.epsilon,
method="clipping",
full_range_sampling=True,
)
max_size = ng.p.Scalar(lower=1, upper=200).set_integer_casting()
array = ng.p.mutation.Crossover(axis=(1, 2), max_size=max_size)(array)
super().__init__(self._loss, array)
Expand Down Expand Up @@ -250,7 +260,10 @@ def make_folder_functions(
an experiment function corresponding to 1 of the image of the provided folder dataset.
"""
assert model in {"resnet50", "test"}
tags = {"folder": "#FAKE#" if folder is None else Path(folder).name, "model": model}
tags = {
"folder": "#FAKE#" if folder is None else Path(folder).name,
"model": model,
}
classifier: tp.Any = Resnet50() if model == "resnet50" else TestClassifier()
classifier.eval()

Expand All @@ -271,7 +284,11 @@ def make_folder_functions(
_, pred = torch.max(classifier(data), axis=1)
if pred == target:
func = cls(
classifier=classifier, image=data[0], label=int(target), targeted=False, epsilon=0.05
classifier=classifier,
image=data[0],
label=int(target),
targeted=False,
epsilon=0.05,
)
func.add_descriptors(**tags)
yield func
Expand Down Expand Up @@ -310,7 +327,8 @@ def __init__(
if not torch.cuda.is_available():
use_gpu = False
# Storing high level information..
if os.environ.get("CIRCLECI", False):
CI = bool(os.environ.get("CIRCLECI", False)) or bool(os.environ.get("CI", False))
if CI:
raise errors.UnsupportedExperiment("ImageFromPGAN is not well supported in CircleCI")
self.pgan_model = torch.hub.load(
"facebookresearch/pytorch_GAN_zoo:hub",
Expand Down
31 changes: 21 additions & 10 deletions nevergrad/functions/photonics/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
# LICENSE file in the root directory of this source tree.

import os
from unittest import SkipTest
import warnings
import typing as tp
import pytest
import warnings
from unittest import SkipTest

import numpy as np
import pytest
from nevergrad.common import testing
from . import core
from . import photonics

from . import core, photonics

CI = bool(os.environ.get("CIRCLECI", False)) or bool(os.environ.get("CI", False))


@testing.parametrized(
Expand Down Expand Up @@ -66,7 +69,7 @@ def test_photonics_bragg_recombination() -> None:


def test_photonics_custom_mutation() -> None:
if os.environ.get("CIRCLECI", False):
if CI:
raise SkipTest("Skipping in CI because way too slow on their machine (weird)")
func = core.Photonics("morpho", 16, rolling=True)
param = func.parametrization.spawn_child()
Expand Down Expand Up @@ -102,7 +105,7 @@ def test_no_warning(name: str, method: str) -> None:
bragg=("bragg", 2.5, 0.93216),
)
def test_photonics_values(name: str, value: float, expected: float) -> None:
if name == "morpho" and os.environ.get("CIRCLECI", False):
if name == "morpho" and CI:
raise SkipTest("Too slow in CircleCI")
photo = core.Photonics(name, 16)
np.testing.assert_almost_equal(photo(value * np.ones(16)), expected, decimal=4)
Expand Down Expand Up @@ -169,13 +172,21 @@ def test_photonics_values(name: str, value: float, expected: float) -> None:
@testing.parametrized(
morpho=("morpho", 1.127904, None),
chirped=("chirped", 0.594587, None),
good_chirped=("chirped", 0.275923, np.array([GOOD_CHIRPED])), # supposed to be better
good_chirped=(
"chirped",
0.275923,
np.array([GOOD_CHIRPED]),
), # supposed to be better
bragg=("bragg", 0.96776, None),
photosic_realistic=("cf_photosic_realistic", 0.0860257, np.array(EPS_AND_D).reshape((2, -1))),
photosic_realistic=(
"cf_photosic_realistic",
0.0860257,
np.array(EPS_AND_D).reshape((2, -1)),
),
photosic_reference=("cf_photosic_reference", 0.431072, None),
)
def test_photonics_values_random(name: str, expected: float, data: tp.Optional[np.ndarray]) -> None:
if name == "morpho" and os.environ.get("CIRCLECI", False):
if name == "morpho" and CI:
raise SkipTest("Too slow in CircleCI")
size = data.size if data is not None else (16 if name != "morpho" else 4)
photo = core.Photonics(name, size)
Expand Down
41 changes: 20 additions & 21 deletions nevergrad/optimization/test_optimizerlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
np.random.seed(0)


CI = bool(os.environ.get("CIRCLECI", False)) or bool(os.environ.get("CI", False))


def long_name(s: str):
if s[-1] in "0123456789":
return True
Expand All @@ -55,9 +58,7 @@ def long_name(s: str):
return True
if "DS" in s or "AX" in s or "BO" in s or any(x in s for x in [str(i) for i in range(10)]):
return True
return len(s.replace("DiscreteOnePlusOne", "D1+1").replace("Tuned", "")) > 2 and os.environ.get(
"CIRCLECI", False
)
return len(s.replace("DiscreteOnePlusOne", "D1+1").replace("Tuned", "")) > 2 and CI


short_registry = [r for r in registry if not long_name(r)]
Expand Down Expand Up @@ -206,8 +207,8 @@ def test_ngopt(dim: int, budget_multiplier: int, num_workers: int, bounded: bool
@pytest.mark.parametrize("name", short_registry) # type: ignore
@testing.suppress_nevergrad_warnings() # hides bad loss
def test_infnan(name: str) -> None:
if any(x in name for x in ["SMAC", "BO", "AX"]) and os.environ.get("CIRCLECI", False):
raise SkipTest("too slow for CircleCI!")
if any(x in name for x in ["SMAC", "BO", "AX"]) and CI:
raise SkipTest("too slow for CI!")
if "Force" in name:
raise SkipTest("Forced methods not tested for infnan")

Expand Down Expand Up @@ -264,8 +265,8 @@ def doint(s): # Converting a string into an int.
@pytest.mark.parametrize("name", short_registry) # type: ignore
def test_optimizers(name: str) -> None:
"""Checks that each optimizer is able to converge on a simple test case"""
if any(x in name for x in ["Chain", "SMAC", "BO", "AX"]) and os.environ.get("CIRCLECI", False):
raise SkipTest("too slow for CircleCI!")
if any(x in name for x in ["Chain", "SMAC", "BO", "AX"]) and CI:
raise SkipTest("too slow for CI!")
if "BO" in name or "Chain" in name or "Tiny" in name or "Micro" in name: # moo issues :-(
return
if any(x in name for x in ["Tiny", "Vast"]):
Expand All @@ -289,7 +290,7 @@ def doint(s): # Converting a string into an int.
]
or "Tiny" in name
or "Micro" in name
) and os.environ.get("CIRCLECI", False):
) and CI:
raise SkipTest("Too expensive: we randomly skip 3/4 of these tests.")
if name in ["CMAbounded", "NEWUOA"]: # Not a general purpose optimization method.
return
Expand Down Expand Up @@ -322,8 +323,8 @@ def doint(s): # Converting a string into an int.
@pytest.mark.parametrize("name", short_registry) # type: ignore
def test_optimizers_minimal(name: str) -> None:
optimizer_cls = registry[name]
if any(x in name for x in ["SMAC", "BO", "AX"]) and os.environ.get("CIRCLECI", False):
raise SkipTest("too slow for CircleCI!")
if any(x in name for x in ["SMAC", "BO", "AX"]) and CI:
raise SkipTest("too slow for CI!")
if optimizer_cls.one_shot or name in [
"CM",
"NLOPT_LN_PRAXIS",
Expand Down Expand Up @@ -480,8 +481,8 @@ def recomkeeper() -> tp.Generator[RecommendationKeeper, None, None]:
# pylint: disable=redefined-outer-name
@pytest.mark.parametrize("name", short_registry) # type: ignore
def test_optimizers_recommendation(name: str, recomkeeper: RecommendationKeeper) -> None:
if any(x in name for x in ["SMAC", "BO", "AX"]) and os.environ.get("CIRCLECI", False):
raise SkipTest("too slow for CircleCI!")
if any(x in name for x in ["SMAC", "BO", "AX"]) and CI:
raise SkipTest("too slow for CI!")
if (
name in UNSEEDABLE
or "BAR" in name
Expand Down Expand Up @@ -906,10 +907,8 @@ def constraint(i: tp.Any) -> tp.Union[bool, float]:
def test_parametrization_offset(name: str) -> None:
if long_name(name):
return
if any(x in name for x in ["SMAC", "BO", "AX"]) and os.environ.get(
"CIRCLECI", False
): # Outside CircleCI, only the big.
raise SkipTest("too slow for CircleCI!")
if any(x in name for x in ["SMAC", "BO", "AX"]) and CI:
raise SkipTest("too slow for CI!")
if sum([ord(c) for c in name]) % 4 > 0:
raise SkipTest("Randomly skipping 75% of these tests.")
if "PSO" in name or "BO" in name:
Expand Down Expand Up @@ -1212,13 +1211,13 @@ def test_smoother() -> None:
@pytest.mark.parametrize("n", [5, 10, 15, 25, 40]) # type: ignore
@pytest.mark.parametrize("b_per_dim", [10, 20]) # type: ignore
def test_voronoide(n, b_per_dim) -> None:
if n < 25 or b_per_dim < 1 and not os.environ.get("CIRCLECI", False): # Outside CircleCI, only the big.
raise SkipTest("Only big things outside CircleCI.")
if n < 25 or b_per_dim < 1 and not CI: # Outside CircleCI, only the big.
raise SkipTest("Only big things outside CI.")

list_optims = ["CMA", "DE", "PSO", "RandomSearch", "TwoPointsDE", "OnePlusOne"]
if os.environ.get("CIRCLECI", False) and (n > 10 or n * b_per_dim > 100): # In CircleCI, only the small.
raise SkipTest("Topology optimization too slow in CircleCI")
if os.environ.get("CIRCLECI", False) or (n < 10 or b_per_dim < 20):
if CI and (n > 10 or n * b_per_dim > 100): # In CircleCI, only the small.
raise SkipTest("Topology optimization too slow in CI")
if CI or (n < 10 or b_per_dim < 20):
list_optims = ["CMA", "PSO", "OnePlusOne"]
if n > 20:
list_optims = ["DE", "TwoPointsDE"]
Expand Down
Loading

0 comments on commit f931d31

Please sign in to comment.