Repository: kubeflow/pipelines

Issue:
[sdk] Compilation problems in kfp==1.7.1 when creating two independent operators from the same python component.
### Environment

```
$ pip list | grep kfp
kfp                           1.7.1
kfp-pipeline-spec             0.1.9
kfp-server-api                1.4.1
```

### Steps to reproduce

I have a python component function and call it twice in a pipeline with different parameter to create two independent operators from it. But during compilation of my pipeline, I get to following error:

```
Traceback (most recent call last):
  File "C:\Users\t13muell\.conda\envs\dstk\Scripts\kf_pipeline_preprocessing-script.py", line 33, in <module>
    sys.exit(load_entry_point('data-science-toolkit', 'console_scripts', 'kf_pipeline_preprocessing')())
  File "d:\code\data_science_toolkit\data_science_toolkit\scripts\kf_pipeline_preprocessing.py", line 115, in kf_pipeline_preprocessing_cli
    dry_run=args.dry_run,
  File "d:\code\kubeflow\kubeflow_util\kubeflow_util\pipelines.py", line 309, in submit_pipeline
    pipeline_func=pipeline_function, package_path=pipeline_package_file.name, type_check=False, pipeline_conf=pipeline_conf
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 1064, in compile
    package_path=package_path)
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 1119, in _create_and_write_workflow
    pipeline_conf)
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 954, in _create_workflow
    pipeline_conf,
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 717, in _create_pipeline_workflow
    templates = self._create_dag_templates(pipeline, op_transformers)
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 659, in _create_dag_templates
    op_name_to_for_loop_op,
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 272, in _get_inputs_outputs
    upstream_op = pipeline.ops[param.op_name]
KeyError: 'kf-comp-iterable-indices 2'
```

My python function is called `kf_comp_iterable_indices `. It all works with `pip install "kfp<1.7.1"` which results in version 1.7.0.

### Expected result

Correct execution of the two independent operators.

---

<!-- Don't delete message below to encourage users to support your issue! -->
Impacted by this bug? Give it a 👍. We prioritise the issues with the most 👍.



Discussion:
cc @chensun 
@thomas-mueller can you provide a minimal reproduction sample?
@Bobgy, @chensun, here is my smallest example:

```python
import functools
import kfp
import typing

create_component_from_func = functools.partial(kfp.components.create_component_from_func, base_image="python:3.7-buster")


@create_component_from_func
def kf_comp_ranges(n1: int, n2: int) -> typing.NamedTuple("kf_comp_ranges", [("r1", str), ("r2", str)]):
    import json
    return json.dumps(list(range(n1))), json.dumps(list(range(n2)))


@create_component_from_func
def kf_comp_indices(iterable: str) -> typing.List[int]:
    import json
    return list(range(len(json.loads(iterable))))


@create_component_from_func
def kf_comp_item(iterable: str, index: int) -> int:
    import json
    return json.loads(iterable)[index]


@kfp.dsl.pipeline(name="test", description="test")
def kf_pipeline(n1: int, n2: int):
    ranges = kf_comp_ranges(n1=n1, n2=n2)

    indicies1 = kf_comp_indices(iterable=ranges.outputs["r1"])
    indicies2 = kf_comp_indices(iterable=ranges.outputs["r2"])

    # without these loops, compiling would work.
    with kfp.dsl.ParallelFor(indicies1.output) as index1:
        item1 = kf_comp_item(iterable=ranges.outputs["r1"], index=index1)
    with kfp.dsl.ParallelFor(indicies2.output) as index2:
        item2 = kf_comp_item(iterable=ranges.outputs["r2"], index=index2)


kfp.compiler.Compiler().compile(pipeline_func=kf_pipeline, package_path="test.yaml", type_check=False)
```

The code works until `kfp==1.7.0`. Versions 1.7.1 and 1.7.2 give errors like
```
Traceback (most recent call last):
  File "test.py", line 40, in <module>
    kfp.compiler.Compiler().compile(pipeline_func=kf_pipeline, package_path="test.yaml", type_check=False)
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 1064, in compile
    package_path=package_path)
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 1119, in _create_and_write_workflow
    pipeline_conf)
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 954, in _create_workflow
    pipeline_conf,
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 717, in _create_pipeline_workflow
    templates = self._create_dag_templates(pipeline, op_transformers)
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 659, in _create_dag_templates
    op_name_to_for_loop_op,
  File "C:\Users\t13muell\.conda\envs\dstk\lib\site-packages\kfp\compiler\compiler.py", line 272, in _get_inputs_outputs
    upstream_op = pipeline.ops[param.op_name]
KeyError: 'kf-comp-indices 2'
```
/assign @chensun 

Resolving patch:
diff --git a/sdk/python/kfp/dsl/_pipeline.py b/sdk/python/kfp/dsl/_pipeline.py
--- a/sdk/python/kfp/dsl/_pipeline.py
+++ b/sdk/python/kfp/dsl/_pipeline.py
@@ -331,10 +331,10 @@ def add_op(self, op: _container_op.BaseOp, define_only: bool):
             '_', '-')
         #If there is an existing op with this name then generate a new name.
         op_name = _naming._make_name_unique_by_adding_index(
-            op_name, list(self.ops.keys()), ' ')
+            op_name, list(self.ops.keys()), '-')
         if op_name == '':
             op_name = _naming._make_name_unique_by_adding_index(
-                'task', list(self.ops.keys()), ' ')
+                'task', list(self.ops.keys()), '-')
 
         self.ops[op_name] = op
         if not define_only:


Test patch: