def test_mpi_passes(self):
        run_config = CompiledOperationSpecification.read([
            os.path.abspath("tests/fixtures/plain/distributed_mpi_file.yml"),
            {
                "kind": "compiled_operation"
            },
        ])

        run_config = CompiledOperationSpecification.apply_context(run_config)
        assert run_config.version == 1.05
        assert run_config.is_mpi_job_run
        assert run_config.termination is None
        assert run_config.run.launcher.replicas == 1
        assert run_config.run.launcher.to_dict() == {
            "replicas": 1,
            "container": {
                "name": "polyaxon-main",
                "image": "mpioperator/tensorflow-benchmarks:latest",
                "command": ["mpirun", "python", "run.py"],
            },
        }
        assert run_config.run.launcher.environment is None

        assert run_config.run.worker.replicas == 2
        assert run_config.run.worker.environment.affinity is None
        assert run_config.run.worker.environment.node_selector is not None
        assert isinstance(run_config.run.worker.environment.tolerations, list)
        assert run_config.run.worker.to_dict()["container"] == {
            "name": "polyaxon-main",
            "image": "mpioperator/tensorflow-benchmarks:latest",
            "command": ["mpirun", "python", "run.py"],
            "resources": {
                "limits": {
                    "nvidia.com/gpu": 1
                }
            },
        }
