Don't require pygraphviz for regenerate.sh (#17485)

Summary:
closes #17336

Do not overwrite config.yml if script throws an error
Pull Request resolved: https://github.com/pytorch/pytorch/pull/17485

Differential Revision: D14604388

Pulled By: kostmo

fbshipit-source-id: 5024545e3a8711abdbc0800911c766929dbca196
This commit is contained in:
Karl Ostmo
2019-03-25 18:01:39 -07:00
committed by Facebook Github Bot
parent 13b95eac55
commit e1c272797b
25 changed files with 259 additions and 267 deletions

View File

@ -23,7 +23,9 @@ The documentation, in the form of diagrams, is automatically generated and canno
Furthermore, consistency is enforced within the YAML config itself, by using a single source of data to generate
multiple parts of the file.
See https://github.com/pytorch/pytorch/issues/17038
* Facilitates one-off culling/enabling of CI configs for testing PRs on special targets
Also see https://github.com/pytorch/pytorch/issues/17038
Future direction

View File

View File

@ -14,7 +14,8 @@ to produce a visualization of config dimensions.
from collections import OrderedDict
from cimodel.conf_tree import ConfigNode
from cimodel.lib.conf_tree import ConfigNode
import cimodel.data.dimensions as dimensions
LINKING_DIMENSIONS = [
@ -32,23 +33,8 @@ def get_processor_arch_name(cuda_version):
return "cpu" if not cuda_version else "cu" + cuda_version
CUDA_VERSIONS = [
None, # cpu build
"80",
"90",
"100",
]
STANDARD_PYTHON_VERSIONS = [
"2.7",
"3.5",
"3.6",
"3.7",
]
CONFIG_TREE_DATA = OrderedDict(
linux=(CUDA_VERSIONS, OrderedDict(
linux=(dimensions.CUDA_VERSIONS, OrderedDict(
manywheel=[
"2.7m",
"2.7mu",
@ -56,14 +42,14 @@ CONFIG_TREE_DATA = OrderedDict(
"3.6m",
"3.7m",
],
conda=STANDARD_PYTHON_VERSIONS,
conda=dimensions.STANDARD_PYTHON_VERSIONS,
libtorch=[
"2.7m",
]
)),
macos=([None], OrderedDict(
wheel=STANDARD_PYTHON_VERSIONS,
conda=STANDARD_PYTHON_VERSIONS,
wheel=dimensions.STANDARD_PYTHON_VERSIONS,
conda=dimensions.STANDARD_PYTHON_VERSIONS,
libtorch=[
"2.7",
],

View File

@ -2,10 +2,10 @@
from collections import OrderedDict
import cimodel.conf_tree as conf_tree
import cimodel.miniutils as miniutils
import cimodel.make_build_configs as make_build_configs
import cimodel.visualization as visualization
import cimodel.data.binary_build_data as binary_build_data
import cimodel.lib.conf_tree as conf_tree
import cimodel.lib.miniutils as miniutils
import cimodel.lib.visualization as visualization
class Conf(object):
@ -19,7 +19,7 @@ class Conf(object):
self.libtorch_variant = libtorch_variant
def gen_build_env_parms(self):
return [self.pydistro] + self.parms + [make_build_configs.get_processor_arch_name(self.cuda_version)]
return [self.pydistro] + self.parms + [binary_build_data.get_processor_arch_name(self.cuda_version)]
def gen_docker_image(self):
@ -50,40 +50,28 @@ class Conf(object):
def gen_yaml_tree(self, build_or_test):
env_dict = OrderedDict({
"BUILD_ENVIRONMENT": miniutils.quote(" ".join(self.gen_build_env_parms())),
})
env_tuples = [("BUILD_ENVIRONMENT", miniutils.quote(" ".join(self.gen_build_env_parms())))]
if self.libtorch_variant:
env_dict["LIBTORCH_VARIANT"] = miniutils.quote(self.libtorch_variant)
env_tuples.append(("LIBTORCH_VARIANT", miniutils.quote(self.libtorch_variant)))
os_word_substitution = {
"macos": "mac",
}
os_name = miniutils.override(self.os, os_word_substitution)
d = {
"environment": env_dict,
"<<": "*" + "_".join([self.get_name_prefix(), os_name, build_or_test]),
}
os_name = miniutils.override(self.os, {"macos": "mac"})
d = {"<<": "*" + "_".join([self.get_name_prefix(), os_name, build_or_test])}
if build_or_test == "test":
tuples = []
if not (self.smoke and self.os == "macos"):
tuples.append(("DOCKER_IMAGE", self.gen_docker_image()))
env_tuples.append(("DOCKER_IMAGE", self.gen_docker_image()))
if self.cuda_version:
tuples.append(("USE_CUDA_DOCKER_RUNTIME", miniutils.quote("1")))
for (k, v) in tuples:
env_dict[k] = v
env_tuples.append(("USE_CUDA_DOCKER_RUNTIME", miniutils.quote("1")))
else:
if self.os == "linux" and build_or_test != "upload":
d["docker"] = [{"image": self.gen_docker_image()}]
d["environment"] = OrderedDict(env_tuples)
if build_or_test == "test":
if self.cuda_version:
d["resource_class"] = "gpu.medium"
@ -93,9 +81,9 @@ class Conf(object):
def get_root(smoke, name):
return make_build_configs.TopLevelNode(
return binary_build_data.TopLevelNode(
name,
make_build_configs.CONFIG_TREE_DATA,
binary_build_data.CONFIG_TREE_DATA,
smoke,
)

View File

@ -2,9 +2,9 @@
from collections import OrderedDict
import cimodel.dimensions as dimensions
import cimodel.miniutils as miniutils
from cimodel.conf_tree import Ver
import cimodel.data.dimensions as dimensions
import cimodel.lib.miniutils as miniutils
from cimodel.lib.conf_tree import Ver
DOCKER_IMAGE_PATH_BASE = "308535385114.dkr.ecr.us-east-1.amazonaws.com/caffe2/"
@ -126,33 +126,22 @@ class Conf(object):
tuples.append(("BUILD_IOS", miniutils.quote("1")))
if self.phase == "test":
use_cuda_docker = self.compiler.name == "cuda"
if use_cuda_docker:
# TODO cuda should not be considered a compiler
if self.compiler.name == "cuda":
tuples.append(("USE_CUDA_DOCKER_RUNTIME", miniutils.quote("1")))
if not self.distro.name == "macos":
tuples.append(("DOCKER_IMAGE", self.gen_docker_image()))
if self.is_build_only():
if not self.distro.name == "macos":
tuples.append(("BUILD_ONLY", miniutils.quote("1")))
# TODO: not sure we need the distinction between system and homebrew anymore. Our python handling in cmake
# and setuptools is more robust now than when we first had these.
if self.distro.name == "macos":
tuples.append(("PYTHON_INSTALLATION", miniutils.quote("system")))
tuples.append(("PYTHON_VERSION", miniutils.quote("2")))
env_dict = OrderedDict(tuples)
else:
tuples.append(("DOCKER_IMAGE", self.gen_docker_image()))
if self.is_build_only():
tuples.append(("BUILD_ONLY", miniutils.quote("1")))
d = OrderedDict([
("environment", env_dict),
])
d = OrderedDict({"environment": OrderedDict(tuples)})
if self.phase == "test":
is_large = self.compiler.name != "cuda"
resource_class = "large" if is_large else "gpu.medium"
resource_class = "large" if self.compiler.name != "cuda" else "gpu.medium"
d["resource_class"] = resource_class
d["<<"] = "*" + "_".join(["caffe2", self.get_platform(), self.phase, "defaults"])

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
PHASES = ["build", "test"]
CUDA_VERSIONS = [
None, # cpu build
"80",
"90",
"100",
]
STANDARD_PYTHON_VERSIONS = [
"2.7",
"3.5",
"3.6",
"3.7",
]

View File

@ -2,11 +2,11 @@
from collections import OrderedDict
import cimodel.conf_tree as conf_tree
import cimodel.dimensions as dimensions
import cimodel.miniutils as miniutils
import cimodel.visualization as visualization
from cimodel.conf_tree import ConfigNode
import cimodel.data.dimensions as dimensions
import cimodel.lib.conf_tree as conf_tree
import cimodel.lib.miniutils as miniutils
import cimodel.lib.visualization as visualization
from cimodel.lib.conf_tree import ConfigNode
DOCKER_IMAGE_PATH_BASE = "308535385114.dkr.ecr.us-east-1.amazonaws.com/pytorch/"
@ -129,11 +129,7 @@ class HiddenConf(object):
def gen_workflow_yaml_item(self, phase):
val = OrderedDict()
dependency_build = self.parent_build
val["requires"] = [dependency_build.gen_build_name("build")]
return {self.gen_build_name(phase): val}
return {self.gen_build_name(phase): {"requires": [self.parent_build.gen_build_name("build")]}}
def gen_build_name(self, _):
return self.name
@ -153,10 +149,10 @@ def gen_dependent_configs(xenial_parent_config):
for parms, gpu in extra_parms:
c = Conf(
"xenial",
xenial_parent_config.distro,
["py3"] + parms,
pyver="3.6",
cuda_version="8",
cuda_version=xenial_parent_config.cuda_version,
restrict_phases=["test"],
gpu_resource=gpu,
parent_build=xenial_parent_config,
@ -170,25 +166,33 @@ def gen_dependent_configs(xenial_parent_config):
return configs
# TODO make the schema consistent between "trusty" and "xenial"
def X(val):
"""
Compact way to write a leaf node
"""
return val, []
CONFIG_TREE_DATA = [
("trusty", [
("2.7.9", []),
("2.7", []),
("3.5", []),
("3.6", [
("gcc4.8", []),
("gcc5.4", [False, True]),
("gcc7", []),
(None, [
X("2.7.9"),
X("2.7"),
X("3.5"),
X("nightly"),
]),
("gcc", [
("4.8", [X("3.6")]),
("5.4", [("3.6", [X(False), X(True)])]),
("7", [X("3.6")]),
]),
("nightly", []),
]),
("xenial", [
("clang", [
("5", [("3.6", [])]),
("5", [X("3.6")]),
]),
("cuda", [
("8", [("3.6", [])]),
("8", [X("3.6")]),
("9", [
# Note there are magic strings here
# https://github.com/pytorch/pytorch/blob/master/.jenkins/pytorch/build.sh#L21
@ -197,11 +201,11 @@ CONFIG_TREE_DATA = [
# and
# https://github.com/pytorch/pytorch/blob/master/.jenkins/pytorch/build.sh#L153
# (from https://github.com/pytorch/pytorch/pull/17323#discussion_r259453144)
("2.7", []),
("3.6", []),
X("2.7"),
X("3.6"),
]),
("9.2", [("3.6", [])]),
("10", [("3.6", [])]),
("9.2", [X("3.6")]),
("10", [X("3.6")]),
]),
]),
]
@ -222,99 +226,92 @@ def gen_tree():
return configs_list
class TopLevelNode(ConfigNode):
def __init__(self, node_name, config_tree_data):
super(TopLevelNode, self).__init__(None, node_name)
self.config_tree_data = config_tree_data
def get_children(self):
return [DistroConfigNode(self, d, p) for (d, p) in self.config_tree_data]
class DistroConfigNode(ConfigNode):
def __init__(self, parent, distro_name, subtree):
super(DistroConfigNode, self).__init__(parent, distro_name)
class TreeConfigNode(ConfigNode):
def __init__(self, parent, node_name, subtree):
super(TreeConfigNode, self).__init__(parent, self.modify_label(node_name))
self.subtree = subtree
self.props["distro_name"] = distro_name
self.init2(node_name)
def modify_label(self, label):
return label
def init2(self, node_name):
pass
def get_children(self):
if self.find_prop("distro_name") == "trusty":
return [PyVerConfigNode(self, k, v) for k, v in self.subtree]
else:
return [XenialCompilerConfigNode(self, v, subtree) for (v, subtree) in self.subtree]
return [self.child_constructor()(self, k, v) for (k, v) in self.subtree]
class PyVerConfigNode(ConfigNode):
def __init__(self, parent, pyver, subtree):
super(PyVerConfigNode, self).__init__(parent, pyver)
class TopLevelNode(TreeConfigNode):
def __init__(self, node_name, subtree):
super(TopLevelNode, self).__init__(None, node_name, subtree)
self.subtree = subtree
self.props["pyver"] = pyver
self.props["abbreviated_pyver"] = get_major_pyver(pyver)
def get_children(self):
return [CompilerConfigNode(self, v, xla_options) for (v, xla_options) in self.subtree]
def child_constructor(self):
return DistroConfigNode
class CompilerConfigNode(ConfigNode):
def __init__(self, parent, compiler_name, subtree):
super(CompilerConfigNode, self).__init__(parent, compiler_name)
class DistroConfigNode(TreeConfigNode):
def init2(self, node_name):
self.props["distro_name"] = node_name
self.props["compiler_name"] = compiler_name
self.subtree = subtree
def get_children(self):
return [XlaConfigNode(self, v) for v in self.subtree]
def child_constructor(self):
distro = self.find_prop("distro_name")
return TrustyCompilerConfigNode if distro == "trusty" else XenialCompilerConfigNode
class XenialCompilerConfigNode(ConfigNode):
def __init__(self, parent, compiler_name, subtree):
super(XenialCompilerConfigNode, self).__init__(parent, compiler_name)
class TrustyCompilerConfigNode(TreeConfigNode):
self.props["compiler_name"] = compiler_name
def modify_label(self, label):
return label or "<unspecified>"
self.subtree = subtree
def init2(self, node_name):
self.props["compiler_name"] = node_name
def get_children(self):
return [XenialCompilerVersionConfigNode(self, k, v) for (k, v) in self.subtree]
def child_constructor(self):
return TrustyCompilerVersionConfigNode if self.props["compiler_name"] else PyVerConfigNode
class XenialCompilerVersionConfigNode(ConfigNode):
def __init__(self, parent, compiler_version, subtree):
super(XenialCompilerVersionConfigNode, self).__init__(parent, compiler_version)
class TrustyCompilerVersionConfigNode(TreeConfigNode):
self.subtree = subtree
def init2(self, node_name):
self.props["compiler_version"] = node_name
self.props["compiler_version"] = compiler_version
def get_children(self):
return [XenialPythonVersionConfigNode(self, v) for (v, _) in self.subtree]
def child_constructor(self):
return PyVerConfigNode
class XenialPythonVersionConfigNode(ConfigNode):
def __init__(self, parent, python_version):
super(XenialPythonVersionConfigNode, self).__init__(parent, python_version)
class PyVerConfigNode(TreeConfigNode):
def init2(self, node_name):
self.props["pyver"] = node_name
self.props["abbreviated_pyver"] = get_major_pyver(node_name)
self.props["pyver"] = python_version
self.props["abbreviated_pyver"] = get_major_pyver(python_version)
def get_children(self):
return []
def child_constructor(self):
return XlaConfigNode
class XlaConfigNode(ConfigNode):
def __init__(self, parent, xla_enabled):
super(XlaConfigNode, self).__init__(parent, "XLA=" + str(xla_enabled))
class XlaConfigNode(TreeConfigNode):
def modify_label(self, label):
return "XLA=" + str(label)
self.props["is_xla"] = xla_enabled
def init2(self, node_name):
self.props["is_xla"] = node_name
def get_children(self):
return []
class XenialCompilerConfigNode(TreeConfigNode):
def init2(self, node_name):
self.props["compiler_name"] = node_name
def child_constructor(self):
return XenialCompilerVersionConfigNode
class XenialCompilerVersionConfigNode(TreeConfigNode):
def init2(self, node_name):
self.props["compiler_version"] = node_name
def child_constructor(self):
return PyVerConfigNode
def instantiate_configs():
@ -330,18 +327,17 @@ def instantiate_configs():
python_version = None
if distro_name == "xenial":
python_version = fc.find_prop("pyver")
if distro_name == "xenial":
parms_list = [fc.find_prop("abbreviated_pyver")]
else:
parms_list = ["py" + fc.find_prop("pyver")]
compiler_name = fc.find_prop("compiler_name")
cuda_version = None
if fc.find_prop("compiler_name") == "cuda":
if compiler_name == "cuda":
cuda_version = fc.find_prop("compiler_version")
compiler_name = fc.find_prop("compiler_name")
if compiler_name and compiler_name != "cuda":
elif compiler_name:
gcc_version = compiler_name + (fc.find_prop("compiler_version") or "")
parms_list.append(gcc_version)
@ -381,7 +377,6 @@ def add_build_env_defs(jobs_dict):
mydict = OrderedDict()
config_list = instantiate_configs()
for c in config_list:
for phase in dimensions.PHASES:
@ -427,7 +422,7 @@ def get_workflow_list():
x.append(conf_options.gen_workflow_yaml_item(phase))
# TODO convert to recursion
for conf in conf_options.dependent_tests:
for conf in conf_options.get_dependents():
x.append(conf.gen_workflow_yaml_item("test"))
return x

View File

@ -1,4 +0,0 @@
#!/usr/bin/env python3
PHASES = ["build", "test"]

View File

View File

@ -22,6 +22,7 @@ class ConfigNode(object):
def get_label(self):
return self.node_name
# noinspection PyMethodMayBeStatic
def get_children(self):
return []

View File

@ -2,7 +2,11 @@
def quote(s):
return '"' + s + '"'
return sandwich('"', s)
def sandwich(bread, jam):
return bread + jam + bread
def override(word, substitutions):

View File

@ -6,7 +6,7 @@ This module encapsulates dependencies on pygraphviz
import colorsys
import cimodel.conf_tree as conf_tree
import cimodel.lib.conf_tree as conf_tree
def rgb2hex(rgb_tuple):
@ -16,6 +16,25 @@ def rgb2hex(rgb_tuple):
return "#" + "".join(map(to_hex, list(rgb_tuple)))
def handle_missing_graphviz(f):
"""
If the user has not installed pygraphviz, this causes
calls to the draw() method of the returned object to do nothing.
"""
try:
import pygraphviz
return f
except ModuleNotFoundError:
class FakeGraph:
def draw(self, *args, **kwargs):
pass
return lambda _: FakeGraph()
@handle_missing_graphviz
def generate_graph(toplevel_config_node):
"""
Traverses the graph once first just to find the max depth
@ -27,9 +46,9 @@ def generate_graph(toplevel_config_node):
for config in config_list:
max_depth = max(max_depth, config.get_depth())
from pygraphviz import AGraph
# color the nodes using the max depth
from pygraphviz import AGraph
dot = AGraph()
def node_discovery_callback(node, sibling_index, sibling_count):

View File

@ -5,8 +5,8 @@
# https://github.com/pytorch/ossci-job-dsl/blob/master/src/main/groovy/ossci/pytorch/DockerVersion.groovy and
# https://github.com/pytorch/ossci-job-dsl/blob/master/src/main/groovy/ossci/caffe2/DockerVersion.groovy,
# and then update DOCKER_IMAGE_VERSION at the top of the following files:
# * cimodel/pytorch_build_definitions.py
# * cimodel/caffe2_build_definitions.py
# * cimodel/data/pytorch_build_definitions.py
# * cimodel/data/caffe2_build_definitions.py
docker_config_defaults: &docker_config_defaults
user: jenkins
@ -1102,11 +1102,9 @@ smoke_mac_test: &smoke_mac_test
##############################################################################
##############################################################################
# Job specifications job specs
##############################################################################
##############################################################################
version: 2
jobs:
pytorch_linux_trusty_py2_7_9_build:
@ -1148,6 +1146,19 @@ jobs:
resource_class: large
<<: *pytorch_linux_test_defaults
pytorch_linux_trusty_pynightly_build:
environment:
BUILD_ENVIRONMENT: pytorch-linux-trusty-pynightly-build
DOCKER_IMAGE: "308535385114.dkr.ecr.us-east-1.amazonaws.com/pytorch/pytorch-linux-trusty-pynightly:291"
<<: *pytorch_linux_build_defaults
pytorch_linux_trusty_pynightly_test:
environment:
BUILD_ENVIRONMENT: pytorch-linux-trusty-pynightly-test
DOCKER_IMAGE: "308535385114.dkr.ecr.us-east-1.amazonaws.com/pytorch/pytorch-linux-trusty-pynightly:291"
resource_class: large
<<: *pytorch_linux_test_defaults
pytorch_linux_trusty_py3_6_gcc4_8_build:
environment:
BUILD_ENVIRONMENT: pytorch-linux-trusty-py3.6-gcc4.8-build
@ -1200,19 +1211,6 @@ jobs:
resource_class: large
<<: *pytorch_linux_test_defaults
pytorch_linux_trusty_pynightly_build:
environment:
BUILD_ENVIRONMENT: pytorch-linux-trusty-pynightly-build
DOCKER_IMAGE: "308535385114.dkr.ecr.us-east-1.amazonaws.com/pytorch/pytorch-linux-trusty-pynightly:291"
<<: *pytorch_linux_build_defaults
pytorch_linux_trusty_pynightly_test:
environment:
BUILD_ENVIRONMENT: pytorch-linux-trusty-pynightly-test
DOCKER_IMAGE: "308535385114.dkr.ecr.us-east-1.amazonaws.com/pytorch/pytorch-linux-trusty-pynightly:291"
resource_class: large
<<: *pytorch_linux_test_defaults
pytorch_linux_xenial_py3_clang5_asan_build:
environment:
BUILD_ENVIRONMENT: pytorch-linux-xenial-py3-clang5-asan-build
@ -1677,14 +1675,12 @@ jobs:
environment:
BUILD_ENVIRONMENT: caffe2-py2-ios-macos10.13-build
BUILD_IOS: "1"
PYTHON_INSTALLATION: "system"
PYTHON_VERSION: "2"
<<: *caffe2_macos_build_defaults
caffe2_py2_system_macos10_13_build:
environment:
BUILD_ENVIRONMENT: caffe2-py2-system-macos10.13-build
PYTHON_INSTALLATION: "system"
PYTHON_VERSION: "2"
<<: *caffe2_macos_build_defaults
@ -2040,10 +2036,11 @@ jobs:
BUILD_ENVIRONMENT: "libtorch 2.7 cpu"
<<: *binary_mac_build
# Binary build tests
# These are the smoke tests run right after the build, before the upload. If
# these fail, the upload doesn't happen
#############################################################################
##############################################################################
# Binary build tests
# These are the smoke tests run right after the build, before the upload.
# If these fail, the upload doesn't happen.
##############################################################################
binary_linux_manywheel_2.7m_cpu_test:
environment:
BUILD_ENVIRONMENT: "manywheel 2.7m cpu"
@ -2339,8 +2336,9 @@ jobs:
# resource_class: gpu.medium
# <<: *binary_linux_test
# Binary build uploads
#############################################################################
##############################################################################
# Binary build uploads
##############################################################################
binary_linux_manywheel_2.7m_cpu_upload:
environment:
BUILD_ENVIRONMENT: "manywheel 2.7m cpu"
@ -2586,7 +2584,6 @@ jobs:
BUILD_ENVIRONMENT: "libtorch 2.7 cpu"
<<: *binary_mac_upload
##############################################################################
# Smoke test specs individual job specifications
##############################################################################
@ -3065,6 +3062,10 @@ workflows:
- pytorch_linux_trusty_py3_5_test:
requires:
- pytorch_linux_trusty_py3_5_build
- pytorch_linux_trusty_pynightly_build
- pytorch_linux_trusty_pynightly_test:
requires:
- pytorch_linux_trusty_pynightly_build
- pytorch_linux_trusty_py3_6_gcc4_8_build
- pytorch_linux_trusty_py3_6_gcc4_8_test:
requires:
@ -3081,10 +3082,6 @@ workflows:
- pytorch_linux_trusty_py3_6_gcc7_test:
requires:
- pytorch_linux_trusty_py3_6_gcc7_build
- pytorch_linux_trusty_pynightly_build
- pytorch_linux_trusty_pynightly_test:
requires:
- pytorch_linux_trusty_pynightly_build
- pytorch_linux_xenial_py3_clang5_asan_build
- pytorch_linux_xenial_py3_clang5_asan_test:
requires:
@ -3270,7 +3267,6 @@ workflows:
- smoke_macos_conda_3.7_cpu
- smoke_macos_libtorch_2.7_cpu
##############################################################################
# Daily binary build trigger
##############################################################################
@ -3333,7 +3329,9 @@ workflows:
- binary_macos_conda_3.7_cpu_build
- binary_macos_libtorch_2.7_cpu_build
# Nightly tests
##############################################################################
# Nightly tests
##############################################################################
- binary_linux_manywheel_2.7m_cpu_test:
requires:
- binary_linux_manywheel_2.7m_cpu_build

View File

@ -3,18 +3,18 @@
"""
This script is the source of truth for config.yml.
Please see README.md in this directory for details.
In this module,
"""
import os
import sys
from collections import OrderedDict
import shutil
from collections import namedtuple, OrderedDict
import cimodel.pytorch_build_definitions as pytorch_build_definitions
import cimodel.binary_build_definitions as binary_build_definitions
import cimodel.caffe2_build_definitions as caffe2_build_definitions
import cimodel.miniyaml as miniyaml
import cimodel.data.pytorch_build_definitions as pytorch_build_definitions
import cimodel.data.binary_build_definitions as binary_build_definitions
import cimodel.data.caffe2_build_definitions as caffe2_build_definitions
import cimodel.lib.miniutils as miniutils
import cimodel.lib.miniyaml as miniyaml
class File(object):
@ -26,16 +26,17 @@ class File(object):
def write(self, output_filehandle):
with open(os.path.join("verbatim-sources", self.filename)) as fh:
output_filehandle.write(fh.read())
shutil.copyfileobj(fh, output_filehandle)
class Treegen(object):
class FunctionGen(namedtuple('FunctionGen', 'function depth')):
__slots__ = ()
class Treegen(FunctionGen):
"""
Insert the content of a YAML tree into config.yml
"""
def __init__(self, function, depth):
self.function = function
self.depth = depth
def write(self, output_filehandle):
build_dict = OrderedDict()
@ -43,18 +44,33 @@ class Treegen(object):
miniyaml.render(output_filehandle, build_dict, self.depth)
class Listgen(object):
class Listgen(FunctionGen):
"""
Insert the content of a YAML list into config.yml
"""
def __init__(self, function, depth):
self.function = function
self.depth = depth
def write(self, output_filehandle):
miniyaml.render(output_filehandle, self.function(), self.depth)
def horizontal_rule():
return "".join("#" * 78)
class Header(object):
def __init__(self, title, summary=None):
self.title = title
self.summary_lines = summary or []
def write(self, output_filehandle):
text_lines = [self.title] + self.summary_lines
comment_lines = ["# " + x for x in text_lines]
lines = miniutils.sandwich([horizontal_rule()], comment_lines)
for line in filter(None, lines):
output_filehandle.write(line + "\n")
# Order of this list matters to the generated config.yml.
YAML_SOURCES = [
File("header-section.yml"),
@ -64,30 +80,35 @@ YAML_SOURCES = [
File("linux-binary-build-defaults.yml"),
File("macos-binary-build-defaults.yml"),
File("nightly-build-smoke-tests-defaults.yml"),
File("job-specs-header.yml"),
Header("Job specifications job specs"),
Treegen(pytorch_build_definitions.add_build_env_defs, 0),
File("job-specs-custom.yml"),
Treegen(caffe2_build_definitions.add_caffe2_builds, 1),
File("job-specs-html-update.yml"),
File("binary-build-specs-header.yml"),
Header("Binary build specs individual job specifications"),
Treegen(binary_build_definitions.add_binary_build_specs, 1),
File("binary-build-tests-header.yml"),
Header(
"Binary build tests", [
"These are the smoke tests run right after the build, before the upload.",
"If these fail, the upload doesn't happen."
]
),
Treegen(binary_build_definitions.add_binary_build_tests, 1),
File("binary-build-tests.yml"),
File("binary-build-uploads-header.yml"),
Header("Binary build uploads"),
Treegen(binary_build_definitions.add_binary_build_uploads, 1),
File("smoke-test-specs-header.yml"),
Header("Smoke test specs individual job specifications"),
Treegen(binary_build_definitions.add_smoke_test_specs, 1),
File("workflows.yml"),
Listgen(pytorch_build_definitions.get_workflow_list, 3),
File("workflows-pytorch-macos-builds.yml"),
Listgen(caffe2_build_definitions.get_caffe2_workflows, 3),
File("workflows-binary-builds-smoke-subset.yml"),
File("workflows-binary-smoke-header.yml"),
Header("Daily smoke test trigger"),
Treegen(binary_build_definitions.add_binary_smoke_test_jobs, 1),
File("workflows-binary-build-header.yml"),
Header("Daily binary build trigger"),
Treegen(binary_build_definitions.add_binary_build_jobs, 1),
File("workflows-nightly-tests-header.yml"),
Header("Nightly tests"),
Listgen(binary_build_definitions.get_nightly_tests, 3),
File("workflows-nightly-uploads-header.yml"),
Listgen(binary_build_definitions.get_nightly_uploads, 3),

View File

@ -3,4 +3,6 @@
# Allows this script to be invoked from any directory:
cd $(dirname "$0")
./generate_config_yml.py > config.yml
NEW_FILE=$(mktemp)
./generate_config_yml.py > $NEW_FILE
cp $NEW_FILE config.yml

View File

@ -1,3 +0,0 @@
##############################################################################
# Binary build specs individual job specifications
##############################################################################

View File

@ -1,4 +0,0 @@
# Binary build tests
# These are the smoke tests run right after the build, before the upload. If
# these fail, the upload doesn't happen
#############################################################################

View File

@ -1,2 +0,0 @@
# Binary build uploads
#############################################################################

View File

@ -5,8 +5,8 @@
# https://github.com/pytorch/ossci-job-dsl/blob/master/src/main/groovy/ossci/pytorch/DockerVersion.groovy and
# https://github.com/pytorch/ossci-job-dsl/blob/master/src/main/groovy/ossci/caffe2/DockerVersion.groovy,
# and then update DOCKER_IMAGE_VERSION at the top of the following files:
# * cimodel/pytorch_build_definitions.py
# * cimodel/caffe2_build_definitions.py
# * cimodel/data/pytorch_build_definitions.py
# * cimodel/data/caffe2_build_definitions.py
docker_config_defaults: &docker_config_defaults
user: jenkins

View File

@ -1,5 +0,0 @@
##############################################################################
##############################################################################
# Job specifications job specs
##############################################################################
##############################################################################

View File

@ -1,4 +0,0 @@
##############################################################################
# Smoke test specs individual job specifications
##############################################################################

View File

@ -1,3 +0,0 @@
##############################################################################
# Daily smoke test trigger
##############################################################################

View File

@ -1 +0,0 @@
# Nightly tests

View File

@ -15,11 +15,6 @@ matrix:
- name: "Ensure consistent CircleCI YAML"
python: "3.6"
dist: xenial
install:
- sudo add-apt-repository universe
- sudo apt update
- sudo apt install graphviz
- pip3 install pygraphviz
script: cd .circleci && ./ensure-consistency.py
- name: "Python 2.7 Lint"
python: "2.7"