Beispiel #2
0
    def test_matrix_file_passes_int_float_types(self):
        run_config = V1CompiledOperation.read(
            [
                reader.read(
                    os.path.abspath(
                        "tests/fixtures/pipelines/matrix_file_with_int_float_types.yml"
                    )
                ),
                {"kind": "compiled_operation"},
            ]
        )

        run_config = CompiledOperationSpecification.apply_context(run_config)
        assert run_config.version == 1.05
        assert run_config.is_dag_run is True
        assert run_config.has_pipeline is True
        assert run_config.schedule is None
        assert run_config.run.concurrency == 4
        assert isinstance(run_config.run, V1Dag)
        assert run_config.run.early_stopping is None
        assert run_config.run.kind == V1Dag.IDENTIFIER
        assert len(run_config.run.operations) == 2
        assert len(run_config.run.components) == 1
        template_grid = run_config.run.operations[1].parallel
        assert isinstance(template_grid, V1GridSearch)
        assert isinstance(template_grid.params["param1"], V1HpChoice)
        assert isinstance(template_grid.params["param2"], V1HpChoice)
        assert template_grid.params["param1"].to_dict() == {
            "kind": "choice",
            "value": [1, 2],
        }
        assert template_grid.params["param2"].to_dict() == {
            "kind": "choice",
            "value": [3.3, 4.4],
        }
        assert template_grid.concurrency == 2
        assert template_grid.early_stopping is None
    def test_patch_experiment_without_io_and_params_raises(self):
        content = {
            "version": 1.05,
            "kind": "component",
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        config = V1Component.read(content)
        assert config.to_dict() == content

        content = {
            "version": 1.05,
            "kind": "compiled_operation",
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        config = V1CompiledOperation.read(content)
        config = CompiledOperationSpecification.apply_context(config)
        assert config.to_dict() == content

        # Add params
        params = {"params": {"lr": 0.1}}
        with self.assertRaises(ValidationError):
            config.patch(values=params)
    def test_build_run_pipeline(self):
        run_config = V1CompiledOperation.read(
            [
                os.path.abspath("tests/fixtures/pipelines/build_run_pipeline.yml"),
                {"kind": "compiled_operation"},
            ]
        )

        run_config = CompiledOperationSpecification.apply_context(run_config)
        assert len(run_config.run.operations) == 2
        assert run_config.run.operations[0].name == "build"
        assert run_config.run.operations[1].name == "run"
        assert run_config.is_dag_run is True
        assert run_config.has_pipeline is True
        assert run_config.schedule is None
        assert len(run_config.run.components) == 2
        assert run_config.run.components[0].name == "experiment-template"
        assert run_config.run.components[0].termination.to_dict() == {"maxRetries": 2}
        assert run_config.run.components[0].run.to_dict() == {
            "kind": V1RunKind.JOB,
            "environment": {
                "nodeSelector": {"polyaxon": "experiments"},
                "serviceAccountName": "service",
                "imagePullSecrets": ["secret1", "secret2"],
            },
            "container": {
                "image": "{{ image }}",
                "command": ["python3", "main.py"],
                "args": "--lr={{ lr }}",
                "name": "polyaxon-main",
                "resources": {"requests": {"cpu": 1}},
            },
        }
        assert run_config.run.components[1].name == "build-template"
        assert run_config.run.components[1].run.container.image == "base"
        assert run_config.run.operations[0].name == "build"

        # Create a an op spec
        run_config.run.set_op_component("run")
        assert run_config.run.operations[1].has_component_reference is True
        job_config = run_config.run.get_op_spec_by_index(1)
        assert {p: job_config.params[p].to_dict() for p in job_config.params} == {
            "image": {"value": "outputs.docker-image", "ref": "ops.build"},
            "lr": {"value": 0.001},
        }
        run_config = OperationSpecification.compile_operation(job_config)
        run_config.apply_params({"image": {"value": "foo"}, "lr": {"value": 0.001}})
        run_config = CompiledOperationSpecification.apply_context(run_config)
        run_config = CompiledOperationSpecification.apply_run_contexts(run_config)
        assert run_config.termination.to_dict() == {"maxRetries": 2}
        assert run_config.run.to_dict() == {
            "kind": V1RunKind.JOB,
            "environment": {
                "nodeSelector": {"polyaxon": "experiments"},
                "serviceAccountName": "service",
                "imagePullSecrets": ["secret1", "secret2"],
            },
            "container": {
                "image": "foo",
                "command": ["python3", "main.py"],
                "args": "--lr=0.001",
                "name": "polyaxon-main",
                "resources": {"requests": {"cpu": 1}},
            },
        }
Beispiel #5
0
    def test_required_inputs_with_params(self):
        run_config = V1CompiledOperation.read([
            os.path.abspath("tests/fixtures/typing/required_inputs.yml"),
            {
                "kind": "compiled_operation"
            },
        ])

        with self.assertRaises(ValidationError):
            CompiledOperationSpecification.apply_context(run_config)

        assert run_config.inputs[0].value is None
        assert run_config.inputs[1].value is None
        run_config.apply_params(params={
            "loss": {
                "value": "bar"
            },
            "flag": {
                "value": False
            }
        })
        assert run_config.inputs[0].value == "bar"
        assert run_config.inputs[1].value is False
        run_config = CompiledOperationSpecification.apply_context(run_config)
        run_config = CompiledOperationSpecification.apply_run_contexts(
            run_config)
        assert run_config.version == 1.1
        assert run_config.tags == ["foo", "bar"]
        assert run_config.run.container.image == "my_image"
        assert run_config.run.container.command == ["/bin/sh", "-c"]
        assert run_config.run.container.args == "video_prediction_train --loss=bar "

        run_config = V1CompiledOperation.read([
            os.path.abspath("tests/fixtures/typing/required_inputs.yml"),
            {
                "kind": "compiled_operation"
            },
        ])

        assert run_config.inputs[0].value is None
        assert run_config.inputs[1].value is None
        run_config.apply_params(params={
            "loss": {
                "value": "bar"
            },
            "flag": {
                "value": True
            }
        })
        assert run_config.inputs[0].value == "bar"
        assert run_config.inputs[1].value is True
        run_config = CompiledOperationSpecification.apply_context(run_config)
        run_config = CompiledOperationSpecification.apply_run_contexts(
            run_config)
        assert run_config.version == 1.1
        assert run_config.tags == ["foo", "bar"]
        assert run_config.run.container.image == "my_image"
        assert run_config.run.container.command == ["/bin/sh", "-c"]
        assert (run_config.run.container.args ==
                "video_prediction_train --loss=bar --flag")

        # Adding extra value raises
        with self.assertRaises(ValidationError):
            run_config.validate_params(
                params={
                    "loss": {
                        "value": "bar"
                    },
                    "flag": {
                        "value": True
                    },
                    "value": {
                        "value": 1.1
                    },
                })
        with self.assertRaises(PolyaxonfileError):
            check_polyaxonfile(
                polyaxonfile=os.path.abspath(
                    "tests/fixtures/typing/required_inputs.yml"),
                params={
                    "loss": {
                        "value": "bar"
                    },
                    "value": {
                        "value": 1.1
                    }
                },
                is_cli=False,
            )

        # Adding non valid params raises
        with self.assertRaises(ValidationError):
            run_config.validate_params(params={"value": {"value": 1.1}})
    def test_apply_context_raises_with_required_inputs(self):
        content = {
            "version":
            1.05,
            "kind":
            "component",
            "inputs": [
                {
                    "name": "lr",
                    "type": types.FLOAT
                },
                {
                    "name": "num_steps",
                    "type": types.INT
                },
            ],
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        component_config = V1Component.read(content)
        assert component_config.to_dict() == content

        content = {
            "version":
            1.05,
            "kind":
            "compiled_operation",
            "inputs": [
                {
                    "name": "lr",
                    "type": types.FLOAT
                },
                {
                    "name": "num_steps",
                    "type": types.INT
                },
            ],
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        run_config = V1CompiledOperation.read(content)

        # Raise because required inputs are not met
        with self.assertRaises(ValidationError):
            CompiledOperationSpecification.apply_context(run_config)

        # Validation for template should pass
        validated_params = run_config.validate_params()
        assert {
            "lr": None,
            "num_steps": None
        } == {p.name: p.param.value
              for p in validated_params}
        # Validation for non template should raise
        with self.assertRaises(ValidationError):
            run_config.validate_params(is_template=False)
    def test_patch_experiment_with_optional_inputs(self):
        content = {
            "version":
            1.05,
            "kind":
            "compiled_operation",
            "inputs": [
                {
                    "name": "lr",
                    "type": types.FLOAT,
                    "value": 0.6,
                    "isOptional": True
                },
                {
                    "name": "num_steps",
                    "type": types.INT,
                    "value": 16,
                    "isOptional": True,
                },
            ],
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        config = V1CompiledOperation.read(content)
        assert config.inputs[0].value == 0.6
        assert config.inputs[1].value == 16
        config = CompiledOperationSpecification.apply_context(config)
        validated_params = config.validate_params()
        assert {
            "lr": 0.6,
            "num_steps": 16
        } == {p.name: p.param.value
              for p in validated_params}
        assert config.inputs[0].value == 0.6
        assert config.inputs[1].value == 16

        with self.assertRaises(ValidationError):  # not valid
            params = {"params": {"lr": 0.1}}
            config.patch(values=params)

        # Add env
        assert config.run.container.resources is None
        env = {
            "run": {
                "container": {
                    "resources": {
                        "requests": {
                            "gpu": 1,
                            "tpu": 1
                        },
                        "limits": {
                            "gpu": 1,
                            "tpu": 1
                        },
                    }
                }
            }
        }
        config = config.patch(values=env)
        assert config.run.container.resources == {
            "requests": {
                "gpu": 1,
                "tpu": 1
            },
            "limits": {
                "gpu": 1,
                "tpu": 1
            },
        }

        # Patch with unsupported spec
        matrix = {"hptuning": {"params": {"lr": {"values": [0.1, 0.2]}}}}
        with self.assertRaises(ValidationError):
            config.patch(values=matrix)

        # Patch with unsupported spec
        wrong_config = {"lr": {"values": [0.1, 0.2]}}
        with self.assertRaises(ValidationError):
            config.patch(values=wrong_config)
    def test_apply_context_passes_with_required_inputs_and_params(self):
        content = {
            "version":
            1.05,
            "kind":
            "component",
            "inputs": [
                {
                    "name": "lr",
                    "type": types.FLOAT
                },
                {
                    "name": "num_steps",
                    "type": types.INT
                },
            ],
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        component_config = V1Component.read(content)
        assert component_config.to_dict() == content

        content = {
            "version":
            1.05,
            "kind":
            "compiled_operation",
            "inputs": [
                {
                    "name": "lr",
                    "type": types.FLOAT
                },
                {
                    "name": "num_steps",
                    "type": types.INT
                },
            ],
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        run_config = V1CompiledOperation.read(content)
        # no params
        with self.assertRaises(ValidationError):
            CompiledOperationSpecification.apply_context(run_config)

        params = {"lr": {"value": 0.1}, "num_steps": {"value": 100}}

        assert run_config.inputs[0].value is None
        assert run_config.inputs[1].value is None
        validated_params = run_config.validate_params(params=params)
        run_config.apply_params(params=params)
        assert params == {p.name: p.param.to_dict() for p in validated_params}
        assert run_config.inputs[0].value == 0.1
        assert run_config.inputs[1].value == 100

        run_config = CompiledOperationSpecification.apply_context(run_config)
        updated_content = {
            "version":
            1.05,
            "kind":
            "compiled_operation",
            "inputs": [
                {
                    "name": "lr",
                    "type": types.FLOAT,
                    "isOptional": True,
                    "value": 0.1
                },
                {
                    "name": "num_steps",
                    "type": types.INT,
                    "isOptional": True,
                    "value": 100,
                },
            ],
            "run": {
                "kind": V1RunKind.JOB,
                "container": {
                    "name": "polyaxon-main",
                    "image": "test/test:latest",
                    "command": "train",
                },
            },
        }
        assert run_config.to_dict() == updated_content

        env = {
            "run": {
                "container": {
                    "resources": {
                        "requests": {
                            "gpu": 1,
                            "tpu": 1
                        },
                        "limits": {
                            "gpu": 1,
                            "tpu": 1
                        },
                    }
                }
            }
        }
        run_config = run_config.patch(values=env)
        assert (run_config.run.container.resources == env["run"]["container"]
                ["resources"])