From c1cdcdcd724a553fa22f9920742f81b87f7ada8e Mon Sep 17 00:00:00 2001 From: Clive Cox Date: Sun, 11 Dec 2022 19:08:42 +0000 Subject: [PATCH 01/18] initial commit for pipeline inputs from other pipelines --- apis/go/mlops/agent/agent.pb.go | 16 - apis/go/mlops/agent/agent_grpc.pb.go | 16 - apis/go/mlops/agent_debug/agent_debug.pb.go | 16 - .../mlops/agent_debug/agent_debug_grpc.pb.go | 16 - apis/go/mlops/chainer/chainer.pb.go | 341 ++- apis/go/mlops/chainer/chainer_grpc.pb.go | 16 - apis/go/mlops/proxy/proxy.pb.go | 16 - apis/go/mlops/proxy/proxy_grpc.pb.go | 16 - apis/go/mlops/scheduler/scheduler.pb.go | 1100 ++++---- apis/go/mlops/scheduler/scheduler_grpc.pb.go | 16 - apis/go/mlops/scheduler/storage.pb.go | 16 - .../v2_dataplane/v2_dataplane_grpc.pb.go | 16 - apis/mlops/chainer/chainer.proto | 11 +- .../kotlin/io/seldon/mlops/chainer/BatchKt.kt | 16 - .../mlops/chainer/ChainerOuterClass.java | 2266 +++++++++++++---- .../mlops/chainer/ChainerOuterClassGrpcKt.kt | 16 - .../mlops/chainer/ChainerOuterClassKt.kt | 16 - .../mlops/chainer/PipelineStepUpdateKt.kt | 100 +- .../chainer/PipelineSubscriptionRequestKt.kt | 16 - .../seldon/mlops/chainer/PipelineTopicKt.kt | 63 + .../mlops/chainer/PipelineUpdateMessageKt.kt | 16 - .../chainer/PipelineUpdateStatusMessageKt.kt | 16 - .../chainer/PipelineUpdateStatusResponseKt.kt | 16 - apis/mlops/scheduler/scheduler.proto | 15 + .../apis/mlops/v1alpha1/pipeline_types.go | 54 +- .../mlops/v1alpha1/zz_generated.deepcopy.go | 52 + samples/multiple-pipelines.ipynb | 534 ++++ samples/pipeline-examples.ipynb | 107 +- samples/pipelines/tfsimple-extended.yaml | 16 + .../io/seldon/dataflow/kafka/Chainer.kt | 58 +- .../kotlin/io/seldon/dataflow/kafka/Joiner.kt | 56 +- .../io/seldon/dataflow/kafka/PipelineStep.kt | 74 +- .../seldon/dataflow/kafka/StreamTransforms.kt | 6 + .../dataflow/kafka/TriggerTransforms.kt | 17 +- .../kafka/headers/PipelineHeaderSetter.kt | 21 + .../seldon/dataflow/kafka/PipelineStepTest.kt | 101 +- .../triton/config/model_config.pb.go | 584 ++--- scheduler/pkg/kafka/dataflow/server.go | 62 +- scheduler/pkg/kafka/dataflow/server_test.go | 59 +- scheduler/pkg/kafka/topics.go | 32 +- scheduler/pkg/proxy/chainer.go | 8 +- scheduler/pkg/store/pipeline/errors.go | 10 + scheduler/pkg/store/pipeline/pipeline.go | 10 + scheduler/pkg/store/pipeline/utils.go | 83 +- scheduler/pkg/store/pipeline/utils_test.go | 2 +- scheduler/pkg/store/pipeline/validate.go | 66 +- scheduler/pkg/store/pipeline/validate_test.go | 213 +- 47 files changed, 4378 insertions(+), 2015 deletions(-) create mode 100644 apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTopicKt.kt create mode 100644 samples/multiple-pipelines.ipynb create mode 100644 samples/pipelines/tfsimple-extended.yaml create mode 100644 scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/headers/PipelineHeaderSetter.kt diff --git a/apis/go/mlops/agent/agent.pb.go b/apis/go/mlops/agent/agent.pb.go index 883393ef2a..3e36cd3f9f 100644 --- a/apis/go/mlops/agent/agent.pb.go +++ b/apis/go/mlops/agent/agent.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 diff --git a/apis/go/mlops/agent/agent_grpc.pb.go b/apis/go/mlops/agent/agent_grpc.pb.go index 5894bfd911..f5ea789141 100644 --- a/apis/go/mlops/agent/agent_grpc.pb.go +++ b/apis/go/mlops/agent/agent_grpc.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 diff --git a/apis/go/mlops/agent_debug/agent_debug.pb.go b/apis/go/mlops/agent_debug/agent_debug.pb.go index 8affc2991d..4507be2417 100644 --- a/apis/go/mlops/agent_debug/agent_debug.pb.go +++ b/apis/go/mlops/agent_debug/agent_debug.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Debug service for agent replica // Code generated by protoc-gen-go. DO NOT EDIT. diff --git a/apis/go/mlops/agent_debug/agent_debug_grpc.pb.go b/apis/go/mlops/agent_debug/agent_debug_grpc.pb.go index 7c85ff2316..c66eda6366 100644 --- a/apis/go/mlops/agent_debug/agent_debug_grpc.pb.go +++ b/apis/go/mlops/agent_debug/agent_debug_grpc.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 diff --git a/apis/go/mlops/chainer/chainer.pb.go b/apis/go/mlops/chainer/chainer.pb.go index 6b64e39be1..489dd7a047 100644 --- a/apis/go/mlops/chainer/chainer.pb.go +++ b/apis/go/mlops/chainer/chainer.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 @@ -272,9 +256,9 @@ type PipelineStepUpdate struct { // Pipeline Resource example, e.g. transform.outputs.traffic // // seldon.... - Sources []string `protobuf:"bytes,1,rep,name=sources,proto3" json:"sources,omitempty"` - Triggers []string `protobuf:"bytes,2,rep,name=triggers,proto3" json:"triggers,omitempty"` - Sink string `protobuf:"bytes,3,opt,name=sink,proto3" json:"sink,omitempty"` + Sources []*PipelineTopic `protobuf:"bytes,1,rep,name=sources,proto3" json:"sources,omitempty"` + Triggers []*PipelineTopic `protobuf:"bytes,2,rep,name=triggers,proto3" json:"triggers,omitempty"` + Sink *PipelineTopic `protobuf:"bytes,3,opt,name=sink,proto3" json:"sink,omitempty"` InputJoinTy PipelineStepUpdate_PipelineJoinType `protobuf:"varint,4,opt,name=inputJoinTy,proto3,enum=seldon.mlops.chainer.PipelineStepUpdate_PipelineJoinType" json:"inputJoinTy,omitempty"` TriggersJoinTy PipelineStepUpdate_PipelineJoinType `protobuf:"varint,5,opt,name=triggersJoinTy,proto3,enum=seldon.mlops.chainer.PipelineStepUpdate_PipelineJoinType" json:"triggersJoinTy,omitempty"` PassEmptyResponses bool `protobuf:"varint,6,opt,name=passEmptyResponses,proto3" json:"passEmptyResponses,omitempty"` // Forward empty response to following steps, default false @@ -315,25 +299,25 @@ func (*PipelineStepUpdate) Descriptor() ([]byte, []int) { return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{2} } -func (x *PipelineStepUpdate) GetSources() []string { +func (x *PipelineStepUpdate) GetSources() []*PipelineTopic { if x != nil { return x.Sources } return nil } -func (x *PipelineStepUpdate) GetTriggers() []string { +func (x *PipelineStepUpdate) GetTriggers() []*PipelineTopic { if x != nil { return x.Triggers } return nil } -func (x *PipelineStepUpdate) GetSink() string { +func (x *PipelineStepUpdate) GetSink() *PipelineTopic { if x != nil { return x.Sink } - return "" + return nil } func (x *PipelineStepUpdate) GetInputJoinTy() PipelineStepUpdate_PipelineJoinType { @@ -378,6 +362,61 @@ func (x *PipelineStepUpdate) GetBatch() *Batch { return nil } +type PipelineTopic struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineName string `protobuf:"bytes,1,opt,name=pipelineName,proto3" json:"pipelineName,omitempty"` + TopicName string `protobuf:"bytes,2,opt,name=topicName,proto3" json:"topicName,omitempty"` +} + +func (x *PipelineTopic) Reset() { + *x = PipelineTopic{} + if protoimpl.UnsafeEnabled { + mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PipelineTopic) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PipelineTopic) ProtoMessage() {} + +func (x *PipelineTopic) ProtoReflect() protoreflect.Message { + mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PipelineTopic.ProtoReflect.Descriptor instead. +func (*PipelineTopic) Descriptor() ([]byte, []int) { + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{3} +} + +func (x *PipelineTopic) GetPipelineName() string { + if x != nil { + return x.PipelineName + } + return "" +} + +func (x *PipelineTopic) GetTopicName() string { + if x != nil { + return x.TopicName + } + return "" +} + type Batch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -391,7 +430,7 @@ type Batch struct { func (x *Batch) Reset() { *x = Batch{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + mi := &file_mlops_chainer_chainer_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -404,7 +443,7 @@ func (x *Batch) String() string { func (*Batch) ProtoMessage() {} func (x *Batch) ProtoReflect() protoreflect.Message { - mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + mi := &file_mlops_chainer_chainer_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -417,7 +456,7 @@ func (x *Batch) ProtoReflect() protoreflect.Message { // Deprecated: Use Batch.ProtoReflect.Descriptor instead. func (*Batch) Descriptor() ([]byte, []int) { - return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{3} + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{4} } func (x *Batch) GetSize() uint32 { @@ -455,7 +494,7 @@ type PipelineUpdateStatusMessage struct { func (x *PipelineUpdateStatusMessage) Reset() { *x = PipelineUpdateStatusMessage{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_chainer_chainer_proto_msgTypes[4] + mi := &file_mlops_chainer_chainer_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -468,7 +507,7 @@ func (x *PipelineUpdateStatusMessage) String() string { func (*PipelineUpdateStatusMessage) ProtoMessage() {} func (x *PipelineUpdateStatusMessage) ProtoReflect() protoreflect.Message { - mi := &file_mlops_chainer_chainer_proto_msgTypes[4] + mi := &file_mlops_chainer_chainer_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -481,7 +520,7 @@ func (x *PipelineUpdateStatusMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineUpdateStatusMessage.ProtoReflect.Descriptor instead. func (*PipelineUpdateStatusMessage) Descriptor() ([]byte, []int) { - return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{4} + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{5} } func (x *PipelineUpdateStatusMessage) GetUpdate() *PipelineUpdateMessage { @@ -514,7 +553,7 @@ type PipelineUpdateStatusResponse struct { func (x *PipelineUpdateStatusResponse) Reset() { *x = PipelineUpdateStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_chainer_chainer_proto_msgTypes[5] + mi := &file_mlops_chainer_chainer_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -527,7 +566,7 @@ func (x *PipelineUpdateStatusResponse) String() string { func (*PipelineUpdateStatusResponse) ProtoMessage() {} func (x *PipelineUpdateStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_mlops_chainer_chainer_proto_msgTypes[5] + mi := &file_mlops_chainer_chainer_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -540,7 +579,7 @@ func (x *PipelineUpdateStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineUpdateStatusResponse.ProtoReflect.Descriptor instead. func (*PipelineUpdateStatusResponse) Descriptor() ([]byte, []int) { - return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{5} + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{6} } var File_mlops_chainer_chainer_proto protoreflect.FileDescriptor @@ -571,89 +610,101 @@ var file_mlops_chainer_chainer_proto_rawDesc = []byte{ 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x10, 0x02, 0x22, 0x90, 0x05, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, - 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, - 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x12, 0x5b, 0x0a, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4a, - 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x73, 0x65, - 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x6f, - 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4a, 0x6f, 0x69, - 0x6e, 0x54, 0x79, 0x12, 0x61, 0x0a, 0x0e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, - 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x73, 0x65, - 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x6f, - 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, - 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x70, 0x61, 0x73, 0x73, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x12, 0x70, 0x61, 0x73, 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, - 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, - 0x55, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x08, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, - 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x65, 0x6e, - 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, - 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x31, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, - 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, - 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3e, 0x0a, 0x10, 0x50, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, - 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, - 0x72, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x10, 0x02, 0x12, 0x07, - 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x10, 0x03, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, - 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x71, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, - 0x00, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x77, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x08, - 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x72, - 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x6f, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x0b, - 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x94, 0x01, 0x0a, 0x1b, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x65, - 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x22, 0x1e, 0x0a, 0x1c, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x32, 0x89, 0x02, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x7e, - 0x0a, 0x18, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x10, 0x02, 0x22, 0xff, 0x05, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x07, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x70, + 0x69, 0x63, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x08, 0x74, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x70, + 0x69, 0x63, 0x52, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x37, 0x0a, 0x04, + 0x73, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x6c, + 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x52, + 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x12, 0x5b, 0x0a, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4a, 0x6f, + 0x69, 0x6e, 0x54, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x73, 0x65, 0x6c, + 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x6f, 0x69, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4a, 0x6f, 0x69, 0x6e, + 0x54, 0x79, 0x12, 0x61, 0x0a, 0x0e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, + 0x69, 0x6e, 0x54, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x6f, 0x69, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, + 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x70, 0x61, 0x73, 0x73, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x12, 0x70, 0x61, 0x73, 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x6a, + 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x55, + 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x37, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, + 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x65, 0x6e, 0x73, + 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, + 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x31, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, + 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, + 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3e, 0x0a, 0x10, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, + 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x10, 0x02, 0x12, 0x07, 0x0a, + 0x03, 0x41, 0x6e, 0x79, 0x10, 0x03, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x51, 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x71, 0x0a, 0x05, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x48, 0x00, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, + 0x52, 0x08, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, + 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x94, 0x01, + 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, + 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x7e, - 0x0a, 0x13, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, - 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x32, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, - 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x53, - 0x0a, 0x17, 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, - 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x69, 0x6f, 0x2f, 0x73, - 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, - 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x1e, 0x0a, 0x1c, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x89, 0x02, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x12, 0x7e, 0x0a, 0x18, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x73, + 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, + 0x12, 0x7e, 0x0a, 0x13, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, + 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, + 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x32, 0x2e, 0x73, 0x65, 0x6c, + 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x53, 0x0a, 0x17, 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, + 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5a, 0x38, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x69, 0x6f, + 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -669,35 +720,39 @@ func file_mlops_chainer_chainer_proto_rawDescGZIP() []byte { } var file_mlops_chainer_chainer_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_mlops_chainer_chainer_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_mlops_chainer_chainer_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_mlops_chainer_chainer_proto_goTypes = []interface{}{ (PipelineUpdateMessage_PipelineOperation)(0), // 0: seldon.mlops.chainer.PipelineUpdateMessage.PipelineOperation (PipelineStepUpdate_PipelineJoinType)(0), // 1: seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType (*PipelineSubscriptionRequest)(nil), // 2: seldon.mlops.chainer.PipelineSubscriptionRequest (*PipelineUpdateMessage)(nil), // 3: seldon.mlops.chainer.PipelineUpdateMessage (*PipelineStepUpdate)(nil), // 4: seldon.mlops.chainer.PipelineStepUpdate - (*Batch)(nil), // 5: seldon.mlops.chainer.Batch - (*PipelineUpdateStatusMessage)(nil), // 6: seldon.mlops.chainer.PipelineUpdateStatusMessage - (*PipelineUpdateStatusResponse)(nil), // 7: seldon.mlops.chainer.PipelineUpdateStatusResponse - nil, // 8: seldon.mlops.chainer.PipelineStepUpdate.TensorMapEntry + (*PipelineTopic)(nil), // 5: seldon.mlops.chainer.PipelineTopic + (*Batch)(nil), // 6: seldon.mlops.chainer.Batch + (*PipelineUpdateStatusMessage)(nil), // 7: seldon.mlops.chainer.PipelineUpdateStatusMessage + (*PipelineUpdateStatusResponse)(nil), // 8: seldon.mlops.chainer.PipelineUpdateStatusResponse + nil, // 9: seldon.mlops.chainer.PipelineStepUpdate.TensorMapEntry } var file_mlops_chainer_chainer_proto_depIdxs = []int32{ - 0, // 0: seldon.mlops.chainer.PipelineUpdateMessage.op:type_name -> seldon.mlops.chainer.PipelineUpdateMessage.PipelineOperation - 4, // 1: seldon.mlops.chainer.PipelineUpdateMessage.updates:type_name -> seldon.mlops.chainer.PipelineStepUpdate - 1, // 2: seldon.mlops.chainer.PipelineStepUpdate.inputJoinTy:type_name -> seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType - 1, // 3: seldon.mlops.chainer.PipelineStepUpdate.triggersJoinTy:type_name -> seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType - 8, // 4: seldon.mlops.chainer.PipelineStepUpdate.tensorMap:type_name -> seldon.mlops.chainer.PipelineStepUpdate.TensorMapEntry - 5, // 5: seldon.mlops.chainer.PipelineStepUpdate.batch:type_name -> seldon.mlops.chainer.Batch - 3, // 6: seldon.mlops.chainer.PipelineUpdateStatusMessage.update:type_name -> seldon.mlops.chainer.PipelineUpdateMessage - 2, // 7: seldon.mlops.chainer.Chainer.SubscribePipelineUpdates:input_type -> seldon.mlops.chainer.PipelineSubscriptionRequest - 6, // 8: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:input_type -> seldon.mlops.chainer.PipelineUpdateStatusMessage - 3, // 9: seldon.mlops.chainer.Chainer.SubscribePipelineUpdates:output_type -> seldon.mlops.chainer.PipelineUpdateMessage - 7, // 10: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:output_type -> seldon.mlops.chainer.PipelineUpdateStatusResponse - 9, // [9:11] is the sub-list for method output_type - 7, // [7:9] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 0, // 0: seldon.mlops.chainer.PipelineUpdateMessage.op:type_name -> seldon.mlops.chainer.PipelineUpdateMessage.PipelineOperation + 4, // 1: seldon.mlops.chainer.PipelineUpdateMessage.updates:type_name -> seldon.mlops.chainer.PipelineStepUpdate + 5, // 2: seldon.mlops.chainer.PipelineStepUpdate.sources:type_name -> seldon.mlops.chainer.PipelineTopic + 5, // 3: seldon.mlops.chainer.PipelineStepUpdate.triggers:type_name -> seldon.mlops.chainer.PipelineTopic + 5, // 4: seldon.mlops.chainer.PipelineStepUpdate.sink:type_name -> seldon.mlops.chainer.PipelineTopic + 1, // 5: seldon.mlops.chainer.PipelineStepUpdate.inputJoinTy:type_name -> seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType + 1, // 6: seldon.mlops.chainer.PipelineStepUpdate.triggersJoinTy:type_name -> seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType + 9, // 7: seldon.mlops.chainer.PipelineStepUpdate.tensorMap:type_name -> seldon.mlops.chainer.PipelineStepUpdate.TensorMapEntry + 6, // 8: seldon.mlops.chainer.PipelineStepUpdate.batch:type_name -> seldon.mlops.chainer.Batch + 3, // 9: seldon.mlops.chainer.PipelineUpdateStatusMessage.update:type_name -> seldon.mlops.chainer.PipelineUpdateMessage + 2, // 10: seldon.mlops.chainer.Chainer.SubscribePipelineUpdates:input_type -> seldon.mlops.chainer.PipelineSubscriptionRequest + 7, // 11: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:input_type -> seldon.mlops.chainer.PipelineUpdateStatusMessage + 3, // 12: seldon.mlops.chainer.Chainer.SubscribePipelineUpdates:output_type -> seldon.mlops.chainer.PipelineUpdateMessage + 8, // 13: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:output_type -> seldon.mlops.chainer.PipelineUpdateStatusResponse + 12, // [12:14] is the sub-list for method output_type + 10, // [10:12] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_mlops_chainer_chainer_proto_init() } @@ -743,7 +798,7 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Batch); i { + switch v := v.(*PipelineTopic); i { case 0: return &v.state case 1: @@ -755,7 +810,7 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineUpdateStatusMessage); i { + switch v := v.(*Batch); i { case 0: return &v.state case 1: @@ -767,6 +822,18 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PipelineUpdateStatusMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mlops_chainer_chainer_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PipelineUpdateStatusResponse); i { case 0: return &v.state @@ -780,14 +847,14 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[2].OneofWrappers = []interface{}{} - file_mlops_chainer_chainer_proto_msgTypes[3].OneofWrappers = []interface{}{} + file_mlops_chainer_chainer_proto_msgTypes[4].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mlops_chainer_chainer_proto_rawDesc, NumEnums: 2, - NumMessages: 7, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/apis/go/mlops/chainer/chainer_grpc.pb.go b/apis/go/mlops/chainer/chainer_grpc.pb.go index 9fda44f0de..85d299adb0 100644 --- a/apis/go/mlops/chainer/chainer_grpc.pb.go +++ b/apis/go/mlops/chainer/chainer_grpc.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 diff --git a/apis/go/mlops/proxy/proxy.pb.go b/apis/go/mlops/proxy/proxy.pb.go index 21bd1a7192..6ccbbbace8 100644 --- a/apis/go/mlops/proxy/proxy.pb.go +++ b/apis/go/mlops/proxy/proxy.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 diff --git a/apis/go/mlops/proxy/proxy_grpc.pb.go b/apis/go/mlops/proxy/proxy_grpc.pb.go index 0ef992ade3..973e9d4790 100644 --- a/apis/go/mlops/proxy/proxy_grpc.pb.go +++ b/apis/go/mlops/proxy/proxy_grpc.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 diff --git a/apis/go/mlops/scheduler/scheduler.pb.go b/apis/go/mlops/scheduler/scheduler.pb.go index 649d0ec991..d3f8338f95 100644 --- a/apis/go/mlops/scheduler/scheduler.pb.go +++ b/apis/go/mlops/scheduler/scheduler.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 @@ -275,6 +259,55 @@ func (PipelineStep_JoinOp) EnumDescriptor() ([]byte, []int) { return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{39, 0} } +type PipelineInput_JoinOp int32 + +const ( + PipelineInput_INNER PipelineInput_JoinOp = 0 + PipelineInput_OUTER PipelineInput_JoinOp = 1 + PipelineInput_ANY PipelineInput_JoinOp = 2 +) + +// Enum value maps for PipelineInput_JoinOp. +var ( + PipelineInput_JoinOp_name = map[int32]string{ + 0: "INNER", + 1: "OUTER", + 2: "ANY", + } + PipelineInput_JoinOp_value = map[string]int32{ + "INNER": 0, + "OUTER": 1, + "ANY": 2, + } +) + +func (x PipelineInput_JoinOp) Enum() *PipelineInput_JoinOp { + p := new(PipelineInput_JoinOp) + *p = x + return p +} + +func (x PipelineInput_JoinOp) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PipelineInput_JoinOp) Descriptor() protoreflect.EnumDescriptor { + return file_mlops_scheduler_scheduler_proto_enumTypes[4].Descriptor() +} + +func (PipelineInput_JoinOp) Type() protoreflect.EnumType { + return &file_mlops_scheduler_scheduler_proto_enumTypes[4] +} + +func (x PipelineInput_JoinOp) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PipelineInput_JoinOp.Descriptor instead. +func (PipelineInput_JoinOp) EnumDescriptor() ([]byte, []int) { + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{41, 0} +} + type PipelineOutput_JoinOp int32 const ( @@ -308,11 +341,11 @@ func (x PipelineOutput_JoinOp) String() string { } func (PipelineOutput_JoinOp) Descriptor() protoreflect.EnumDescriptor { - return file_mlops_scheduler_scheduler_proto_enumTypes[4].Descriptor() + return file_mlops_scheduler_scheduler_proto_enumTypes[5].Descriptor() } func (PipelineOutput_JoinOp) Type() protoreflect.EnumType { - return &file_mlops_scheduler_scheduler_proto_enumTypes[4] + return &file_mlops_scheduler_scheduler_proto_enumTypes[5] } func (x PipelineOutput_JoinOp) Number() protoreflect.EnumNumber { @@ -321,7 +354,7 @@ func (x PipelineOutput_JoinOp) Number() protoreflect.EnumNumber { // Deprecated: Use PipelineOutput_JoinOp.Descriptor instead. func (PipelineOutput_JoinOp) EnumDescriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{41, 0} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{42, 0} } type PipelineVersionState_PipelineStatus int32 @@ -372,11 +405,11 @@ func (x PipelineVersionState_PipelineStatus) String() string { } func (PipelineVersionState_PipelineStatus) Descriptor() protoreflect.EnumDescriptor { - return file_mlops_scheduler_scheduler_proto_enumTypes[5].Descriptor() + return file_mlops_scheduler_scheduler_proto_enumTypes[6].Descriptor() } func (PipelineVersionState_PipelineStatus) Type() protoreflect.EnumType { - return &file_mlops_scheduler_scheduler_proto_enumTypes[5] + return &file_mlops_scheduler_scheduler_proto_enumTypes[6] } func (x PipelineVersionState_PipelineStatus) Number() protoreflect.EnumNumber { @@ -385,7 +418,7 @@ func (x PipelineVersionState_PipelineStatus) Number() protoreflect.EnumNumber { // Deprecated: Use PipelineVersionState_PipelineStatus.Descriptor instead. func (PipelineVersionState_PipelineStatus) EnumDescriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{49, 0} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{50, 0} } type LoadModelRequest struct { @@ -2699,6 +2732,7 @@ type Pipeline struct { Steps []*PipelineStep `protobuf:"bytes,4,rep,name=steps,proto3" json:"steps,omitempty"` Output *PipelineOutput `protobuf:"bytes,5,opt,name=output,proto3,oneof" json:"output,omitempty"` KubernetesMeta *KubernetesMeta `protobuf:"bytes,6,opt,name=kubernetesMeta,proto3,oneof" json:"kubernetesMeta,omitempty"` + Input *PipelineInput `protobuf:"bytes,7,opt,name=input,proto3,oneof" json:"input,omitempty"` } func (x *Pipeline) Reset() { @@ -2775,6 +2809,13 @@ func (x *Pipeline) GetKubernetesMeta() *KubernetesMeta { return nil } +func (x *Pipeline) GetInput() *PipelineInput { + if x != nil { + return x.Input + } + return nil +} + type PipelineStep struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2933,6 +2974,93 @@ func (x *Batch) GetWindowMs() uint32 { return 0 } +type PipelineInput struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExternalInputs []string `protobuf:"bytes,1,rep,name=externalInputs,proto3" json:"externalInputs,omitempty"` + ExternalTriggers []string `protobuf:"bytes,2,rep,name=externalTriggers,proto3" json:"externalTriggers,omitempty"` + JoinWindowMs *uint32 `protobuf:"varint,3,opt,name=joinWindowMs,proto3,oneof" json:"joinWindowMs,omitempty"` // Join window millisecs for output, default 0 + JoinType PipelineInput_JoinOp `protobuf:"varint,4,opt,name=joinType,proto3,enum=seldon.mlops.scheduler.PipelineInput_JoinOp" json:"joinType,omitempty"` + TriggersJoin PipelineInput_JoinOp `protobuf:"varint,5,opt,name=triggersJoin,proto3,enum=seldon.mlops.scheduler.PipelineInput_JoinOp" json:"triggersJoin,omitempty"` + TensorMap map[string]string `protobuf:"bytes,6,rep,name=tensorMap,proto3" json:"tensorMap,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // optional map of tensor name mappings +} + +func (x *PipelineInput) Reset() { + *x = PipelineInput{} + if protoimpl.UnsafeEnabled { + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PipelineInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PipelineInput) ProtoMessage() {} + +func (x *PipelineInput) ProtoReflect() protoreflect.Message { + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PipelineInput.ProtoReflect.Descriptor instead. +func (*PipelineInput) Descriptor() ([]byte, []int) { + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{41} +} + +func (x *PipelineInput) GetExternalInputs() []string { + if x != nil { + return x.ExternalInputs + } + return nil +} + +func (x *PipelineInput) GetExternalTriggers() []string { + if x != nil { + return x.ExternalTriggers + } + return nil +} + +func (x *PipelineInput) GetJoinWindowMs() uint32 { + if x != nil && x.JoinWindowMs != nil { + return *x.JoinWindowMs + } + return 0 +} + +func (x *PipelineInput) GetJoinType() PipelineInput_JoinOp { + if x != nil { + return x.JoinType + } + return PipelineInput_INNER +} + +func (x *PipelineInput) GetTriggersJoin() PipelineInput_JoinOp { + if x != nil { + return x.TriggersJoin + } + return PipelineInput_INNER +} + +func (x *PipelineInput) GetTensorMap() map[string]string { + if x != nil { + return x.TensorMap + } + return nil +} + type PipelineOutput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2947,7 +3075,7 @@ type PipelineOutput struct { func (x *PipelineOutput) Reset() { *x = PipelineOutput{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[41] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2960,7 +3088,7 @@ func (x *PipelineOutput) String() string { func (*PipelineOutput) ProtoMessage() {} func (x *PipelineOutput) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[41] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2973,7 +3101,7 @@ func (x *PipelineOutput) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineOutput.ProtoReflect.Descriptor instead. func (*PipelineOutput) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{41} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{42} } func (x *PipelineOutput) GetSteps() []string { @@ -3013,7 +3141,7 @@ type LoadPipelineResponse struct { func (x *LoadPipelineResponse) Reset() { *x = LoadPipelineResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[42] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3026,7 +3154,7 @@ func (x *LoadPipelineResponse) String() string { func (*LoadPipelineResponse) ProtoMessage() {} func (x *LoadPipelineResponse) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[42] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3039,7 +3167,7 @@ func (x *LoadPipelineResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LoadPipelineResponse.ProtoReflect.Descriptor instead. func (*LoadPipelineResponse) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{42} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{43} } type UnloadPipelineRequest struct { @@ -3053,7 +3181,7 @@ type UnloadPipelineRequest struct { func (x *UnloadPipelineRequest) Reset() { *x = UnloadPipelineRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[43] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3066,7 +3194,7 @@ func (x *UnloadPipelineRequest) String() string { func (*UnloadPipelineRequest) ProtoMessage() {} func (x *UnloadPipelineRequest) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[43] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3079,7 +3207,7 @@ func (x *UnloadPipelineRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UnloadPipelineRequest.ProtoReflect.Descriptor instead. func (*UnloadPipelineRequest) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{43} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{44} } func (x *UnloadPipelineRequest) GetName() string { @@ -3098,7 +3226,7 @@ type UnloadPipelineResponse struct { func (x *UnloadPipelineResponse) Reset() { *x = UnloadPipelineResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[44] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3111,7 +3239,7 @@ func (x *UnloadPipelineResponse) String() string { func (*UnloadPipelineResponse) ProtoMessage() {} func (x *UnloadPipelineResponse) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[44] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3124,7 +3252,7 @@ func (x *UnloadPipelineResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UnloadPipelineResponse.ProtoReflect.Descriptor instead. func (*UnloadPipelineResponse) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{44} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{45} } type PipelineStatusRequest struct { @@ -3140,7 +3268,7 @@ type PipelineStatusRequest struct { func (x *PipelineStatusRequest) Reset() { *x = PipelineStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[45] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3153,7 +3281,7 @@ func (x *PipelineStatusRequest) String() string { func (*PipelineStatusRequest) ProtoMessage() {} func (x *PipelineStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[45] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3166,7 +3294,7 @@ func (x *PipelineStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineStatusRequest.ProtoReflect.Descriptor instead. func (*PipelineStatusRequest) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{45} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{46} } func (x *PipelineStatusRequest) GetSubscriberName() string { @@ -3201,7 +3329,7 @@ type PipelineSubscriptionRequest struct { func (x *PipelineSubscriptionRequest) Reset() { *x = PipelineSubscriptionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[46] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3214,7 +3342,7 @@ func (x *PipelineSubscriptionRequest) String() string { func (*PipelineSubscriptionRequest) ProtoMessage() {} func (x *PipelineSubscriptionRequest) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[46] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3227,7 +3355,7 @@ func (x *PipelineSubscriptionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineSubscriptionRequest.ProtoReflect.Descriptor instead. func (*PipelineSubscriptionRequest) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{46} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{47} } func (x *PipelineSubscriptionRequest) GetSubscriberName() string { @@ -3249,7 +3377,7 @@ type PipelineStatusResponse struct { func (x *PipelineStatusResponse) Reset() { *x = PipelineStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[47] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3262,7 +3390,7 @@ func (x *PipelineStatusResponse) String() string { func (*PipelineStatusResponse) ProtoMessage() {} func (x *PipelineStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[47] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3275,7 +3403,7 @@ func (x *PipelineStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineStatusResponse.ProtoReflect.Descriptor instead. func (*PipelineStatusResponse) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{47} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{48} } func (x *PipelineStatusResponse) GetPipelineName() string { @@ -3304,7 +3432,7 @@ type PipelineWithState struct { func (x *PipelineWithState) Reset() { *x = PipelineWithState{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[48] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3317,7 +3445,7 @@ func (x *PipelineWithState) String() string { func (*PipelineWithState) ProtoMessage() {} func (x *PipelineWithState) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[48] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3330,7 +3458,7 @@ func (x *PipelineWithState) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineWithState.ProtoReflect.Descriptor instead. func (*PipelineWithState) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{48} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{49} } func (x *PipelineWithState) GetPipeline() *Pipeline { @@ -3362,7 +3490,7 @@ type PipelineVersionState struct { func (x *PipelineVersionState) Reset() { *x = PipelineVersionState{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[49] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3375,7 +3503,7 @@ func (x *PipelineVersionState) String() string { func (*PipelineVersionState) ProtoMessage() {} func (x *PipelineVersionState) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[49] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3388,7 +3516,7 @@ func (x *PipelineVersionState) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineVersionState.ProtoReflect.Descriptor instead. func (*PipelineVersionState) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{49} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{50} } func (x *PipelineVersionState) GetPipelineVersion() uint32 { @@ -3437,7 +3565,7 @@ type SchedulerStatusRequest struct { func (x *SchedulerStatusRequest) Reset() { *x = SchedulerStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[50] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3450,7 +3578,7 @@ func (x *SchedulerStatusRequest) String() string { func (*SchedulerStatusRequest) ProtoMessage() {} func (x *SchedulerStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[50] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3463,7 +3591,7 @@ func (x *SchedulerStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SchedulerStatusRequest.ProtoReflect.Descriptor instead. func (*SchedulerStatusRequest) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{50} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{51} } func (x *SchedulerStatusRequest) GetSubscriberName() string { @@ -3484,7 +3612,7 @@ type SchedulerStatusResponse struct { func (x *SchedulerStatusResponse) Reset() { *x = SchedulerStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[51] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3497,7 +3625,7 @@ func (x *SchedulerStatusResponse) String() string { func (*SchedulerStatusResponse) ProtoMessage() {} func (x *SchedulerStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_mlops_scheduler_scheduler_proto_msgTypes[51] + mi := &file_mlops_scheduler_scheduler_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3510,7 +3638,7 @@ func (x *SchedulerStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SchedulerStatusResponse.ProtoReflect.Descriptor instead. func (*SchedulerStatusResponse) Descriptor() ([]byte, []int) { - return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{51} + return file_mlops_scheduler_scheduler_proto_rawDescGZIP(), []int{52} } func (x *SchedulerStatusResponse) GetApplicationVersion() string { @@ -3927,7 +4055,7 @@ var file_mlops_scheduler_scheduler_proto_rawDesc = []byte{ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, - 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xbe, 0x02, 0x0a, 0x08, 0x50, 0x69, + 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8a, 0x03, 0x0a, 0x08, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, @@ -3945,271 +4073,307 @@ var file_mlops_scheduler_scheduler_proto_rawDesc = []byte{ 0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, - 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6b, 0x75, 0x62, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x22, 0x9d, 0x04, 0x0a, 0x0c, 0x50, - 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, - 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, - 0x12, 0x51, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, - 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, - 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, - 0x4d, 0x61, 0x70, 0x12, 0x4b, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, - 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, - 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, - 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x0c, - 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, - 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, - 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, - 0x0c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x33, 0x0a, - 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, - 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, - 0x63, 0x68, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x27, 0x0a, 0x06, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, - 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, - 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, - 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x57, 0x0a, 0x05, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x48, 0x00, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, - 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, - 0x52, 0x08, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, - 0x05, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x4d, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0x22, 0x0a, 0x0c, - 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, - 0x12, 0x4b, 0x0a, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, + 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x05, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x65, + 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x70, + 0x75, 0x74, 0x48, 0x02, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, + 0x0a, 0x07, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6b, 0x75, + 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x08, 0x0a, 0x06, + 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x9d, 0x04, 0x0a, 0x0c, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x4d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x6a, 0x6f, 0x69, + 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, 0x09, + 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x12, + 0x4b, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, - 0x4f, 0x70, 0x52, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x53, 0x0a, - 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x35, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, + 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, + 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x0c, 0x74, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x33, 0x0a, 0x05, 0x62, 0x61, 0x74, + 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, + 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x3c, + 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x06, + 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x10, + 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, + 0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x57, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x08, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, + 0xf4, 0x03, 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x70, 0x75, + 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x70, + 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x65, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x6a, + 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x48, + 0x0a, 0x08, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, - 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, - 0x61, 0x70, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x27, 0x0a, 0x06, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, - 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, - 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x22, 0x16, 0x0a, 0x14, 0x4c, 0x6f, 0x61, - 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x2b, 0x0a, 0x15, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x18, - 0x0a, 0x16, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x15, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x45, - 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, - 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x16, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, - 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x95, 0x01, 0x0a, 0x11, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, - 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, - 0x42, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, + 0x6e, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x08, + 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x22, 0xe4, 0x03, 0x0a, 0x14, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, - 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x0c, 0x74, 0x72, + 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x52, 0x0a, 0x09, 0x74, 0x65, + 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, + 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x1a, 0x3c, + 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x06, + 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x10, + 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, + 0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x65, + 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, + 0x22, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x4d, 0x73, 0x12, 0x4b, 0x0a, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f, 0x69, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, - 0x73, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x13, 0x6c, 0x61, - 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x52, 0x65, - 0x61, 0x64, 0x79, 0x22, 0xc4, 0x01, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, - 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, - 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, - 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x10, 0x03, 0x12, 0x12, - 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6e, 0x67, - 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x10, 0x07, 0x22, 0x40, 0x0a, 0x16, 0x53, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x49, 0x0a, 0x17, - 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x27, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x44, 0x45, 0x4c, - 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, - 0x32, 0xd9, 0x0e, 0x0a, 0x09, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x12, 0x6b, - 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x2b, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x4a, + 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f, 0x69, 0x6e, + 0x12, 0x53, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, + 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x73, + 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, + 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, + 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x06, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, + 0x05, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, + 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x22, 0x16, 0x0a, 0x14, + 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x0a, 0x15, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x18, 0x0a, 0x16, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x15, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x45, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x16, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x64, + 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x95, + 0x01, 0x0a, 0x11, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, + 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x12, 0x42, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xe4, 0x03, 0x0a, 0x14, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x28, 0x0a, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x73, 0x65, 0x6c, 0x64, + 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x52, 0x65, + 0x61, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x22, 0xc4, 0x01, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x11, + 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x10, + 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6e, 0x67, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x10, 0x07, 0x22, 0x40, 0x0a, + 0x16, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, + 0x49, 0x0a, 0x17, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x27, 0x0a, 0x0c, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, + 0x44, 0x45, 0x4c, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, + 0x45, 0x10, 0x01, 0x32, 0xd9, 0x0e, 0x0a, 0x09, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x12, 0x6b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, - 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, + 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, + 0x0a, 0x09, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x28, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x09, 0x4c, - 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x28, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, - 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, - 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, - 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x68, 0x0a, 0x0b, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x2a, - 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, - 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x65, 0x6c, - 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x0c, 0x4c, 0x6f, 0x61, - 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, + 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, + 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x68, 0x0a, 0x0b, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x12, 0x2a, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x0c, + 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2b, 0x2e, 0x73, + 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, - 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, - 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x0e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, - 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, - 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x0f, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78, 0x70, 0x65, 0x72, - 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x73, - 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78, 0x70, 0x65, 0x72, - 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x71, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, - 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x45, - 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x0e, 0x55, 0x6e, 0x6c, + 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2d, 0x2e, 0x73, 0x65, + 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x0f, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78, + 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, + 0x22, 0x00, 0x12, 0x71, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, + 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, + 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, + 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, + 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, + 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x30, 0x01, 0x12, 0x6a, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x2a, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, + 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, + 0x12, 0x73, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, + 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x79, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, + 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, + 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x73, 0x65, 0x6c, + 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, + 0x12, 0x74, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, + 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, + 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7c, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, - 0x01, 0x12, 0x6a, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x2a, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, + 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x30, 0x01, 0x12, 0x79, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x73, 0x0a, - 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, - 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x30, 0x01, 0x12, 0x79, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, + 0x88, 0x01, 0x0a, 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x45, 0x78, 0x70, + 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x2e, + 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, + 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, + 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x82, 0x01, 0x0a, 0x17, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, - 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, - 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x74, 0x0a, - 0x0f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x7c, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x2e, 0x73, - 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, - 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, - 0x01, 0x12, 0x79, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4d, 0x6f, - 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x2e, 0x73, 0x65, 0x6c, 0x64, - 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x65, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x88, 0x01, 0x0a, - 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, - 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x2e, 0x73, 0x65, 0x6c, - 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x30, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, - 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, - 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x82, 0x01, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, - 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, - 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x3c, 0x5a, 0x3a, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, - 0x6e, 0x69, 0x6f, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, - 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6c, 0x6f, 0x70, 0x73, - 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, + 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, + 0x6c, 0x64, 0x6f, 0x6e, 0x69, 0x6f, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6c, + 0x6f, 0x70, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4224,157 +4388,164 @@ func file_mlops_scheduler_scheduler_proto_rawDescGZIP() []byte { return file_mlops_scheduler_scheduler_proto_rawDescData } -var file_mlops_scheduler_scheduler_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_mlops_scheduler_scheduler_proto_msgTypes = make([]protoimpl.MessageInfo, 55) +var file_mlops_scheduler_scheduler_proto_enumTypes = make([]protoimpl.EnumInfo, 7) +var file_mlops_scheduler_scheduler_proto_msgTypes = make([]protoimpl.MessageInfo, 57) var file_mlops_scheduler_scheduler_proto_goTypes = []interface{}{ (ResourceType)(0), // 0: seldon.mlops.scheduler.ResourceType (ModelStatus_ModelState)(0), // 1: seldon.mlops.scheduler.ModelStatus.ModelState (ModelReplicaStatus_ModelReplicaState)(0), // 2: seldon.mlops.scheduler.ModelReplicaStatus.ModelReplicaState (PipelineStep_JoinOp)(0), // 3: seldon.mlops.scheduler.PipelineStep.JoinOp - (PipelineOutput_JoinOp)(0), // 4: seldon.mlops.scheduler.PipelineOutput.JoinOp - (PipelineVersionState_PipelineStatus)(0), // 5: seldon.mlops.scheduler.PipelineVersionState.PipelineStatus - (*LoadModelRequest)(nil), // 6: seldon.mlops.scheduler.LoadModelRequest - (*Model)(nil), // 7: seldon.mlops.scheduler.Model - (*MetaData)(nil), // 8: seldon.mlops.scheduler.MetaData - (*DeploymentSpec)(nil), // 9: seldon.mlops.scheduler.DeploymentSpec - (*ModelSpec)(nil), // 10: seldon.mlops.scheduler.ModelSpec - (*ParameterSpec)(nil), // 11: seldon.mlops.scheduler.ParameterSpec - (*ExplainerSpec)(nil), // 12: seldon.mlops.scheduler.ExplainerSpec - (*KubernetesMeta)(nil), // 13: seldon.mlops.scheduler.KubernetesMeta - (*StreamSpec)(nil), // 14: seldon.mlops.scheduler.StreamSpec - (*StorageConfig)(nil), // 15: seldon.mlops.scheduler.StorageConfig - (*LoadModelResponse)(nil), // 16: seldon.mlops.scheduler.LoadModelResponse - (*ModelReference)(nil), // 17: seldon.mlops.scheduler.ModelReference - (*UnloadModelRequest)(nil), // 18: seldon.mlops.scheduler.UnloadModelRequest - (*UnloadModelResponse)(nil), // 19: seldon.mlops.scheduler.UnloadModelResponse - (*ModelStatusResponse)(nil), // 20: seldon.mlops.scheduler.ModelStatusResponse - (*ModelVersionStatus)(nil), // 21: seldon.mlops.scheduler.ModelVersionStatus - (*ModelStatus)(nil), // 22: seldon.mlops.scheduler.ModelStatus - (*ModelReplicaStatus)(nil), // 23: seldon.mlops.scheduler.ModelReplicaStatus - (*ServerStatusRequest)(nil), // 24: seldon.mlops.scheduler.ServerStatusRequest - (*ServerStatusResponse)(nil), // 25: seldon.mlops.scheduler.ServerStatusResponse - (*ServerReplicaResources)(nil), // 26: seldon.mlops.scheduler.ServerReplicaResources - (*ModelSubscriptionRequest)(nil), // 27: seldon.mlops.scheduler.ModelSubscriptionRequest - (*ModelStatusRequest)(nil), // 28: seldon.mlops.scheduler.ModelStatusRequest - (*ServerNotifyRequest)(nil), // 29: seldon.mlops.scheduler.ServerNotifyRequest - (*ServerNotifyResponse)(nil), // 30: seldon.mlops.scheduler.ServerNotifyResponse - (*ServerSubscriptionRequest)(nil), // 31: seldon.mlops.scheduler.ServerSubscriptionRequest - (*StartExperimentRequest)(nil), // 32: seldon.mlops.scheduler.StartExperimentRequest - (*Experiment)(nil), // 33: seldon.mlops.scheduler.Experiment - (*ExperimentConfig)(nil), // 34: seldon.mlops.scheduler.ExperimentConfig - (*ExperimentCandidate)(nil), // 35: seldon.mlops.scheduler.ExperimentCandidate - (*ExperimentMirror)(nil), // 36: seldon.mlops.scheduler.ExperimentMirror - (*StartExperimentResponse)(nil), // 37: seldon.mlops.scheduler.StartExperimentResponse - (*StopExperimentRequest)(nil), // 38: seldon.mlops.scheduler.StopExperimentRequest - (*StopExperimentResponse)(nil), // 39: seldon.mlops.scheduler.StopExperimentResponse - (*ExperimentSubscriptionRequest)(nil), // 40: seldon.mlops.scheduler.ExperimentSubscriptionRequest - (*ExperimentStatusResponse)(nil), // 41: seldon.mlops.scheduler.ExperimentStatusResponse - (*LoadPipelineRequest)(nil), // 42: seldon.mlops.scheduler.LoadPipelineRequest - (*ExperimentStatusRequest)(nil), // 43: seldon.mlops.scheduler.ExperimentStatusRequest - (*Pipeline)(nil), // 44: seldon.mlops.scheduler.Pipeline - (*PipelineStep)(nil), // 45: seldon.mlops.scheduler.PipelineStep - (*Batch)(nil), // 46: seldon.mlops.scheduler.Batch - (*PipelineOutput)(nil), // 47: seldon.mlops.scheduler.PipelineOutput - (*LoadPipelineResponse)(nil), // 48: seldon.mlops.scheduler.LoadPipelineResponse - (*UnloadPipelineRequest)(nil), // 49: seldon.mlops.scheduler.UnloadPipelineRequest - (*UnloadPipelineResponse)(nil), // 50: seldon.mlops.scheduler.UnloadPipelineResponse - (*PipelineStatusRequest)(nil), // 51: seldon.mlops.scheduler.PipelineStatusRequest - (*PipelineSubscriptionRequest)(nil), // 52: seldon.mlops.scheduler.PipelineSubscriptionRequest - (*PipelineStatusResponse)(nil), // 53: seldon.mlops.scheduler.PipelineStatusResponse - (*PipelineWithState)(nil), // 54: seldon.mlops.scheduler.PipelineWithState - (*PipelineVersionState)(nil), // 55: seldon.mlops.scheduler.PipelineVersionState - (*SchedulerStatusRequest)(nil), // 56: seldon.mlops.scheduler.SchedulerStatusRequest - (*SchedulerStatusResponse)(nil), // 57: seldon.mlops.scheduler.SchedulerStatusResponse - nil, // 58: seldon.mlops.scheduler.ModelVersionStatus.ModelReplicaStateEntry - nil, // 59: seldon.mlops.scheduler.PipelineStep.TensorMapEntry - nil, // 60: seldon.mlops.scheduler.PipelineOutput.TensorMapEntry - (*timestamppb.Timestamp)(nil), // 61: google.protobuf.Timestamp + (PipelineInput_JoinOp)(0), // 4: seldon.mlops.scheduler.PipelineInput.JoinOp + (PipelineOutput_JoinOp)(0), // 5: seldon.mlops.scheduler.PipelineOutput.JoinOp + (PipelineVersionState_PipelineStatus)(0), // 6: seldon.mlops.scheduler.PipelineVersionState.PipelineStatus + (*LoadModelRequest)(nil), // 7: seldon.mlops.scheduler.LoadModelRequest + (*Model)(nil), // 8: seldon.mlops.scheduler.Model + (*MetaData)(nil), // 9: seldon.mlops.scheduler.MetaData + (*DeploymentSpec)(nil), // 10: seldon.mlops.scheduler.DeploymentSpec + (*ModelSpec)(nil), // 11: seldon.mlops.scheduler.ModelSpec + (*ParameterSpec)(nil), // 12: seldon.mlops.scheduler.ParameterSpec + (*ExplainerSpec)(nil), // 13: seldon.mlops.scheduler.ExplainerSpec + (*KubernetesMeta)(nil), // 14: seldon.mlops.scheduler.KubernetesMeta + (*StreamSpec)(nil), // 15: seldon.mlops.scheduler.StreamSpec + (*StorageConfig)(nil), // 16: seldon.mlops.scheduler.StorageConfig + (*LoadModelResponse)(nil), // 17: seldon.mlops.scheduler.LoadModelResponse + (*ModelReference)(nil), // 18: seldon.mlops.scheduler.ModelReference + (*UnloadModelRequest)(nil), // 19: seldon.mlops.scheduler.UnloadModelRequest + (*UnloadModelResponse)(nil), // 20: seldon.mlops.scheduler.UnloadModelResponse + (*ModelStatusResponse)(nil), // 21: seldon.mlops.scheduler.ModelStatusResponse + (*ModelVersionStatus)(nil), // 22: seldon.mlops.scheduler.ModelVersionStatus + (*ModelStatus)(nil), // 23: seldon.mlops.scheduler.ModelStatus + (*ModelReplicaStatus)(nil), // 24: seldon.mlops.scheduler.ModelReplicaStatus + (*ServerStatusRequest)(nil), // 25: seldon.mlops.scheduler.ServerStatusRequest + (*ServerStatusResponse)(nil), // 26: seldon.mlops.scheduler.ServerStatusResponse + (*ServerReplicaResources)(nil), // 27: seldon.mlops.scheduler.ServerReplicaResources + (*ModelSubscriptionRequest)(nil), // 28: seldon.mlops.scheduler.ModelSubscriptionRequest + (*ModelStatusRequest)(nil), // 29: seldon.mlops.scheduler.ModelStatusRequest + (*ServerNotifyRequest)(nil), // 30: seldon.mlops.scheduler.ServerNotifyRequest + (*ServerNotifyResponse)(nil), // 31: seldon.mlops.scheduler.ServerNotifyResponse + (*ServerSubscriptionRequest)(nil), // 32: seldon.mlops.scheduler.ServerSubscriptionRequest + (*StartExperimentRequest)(nil), // 33: seldon.mlops.scheduler.StartExperimentRequest + (*Experiment)(nil), // 34: seldon.mlops.scheduler.Experiment + (*ExperimentConfig)(nil), // 35: seldon.mlops.scheduler.ExperimentConfig + (*ExperimentCandidate)(nil), // 36: seldon.mlops.scheduler.ExperimentCandidate + (*ExperimentMirror)(nil), // 37: seldon.mlops.scheduler.ExperimentMirror + (*StartExperimentResponse)(nil), // 38: seldon.mlops.scheduler.StartExperimentResponse + (*StopExperimentRequest)(nil), // 39: seldon.mlops.scheduler.StopExperimentRequest + (*StopExperimentResponse)(nil), // 40: seldon.mlops.scheduler.StopExperimentResponse + (*ExperimentSubscriptionRequest)(nil), // 41: seldon.mlops.scheduler.ExperimentSubscriptionRequest + (*ExperimentStatusResponse)(nil), // 42: seldon.mlops.scheduler.ExperimentStatusResponse + (*LoadPipelineRequest)(nil), // 43: seldon.mlops.scheduler.LoadPipelineRequest + (*ExperimentStatusRequest)(nil), // 44: seldon.mlops.scheduler.ExperimentStatusRequest + (*Pipeline)(nil), // 45: seldon.mlops.scheduler.Pipeline + (*PipelineStep)(nil), // 46: seldon.mlops.scheduler.PipelineStep + (*Batch)(nil), // 47: seldon.mlops.scheduler.Batch + (*PipelineInput)(nil), // 48: seldon.mlops.scheduler.PipelineInput + (*PipelineOutput)(nil), // 49: seldon.mlops.scheduler.PipelineOutput + (*LoadPipelineResponse)(nil), // 50: seldon.mlops.scheduler.LoadPipelineResponse + (*UnloadPipelineRequest)(nil), // 51: seldon.mlops.scheduler.UnloadPipelineRequest + (*UnloadPipelineResponse)(nil), // 52: seldon.mlops.scheduler.UnloadPipelineResponse + (*PipelineStatusRequest)(nil), // 53: seldon.mlops.scheduler.PipelineStatusRequest + (*PipelineSubscriptionRequest)(nil), // 54: seldon.mlops.scheduler.PipelineSubscriptionRequest + (*PipelineStatusResponse)(nil), // 55: seldon.mlops.scheduler.PipelineStatusResponse + (*PipelineWithState)(nil), // 56: seldon.mlops.scheduler.PipelineWithState + (*PipelineVersionState)(nil), // 57: seldon.mlops.scheduler.PipelineVersionState + (*SchedulerStatusRequest)(nil), // 58: seldon.mlops.scheduler.SchedulerStatusRequest + (*SchedulerStatusResponse)(nil), // 59: seldon.mlops.scheduler.SchedulerStatusResponse + nil, // 60: seldon.mlops.scheduler.ModelVersionStatus.ModelReplicaStateEntry + nil, // 61: seldon.mlops.scheduler.PipelineStep.TensorMapEntry + nil, // 62: seldon.mlops.scheduler.PipelineInput.TensorMapEntry + nil, // 63: seldon.mlops.scheduler.PipelineOutput.TensorMapEntry + (*timestamppb.Timestamp)(nil), // 64: google.protobuf.Timestamp } var file_mlops_scheduler_scheduler_proto_depIdxs = []int32{ - 7, // 0: seldon.mlops.scheduler.LoadModelRequest.model:type_name -> seldon.mlops.scheduler.Model - 8, // 1: seldon.mlops.scheduler.Model.meta:type_name -> seldon.mlops.scheduler.MetaData - 10, // 2: seldon.mlops.scheduler.Model.modelSpec:type_name -> seldon.mlops.scheduler.ModelSpec - 9, // 3: seldon.mlops.scheduler.Model.deploymentSpec:type_name -> seldon.mlops.scheduler.DeploymentSpec - 14, // 4: seldon.mlops.scheduler.Model.streamSpec:type_name -> seldon.mlops.scheduler.StreamSpec - 13, // 5: seldon.mlops.scheduler.MetaData.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta - 15, // 6: seldon.mlops.scheduler.ModelSpec.storageConfig:type_name -> seldon.mlops.scheduler.StorageConfig - 12, // 7: seldon.mlops.scheduler.ModelSpec.explainer:type_name -> seldon.mlops.scheduler.ExplainerSpec - 11, // 8: seldon.mlops.scheduler.ModelSpec.parameters:type_name -> seldon.mlops.scheduler.ParameterSpec - 17, // 9: seldon.mlops.scheduler.UnloadModelRequest.model:type_name -> seldon.mlops.scheduler.ModelReference - 13, // 10: seldon.mlops.scheduler.UnloadModelRequest.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta - 21, // 11: seldon.mlops.scheduler.ModelStatusResponse.versions:type_name -> seldon.mlops.scheduler.ModelVersionStatus - 13, // 12: seldon.mlops.scheduler.ModelVersionStatus.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta - 58, // 13: seldon.mlops.scheduler.ModelVersionStatus.modelReplicaState:type_name -> seldon.mlops.scheduler.ModelVersionStatus.ModelReplicaStateEntry - 22, // 14: seldon.mlops.scheduler.ModelVersionStatus.state:type_name -> seldon.mlops.scheduler.ModelStatus - 7, // 15: seldon.mlops.scheduler.ModelVersionStatus.modelDefn:type_name -> seldon.mlops.scheduler.Model + 8, // 0: seldon.mlops.scheduler.LoadModelRequest.model:type_name -> seldon.mlops.scheduler.Model + 9, // 1: seldon.mlops.scheduler.Model.meta:type_name -> seldon.mlops.scheduler.MetaData + 11, // 2: seldon.mlops.scheduler.Model.modelSpec:type_name -> seldon.mlops.scheduler.ModelSpec + 10, // 3: seldon.mlops.scheduler.Model.deploymentSpec:type_name -> seldon.mlops.scheduler.DeploymentSpec + 15, // 4: seldon.mlops.scheduler.Model.streamSpec:type_name -> seldon.mlops.scheduler.StreamSpec + 14, // 5: seldon.mlops.scheduler.MetaData.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 16, // 6: seldon.mlops.scheduler.ModelSpec.storageConfig:type_name -> seldon.mlops.scheduler.StorageConfig + 13, // 7: seldon.mlops.scheduler.ModelSpec.explainer:type_name -> seldon.mlops.scheduler.ExplainerSpec + 12, // 8: seldon.mlops.scheduler.ModelSpec.parameters:type_name -> seldon.mlops.scheduler.ParameterSpec + 18, // 9: seldon.mlops.scheduler.UnloadModelRequest.model:type_name -> seldon.mlops.scheduler.ModelReference + 14, // 10: seldon.mlops.scheduler.UnloadModelRequest.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 22, // 11: seldon.mlops.scheduler.ModelStatusResponse.versions:type_name -> seldon.mlops.scheduler.ModelVersionStatus + 14, // 12: seldon.mlops.scheduler.ModelVersionStatus.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 60, // 13: seldon.mlops.scheduler.ModelVersionStatus.modelReplicaState:type_name -> seldon.mlops.scheduler.ModelVersionStatus.ModelReplicaStateEntry + 23, // 14: seldon.mlops.scheduler.ModelVersionStatus.state:type_name -> seldon.mlops.scheduler.ModelStatus + 8, // 15: seldon.mlops.scheduler.ModelVersionStatus.modelDefn:type_name -> seldon.mlops.scheduler.Model 1, // 16: seldon.mlops.scheduler.ModelStatus.state:type_name -> seldon.mlops.scheduler.ModelStatus.ModelState - 61, // 17: seldon.mlops.scheduler.ModelStatus.lastChangeTimestamp:type_name -> google.protobuf.Timestamp + 64, // 17: seldon.mlops.scheduler.ModelStatus.lastChangeTimestamp:type_name -> google.protobuf.Timestamp 2, // 18: seldon.mlops.scheduler.ModelReplicaStatus.state:type_name -> seldon.mlops.scheduler.ModelReplicaStatus.ModelReplicaState - 61, // 19: seldon.mlops.scheduler.ModelReplicaStatus.lastChangeTimestamp:type_name -> google.protobuf.Timestamp - 26, // 20: seldon.mlops.scheduler.ServerStatusResponse.resources:type_name -> seldon.mlops.scheduler.ServerReplicaResources - 13, // 21: seldon.mlops.scheduler.ServerStatusResponse.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta - 17, // 22: seldon.mlops.scheduler.ModelStatusRequest.model:type_name -> seldon.mlops.scheduler.ModelReference - 13, // 23: seldon.mlops.scheduler.ServerNotifyRequest.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta - 33, // 24: seldon.mlops.scheduler.StartExperimentRequest.experiment:type_name -> seldon.mlops.scheduler.Experiment - 35, // 25: seldon.mlops.scheduler.Experiment.candidates:type_name -> seldon.mlops.scheduler.ExperimentCandidate - 36, // 26: seldon.mlops.scheduler.Experiment.mirror:type_name -> seldon.mlops.scheduler.ExperimentMirror - 34, // 27: seldon.mlops.scheduler.Experiment.config:type_name -> seldon.mlops.scheduler.ExperimentConfig - 13, // 28: seldon.mlops.scheduler.Experiment.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 64, // 19: seldon.mlops.scheduler.ModelReplicaStatus.lastChangeTimestamp:type_name -> google.protobuf.Timestamp + 27, // 20: seldon.mlops.scheduler.ServerStatusResponse.resources:type_name -> seldon.mlops.scheduler.ServerReplicaResources + 14, // 21: seldon.mlops.scheduler.ServerStatusResponse.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 18, // 22: seldon.mlops.scheduler.ModelStatusRequest.model:type_name -> seldon.mlops.scheduler.ModelReference + 14, // 23: seldon.mlops.scheduler.ServerNotifyRequest.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 34, // 24: seldon.mlops.scheduler.StartExperimentRequest.experiment:type_name -> seldon.mlops.scheduler.Experiment + 36, // 25: seldon.mlops.scheduler.Experiment.candidates:type_name -> seldon.mlops.scheduler.ExperimentCandidate + 37, // 26: seldon.mlops.scheduler.Experiment.mirror:type_name -> seldon.mlops.scheduler.ExperimentMirror + 35, // 27: seldon.mlops.scheduler.Experiment.config:type_name -> seldon.mlops.scheduler.ExperimentConfig + 14, // 28: seldon.mlops.scheduler.Experiment.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta 0, // 29: seldon.mlops.scheduler.Experiment.resourceType:type_name -> seldon.mlops.scheduler.ResourceType - 13, // 30: seldon.mlops.scheduler.ExperimentStatusResponse.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta - 44, // 31: seldon.mlops.scheduler.LoadPipelineRequest.pipeline:type_name -> seldon.mlops.scheduler.Pipeline - 45, // 32: seldon.mlops.scheduler.Pipeline.steps:type_name -> seldon.mlops.scheduler.PipelineStep - 47, // 33: seldon.mlops.scheduler.Pipeline.output:type_name -> seldon.mlops.scheduler.PipelineOutput - 13, // 34: seldon.mlops.scheduler.Pipeline.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta - 59, // 35: seldon.mlops.scheduler.PipelineStep.tensorMap:type_name -> seldon.mlops.scheduler.PipelineStep.TensorMapEntry - 3, // 36: seldon.mlops.scheduler.PipelineStep.inputsJoin:type_name -> seldon.mlops.scheduler.PipelineStep.JoinOp - 3, // 37: seldon.mlops.scheduler.PipelineStep.triggersJoin:type_name -> seldon.mlops.scheduler.PipelineStep.JoinOp - 46, // 38: seldon.mlops.scheduler.PipelineStep.batch:type_name -> seldon.mlops.scheduler.Batch - 4, // 39: seldon.mlops.scheduler.PipelineOutput.stepsJoin:type_name -> seldon.mlops.scheduler.PipelineOutput.JoinOp - 60, // 40: seldon.mlops.scheduler.PipelineOutput.tensorMap:type_name -> seldon.mlops.scheduler.PipelineOutput.TensorMapEntry - 54, // 41: seldon.mlops.scheduler.PipelineStatusResponse.versions:type_name -> seldon.mlops.scheduler.PipelineWithState - 44, // 42: seldon.mlops.scheduler.PipelineWithState.pipeline:type_name -> seldon.mlops.scheduler.Pipeline - 55, // 43: seldon.mlops.scheduler.PipelineWithState.state:type_name -> seldon.mlops.scheduler.PipelineVersionState - 5, // 44: seldon.mlops.scheduler.PipelineVersionState.status:type_name -> seldon.mlops.scheduler.PipelineVersionState.PipelineStatus - 61, // 45: seldon.mlops.scheduler.PipelineVersionState.lastChangeTimestamp:type_name -> google.protobuf.Timestamp - 23, // 46: seldon.mlops.scheduler.ModelVersionStatus.ModelReplicaStateEntry.value:type_name -> seldon.mlops.scheduler.ModelReplicaStatus - 29, // 47: seldon.mlops.scheduler.Scheduler.ServerNotify:input_type -> seldon.mlops.scheduler.ServerNotifyRequest - 6, // 48: seldon.mlops.scheduler.Scheduler.LoadModel:input_type -> seldon.mlops.scheduler.LoadModelRequest - 18, // 49: seldon.mlops.scheduler.Scheduler.UnloadModel:input_type -> seldon.mlops.scheduler.UnloadModelRequest - 42, // 50: seldon.mlops.scheduler.Scheduler.LoadPipeline:input_type -> seldon.mlops.scheduler.LoadPipelineRequest - 49, // 51: seldon.mlops.scheduler.Scheduler.UnloadPipeline:input_type -> seldon.mlops.scheduler.UnloadPipelineRequest - 32, // 52: seldon.mlops.scheduler.Scheduler.StartExperiment:input_type -> seldon.mlops.scheduler.StartExperimentRequest - 38, // 53: seldon.mlops.scheduler.Scheduler.StopExperiment:input_type -> seldon.mlops.scheduler.StopExperimentRequest - 24, // 54: seldon.mlops.scheduler.Scheduler.ServerStatus:input_type -> seldon.mlops.scheduler.ServerStatusRequest - 28, // 55: seldon.mlops.scheduler.Scheduler.ModelStatus:input_type -> seldon.mlops.scheduler.ModelStatusRequest - 51, // 56: seldon.mlops.scheduler.Scheduler.PipelineStatus:input_type -> seldon.mlops.scheduler.PipelineStatusRequest - 43, // 57: seldon.mlops.scheduler.Scheduler.ExperimentStatus:input_type -> seldon.mlops.scheduler.ExperimentStatusRequest - 56, // 58: seldon.mlops.scheduler.Scheduler.SchedulerStatus:input_type -> seldon.mlops.scheduler.SchedulerStatusRequest - 31, // 59: seldon.mlops.scheduler.Scheduler.SubscribeServerStatus:input_type -> seldon.mlops.scheduler.ServerSubscriptionRequest - 27, // 60: seldon.mlops.scheduler.Scheduler.SubscribeModelStatus:input_type -> seldon.mlops.scheduler.ModelSubscriptionRequest - 40, // 61: seldon.mlops.scheduler.Scheduler.SubscribeExperimentStatus:input_type -> seldon.mlops.scheduler.ExperimentSubscriptionRequest - 52, // 62: seldon.mlops.scheduler.Scheduler.SubscribePipelineStatus:input_type -> seldon.mlops.scheduler.PipelineSubscriptionRequest - 30, // 63: seldon.mlops.scheduler.Scheduler.ServerNotify:output_type -> seldon.mlops.scheduler.ServerNotifyResponse - 16, // 64: seldon.mlops.scheduler.Scheduler.LoadModel:output_type -> seldon.mlops.scheduler.LoadModelResponse - 19, // 65: seldon.mlops.scheduler.Scheduler.UnloadModel:output_type -> seldon.mlops.scheduler.UnloadModelResponse - 48, // 66: seldon.mlops.scheduler.Scheduler.LoadPipeline:output_type -> seldon.mlops.scheduler.LoadPipelineResponse - 50, // 67: seldon.mlops.scheduler.Scheduler.UnloadPipeline:output_type -> seldon.mlops.scheduler.UnloadPipelineResponse - 37, // 68: seldon.mlops.scheduler.Scheduler.StartExperiment:output_type -> seldon.mlops.scheduler.StartExperimentResponse - 39, // 69: seldon.mlops.scheduler.Scheduler.StopExperiment:output_type -> seldon.mlops.scheduler.StopExperimentResponse - 25, // 70: seldon.mlops.scheduler.Scheduler.ServerStatus:output_type -> seldon.mlops.scheduler.ServerStatusResponse - 20, // 71: seldon.mlops.scheduler.Scheduler.ModelStatus:output_type -> seldon.mlops.scheduler.ModelStatusResponse - 53, // 72: seldon.mlops.scheduler.Scheduler.PipelineStatus:output_type -> seldon.mlops.scheduler.PipelineStatusResponse - 41, // 73: seldon.mlops.scheduler.Scheduler.ExperimentStatus:output_type -> seldon.mlops.scheduler.ExperimentStatusResponse - 57, // 74: seldon.mlops.scheduler.Scheduler.SchedulerStatus:output_type -> seldon.mlops.scheduler.SchedulerStatusResponse - 25, // 75: seldon.mlops.scheduler.Scheduler.SubscribeServerStatus:output_type -> seldon.mlops.scheduler.ServerStatusResponse - 20, // 76: seldon.mlops.scheduler.Scheduler.SubscribeModelStatus:output_type -> seldon.mlops.scheduler.ModelStatusResponse - 41, // 77: seldon.mlops.scheduler.Scheduler.SubscribeExperimentStatus:output_type -> seldon.mlops.scheduler.ExperimentStatusResponse - 53, // 78: seldon.mlops.scheduler.Scheduler.SubscribePipelineStatus:output_type -> seldon.mlops.scheduler.PipelineStatusResponse - 63, // [63:79] is the sub-list for method output_type - 47, // [47:63] is the sub-list for method input_type - 47, // [47:47] is the sub-list for extension type_name - 47, // [47:47] is the sub-list for extension extendee - 0, // [0:47] is the sub-list for field type_name + 14, // 30: seldon.mlops.scheduler.ExperimentStatusResponse.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 45, // 31: seldon.mlops.scheduler.LoadPipelineRequest.pipeline:type_name -> seldon.mlops.scheduler.Pipeline + 46, // 32: seldon.mlops.scheduler.Pipeline.steps:type_name -> seldon.mlops.scheduler.PipelineStep + 49, // 33: seldon.mlops.scheduler.Pipeline.output:type_name -> seldon.mlops.scheduler.PipelineOutput + 14, // 34: seldon.mlops.scheduler.Pipeline.kubernetesMeta:type_name -> seldon.mlops.scheduler.KubernetesMeta + 48, // 35: seldon.mlops.scheduler.Pipeline.input:type_name -> seldon.mlops.scheduler.PipelineInput + 61, // 36: seldon.mlops.scheduler.PipelineStep.tensorMap:type_name -> seldon.mlops.scheduler.PipelineStep.TensorMapEntry + 3, // 37: seldon.mlops.scheduler.PipelineStep.inputsJoin:type_name -> seldon.mlops.scheduler.PipelineStep.JoinOp + 3, // 38: seldon.mlops.scheduler.PipelineStep.triggersJoin:type_name -> seldon.mlops.scheduler.PipelineStep.JoinOp + 47, // 39: seldon.mlops.scheduler.PipelineStep.batch:type_name -> seldon.mlops.scheduler.Batch + 4, // 40: seldon.mlops.scheduler.PipelineInput.joinType:type_name -> seldon.mlops.scheduler.PipelineInput.JoinOp + 4, // 41: seldon.mlops.scheduler.PipelineInput.triggersJoin:type_name -> seldon.mlops.scheduler.PipelineInput.JoinOp + 62, // 42: seldon.mlops.scheduler.PipelineInput.tensorMap:type_name -> seldon.mlops.scheduler.PipelineInput.TensorMapEntry + 5, // 43: seldon.mlops.scheduler.PipelineOutput.stepsJoin:type_name -> seldon.mlops.scheduler.PipelineOutput.JoinOp + 63, // 44: seldon.mlops.scheduler.PipelineOutput.tensorMap:type_name -> seldon.mlops.scheduler.PipelineOutput.TensorMapEntry + 56, // 45: seldon.mlops.scheduler.PipelineStatusResponse.versions:type_name -> seldon.mlops.scheduler.PipelineWithState + 45, // 46: seldon.mlops.scheduler.PipelineWithState.pipeline:type_name -> seldon.mlops.scheduler.Pipeline + 57, // 47: seldon.mlops.scheduler.PipelineWithState.state:type_name -> seldon.mlops.scheduler.PipelineVersionState + 6, // 48: seldon.mlops.scheduler.PipelineVersionState.status:type_name -> seldon.mlops.scheduler.PipelineVersionState.PipelineStatus + 64, // 49: seldon.mlops.scheduler.PipelineVersionState.lastChangeTimestamp:type_name -> google.protobuf.Timestamp + 24, // 50: seldon.mlops.scheduler.ModelVersionStatus.ModelReplicaStateEntry.value:type_name -> seldon.mlops.scheduler.ModelReplicaStatus + 30, // 51: seldon.mlops.scheduler.Scheduler.ServerNotify:input_type -> seldon.mlops.scheduler.ServerNotifyRequest + 7, // 52: seldon.mlops.scheduler.Scheduler.LoadModel:input_type -> seldon.mlops.scheduler.LoadModelRequest + 19, // 53: seldon.mlops.scheduler.Scheduler.UnloadModel:input_type -> seldon.mlops.scheduler.UnloadModelRequest + 43, // 54: seldon.mlops.scheduler.Scheduler.LoadPipeline:input_type -> seldon.mlops.scheduler.LoadPipelineRequest + 51, // 55: seldon.mlops.scheduler.Scheduler.UnloadPipeline:input_type -> seldon.mlops.scheduler.UnloadPipelineRequest + 33, // 56: seldon.mlops.scheduler.Scheduler.StartExperiment:input_type -> seldon.mlops.scheduler.StartExperimentRequest + 39, // 57: seldon.mlops.scheduler.Scheduler.StopExperiment:input_type -> seldon.mlops.scheduler.StopExperimentRequest + 25, // 58: seldon.mlops.scheduler.Scheduler.ServerStatus:input_type -> seldon.mlops.scheduler.ServerStatusRequest + 29, // 59: seldon.mlops.scheduler.Scheduler.ModelStatus:input_type -> seldon.mlops.scheduler.ModelStatusRequest + 53, // 60: seldon.mlops.scheduler.Scheduler.PipelineStatus:input_type -> seldon.mlops.scheduler.PipelineStatusRequest + 44, // 61: seldon.mlops.scheduler.Scheduler.ExperimentStatus:input_type -> seldon.mlops.scheduler.ExperimentStatusRequest + 58, // 62: seldon.mlops.scheduler.Scheduler.SchedulerStatus:input_type -> seldon.mlops.scheduler.SchedulerStatusRequest + 32, // 63: seldon.mlops.scheduler.Scheduler.SubscribeServerStatus:input_type -> seldon.mlops.scheduler.ServerSubscriptionRequest + 28, // 64: seldon.mlops.scheduler.Scheduler.SubscribeModelStatus:input_type -> seldon.mlops.scheduler.ModelSubscriptionRequest + 41, // 65: seldon.mlops.scheduler.Scheduler.SubscribeExperimentStatus:input_type -> seldon.mlops.scheduler.ExperimentSubscriptionRequest + 54, // 66: seldon.mlops.scheduler.Scheduler.SubscribePipelineStatus:input_type -> seldon.mlops.scheduler.PipelineSubscriptionRequest + 31, // 67: seldon.mlops.scheduler.Scheduler.ServerNotify:output_type -> seldon.mlops.scheduler.ServerNotifyResponse + 17, // 68: seldon.mlops.scheduler.Scheduler.LoadModel:output_type -> seldon.mlops.scheduler.LoadModelResponse + 20, // 69: seldon.mlops.scheduler.Scheduler.UnloadModel:output_type -> seldon.mlops.scheduler.UnloadModelResponse + 50, // 70: seldon.mlops.scheduler.Scheduler.LoadPipeline:output_type -> seldon.mlops.scheduler.LoadPipelineResponse + 52, // 71: seldon.mlops.scheduler.Scheduler.UnloadPipeline:output_type -> seldon.mlops.scheduler.UnloadPipelineResponse + 38, // 72: seldon.mlops.scheduler.Scheduler.StartExperiment:output_type -> seldon.mlops.scheduler.StartExperimentResponse + 40, // 73: seldon.mlops.scheduler.Scheduler.StopExperiment:output_type -> seldon.mlops.scheduler.StopExperimentResponse + 26, // 74: seldon.mlops.scheduler.Scheduler.ServerStatus:output_type -> seldon.mlops.scheduler.ServerStatusResponse + 21, // 75: seldon.mlops.scheduler.Scheduler.ModelStatus:output_type -> seldon.mlops.scheduler.ModelStatusResponse + 55, // 76: seldon.mlops.scheduler.Scheduler.PipelineStatus:output_type -> seldon.mlops.scheduler.PipelineStatusResponse + 42, // 77: seldon.mlops.scheduler.Scheduler.ExperimentStatus:output_type -> seldon.mlops.scheduler.ExperimentStatusResponse + 59, // 78: seldon.mlops.scheduler.Scheduler.SchedulerStatus:output_type -> seldon.mlops.scheduler.SchedulerStatusResponse + 26, // 79: seldon.mlops.scheduler.Scheduler.SubscribeServerStatus:output_type -> seldon.mlops.scheduler.ServerStatusResponse + 21, // 80: seldon.mlops.scheduler.Scheduler.SubscribeModelStatus:output_type -> seldon.mlops.scheduler.ModelStatusResponse + 42, // 81: seldon.mlops.scheduler.Scheduler.SubscribeExperimentStatus:output_type -> seldon.mlops.scheduler.ExperimentStatusResponse + 55, // 82: seldon.mlops.scheduler.Scheduler.SubscribePipelineStatus:output_type -> seldon.mlops.scheduler.PipelineStatusResponse + 67, // [67:83] is the sub-list for method output_type + 51, // [51:67] is the sub-list for method input_type + 51, // [51:51] is the sub-list for extension type_name + 51, // [51:51] is the sub-list for extension extendee + 0, // [0:51] is the sub-list for field type_name } func init() { file_mlops_scheduler_scheduler_proto_init() } @@ -4876,7 +5047,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineOutput); i { + switch v := v.(*PipelineInput); i { case 0: return &v.state case 1: @@ -4888,7 +5059,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LoadPipelineResponse); i { + switch v := v.(*PipelineOutput); i { case 0: return &v.state case 1: @@ -4900,7 +5071,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnloadPipelineRequest); i { + switch v := v.(*LoadPipelineResponse); i { case 0: return &v.state case 1: @@ -4912,7 +5083,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnloadPipelineResponse); i { + switch v := v.(*UnloadPipelineRequest); i { case 0: return &v.state case 1: @@ -4924,7 +5095,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineStatusRequest); i { + switch v := v.(*UnloadPipelineResponse); i { case 0: return &v.state case 1: @@ -4936,7 +5107,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineSubscriptionRequest); i { + switch v := v.(*PipelineStatusRequest); i { case 0: return &v.state case 1: @@ -4948,7 +5119,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineStatusResponse); i { + switch v := v.(*PipelineSubscriptionRequest); i { case 0: return &v.state case 1: @@ -4960,7 +5131,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineWithState); i { + switch v := v.(*PipelineStatusResponse); i { case 0: return &v.state case 1: @@ -4972,7 +5143,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineVersionState); i { + switch v := v.(*PipelineWithState); i { case 0: return &v.state case 1: @@ -4984,7 +5155,7 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SchedulerStatusRequest); i { + switch v := v.(*PipelineVersionState); i { case 0: return &v.state case 1: @@ -4996,6 +5167,18 @@ func file_mlops_scheduler_scheduler_proto_init() { } } file_mlops_scheduler_scheduler_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SchedulerStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mlops_scheduler_scheduler_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SchedulerStatusResponse); i { case 0: return &v.state @@ -5028,14 +5211,15 @@ func file_mlops_scheduler_scheduler_proto_init() { file_mlops_scheduler_scheduler_proto_msgTypes[38].OneofWrappers = []interface{}{} file_mlops_scheduler_scheduler_proto_msgTypes[39].OneofWrappers = []interface{}{} file_mlops_scheduler_scheduler_proto_msgTypes[40].OneofWrappers = []interface{}{} - file_mlops_scheduler_scheduler_proto_msgTypes[45].OneofWrappers = []interface{}{} + file_mlops_scheduler_scheduler_proto_msgTypes[41].OneofWrappers = []interface{}{} + file_mlops_scheduler_scheduler_proto_msgTypes[46].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mlops_scheduler_scheduler_proto_rawDesc, - NumEnums: 6, - NumMessages: 55, + NumEnums: 7, + NumMessages: 57, NumExtensions: 0, NumServices: 1, }, diff --git a/apis/go/mlops/scheduler/scheduler_grpc.pb.go b/apis/go/mlops/scheduler/scheduler_grpc.pb.go index 757dd82a05..1541bdf442 100644 --- a/apis/go/mlops/scheduler/scheduler_grpc.pb.go +++ b/apis/go/mlops/scheduler/scheduler_grpc.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 diff --git a/apis/go/mlops/scheduler/storage.pb.go b/apis/go/mlops/scheduler/storage.pb.go index 5965f6f19c..b453f9cfb8 100644 --- a/apis/go/mlops/scheduler/storage.pb.go +++ b/apis/go/mlops/scheduler/storage.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 diff --git a/apis/go/mlops/v2_dataplane/v2_dataplane_grpc.pb.go b/apis/go/mlops/v2_dataplane/v2_dataplane_grpc.pb.go index 4e31d889f5..80f7ee7457 100644 --- a/apis/go/mlops/v2_dataplane/v2_dataplane_grpc.pb.go +++ b/apis/go/mlops/v2_dataplane/v2_dataplane_grpc.pb.go @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 diff --git a/apis/mlops/chainer/chainer.proto b/apis/mlops/chainer/chainer.proto index 977c90a4ff..727b42d7c0 100644 --- a/apis/mlops/chainer/chainer.proto +++ b/apis/mlops/chainer/chainer.proto @@ -32,9 +32,9 @@ message PipelineStepUpdate { // https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit // Pipeline Resource example, e.g. transform.outputs.traffic // seldon.... - repeated string sources = 1; - repeated string triggers = 2; - string sink = 3; + repeated PipelineTopic sources = 1; + repeated PipelineTopic triggers = 2; + PipelineTopic sink = 3; PipelineJoinType inputJoinTy = 4; PipelineJoinType triggersJoinTy = 5; bool passEmptyResponses = 6; // Forward empty response to following steps, default false @@ -43,6 +43,11 @@ message PipelineStepUpdate { Batch batch = 9; // Batch settings } +message PipelineTopic { + string pipelineName = 1; + string topicName = 2; +} + message Batch { optional uint32 size = 1; optional uint32 windowMs = 2; diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/BatchKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/BatchKt.kt index dd17ff027f..459db9bb81 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/BatchKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/BatchKt.kt @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - //Generated by the protocol buffer compiler. DO NOT EDIT! // source: chainer.proto diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java index ff7faf578e..4311e44f51 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java @@ -1955,10 +1955,9 @@ public interface PipelineStepUpdateOrBuilder extends * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @return A list containing the sources. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - java.util.List + java.util.List getSourcesList(); /** *
@@ -1967,8 +1966,17 @@ public interface PipelineStepUpdateOrBuilder extends
      *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
      * 
* - * repeated string sources = 1; - * @return The count of sources. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; + */ + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getSources(int index); + /** + *
+     * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+     * Pipeline Resource example, e.g. transform.outputs.traffic
+     *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+     * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ int getSourcesCount(); /** @@ -1978,11 +1986,10 @@ public interface PipelineStepUpdateOrBuilder extends * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @param index The index of the element to return. - * @return The sources at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - java.lang.String getSources(int index); + java.util.List + getSourcesOrBuilderList(); /** *
      * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
@@ -1990,49 +1997,49 @@ public interface PipelineStepUpdateOrBuilder extends
      *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
      * 
* - * repeated string sources = 1; - * @param index The index of the value to return. - * @return The bytes of the sources at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - com.google.protobuf.ByteString - getSourcesBytes(int index); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getSourcesOrBuilder( + int index); /** - * repeated string triggers = 2; - * @return A list containing the triggers. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - java.util.List + java.util.List getTriggersList(); /** - * repeated string triggers = 2; - * @return The count of triggers. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getTriggers(int index); + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ int getTriggersCount(); /** - * repeated string triggers = 2; - * @param index The index of the element to return. - * @return The triggers at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - java.lang.String getTriggers(int index); + java.util.List + getTriggersOrBuilderList(); /** - * repeated string triggers = 2; - * @param index The index of the value to return. - * @return The bytes of the triggers at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - com.google.protobuf.ByteString - getTriggersBytes(int index); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getTriggersOrBuilder( + int index); /** - * string sink = 3; + * .seldon.mlops.chainer.PipelineTopic sink = 3; + * @return Whether the sink field is set. + */ + boolean hasSink(); + /** + * .seldon.mlops.chainer.PipelineTopic sink = 3; * @return The sink. */ - java.lang.String getSink(); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getSink(); /** - * string sink = 3; - * @return The bytes for sink. + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ - com.google.protobuf.ByteString - getSinkBytes(); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getSinkOrBuilder(); /** * .seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType inputJoinTy = 4; @@ -2179,9 +2186,8 @@ private PipelineStepUpdate(com.google.protobuf.GeneratedMessageV3.Builder bui super(builder); } private PipelineStepUpdate() { - sources_ = com.google.protobuf.LazyStringArrayList.EMPTY; - triggers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - sink_ = ""; + sources_ = java.util.Collections.emptyList(); + triggers_ = java.util.Collections.emptyList(); inputJoinTy_ = 0; triggersJoinTy_ = 0; } @@ -2352,7 +2358,20 @@ private PipelineJoinType(int value) { private int bitField0_; public static final int SOURCES_FIELD_NUMBER = 1; @SuppressWarnings("serial") - private com.google.protobuf.LazyStringList sources_; + private java.util.List sources_; + /** + *
+     * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+     * Pipeline Resource example, e.g. transform.outputs.traffic
+     *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+     * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; + */ + @java.lang.Override + public java.util.List getSourcesList() { + return sources_; + } /** *
      * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
@@ -2360,11 +2379,11 @@ private PipelineJoinType(int value) {
      *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
      * 
* - * repeated string sources = 1; - * @return A list containing the sources. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public com.google.protobuf.ProtocolStringList - getSourcesList() { + @java.lang.Override + public java.util.List + getSourcesOrBuilderList() { return sources_; } /** @@ -2374,9 +2393,9 @@ private PipelineJoinType(int value) { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @return The count of sources. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ + @java.lang.Override public int getSourcesCount() { return sources_.size(); } @@ -2387,11 +2406,10 @@ public int getSourcesCount() { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @param index The index of the element to return. - * @return The sources at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public java.lang.String getSources(int index) { + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getSources(int index) { return sources_.get(index); } /** @@ -2401,88 +2419,79 @@ public java.lang.String getSources(int index) { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @param index The index of the value to return. - * @return The bytes of the sources at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public com.google.protobuf.ByteString - getSourcesBytes(int index) { - return sources_.getByteString(index); + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getSourcesOrBuilder( + int index) { + return sources_.get(index); } public static final int TRIGGERS_FIELD_NUMBER = 2; @SuppressWarnings("serial") - private com.google.protobuf.LazyStringList triggers_; + private java.util.List triggers_; + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + @java.lang.Override + public java.util.List getTriggersList() { + return triggers_; + } /** - * repeated string triggers = 2; - * @return A list containing the triggers. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - public com.google.protobuf.ProtocolStringList - getTriggersList() { + @java.lang.Override + public java.util.List + getTriggersOrBuilderList() { return triggers_; } /** - * repeated string triggers = 2; - * @return The count of triggers. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ + @java.lang.Override public int getTriggersCount() { return triggers_.size(); } /** - * repeated string triggers = 2; - * @param index The index of the element to return. - * @return The triggers at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - public java.lang.String getTriggers(int index) { + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getTriggers(int index) { return triggers_.get(index); } /** - * repeated string triggers = 2; - * @param index The index of the value to return. - * @return The bytes of the triggers at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - public com.google.protobuf.ByteString - getTriggersBytes(int index) { - return triggers_.getByteString(index); + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getTriggersOrBuilder( + int index) { + return triggers_.get(index); } public static final int SINK_FIELD_NUMBER = 3; - @SuppressWarnings("serial") - private volatile java.lang.Object sink_ = ""; + private io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic sink_; /** - * string sink = 3; + * .seldon.mlops.chainer.PipelineTopic sink = 3; + * @return Whether the sink field is set. + */ + @java.lang.Override + public boolean hasSink() { + return sink_ != null; + } + /** + * .seldon.mlops.chainer.PipelineTopic sink = 3; * @return The sink. */ @java.lang.Override - public java.lang.String getSink() { - java.lang.Object ref = sink_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - sink_ = s; - return s; - } + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getSink() { + return sink_ == null ? io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance() : sink_; } /** - * string sink = 3; - * @return The bytes for sink. + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ @java.lang.Override - public com.google.protobuf.ByteString - getSinkBytes() { - java.lang.Object ref = sink_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - sink_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getSinkOrBuilder() { + return sink_ == null ? io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance() : sink_; } public static final int INPUTJOINTY_FIELD_NUMBER = 4; @@ -2711,13 +2720,13 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { for (int i = 0; i < sources_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, sources_.getRaw(i)); + output.writeMessage(1, sources_.get(i)); } for (int i = 0; i < triggers_.size(); i++) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 2, triggers_.getRaw(i)); + output.writeMessage(2, triggers_.get(i)); } - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(sink_)) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 3, sink_); + if (sink_ != null) { + output.writeMessage(3, getSink()); } if (inputJoinTy_ != io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Unknown.getNumber()) { output.writeEnum(4, inputJoinTy_); @@ -2749,24 +2758,17 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - { - int dataSize = 0; - for (int i = 0; i < sources_.size(); i++) { - dataSize += computeStringSizeNoTag(sources_.getRaw(i)); - } - size += dataSize; - size += 1 * getSourcesList().size(); + for (int i = 0; i < sources_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, sources_.get(i)); } - { - int dataSize = 0; - for (int i = 0; i < triggers_.size(); i++) { - dataSize += computeStringSizeNoTag(triggers_.getRaw(i)); - } - size += dataSize; - size += 1 * getTriggersList().size(); + for (int i = 0; i < triggers_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, triggers_.get(i)); } - if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(sink_)) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, sink_); + if (sink_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, getSink()); } if (inputJoinTy_ != io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Unknown.getNumber()) { size += com.google.protobuf.CodedOutputStream @@ -2817,8 +2819,11 @@ public boolean equals(final java.lang.Object obj) { .equals(other.getSourcesList())) return false; if (!getTriggersList() .equals(other.getTriggersList())) return false; - if (!getSink() - .equals(other.getSink())) return false; + if (hasSink() != other.hasSink()) return false; + if (hasSink()) { + if (!getSink() + .equals(other.getSink())) return false; + } if (inputJoinTy_ != other.inputJoinTy_) return false; if (triggersJoinTy_ != other.triggersJoinTy_) return false; if (getPassEmptyResponses() @@ -2854,8 +2859,10 @@ public int hashCode() { hash = (37 * hash) + TRIGGERS_FIELD_NUMBER; hash = (53 * hash) + getTriggersList().hashCode(); } - hash = (37 * hash) + SINK_FIELD_NUMBER; - hash = (53 * hash) + getSink().hashCode(); + if (hasSink()) { + hash = (37 * hash) + SINK_FIELD_NUMBER; + hash = (53 * hash) + getSink().hashCode(); + } hash = (37 * hash) + INPUTJOINTY_FIELD_NUMBER; hash = (53 * hash) + inputJoinTy_; hash = (37 * hash) + TRIGGERSJOINTY_FIELD_NUMBER; @@ -3026,11 +3033,25 @@ private Builder( public Builder clear() { super.clear(); bitField0_ = 0; - sources_ = com.google.protobuf.LazyStringArrayList.EMPTY; + if (sourcesBuilder_ == null) { + sources_ = java.util.Collections.emptyList(); + } else { + sources_ = null; + sourcesBuilder_.clear(); + } bitField0_ = (bitField0_ & ~0x00000001); - triggers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + if (triggersBuilder_ == null) { + triggers_ = java.util.Collections.emptyList(); + } else { + triggers_ = null; + triggersBuilder_.clear(); + } bitField0_ = (bitField0_ & ~0x00000002); - sink_ = ""; + sink_ = null; + if (sinkBuilder_ != null) { + sinkBuilder_.dispose(); + sinkBuilder_ = null; + } inputJoinTy_ = 0; triggersJoinTy_ = 0; passEmptyResponses_ = false; @@ -3074,22 +3095,32 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate buildPartial } private void buildPartialRepeatedFields(io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate result) { - if (((bitField0_ & 0x00000001) != 0)) { - sources_ = sources_.getUnmodifiableView(); - bitField0_ = (bitField0_ & ~0x00000001); + if (sourcesBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + sources_ = java.util.Collections.unmodifiableList(sources_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.sources_ = sources_; + } else { + result.sources_ = sourcesBuilder_.build(); } - result.sources_ = sources_; - if (((bitField0_ & 0x00000002) != 0)) { - triggers_ = triggers_.getUnmodifiableView(); - bitField0_ = (bitField0_ & ~0x00000002); + if (triggersBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0)) { + triggers_ = java.util.Collections.unmodifiableList(triggers_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.triggers_ = triggers_; + } else { + result.triggers_ = triggersBuilder_.build(); } - result.triggers_ = triggers_; } private void buildPartial0(io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate result) { int from_bitField0_ = bitField0_; if (((from_bitField0_ & 0x00000004) != 0)) { - result.sink_ = sink_; + result.sink_ = sinkBuilder_ == null + ? sink_ + : sinkBuilder_.build(); } if (((from_bitField0_ & 0x00000008) != 0)) { result.inputJoinTy_ = inputJoinTy_; @@ -3161,30 +3192,60 @@ public Builder mergeFrom(com.google.protobuf.Message other) { public Builder mergeFrom(io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate other) { if (other == io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate.getDefaultInstance()) return this; - if (!other.sources_.isEmpty()) { - if (sources_.isEmpty()) { - sources_ = other.sources_; - bitField0_ = (bitField0_ & ~0x00000001); - } else { - ensureSourcesIsMutable(); - sources_.addAll(other.sources_); + if (sourcesBuilder_ == null) { + if (!other.sources_.isEmpty()) { + if (sources_.isEmpty()) { + sources_ = other.sources_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureSourcesIsMutable(); + sources_.addAll(other.sources_); + } + onChanged(); + } + } else { + if (!other.sources_.isEmpty()) { + if (sourcesBuilder_.isEmpty()) { + sourcesBuilder_.dispose(); + sourcesBuilder_ = null; + sources_ = other.sources_; + bitField0_ = (bitField0_ & ~0x00000001); + sourcesBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getSourcesFieldBuilder() : null; + } else { + sourcesBuilder_.addAllMessages(other.sources_); + } } - onChanged(); } - if (!other.triggers_.isEmpty()) { - if (triggers_.isEmpty()) { - triggers_ = other.triggers_; - bitField0_ = (bitField0_ & ~0x00000002); - } else { - ensureTriggersIsMutable(); - triggers_.addAll(other.triggers_); + if (triggersBuilder_ == null) { + if (!other.triggers_.isEmpty()) { + if (triggers_.isEmpty()) { + triggers_ = other.triggers_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureTriggersIsMutable(); + triggers_.addAll(other.triggers_); + } + onChanged(); + } + } else { + if (!other.triggers_.isEmpty()) { + if (triggersBuilder_.isEmpty()) { + triggersBuilder_.dispose(); + triggersBuilder_ = null; + triggers_ = other.triggers_; + bitField0_ = (bitField0_ & ~0x00000002); + triggersBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getTriggersFieldBuilder() : null; + } else { + triggersBuilder_.addAllMessages(other.triggers_); + } } - onChanged(); } - if (!other.getSink().isEmpty()) { - sink_ = other.sink_; - bitField0_ |= 0x00000004; - onChanged(); + if (other.hasSink()) { + mergeSink(other.getSink()); } if (other.inputJoinTy_ != 0) { setInputJoinTyValue(other.getInputJoinTyValue()); @@ -3231,19 +3292,35 @@ public Builder mergeFrom( done = true; break; case 10: { - java.lang.String s = input.readStringRequireUtf8(); - ensureSourcesIsMutable(); - sources_.add(s); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic m = + input.readMessage( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.parser(), + extensionRegistry); + if (sourcesBuilder_ == null) { + ensureSourcesIsMutable(); + sources_.add(m); + } else { + sourcesBuilder_.addMessage(m); + } break; } // case 10 case 18: { - java.lang.String s = input.readStringRequireUtf8(); - ensureTriggersIsMutable(); - triggers_.add(s); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic m = + input.readMessage( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.parser(), + extensionRegistry); + if (triggersBuilder_ == null) { + ensureTriggersIsMutable(); + triggers_.add(m); + } else { + triggersBuilder_.addMessage(m); + } break; } // case 18 case 26: { - sink_ = input.readStringRequireUtf8(); + input.readMessage( + getSinkFieldBuilder().getBuilder(), + extensionRegistry); bitField0_ |= 0x00000004; break; } // case 26 @@ -3300,13 +3377,18 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.LazyStringList sources_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private java.util.List sources_ = + java.util.Collections.emptyList(); private void ensureSourcesIsMutable() { if (!((bitField0_ & 0x00000001) != 0)) { - sources_ = new com.google.protobuf.LazyStringArrayList(sources_); + sources_ = new java.util.ArrayList(sources_); bitField0_ |= 0x00000001; } } + + private com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder> sourcesBuilder_; + /** *
        * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
@@ -3314,12 +3396,14 @@ private void ensureSourcesIsMutable() {
        *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
        * 
* - * repeated string sources = 1; - * @return A list containing the sources. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public com.google.protobuf.ProtocolStringList - getSourcesList() { - return sources_.getUnmodifiableView(); + public java.util.List getSourcesList() { + if (sourcesBuilder_ == null) { + return java.util.Collections.unmodifiableList(sources_); + } else { + return sourcesBuilder_.getMessageList(); + } } /** *
@@ -3328,11 +3412,14 @@ private void ensureSourcesIsMutable() {
        *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
        * 
* - * repeated string sources = 1; - * @return The count of sources. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ public int getSourcesCount() { - return sources_.size(); + if (sourcesBuilder_ == null) { + return sources_.size(); + } else { + return sourcesBuilder_.getCount(); + } } /** *
@@ -3341,12 +3428,14 @@ public int getSourcesCount() {
        *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
        * 
* - * repeated string sources = 1; - * @param index The index of the element to return. - * @return The sources at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public java.lang.String getSources(int index) { - return sources_.get(index); + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getSources(int index) { + if (sourcesBuilder_ == null) { + return sources_.get(index); + } else { + return sourcesBuilder_.getMessage(index); + } } /** *
@@ -3355,13 +3444,21 @@ public java.lang.String getSources(int index) {
        *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
        * 
* - * repeated string sources = 1; - * @param index The index of the value to return. - * @return The bytes of the sources at the given index. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public com.google.protobuf.ByteString - getSourcesBytes(int index) { - return sources_.getByteString(index); + public Builder setSources( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (sourcesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSourcesIsMutable(); + sources_.set(index, value); + onChanged(); + } else { + sourcesBuilder_.setMessage(index, value); + } + return this; } /** *
@@ -3370,17 +3467,17 @@ public java.lang.String getSources(int index) {
        *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
        * 
* - * repeated string sources = 1; - * @param index The index to set the value at. - * @param value The sources to set. - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ public Builder setSources( - int index, java.lang.String value) { - if (value == null) { throw new NullPointerException(); } - ensureSourcesIsMutable(); - sources_.set(index, value); - onChanged(); + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder builderForValue) { + if (sourcesBuilder_ == null) { + ensureSourcesIsMutable(); + sources_.set(index, builderForValue.build()); + onChanged(); + } else { + sourcesBuilder_.setMessage(index, builderForValue.build()); + } return this; } /** @@ -3390,16 +3487,19 @@ public Builder setSources( * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @param value The sources to add. - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public Builder addSources( - java.lang.String value) { - if (value == null) { throw new NullPointerException(); } - ensureSourcesIsMutable(); - sources_.add(value); - onChanged(); + public Builder addSources(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (sourcesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSourcesIsMutable(); + sources_.add(value); + onChanged(); + } else { + sourcesBuilder_.addMessage(value); + } return this; } /** @@ -3409,16 +3509,20 @@ public Builder addSources( * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @param values The sources to add. - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public Builder addAllSources( - java.lang.Iterable values) { - ensureSourcesIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, sources_); - onChanged(); + public Builder addSources( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (sourcesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSourcesIsMutable(); + sources_.add(index, value); + onChanged(); + } else { + sourcesBuilder_.addMessage(index, value); + } return this; } /** @@ -3428,13 +3532,17 @@ public Builder addAllSources( * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public Builder clearSources() { - sources_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); - onChanged(); + public Builder addSources( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder builderForValue) { + if (sourcesBuilder_ == null) { + ensureSourcesIsMutable(); + sources_.add(builderForValue.build()); + onChanged(); + } else { + sourcesBuilder_.addMessage(builderForValue.build()); + } return this; } /** @@ -3444,194 +3552,536 @@ public Builder clearSources() { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @param value The bytes of the sources to add. - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public Builder addSourcesBytes( - com.google.protobuf.ByteString value) { - if (value == null) { throw new NullPointerException(); } - checkByteStringIsUtf8(value); - ensureSourcesIsMutable(); - sources_.add(value); - onChanged(); + public Builder addSources( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder builderForValue) { + if (sourcesBuilder_ == null) { + ensureSourcesIsMutable(); + sources_.add(index, builderForValue.build()); + onChanged(); + } else { + sourcesBuilder_.addMessage(index, builderForValue.build()); + } return this; } - - private com.google.protobuf.LazyStringList triggers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - private void ensureTriggersIsMutable() { - if (!((bitField0_ & 0x00000002) != 0)) { - triggers_ = new com.google.protobuf.LazyStringArrayList(triggers_); - bitField0_ |= 0x00000002; - } - } /** - * repeated string triggers = 2; - * @return A list containing the triggers. + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public com.google.protobuf.ProtocolStringList - getTriggersList() { - return triggers_.getUnmodifiableView(); + public Builder addAllSources( + java.lang.Iterable values) { + if (sourcesBuilder_ == null) { + ensureSourcesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, sources_); + onChanged(); + } else { + sourcesBuilder_.addAllMessages(values); + } + return this; } /** - * repeated string triggers = 2; - * @return The count of triggers. + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public int getTriggersCount() { - return triggers_.size(); + public Builder clearSources() { + if (sourcesBuilder_ == null) { + sources_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + sourcesBuilder_.clear(); + } + return this; } /** - * repeated string triggers = 2; - * @param index The index of the element to return. - * @return The triggers at the given index. + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public java.lang.String getTriggers(int index) { - return triggers_.get(index); + public Builder removeSources(int index) { + if (sourcesBuilder_ == null) { + ensureSourcesIsMutable(); + sources_.remove(index); + onChanged(); + } else { + sourcesBuilder_.remove(index); + } + return this; } /** - * repeated string triggers = 2; - * @param index The index of the value to return. - * @return The bytes of the triggers at the given index. + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public com.google.protobuf.ByteString - getTriggersBytes(int index) { - return triggers_.getByteString(index); + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder getSourcesBuilder( + int index) { + return getSourcesFieldBuilder().getBuilder(index); } /** - * repeated string triggers = 2; - * @param index The index to set the value at. - * @param value The triggers to set. - * @return This builder for chaining. + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public Builder setTriggers( - int index, java.lang.String value) { - if (value == null) { throw new NullPointerException(); } - ensureTriggersIsMutable(); - triggers_.set(index, value); - onChanged(); - return this; + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getSourcesOrBuilder( + int index) { + if (sourcesBuilder_ == null) { + return sources_.get(index); } else { + return sourcesBuilder_.getMessageOrBuilder(index); + } } /** - * repeated string triggers = 2; - * @param value The triggers to add. - * @return This builder for chaining. - */ - public Builder addTriggers( - java.lang.String value) { - if (value == null) { throw new NullPointerException(); } - ensureTriggersIsMutable(); - triggers_.add(value); - onChanged(); + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; + */ + public java.util.List + getSourcesOrBuilderList() { + if (sourcesBuilder_ != null) { + return sourcesBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(sources_); + } + } + /** + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder addSourcesBuilder() { + return getSourcesFieldBuilder().addBuilder( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance()); + } + /** + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder addSourcesBuilder( + int index) { + return getSourcesFieldBuilder().addBuilder( + index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance()); + } + /** + *
+       * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
+       * Pipeline Resource example, e.g. transform.outputs.traffic
+       *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; + */ + public java.util.List + getSourcesBuilderList() { + return getSourcesFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder> + getSourcesFieldBuilder() { + if (sourcesBuilder_ == null) { + sourcesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder>( + sources_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + sources_ = null; + } + return sourcesBuilder_; + } + + private java.util.List triggers_ = + java.util.Collections.emptyList(); + private void ensureTriggersIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + triggers_ = new java.util.ArrayList(triggers_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder> triggersBuilder_; + + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public java.util.List getTriggersList() { + if (triggersBuilder_ == null) { + return java.util.Collections.unmodifiableList(triggers_); + } else { + return triggersBuilder_.getMessageList(); + } + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public int getTriggersCount() { + if (triggersBuilder_ == null) { + return triggers_.size(); + } else { + return triggersBuilder_.getCount(); + } + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getTriggers(int index) { + if (triggersBuilder_ == null) { + return triggers_.get(index); + } else { + return triggersBuilder_.getMessage(index); + } + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public Builder setTriggers( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (triggersBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTriggersIsMutable(); + triggers_.set(index, value); + onChanged(); + } else { + triggersBuilder_.setMessage(index, value); + } return this; } /** - * repeated string triggers = 2; - * @param values The triggers to add. - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public Builder setTriggers( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder builderForValue) { + if (triggersBuilder_ == null) { + ensureTriggersIsMutable(); + triggers_.set(index, builderForValue.build()); + onChanged(); + } else { + triggersBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public Builder addTriggers(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (triggersBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTriggersIsMutable(); + triggers_.add(value); + onChanged(); + } else { + triggersBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public Builder addTriggers( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (triggersBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTriggersIsMutable(); + triggers_.add(index, value); + onChanged(); + } else { + triggersBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public Builder addTriggers( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder builderForValue) { + if (triggersBuilder_ == null) { + ensureTriggersIsMutable(); + triggers_.add(builderForValue.build()); + onChanged(); + } else { + triggersBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public Builder addTriggers( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder builderForValue) { + if (triggersBuilder_ == null) { + ensureTriggersIsMutable(); + triggers_.add(index, builderForValue.build()); + onChanged(); + } else { + triggersBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ public Builder addAllTriggers( - java.lang.Iterable values) { - ensureTriggersIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, triggers_); - onChanged(); + java.lang.Iterable values) { + if (triggersBuilder_ == null) { + ensureTriggersIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, triggers_); + onChanged(); + } else { + triggersBuilder_.addAllMessages(values); + } return this; } /** - * repeated string triggers = 2; - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ public Builder clearTriggers() { - triggers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000002); - onChanged(); + if (triggersBuilder_ == null) { + triggers_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + triggersBuilder_.clear(); + } return this; } /** - * repeated string triggers = 2; - * @param value The bytes of the triggers to add. - * @return This builder for chaining. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - public Builder addTriggersBytes( - com.google.protobuf.ByteString value) { - if (value == null) { throw new NullPointerException(); } - checkByteStringIsUtf8(value); - ensureTriggersIsMutable(); - triggers_.add(value); - onChanged(); + public Builder removeTriggers(int index) { + if (triggersBuilder_ == null) { + ensureTriggersIsMutable(); + triggers_.remove(index); + onChanged(); + } else { + triggersBuilder_.remove(index); + } return this; } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder getTriggersBuilder( + int index) { + return getTriggersFieldBuilder().getBuilder(index); + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getTriggersOrBuilder( + int index) { + if (triggersBuilder_ == null) { + return triggers_.get(index); } else { + return triggersBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public java.util.List + getTriggersOrBuilderList() { + if (triggersBuilder_ != null) { + return triggersBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(triggers_); + } + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder addTriggersBuilder() { + return getTriggersFieldBuilder().addBuilder( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance()); + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder addTriggersBuilder( + int index) { + return getTriggersFieldBuilder().addBuilder( + index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance()); + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; + */ + public java.util.List + getTriggersBuilderList() { + return getTriggersFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder> + getTriggersFieldBuilder() { + if (triggersBuilder_ == null) { + triggersBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder>( + triggers_, + ((bitField0_ & 0x00000002) != 0), + getParentForChildren(), + isClean()); + triggers_ = null; + } + return triggersBuilder_; + } - private java.lang.Object sink_ = ""; + private io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic sink_; + private com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder> sinkBuilder_; + /** + * .seldon.mlops.chainer.PipelineTopic sink = 3; + * @return Whether the sink field is set. + */ + public boolean hasSink() { + return ((bitField0_ & 0x00000004) != 0); + } /** - * string sink = 3; + * .seldon.mlops.chainer.PipelineTopic sink = 3; * @return The sink. */ - public java.lang.String getSink() { - java.lang.Object ref = sink_; - if (!(ref instanceof java.lang.String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - sink_ = s; - return s; + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getSink() { + if (sinkBuilder_ == null) { + return sink_ == null ? io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance() : sink_; } else { - return (java.lang.String) ref; + return sinkBuilder_.getMessage(); } } /** - * string sink = 3; - * @return The bytes for sink. + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ - public com.google.protobuf.ByteString - getSinkBytes() { - java.lang.Object ref = sink_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - sink_ = b; - return b; + public Builder setSink(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (sinkBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + sink_ = value; } else { - return (com.google.protobuf.ByteString) ref; + sinkBuilder_.setMessage(value); } + bitField0_ |= 0x00000004; + onChanged(); + return this; } /** - * string sink = 3; - * @param value The sink to set. - * @return This builder for chaining. + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ public Builder setSink( - java.lang.String value) { - if (value == null) { throw new NullPointerException(); } - sink_ = value; + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder builderForValue) { + if (sinkBuilder_ == null) { + sink_ = builderForValue.build(); + } else { + sinkBuilder_.setMessage(builderForValue.build()); + } bitField0_ |= 0x00000004; onChanged(); return this; } /** - * string sink = 3; - * @return This builder for chaining. + * .seldon.mlops.chainer.PipelineTopic sink = 3; + */ + public Builder mergeSink(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic value) { + if (sinkBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + sink_ != null && + sink_ != io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance()) { + getSinkBuilder().mergeFrom(value); + } else { + sink_ = value; + } + } else { + sinkBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ public Builder clearSink() { - sink_ = getDefaultInstance().getSink(); bitField0_ = (bitField0_ & ~0x00000004); + sink_ = null; + if (sinkBuilder_ != null) { + sinkBuilder_.dispose(); + sinkBuilder_ = null; + } onChanged(); return this; } /** - * string sink = 3; - * @param value The bytes for sink to set. - * @return This builder for chaining. + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ - public Builder setSinkBytes( - com.google.protobuf.ByteString value) { - if (value == null) { throw new NullPointerException(); } - checkByteStringIsUtf8(value); - sink_ = value; + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder getSinkBuilder() { bitField0_ |= 0x00000004; onChanged(); - return this; + return getSinkFieldBuilder().getBuilder(); + } + /** + * .seldon.mlops.chainer.PipelineTopic sink = 3; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getSinkOrBuilder() { + if (sinkBuilder_ != null) { + return sinkBuilder_.getMessageOrBuilder(); + } else { + return sink_ == null ? + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance() : sink_; + } + } + /** + * .seldon.mlops.chainer.PipelineTopic sink = 3; + */ + private com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder> + getSinkFieldBuilder() { + if (sinkBuilder_ == null) { + sinkBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder>( + getSink(), + getParentForChildren(), + isClean()); + sink_ = null; + } + return sinkBuilder_; } private int inputJoinTy_ = 0; @@ -3941,214 +4391,917 @@ public Builder clearTensorMap() { return this; } /** - *
-       * optional map of tensor name mappings
-       * 
- * - * map<string, string> tensorMap = 8; + *
+       * optional map of tensor name mappings
+       * 
+ * + * map<string, string> tensorMap = 8; + */ + public Builder removeTensorMap( + java.lang.String key) { + if (key == null) { throw new NullPointerException("map key"); } + internalGetMutableTensorMap().getMutableMap() + .remove(key); + return this; + } + /** + * Use alternate mutation accessors instead. + */ + @java.lang.Deprecated + public java.util.Map + getMutableTensorMap() { + bitField0_ |= 0x00000080; + return internalGetMutableTensorMap().getMutableMap(); + } + /** + *
+       * optional map of tensor name mappings
+       * 
+ * + * map<string, string> tensorMap = 8; + */ + public Builder putTensorMap( + java.lang.String key, + java.lang.String value) { + if (key == null) { throw new NullPointerException("map key"); } + if (value == null) { throw new NullPointerException("map value"); } + internalGetMutableTensorMap().getMutableMap() + .put(key, value); + bitField0_ |= 0x00000080; + return this; + } + /** + *
+       * optional map of tensor name mappings
+       * 
+ * + * map<string, string> tensorMap = 8; + */ + public Builder putAllTensorMap( + java.util.Map values) { + internalGetMutableTensorMap().getMutableMap() + .putAll(values); + bitField0_ |= 0x00000080; + return this; + } + + private io.seldon.mlops.chainer.ChainerOuterClass.Batch batch_; + private com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> batchBuilder_; + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + * @return Whether the batch field is set. + */ + public boolean hasBatch() { + return ((bitField0_ & 0x00000100) != 0); + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + * @return The batch. + */ + public io.seldon.mlops.chainer.ChainerOuterClass.Batch getBatch() { + if (batchBuilder_ == null) { + return batch_ == null ? io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; + } else { + return batchBuilder_.getMessage(); + } + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder setBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { + if (batchBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + batch_ = value; + } else { + batchBuilder_.setMessage(value); + } + bitField0_ |= 0x00000100; + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder setBatch( + io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder builderForValue) { + if (batchBuilder_ == null) { + batch_ = builderForValue.build(); + } else { + batchBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000100; + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder mergeBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { + if (batchBuilder_ == null) { + if (((bitField0_ & 0x00000100) != 0) && + batch_ != null && + batch_ != io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance()) { + getBatchBuilder().mergeFrom(value); + } else { + batch_ = value; + } + } else { + batchBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000100; + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder clearBatch() { + bitField0_ = (bitField0_ & ~0x00000100); + batch_ = null; + if (batchBuilder_ != null) { + batchBuilder_.dispose(); + batchBuilder_ = null; + } + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder getBatchBuilder() { + bitField0_ |= 0x00000100; + onChanged(); + return getBatchFieldBuilder().getBuilder(); + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder getBatchOrBuilder() { + if (batchBuilder_ != null) { + return batchBuilder_.getMessageOrBuilder(); + } else { + return batch_ == null ? + io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; + } + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + private com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> + getBatchFieldBuilder() { + if (batchBuilder_ == null) { + batchBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder>( + getBatch(), + getParentForChildren(), + isClean()); + batch_ = null; + } + return batchBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:seldon.mlops.chainer.PipelineStepUpdate) + } + + // @@protoc_insertion_point(class_scope:seldon.mlops.chainer.PipelineStepUpdate) + private static final io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate(); + } + + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PipelineStepUpdate parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PipelineTopicOrBuilder extends + // @@protoc_insertion_point(interface_extends:seldon.mlops.chainer.PipelineTopic) + com.google.protobuf.MessageOrBuilder { + + /** + * string pipelineName = 1; + * @return The pipelineName. + */ + java.lang.String getPipelineName(); + /** + * string pipelineName = 1; + * @return The bytes for pipelineName. + */ + com.google.protobuf.ByteString + getPipelineNameBytes(); + + /** + * string topicName = 2; + * @return The topicName. + */ + java.lang.String getTopicName(); + /** + * string topicName = 2; + * @return The bytes for topicName. + */ + com.google.protobuf.ByteString + getTopicNameBytes(); + } + /** + * Protobuf type {@code seldon.mlops.chainer.PipelineTopic} + */ + public static final class PipelineTopic extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:seldon.mlops.chainer.PipelineTopic) + PipelineTopicOrBuilder { + private static final long serialVersionUID = 0L; + // Use PipelineTopic.newBuilder() to construct. + private PipelineTopic(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PipelineTopic() { + pipelineName_ = ""; + topicName_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new PipelineTopic(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTopic_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTopic_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.class, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder.class); + } + + public static final int PIPELINENAME_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private volatile java.lang.Object pipelineName_ = ""; + /** + * string pipelineName = 1; + * @return The pipelineName. + */ + @java.lang.Override + public java.lang.String getPipelineName() { + java.lang.Object ref = pipelineName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + pipelineName_ = s; + return s; + } + } + /** + * string pipelineName = 1; + * @return The bytes for pipelineName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getPipelineNameBytes() { + java.lang.Object ref = pipelineName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + pipelineName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TOPICNAME_FIELD_NUMBER = 2; + @SuppressWarnings("serial") + private volatile java.lang.Object topicName_ = ""; + /** + * string topicName = 2; + * @return The topicName. + */ + @java.lang.Override + public java.lang.String getTopicName() { + java.lang.Object ref = topicName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + topicName_ = s; + return s; + } + } + /** + * string topicName = 2; + * @return The bytes for topicName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getTopicNameBytes() { + java.lang.Object ref = topicName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + topicName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(pipelineName_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, pipelineName_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(topicName_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, topicName_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(pipelineName_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, pipelineName_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(topicName_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, topicName_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic)) { + return super.equals(obj); + } + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic other = (io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) obj; + + if (!getPipelineName() + .equals(other.getPipelineName())) return false; + if (!getTopicName() + .equals(other.getTopicName())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + PIPELINENAME_FIELD_NUMBER; + hash = (53 * hash) + getPipelineName().hashCode(); + hash = (37 * hash) + TOPICNAME_FIELD_NUMBER; + hash = (53 * hash) + getTopicName().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code seldon.mlops.chainer.PipelineTopic} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:seldon.mlops.chainer.PipelineTopic) + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTopic_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTopic_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.class, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder.class); + } + + // Construct using io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + pipelineName_ = ""; + topicName_ = ""; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTopic_descriptor; + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getDefaultInstanceForType() { + return io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance(); + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic build() { + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic buildPartial() { + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic result = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.pipelineName_ = pipelineName_; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.topicName_ = topicName_; + } + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) { + return mergeFrom((io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic other) { + if (other == io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.getDefaultInstance()) return this; + if (!other.getPipelineName().isEmpty()) { + pipelineName_ = other.pipelineName_; + bitField0_ |= 0x00000001; + onChanged(); + } + if (!other.getTopicName().isEmpty()) { + topicName_ = other.topicName_; + bitField0_ |= 0x00000002; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + pipelineName_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: { + topicName_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000002; + break; + } // case 18 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.lang.Object pipelineName_ = ""; + /** + * string pipelineName = 1; + * @return The pipelineName. */ - public Builder removeTensorMap( - java.lang.String key) { - if (key == null) { throw new NullPointerException("map key"); } - internalGetMutableTensorMap().getMutableMap() - .remove(key); - return this; + public java.lang.String getPipelineName() { + java.lang.Object ref = pipelineName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + pipelineName_ = s; + return s; + } else { + return (java.lang.String) ref; + } } /** - * Use alternate mutation accessors instead. + * string pipelineName = 1; + * @return The bytes for pipelineName. */ - @java.lang.Deprecated - public java.util.Map - getMutableTensorMap() { - bitField0_ |= 0x00000080; - return internalGetMutableTensorMap().getMutableMap(); + public com.google.protobuf.ByteString + getPipelineNameBytes() { + java.lang.Object ref = pipelineName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + pipelineName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } } /** - *
-       * optional map of tensor name mappings
-       * 
- * - * map<string, string> tensorMap = 8; + * string pipelineName = 1; + * @param value The pipelineName to set. + * @return This builder for chaining. */ - public Builder putTensorMap( - java.lang.String key, + public Builder setPipelineName( java.lang.String value) { - if (key == null) { throw new NullPointerException("map key"); } - if (value == null) { throw new NullPointerException("map value"); } - internalGetMutableTensorMap().getMutableMap() - .put(key, value); - bitField0_ |= 0x00000080; + if (value == null) { throw new NullPointerException(); } + pipelineName_ = value; + bitField0_ |= 0x00000001; + onChanged(); return this; } /** - *
-       * optional map of tensor name mappings
-       * 
- * - * map<string, string> tensorMap = 8; + * string pipelineName = 1; + * @return This builder for chaining. */ - public Builder putAllTensorMap( - java.util.Map values) { - internalGetMutableTensorMap().getMutableMap() - .putAll(values); - bitField0_ |= 0x00000080; + public Builder clearPipelineName() { + pipelineName_ = getDefaultInstance().getPipelineName(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); return this; } - - private io.seldon.mlops.chainer.ChainerOuterClass.Batch batch_; - private com.google.protobuf.SingleFieldBuilderV3< - io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> batchBuilder_; /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; - * @return Whether the batch field is set. + * string pipelineName = 1; + * @param value The bytes for pipelineName to set. + * @return This builder for chaining. */ - public boolean hasBatch() { - return ((bitField0_ & 0x00000100) != 0); + public Builder setPipelineNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + pipelineName_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; } + + private java.lang.Object topicName_ = ""; /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; - * @return The batch. + * string topicName = 2; + * @return The topicName. */ - public io.seldon.mlops.chainer.ChainerOuterClass.Batch getBatch() { - if (batchBuilder_ == null) { - return batch_ == null ? io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; + public java.lang.String getTopicName() { + java.lang.Object ref = topicName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + topicName_ = s; + return s; } else { - return batchBuilder_.getMessage(); + return (java.lang.String) ref; } } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string topicName = 2; + * @return The bytes for topicName. */ - public Builder setBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { - if (batchBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - batch_ = value; + public com.google.protobuf.ByteString + getTopicNameBytes() { + java.lang.Object ref = topicName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + topicName_ = b; + return b; } else { - batchBuilder_.setMessage(value); + return (com.google.protobuf.ByteString) ref; } - bitField0_ |= 0x00000100; - onChanged(); - return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string topicName = 2; + * @param value The topicName to set. + * @return This builder for chaining. */ - public Builder setBatch( - io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder builderForValue) { - if (batchBuilder_ == null) { - batch_ = builderForValue.build(); - } else { - batchBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000100; + public Builder setTopicName( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + topicName_ = value; + bitField0_ |= 0x00000002; onChanged(); return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string topicName = 2; + * @return This builder for chaining. */ - public Builder mergeBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { - if (batchBuilder_ == null) { - if (((bitField0_ & 0x00000100) != 0) && - batch_ != null && - batch_ != io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance()) { - getBatchBuilder().mergeFrom(value); - } else { - batch_ = value; - } - } else { - batchBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000100; + public Builder clearTopicName() { + topicName_ = getDefaultInstance().getTopicName(); + bitField0_ = (bitField0_ & ~0x00000002); onChanged(); return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string topicName = 2; + * @param value The bytes for topicName to set. + * @return This builder for chaining. */ - public Builder clearBatch() { - bitField0_ = (bitField0_ & ~0x00000100); - batch_ = null; - if (batchBuilder_ != null) { - batchBuilder_.dispose(); - batchBuilder_ = null; - } + public Builder setTopicNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + topicName_ = value; + bitField0_ |= 0x00000002; onChanged(); return this; } - /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; - */ - public io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder getBatchBuilder() { - bitField0_ |= 0x00000100; - onChanged(); - return getBatchFieldBuilder().getBuilder(); - } - /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; - */ - public io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder getBatchOrBuilder() { - if (batchBuilder_ != null) { - return batchBuilder_.getMessageOrBuilder(); - } else { - return batch_ == null ? - io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; - } - } - /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; - */ - private com.google.protobuf.SingleFieldBuilderV3< - io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> - getBatchFieldBuilder() { - if (batchBuilder_ == null) { - batchBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder>( - getBatch(), - getParentForChildren(), - isClean()); - batch_ = null; - } - return batchBuilder_; - } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -4162,23 +5315,23 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:seldon.mlops.chainer.PipelineStepUpdate) + // @@protoc_insertion_point(builder_scope:seldon.mlops.chainer.PipelineTopic) } - // @@protoc_insertion_point(class_scope:seldon.mlops.chainer.PipelineStepUpdate) - private static final io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:seldon.mlops.chainer.PipelineTopic) + private static final io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate(); + DEFAULT_INSTANCE = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic(); } - public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstance() { + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getDefaultInstance() { return DEFAULT_INSTANCE; } - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public PipelineStepUpdate parsePartialFrom( + public PipelineTopic parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -4197,17 +5350,17 @@ public PipelineStepUpdate parsePartialFrom( } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstanceForType() { + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -6198,6 +7351,11 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineUpdateStatusResponse ge private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_seldon_mlops_chainer_PipelineTopic_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_seldon_mlops_chainer_PipelineTopic_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_seldon_mlops_chainer_Batch_descriptor; private static final @@ -6230,36 +7388,40 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineUpdateStatusResponse ge "\t\022\017\n\007version\030\003 \001(\r\022\013\n\003uid\030\004 \001(\t\0229\n\007updat" + "es\030\005 \003(\0132(.seldon.mlops.chainer.Pipeline" + "StepUpdate\"8\n\021PipelineOperation\022\013\n\007Unkno" + - "wn\020\000\022\n\n\006Create\020\001\022\n\n\006Delete\020\002\"\232\004\n\022Pipelin" + - "eStepUpdate\022\017\n\007sources\030\001 \003(\t\022\020\n\010triggers" + - "\030\002 \003(\t\022\014\n\004sink\030\003 \001(\t\022N\n\013inputJoinTy\030\004 \001(" + - "\01629.seldon.mlops.chainer.PipelineStepUpd" + - "ate.PipelineJoinType\022Q\n\016triggersJoinTy\030\005" + - " \001(\01629.seldon.mlops.chainer.PipelineStep" + - "Update.PipelineJoinType\022\032\n\022passEmptyResp" + - "onses\030\006 \001(\010\022\031\n\014joinWindowMs\030\007 \001(\rH\000\210\001\001\022J" + - "\n\ttensorMap\030\010 \003(\01327.seldon.mlops.chainer" + - ".PipelineStepUpdate.TensorMapEntry\022*\n\005ba" + - "tch\030\t \001(\0132\033.seldon.mlops.chainer.Batch\0320" + - "\n\016TensorMapEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002" + - " \001(\t:\0028\001\">\n\020PipelineJoinType\022\013\n\007Unknown\020" + - "\000\022\t\n\005Inner\020\001\022\t\n\005Outer\020\002\022\007\n\003Any\020\003B\017\n\r_joi" + - "nWindowMs\"X\n\005Batch\022\021\n\004size\030\001 \001(\rH\000\210\001\001\022\025\n" + - "\010windowMs\030\002 \001(\rH\001\210\001\001\022\017\n\007rolling\030\003 \001(\010B\007\n" + - "\005_sizeB\013\n\t_windowMs\"{\n\033PipelineUpdateSta" + - "tusMessage\022;\n\006update\030\001 \001(\0132+.seldon.mlop" + - "s.chainer.PipelineUpdateMessage\022\017\n\007succe" + - "ss\030\002 \001(\010\022\016\n\006reason\030\003 \001(\t\"\036\n\034PipelineUpda" + - "teStatusResponse2\211\002\n\007Chainer\022~\n\030Subscrib" + - "ePipelineUpdates\0221.seldon.mlops.chainer." + - "PipelineSubscriptionRequest\032+.seldon.mlo" + - "ps.chainer.PipelineUpdateMessage\"\0000\001\022~\n\023" + - "PipelineUpdateEvent\0221.seldon.mlops.chain" + - "er.PipelineUpdateStatusMessage\0322.seldon." + - "mlops.chainer.PipelineUpdateStatusRespon" + - "se\"\000BS\n\027io.seldon.mlops.chainerZ8github." + - "com/seldonio/seldon-core/apis/go/v2/mlop" + - "s/chainerb\006proto3" + "wn\020\000\022\n\n\006Create\020\001\022\n\n\006Delete\020\002\"\211\005\n\022Pipelin" + + "eStepUpdate\0224\n\007sources\030\001 \003(\0132#.seldon.ml" + + "ops.chainer.PipelineTopic\0225\n\010triggers\030\002 " + + "\003(\0132#.seldon.mlops.chainer.PipelineTopic" + + "\0221\n\004sink\030\003 \001(\0132#.seldon.mlops.chainer.Pi" + + "pelineTopic\022N\n\013inputJoinTy\030\004 \001(\01629.seldo" + + "n.mlops.chainer.PipelineStepUpdate.Pipel" + + "ineJoinType\022Q\n\016triggersJoinTy\030\005 \001(\01629.se" + + "ldon.mlops.chainer.PipelineStepUpdate.Pi" + + "pelineJoinType\022\032\n\022passEmptyResponses\030\006 \001" + + "(\010\022\031\n\014joinWindowMs\030\007 \001(\rH\000\210\001\001\022J\n\ttensorM" + + "ap\030\010 \003(\01327.seldon.mlops.chainer.Pipeline" + + "StepUpdate.TensorMapEntry\022*\n\005batch\030\t \001(\013" + + "2\033.seldon.mlops.chainer.Batch\0320\n\016TensorM" + + "apEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"" + + ">\n\020PipelineJoinType\022\013\n\007Unknown\020\000\022\t\n\005Inne" + + "r\020\001\022\t\n\005Outer\020\002\022\007\n\003Any\020\003B\017\n\r_joinWindowMs" + + "\"8\n\rPipelineTopic\022\024\n\014pipelineName\030\001 \001(\t\022" + + "\021\n\ttopicName\030\002 \001(\t\"X\n\005Batch\022\021\n\004size\030\001 \001(" + + "\rH\000\210\001\001\022\025\n\010windowMs\030\002 \001(\rH\001\210\001\001\022\017\n\007rolling" + + "\030\003 \001(\010B\007\n\005_sizeB\013\n\t_windowMs\"{\n\033Pipeline" + + "UpdateStatusMessage\022;\n\006update\030\001 \001(\0132+.se" + + "ldon.mlops.chainer.PipelineUpdateMessage" + + "\022\017\n\007success\030\002 \001(\010\022\016\n\006reason\030\003 \001(\t\"\036\n\034Pip" + + "elineUpdateStatusResponse2\211\002\n\007Chainer\022~\n" + + "\030SubscribePipelineUpdates\0221.seldon.mlops" + + ".chainer.PipelineSubscriptionRequest\032+.s" + + "eldon.mlops.chainer.PipelineUpdateMessag" + + "e\"\0000\001\022~\n\023PipelineUpdateEvent\0221.seldon.ml" + + "ops.chainer.PipelineUpdateStatusMessage\032" + + "2.seldon.mlops.chainer.PipelineUpdateSta" + + "tusResponse\"\000BS\n\027io.seldon.mlops.chainer" + + "Z8github.com/seldonio/seldon-core/apis/g" + + "o/v2/mlops/chainerb\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -6289,20 +7451,26 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineUpdateStatusResponse ge com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_descriptor, new java.lang.String[] { "Key", "Value", }); - internal_static_seldon_mlops_chainer_Batch_descriptor = + internal_static_seldon_mlops_chainer_PipelineTopic_descriptor = getDescriptor().getMessageTypes().get(3); + internal_static_seldon_mlops_chainer_PipelineTopic_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_seldon_mlops_chainer_PipelineTopic_descriptor, + new java.lang.String[] { "PipelineName", "TopicName", }); + internal_static_seldon_mlops_chainer_Batch_descriptor = + getDescriptor().getMessageTypes().get(4); internal_static_seldon_mlops_chainer_Batch_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_Batch_descriptor, new java.lang.String[] { "Size", "WindowMs", "Rolling", "Size", "WindowMs", }); internal_static_seldon_mlops_chainer_PipelineUpdateStatusMessage_descriptor = - getDescriptor().getMessageTypes().get(4); + getDescriptor().getMessageTypes().get(5); internal_static_seldon_mlops_chainer_PipelineUpdateStatusMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_PipelineUpdateStatusMessage_descriptor, new java.lang.String[] { "Update", "Success", "Reason", }); internal_static_seldon_mlops_chainer_PipelineUpdateStatusResponse_descriptor = - getDescriptor().getMessageTypes().get(5); + getDescriptor().getMessageTypes().get(6); internal_static_seldon_mlops_chainer_PipelineUpdateStatusResponse_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_PipelineUpdateStatusResponse_descriptor, diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassGrpcKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassGrpcKt.kt index c837e55f3d..fc624c176e 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassGrpcKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassGrpcKt.kt @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - package io.seldon.mlops.chainer import io.grpc.CallOptions diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassKt.kt index 54a4840430..e69de29bb2 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClassKt.kt @@ -1,16 +0,0 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt index e57358f2c3..60c053d5af 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - //Generated by the protocol buffer compiler. DO NOT EDIT! // source: chainer.proto @@ -51,10 +35,9 @@ public object PipelineStepUpdateKt { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; - * @return A list containing the sources. + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ - public val sources: com.google.protobuf.kotlin.DslList + public val sources: com.google.protobuf.kotlin.DslList @kotlin.jvm.JvmSynthetic get() = com.google.protobuf.kotlin.DslList( _builder.getSourcesList() @@ -66,12 +49,12 @@ public object PipelineStepUpdateKt { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; * @param value The sources to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("addSources") - public fun com.google.protobuf.kotlin.DslList.add(value: kotlin.String) { + public fun com.google.protobuf.kotlin.DslList.add(value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) { _builder.addSources(value) } /** @@ -81,13 +64,13 @@ public object PipelineStepUpdateKt { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; * @param value The sources to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("plusAssignSources") @Suppress("NOTHING_TO_INLINE") - public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: kotlin.String) { + public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) { add(value) } /** @@ -97,12 +80,12 @@ public object PipelineStepUpdateKt { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; * @param values The sources to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("addAllSources") - public fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { + public fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { _builder.addAllSources(values) } /** @@ -112,13 +95,13 @@ public object PipelineStepUpdateKt { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; * @param values The sources to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("plusAssignAllSources") @Suppress("NOTHING_TO_INLINE") - public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { + public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { addAll(values) } /** @@ -128,28 +111,31 @@ public object PipelineStepUpdateKt { * seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name> * * - * repeated string sources = 1; + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; * @param index The index to set the value at. * @param value The sources to set. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("setSources") - public operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: kotlin.String) { + public operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) { _builder.setSources(index, value) - }/** + } + /** *
      * https://docs.google.com/document/d/1tX-uaOvngx1RpEyWEZ4EbEcU8D0OgYuRWVb2UAi85n4/edit
      * Pipeline Resource example, e.g. transform.outputs.traffic
      *    seldon.<namespace>.<model name>.<inputs|outputs>.<tensor name>
      * 
* - * repeated string sources = 1; + * repeated .seldon.mlops.chainer.PipelineTopic sources = 1; */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("clearSources") - public fun com.google.protobuf.kotlin.DslList.clear() { + public fun com.google.protobuf.kotlin.DslList.clear() { _builder.clearSources() } + + /** * An uninstantiable, behaviorless type to represent the field in * generics. @@ -157,73 +143,75 @@ public object PipelineStepUpdateKt { @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) public class TriggersProxy private constructor() : com.google.protobuf.kotlin.DslProxy() /** - * repeated string triggers = 2; - * @return A list containing the triggers. + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ - public val triggers: com.google.protobuf.kotlin.DslList + public val triggers: com.google.protobuf.kotlin.DslList @kotlin.jvm.JvmSynthetic get() = com.google.protobuf.kotlin.DslList( _builder.getTriggersList() ) /** - * repeated string triggers = 2; + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; * @param value The triggers to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("addTriggers") - public fun com.google.protobuf.kotlin.DslList.add(value: kotlin.String) { + public fun com.google.protobuf.kotlin.DslList.add(value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) { _builder.addTriggers(value) } /** - * repeated string triggers = 2; + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; * @param value The triggers to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("plusAssignTriggers") @Suppress("NOTHING_TO_INLINE") - public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: kotlin.String) { + public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) { add(value) } /** - * repeated string triggers = 2; + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; * @param values The triggers to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("addAllTriggers") - public fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { + public fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { _builder.addAllTriggers(values) } /** - * repeated string triggers = 2; + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; * @param values The triggers to add. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("plusAssignAllTriggers") @Suppress("NOTHING_TO_INLINE") - public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { + public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { addAll(values) } /** - * repeated string triggers = 2; + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; * @param index The index to set the value at. * @param value The triggers to set. */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("setTriggers") - public operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: kotlin.String) { + public operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic) { _builder.setTriggers(index, value) - }/** - * repeated string triggers = 2; + } + /** + * repeated .seldon.mlops.chainer.PipelineTopic triggers = 2; */ @kotlin.jvm.JvmSynthetic @kotlin.jvm.JvmName("clearTriggers") - public fun com.google.protobuf.kotlin.DslList.clear() { + public fun com.google.protobuf.kotlin.DslList.clear() { _builder.clearTriggers() } + + /** - * string sink = 3; + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ - public var sink: kotlin.String + public var sink: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic @JvmName("getSink") get() = _builder.getSink() @JvmName("setSink") @@ -231,11 +219,18 @@ public object PipelineStepUpdateKt { _builder.setSink(value) } /** - * string sink = 3; + * .seldon.mlops.chainer.PipelineTopic sink = 3; */ public fun clearSink() { _builder.clearSink() } + /** + * .seldon.mlops.chainer.PipelineTopic sink = 3; + * @return Whether the sink field is set. + */ + public fun hasSink(): kotlin.Boolean { + return _builder.hasSink() + } /** * .seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType inputJoinTy = 4; @@ -458,6 +453,9 @@ public object PipelineStepUpdateKt { public inline fun io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate.copy(block: io.seldon.mlops.chainer.PipelineStepUpdateKt.Dsl.() -> kotlin.Unit): io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate = io.seldon.mlops.chainer.PipelineStepUpdateKt.Dsl._create(this.toBuilder()).apply { block() }._build() +public val io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdateOrBuilder.sinkOrNull: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic? + get() = if (hasSink()) getSink() else null + public val io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdateOrBuilder.batchOrNull: io.seldon.mlops.chainer.ChainerOuterClass.Batch? get() = if (hasBatch()) getBatch() else null diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineSubscriptionRequestKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineSubscriptionRequestKt.kt index eab28a5cfe..63ade8cb35 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineSubscriptionRequestKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineSubscriptionRequestKt.kt @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - //Generated by the protocol buffer compiler. DO NOT EDIT! // source: chainer.proto diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTopicKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTopicKt.kt new file mode 100644 index 0000000000..a483f5a2f2 --- /dev/null +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTopicKt.kt @@ -0,0 +1,63 @@ +//Generated by the protocol buffer compiler. DO NOT EDIT! +// source: chainer.proto + +package io.seldon.mlops.chainer; + +@kotlin.jvm.JvmName("-initializepipelineTopic") +public inline fun pipelineTopic(block: io.seldon.mlops.chainer.PipelineTopicKt.Dsl.() -> kotlin.Unit): io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic = + io.seldon.mlops.chainer.PipelineTopicKt.Dsl._create(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.newBuilder()).apply { block() }._build() +public object PipelineTopicKt { + @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class) + @com.google.protobuf.kotlin.ProtoDslMarker + public class Dsl private constructor( + private val _builder: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder + ) { + public companion object { + @kotlin.jvm.JvmSynthetic + @kotlin.PublishedApi + internal fun _create(builder: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.Builder): Dsl = Dsl(builder) + } + + @kotlin.jvm.JvmSynthetic + @kotlin.PublishedApi + internal fun _build(): io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic = _builder.build() + + /** + * string pipelineName = 1; + */ + public var pipelineName: kotlin.String + @JvmName("getPipelineName") + get() = _builder.getPipelineName() + @JvmName("setPipelineName") + set(value) { + _builder.setPipelineName(value) + } + /** + * string pipelineName = 1; + */ + public fun clearPipelineName() { + _builder.clearPipelineName() + } + + /** + * string topicName = 2; + */ + public var topicName: kotlin.String + @JvmName("getTopicName") + get() = _builder.getTopicName() + @JvmName("setTopicName") + set(value) { + _builder.setTopicName(value) + } + /** + * string topicName = 2; + */ + public fun clearTopicName() { + _builder.clearTopicName() + } + } +} +@kotlin.jvm.JvmSynthetic +public inline fun io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic.copy(block: io.seldon.mlops.chainer.PipelineTopicKt.Dsl.() -> kotlin.Unit): io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic = + io.seldon.mlops.chainer.PipelineTopicKt.Dsl._create(this.toBuilder()).apply { block() }._build() + diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateMessageKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateMessageKt.kt index 364823cefd..661d89ef4e 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateMessageKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateMessageKt.kt @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - //Generated by the protocol buffer compiler. DO NOT EDIT! // source: chainer.proto diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusMessageKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusMessageKt.kt index 00390cd293..3e2fc47f60 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusMessageKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusMessageKt.kt @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - //Generated by the protocol buffer compiler. DO NOT EDIT! // source: chainer.proto diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusResponseKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusResponseKt.kt index 86d19d7242..9da131e4c9 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusResponseKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineUpdateStatusResponseKt.kt @@ -1,19 +1,3 @@ -/* -Copyright 2022 Seldon Technologies Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - //Generated by the protocol buffer compiler. DO NOT EDIT! // source: chainer.proto diff --git a/apis/mlops/scheduler/scheduler.proto b/apis/mlops/scheduler/scheduler.proto index 8cc5e58cc8..5a71137f8b 100644 --- a/apis/mlops/scheduler/scheduler.proto +++ b/apis/mlops/scheduler/scheduler.proto @@ -273,6 +273,7 @@ message Pipeline { repeated PipelineStep steps = 4; optional PipelineOutput output = 5; optional KubernetesMeta kubernetesMeta = 6; + optional PipelineInput input = 7; } message PipelineStep { @@ -296,6 +297,20 @@ message Batch { optional uint32 windowMs = 2; } +message PipelineInput { + enum JoinOp { + INNER = 0; + OUTER = 1; + ANY = 2; + } + repeated string externalInputs = 1; + repeated string externalTriggers = 2; + optional uint32 joinWindowMs = 3; // Join window millisecs for output, default 0 + JoinOp joinType = 4; + JoinOp triggersJoin = 5; + map tensorMap = 6; // optional map of tensor name mappings +} + message PipelineOutput { enum JoinOp { INNER = 0; diff --git a/operator/apis/mlops/v1alpha1/pipeline_types.go b/operator/apis/mlops/v1alpha1/pipeline_types.go index 46bfed034f..b9e5a2a954 100644 --- a/operator/apis/mlops/v1alpha1/pipeline_types.go +++ b/operator/apis/mlops/v1alpha1/pipeline_types.go @@ -26,8 +26,11 @@ import ( // PipelineSpec defines the desired state of Pipeline type PipelineSpec struct { + // External inputs to this pipeline, optional + Input *PipelineInput `json:"input,omitempty"` // The steps of this inference graph pipeline - Steps []PipelineStep `json:"steps"` + Steps []PipelineStep `json:"steps"` + // Synchronous output from this pipeline, optional Output *PipelineOutput `json:"output,omitempty"` } @@ -67,6 +70,21 @@ type PipelineBatch struct { Rolling bool `json:"rolling,omitempty"` } +type PipelineInput struct { + // Previous external pipeline steps to receive data from + ExternalInputs []string `json:"externalInputs,omitempty"` + // Triggers required to activate inputs + ExternalTriggers []string `json:"externalTriggers,omitempty"` + // msecs to wait for messages from multiple inputs to arrive before joining the inputs + JoinWindowMs *uint32 `json:"joinWindowMs,omitempty"` + // One of inner (default), outer, or any (see above for details) + JoinType *JoinType `json:"joinType,omitempty"` + // One of inner (default), outer, or any (see above for details) + TriggersJoinType *JoinType `json:"triggersJoinType,omitempty"` + // Map of tensor name conversions to use e.g. output1 -> input1 + TensorMap map[string]string `json:"tensorMap,omitempty"` +} + type PipelineOutput struct { // Previous step to receive data from Steps []string `json:"steps,omitempty"` @@ -112,6 +130,39 @@ func init() { func (p Pipeline) AsSchedulerPipeline() *scheduler.Pipeline { var steps []*scheduler.PipelineStep var output *scheduler.PipelineOutput + var input *scheduler.PipelineInput + if p.Spec.Input != nil { + input = &scheduler.PipelineInput{ + ExternalInputs: p.Spec.Input.ExternalInputs, + ExternalTriggers: p.Spec.Input.ExternalTriggers, + JoinWindowMs: p.Spec.Input.JoinWindowMs, + TensorMap: p.Spec.Input.TensorMap, + } + if p.Spec.Input.JoinType != nil { + switch *p.Spec.Input.JoinType { + case JoinTypeInner: + input.JoinType = scheduler.PipelineInput_INNER + case JoinTypeOuter: + input.JoinType = scheduler.PipelineInput_OUTER + case JoinTypeAny: + input.JoinType = scheduler.PipelineInput_ANY + default: + input.JoinType = scheduler.PipelineInput_INNER + } + } + if p.Spec.Input.TriggersJoinType != nil { + switch *p.Spec.Input.TriggersJoinType { + case JoinTypeInner: + input.TriggersJoin = scheduler.PipelineInput_INNER + case JoinTypeOuter: + input.TriggersJoin = scheduler.PipelineInput_OUTER + case JoinTypeAny: + input.TriggersJoin = scheduler.PipelineInput_ANY + default: + input.TriggersJoin = scheduler.PipelineInput_INNER + } + } + } for _, step := range p.Spec.Steps { pipelineStep := &scheduler.PipelineStep{ Name: step.Name, @@ -174,6 +225,7 @@ func (p Pipeline) AsSchedulerPipeline() *scheduler.Pipeline { return &scheduler.Pipeline{ Name: p.GetName(), Uid: "", // ID Will be set on scheduler side. IDs don't change on k8s when updates are made so can't use it for each version + Input: input, Steps: steps, Output: output, KubernetesMeta: &scheduler.KubernetesMeta{Namespace: p.Namespace, Generation: p.Generation}, diff --git a/operator/apis/mlops/v1alpha1/zz_generated.deepcopy.go b/operator/apis/mlops/v1alpha1/zz_generated.deepcopy.go index 6a7aca189d..92c0a5f927 100644 --- a/operator/apis/mlops/v1alpha1/zz_generated.deepcopy.go +++ b/operator/apis/mlops/v1alpha1/zz_generated.deepcopy.go @@ -486,6 +486,53 @@ func (in *PipelineBatch) DeepCopy() *PipelineBatch { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PipelineInput) DeepCopyInto(out *PipelineInput) { + *out = *in + if in.ExternalInputs != nil { + in, out := &in.ExternalInputs, &out.ExternalInputs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ExternalTriggers != nil { + in, out := &in.ExternalTriggers, &out.ExternalTriggers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.JoinWindowMs != nil { + in, out := &in.JoinWindowMs, &out.JoinWindowMs + *out = new(uint32) + **out = **in + } + if in.JoinType != nil { + in, out := &in.JoinType, &out.JoinType + *out = new(JoinType) + **out = **in + } + if in.TriggersJoinType != nil { + in, out := &in.TriggersJoinType, &out.TriggersJoinType + *out = new(JoinType) + **out = **in + } + if in.TensorMap != nil { + in, out := &in.TensorMap, &out.TensorMap + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PipelineInput. +func (in *PipelineInput) DeepCopy() *PipelineInput { + if in == nil { + return nil + } + out := new(PipelineInput) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PipelineList) DeepCopyInto(out *PipelineList) { *out = *in @@ -553,6 +600,11 @@ func (in *PipelineOutput) DeepCopy() *PipelineOutput { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PipelineSpec) DeepCopyInto(out *PipelineSpec) { *out = *in + if in.Input != nil { + in, out := &in.Input, &out.Input + *out = new(PipelineInput) + (*in).DeepCopyInto(*out) + } if in.Steps != nil { in, out := &in.Steps, &out.Steps *out = make([]PipelineStep, len(*in)) diff --git a/samples/multiple-pipelines.ipynb b/samples/multiple-pipelines.ipynb new file mode 100644 index 0000000000..3a5d253b02 --- /dev/null +++ b/samples/multiple-pipelines.ipynb @@ -0,0 +1,534 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "lesbian-springer", + "metadata": {}, + "source": [ + "## Seldon V2 Pipeline to Pipeline Examples\n", + "\n", + "This notebook illustrates a series of Pipelines that are joined together.\n", + "\n", + "### Models Used\n", + "\n", + " * `gs://seldon-models/triton/simple` an example Triton tensorflow model that takes 2 inputs INPUT0 and INPUT1 and adds them to produce OUTPUT0 and also subtracts INPUT1 from INPUT0 to produce OUTPUT1. See [here](https://github.com/triton-inference-server/server/tree/main/docs/examples/model_repository/simple) for the original source code and license.\n", + " * Other models can be found at https://github.com/SeldonIO/triton-python-examples" + ] + }, + { + "cell_type": "markdown", + "id": "running-antarctica", + "metadata": {}, + "source": [ + "### Pipeline pulling from one other Pipeline\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0f2ab2a3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple1\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple2\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n" + ] + } + ], + "source": [ + "!cat ./models/tfsimple1.yaml\n", + "!cat ./models/tfsimple2.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "f9e073d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model load -f ./models/tfsimple1.yaml \n", + "!seldon model load -f ./models/tfsimple2.yaml " + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "997b4028", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model status tfsimple1 -w ModelAvailable | jq -M .\n", + "!seldon model status tfsimple2 -w ModelAvailable | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "3d017ede", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple\r\n", + "spec:\r\n", + " steps:\r\n", + " - name: tfsimple1\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple1\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "following-winning", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "artistic-kentucky", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple\",\r\n", + " \"uid\": \"ceb2jt37778s739emas0\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple1\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple1.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {}\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-11T19:05:24.983237899Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "87f10a5c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"model_name\": \"\",\r\n", + " \"outputs\": [\r\n", + " {\r\n", + " \"data\": [\r\n", + " 2,\r\n", + " 4,\r\n", + " 6,\r\n", + " 8,\r\n", + " 10,\r\n", + " 12,\r\n", + " 14,\r\n", + " 16,\r\n", + " 18,\r\n", + " 20,\r\n", + " 22,\r\n", + " 24,\r\n", + " 26,\r\n", + " 28,\r\n", + " 30,\r\n", + " 32\r\n", + " ],\r\n", + " \"name\": \"OUTPUT0\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " },\r\n", + " {\r\n", + " \"data\": [\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0\r\n", + " ],\r\n", + " \"name\": \"OUTPUT1\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "748d3f68", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple-extended\r\n", + "spec:\r\n", + " input:\r\n", + " externalInputs:\r\n", + " - tfsimple.outputs\r\n", + " tensorMap:\r\n", + " tfsimple.outputs.OUTPUT0: INPUT0\r\n", + " tfsimple.outputs.OUTPUT1: INPUT1\r\n", + " steps:\r\n", + " - name: tfsimple2\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple2\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple-extended.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "2e2b275c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "7410e21f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple-extended\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple-extended\",\r\n", + " \"uid\": \"ceb2jub7778s739emasg\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple2\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple2.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {},\r\n", + " \"input\": {\r\n", + " \"externalInputs\": [\r\n", + " \"tfsimple.outputs\"\r\n", + " ],\r\n", + " \"tensorMap\": {\r\n", + " \"tfsimple.outputs.OUTPUT0\": \"INPUT0\",\r\n", + " \"tfsimple.outputs.OUTPUT1\": \"INPUT1\"\r\n", + " }\r\n", + " }\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-11T19:05:29.772617037Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple-extended -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "41f58a7d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"model_name\": \"\",\r\n", + " \"outputs\": [\r\n", + " {\r\n", + " \"data\": [\r\n", + " 2,\r\n", + " 4,\r\n", + " 6,\r\n", + " 8,\r\n", + " 10,\r\n", + " 12,\r\n", + " 14,\r\n", + " 16,\r\n", + " 18,\r\n", + " 20,\r\n", + " 22,\r\n", + " 24,\r\n", + " 26,\r\n", + " 28,\r\n", + " 30,\r\n", + " 32\r\n", + " ],\r\n", + " \"name\": \"OUTPUT0\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " },\r\n", + " {\r\n", + " \"data\": [\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0\r\n", + " ],\r\n", + " \"name\": \"OUTPUT1\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "44f69abb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\tceb2jv5mlqdc7398nsu0\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-1b7b594c742bc3db-01\r\n", + "seldon.default.model.tfsimple2.outputs\tceb2jv5mlqdc7398nsu0\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-a1aba81e7ebf0398-01\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tceb2jv5mlqdc7398nsu0\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-9e6954a3b7387bd7-01\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tceb2jv5mlqdc7398nsu0\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-6170594b79633430-01\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "dimensional-hours", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline unload tfsimple-extended\n", + "!seldon pipeline unload tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "outside-inspiration", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model unload tfsimple1\n", + "!seldon model unload tfsimple2" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/samples/pipeline-examples.ipynb b/samples/pipeline-examples.ipynb index cda698f761..62b8c7f149 100644 --- a/samples/pipeline-examples.ipynb +++ b/samples/pipeline-examples.ipynb @@ -178,7 +178,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimples\",\r\n", - " \"uid\": \"cdqjijpqa12c739ab3p0\",\r\n", + " \"uid\": \"ceb1joj3gshc73fmvpu0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -206,7 +206,8 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-11-16T19:26:08.037067065Z\"\r\n", + " \"lastChangeTimestamp\": \"2022-12-11T17:56:51.471467841Z\",\r\n", + " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", " ]\r\n", @@ -412,7 +413,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "10b5bca0", "metadata": {}, "outputs": [ @@ -489,7 +490,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "dimensional-hours", "metadata": {}, "outputs": [ @@ -507,7 +508,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "outside-inspiration", "metadata": {}, "outputs": [ @@ -537,7 +538,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "id": "5e41768d", "metadata": {}, "outputs": [ @@ -587,7 +588,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "id": "fcbc23cc", "metadata": {}, "outputs": [ @@ -609,7 +610,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "id": "f8bb2efb", "metadata": {}, "outputs": [ @@ -639,7 +640,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "id": "cd58ecba", "metadata": {}, "outputs": [ @@ -674,7 +675,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "id": "ce9e163b", "metadata": {}, "outputs": [ @@ -692,7 +693,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "id": "7593c77f", "metadata": {}, "outputs": [ @@ -706,7 +707,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"join\",\r\n", - " \"uid\": \"cdqjit1qa12c739ab3pg\",\r\n", + " \"uid\": \"ceb1k1r3gshc73fmvpug\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -738,7 +739,8 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-11-16T19:26:44.706282241Z\"\r\n", + " \"lastChangeTimestamp\": \"2022-12-11T17:57:27.599682702Z\",\r\n", + " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", " ]\r\n", @@ -760,7 +762,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "id": "2151ee4c", "metadata": { "scrolled": true @@ -840,7 +842,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "id": "06575cca", "metadata": {}, "outputs": [ @@ -858,7 +860,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "id": "8bd56a9c", "metadata": {}, "outputs": [ @@ -890,7 +892,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "id": "e3a2c7f3", "metadata": {}, "outputs": [ @@ -940,7 +942,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "id": "2104f9bf", "metadata": {}, "outputs": [ @@ -962,7 +964,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "id": "7af88e3a", "metadata": {}, "outputs": [ @@ -992,7 +994,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "id": "f5bbe84d", "metadata": {}, "outputs": [ @@ -1031,7 +1033,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "id": "829f9b18", "metadata": {}, "outputs": [ @@ -1049,7 +1051,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "id": "ae202d26", "metadata": {}, "outputs": [ @@ -1063,7 +1065,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple-conditional\",\r\n", - " \"uid\": \"cdqjj21qa12c739ab3q0\",\r\n", + " \"uid\": \"ceb1k7j3gshc73fmvpv0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -1101,7 +1103,8 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-11-16T19:27:04.928498607Z\"\r\n", + " \"lastChangeTimestamp\": \"2022-12-11T17:57:50.612064319Z\",\r\n", + " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", " ]\r\n", @@ -1123,7 +1126,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "id": "0d03d5fe", "metadata": {}, "outputs": [ @@ -1168,7 +1171,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "id": "def4e8e1", "metadata": {}, "outputs": [ @@ -1205,7 +1208,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "id": "3042fe42", "metadata": {}, "outputs": [ @@ -1223,7 +1226,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "id": "3bda8710", "metadata": {}, "outputs": [ @@ -1254,7 +1257,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "id": "baa2cb5f", "metadata": { "scrolled": true @@ -1294,7 +1297,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "id": "33692146", "metadata": {}, "outputs": [ @@ -1314,7 +1317,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "id": "e0493925", "metadata": {}, "outputs": [ @@ -1342,7 +1345,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "id": "c8d27ff3", "metadata": {}, "outputs": [ @@ -1380,7 +1383,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "id": "74768602", "metadata": {}, "outputs": [ @@ -1398,7 +1401,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "id": "922b975e", "metadata": {}, "outputs": [ @@ -1412,7 +1415,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"pipeline-inputs\",\r\n", - " \"uid\": \"cdqjj89qa12c739ab3qg\",\r\n", + " \"uid\": \"ceb1kcj3gshc73fmvpvg\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -1446,7 +1449,8 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-11-16T19:27:30.024128982Z\"\r\n", + " \"lastChangeTimestamp\": \"2022-12-11T17:58:11.137492043Z\",\r\n", + " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", " ]\r\n", @@ -1460,7 +1464,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "id": "792680b5", "metadata": {}, "outputs": [ @@ -1512,7 +1516,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 38, "id": "d6fd0d45", "metadata": {}, "outputs": [ @@ -1530,7 +1534,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 39, "id": "3d5bb23c", "metadata": {}, "outputs": [ @@ -1560,7 +1564,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "id": "1a09de5c", "metadata": { "scrolled": true @@ -1598,7 +1602,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 41, "id": "85eb4ef2", "metadata": {}, "outputs": [ @@ -1618,7 +1622,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 42, "id": "d11e29c6", "metadata": {}, "outputs": [ @@ -1646,7 +1650,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 43, "id": "227e06e4", "metadata": {}, "outputs": [ @@ -1686,7 +1690,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 44, "id": "2bce48e8", "metadata": {}, "outputs": [ @@ -1704,7 +1708,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 45, "id": "66c60286", "metadata": {}, "outputs": [ @@ -1718,7 +1722,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"trigger-joins\",\r\n", - " \"uid\": \"cdqjjdpqa12c739ab3r0\",\r\n", + " \"uid\": \"ceb1khb3gshc73fmvq00\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -1755,7 +1759,8 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-11-16T19:27:51.550445363Z\"\r\n", + " \"lastChangeTimestamp\": \"2022-12-11T17:58:30.105358917Z\",\r\n", + " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", " ]\r\n", @@ -1769,7 +1774,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 46, "id": "403fcbd5", "metadata": {}, "outputs": [ @@ -1806,7 +1811,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 47, "id": "fdba4c3c", "metadata": {}, "outputs": [ @@ -1843,7 +1848,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 48, "id": "52a2bfd0", "metadata": {}, "outputs": [ @@ -1861,7 +1866,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 49, "id": "914d23f5", "metadata": {}, "outputs": [ diff --git a/samples/pipelines/tfsimple-extended.yaml b/samples/pipelines/tfsimple-extended.yaml new file mode 100644 index 0000000000..2b5fde43d0 --- /dev/null +++ b/samples/pipelines/tfsimple-extended.yaml @@ -0,0 +1,16 @@ +apiVersion: mlops.seldon.io/v1alpha1 +kind: Pipeline +metadata: + name: tfsimple-extended +spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt index 9a4d89e409..e07a625a44 100644 --- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt +++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt @@ -25,16 +25,16 @@ import org.apache.kafka.streams.StreamsBuilder */ class Chainer( builder: StreamsBuilder, - internal val inputTopic: TopicName, - internal val outputTopic: TopicName, + internal val inputTopic: TopicForPipeline, + internal val outputTopic: TopicForPipeline, internal val tensors: Set?, internal val pipelineName: String, internal val tensorRenaming: Map, internal val batchProperties: ChainerOuterClass.Batch, private val kafkaDomainParams: KafkaDomainParams, - internal val inputTriggerTopics: Set, + internal val inputTriggerTopics: Set, internal val triggerJoinType: ChainerOuterClass.PipelineStepUpdate.PipelineJoinType, - internal val triggerTensorsByTopic: Map>?, + internal val triggerTensorsByTopic: Map>?, ) : PipelineStep { init { builder.apply { @@ -43,7 +43,7 @@ class Chainer( } } - when (ChainType.create(inputTopic, outputTopic)) { + when (ChainType.create(inputTopic.topicName, outputTopic.topicName)) { ChainType.OUTPUT_INPUT -> buildOutputInputStream(builder) ChainType.INPUT_INPUT -> buildInputInputStream(builder) ChainType.OUTPUT_OUTPUT -> buildOutputOutputStream(builder) @@ -57,10 +57,9 @@ class Chainer( private fun buildPassThroughStream(builder: StreamsBuilder) { val s1 = builder - .stream(inputTopic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(inputTopic.topicName, consumerSerde) + .filterForPipeline(inputTopic.pipelineName) addTriggerTopology( - pipelineName, kafkaDomainParams, builder, inputTriggerTopics, @@ -70,20 +69,20 @@ class Chainer( null, ) .headerRemover() - .to(outputTopic, producerSerde) + .headerSetter(pipelineName) + .to(outputTopic.topicName, producerSerde) } private fun buildInputOutputStream(builder: StreamsBuilder) { val s1 = builder - .stream(inputTopic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(inputTopic.topicName, consumerSerde) + .filterForPipeline(inputTopic.pipelineName) .unmarshallInferenceV2Request() - .convertToResponse(inputTopic, tensors, tensorRenaming) + .convertToResponse(inputTopic.topicName, tensors, tensorRenaming) // handle cases where there are no tensors we want .filter { _, value -> value.outputsList.size != 0 } .marshallInferenceV2Response() addTriggerTopology( - pipelineName, kafkaDomainParams, builder, inputTriggerTopics, @@ -93,20 +92,20 @@ class Chainer( null, ) .headerRemover() - .to(outputTopic, producerSerde) + .headerSetter(pipelineName) + .to(outputTopic.topicName, producerSerde) } private fun buildOutputOutputStream(builder: StreamsBuilder) { val s1 = builder - .stream(inputTopic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(inputTopic.topicName, consumerSerde) + .filterForPipeline(inputTopic.pipelineName) .unmarshallInferenceV2Response() - .filterResponses(inputTopic, tensors, tensorRenaming) + .filterResponses(inputTopic.topicName, tensors, tensorRenaming) // handle cases where there are no tensors we want .filter { _, value -> value.outputsList.size != 0 } .marshallInferenceV2Response() addTriggerTopology( - pipelineName, kafkaDomainParams, builder, inputTriggerTopics, @@ -116,21 +115,21 @@ class Chainer( null, ) .headerRemover() - .to(outputTopic, producerSerde) + .headerSetter(pipelineName) + .to(outputTopic.topicName, producerSerde) } private fun buildOutputInputStream(builder: StreamsBuilder) { val s1 = builder - .stream(inputTopic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(inputTopic.topicName, consumerSerde) + .filterForPipeline(inputTopic.pipelineName) .unmarshallInferenceV2Response() - .convertToRequest(inputTopic, tensors, tensorRenaming) + .convertToRequest(inputTopic.topicName, tensors, tensorRenaming) // handle cases where there are no tensors we want .filter { _, value -> value.inputsList.size != 0 } .batchMessages(batchProperties) .marshallInferenceV2Request() addTriggerTopology( - pipelineName, kafkaDomainParams, builder, inputTriggerTopics, @@ -140,21 +139,21 @@ class Chainer( null, ) .headerRemover() - .to(outputTopic, producerSerde) + .headerSetter(pipelineName) + .to(outputTopic.topicName, producerSerde) } private fun buildInputInputStream(builder: StreamsBuilder) { val s1 = builder - .stream(inputTopic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(inputTopic.topicName, consumerSerde) + .filterForPipeline(inputTopic.pipelineName) .unmarshallInferenceV2Request() - .filterRequests(inputTopic, tensors, tensorRenaming) + .filterRequests(inputTopic.topicName, tensors, tensorRenaming) // handle cases where there are no tensors we want .filter { _, value -> value.inputsList.size != 0 } .batchMessages(batchProperties) .marshallInferenceV2Request() addTriggerTopology( - pipelineName, kafkaDomainParams, builder, inputTriggerTopics, @@ -164,7 +163,8 @@ class Chainer( null, ) .headerRemover() - .to(outputTopic, producerSerde) + .headerSetter(pipelineName) + .to(outputTopic.topicName, producerSerde) } companion object { diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt index 028905dc4a..5e1d09b708 100644 --- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt +++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt @@ -29,21 +29,20 @@ import java.time.Duration */ class Joiner( builder: StreamsBuilder, - internal val inputTopics: Set, - internal val outputTopic: TopicName, - internal val tensorsByTopic: Map>?, + internal val inputTopics: Set, + internal val outputTopic: TopicForPipeline, + internal val tensorsByTopic: Map>?, internal val pipelineName: String, internal val tensorRenaming: Map, internal val kafkaDomainParams: KafkaDomainParams, internal val joinType: PipelineJoinType, - internal val inputTriggerTopics: Set, + internal val inputTriggerTopics: Set, internal val triggerJoinType: PipelineJoinType, - internal val triggerTensorsByTopic: Map>?, + internal val triggerTensorsByTopic: Map>?, ) : PipelineStep { init { val dataStream = buildTopology(builder, inputTopics) addTriggerTopology( - pipelineName, kafkaDomainParams, builder, inputTriggerTopics, @@ -53,12 +52,13 @@ class Joiner( null ) .headerRemover() - .to(outputTopic, producerSerde) + .headerSetter(pipelineName) + .to(outputTopic.topicName, producerSerde) } private fun buildTopology( builder: StreamsBuilder, - inputTopics: Set, + inputTopics: Set, pending: KStream? = null, ): KStream { if (inputTopics.isEmpty()) { @@ -70,7 +70,7 @@ class Joiner( val topic = inputTopics.first() - val chainType = ChainType.create(topic, outputTopic) + val chainType = ChainType.create(topic.topicName, outputTopic.topicName) logger.info("Creating stream ${chainType} for ${topic}->${outputTopic}") val nextStream = when (chainType) { ChainType.OUTPUT_INPUT -> buildOutputInputStream(topic, builder) @@ -136,49 +136,49 @@ class Joiner( } } - private fun buildPassThroughStream(topic: String, builder: StreamsBuilder): KStream { + private fun buildPassThroughStream(topic: TopicForPipeline, builder: StreamsBuilder): KStream { return builder - .stream(topic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(topic.topicName, consumerSerde) + .filterForPipeline(topic.pipelineName) } - private fun buildInputOutputStream(topic: String, builder: StreamsBuilder): KStream { + private fun buildInputOutputStream(topic: TopicForPipeline, builder: StreamsBuilder): KStream { return builder - .stream(topic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(topic.topicName, consumerSerde) + .filterForPipeline(topic.pipelineName) .unmarshallInferenceV2Request() - .convertToResponse(topic, tensorsByTopic?.get(topic), tensorRenaming) + .convertToResponse(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming) // handle cases where there are no tensors we want .filter { _, value -> value.outputsList.size != 0 } .marshallInferenceV2Response() } - private fun buildOutputOutputStream(topic: String, builder: StreamsBuilder): KStream { + private fun buildOutputOutputStream(topic: TopicForPipeline, builder: StreamsBuilder): KStream { return builder - .stream(topic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(topic.topicName, consumerSerde) + .filterForPipeline(topic.pipelineName) .unmarshallInferenceV2Response() - .filterResponses(topic, tensorsByTopic?.get(topic), tensorRenaming) + .filterResponses(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming) // handle cases where there are no tensors we want .filter { _, value -> value.outputsList.size != 0 } .marshallInferenceV2Response() } - private fun buildOutputInputStream(topic: String, builder: StreamsBuilder): KStream { + private fun buildOutputInputStream(topic: TopicForPipeline, builder: StreamsBuilder): KStream { return builder - .stream(topic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(topic.topicName, consumerSerde) + .filterForPipeline(topic.pipelineName) .unmarshallInferenceV2Response() - .convertToRequest(topic, tensorsByTopic?.get(topic), tensorRenaming) + .convertToRequest(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming) .marshallInferenceV2Request() } - private fun buildInputInputStream(topic: String, builder: StreamsBuilder): KStream { + private fun buildInputInputStream(topic: TopicForPipeline, builder: StreamsBuilder): KStream { return builder - .stream(topic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(topic.topicName, consumerSerde) + .filterForPipeline(topic.pipelineName) .unmarshallInferenceV2Request() - .filterRequests(topic, tensorsByTopic?.get(topic), tensorRenaming) + .filterRequests(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming) // handle cases where there are no tensors we want .filter { _, value -> value.inputsList.size != 0 } .marshallInferenceV2Request() diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt index a87067de4a..eb8ff13eeb 100644 --- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt +++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt @@ -18,22 +18,28 @@ package io.seldon.dataflow.kafka import io.seldon.mlops.chainer.ChainerOuterClass.Batch import io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate.PipelineJoinType +import io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic import org.apache.kafka.streams.StreamsBuilder interface PipelineStep data class TopicTensors( - val topicName: TopicName, + val topicForPipeline: TopicForPipeline, val tensors: Set, ) +data class TopicForPipeline( + val topicName: TopicName, + val pipelineName: String, +) + fun stepFor( builder: StreamsBuilder, pipelineName: String, - sources: List, - triggerSources: List, + sources: List, + triggerSources: List, tensorMap: Map, - sink: TopicName, + sink: PipelineTopic, joinType: PipelineJoinType, triggerJoinType: PipelineJoinType, batchProperties: Batch, @@ -44,8 +50,8 @@ fun stepFor( is SourceProjection.Empty -> null is SourceProjection.Single -> Chainer( builder, - result.topicName, - sink, + result.topicForPipeline, + TopicForPipeline(topicName = sink.topicName, pipelineName = sink.pipelineName), null, pipelineName, tensorMap, @@ -57,8 +63,8 @@ fun stepFor( ) is SourceProjection.SingleSubset -> Chainer( builder, - result.topicName, - sink, + result.topicForPipeline, + TopicForPipeline(topicName = sink.topicName, pipelineName = sink.pipelineName), result.tensors, pipelineName, tensorMap, @@ -71,7 +77,7 @@ fun stepFor( is SourceProjection.Many -> Joiner( builder, result.topicNames, - sink, + TopicForPipeline(topicName = sink.topicName, pipelineName = sink.pipelineName), null, pipelineName, tensorMap, @@ -84,7 +90,7 @@ fun stepFor( is SourceProjection.ManySubsets -> Joiner( builder, result.tensorsByTopic.keys, - sink, + TopicForPipeline(topicName = sink.topicName, pipelineName = sink.pipelineName), result.tensorsByTopic, pipelineName, tensorMap, @@ -97,63 +103,53 @@ fun stepFor( } } -fun List.areTensorsFromSameTopic(): Pair { - val (topics, tensors) = this - .map { parseSource(it) } - .unzip() - .run { first.toSet() to second.filterNotNull().toSet() } - - if (tensors.isEmpty() || topics.size > 1) return false to (topics to emptySet()) - - return true to (topics to tensors) -} sealed class SourceProjection { object Empty : SourceProjection() - data class Single(val topicName: TopicName) : SourceProjection() - data class SingleSubset(val topicName: TopicName, val tensors: Set) : SourceProjection() - data class Many(val topicNames: Set) : SourceProjection() - data class ManySubsets(val tensorsByTopic: Map>) : SourceProjection() + data class Single(val topicForPipeline: TopicForPipeline) : SourceProjection() + data class SingleSubset(val topicForPipeline: TopicForPipeline, val tensors: Set) : SourceProjection() + data class Many(val topicNames: Set) : SourceProjection() + data class ManySubsets(val tensorsByTopic: Map>) : SourceProjection() } -fun parseTriggers(sources: List): Map> { +fun parseTriggers(sources: List): Map> { return sources .map { parseSource(it) } - .groupBy(keySelector = { it.first }, valueTransform = { it.second }) + .groupBy(keySelector = { it.first+":"+it.third }, valueTransform = { it.second }) .mapValues { it.value.filterNotNull().toSet() } - .map { TopicTensors(it.key, it.value) } - .associate { it.topicName to it.tensors } + .map { TopicTensors(TopicForPipeline(topicName = it.key.split(":")[0], pipelineName = it.key.split(":")[1]), it.value) } + .associate {it.topicForPipeline to it.tensors } } -fun parseSources(sources: List): SourceProjection { +fun parseSources(sources: List): SourceProjection { val topicsAndTensors = sources .map { parseSource(it) } - .groupBy(keySelector = { it.first }, valueTransform = { it.second }) + .groupBy(keySelector = { it.first+":"+it.third }, valueTransform = { it.second }) .mapValues { it.value.filterNotNull().toSet() } - .map { TopicTensors(it.key, it.value) } + .map { TopicTensors(TopicForPipeline(topicName = it.key.split(":")[0], pipelineName = it.key.split(":")[1]), it.value) } return when { topicsAndTensors.isEmpty() -> SourceProjection.Empty topicsAndTensors.size == 1 && topicsAndTensors.first().tensors.isEmpty() -> - SourceProjection.Single(topicsAndTensors.first().topicName) + SourceProjection.Single(topicsAndTensors.first().topicForPipeline) topicsAndTensors.size == 1 -> SourceProjection.SingleSubset( - topicsAndTensors.first().topicName, + topicsAndTensors.first().topicForPipeline, topicsAndTensors.first().tensors, ) topicsAndTensors.all { it.tensors.isEmpty() } -> - SourceProjection.Many(topicsAndTensors.map { it.topicName }.toSet()) + SourceProjection.Many(topicsAndTensors.map { it.topicForPipeline }.toSet()) else -> SourceProjection.ManySubsets( - topicsAndTensors.associate { it.topicName to it.tensors }, + topicsAndTensors.associate { it.topicForPipeline to it.tensors }, ) } } -fun parseSource(source: TopicName): Pair { - return if (source.split(".").size > 5) { - source.substringBeforeLast(".") to source.substringAfterLast(".", "") +fun parseSource(source: PipelineTopic): Triple { + return if (source.topicName.split(".").size > 5 ){ + Triple(source.topicName.substringBeforeLast("."), source.topicName.substringAfterLast(".", ""), source.pipelineName) } else { - source to null + Triple(source.topicName, null, source.pipelineName) } } \ No newline at end of file diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt index 764cf39fc0..358c2874ee 100644 --- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt +++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt @@ -18,6 +18,7 @@ package io.seldon.dataflow.kafka import io.seldon.dataflow.kafka.headers.PipelineNameFilter import io.seldon.dataflow.kafka.headers.AlibiDetectRemover +import io.seldon.dataflow.kafka.headers.PipelineHeaderSetter import io.seldon.mlops.chainer.ChainerOuterClass.Batch import io.seldon.mlops.inference.v2.V2Dataplane.ModelInferRequest import io.seldon.mlops.inference.v2.V2Dataplane.ModelInferResponse @@ -35,6 +36,11 @@ fun KStream.headerRemover(): KStream { .transformValues(ValueTransformerSupplier { AlibiDetectRemover() }) } +fun KStream.headerSetter(pipelineName: String): KStream { + return this + .transformValues(ValueTransformerSupplier { PipelineHeaderSetter(pipelineName) }) +} + fun KStream.unmarshallInferenceV2Response(): KStream { return this .mapValues { bytes -> ModelInferResponse.parseFrom(bytes) } diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt index 75a6c45a8b..1547d80e7f 100644 --- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt +++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt @@ -23,11 +23,10 @@ import org.apache.kafka.streams.kstream.KStream import java.time.Duration fun addTriggerTopology( - pipelineName: String, kafkaDomainParams: KafkaDomainParams, builder: StreamsBuilder, - inputTopics: Set, - tensorsByTopic: Map>?, + inputTopics: Set, + tensorsByTopic: Map>?, joinType: ChainerOuterClass.PipelineStepUpdate.PipelineJoinType, lastStream: KStream, pending: KStream? = null, @@ -49,10 +48,10 @@ fun addTriggerTopology( val topic = inputTopics.first() val nextStream = builder //TODO possible bug - not all streams will be v2 requests? Maybe v2 responses? - .stream(topic, consumerSerde) - .filterForPipeline(pipelineName) + .stream(topic.topicName, consumerSerde) + .filterForPipeline(topic.pipelineName) .unmarshallInferenceV2Response() - .convertToRequest(topic, tensorsByTopic?.get(topic), emptyMap()) + .convertToRequest(topic.topicName, tensorsByTopic?.get(topic), emptyMap()) // handle cases where there are no tensors we want .filter { _, value -> value.inputsList.size != 0} .marshallInferenceV2Request() @@ -73,7 +72,7 @@ fun addTriggerTopology( ) ?: nextStream - return addTriggerTopology(pipelineName, kafkaDomainParams, builder, inputTopics.minus(topic), tensorsByTopic, joinType, lastStream, nextPending) + return addTriggerTopology(kafkaDomainParams, builder, inputTopics.minus(topic), tensorsByTopic, joinType, lastStream, nextPending) } ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Outer -> { @@ -89,7 +88,7 @@ fun addTriggerTopology( ) ?: nextStream - return addTriggerTopology(pipelineName, kafkaDomainParams, builder, inputTopics.minus(topic), tensorsByTopic, joinType, lastStream, nextPending) + return addTriggerTopology(kafkaDomainParams, builder, inputTopics.minus(topic), tensorsByTopic, joinType, lastStream, nextPending) } else -> { @@ -103,7 +102,7 @@ fun addTriggerTopology( joinSerde, ) ?: nextStream - return addTriggerTopology(pipelineName, kafkaDomainParams, builder, inputTopics.minus(topic), tensorsByTopic, joinType, lastStream, nextPending) + return addTriggerTopology(kafkaDomainParams, builder, inputTopics.minus(topic), tensorsByTopic, joinType, lastStream, nextPending) } } } diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/headers/PipelineHeaderSetter.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/headers/PipelineHeaderSetter.kt new file mode 100644 index 0000000000..3da7ea05d1 --- /dev/null +++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/headers/PipelineHeaderSetter.kt @@ -0,0 +1,21 @@ +package io.seldon.dataflow.kafka.headers + +import io.seldon.dataflow.kafka.TRecord +import org.apache.kafka.streams.kstream.ValueTransformer +import org.apache.kafka.streams.processor.ProcessorContext + +class PipelineHeaderSetter(private val pipelineName: String) : ValueTransformer { + var context: ProcessorContext? = null + + override fun init(context: ProcessorContext?) { + this.context = context + } + + override fun transform(value: TRecord?): TRecord? { + this.context?.headers()?.remove(SeldonHeaders.pipelineName) + this.context?.headers()?.add(SeldonHeaders.pipelineName, pipelineName.toByteArray()) + return value + } + + override fun close() {} +} \ No newline at end of file diff --git a/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt b/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt index aaf8ab855d..fcf3395519 100644 --- a/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt +++ b/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt @@ -17,6 +17,7 @@ limitations under the License. package io.seldon.dataflow.kafka import io.seldon.mlops.chainer.ChainerOuterClass +import io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic import org.apache.kafka.streams.StreamsBuilder import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.Arguments @@ -30,19 +31,12 @@ import java.util.stream.Stream internal class PipelineStepTest { - @ParameterizedTest(name = "{0}") - @MethodSource - fun areTensorsFromSameTopic(testName: String, expected: Boolean, sources: List) { - val (actual, _) = sources.areTensorsFromSameTopic() - expectThat(expected).isEqualTo(actual) - } - @ParameterizedTest(name = "{0}") @MethodSource fun stepFor( testName: String, expected: PipelineStep?, - sources: List, + sources: List, ) { val result = stepFor( @@ -51,7 +45,7 @@ internal class PipelineStepTest { sources, emptyList(), emptyMap(), - defaultSink, + defaultPipelineTopic, ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Inner, ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Inner, ChainerOuterClass.Batch.getDefaultInstance(), @@ -67,113 +61,102 @@ internal class PipelineStepTest { } companion object { - private const val defaultSink = "seldon.namespace.sinkModel.inputs" private const val defaultPipelineName = "some-pipeline" + private val defaultPipelineTopic = PipelineTopic.newBuilder() + .setTopicName("seldon.namespace.sinkModel.inputs") + .setPipelineName(defaultPipelineName).build() + private val defaultSink = TopicForPipeline(topicName = "seldon.namespace.sinkModel.inputs", pipelineName = defaultPipelineName) private val kafkaDomainParams = KafkaDomainParams(useCleanState = true, joinWindowMillis = 1_000L) - @JvmStatic - fun areTensorsFromSameTopic(): Stream = - Stream.of( - arguments("no sources", false, emptyList()), - arguments("no tensors", false, listOf("seldon.namespace.model.model1.outputs")), - arguments("single tensor", true, listOf("seldon.namespace.model.model1.outputs.tensorA")), - arguments( - "tensors from same model", - true, - listOf( - "seldon.namespace.model.model1.outputs.tensorA", - "seldon.namespace.model.model1.outputs.tensorB", - ), - ), - arguments( - "tensors from different models", - false, - listOf( - "seldon.namespace.model.model1.outputs.tensorA", - "seldon.namespace.model.model2.outputs.tensorA", - ), - ), - ) @JvmStatic fun stepFor(): Stream = Stream.of( - arguments("no sources", null, emptyList()), + arguments("no sources", null, emptyList()), arguments( "single source, no tensors", makeChainerFor( - inputTopic = "seldon.namespace.model.model1.outputs", + inputTopic = TopicForPipeline(topicName = "seldon.namespace.model.model1.outputs", pipelineName = defaultPipelineName), tensors = null, ), - listOf("seldon.namespace.model.model1.outputs"), + listOf(PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.model1.outputs").setPipelineName(defaultPipelineName).build()), ), arguments( "single source, one tensor", makeChainerFor( - inputTopic = "seldon.namespace.model.model1.outputs", + inputTopic = TopicForPipeline(topicName = "seldon.namespace.model.model1.outputs", pipelineName = defaultPipelineName), tensors = setOf("tensorA") ), - listOf("seldon.namespace.model.model1.outputs.tensorA"), + listOf(PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.model1.outputs.tensorA").setPipelineName(defaultPipelineName).build()), ), arguments( "single source, multiple tensors", makeChainerFor( - inputTopic = "seldon.namespace.model.model1.outputs", + inputTopic = TopicForPipeline(topicName = "seldon.namespace.model.model1.outputs", pipelineName = defaultPipelineName), tensors = setOf("tensorA", "tensorB") ), listOf( - "seldon.namespace.model.model1.outputs.tensorA", - "seldon.namespace.model.model1.outputs.tensorB", + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.model1.outputs.tensorA").setPipelineName( + defaultPipelineName).build(), + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.model1.outputs.tensorB").setPipelineName( + defaultPipelineName).build(), ), ), arguments( "multiple sources, no tensors", makeJoinerFor( - inputTopics = setOf("seldon.namespace.model.modelA.outputs", "seldon.namespace.model.modelB.outputs"), + inputTopics = setOf(TopicForPipeline(topicName = "seldon.namespace.model.modelA.outputs", pipelineName = defaultPipelineName), + TopicForPipeline(topicName = "seldon.namespace.model.modelB.outputs", pipelineName = defaultPipelineName)), tensorsByTopic = null, ), listOf( - "seldon.namespace.model.modelA.outputs", - "seldon.namespace.model.modelB.outputs", + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.modelA.outputs").setPipelineName( + defaultPipelineName).build(), + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.modelB.outputs").setPipelineName( + defaultPipelineName).build(), ), ), arguments( "multiple sources, multiple tensors", makeJoinerFor( inputTopics = setOf( - "seldon.namespace.model.modelA.outputs", - "seldon.namespace.model.modelB.outputs", + TopicForPipeline(topicName = "seldon.namespace.model.modelA.outputs", pipelineName = defaultPipelineName), + TopicForPipeline(topicName = "seldon.namespace.model.modelB.outputs", pipelineName = defaultPipelineName), ), tensorsByTopic = mapOf( - "seldon.namespace.model.modelA.outputs" to setOf("tensor1"), - "seldon.namespace.model.modelB.outputs" to setOf("tensor2"), + TopicForPipeline(topicName = "seldon.namespace.model.modelA.outputs", pipelineName = defaultPipelineName) to setOf("tensor1"), + TopicForPipeline(topicName = "seldon.namespace.model.modelB.outputs", pipelineName = defaultPipelineName) to setOf("tensor2"), ), ), listOf( - "seldon.namespace.model.modelA.outputs.tensor1", - "seldon.namespace.model.modelB.outputs.tensor2", + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.modelA.outputs.tensor1").setPipelineName( + defaultPipelineName).build(), + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.modelB.outputs.tensor2").setPipelineName( + defaultPipelineName).build(), ), ), arguments( "tensors override plain topic", makeChainerFor( - inputTopic = "seldon.namespace.model.modelA.outputs", + inputTopic = TopicForPipeline(topicName = "seldon.namespace.model.modelA.outputs", pipelineName = defaultPipelineName), tensors = setOf("tensorA"), ), listOf( - "seldon.namespace.model.modelA.outputs.tensorA", - "seldon.namespace.model.modelA.outputs", + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.modelA.outputs.tensorA").setPipelineName( + defaultPipelineName).build(), + PipelineTopic.newBuilder().setTopicName("seldon.namespace.model.modelA.outputs").setPipelineName( + defaultPipelineName).build(), ), ), ) - private fun makeChainerFor(inputTopic: TopicName, tensors: Set?): Chainer = + private fun makeChainerFor(inputTopic: TopicForPipeline, tensors: Set?): Chainer = Chainer( StreamsBuilder(), inputTopic = inputTopic, tensors = tensors, - outputTopic = defaultSink, pipelineName = defaultPipelineName, + outputTopic = defaultSink, tensorRenaming = emptyMap(), kafkaDomainParams = kafkaDomainParams, inputTriggerTopics = emptySet(), @@ -183,15 +166,15 @@ internal class PipelineStepTest { ) private fun makeJoinerFor( - inputTopics: Set, - tensorsByTopic: Map>?, + inputTopics: Set, + tensorsByTopic: Map>?, ): Joiner = Joiner( StreamsBuilder(), inputTopics = inputTopics, tensorsByTopic = tensorsByTopic, - outputTopic = defaultSink, pipelineName = defaultPipelineName, + outputTopic = defaultSink, tensorRenaming = emptyMap(), kafkaDomainParams = kafkaDomainParams, joinType = ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Inner, @@ -215,7 +198,6 @@ fun Assertion.Builder.matches(expected: PipelineStep) = when { it is Chainer && expected is Chainer -> expect { that(it) { - get { pipelineName }.isEqualTo(expected.pipelineName) get { inputTopic }.isEqualTo(expected.inputTopic) get { outputTopic }.isEqualTo(expected.outputTopic) get { tensors }.isEqualTo(expected.tensors) @@ -223,7 +205,6 @@ fun Assertion.Builder.matches(expected: PipelineStep) = } it is Joiner && expected is Joiner -> expect { that(it) { - get { pipelineName }.isEqualTo(expected.pipelineName) get { inputTopics }.isEqualTo(expected.inputTopics) get { outputTopic }.isEqualTo(expected.outputTopic) get { tensorsByTopic }.isEqualTo(expected.tensorsByTopic) diff --git a/scheduler/pkg/agent/repository/triton/config/model_config.pb.go b/scheduler/pkg/agent/repository/triton/config/model_config.pb.go index 14209973ab..4c79d20ca0 100644 --- a/scheduler/pkg/agent/repository/triton/config/model_config.pb.go +++ b/scheduler/pkg/agent/repository/triton/config/model_config.pb.go @@ -48,11 +48,11 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -//@@ -//@@.. cpp:enum:: DataType -//@@ -//@@ Data types supported for input and output tensors. -//@@ +// @@ +// @@.. cpp:enum:: DataType +// @@ +// @@ Data types supported for input and output tensors. +// @@ type DataType int32 const ( @@ -149,11 +149,11 @@ func (DataType) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{0} } -//@@ -//@@ .. cpp:enum:: Kind -//@@ -//@@ Kind of this instance group. -//@@ +// @@ +// @@ .. cpp:enum:: Kind +// @@ +// @@ Kind of this instance group. +// @@ type ModelInstanceGroup_Kind int32 const ( @@ -230,11 +230,11 @@ func (ModelInstanceGroup_Kind) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{1, 0} } -//@@ -//@@ .. cpp:enum:: SecondaryDeviceKind -//@@ -//@@ The kind of the secondary device. -//@@ +// @@ +// @@ .. cpp:enum:: SecondaryDeviceKind +// @@ +// @@ The kind of the secondary device. +// @@ type ModelInstanceGroup_SecondaryDevice_SecondaryDeviceKind int32 const ( @@ -283,11 +283,11 @@ func (ModelInstanceGroup_SecondaryDevice_SecondaryDeviceKind) EnumDescriptor() ( return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{1, 0, 0} } -//@@ -//@@ .. cpp:enum:: Format -//@@ -//@@ The format for the input. -//@@ +// @@ +// @@ .. cpp:enum:: Format +// @@ +// @@ The format for the input. +// @@ type ModelInput_Format int32 const ( @@ -357,11 +357,11 @@ func (ModelInput_Format) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{3, 0} } -//@@ -//@@ .. cpp:enum:: Kind -//@@ -//@@ The kind of the batch input. -//@@ +// @@ +// @@ .. cpp:enum:: Kind +// @@ +// @@ The kind of the batch input. +// @@ type BatchInput_Kind int32 const ( @@ -443,11 +443,11 @@ func (BatchInput_Kind) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{5, 0} } -//@@ -//@@ .. cpp:enum:: Kind -//@@ -//@@ The kind of the batch output. -//@@ +// @@ +// @@ .. cpp:enum:: Kind +// @@ +// @@ The kind of the batch output. +// @@ type BatchOutput_Kind int32 const ( @@ -497,13 +497,13 @@ func (BatchOutput_Kind) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{6, 0} } -//@@ -//@@ .. cpp:enum:: ModelPriority -//@@ -//@@ Model priorities. A model will be given scheduling and execution -//@@ preference over models at lower priorities. Current model -//@@ priorities only work for TensorRT models. -//@@ +// @@ +// @@ .. cpp:enum:: ModelPriority +// @@ +// @@ Model priorities. A model will be given scheduling and execution +// @@ preference over models at lower priorities. Current model +// @@ priorities only work for TensorRT models. +// @@ type ModelOptimizationPolicy_ModelPriority int32 const ( @@ -565,11 +565,11 @@ func (ModelOptimizationPolicy_ModelPriority) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{8, 0} } -//@@ -//@@ .. cpp:enum:: TimeoutAction -//@@ -//@@ The action applied to timed-out requests. -//@@ +// @@ +// @@ .. cpp:enum:: TimeoutAction +// @@ +// @@ The action applied to timed-out requests. +// @@ type ModelQueuePolicy_TimeoutAction int32 const ( @@ -627,11 +627,11 @@ func (ModelQueuePolicy_TimeoutAction) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{9, 0} } -//@@ -//@@ .. cpp:enum:: Kind -//@@ -//@@ The kind of the control. -//@@ +// @@ +// @@ .. cpp:enum:: Kind +// @@ +// @@ The kind of the control. +// @@ type ModelSequenceBatching_Control_Kind int32 const ( @@ -717,13 +717,13 @@ func (ModelSequenceBatching_Control_Kind) EnumDescriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{11, 0, 0} } -//@@ -//@@ .. cpp:var:: message ModelRateLimiter -//@@ -//@@ The specifications required by the rate limiter to properly -//@@ schedule the inference requests across the different models -//@@ and their instances. -//@@ +// @@ +// @@ .. cpp:var:: message ModelRateLimiter +// @@ +// @@ The specifications required by the rate limiter to properly +// @@ schedule the inference requests across the different models +// @@ and their instances. +// @@ type ModelRateLimiter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -794,12 +794,12 @@ func (x *ModelRateLimiter) GetPriority() uint32 { return 0 } -//@@ -//@@.. cpp:var:: message ModelInstanceGroup -//@@ -//@@ A group of one or more instances of a model and resources made -//@@ available for those instances. -//@@ +// @@ +// @@.. cpp:var:: message ModelInstanceGroup +// @@ +// @@ A group of one or more instances of a model and resources made +// @@ available for those instances. +// @@ type ModelInstanceGroup struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -972,11 +972,11 @@ func (x *ModelInstanceGroup) GetHostPolicy() string { return "" } -//@@ -//@@.. cpp:var:: message ModelTensorReshape -//@@ -//@@ Reshape specification for input and output tensors. -//@@ +// @@ +// @@.. cpp:var:: message ModelTensorReshape +// @@ +// @@ Reshape specification for input and output tensors. +// @@ type ModelTensorReshape struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1028,11 +1028,11 @@ func (x *ModelTensorReshape) GetShape() []int64 { return nil } -//@@ -//@@.. cpp:var:: message ModelInput -//@@ -//@@ An input required by the model. -//@@ +// @@ +// @@.. cpp:var:: message ModelInput +// @@ +// @@ An input required by the model. +// @@ type ModelInput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1181,11 +1181,11 @@ func (x *ModelInput) GetOptional() bool { return false } -//@@ -//@@.. cpp:var:: message ModelOutput -//@@ -//@@ An output produced by the model. -//@@ +// @@ +// @@.. cpp:var:: message ModelOutput +// @@ +// @@ An output produced by the model. +// @@ type ModelOutput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1304,11 +1304,11 @@ func (x *ModelOutput) GetIsShapeTensor() bool { return false } -//@@ .. cpp:var:: message BatchInput -//@@ -//@@ A batch input is an additional input that must be added by -//@@ the backend based on all the requests in a batch. -//@@ +// @@ .. cpp:var:: message BatchInput +// @@ +// @@ A batch input is an additional input that must be added by +// @@ the backend based on all the requests in a batch. +// @@ type BatchInput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1400,11 +1400,11 @@ func (x *BatchInput) GetSourceInput() []string { return nil } -//@@.. cpp:var:: message BatchOutput -//@@ -//@@ A batch output is an output produced by the model that must be handled -//@@ differently by the backend based on all the requests in a batch. -//@@ +// @@.. cpp:var:: message BatchOutput +// @@ +// @@ A batch output is an output produced by the model that must be handled +// @@ differently by the backend based on all the requests in a batch. +// @@ type BatchOutput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1482,12 +1482,12 @@ func (x *BatchOutput) GetSourceInput() []string { return nil } -//@@ -//@@.. cpp:var:: message ModelVersionPolicy -//@@ -//@@ Policy indicating which versions of a model should be made -//@@ available by the inference server. -//@@ +// @@ +// @@.. cpp:var:: message ModelVersionPolicy +// @@ +// @@ Policy indicating which versions of a model should be made +// @@ available by the inference server. +// @@ type ModelVersionPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1600,13 +1600,13 @@ func (*ModelVersionPolicy_All_) isModelVersionPolicy_PolicyChoice() {} func (*ModelVersionPolicy_Specific_) isModelVersionPolicy_PolicyChoice() {} -//@@ -//@@.. cpp:var:: message ModelOptimizationPolicy -//@@ -//@@ Optimization settings for a model. These settings control if/how a -//@@ model is optimized and prioritized by the backend framework when -//@@ it is loaded. -//@@ +// @@ +// @@.. cpp:var:: message ModelOptimizationPolicy +// @@ +// @@ Optimization settings for a model. These settings control if/how a +// @@ model is optimized and prioritized by the backend framework when +// @@ it is loaded. +// @@ type ModelOptimizationPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1757,11 +1757,11 @@ func (x *ModelOptimizationPolicy) GetEagerBatching() bool { return false } -//@@ -//@@.. cpp:var:: message ModelQueuePolicy -//@@ -//@@ Queue policy for inference requests. -//@@ +// @@ +// @@.. cpp:var:: message ModelQueuePolicy +// @@ +// @@ Queue policy for inference requests. +// @@ type ModelQueuePolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1861,12 +1861,12 @@ func (x *ModelQueuePolicy) GetMaxQueueSize() uint32 { return 0 } -//@@ -//@@.. cpp:var:: message ModelDynamicBatching -//@@ -//@@ Dynamic batching configuration. These settings control how dynamic -//@@ batching operates for the model. -//@@ +// @@ +// @@.. cpp:var:: message ModelDynamicBatching +// @@ +// @@ Dynamic batching configuration. These settings control how dynamic +// @@ batching operates for the model. +// @@ type ModelDynamicBatching struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2014,12 +2014,12 @@ func (x *ModelDynamicBatching) GetPriorityQueuePolicy() map[uint32]*ModelQueuePo return nil } -//@@ -//@@.. cpp:var:: message ModelSequenceBatching -//@@ -//@@ Sequence batching configuration. These settings control how sequence -//@@ batching operates for the model. -//@@ +// @@ +// @@.. cpp:var:: message ModelSequenceBatching +// @@ +// @@ Sequence batching configuration. These settings control how sequence +// @@ batching operates for the model. +// @@ type ModelSequenceBatching struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2164,12 +2164,12 @@ func (*ModelSequenceBatching_Direct) isModelSequenceBatching_StrategyChoice() {} func (*ModelSequenceBatching_Oldest) isModelSequenceBatching_StrategyChoice() {} -//@@ -//@@.. cpp:var:: message ModelEnsembling -//@@ -//@@ Model ensembling configuration. These settings specify the models that -//@@ compose the ensemble and how data flows between the models. -//@@ +// @@ +// @@.. cpp:var:: message ModelEnsembling +// @@ +// @@ Model ensembling configuration. These settings specify the models that +// @@ compose the ensemble and how data flows between the models. +// @@ type ModelEnsembling struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2221,11 +2221,11 @@ func (x *ModelEnsembling) GetStep() []*ModelEnsembling_Step { return nil } -//@@ -//@@.. cpp:var:: message ModelParameter -//@@ -//@@ A model parameter. -//@@ +// @@ +// @@.. cpp:var:: message ModelParameter +// @@ +// @@ A model parameter. +// @@ type ModelParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2277,11 +2277,11 @@ func (x *ModelParameter) GetStringValue() string { return "" } -//@@ -//@@.. cpp:var:: message ModelWarmup -//@@ -//@@ Settings used to construct the request sample for model warmup. -//@@ +// @@ +// @@.. cpp:var:: message ModelWarmup +// @@ +// @@ Settings used to construct the request sample for model warmup. +// @@ type ModelWarmup struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2361,11 +2361,11 @@ func (x *ModelWarmup) GetInputs() map[string]*ModelWarmup_Input { return nil } -//@@ -//@@ .. cpp:var:: message ModelOperations -//@@ -//@@ The metadata of libraries providing custom operations for this model. -//@@ +// @@ +// @@ .. cpp:var:: message ModelOperations +// @@ +// @@ The metadata of libraries providing custom operations for this model. +// @@ type ModelOperations struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2418,12 +2418,12 @@ func (x *ModelOperations) GetOpLibraryFilename() []string { return nil } -//@@ -//@@ .. cpp:var:: message ModelTransactionPolicy -//@@ -//@@ The specification that describes the nature of transactions -//@@ to be expected from the model. -//@@ +// @@ +// @@ .. cpp:var:: message ModelTransactionPolicy +// @@ +// @@ The specification that describes the nature of transactions +// @@ to be expected from the model. +// @@ type ModelTransactionPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2480,11 +2480,11 @@ func (x *ModelTransactionPolicy) GetDecoupled() bool { return false } -//@@ -//@@.. cpp:var:: message ModelRepositoryAgents -//@@ -//@@ The repository agents for the model. -//@@ +// @@ +// @@.. cpp:var:: message ModelRepositoryAgents +// @@ +// @@ The repository agents for the model. +// @@ type ModelRepositoryAgents struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2539,11 +2539,11 @@ func (x *ModelRepositoryAgents) GetAgents() []*ModelRepositoryAgents_Agent { return nil } -//@@ -//@@.. cpp:var:: message ModelResponseCache -//@@ -//@@ The response cache setting for the model. -//@@ +// @@ +// @@.. cpp:var:: message ModelResponseCache +// @@ +// @@ The response cache setting for the model. +// @@ type ModelResponseCache struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2600,11 +2600,11 @@ func (x *ModelResponseCache) GetEnable() bool { return false } -//@@ -//@@.. cpp:var:: message ModelConfig -//@@ -//@@ A model configuration. -//@@ +// @@ +// @@.. cpp:var:: message ModelConfig +// @@ +// @@ A model configuration. +// @@ type ModelConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3007,10 +3007,10 @@ func (*ModelConfig_SequenceBatching) isModelConfig_SchedulingChoice() {} func (*ModelConfig_EnsembleScheduling) isModelConfig_SchedulingChoice() {} -//@@ .. cpp:var:: message Resource -//@@ -//@@ The resource property. -//@@ +// @@ .. cpp:var:: message Resource +// @@ +// @@ The resource property. +// @@ type ModelRateLimiter_Resource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3090,11 +3090,11 @@ func (x *ModelRateLimiter_Resource) GetCount() uint32 { return 0 } -//@@ -//@@ .. cpp:var:: message SecondaryDevice -//@@ -//@@ A secondary device required for a model instance. -//@@ +// @@ +// @@ .. cpp:var:: message SecondaryDevice +// @@ +// @@ A secondary device required for a model instance. +// @@ type ModelInstanceGroup_SecondaryDevice struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3158,11 +3158,11 @@ func (x *ModelInstanceGroup_SecondaryDevice) GetDeviceId() int64 { return 0 } -//@@ .. cpp:var:: message Latest -//@@ -//@@ Serve only the latest version(s) of a model. This is -//@@ the default policy. -//@@ +// @@ .. cpp:var:: message Latest +// @@ +// @@ Serve only the latest version(s) of a model. This is +// @@ the default policy. +// @@ type ModelVersionPolicy_Latest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3217,10 +3217,10 @@ func (x *ModelVersionPolicy_Latest) GetNumVersions() uint32 { return 0 } -//@@ .. cpp:var:: message All -//@@ -//@@ Serve all versions of the model. -//@@ +// @@ .. cpp:var:: message All +// @@ +// @@ Serve all versions of the model. +// @@ type ModelVersionPolicy_All struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3259,10 +3259,10 @@ func (*ModelVersionPolicy_All) Descriptor() ([]byte, []int) { return file_pkg_agent_repository_triton_config_model_config_proto_rawDescGZIP(), []int{7, 1} } -//@@ .. cpp:var:: message Specific -//@@ -//@@ Serve only specific versions of the model. -//@@ +// @@ .. cpp:var:: message Specific +// @@ +// @@ Serve only specific versions of the model. +// @@ type ModelVersionPolicy_Specific struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3314,16 +3314,16 @@ func (x *ModelVersionPolicy_Specific) GetVersions() []int64 { return nil } -//@@ -//@@ .. cpp:var:: message Graph -//@@ -//@@ Enable generic graph optimization of the model. If not specified -//@@ the framework's default level of optimization is used. Supports -//@@ TensorFlow graphdef and savedmodel and Onnx models. For TensorFlow -//@@ causes XLA to be enabled/disabled for the model. For Onnx defaults -//@@ to enabling all optimizations, -1 enables only basic optimizations, -//@@ +1 enables only basic and extended optimizations. -//@@ +// @@ +// @@ .. cpp:var:: message Graph +// @@ +// @@ Enable generic graph optimization of the model. If not specified +// @@ the framework's default level of optimization is used. Supports +// @@ TensorFlow graphdef and savedmodel and Onnx models. For TensorFlow +// @@ causes XLA to be enabled/disabled for the model. For Onnx defaults +// @@ to enabling all optimizations, -1 enables only basic optimizations, +// @@ +1 enables only basic and extended optimizations. +// @@ type ModelOptimizationPolicy_Graph struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3380,11 +3380,11 @@ func (x *ModelOptimizationPolicy_Graph) GetLevel() int32 { return 0 } -//@@ -//@@ .. cpp:var:: message Cuda -//@@ -//@@ CUDA-specific optimization settings. -//@@ +// @@ +// @@ .. cpp:var:: message Cuda +// @@ +// @@ CUDA-specific optimization settings. +// @@ type ModelOptimizationPolicy_Cuda struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3485,22 +3485,22 @@ func (x *ModelOptimizationPolicy_Cuda) GetOutputCopyStream() bool { return false } -//@@ -//@@ .. cpp:var:: message ExecutionAccelerators -//@@ -//@@ Specify the preferred execution accelerators to be used to execute -//@@ the model. Currently only recognized by ONNX Runtime backend and -//@@ TensorFlow backend. -//@@ -//@@ For ONNX Runtime backend, it will deploy the model with the execution -//@@ accelerators by priority, the priority is determined based on the -//@@ order that they are set, i.e. the provider at the front has highest -//@@ priority. Overall, the priority will be in the following order: -//@@ (if instance is on GPU) -//@@ CUDA Execution Provider (if instance is on GPU) -//@@ -//@@ Default CPU Execution Provider -//@@ +// @@ +// @@ .. cpp:var:: message ExecutionAccelerators +// @@ +// @@ Specify the preferred execution accelerators to be used to execute +// @@ the model. Currently only recognized by ONNX Runtime backend and +// @@ TensorFlow backend. +// @@ +// @@ For ONNX Runtime backend, it will deploy the model with the execution +// @@ accelerators by priority, the priority is determined based on the +// @@ order that they are set, i.e. the provider at the front has highest +// @@ priority. Overall, the priority will be in the following order: +// @@ (if instance is on GPU) +// @@ CUDA Execution Provider (if instance is on GPU) +// @@ +// @@ Default CPU Execution Provider +// @@ type ModelOptimizationPolicy_ExecutionAccelerators struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3602,19 +3602,19 @@ func (x *ModelOptimizationPolicy_ExecutionAccelerators) GetCpuExecutionAccelerat return nil } -//@@ -//@@ .. cpp:var:: message PinnedMemoryBuffer -//@@ -//@@ Specify whether to use a pinned memory buffer when transferring data -//@@ between non-pinned system memory and GPU memory. Using a pinned -//@@ memory buffer for system from/to GPU transfers will typically provide -//@@ increased performance. For example, in the common use case where the -//@@ request provides inputs and delivers outputs via non-pinned system -//@@ memory, if the model instance accepts GPU IOs, the inputs will be -//@@ processed by two copies: from non-pinned system memory to pinned -//@@ memory, and from pinned memory to GPU memory. Similarly, pinned -//@@ memory will be used for delivering the outputs. -//@@ +// @@ +// @@ .. cpp:var:: message PinnedMemoryBuffer +// @@ +// @@ Specify whether to use a pinned memory buffer when transferring data +// @@ between non-pinned system memory and GPU memory. Using a pinned +// @@ memory buffer for system from/to GPU transfers will typically provide +// @@ increased performance. For example, in the common use case where the +// @@ request provides inputs and delivers outputs via non-pinned system +// @@ memory, if the model instance accepts GPU IOs, the inputs will be +// @@ processed by two copies: from non-pinned system memory to pinned +// @@ memory, and from pinned memory to GPU memory. Similarly, pinned +// @@ memory will be used for delivering the outputs. +// @@ type ModelOptimizationPolicy_PinnedMemoryBuffer struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3666,10 +3666,10 @@ func (x *ModelOptimizationPolicy_PinnedMemoryBuffer) GetEnable() bool { return false } -//@@ .. cpp:var:: message GraphSpec -//@@ -//@@ Specification of the CUDA graph to be captured. -//@@ +// @@ .. cpp:var:: message GraphSpec +// @@ +// @@ Specification of the CUDA graph to be captured. +// @@ type ModelOptimizationPolicy_Cuda_GraphSpec struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3757,10 +3757,10 @@ func (x *ModelOptimizationPolicy_Cuda_GraphSpec) GetGraphLowerBound() *ModelOpti return nil } -//@@ .. cpp:var:: message Dims -//@@ -//@@ Specification of tensor dimension. -//@@ +// @@ .. cpp:var:: message Dims +// @@ +// @@ Specification of tensor dimension. +// @@ type ModelOptimizationPolicy_Cuda_GraphSpec_Shape struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3878,13 +3878,13 @@ func (x *ModelOptimizationPolicy_Cuda_GraphSpec_LowerBound) GetInput() map[strin return nil } -//@@ -//@@ .. cpp:var:: message Accelerator -//@@ -//@@ Specify the accelerator to be used to execute the model. -//@@ Accelerator with the same name may accept different parameters -//@@ depending on the backends. -//@@ +// @@ +// @@ .. cpp:var:: message Accelerator +// @@ +// @@ Specify the accelerator to be used to execute the model. +// @@ Accelerator with the same name may accept different parameters +// @@ depending on the backends. +// @@ type ModelOptimizationPolicy_ExecutionAccelerators_Accelerator struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3948,11 +3948,11 @@ func (x *ModelOptimizationPolicy_ExecutionAccelerators_Accelerator) GetParameter return nil } -//@@ .. cpp:var:: message Control -//@@ -//@@ A control is a signal that the sequence batcher uses to -//@@ communicate with a backend. -//@@ +// @@ .. cpp:var:: message Control +// @@ +// @@ A control is a signal that the sequence batcher uses to +// @@ communicate with a backend. +// @@ type ModelSequenceBatching_Control struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4064,10 +4064,10 @@ func (x *ModelSequenceBatching_Control) GetDataType() DataType { return DataType_TYPE_INVALID } -//@@ .. cpp:var:: message ControlInput -//@@ -//@@ The sequence control values to communicate by a model input. -//@@ +// @@ .. cpp:var:: message ControlInput +// @@ +// @@ The sequence control values to communicate by a model input. +// @@ type ModelSequenceBatching_ControlInput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4132,11 +4132,11 @@ func (x *ModelSequenceBatching_ControlInput) GetControl() []*ModelSequenceBatchi return nil } -//@@ -//@@ .. cpp:var:: message InitialState -//@@ -//@@ Settings used to initialize data for implicit state. -//@@ +// @@ +// @@ .. cpp:var:: message InitialState +// @@ +// @@ Settings used to initialize data for implicit state. +// @@ type ModelSequenceBatching_InitialState struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4273,10 +4273,10 @@ func (*ModelSequenceBatching_InitialState_ZeroData) isModelSequenceBatching_Init func (*ModelSequenceBatching_InitialState_DataFile) isModelSequenceBatching_InitialState_StateData() { } -//@@ .. cpp:var:: message State -//@@ -//@@ An input / output pair of tensors that carry state for the sequence. -//@@ +// @@ .. cpp:var:: message State +// @@ +// @@ An input / output pair of tensors that carry state for the sequence. +// @@ type ModelSequenceBatching_State struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4376,14 +4376,14 @@ func (x *ModelSequenceBatching_State) GetInitialState() []*ModelSequenceBatching return nil } -//@@ .. cpp:var:: message StrategyDirect -//@@ -//@@ The sequence batcher uses a specific, unique batch -//@@ slot for each sequence. All inference requests in a -//@@ sequence are directed to the same batch slot in the same -//@@ model instance over the lifetime of the sequence. This -//@@ is the default strategy. -//@@ +// @@ .. cpp:var:: message StrategyDirect +// @@ +// @@ The sequence batcher uses a specific, unique batch +// @@ slot for each sequence. All inference requests in a +// @@ sequence are directed to the same batch slot in the same +// @@ model instance over the lifetime of the sequence. This +// @@ is the default strategy. +// @@ type ModelSequenceBatching_StrategyDirect struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4458,17 +4458,17 @@ func (x *ModelSequenceBatching_StrategyDirect) GetMinimumSlotUtilization() float return 0 } -//@@ .. cpp:var:: message StrategyOldest -//@@ -//@@ The sequence batcher maintains up to 'max_candidate_sequences' -//@@ candidate sequences. 'max_candidate_sequences' can be greater -//@@ than the model's 'max_batch_size'. For inferencing the batcher -//@@ chooses from the candidate sequences up to 'max_batch_size' -//@@ inference requests. Requests are chosen in an oldest-first -//@@ manner across all candidate sequences. A given sequence is -//@@ not guaranteed to be assigned to the same batch slot for -//@@ all inference requests of that sequence. -//@@ +// @@ .. cpp:var:: message StrategyOldest +// @@ +// @@ The sequence batcher maintains up to 'max_candidate_sequences' +// @@ candidate sequences. 'max_candidate_sequences' can be greater +// @@ than the model's 'max_batch_size'. For inferencing the batcher +// @@ chooses from the candidate sequences up to 'max_batch_size' +// @@ inference requests. Requests are chosen in an oldest-first +// @@ manner across all candidate sequences. A given sequence is +// @@ not guaranteed to be assigned to the same batch slot for +// @@ all inference requests of that sequence. +// @@ type ModelSequenceBatching_StrategyOldest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4553,12 +4553,12 @@ func (x *ModelSequenceBatching_StrategyOldest) GetMaxQueueDelayMicroseconds() ui return 0 } -//@@ .. cpp:var:: message Step -//@@ -//@@ Each step specifies a model included in the ensemble, -//@@ maps ensemble tensor names to the model input tensors, -//@@ and maps model output tensors to ensemble tensor names -//@@ +// @@ .. cpp:var:: message Step +// @@ +// @@ Each step specifies a model included in the ensemble, +// @@ maps ensemble tensor names to the model input tensors, +// @@ and maps model output tensors to ensemble tensor names +// @@ type ModelEnsembling_Step struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4655,11 +4655,11 @@ func (x *ModelEnsembling_Step) GetOutputMap() map[string]string { return nil } -//@@ -//@@ .. cpp:var:: message Input -//@@ -//@@ Meta data associated with an input. -//@@ +// @@ +// @@ .. cpp:var:: message Input +// @@ +// @@ Meta data associated with an input. +// @@ type ModelWarmup_Input struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4805,12 +4805,12 @@ func (*ModelWarmup_Input_RandomData) isModelWarmup_Input_InputDataType() {} func (*ModelWarmup_Input_InputDataFile) isModelWarmup_Input_InputDataType() {} -//@@ -//@@ .. cpp:var:: message Agent -//@@ -//@@ A repository agent that should be invoked for the specified -//@@ repository actions for this model. -//@@ +// @@ +// @@ .. cpp:var:: message Agent +// @@ +// @@ A repository agent that should be invoked for the specified +// @@ repository actions for this model. +// @@ type ModelRepositoryAgents_Agent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/scheduler/pkg/kafka/dataflow/server.go b/scheduler/pkg/kafka/dataflow/server.go index 337fa380a3..49d417bc26 100644 --- a/scheduler/pkg/kafka/dataflow/server.go +++ b/scheduler/pkg/kafka/dataflow/server.go @@ -168,23 +168,33 @@ func (c *ChainerServer) StopSendPipelineEvents() { } } -func (c *ChainerServer) createTopicSources(inputs []string, pipelineName string) []string { - var sources []string +func (c *ChainerServer) createPipelineTopicSources(inputs []string) []*chainer.PipelineTopic { + var pipelineTopics []*chainer.PipelineTopic + for _, inp := range inputs { + pipelineName := c.topicNamer.GetPipelineNameFromInput(inp) + source := c.topicNamer.GetModelOrPipelineTopic(pipelineName, c.topicNamer.CreateStepReferenceFromPipelineInput(inp)) + pipelineTopics = append(pipelineTopics, &chainer.PipelineTopic{PipelineName: pipelineName, TopicName: source}) + } + return pipelineTopics +} + +func (c *ChainerServer) createTopicSources(inputs []string, pipelineName string) []*chainer.PipelineTopic { + var pipelineTopics []*chainer.PipelineTopic for _, inp := range inputs { source := c.topicNamer.GetModelOrPipelineTopic(pipelineName, inp) - sources = append(sources, source) + pipelineTopics = append(pipelineTopics, &chainer.PipelineTopic{PipelineName: pipelineName, TopicName: source}) } - if len(sources) == 0 { - sources = append(sources, c.topicNamer.GetPipelineTopicInputs(pipelineName)) + if len(pipelineTopics) == 0 { + pipelineTopics = append(pipelineTopics, &chainer.PipelineTopic{PipelineName: pipelineName, TopicName: c.topicNamer.GetPipelineTopicInputs(pipelineName)}) } - return sources + return pipelineTopics } -func (c *ChainerServer) createTriggerSources(inputs []string, pipelineName string) []string { - var sources []string +func (c *ChainerServer) createTriggerSources(inputs []string, pipelineName string) []*chainer.PipelineTopic { + var sources []*chainer.PipelineTopic for _, inp := range inputs { source := c.topicNamer.GetModelOrPipelineTopic(pipelineName, inp) - sources = append(sources, source) + sources = append(sources, &chainer.PipelineTopic{PipelineName: pipelineName, TopicName: source}) } return sources } @@ -195,7 +205,7 @@ func (c *ChainerServer) createPipelineMessage(pv *pipeline.PipelineVersion) *cha stepUpdate := chainer.PipelineStepUpdate{ Sources: c.createTopicSources(step.Inputs, pv.Name), Triggers: c.createTriggerSources(step.Triggers, pv.Name), - Sink: c.topicNamer.GetModelTopicInputs(step.Name), + Sink: &chainer.PipelineTopic{PipelineName: pv.Name, TopicName: c.topicNamer.GetModelTopicInputs(step.Name)}, TensorMap: c.topicNamer.GetFullyQualifiedTensorMap(pv.Name, step.TensorMap), } switch step.InputsJoinType { @@ -223,10 +233,36 @@ func (c *ChainerServer) createPipelineMessage(pv *pipeline.PipelineVersion) *cha c.logger.Infof("Adding sources %v to %s", stepUpdate.Sources, stepUpdate.Sink) stepUpdates = append(stepUpdates, &stepUpdate) } + if pv.Input != nil { + stepUpdate := chainer.PipelineStepUpdate{ + Sources: c.createPipelineTopicSources(pv.Input.ExternalInputs), + Sink: &chainer.PipelineTopic{PipelineName: pv.Name, TopicName: c.topicNamer.GetPipelineTopicInputs(pv.Name)}, + Triggers: c.createPipelineTopicSources(pv.Input.ExternalTriggers), + TensorMap: c.topicNamer.GetFullyQualifiedPipelineTensorMap(pv.Input.TensorMap), + } + switch pv.Input.InputsJoinType { + case pipeline.JoinInner: + stepUpdate.InputJoinTy = chainer.PipelineStepUpdate_Inner + case pipeline.JoinOuter: + stepUpdate.InputJoinTy = chainer.PipelineStepUpdate_Outer + case pipeline.JoinAny: + stepUpdate.InputJoinTy = chainer.PipelineStepUpdate_Any + } + switch pv.Input.TriggersJoinType { + case pipeline.JoinInner: + stepUpdate.TriggersJoinTy = chainer.PipelineStepUpdate_Inner + case pipeline.JoinOuter: + stepUpdate.TriggersJoinTy = chainer.PipelineStepUpdate_Outer + case pipeline.JoinAny: + stepUpdate.TriggersJoinTy = chainer.PipelineStepUpdate_Any + } + c.logger.Infof("Adding input sources %v with tensorMap %v to %s", stepUpdate.Sources, stepUpdate.TensorMap, stepUpdate.Sink) + stepUpdates = append(stepUpdates, &stepUpdate) + } if pv.Output != nil { stepUpdate := chainer.PipelineStepUpdate{ Sources: c.createTopicSources(pv.Output.Steps, pv.Name), - Sink: c.topicNamer.GetPipelineTopicOutputs(pv.Name), + Sink: &chainer.PipelineTopic{PipelineName: pv.Name, TopicName: c.topicNamer.GetPipelineTopicOutputs(pv.Name)}, TensorMap: c.topicNamer.GetFullyQualifiedTensorMap(pv.Name, pv.Output.TensorMap), } switch pv.Output.StepsJoinType { @@ -242,8 +278,8 @@ func (c *ChainerServer) createPipelineMessage(pv *pipeline.PipelineVersion) *cha } //Append an error step to send any errors to pipeline output stepUpdates = append(stepUpdates, &chainer.PipelineStepUpdate{ - Sources: []string{c.topicNamer.GetModelErrorTopic()}, - Sink: c.topicNamer.GetPipelineTopicOutputs(pv.Name), + Sources: []*chainer.PipelineTopic{{PipelineName: pv.Name, TopicName: c.topicNamer.GetModelErrorTopic()}}, + Sink: &chainer.PipelineTopic{PipelineName: pv.Name, TopicName: c.topicNamer.GetPipelineTopicOutputs(pv.Name)}, InputJoinTy: chainer.PipelineStepUpdate_Inner, }) diff --git a/scheduler/pkg/kafka/dataflow/server_test.go b/scheduler/pkg/kafka/dataflow/server_test.go index 5d5b6258da..4cf4e78987 100644 --- a/scheduler/pkg/kafka/dataflow/server_test.go +++ b/scheduler/pkg/kafka/dataflow/server_test.go @@ -19,6 +19,8 @@ package dataflow import ( "testing" + "github.com/seldonio/seldon-core/apis/go/v2/mlops/chainer" + "github.com/seldonio/seldon-core/scheduler/v2/pkg/kafka" . "github.com/onsi/gomega" @@ -33,7 +35,7 @@ func TestCreateTopicSources(t *testing.T) { server *ChainerServer pipelineName string inputs []string - sources []string + sources []*chainer.PipelineTopic } tests := []test{ @@ -49,10 +51,10 @@ func TestCreateTopicSources(t *testing.T) { "b.inputs", "c.inputs.t1", }, - sources: []string{ - "seldon.default.model.a", - "seldon.default.model.b.inputs", - "seldon.default.model.c.inputs.t1", + sources: []*chainer.PipelineTopic{ + {PipelineName: "p1", TopicName: "seldon.default.model.a"}, + {PipelineName: "p1", TopicName: "seldon.default.model.b.inputs"}, + {PipelineName: "p1", TopicName: "seldon.default.model.c.inputs.t1"}, }, }, { @@ -63,8 +65,8 @@ func TestCreateTopicSources(t *testing.T) { }, pipelineName: "p1", inputs: []string{}, - sources: []string{ - "seldon.ns1.pipeline.p1.inputs", + sources: []*chainer.PipelineTopic{ + {PipelineName: "p1", TopicName: "seldon.ns1.pipeline.p1.inputs"}, }, }, } @@ -75,3 +77,46 @@ func TestCreateTopicSources(t *testing.T) { }) } } + +func TestCreatePipelineTopicSources(t *testing.T) { + g := NewGomegaWithT(t) + + type test struct { + name string + server *ChainerServer + pipelineName string + inputs []string + sources []*chainer.PipelineTopic + } + + tests := []test{ + { + name: "misc inputs", + server: &ChainerServer{ + logger: log.New(), + topicNamer: kafka.NewTopicNamer("default"), + }, + pipelineName: "p1", + inputs: []string{ + "foo.inputs", + "foo.outputs", + "foo.step.bar.inputs", + "foo.step.bar.outputs", + "foo.step.bar.inputs.tensora", + }, + sources: []*chainer.PipelineTopic{ + {PipelineName: "foo", TopicName: "seldon.default.pipeline.foo.inputs"}, + {PipelineName: "foo", TopicName: "seldon.default.pipeline.foo.outputs"}, + {PipelineName: "foo", TopicName: "seldon.default.model.bar.inputs"}, + {PipelineName: "foo", TopicName: "seldon.default.model.bar.outputs"}, + {PipelineName: "foo", TopicName: "seldon.default.model.bar.inputs.tensora"}, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + sources := test.server.createPipelineTopicSources(test.inputs) + g.Expect(sources).To(Equal(test.sources)) + }) + } +} diff --git a/scheduler/pkg/kafka/topics.go b/scheduler/pkg/kafka/topics.go index 9e3cf3ddc2..b91bfa23d7 100644 --- a/scheduler/pkg/kafka/topics.go +++ b/scheduler/pkg/kafka/topics.go @@ -58,7 +58,7 @@ func (tn *TopicNamer) GetKafkaModelTopicRegex() string { func (tn *TopicNamer) GetModelNameFromModelInputTopic(topic string) (string, error) { parts := strings.Split(topic, ".") if len(parts) != 5 { - return "", fmt.Errorf("Wrong number of sections in topic %s. Whas expecting 5 with separator '.'", topic) + return "", fmt.Errorf("Wrong number of sections in topic %s. Was expecting 5 with separator '.'", topic) } if parts[0] != seldonTopicPrefix || parts[1] != tn.namespace || parts[2] != modelTopic || parts[4] != inputsSuffix { return "", fmt.Errorf("Bad topic name %s needs to match %s", topic, tn.GetKafkaModelTopicRegex()) @@ -106,3 +106,33 @@ func (tn *TopicNamer) GetFullyQualifiedTensorMap(pipelineName string, tin map[st } return tout } + +func (tn *TopicNamer) GetFullyQualifiedPipelineTensorMap(tin map[string]string) map[string]string { + tout := make(map[string]string) + for k, v := range tin { + parts := strings.Split(k, pipeline.StepNameSeperator) + var kout string + switch len(parts) { + case 3: + kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, pipelineTopic, k) + case 5: + kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, k) + } + tout[kout] = v + } + return tout +} + +func (tn *TopicNamer) GetPipelineNameFromInput(inputSpecifier string) string { + return strings.Split(inputSpecifier, pipeline.StepNameSeperator)[0] +} + +func (tn *TopicNamer) CreateStepReferenceFromPipelineInput(pipelineInputs string) string { + parts := strings.Split(pipelineInputs, pipeline.StepNameSeperator) + switch parts[1] { + case pipeline.StepInputSpecifier, pipeline.StepOutputSpecifier: + return pipelineInputs + default: + return strings.Join(parts[2:], pipeline.StepNameSeperator) + } +} diff --git a/scheduler/pkg/proxy/chainer.go b/scheduler/pkg/proxy/chainer.go index 47223518a3..0d37874e6d 100644 --- a/scheduler/pkg/proxy/chainer.go +++ b/scheduler/pkg/proxy/chainer.go @@ -79,13 +79,13 @@ func (pc *ProxyChainer) SubscribePipelineUpdates( Uid: "1234", Updates: []*chainer.PipelineStepUpdate{ &chainer.PipelineStepUpdate{ - Sources: []string{chainerInputTopic1}, - Sink: chainerOutputTopic1, + Sources: []*chainer.PipelineTopic{{PipelineName: "some-pipeline", TopicName: chainerInputTopic1}}, + Sink: &chainer.PipelineTopic{PipelineName: "some-pipeline", TopicName: chainerOutputTopic1}, InputJoinTy: chainer.PipelineStepUpdate_Inner, }, &chainer.PipelineStepUpdate{ - Sources: []string{chainerInputTopic2}, - Sink: chainerOutputTopic2, + Sources: []*chainer.PipelineTopic{{PipelineName: "some-pipeline", TopicName: chainerInputTopic2}}, + Sink: &chainer.PipelineTopic{PipelineName: "some-pipeline", TopicName: chainerOutputTopic2}, InputJoinTy: chainer.PipelineStepUpdate_Inner, }, }, diff --git a/scheduler/pkg/store/pipeline/errors.go b/scheduler/pkg/store/pipeline/errors.go index bc5c4107ab..562a5b5da0 100644 --- a/scheduler/pkg/store/pipeline/errors.go +++ b/scheduler/pkg/store/pipeline/errors.go @@ -192,3 +192,13 @@ type PipelineStepNameEqualsPipelineNameErr struct { func (psr *PipelineStepNameEqualsPipelineNameErr) Error() string { return fmt.Sprintf("pipeline %s must not have a step name with the same name as pipeline name", psr.pipeline) } + +type PipelineInputErr struct { + pipeline string + input string + reason string +} + +func (pie *PipelineInputErr) Error() string { + return fmt.Sprintf("pipeline %s input %s is invalid. %s", pie.pipeline, pie.input, pie.reason) +} diff --git a/scheduler/pkg/store/pipeline/pipeline.go b/scheduler/pkg/store/pipeline/pipeline.go index f849340039..69f9ea60dd 100644 --- a/scheduler/pkg/store/pipeline/pipeline.go +++ b/scheduler/pkg/store/pipeline/pipeline.go @@ -55,6 +55,7 @@ type PipelineVersion struct { Name string Version uint32 UID string + Input *PipelineInput Steps map[string]*PipelineStep State *PipelineState Output *PipelineOutput @@ -131,3 +132,12 @@ type PipelineOutput struct { StepsJoinType JoinType TensorMap map[string]string } + +type PipelineInput struct { + ExternalInputs []string + ExternalTriggers []string + TensorMap map[string]string + JoinWindowMs *uint32 + InputsJoinType JoinType + TriggersJoinType JoinType +} diff --git a/scheduler/pkg/store/pipeline/utils.go b/scheduler/pkg/store/pipeline/utils.go index b931aea8d1..f9258cda4c 100644 --- a/scheduler/pkg/store/pipeline/utils.go +++ b/scheduler/pkg/store/pipeline/utils.go @@ -29,6 +29,7 @@ import ( func CreateProtoFromPipelineVersion(pv *PipelineVersion) *scheduler.Pipeline { var protoSteps []*scheduler.PipelineStep + var protoInput *scheduler.PipelineInput var protoOutput *scheduler.PipelineOutput keys := make([]string, 0) for k := range pv.Steps { @@ -68,6 +69,30 @@ func CreateProtoFromPipelineVersion(pv *PipelineVersion) *scheduler.Pipeline { } protoSteps = append(protoSteps, protoStep) } + if pv.Input != nil { + protoInput = &scheduler.PipelineInput{ + ExternalInputs: pv.Input.ExternalInputs, + ExternalTriggers: pv.Input.ExternalTriggers, + JoinWindowMs: pv.Input.JoinWindowMs, + TensorMap: pv.Input.TensorMap, + } + switch pv.Input.InputsJoinType { + case JoinInner: + protoInput.JoinType = scheduler.PipelineInput_INNER + case JoinOuter: + protoInput.JoinType = scheduler.PipelineInput_OUTER + case JoinAny: + protoInput.JoinType = scheduler.PipelineInput_ANY + } + switch pv.Input.TriggersJoinType { + case JoinInner: + protoInput.TriggersJoin = scheduler.PipelineInput_INNER + case JoinOuter: + protoInput.TriggersJoin = scheduler.PipelineInput_OUTER + case JoinAny: + protoInput.TriggersJoin = scheduler.PipelineInput_ANY + } + } if pv.Output != nil { protoOutput = &scheduler.PipelineOutput{ Steps: pv.Output.Steps, @@ -94,6 +119,7 @@ func CreateProtoFromPipelineVersion(pv *PipelineVersion) *scheduler.Pipeline { Name: pv.Name, Uid: pv.UID, Version: pv.Version, + Input: protoInput, Steps: protoSteps, Output: protoOutput, KubernetesMeta: kubernetesMeta, @@ -105,10 +131,10 @@ func CreatePipelineVersionFromProto(pipelineProto *scheduler.Pipeline) (*Pipelin for _, stepProto := range pipelineProto.Steps { step := &PipelineStep{ Name: stepProto.GetName(), - Inputs: updateInputSteps(pipelineProto.Name, stepProto.Inputs), + Inputs: updateInternalInputSteps(pipelineProto.Name, stepProto.Inputs), TensorMap: stepProto.TensorMap, JoinWindowMs: stepProto.JoinWindowMs, - Triggers: updateInputSteps(pipelineProto.Name, stepProto.Triggers), + Triggers: updateInternalInputSteps(pipelineProto.Name, stepProto.Triggers), } switch stepProto.InputsJoin { case scheduler.PipelineStep_INNER: @@ -137,11 +163,36 @@ func CreatePipelineVersionFromProto(pipelineProto *scheduler.Pipeline) (*Pipelin } steps[stepProto.Name] = step } + var input *PipelineInput + if pipelineProto.Input != nil { + input = &PipelineInput{ + ExternalInputs: updateExternalInputSteps(pipelineProto.Input.ExternalInputs), + ExternalTriggers: updateExternalInputSteps(pipelineProto.Input.ExternalTriggers), + JoinWindowMs: pipelineProto.Input.JoinWindowMs, + TensorMap: pipelineProto.Input.TensorMap, + } + switch pipelineProto.Input.JoinType { + case scheduler.PipelineInput_INNER: + input.InputsJoinType = JoinInner + case scheduler.PipelineInput_OUTER: + input.InputsJoinType = JoinOuter + case scheduler.PipelineInput_ANY: + input.InputsJoinType = JoinAny + } + switch pipelineProto.Input.TriggersJoin { + case scheduler.PipelineInput_INNER: + input.TriggersJoinType = JoinInner + case scheduler.PipelineInput_OUTER: + input.TriggersJoinType = JoinOuter + case scheduler.PipelineInput_ANY: + input.TriggersJoinType = JoinAny + } + } var output *PipelineOutput if pipelineProto.Output != nil { output = &PipelineOutput{ - Steps: updateInputSteps(pipelineProto.Name, pipelineProto.Output.Steps), + Steps: updateInternalInputSteps(pipelineProto.Name, pipelineProto.Output.Steps), JoinWindowMs: pipelineProto.Output.JoinWindowMs, TensorMap: pipelineProto.Output.TensorMap, } @@ -166,6 +217,7 @@ func CreatePipelineVersionFromProto(pipelineProto *scheduler.Pipeline) (*Pipelin Name: pipelineProto.Name, UID: pipelineProto.Uid, Version: pipelineProto.Version, + Input: input, Steps: steps, State: &PipelineState{}, Output: output, @@ -178,7 +230,7 @@ func CreatePipelineVersionFromProto(pipelineProto *scheduler.Pipeline) (*Pipelin return pv, nil } -func updateInputSteps(pipelineName string, inputs []string) []string { +func updateInternalInputSteps(pipelineName string, inputs []string) []string { if len(inputs) == 0 { return inputs } @@ -200,6 +252,29 @@ func updateInputSteps(pipelineName string, inputs []string) []string { return updatedInputs } +func updateExternalInputSteps(inputs []string) []string { + if len(inputs) == 0 { + return inputs + } + var updatedInputs []string + for _, inp := range inputs { + parts := strings.Split(inp, StepNameSeperator) + switch len(parts) { + case 1: // Add outputs if just pipeline specified + updatedInputs = append(updatedInputs, fmt.Sprintf("%s.%s", inp, StepOutputSpecifier)) + case 3: // Add outputs if step name only specified + if parts[1] == PipelineStepSpecifier { + updatedInputs = append(updatedInputs, fmt.Sprintf("%s.%s", inp, StepOutputSpecifier)) + } else { + updatedInputs = append(updatedInputs, inp) + } + default: + updatedInputs = append(updatedInputs, inp) + } + } + return updatedInputs +} + func CreatePipelineWithState(pv *PipelineVersion) *scheduler.PipelineWithState { pvs := &scheduler.PipelineVersionState{ PipelineVersion: pv.Version, diff --git a/scheduler/pkg/store/pipeline/utils_test.go b/scheduler/pkg/store/pipeline/utils_test.go index e45db5ecec..d9af0df517 100644 --- a/scheduler/pkg/store/pipeline/utils_test.go +++ b/scheduler/pkg/store/pipeline/utils_test.go @@ -42,7 +42,7 @@ func TestUpdateInputsSteps(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - updated := updateInputSteps(test.pipelineName, test.inputs) + updated := updateInternalInputSteps(test.pipelineName, test.inputs) g.Expect(updated).To(Equal(test.expected)) }) } diff --git a/scheduler/pkg/store/pipeline/validate.go b/scheduler/pkg/store/pipeline/validate.go index 66c3a6b75c..dcc5b50ffb 100644 --- a/scheduler/pkg/store/pipeline/validate.go +++ b/scheduler/pkg/store/pipeline/validate.go @@ -27,9 +27,10 @@ import ( // step1.outputs.out1 // step1.inputs.in1 const ( - StepInputSpecifier = "inputs" - StepOutputSpecifier = "outputs" - StepNameSeperator = "." + StepInputSpecifier = "inputs" + StepOutputSpecifier = "outputs" + PipelineStepSpecifier = "step" + StepNameSeperator = "." ) func validate(pv *PipelineVersion) error { @@ -48,7 +49,7 @@ func validate(pv *PipelineVersion) error { if err := checkStepReferencesExist(pv); err != nil { return err } - if err := checkStepOutputs(pv); err != nil { + if err := checkPipelineOutputs(pv); err != nil { return err } if err := checkForCycles(pv); err != nil { @@ -57,6 +58,9 @@ func validate(pv *PipelineVersion) error { if err := checkInputsAndTriggersDiffer(pv); err != nil { return err } + if err := checkPipelineInput(pv); err != nil { + return err + } return nil } @@ -221,7 +225,59 @@ func checkStepTriggers(pv *PipelineVersion) error { return nil } -func checkStepOutputs(pv *PipelineVersion) error { +const ( + pipelineInputEmptyErr = "At least one pipeline input must be specified" + pipelineInputEmptyErrReason = "Input name must not be empty" + pipelineInputOnlyPipelineNameReason = "A Pipeline name must also specify one of inputs, outputs or a step name" + pipelineInputInvalidPrefixReason = "A Pipeline inputs referencing another pipeline must be .(inputs|outputs|step.)" + pipelineInputStepBadSuffix = "A pipeline step must be .step..(inputs|outputs)" + pipelineInputTooLongReason = "The input is too long. It must be .(inputs|outputs).(tensorName)? or .step..." +) + +func checkPipelineInput(pv *PipelineVersion) error { + if pv.Input != nil { + if len(pv.Input.ExternalInputs) == 0 { + return &PipelineInputErr{pv.Name, "", pipelineInputEmptyErr} + } + for _, v := range pv.Input.ExternalInputs { + if strings.TrimSpace(v) == "" { + return &PipelineInputErr{pv.Name, v, pipelineInputEmptyErrReason} + } + parts := strings.Split(v, StepNameSeperator) + switch len(parts) { + case 1: + return &PipelineInputErr{pv.Name, v, pipelineInputOnlyPipelineNameReason} + case 2: + if !(parts[1] == StepInputSpecifier || parts[1] == StepOutputSpecifier) { + return &PipelineInputErr{pv.Name, v, pipelineInputInvalidPrefixReason} + } + case 3: + if !(parts[1] == StepInputSpecifier || parts[1] == StepOutputSpecifier || parts[1] == PipelineStepSpecifier) { + return &PipelineInputErr{pv.Name, v, pipelineInputInvalidPrefixReason} + } + if parts[1] == PipelineStepSpecifier { + return &PipelineInputErr{pv.Name, v, pipelineInputStepBadSuffix} + } + default: + if !(parts[1] == StepInputSpecifier || parts[1] == StepOutputSpecifier || parts[1] == PipelineStepSpecifier) { + return &PipelineInputErr{pv.Name, v, pipelineInputInvalidPrefixReason} + } + if !(parts[3] == StepInputSpecifier || parts[3] == StepOutputSpecifier) { + return &PipelineInputErr{pv.Name, v, pipelineInputStepBadSuffix} + } + if parts[1] == StepInputSpecifier || parts[1] == StepOutputSpecifier { + return &PipelineInputErr{pv.Name, v, pipelineInputInvalidPrefixReason} + } + if len(parts) > 5 { + return &PipelineInputErr{pv.Name, v, pipelineInputTooLongReason} + } + } + } + } + return nil +} + +func checkPipelineOutputs(pv *PipelineVersion) error { if pv.Output != nil { for _, v := range pv.Output.Steps { parts := strings.Split(v, StepNameSeperator) diff --git a/scheduler/pkg/store/pipeline/validate_test.go b/scheduler/pkg/store/pipeline/validate_test.go index 56f8b1d23d..68298e36c0 100644 --- a/scheduler/pkg/store/pipeline/validate_test.go +++ b/scheduler/pkg/store/pipeline/validate_test.go @@ -533,6 +533,217 @@ func TestCheckInputsAndTriggersDiffer(t *testing.T) { } } +func TestPipelineInput(t *testing.T) { + g := NewGomegaWithT(t) + tests := []validateTest{ + { + name: "No input", + pipelineVersion: &PipelineVersion{ + Name: "test", + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + }, + { + name: "No external inputs", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{}, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + err: &PipelineInputErr{"test", "", pipelineInputEmptyErr}, + }, + { + name: "Valid pipeline input", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.inputs", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + }, + { + name: "Valid pipeline outputs", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.outputs", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + }, + { + name: "Bad input specifier", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.foo", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + err: &PipelineInputErr{"test", "foo.foo", pipelineInputInvalidPrefixReason}, + }, + { + name: "Bad input specifier", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.step", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + err: &PipelineInputErr{"test", "foo.step", pipelineInputInvalidPrefixReason}, + }, + { + name: "Bad input step no suffix", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.step.bar", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + err: &PipelineInputErr{"test", "foo.step.bar", pipelineInputStepBadSuffix}, + }, + { + name: "Bad input step no suffix", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.step.bar.zee", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + err: &PipelineInputErr{"test", "foo.step.bar.zee", pipelineInputStepBadSuffix}, + }, + { + name: "Bad input step inputs ok", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.step.bar.inputs", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + }, + { + name: "Bad input step outputs ok", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.step.bar.outputs", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + }, + { + name: "input step inputs tensor ok", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.step.bar.inputs.tensor", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + }, + { + name: "Bad input step inputs too long", + pipelineVersion: &PipelineVersion{ + Name: "test", + Input: &PipelineInput{ + ExternalInputs: []string{ + "foo.step.bar.inputs.tensor.xyz", + }, + }, + Steps: map[string]*PipelineStep{ + "a": { + Name: "a", + }, + }, + }, + err: &PipelineInputErr{"test", "foo.step.bar.inputs.tensor.xyz", pipelineInputTooLongReason}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := checkPipelineInput(test.pipelineVersion) + if test.err == nil { + g.Expect(err).To(BeNil()) + } else { + g.Expect(err.Error()).To(Equal(test.err.Error())) + } + err = validate(test.pipelineVersion) + if test.err == nil { + g.Expect(err).To(BeNil()) + } else { + g.Expect(err.Error()).To(Equal(test.err.Error())) + } + }) + } +} + func TestCheckStepNameNotPipelineName(t *testing.T) { g := NewGomegaWithT(t) tests := []validateTest{ @@ -626,7 +837,7 @@ func TestCheckStepOutputs(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - err := checkStepOutputs(test.pipelineVersion) + err := checkPipelineOutputs(test.pipelineVersion) if test.err == nil { g.Expect(err).To(BeNil()) } else { From b140009be2a45d7f268f0d81cd7dbbd08c1bc0c0 Mon Sep 17 00:00:00 2001 From: Clive Cox Date: Mon, 12 Dec 2022 17:18:34 +0000 Subject: [PATCH 02/18] Add extended example --- samples/img_pipeline1.jpg | Bin 0 -> 77889 bytes samples/img_pipeline2.jpg | Bin 0 -> 84755 bytes samples/multiple-pipelines.ipynb | 534 ---------- samples/pipeline-to-pipeline.ipynb | 1137 +++++++++++++++++++++ samples/pipelines/tfsimple-combined.yaml | 17 + samples/pipelines/tfsimple-extended2.yaml | 16 + scheduler/pkg/kafka/pipeline/utils.go | 2 +- 7 files changed, 1171 insertions(+), 535 deletions(-) create mode 100644 samples/img_pipeline1.jpg create mode 100644 samples/img_pipeline2.jpg delete mode 100644 samples/multiple-pipelines.ipynb create mode 100644 samples/pipeline-to-pipeline.ipynb create mode 100644 samples/pipelines/tfsimple-combined.yaml create mode 100644 samples/pipelines/tfsimple-extended2.yaml diff --git a/samples/img_pipeline1.jpg b/samples/img_pipeline1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f10b79c0dfb5c7db6382ae0319c5a55860431ec GIT binary patch literal 77889 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 z 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 literal 0 HcmV?d00001 diff --git a/samples/img_pipeline2.jpg b/samples/img_pipeline2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..64e81296836346cdc8b39910a7597d04faa2c742 GIT binary patch literal 84755 zcmeEv2|Sc-+xKN1yX?EEkg|rXVMs`dQV1bQwj|jZhO%T2p(vw}o$Ogh#!^XkvNP7K zGuFYF`L6qZp7(j5`+4rZ`+nZ#_j|wZ?efdG#(9nNJkIm{AII@Oj`N80jWh)uxu~P3 z1CWsc02%lNkVXM5fP(y&>zD5o;6+JI`O8H^O-)5jOG8ITOG8Ub$H2@$N6$o0OUuZ@ z$i#f)2+I*V239uKBW&Q$M}GMbvR|I0pripGJVH-P55D^^UZf^~g@&90l0-qq0+6$i zQLvDaS^y~6Pb#usFW|2i894w4lIE;F*!g9ACKBA@L`m}BliaXQLs=_9h0GE)w~L^abr6!8%)D~ zF8+1t2U;OHBP_@5hdp$h!e^#MaK8-g*OC3Xfj#;UjqGm&`}c8;01Oml;N(%T05IV2 zS_XL#9dHu(`SMc)KUcxejqno-{)fULd2C7Xq94`!x*^Xr0R;*YAbEd{m7VY{Sc5;5 z1hlUQ^I9P)i1K*4K38j4OS0PxasTPn2XZ7}I)?<@MeZvh!Vq|qZwTB70Q>pYPf7ew zTocKYJ4uHx*Csz#;t#PC_QaJyv3It6vc=>GwE45RU86pe>KAE? z9A6zMvVYnx|Bbc_#aFm3Zhd+;q%s07?yQiBL9m@83xJ@#TyrN{)6*Zs?RqusI8Ml` zSF+{NIc<1RJWH`W%vJRjC0wkCqlZiOS`f{b!VkP}*euUB<3^eT%ep2br}LgSt7zV& zN!#&@YZ3j5&&0W7pwZ(s{=V{6z4zQ#UEW4{9`#d3Jamrr4Rv(M;M^)1M(lX^EF4&( zJ|Jnw#t~he#592w5@0R+U>(`^F8O$2bs|MkDc%LUe5rlMH3+Wk7@Mw>MCn5U8n2t& z&ze{b&LjaeU120((Yg5Q3089|?GkxJ&|? zE|7rcSo<*wA`6m{1aza`l7J~;#I&y58reVeA@jv9KmtPS(TFYS?iB!CcZe(7=Q?avyb8igpZj^Bw!?hF5=6NGPJ=&Ia=v@n8Ukm7$MqX#nAhyjwm%J6 z8gPnogw-=W2>gtqUV-^f3rJgF13quE6M1lq#OJrwd(fw!#N9ooR&ZlRTz8dBlyH;; zR7gJ_LIe?2v@jMvsDbZ|$~~BuWhB6Rwdx$L>2SKTVXpiD!>7Z_T{6GXo#4TG2~}ha zicWr#wh*x_UnH(F5fiumqG+fqIKbRT=;}CVk*HdV)ty$e(7-VTV;YW+wg_?$uE+<- z;#52QNBKh1X;TI)X-%M7mPZ|~kZDi>?7+{L|2h%yTerAIH8SGwNEFF;M5T4wn@FS@ zgud0d?vrkehbx(>FD{y7cBk;l@rX4)l*Hl?3?iN?Yig#1t*Q)^(JHI=O;doSaj6%av#-6HWPT48!3Au zu^XU$o3up{hC{ZIfbeu0{59z||3kBNxYSc^H^$cJKdEqFAzV)>-2L6LlfrNYb?rH$7}m}(S3KRC{uUy?(-q@O7av?*j%T`}W| zO;(IUs;-5a?((t0Ib%+yGNWP@UF0}sAOgdN z#8`b>M%^OzEAXMsFEea^agvrK5`M+*5(dI}o-Uf;o0R8|Q6|m!V3|s-1|> z(k?Q5fNPU9rxmy&_AX#<1AR0@aJwLDK>k{0H`7Sj4{Ql$#X%yCgLD2EzI?i>#D9vJ z?PhhFJn;#KOUa$>`ZCuo|H3Va&m!&P@hU^c{FWD0tQM)ilK}ooSMu>uJYwf@&#J0Q z-{-2GK(W%hF62ZVC1Y=RLr9_Fe$CfrAH6J9(^4%Cx_!w5vX!7PvS*K&k4AncbNE4L zesWg-5t~;v2gBSNaNm$s4_h#G_$obbhAKv+f4vy3o;LlF-%h0Nn`VMNf2&j0*|-0` z;V9yH*dMh?G3Cng9ZKa2Hq|faqIP`B%+Up96%VB2DcNeg zRiUMJWJQ&Cb%p?P)p`mQieezxX6j~iy|LDuK4fum3FKdL%+uyC?Q|Co3sCWQ4}S1< z{bjmLBH?%$+Q9Sp`oMY)h8h_ydSKcDjWZS1L+Wof(rSu+vls4gPLo%^miWo;AV;nB zB%GZDv_N352`8}O1mVdtg1_hKKw%$0EIzL-?;)RYtoTXM3wFmgY#Ca;7#M@3PE%da z??^7$wMsV+j>2rGX&$CDD&S#y@9Qs1H>0?O`zkCvUyZM<&eT2;c9RhalZo$|5Z*pf zEV%8Xw>Fc@7bE?6eu${3hZSTrmkyuA=9RS7N*S%*CXSCBc+(@1T^nV5YJ@NS{)6F_ z_?n6>3i0+UOKjhvBt875A)$@OHb!SE`+Xy!dpm|#$WHH^E~+N+;2X|*_#J@{54 zB+>;|KKtk@ZSXUfZ?^Yog*WQ_Z}*1y3i*s$8aLj$7ue%$2Wx}zkNF%|vm^3pDnz5W zVPzMe*uCe1DLzwKr;k%~JQ&?|PrMdRt#Dty-oqn^^70H-1v;!i2(F(dH&a1#PPv4t@La3(oI2YTR#i6gwZ!L>;*$$}FGfap!)&>dHTjcA*UuSt7=}J#rjY46eS;`$EghMg_}*Y%<9uJb_wg1(?A)~-GBOrE@jHKSwoVAa0WOYeZPv#u3qYhvP_eqo6$ z=2K;*%<=14F!AyqwQBN%t+Ya#@d&4NR^(%Sxau*{pjD)SBKh)Xo1F@#TZ*uH8COQ) zSKJ8|6Qy*-t%kR|6e~-cLBFf^!8hq@-=@5E_VfH2SNMHrXosux43|Q+j6~^WJ_cEp z)5o60(g?BlIgXRf?$nw_kpO#{9VCrZCMGWIs=M3tOyhzPmS8#C_ib)X^4UWd3#okO zgm!YaWgEAlU9rO{f9r5n-3&bHTq#a5blczZ+Qt6Y7E$^gW)!Vw>@!b6XOC#kH)x#6 z{i#lVG(G>KMy2=|C`Qo1apqv4cq0@|iI5?urAFei%BN_3NazYwDP0>TK7N7hh=$+O zJBaa|&aNjdIwALWDPCitL2!BOB)SLhisnqvWq!WPrO5WtuBM^J{l)$JBCe@sFE_rn zi+%$j!A4p69jO+y)@KmxdlB9?fFc6lFM#)he22F7+%KoRYCC;HrF_iFdc zGFB!NlwZoK?JP6rJ*ma6$DFLWKt}=?0tH9l%Gk*r8&sn4!1_Xfmc^i`M)^`|$jgog z`0t6K*ZGf&9Vg_AFNhl_Io5n+s``XK%Id zmoPb(qsH2?=9VAF5Deaov6M5emBB5WCH9itf}2)Pe)`t``Awwl>FHwYEWf(i^1x!W zt+zuWnnOsN=k9GE0MI)Tq^dQ2qz0dYVbt0Q8_Y;LHY7;`%Il%dvPsTrfRg9Syn`|; zCAMmWgvGHrMxW>V#NNQpd#KZDck8kLt+BO_IPXx<^TgX;$08!`C9mrbO5Q224SC5K z(?(1Auuvt8{}CB~WbUWti&w|Vz7l9~={31GmL?hC-hM;sGFbl78C8AQ$raXThE;GyRT{ZWjp;>?9LxL2LCHoE+mrJYnoyu_82`0ctp&_E?^{E z;+I)lTFpn%gQM10;c>Ng%pAGu)n-IqG@I$SzK0aOt3^dCtC;eNM@qMXIh8VF&gCDE zrUD*-`6%KGisTnH{!lpzI^(og%+aSH| zEKdTE((BgqzNlp>V-f&M86yE7Vbc`^Cv>7~|MLX5C|*cq#MHyc4m|aWJ$OzTc6A=$hMwZ7}0qU=R|}BZiLv zx%OIb5^&-wvFI*pbMA1NfIhVQj9S<@K<+^Z3dqMGv!4V%57O_JXGuWfNfKaEZoRib z+$P!(%jT>%_X4^IkBNMS;83x#xtu7~WBDguzqO*? zm@~d}EGe=~_B2CuA&pqm5#8hUX4ymEAAj$c~-jeBvuK1sft*}UZR zpO86osJd8b+DunVRD`-Cb&f4y+pkmWl4rb6{w1(5zdI{WY+{QaOt-k~GkVazb7u#+^z@3*`(8%+-k24(49O$^?(*v`HX5fY#3?pT6 zDKqSon7~hHR`<^iHR@o@EY&)A%hCtZ_$LG0D@;i(=K7s!5s_{N*f6>^6&2aY=IBK{nf3)I8kU7bt8DVmt*_is*ti&wO;gUi zV`skaqh}zdpDXz4`cIAcp9na2c^%NY!`Iu$S$KI>_7;%r(}CcaA|2Un6>0&_GmqCge?e#GIo4lmvi z6HZ8hMZk8rD@Z_}-K)UYAE0aUFfi_L5}ATS9c;s}(qDB10$$*P|JjlxTSt_}5grGE zu>Y-tiR zM}NBQseB2SQ-M82bqZ^UeS&?P*PC47bd@cEj~UF*)K!RmBlfK@a%U9d7J|;w{QJn5 z+h~Ws=fgMGn4cFN=Qh5;*JCDEKjZbl?NMs&JAtkc5^#^1#;N-FP^%x~MELvZ`$CDU zS7KGFIBo{g4b1d+*mL-tB?A5pG27`mcGQ_UW9@D(p1hq5r7sII8NwjlkFDGdq`uI8 z|6>~&E{fA4>LXi_2Mp$j?`2<6SEk~2d66@SXNDd4$-{jlo@+sfsqqWG>38A;yQpvN zL`~EY#EKnAv|S!d!mo26K2B60){%g$mczJE#OzgF;sgok%?jYNRt@;$?obBF8nTmN ztP~Fm>LJs4v!&S8?Di+cnJ$Ih)rt3Ml!U(A(oB%;{&ceM8r*^O_^2t@CyhLDZB{fm9b}x zH?fS-0eA{bdrQDI3?h0Rt{tHIcIb;k1s?4*#(b=U=j=M_I1U1+;NUNYQ~l0HI)L$xyRNg-Gf zD>5Ki{PZW4H77GcG2;cD!aFr=F1gkIXZ;KG$5-=v z4`VJ=zEbMoc(xytVD&Noa_v}w!i6r1N4l?@I{jGMu0Fh;qm+j#|B|+MZ*uH`A;e63 zAVheoaY$T$q1M_*x9EG3leB1E*od5P>EkoGH8M3O3rb5ls3Cz@{j z7KSA$dm-=S2Mq0LYR-zjamDBrrz2*?mQ%%_8_WBjP=qdNyw{p{k4s7Sor!c72!-ce zk87wZu)gfc)`Urs^O##(&+Hqz46$_DzZ~^^-BVxRo075YYwkn82bYa+S_wX$D=?A? zbU9}90V7`QbbU@_HjU@-Ev$-7kA+-tp!j@U1HY6^9DG3@W<~-WZ}__kIum-UF|Yze zxvKU~ie%&ENvv@7z?o6B*s%5JSOs*MlZP_8u|>+j={qLZq&8b#-1Y9OMvRkA9AeCxv_t6&@-h)8K97!l_qJt$Ovf1PV0z>mP_t z@<(;=h@oE_$P=^Gtpd3Gju*Kf4H^)bBEL1lEYEkRqHRio)Ny4c*wMB|Qi`6`+v@L}HzMWCc7YA8x;MUf!w!?ZO zl_PI)H4dituBX!ZmDu-$#iGM{w@)G^`>M!#<9IV#%4lk%tfw?;;%QtWyppKpE9!Y* zPNW&mlo;#W2E_|?lYl+CdP8UCS!;igWnsn}BRLR@^Yu0);E@_g0X@y#c}LXVMQsBA z{8-%2r~Xce{|`w+UH=eV1@>__c!(Op(^5zR-cLh;3&+HTAyBx-aVA zx9lY2?%T63Yu^3Iw$wIhcn>GpNT&FMm1qDqxYpW1p2c2k}0 z8*0_y5xTGJik@#hcNMmX>fF6zcxS?BVO^j98{qL(QNa%oH}ne=`{sEfTl|w!o$n`u zPrf5-2g1>ZBX|o8|Fvir&a9F-F8b;@fARaH;@@jsy3$^!Me(?~<}Mjk;p0B?%%5x* zik>~Viqw+Xts9FV9FHJuOJ zPN{jAfBwGHJ9+$WeRV0$plX-buCqINWSH#H@LSRF&qp$*__tO4QU?Y@83K=eO-q`g z%DP#rCQyY+e>I$%sj?R+aPCb^wqoHkzar1d)wz;8*Q0XV+qY-wmTHIU1Im(W-)F6@4il>+7QL|A z?ydpi&Tanmx`rp5DPve3$OdIyUO?z6OvMsRLV(thAXu|KqM+z)*9AOW=#khe)&Tb&gA zfdU9_zcf2Et7@p!u2A^W6}wBkv4L;uucFo+D+gfIiHz|3n$WS!HDNFN6>p*pnLb_=QIDaWx)Il z<%|k~@&=xOYhzu5335gF#J2rcMOoFG&Z*gea%eB=iHuqXVxc(O>D^c&Ka^n+c0|?JcSb-*jYCMK=!<{gN^c@vsYn(LH+)TB zU|4C2sZij;_2`!zl@yPPo4{Bl#meO4NybLe3AiM-b0QvBVuh_|9j?fGi_ZLBeLBCs zSLMCql%v6%r)r~`jD~q-F5qSyvZ-sXlqO5 z#F%~02X2uqT5;myLI`fzCu*j;*c|=lk)rhOIpf(azFQI@K>?bxSAN>6f5OfGrODO7 z?M^V2%LYJZO-4b%=c3B)`w?*5Z1#+)G1jSuC45AKN8(bT34F zGU1oNP6CItJ4xl>^@RI)6ozF9^ zf}#<&gWD%V^ju%2U6AE2U}@VqrnfZ$xj7UO(<;`Lz;{%w>ir*|@l|KTza{}9T^Pf| zFiF_fu)THe1KoodLmcX}=p4b7cxXtV-;58pz6-zgZ!9F$jWc+c^|eZNds)jur>Xb~ zN=gQ|HD@{>pS~iM4qtN;AU?XOB6eHEDEeeWraycY@v+k4<@8@DW=I3E4Yt9E2P2ra z64v|oD@xjZ3Wz$}sMX2C6QV0{aT0Jm61KBTOcGig*_&DX!x#-kCsCOoY8aW$sc)ey z6n>-6GUr`9ahdfrPG+SjbfMH(O;)^s_Q`(z+KzuPcCGS_6H%alp{KG_-Cun4?kNd5 zsljW@Ys^=4DIY481jN_exI!&tMexPnpm#DUz?q`sAKsUkiR@@mz{RdI zcewZl!RB6scHObn5azcfdz?iReeW%HkDFamX?3Fv(xZ=tCiO#` zgH-(fc;f$C6EuDsi1?p)N0Ee&!3m)e3?3}SKA~$O2^hQbzO4hL`sL1xt0Z7x)S^W> zK}W3?puNq`3Me6&;L41y7_(9C>fvG!(dh3v?=q?);EMQe zq#jd}uKvTk*uUG%A92tSRcXw!jU&c|yxk~9lXmBc@rdg7$?@w4kHjxrf2HVimTX1= zO4}$FYcUQ{?*d^{P0S)-BAFANPMM+a(rkN>E|y>nXL$vEoS zc+&<@@saN$0G9Wr>|_}u)v)yZ-lOCgh| zhaV^1PJEt2Ej)`hj@z%{CuC3zEdCLH`zPk?|Klcejlyv4?nWLT$9kUy}X2 zUOA-OO=SBXYcUxF^E3Ek{g{HtTSARAAkx^;>EdcBFtvo<88iH7vu*c5g-LR}-n<$9 zVGjwI>m4e6C^O#`)2pD-Ol1yi^Zo|=jy9H6_7@hPSzhFHcFs-b$+X$11v9V@j$FuK z<~)49ww8(4&ha^W{Y6$kf!5P|>Hu8R2rs0ZCYxe0o|RT}O&HPuUz6fb%4)pjSLFW3 z@ga6HEb<@8cC8dNuY9sZO=Bl=={GC*b@8H#bmSR-6thp<#mfGz4tzA1Ny=5)kkAaQ9WY=NC$sPnw@d=jUx9F-i)Uh|Zu7qt<8xN9PQxcR~c>hH(+k!+PyanSr# zQe*bp2`z6&Pu5OK>;*w(Tbm?L8}up4Bf6BlK>GjCniRhg$X{nGa(-#>Gj&aUO(e~= zbv^OWtJ|WH!2Ein7+kt{^DqY|)I9ind109o2NtMs)8LuJHmXAqJ$JFvM0OJd;b9On z-Wp1QS}gbB0uNh@!-&cn5Q21E@Z^?RJw50Fb0EQukU>G@YHwQKmzbaePg+NIk$~7M zWZ+(ynesm5bR`GVX0`3Xniwa4Arx`gv&1OHU7?Bmww20Q$3AKc)4zwMAJ)0{8+Mtn}v0;g;Cz>xbXA4|HHp z6M|GErCSAg2EUz%!br*n{!@zjUD^_`atg`SHovhwbK#x2~b#yvBR37YyPlUP(+_3L%dH-DGg?h=1vA8|1 ztvy)GP)5V62X^;!v(BHUxDRYE{RZ+u%}IfNpe`8L#~YTq@VPfo+)+H=d?AE5+81wA zqe<+qx;xyoq@5LBS|TT#?UNssAy{Ii^jo<6-8(2Fv0K4q$~tC3q!Gtg6pO^vNP0@j zZn&4xR+(#2mimUzv5IS0+;y+)-%LHEcwDZkAQ+7uc>89wwyw-i1Qo#Cg>RQ=!8mKN z=`iVupB1kx@b~JUMomj#OAZ-EOo`O(MEM;OFroz8JAe{s5ifAC;cs1g+tLJZ?>|K} zn@wBq^Hh`&7~=>I#GVgeqUkrV+JZg-eQ=fsOvKCvX9ESMk?O00UX+$X5=aP_l7JZK z-#+g-!rm6P(2v4${gU-bYafbOyxWVyD!_1=2fASDDGappf~7Z^S61u^`zb^aT)+(1 zzw6u?gu@gGSXe<|MTjj>2=yg@D}V-Tihx?lyDeFqy$q# z%S(})OV)T0(ZF1ykn(2KmYkzCo)3!eIm`szKqT15rj)(#9WOazfIgTX`%AuTvX3b- z%mo|<1=uBCSj7Xx<_-+c3ex1nuWg8~Jj9eVnBdCV1?C`icV;7|?jdG$cVd}|f$iX# z73+EEf0x*_?%={h-smJ4vO9|9%jz}65ghg9K4@DG{yJ2*4w*8q>vq3RgL?L1ECH79 zNTe82y_P%N>C7BiS=H}>pO4P0d}EAkYAlJxJdeH;;1n<47)s32Upkf#@L0*lw#txwaf$EoI3Q;+&u5J(g#>Qqm zHmeVeF7_(#x?5jL3R-sft^On9G49XIwX=Cd^YM6)>bZl91F*Xtp9osh&S#@QMU*02 z*;e#MBTTPecIDx2@&#q*O9{QBv9|LU+7v|qfAzFH$NjIMgY#Xn+se$UIfZlR2xteq zxkXp|Zu;3H8lk};iS8c{^7qijekt%+_nAwGd&{W-VLG}a#YR$UfwxamysX6!U>~*; z>ei#w8LAO$9VOE;wx|~3)r+{4K zu=Tg4EA&MwJM_7FO$j^{d9bUkfZ<hro7XRUbY>**}@LNCP3nT)kR$E5%CIX&qlVbJ1|-=0>YY^2RL>6Bq@N z-tjrH6R$aycFAKy73L@iTYuhqcd6h1)8Ui@Xvmb~!87#d575^5Q=oo%lD#TA4i-Q9 zhj%ka4C{WeneDNY#E9K66!sdZ09kY^kY1p5P1iMzI%HdCL`=P9CLWJ-R9^w(M@Tec zUvz?(1bnyzC1?xw27H4M#9?5Or7gpH&{%o&9EOin%Q|?+j5k3rf(JB^KF%b7>NEn! z?yt9d3yLiy@`0y2)UiWEx?3awb8;tf4GdVB5y0|FZvv)E2<)IjZ@K!jvp*&KU$hKp ziq+ZSlJ$mS>(eEn_J(VpGA-T_BCoEVsC}n=Xt-m4_^L8Q9D$WQtvkg zDG7%;#!-`rhN??Cq^nd$PdO50drf-h61%OxiJiPZ>}=ZQx193=p&B@KMiS+)Sg!(B zS%NXC>P}H>9&}#35SH@>jJ516Uug!7NT<1@#Y;Y^#(|s=u-ZanQi)^L{@3ul5hn#M z2a)R9iWhgo?x^ty=$Qyk4Nh77PR{SYQ7M11SaAB_erBYaX&uZ~cSXBWSts>nwyzO1 zi_YPl6Ngt_UUI~he<>t9={qVo^v}>qHa}Sb36_uJBf$KTH2KV2K2~eeEIy9krVtJm zcFC;%!aXlsCJ!S<-ehrHc;A>|iT9s*#f33_XwCj>qEtppwj_7h*2 z&b5zrHY1HrSpv#R9T@_Q|NIyK(YT>0x!U?y;)K``n51?+`<`yB@s)9q8e_~$%128X%z_sm_~+Z(y?Znp{9ap7l3z^ecDwc&MF@@8&Cxs#56>U7=< z5v+7QHFOyH!8~VO)e{41M|Iifhx3D~mhe)j^_H{av1+L15spt10lxQEsK(`XKsWEq z%gU0bbxPHc*-rP@qhntT^Ae2hVXtoEIIK1hJ^~yi&4!^0r{=y9WU;SmNr0Cm=P+b3 zN$Qs}gs^{7kXAp{=1(2}ztVcj48U4U&F3Ijr9&nd>bk69nw5#LR9>ed?F!@sMA`R1 zjQF+sT3Uf?h@e1kF*Bj6$Atuxfxdj>>Lr)`!T45_*xp;`)d5R9d~cGWQJ!!CTadF~ z=UZ7dxIzpQxOCGdApYsWAoh#6E~cOMHI8fb?3A8N5gySDV*FP2Ojpm#MZemTyz2Mf zmCp}F!>c)l3}tepV{R~IHp40)XcUJtCy}G!eLq|hWASp&92#-&PM_-uq1?w`1TDYH z4MLv!4|#~`ys5Wr+KPPlr@~XSjmO~Eu=Z%avt|Ut+>5UATn-+cQlBBU{qm=RKE+N< zoVL>X_=&>lak7|l_NkKv9k*2Xwz{IBT-;qV0v9)@yF!ubR*y5SN_IL&5Pfq5U(Tku zJv%3F1`<%BTIB1w2`vYU^;KZ)gWx>aO??%`NA-%fS>|;w>^O1L3s1KbOqG3a?s|*F zJ#_x^O7FUN;(NaB|9gfvSyHi20lJYF38oEKMme9VEa>m6*h+dgq$p9?!OJuoYKu44 zkuoj&#>9o;S|yu~3!hNyRp&u8OJYh`ed0{Zi9Py~5CeWWQb-Sv)K|$#=iWywyWmNiFrJF9u!rDe-x7if^=v;o*|nzk83(StJg23s*inaS&I)S z9=l+lcA#*2-*W3!=R|so)-l!j^BeOE5ma7R+xoLJ2gsbY@eBUb4LU>3D1j{+xJaJm z#i~K`x%wD|;JnZ6bfshOs7FlHj=rbUn-;XHT<&SM3nhN z=?tUS(3IgLd7hP$ZGSgk%w?l*n9EQd3F9h7?AX|m9_?|BWW&9?vSi;?m_jr0w%VoG zh43x>y)&J%6KD1H9Za3HSWg-o3kH#Ca4r7k^Z#m5VCkP32BElTV>N8B%&qz)K!FD~ zmmH6=KfomtSgeA0{OLp725qeF!9E1v&h*28?%{Rsm zuG4jt18^J6+2Aa^?L}o0a0%rpVut(tfi*1IbV|ZuY&OUn-Q&6NxoQcbj}4zLN@6a~we*_+#&~*ZEMZC^&!|N>yflU2&zUsWrDdH{}Rv%kHBlN8Av1Z3U z84{3U#*Kl%mcBhPq?XeV?D=EcmP|v?6jKs=6>)zY&ovDTN4619l_O4UX~E*NzcYUi z@DIE3&2z(+)eszc)7dcjg62o{-?-lq*i+irS_=u@I3YX+ck{Af+*}%hdHB6Dxwt@! z!S$_#xwr5Qg@B$}llJR*SsogGA*a!v_2PJEK*xuW7r4JB(DVz(eSuB)ZUdAd4G zRT5Kxo?ia6wW@!U_hF3K#M%+>rarFmdX{QFW%aSavezdy4K6$P;@Do@XU5T3&0{!8`V8^1HZl4c}(fTaZ(-`}}US(n7RYWw11B zf%fvfpaEQabV}3yd6haJ+ZNu%)D3!AxkK`awQ1GC(fP7Fx8;{Q(;-Edj(uJAXwX=6 z`ek1;iB9jfmN3CD4At9AuQGKQJzDsnQtmMF*s`5Bs~j*`jI84{PDk5-d@0<1uD$3>@wEvSn{SoO}~u&p#3fFK)0Sylf@m(oTjq>7rz<71r%&JKY5eed6g6Ih@|d-UbOc{WFj5)`&bs7m8cMTy zfu^1eTVjX}*dB_kY%pJFA<7O2u`F2~@8>wbarA7+k)wN(Mb9?gwTG^?PD;VSDj`GO z$>Tw5;xB(^AO9BWC}xqPNOU7Df*pPwhiH)$?ZUPqpYV2A)p(>{xLx7Nz^NT4Os@5i z+CZ(K`@_YX<H|F)_G~YCt{b3sf8okzuHch)ODyZ6y-%*_3zN!V$a{&MSYXYlv#@(LVzO&Z=>I@HdmIp;d= z{#s@5>ffpi1`BAi_qlm%_}s*t_whHqVKt_KQ~q}&iWZ3?y%Ge?=~bg4qds{Wqxs&o!K=d8TF_#P9UmyY zIlc$`fl%~UJ^I_1*}#*8a}{{!X*2n%(nO>F;o*xeU%c5xfViI1FGN*C&XDp1W8o#E@Ykn~8Ho?UUvy)oO1LlcAd~rBH&l~ zAn1?7Z@=5SKYr8Jr@fWPk7W+?gmU{-UyCyA^>}}2SMF0{@JlLV{_^r8`T6v6rvX-t z{1E=xOo67EKt>9U|rs5WlH!N{RDcvx9)8|+uV;_?n!2%$|7$3 z8W=g`YxI>HJ`cB-Amye%(#rPu#~M9w<2Tkmt}W*Gc*9=gY3vMnl^4$@pWwC=`i_t7 zC!22shAL6vf+wo+(ldt!{&*>t(GUBFeRkX8cWzcDp?B*;b-WQB4q$@v+g=IZoZ3# zGL#uzemIaSVAvAX9VI$7GMtWdgf={L=WHDn_r(`FWv^+O?vX7{aAB*%RXH+-@wUx= z@^6!}Z~St^+lBkQ=F7x2J>g_!;RHS5M5{Ad^Lts_6ed|eL{B`*7`xDX8M3oAa0370 zP2of5L0-$D(Cl=+7nCEVFW5Zp1qFQwQ$A)Y5LBXfG3#AH{Hp&xS&NU*v@80gD%rsW z>v3o1sTUFimpmV*(H4{Lv77ofHaj2bG)!bIU)x{TRr8W#bxZB_wC}p?`o?RI?DGq(ttDU2_@szkqUlBx;W2ZxwuGUrUr7_XY5h8Z+ z6}QqZ#Z$b0hB+Rg3s&eodBbW+w^jY*(CFoXZRJYZ?BumCbvo~q?h19>7`S>J064Ps z+*RKB3q$BJ`bcsC(HW8IloD90G~R4?5*xxNQZHh6aPO|>ecQwC#QTR+gcfepaFK1N z4?^KI7UpJuL$xoY0-Vi<}FHI`kg#YM=K#>pQu-NnJN21F9fj;MO`>8qTSP+Xy8 ziE2T4=CzI-j0XZX*p?lJjT_hOuh^>B;TGHg`++!8r;4LaaevE0EX7qZSq z)nz;`h2wfd_5uRq=n^#LIbEoCAn%M@-1VEQ4(@98*T$aNHM*3-;@D{Ot@{kJ{>Fz7 z=X@FK8l7*9j*1g**6s(7Si|Y@_mLHlR#f;^N7IOD7g$rza<`+9QO$wMlGP34TA?o; zA8Q`cvprhz8+58Td?q@$vq#o4?o=ySH;o)NypAt%&!2R#y@ca+X44pARvc!#qviW} zxADrANIVHhwkdCOzW&nA_}ZifkLNsC&Fswb!a3e2SSUeq*&44EI67~Cp!j8`V^bX= zuGEHz3Ji4Vm!A1c=O%pGLASd;0GGIv*MPfR)H;lv2)04I)sdQuRgwY;3A5yx+ow(9 zFNs&YQ=$t0wcPKi-m6O_;EECn5LmK02`2V7k~<+-winr&QUqC!FJBqDx9(cem(TdQ z$g8TiZSKqM)3K{VZbTffrjBfGM#J(}bt>8 zaew_~2TEIq(lG7Y_NTKRd722%sj!l#KCfC(q;ed#aD6WL;ec7|wZ-xzj}W%jNgRwN zG#m3dz9C!^JvbG9I&p!x>v%5Pn=tA%UxQ0=;vfCSoL>;~!)-sSeiSa#t$sB7)#{gB zKZAxWIsMG#{d zUV&pAoa^51xbVf?`$><^g_s-2^6~sfR>RL{$#E%HKB$eUpWqJlMBP$z`U4+0E)tAM z63%<(1|A`ZCR5|y<^b>O`$eMlU8ft=BCM;vHVB#=OQvDoZ>L0#XQnnc_;km~QCLjx zqPv*j^4$jE)A%)E-+AYTbHt5n^7GkVBw$(U{$15i;w+z30rFfr@;GFHiE(!4Q5B~z zKa|M7L-yaAC?#SO(cv>k@sm5_`Uf692qFurd@uemab*JW3U$Aecy~<>#ZBbjG(Rw1 zIZV+X`&Ww4;#Qr|R}Yc$X(dkr>EG4VVg(3Y?wBqn^R_!G{-qsDRWeMP5J@+329>pV z$a8M}rK!^7!*Sikrdo-a@cK=+*b$yO?UsPOs08arVsrmc+RlIocK0CCekDNZm` zYp@77FiC<3g`}%u(Ub*kfo3c(_`>96BU9&+n;u$`#=g%R0X^$#g&x)JEyerFCtJLt5eE7po{B!u@U$ASa4I>F=(_Iuk zeh00Al7o_44Wb5doi#PD-sQ>#0sQ5x=kjwUzGwgmRM&6M@7ccRhlHr|U|`XLqP@gZ zgsVNGy=NFXt*dvM#hapKkquT65j+Tb94B zMP<|zLGtcKVV~PGXkKjU8E?JS`>RYlw|H2M3q~0jP_%0*~ z#mY;qt&ryjC+Mkx)m^5T`U3k#sz*!CM_>^K&-ui)lEA1<^E4k({e-~Qtj)puE-nVe zDq9+8XPd1u%-b+9!(Z&UP87dG?i2F-+$O*SFpZ}815@eOeMb?2w*_|{l8!l&4_#fG z)J_m-JX(hnSs%R5?bv z0=3xcs532%eQQ;vMy-OU*w^%IJ&$F^b5old@!TM%IbO_`r0lM}1QErKwp$5dT_dLO z;yByu{>yuVy4aEkQ8GmJsx6Phi6*-0?vlx?!D7tvy8Eq$2*!vTPbN#QsKwT5{0_4G z>QOL3W}q#@f&4yxBa)EImu*`ckJa#6hgCdk2`Jls_NtfVvnEJ^nW;!PjDLR2aU!qv zv&B)lMh>`A)O34zc2&cG@E}~PU`!z!!+76=ULhxN%Jo_BE{g^&zwMKm^H=*s7n}!^ zd^b;@z1Z?MNc({+^P?{QiRYO4u?L{`Jqy<~WUji6x1D*V5u-@-^>MxVqRgeV_pE-k za2uq9fA%f#0@%SSAsrfC?*1S4zB{g|bxk)I6h$R~(o2vc(iNqbfJhe*5Rfh+NRcMe z13`KbkgimbE+8GGi*%6Qq?6ElLJbh&U7k5}&ff05&vx#dnR{n`$A2&@E316vth)P9pcWqZnRQqog7a&$k$CD8r?qYqvgxNdH-ET{->SGSYH&-21bYDEzT{0tKjq- z(?Oi4jopGS;JYwplVi+;)PRD9wwmb1phyNc>LhSPowC+fh@Out@7wUj@y7`?uN3Jc zi_Dx@uDqZpl@}?zMKth_y@sC{_a9FYPK5%EVP*gt^0LzbTZS0ztc;Zux`BHtIYy3Q z$NZGnq>l%cG}tz$!guX=K5S6zoC@^wBEv>BSDyd@jPUrl_@nw%q46@ci(?|5?9$QH zx&#j|PJJZ=D8z&b6eTs-xu+K{+`7J|a{OYQ;!kjk^ztoy0AvWAV!5vu5SoiHbuDcg zq?>`PaVCakwqEaG#w<#6;-cD;_*1^Tmm)w{qHbf4RccFy%Ldbd%*4)lD5*uyaZ2Zs ztqcpIOM%rmg+rbsu=v7TaOEGTo&lC*ooJjBro63Dg%PENHV&K*S7Vs|tQ5MU0HF*D z7Y)!TG1yq4Q7C<*Z%29a(z#aojYJ>FV3Uzzg~Zlj;*6$jEy;U%>(zsWEMjTZm0r2rwqOoMKYAbOfmlV2s3fUe zv?fZh5~Xh_|0$JpfX)u;DxF?2qQN#sf#ZgZ?QuDL1BtV1nMTY;n!Vh91Cv+Ex0Y6A za<{Sg-LO6QY66|B5ejub#i^)|@ z3#}8pAvu`2CRk|cNG)uWFS%Wbu1?}FT6l0ugyLReHrusL??&voIYSSv0e})mQlj=) zK1}?yxVvqxy&OsA(@wo!b?^Y{N*s8zGrABxI-veOPg;dw)hXvkapd+5)Up+%7w>m# z4MO57ICB0wRR6ts5&9%1!fdAB51{7Zs={yYi1)W-mCo|069gO;oAX)&Xm$ zjK7s&?%D3WR~~Y#RvoZ7{+wL)7B2&-oncWy?c(XeNGU|XHq-5C^IcgU~SDWFBh9_YyU`Qa4C0%WD+PxQT$4>9MJ(iV*0EY`H0tbYE_hs*2$ULq9&y>i-6a?fLs0C$ z$phZs%#o~9g)oSL!87C)g7(0>;rBE>(M$Y*d+c;WmIdNenON?Xp?bE-4pR^AyILF1 zuicl-6lO`Yc*8Ta?~x&qM=xt^s?rX*Q(Rm+$X&2IB|0uP8B!ieiRpYF6X-Havl zAz-C{jx37BM9()hb{x`UlMFA=OJp%yaedhV%GI831vc!mxB~w@Z4ZFXj&@ZVROAW3LuHv2Cz8j?7$9pn7)A?@b?~`kODO3Jy@W6^0rU} z46OqI;GpRz#$SN4mM^|154&JXyE1q>G33_C*=cbA{AK{dc}46YZUS{G{E$6gZs2b} zAw9*zPq`WdgrrhTA=|VL&QJ0a zqN)WrF8rxXAqH(jLiwQpt2>Szv-pmF@d@9%{ClaMgNBmwg z8$=EQd__jW(SpJ)JO^AU;682E<`N?rEI8iI9N^1@W)7d0NMVQ_PZl<2<9^ z#nkV(@dQuNCSILXPxX*<50q`p&7>^CtdIP1S zRsh)D_8W+*0j&stlR9o8o@j4_fE*Vl4?wop;EaF`!&dnX#M*z7tlth4uC^9_1IcY+ zfZawIH-n3o-*>WO0*YQ~8&2pNTDEZH`iN~6=)bQ0uQB;wwN8wxk1;mKLO7%3Z=jl! zSW~JsHdNsnu=s74i3(d_p$8jb(ESIP_Z%x%a|n(!2sa*#e9INn%#G|fLx?!EwHRYD-PMva4XeI z8>rmrklY(AVi5QlarQk*5D8aA3x(A3pe!W?;7q0Z$u1oVwX(@CBLw>Scs8k|B^j&bqZ((~X-ZpU;6h-_rZ1T!Vv{PHaQRDR$q`K*he z=l6fl(sES`d~6qjU@Qj|wUT%@7}?p4oR#A`k)cs~U>Aa1hCE)JiE)LM6bv9?i! zf7+|w{=>M^FKld#1Y*A$tCha0X?bK;7zDplv3*O!aQVnJZo)l@w4~-;J3;$oV!Us+ z`vZ77Lug=Gy5h%!;-yD7;Uwf~Z^$B*7LpvPt)h-Ep<5}p_d)R6Br95uWFs&e1Z z19A2>~0GQ*no{5cxDuaQGlZ(-XJ^0JNuTOT}^l(-hHxw>K)To*AQj*BW^Z38%3dN@Fdso<&MFhYYF&p>;Q9vBoj`}p0TNE zLHu-DkCUS3n{Xg4hL@;XWNT27df%p7!(|QZ$;7-&dwg1eSSF|QP;37ciJ--bLF@0 z0Kry6vEKl1@Lcz;8^;n2!6Of%OKw$Ae!w18=&venT4Uv)#Jiy6~0eLytUxzpNRY1sI^2&u(zdGK{V zDh3VTRwdUk1ht(c;Y{*en~;Jr;%Y#yksRx`gkEfj?ihOdSa3(dGh@5C>EzA*gTidT z7*s~}i(eagu6E{f4878gI>keiIxT9&YN2yi z<%qq393TmhI?+c32DSykd7L;NELiJLh`oL(|oo#3u)kvxDhp zWp!B_SkT;e7BtG1gq$aET~5V8zj-_A6ydPPXxpk95fw={QeU4BIl2!Ro39f>?{W3? zT%lRm8;buLKbvSAyz+P_<|Z)-?=%iU8I6PVtDIW2o;t5m`_X2g*YZM%plB%*E8e`} zBFurW?^H8y6%`N4W`}YKT3)f zf!>ptuKO(l9|#3ba}=S4dSFj5SAwT%eqFk}5g zhZ!m$!}|9QGonC;8Peam%5R)V2oKf(fxLW@=Ed&HjS{oFq-W_RP%M3Lw}9?}k?ACz zn6~7OdEGkUVa`Mm3Amcoh9aQJRn>0=0YQ> zi12EUeUON`dN=49{sPtp6>$k0HHu1Y9kk{xw|sMpk3?T_aRtvnXlifT(t;$qXfJg> zs@UHk4z!o>kE5FZ^pwXh_suVip5KhsFTVqK)ic3ahL$i_u$kz1oeK0;xCUFma*u!6 zhBM)D#Q~;}oq^oxWZrG=87_t(8@+_ud^2ZV6LH=;!2nN<`SAM19v{g}dzR~{@XlL@ z?a7Jg1M>)$w+{S-)&afOy9!S(4>u-!1AWv1v~0s}oI8!$@d*Ue1`uw^ zFWUhfV;=Ma=H2HRfLN)(i_&Y+>Nis4clHjE5QeX@qJhkd(KYdtPR$+3D+9K>t>()C z7H`0w_lubJnLi{QUd{Y^8hd(9xiHB1G>!&!B5yxrSLWf6ljo$oJla_$vsudOi!RJj zJ$fBg$8YdQaFq>k@L#swQkI}aO*g(OTb;c|&A_fs0fv+WP% z2}vCjW-YVL31j{|G7gXwW&=#5695ybe}2R6=--$~@js_uVu9-mc2z_iP#C z;&_}JTn3;`3x@!-X`{cUP2&ZsUjI&;<^<5DUHR=re)K0^c!K9xif0eaqrEeCON9g6K>L@ zZC9$)jBvSJkt5aKYs=pk{Y|(m%9sQzub66t(XPo}KC&tLGU_tQLCCS^0s!Z?N3o@I z4IzYIaYX30*vxjphL<>b8*W@ROA^V{;w?F~IOJsl4gNtxt#h*M|*xu*u!$^)Jq{~egy*Nu?;8B)aJPkj*Ock-oZe5I7Rmo_r5Q`Q5_fTXaV({ zScv$_zXpgx0eka?O<-NIAr@7l9H!-qvF4qHrei$NKJfpr?|@ z0-L-@>xPgT(g~;q8yWgNE#i6KE#D0zKmIX+Ev162|11BQffe_hH!5^UsLWS zwW_X5>Ss^Bn4vQoHAVe^7kYL_`1JjG(-%es!rQX)MNpj;_pIcCm64;0NRNwC$&-&B zJPEF3$z7JtJ2m_ZmlA9^z-r0rbVo|}O*jagd(|5zg1-S*8J6U5?b*_+s)||ZYe%m* zZ+vdFOO0Q^?|^6`3^08lkgyd%Rkl1c#)Z<_rTx-yv0S+_u4h%~HlnUn3V77QQiV6%5Tk}yt^~TPo!3RIeCTOV`M2(BCuE0#09{D~VBit0egQf| zq1yk4c7~EIu{&Q8ExX% zzPE;&`p2!Im@OY-C`JW1pG9q}yu=SeC(dOAy?|JaG8;~ZQ&G3oJ0_&&1MLy>B`PBX z@Rs@*=y1bW3iGjY+|1Q2Ecy7VyUk7qLwK5veP5D7vC@Zo$Fmq6EBaa*&mL$)3b0dZQ{1>G@RrBEx)(iXXi^ZSka!uKV zHPxmn3iJ+Et0z>a6X+flQP|u2tqN=z-`TQ$?#Wk(FjS%45cctwSlj0Zf>eA#i2WOl z->HE0eoY13@=GeA!O*K7BJSOmSRaq%>N2X4qsOK14OGr7 z8ZHOM(a6(3p;IwtO>*0K%P4)UjZ>~ixB5Ss?Iyt#Yzbt#@y>@8tyoAJ)~9=r^NX>N z>`le@X|XQx#4i%HYi)q;o$2)xH~fI5YZgqoie8x0pB}4UkkA^%Mz%Sz_`nK4o(RSi z%-=gb1>Sc@pGnS_Mj=FNF}4J}^OY!M2;D?6?cvYzGX@o1r?1?`Ui4{#TLVHk+_ zHp5Pdi%AwZ0JVkHK%~|iuJUa9@lilv@xxk#evROn^Qq2{cW(5L7J%*{=x`2b@>tAL zlZCih_8pO793{4D;$-F4L_7)P*_8y--t$tlDS-QihqyM}qh*T^<0;#)m}P+Kg{$1W zckyJVbn?AIGo$1^`8tsMcLe4aY!m8 z5uqoFUjZC-8swN-25AnB2!N5;?uFghw~8+*@b|U3xX?KpeT66@mZH6#<%;xdAJI~G zcX!JIU>`Yli0{-Wa+lnA;=<1MIz^FnK3a;bkFcUrM^Na7(U^ha>1LAe=B`$MW4js4 zE9ou8jN#W%cN{791z$5Fa71rvCt%2CEWfZF1Qs=2{Pc+~HnQjp!6PE2!*wmFiF%7o zAIVYGKQ@jDN)%qT4s;^bFPGj}2CZ6vJL|7u2R|E0o+JW%S`m##EQ5Om{D^bbS9qUh z>uNIh805B1nM|pk-Q>(ZCq1t81roWAnCqOuSFvwX9B=R;+xns2T6oqvT?q^GCstle z1GhXvt!T3s6T7)Jn4KqYOUKtd zcSWSnH!6HzWpl&Kw$Aesrwl4lIoWCsP+-k1<~PL)UDMjSqRT-dU~feh!c?Wj0Bh9` zoDW=u$LZ?LJPY4db!iHkY)W z7pQHYz4=i+I?2goM)J*yAD&Txo81Pr z9k%!f0}qq*Ro?5#-#~E74dy(WgnwignRnRaTzJ{^*{es3Ic21}?%0b}hA21}VoChW zYP2r7VEUwt@}lP5YW{+Xbn6?wZ|*p9xgoY5Vz9$96t@fc{RS7NyT#o1Dem&P8+@?0 zPPEP{T$$wAv*F!zw6V<9>*fz@6<*YSC}B_Hpp?SvZ~06!!LG!zDA%u9J+LhIOuTb~ ztTm7OfG1D6{>qgS|0fCL1D&TLc(o(M!imHjv8dv-h-{6(5zg|{ZahW_ift}7>o&#& z8Wi|KMUfiWEJ2RNb+D zvH}rm>2>uv`h%u@9@}}lZYM13%&gemq1j=ZaaYqg!Em{N2MY$`wsrSsBM-?%-Zwom z3Gq$R)V8^Gpz{1ti%GVBf?tA*VpfIao-tb4sn3ymS^#jLgn;~Rk=ZCd#A>!1F$u^* zALAosi3`~$_&_Y+e`m7n3IXz;8=zp@L)ro0_>qS5Fh_wu(Ez8suj3fzQi&Sr-oY2a;KhQoMMwDK_};4lA-|Ob ztEsNS@fEN_pz@0)yK9Q}ADTEjxLz_ev0FT{m$<;AcYmcyS$4vnE9=Fa+IiQ(mT{tH zHA=o&07Y?axeDHkBTx4!S^AaX-L<#3)beWj z&W@hi1ydf@r+ItKr3F-?&qAiMtmTv_SlCM}7J1@OOG*Iii>Y(e14C(s&mFeQrd+nG zZIPYxFFrnY9I55Ba=MOvkfSK9#HpjA*Jrs|(V&(6W^>p+JE*0jhews)p)9&?F=1@W zHo}-$eM#5aT;eKS2PJC9bLi5TP)ybFK${?l;bvGjK+QflofcBTpqQ()t;#$7OtZwu zxu(8@1?F5&i4D9wM<<)hbtwCJfzSajV%1UjV*p}f6XgRhKeHS(~g=# zrl<44g2(=WO@s1t3cH8J7{QVQJ+tA_L`$nT0YFQ)1$Y|qIhtP0w%qqxX)+9kLs<*1 zjh0lr5%M;LOWDrK>7rO#vTSv^fy5Cd3GMgC6J18_1$OVOt<5OB!xc6WNQSs!WA>-d z;^;IHcf(TyfEGC18X38I1N*!}%NgS(4NgZ46gR%=XpPj(ZNwA|x3Ig|_U;usHdWj! zKgrm-TEWZ1lW>KiJITI&4e3P10f-bC zBBiw3_p=Few>uT5`JdV3jg9rF*cA+ze@G?lKrtA(_>YKad}WEfqE9^5xD~Q{9UbEk zn=uk5*IWN`2XpCV(S4?r+@7`aae=%(@!7W!rIR5dq*!Vrg50K7$cC}zR5xMu zWtUbRd~dnf!L8uRmlsScthX82V<>I(0UkhifZdCI-2jmM|K6i#0)ZsN?g8%qff`VC zCkSMyjUW5XrdzBAir2jhn|HYU{DxDO0k>TvHz8JAa zM&dpvipB68itzcqP7ea5DVxw^>FZ;o9>*MNki z`V(LZKx!MF03{5fYK^@YS40bg%G&wTL);jr_1j18=<>2Y?~IO&F=P1}0@_>73PG_Y z00euJW`@)hEI&`K_kWZ7_=Pj`PyTscu2q707(l0+ZzWhE`0C=oq`{YBIp5(oK_E{H za0gBWqdA-1tS@p)+4!6?Mtkf*o=m1I;#jZE<+kJ?^T{h{e%0K#xA?f7U&_t8r?_ia z_5z%s&T&aEhS!Eyz-X+v=-7a0x2c?2S2_#RIu z*hQ>QAtQp08hq?N0PS*4K`u;$Y21lXNoND#i`24|XQ!B-P9!-bEmd%Jv~?1{)6g0G z$XE=lBlfn!Bfe^&jXHZ0e#0Ki|lrte_he;xjRFeVq{8=(xy zu!ZP3daA!-vyT zRh6_;+0i$tquQg(4HXFzgAU*?TdezAbl&A|E9)G>KkbG>vD-jg_=6(O->X*{>#!?7 zOMwXH(^k`?c@5;?-keEGUxk^cJm7f}-Lw73Qdj0qC&}>Xpbqeh>Dt<+gk&p4)2&cE*^F%-TS%{=AtUBBd5L?61So2G0?wXy*rsJ zW;J@GGIY_-!GYH3!E1I8K_AQeYBZkxuOOXgTx`HJb1z3Fa&$%m<6_TaJ&B`y`-g~5A1 zbov|8i^l@h9sG6)YP`~P>5m_#+>Q=xN0lCxyAGzS=d#fZH*l&dZO3yhSWfAe)FqGj z=gXeEU!d}=@|uS7n{q0Pwl|LKbYch2)ulsq3`jISx>BipcyqqKDzZ7Ak^~-QuRAW> zuVAoEWzoT&&FUmq3HW6vDL12&5^H=1jw`8KZq;yc)lYoTRo4w*#s=T!Bvb0N)_)q4 zc{Oo!bG>GL4=2n+*%&pUGD6YvZ6ePZ1eNW=M@Vn) z+m|^&&)#0R{Py$a&f%vype+RN_YDT5OQ2{UIAD9dI|dS@NIJ;(l7*D`Z7-&O9si#- z4sfkw82sYNJGdIA#sHg(UTdaGIgPHHE*6hkJag^bbF?C4ft<6mzFUz-A(nY>nX?F_7$O?G^b>nS z86g1!f^Jm$r7`|ASID(oU{dd!kBLDi%zsZ+0!9uP1szwOmCKwBbKYw8qAzyC3FUN} zzq*sU4Ti z){CcEn7|Mlc=8jCAlcKU5h(+cuT;0>A5pQq_a-7NV!SFw{=Qz}srP~C&UX{=*BO8x zKmFgp04N>~A}brJht!igoQv~(Fpi_aDSc~ztPyqnB{svmP0eb|bFE6Wq164Nc z=0fFldZD-f9WeBZpwX`pAB>imIixT)6R8#Q>7BKnuG>0IIK}oEtfDw*LMNp~r^34M zT+sfd(I+3FB&*fhnQ5z+RzzD~j=042m;x2idFdX$coh#!R6?!usm$vV?6ZZ9HZG{1 zI@%!fiawji&~d6`d(f)s%M{w%k~NOeUr8ZlTV7{y6vJn2bdXfOe3NpKb~SwkPoCwZ z-KTucij<;H@$tU?o$JmEl6TdPXUHVp)-*m_fRv&Dp*&>2b&)I7txxfCzwqG1!0GXC?Q2zp&7P!L~9dP}eYrZULpR-XJT8AyU+6iRbIIQ^cHF66PSxr9H+ z4T~{ug9NWreM+H=KyC%j;7z^Q%Xi8ZM@ME*Nm zv+tAwMY3LTI-@1QL9aKCE(;6(oPhAZRbs?-4ZR&1kf8Bw8=6P%kaC7d+E`34uRuuf z%*o?Fn>2f4C{R}9i&Fs5I`R(ylz<2T-kkV_DfkWaYg_QIdzEbRcI9h zm-p}cN$mB&b-~HI9wj?TQpw5~q=_crTk)eVl`@=60Tz z)2dQ_WwhPaP(m61UmU&vViW^B@mLv0KJ_}E5BXAmD$@-<*yU{%S}sE=hbSAS-?Q>t-`R~DQn|!j1Der4KdMh zbXV=`M;*NEWyHqT38#Gj@J?Ib?_A)=)ktl`f#&nYS%WGuYJpG7N%P7Xfi>tx-J_s* zh5>PkOUdbp@~ktsl^H96p5_~uX)+?|$8muM)@ylk*T(B=2f7^S2NDw>aQmL4DH5rD z`rM{==~Ugzi+ZuqjxOMpL@_Q2(Ge~N$pJcRi_5I{nyBx{GMvhpg_s!5s{Cd5(xYV@ zFT{;r&nW85WDOhQul{$I-R<);eqL-?Qzr)$Y;1dVq-R{-atnUR^NJz!UT_zkHYi!r zd@1G(rSKFK10oqj_BL-p;0ndnHlkt$VmbpEl;f?zIZPqPcavToI?6{k(&yz~n~OES zOfdR0Amks%>6er6-}D{9e05t(w?}J2%c!p;7~sfgnTpApxsMUpoO`#z52>TRCSzm( zIh-RS&WPZ@vn(ZmyNK4mjjjhG2GdzhKDFWuFh0 zLj+YVdP|V}g8B(8WQ1OPfeO8pU1G(c>`fepkhz_gX5iH8LPSv>l%(M4uEr+TmKt)cq`sX`Gm@ncRXj>Z3iujtI zk658EBf!{1;N0}Tfks*Jw;K?dIN>7}G;u?7d>(tjh0niuxqmaWS}}#V;Oc`DU*3jY zO`S8=c%(57XrecuyKDyA+J&`2PdK1y^%OvE&r}}ZR6mb6p)AMh9s}HuKQZ_8f(>XG zQa<=YH@;vtk422!aAREg(R@Se)bEFe)0srn#^gWY$>JMbj7gc%d(qvw zt`U0C@>OwHSSya6>g+UHkWH|HFDOjB=$MI8@jNX!c_|KnyRH6cDxUg~n>A)FYBn8_ zD^)sfEX`KltkOT{#M$ZfHd2aF;F#aa#SzCaATE$+K;vY0y4w+X@lNH;&hARW&`pn8 z2l=ZW!30~zVxfVh1#COuVXoIdTAsfX_=EW2f!f&)XKeI0kclf&$aX} zz3)c6OOV4fue(m)!?X@rw^gEYod&Wc)jcKo-O8wFeIdfm%+%~sucM;_Q}{Jg^*9&P z&pDtd6_9K5GuPDpSlKul0lo`3j#u;i@fAZjEvjPV##4QC95A0L7G4h_rhU5-bWNhN zSuc=NoP&1mPZk2O?f z8`})hx8J`j?5uvK0_$6^=<6;N(R|f1gP>Ww<9=5Zfp*A zkViNdSTv2_R|kKDf?^a5MuCOJ`xaJlJsPLl9C+Jt>UQKjSo3`${p5sc|crM&n*oVD& zy{SK4TtN3)=Yh_^5nJ}8mq)9c7jwDABTLy%4&4cTtLX-}R)n1eVwVQcRG$DMA==}J z0svUNH1D+w7aG0+-PtsDglud;@VLr}T(KHnACBG%TcUK;F96#A~>>=|F^tKylfXa^T->Ze;a1qnKtFI#t5BRDA_xFK& zNhd;aXVoz2Yp#gHLueh*fBJQwrd;V`mSIg;ObJP6OIQGbcQUzcX*suZ>D=F?`!siq z-4qy6O z?K;_7;0}=I>d!}=K)#mHv)v^zRPr~oWZl}a!Dly&hPxyGTq_b?!MLF9~Nw6BiA)Y^!XTol=v+**}v`vB1F6r z9x7AShN7l}>~X=pM^*N&+E2Zmy+D}JKs=kPyc#Aoz&vuj{A|beqDr)WXGZ=jrDP3- zDP0;hIgM-Jv_A>V{QU|3EQIr4b7p4#ny6af^TawA!y%jXTWe>HP^+sbsYn^}m!+kQ zAOP$WZs|^$cPwW-;ab@y>e-Wuo*po(>Z=uUqzPAXh*=cdkcKeRd-v-L88J$!4&8&; zfvyq11qp-ho$C8hBv5;apuHk6M2+rSFW}NtZ?dqysvie!V@Tjt>DQXwuU~xSL3$D7 z*1LX)sxxkZo-g|8hBQPuUSu7kF9QDUQnkZ zef_}MMU^>a{PCfY2w9QV3qnWZ%GsNDuW~_XU*%Nj=;)}G!bsZ|Tx+i~-(OPMTwh-w zeQxlpO)oI^*PR;<`uDvSO5?ue$97l>&-MfA6XgzLT_CiUMr)dlL z!c%F+nypfkx>4-h4E0MgTE1BQ>Q5yFG405UG}ox!V_35uPe8794I?l+bCdP2U5zH4gG-*>OY=) zt>!#%n!f!QD9|bI-8#1~{_^N&$Pt?n zpdlL>3ITFv*{`}pIF3R;=&n*N5YzGzGsZKA7L`D-n#N~g%dxI7AeiFZfRm*%c??Bo z)srInInfCG*$o6Xg!l7*_4O0(*MH9`A*-w7t>e}c6F~(V8*`RsaXM!s-@Poo3Fs7Z#T6+= zuFMAp`2M4X!qB}n%STw_jGju`Gx4Gnk}Op+F+;ZZzJa>lzq&wn{ji74A%e#OJhA+{ z3KINzZ@B?^->c8LdLV+U2}T*o&D*Q6Q7dmvb}SxPBqW&A?@^Z_lee>Ee%TGVLAkaK z9pgIQnq89dk>N=>`BTHJ`kHA|)8AXF>mFC8`)umZp$Zm=~n9TUYE%A5n=(M5c{lQ%o z{w>|%E#|V~B7hV;FIXRFB*yW?S;G6CqU6wk%^1NaukHlF^!FA=y{*0EW6CxKK;fr~ zDwo?RAaMJ0RRo73kj&)f4y|learIIDY;pSlON+YlO1%HsTeBFQ_}3ICobLa7-XHKJ_UiaR#^8U3K z*@K}9EVHAu5Dg3vmo))+4c|{FK5?;Q>g>9dtF4J;OplbJr)o@g(HTs%OfIDN^XWdwRTVYgix^y+N zE3v_w ztx^LAa3cWoMYadjk_S(>mZ`R6#pzkcwjVzY@TcX91EID%2dE`HosAt3bj#V_ZFu9k z493$&HyZD%dGR8U6(iq3hqMuP%7_2@#lObtU#sMwzCZHu5SiAjdf`E6^^7Z#VIWk) zMlhl$p+IGW?cjyA>PbGrd_!(tSE$wa!pbPmz>H1}zB}glX*F4eXR&sI`&$Y2JD4-R zD1C|{oJhe}tBR-gm6SRh;&+bu$zggAE&e=e_ct9t6tb$Je0;|>VXcX>3VK0Y!ujC{ zFTq@MB}S;*jE3PU${{#0<3s(u&iq7giFd*StPkGF-jSlvk^_MOsrDDR<=?LLH_=Vs z(A*n%B;NuBucn+G$xJv~ezq}S6I|iJ6=T9mbpwiw;?QE%Jej|oprZSt8ApYE@!qxJ zP91tFjGWGn9xJ(Y%+fp(8TQ`xvbosDnAt-rvWmo;LZ6p~>qMkO%*sI8jplB+5!-<9mg``}iST)0X zG+6V!V#I-fe_-#^?z4Yj|2i6z)kCo^s0d#tJ}@?mhPF-pB>^{IiHBvZudKuQJ)pON zjvNDxbXwl>r=1ADdU4DtE1gs#FHY6axn2_4h7C#MSgN2~vlEYoHrmt@7jz@lHZv!M zwQs{O7}4~_j(+~MM?3eEFZick&u{JC9t<>Sm+$Pd5S|?)m}i%@qGtecbaSykHVt5- z;a1ySbtkb(r(!qz$moKOXrdi$Mo%mHxIlfBBw29;7J0 zcvEF~BcWGoaHG&>B43A$JIL$(rx45XB1VTi{FhYlp4k2fH=M{CIi=gM$c}uI*>5LA z^3uG-;tdeywMdwze&07Pr4{iB#sELh^bzZTd9Ow`ma`;_Styyx^N`Qc=XN1Wa*2F$ zq+=%DsjL*b3D)l25Abb@md(c5qiqhFIxt1suPf@u97a*Ifu?vzq{Xx*0? zoUM;^f3fB~DtHiwF&tN;N8j~PSP1iF$)&lFVK2?lVoO-|6N5l7-#{*~VTU3LPMr<( z7EoNLzY~pZFerbjnDMopzoM^F7T_Quc5h)^xe?7MCBfBnbS4aGNYd8i#W47AaJQR( zipPe>#4z`=!u9t=eE@#`_8)qd;I?`JSE^=h+U`K0C*+Z}5zuI1WN}nuApHsg$=rWn z8}%i+EtTd=#k#xXJdC^G!J})O=!J()l0=w>0H6(}QClk``H=R`-67I4yRy92PqD7^ zGCT6j*E!oi@t3@kVy<_$j};N_vKO-Y!8QK1P5YnvB))^1X--!DZ2uK2_Nf}K*A{_O zHM&To@(lhF^MY-!pFT66z*o%4v_jx8**g1Tplh&x_C3);ztju2dj0T_(5ATfl2twb zFWXk4Jq7k}4XmnPwgG(mb2UN)?#!G_NLkMdkKW~1fXe{%;2$hb`xy#6g=NE~-9#D2 zOu=B33W=i!a>J{iplVUuY{Y666hfHCPwqTj3lWEL~pjVvon|n z#W;*prxA64obfSlryU+HqTSD>Iw-Ko)Tp>o)Wepnr$KT@JxRh1`x0(>T(*bsW-xw% zr*@@74(UMAAr?0#re;VF#$Rqrw4Cfj%zdnmDH{~3DQj%}Q7MErcM$91hoJnT8S`#hg{ zc=Rik35=i<;CFX!J4_-fdes2r=?Hy8AvE%?4j(V1M*6JLPj{?!H`a+$=sPPw(dH6v_ zf)P9&TpFYHIfDG_nrNHPE&T!|W#v5mpxf0_+jopa2yHPpjB5i4pWDi6GF&f|cFNg>nB#r=DB)XQ<>31hl?2C6+<#2p;r)P5yFLzUA{y+zB}1EZ7D zPd|Unn2NNcaCK>&hL&J-{Psd^G!=(TcWi7oW}YcjG0pY)oMqYu^8d1?*FH+>+7exI zIaY*|7Gcuiuo|qd8Dm*|URJHw-PW_46EDC9e%q7=n4*tQF)uNC+!8vB9u@?7UIVbx z&##HAOP0<(E|I)g7pOLpme9KLq%y_4S*e&B*Wo)GYcV|JtsqR3RkX)u&9e`t+}h8_ z8k=GQpuX`MR>3)HW_H3=v}Rq*lf9f7&OMDNRuvIX`v%Uklv() z-V>w*2=T4G&wc0ay^p*6?m6eZ`|k6P{IOP&xz?O(t~tLk#y7@CsOvV+2%W~tmPhF; zj|>^XI84vD+BW%?+;k_t>Nak8-L1pzt?u&@$%D^C-d9cwr13EP`XiDONaJ9EiFJK8 z(LFA>P!DspcB9iteH$5+69M1(gEqB7d|cb77HIq3P?;5?`RTHa~sD$0TZC$2YCZk2!AN5s!?F$5>pUE(*8`; z6DN$h(+4h0$fI!K@;jRuDI5-X%y{}Etv7}boJRHtKJy_gA^wTRkR2RX`$7-Jd@8r8 zy_ee>i%4aY?~)|%8?9L0_cxOx=Y1S_IB&j5XRjjY#j>90LZF^nXmfucTC7%$wg}jR z5tbkx)|%BvTf4e?TW1+WOJrzvwUqNXK*T^>lKkw#D_M3kGEPu3xTQU%TNpA4a4Scn z{0^IrmuAA9rzNkKo_iBJ8FC#e&<2h>0xyZ3WLOEnX!Hz z-$&Y)<8`@rOjFd=Wotl2%aGd#V8j0*2teC2xPjXcWRjY2w8#9pm&f7Hv(DEW%ySuX z9^``{HF_&ViQQQw*#Ym>sY7cE$FA}al~H^pC`TDbcnYDxt<^JEPzkw-wO)Noq*XDB z*_u_zgzI=&@pROWA70cYmtm>D*m8fVhy5*m{2%Nd-`Sjgy;J`F5nd}+4wDS^Unxf+ zf`o(6&}EAj`LP@rO-|pw zOk_XJdi2JOIGU+*w91#_HqnRO%`NrCb{iVS+kLtTuIyiu4%ajzxOUqhw~PO9C>I-9 zv4W_vwo?{Ti3haWHP1a;c9ch+aP0C|_GA!JPIcpPjkA%<>S$<<#KjA7<(KF^0Vhpi z@1PZ0l*c`VPGq|5gpU|*~12f0b=-X#9JX!E<9;a@mO5CLT10-DrhpGwlb$HdbR1&^(apo7R0 z`JA`!wy2m<{+JwxvOFDUhS6b5)rv}TIvnj!WLgHBBzPNt)CB{nj#R-J%QQ$u;-?`e ztDrAwu1zPlNdLAMgjr&{iLAZ$j*x&rMytYYaQT?x?@R#q{*GB<8~wbX&3dc39%ER0 ztcJbPbfIUL`KZgluyrt(#R03HNZ-Z%k{TE0(4V zZi~gpcfM06zNU57FD_1NoXHs|>TGlcJyU3brd^nvGPHIXIxUq$6U%r!vj2;46UTRDb~fcAS8mq5&B;Q@pX=YcjH*EP2RE`pX|Z$|c#)MicjVyY-=-AqsiLw|FGN`31wQk$q1KKUA(Wfx+Zrcf zv^lWDROK0Za-pm80z@8I+e0wt`dgAlgRvwp^XIo=VxzBR036NM4>ds~*LApoUIZthUWieX+<_+gqtgYuW9+#gy*t9mKZG zq`+QlcjJDWk(wO81RiqIezR<$0b+;-``4?W5c=r!pnW)%QjvjmwGqtrdb>%2*26;@ z_T3?ci1zsNKwh)Y$Y-=bjD|*qG7wxQ7xBJ|J%brr_y&ronT76^22I{|#0Y5&v3!<< zIXhY#v{fJMUQ1ZEIupPGPocxM&~f|7a0}+^=O zo`@7f+R~^iKZ{U#nNN<|GO1M-#Yl!KyH8O+zisfW4+2WLzt$a8;ZUJ^Vh4_1LzH($ z?nybeF_ED~TTX2{yrCo5dmLr91ru(kl~dG#dRqQpbQ612m_%vrvj>Bi2())7&$F}h z2-g{-2|ho@Tt<_r+&ajtvnR@e2G>4unYrlbY^U;-FQU!E`x|H*;kF8Mf9C*^jZUl% z$hSf59QsCNVgZ?7)Iz)Qd2hB=V=`OGd#-Oh#j8=~Wm%t!rY0Lxp9ZqrzeYEn57!FVi0hN1CK z+Ggn*!PA{ceoD5mLQMBc+W{?)JrVxri7CAny*K_(wI+*{U_z8Wc){_UWcm&RP8Hau zN@nGTWUL9;5Vu(s1&U7j?nEvv7I&!`{T*4Z{RP<AVtuMH>Dd`f6#o`n+1DIpnoBqiq{;7czXf$EDK}FlI`FtaRwpg&V z#}OIO-t#})yn&H`aG*O|NbP#sbc`vziPx)ZIYaHL8w+zEY~#Ang!g=|#>-k-5aAaO zo4SF(diT%L>9n@gR@UI*@G*6nm>%`ymgiLwV}X(uCeYV!-E6cb6Q6P25Nwg1aI{mK zPGkA#fHygDZ+@(`&;PJ`8|-R0_YeMn-$yyWvuFMG4@_ExSe;Q%n<7Iu+BwGJgt`KQ zJGT336o!Fbl($%Sz|n*!4?b?$Qa*<6N0Bcc&Z9I6chqi!?NOccSHn<~Jf|}2qP2%1 zRW*9f2=a9~{jciL3f*~@#8g*eSOW#hGB^p?U!ADGu!K=t}=S zweei_!L`M&y9Hff$=i9$C3i65&Q%k>nrf$6^{hGT?*N^EgJcg>Pn%Hn$KrZ<4GA8g zu6y1CS*7Zf=U4ZEVjY_8?pjZ^tek3h2}Y0!SCC3`(T^kL$RdNdyWP)F4C^qH{k0J6 zUvi2s;Fvv)Fczrl8L@hg1r;I17;nB}wnVS#0Zu%Vn!7zhlpPehqj77hg_YDzfV*in z5=N6~?=LCD*=kIt(s{5F!k3_8?u6T~PL6p;*~he2E_mK&EJxw$20(Jzg9O0|>uFJ+ z>`E$ml*1Y@8 zQjEzj!1BL3@`j=v4KcATNAt`dcJNI85TSBj+vBgpHeP@OGf zOx$RCLrKM-w99NL64r6+x2ow4+&Tr7S;-5s))hf7lke#~bU$n@#lr-i7$+`(+uzz| zqjNKfWlc>eLyGG~9(J;HPuB`Z_*kSo{5XdfJODzKx#d0B?VKkV;tBqth2HMtipy1Se zR46Zw2&+7DRfI?j?$9YN(R;h(ab5~<# z7l^MEJB5ijqogCA2I$Ys$W2bBwlK-Htv?NQ52fjxjYi>Z-v0|r3SKu>7T~|9ha5i< zcMTVQ_VmEP{ebq}orA+#&(qxM_u(Oz;Rn%y3Sj1FrFJDf-{nIXs-cl0cPjO|S{M_p z|Mr)OBkdWss$h7(qH2%FCIlJYdKq9q*iCSLDo(s&qcZi8bQYjt)8lBcs_zq3P>Es1 zW+Ph;SN9CwjV7gLLFy~?dTA^_?(;<6;HdA8j+&~TGzN`C?LeUok@ji(Z( zgvLH%viA}+D8&LtK1({I6czw$eQOP3iw%Ej67VQ|_hOFzKG(zifsys5{Zrc81NEZW zldIB9gHQH8UGKO?T9ukYOd^o6`Zg5*?E!wBOvCTFx_{jxjZxtT^ljo#j;|xKC#(T& zl+Co!-7`rSbq1oFwVB$~!7r6hcrbu=Cn+3d+F`_rF_pOXa$?n0`FboXQ%>bZPQtXp zse^8RgQ-S6qTl@h^ZckYcaipKg~wL77f+=76KKok zS&7mxAV0u~1Q7~1#0|-ZASZlJq2^=B0`?HvHz3+cPy-FI?X@(8bMD zSBwdJ=jqYwbtYpy7yM4FFdyQS!X9V_Bmdz3>CJcGU!A$PPt*iOeXa(?{Nx(>fpqVS z&I-dkAb9J|DWF0(4F&=DEX_us>P2{f{1h=jRJm;chEB zq9fo*f@zh2J9|O}p`RucHq=g}YhF^r=QBJlyqK##!_44ehdQK(q)Q2@Cg+d4MCPV2 zp*aa79+hX?(41RpNW!+~qRr6r7{eNDy<1d!$9xuazoi>Y;#I%Iv|s7azx?t-x?lQ5 zNyB7scJI%%0jWg@;aYp&y|;Tn(uCudrbzp!)W8DgWNoHz7FpsxK{>_)#W~N}(v^)s z>G*E)iHLnYh|u>M(~oGDx?AH&oB9zbHDM80cuQupMy}d zcvWK^>9norR{g-+sJ^uFTXTHUk9lgrXU#_0H2YtR$GlsKs}Y;)n{&fp)r1c2O}%BR zF?#q%Hp4&p9m7r=1b-DlfxY4}FXh@FNuL@c>-+@wpgq3#2^0M*Xn`_AXi3CGobyF$ zr}aB=amcg${!FkjPg(nX3luP<;!e$j5U;rTV02 zWoc>qrO50R4F3+8k-Vb~t%QdrjlyO;c~I@!obV$HWU4B_lhB4C%1N=CC%2u|~U7tXK4W$Rp|1ZcFPE-)815s;-rfPDv#Zipvy6oaxkM2vw)Qft;{96&^TUrv zaFlNJ?Q_tC1sSwtt!KE@)($gw9&Rdn$1tXccH$*f^1@1#QTy#S6q&r7K@P?BYH2 zW@%8TpH6mw#(_xezbD|PBo0TG5n7$Fkr zD9(oFDM@2~h8U^49T=@dC-*)W?tQ@@U%O39mswBi*P z)xmry|BmOQdG>GJ2s#}~u^egSmRru8=gXYwUBH`@;kRMjgaMSI{@JWr2?Whzgl@98Ci8P^CeUD`lW3fRU`AE zvO$#t11?qx<6B{#cUlP!6EBSUMiy>yPdxG2FZc@-(ROrt*d9L!qoavV46(a=$u8Dz zjFznMLog$?4(4?TQPu}$O{JR09D_O*eYEguNK{F#&?@|VWthkHW%l9yBbvq1M{Cq| zEDWaHjAiRK8&{s1n`#r;c8IP{A?A{>YO#eK?#@@dwHq5Y6XV{AzJ@lGNj6NOv-sSpWZ4?3cCa3N6vFjNMRtGuWW8xC(h znm_CTvKb)zv-~)vQ-G7Q=#RU!f-F6ygc8B$WgP*Ts7iSL#h|aPKQ+Yy-2mE+J;?$J zYk;vL{q4rb9MV)k^=Q8ppb^V&APphNN)XW0Z2MM*UkiSQqj+4teRqTbOL4k(Izkwd?0{50a z4aF(K=1aV}0b}!U*^Ptod{tq5S=sOt5mxsncIm;$ILUkUW_=WjWW?lTU&a!Xo^A_W$t@VIh#XU? zdp^xN+>HqWC*OB^JFV;?VsorlvHBbp<@BE+i(i1;pNES^s zk8KtY3I%-38-usKiQY#71mv8k<9^6YWt6qQWIBuPwrxWK9iqWlA)s(8|B6)8LHFuE z0&U6Ujz&H-Z5u!Nj3+xrCtvB2En!%@G-uEm%he`m`4m%>=ek!L(XE=^d%6UlJulBg zA#RkdE=(6tC9fF+6LZ^_WQiUxqyXuAdJ`e$=IpOS*kY72NJIZDF7dnl{B^JY=N)~G z3S%M}+qM(l2}viL3#m7ocY1ltZfB{pNLTEfm$>#S!IpMJ|9Ng!ufaJVXP{PGbpRUD za$v-Z+8h)qM!vJmRlDk8^)f!;{L9^#j``@}-HVDDq{qJ+Z%O-u?1m4+^~AYYt|1Gz z(nih=0k`}0wn352Bg?~&=~lwHuF6Qg9xX4{oX~XK1ivvbFqklqv#`Ryb%wA^j=`Gx z9@RrGf(#H|=uvS~!pmRo^55O{z!BbKi&224o)JL-g1Q`*j-?SE3SZPTz)b_idZPCv`M!Zz ztzid;K&_MkaqQF6;J-342)ewvlmJVMzr7TwbwYDlg0G}Bx#@TY7CCm$?1Z((KIWLm z8T{^j>}UgTbx!WwvF~=(rq6E>0Qlv`%ndZ8-PYmj{7&!4a69)<#Z@4zdst4kxK}-?xRSw_-Y54iFps@%QoG z>XoWhv-n)RLHWk_a6}2T*H4J4YxR~yO$UY5vlcezuZhRqw6S@mMj}owyQE9573Xu` zkMInI4E-@l$}^)OZhYO~HkqnHz6ABU<^p(yxwfcg|n_ zj*m$VNN|3T4Ig(^1ZF;lX9bgolM_K~%>t#vWLsu;uLJwIJ$#M#l&Z87GT!nV1ohom zi{#;fKPqP@LYmkOadS{rL^ikKAfd^^_Oy(aCJ&WH_sKRWy`u0U-YkZ=y;@otB^u=E zoJ*qb7Ivp{3vLN=P@g9{gTBA?n}TU>#IQku=iB+Ib+_fHRM$AaJBHf>tRClRhU(&ScIz|TPY z(_onaNxm#SjB9I>R!MTM6`Bx8J$OXX{!@Xc8&r7Sf2E_}?fw5JCnZhWVZ`;u057!- z0DY7={3AZceC2~uayRj16Pom51X_(CjgO!38z{kl@ulxFWFdpBXTGz27VN1SxjiMH zwA`sb_)$gY=J5RW$%K@Z%Fm+A45*C{^cdaGV4J_q(=)ELGzTub)6@M7Y*Ku!A5$^cgDfVR>P$=geix+NDaCud2{G?^e2#8W7x?} z%;9ZxNyEZNxM|3yBS|}47*Gbkq?{WSWMfPl&A1DC^=Lf%XXS2DTZcQ z6J}H$I-xf(IeDx90QDusaj6k+de-D(=glt*U2P9@WF7g`nHmgbe))2LcPV8OI(Z21 z0*%2pFTa7WjSkj1%pP{bkWtH#ygjFVH5juap{2>waV*<+UiB;M(2dHd6S6hvvGG|? z;DrXjX710$<#Je8Zy4a@hkq)J$)5fu9y5PJ_nUp>J4-a)3W6FZf-#;~seCqDIJ-W^ z(>SZ<+w#H4+nsKu=We*gnb;Hp|Hu?+8n>X_u=h}j^>3i6&bFzI1h4C3ibKU;cjc>> zwWrd;`#L$l;O&*FiaE1Y)#0x+l}2xR=3lI}-F$n1wlg_rfW=Z`PM zop1gSbdfC$c(vI_fbb$cpQ&bg%j{W6v1e$Afu9-&64`x^EFup9uUtPv*US*ha8vIF zt7XRdN{HW>eqWi@f^kF|vl^Yvr~`2r{h1f7Z`Ll51x^mfHp=x=_8O@Q)`_cw3qF5m ztp2T@i~kp|hu4g~gW;P?551so{k&eM)*O*baGH!HWm=qAcM)4>O?BsXaHJ2sm3IF# zn4z|2ixX8A&{&nB=c$jvvPRsx<5oHCBFuQVx}3uPY16Y;X@av~`qfFNDS>1Pv4Uy2 z9P1gt_IshDlNhy$pqf(3ng-+M3|{*7p9BPD3gfL^cddRNP&+;Tpw*FJx4f0v$v%_e z66h;DG`&)%HQjH92Q?em$oj=-?fMLt60WOA33Q!8nV$KYGP6V$XD^uD#kb2uhROEi zq3503sK}6cdot^%{WeGe`@HwnapEf0$)4|u1TQj1Zu)-%@phWZKv{tI3F7BooEy13 zX%VXXO45N9U}HNF{-gqVOJ~6Mm=qP;aRIY4KNE(uDe@{n5-|3GE+$>SR`<}UOQY#I zg|TRG-e$pjX7S^uKQ=xDJs%*su&nbBOxqo;#uCx1qe8O{#YsGBf^7la@ipXTR?${M{Zt8`gcKv_nr8~r zUw0C4N>YC8eE!vX!CJFJf%KAX9?f>~^wn~Go{gM?vNesSp?v=Y4y_B;N_w*uUM%}A zLk9NVfkvrF;WT4$2)!`f z)~lOfFW$+mv6hO&sv0P9-OE_;))G?&I_@%)P+hAh<|>jqYJMxvzAR~Y#)#fL(pjU) z-R`LS1Hra)*RdE>bSO-KbJ8O%9y{C7HMD@F8n#K7hO|$5l?PtWFShdJYdg)~xfhdc1>~mLr4HIS59PDi6!LDF z@x_m%Y!UPmrfOc`USM}ATQqYZgGlknMQX(6aJ|3tsc`CkonAvpNosoZg{JrITH(XU zB-OEjhEk`RiV7VgGZoP`4MtWa!70Pp+39gPXKsT60>7{ieaHelPT$!SGM;48S6%aO zzsmJxXJil7n7M2Z>hGN-1j%z=4Q(4;iV3*!sa@22yG!r--o{~rvaQEk>x6{ENzzX# zF1wj7G3%V>{f91rhNdYoZmc;@;`?Ry7j({Zy{+=-65XvDsox(e>w9~zWjLPK@bO}5 zF->CMf$Q#&(c&ac7DsWm{<>fbi~G}YD|V}Y5eu5v%{NDs$Ll_PYT6cSZD9*G^rJskiu4GK+3uB6Y`2JkJ+GB zqs}%Ggz%M|;k666Co&ljDa2_`_<__3^7P<5txl651pi4x*d!^Cgmh(>fy=0(&n zq+TL-nkJQM>?F2JA%ia zy|g_x?;Vv5@O_@EP$}hH;jtdI=1T^ zM^t6fQ(WLN2wAijC{%PPz-u}iXYM0r9|o_mi#-v?XtpHr2Z=-&XqUe-WFHyX%L$rn zl$Rj)e3yl>WfX($VVHK6-xXc1SI$|7NsQc&nIZWjZ1c}4DhT{f7)7_@cKxA zySUK`-IK-wmT0SQ5qwvUY34!V7obc|TK%}1yA*ns$?7D5T_FYG(=n0*@2bgMwrM)kkG>migP138y4eYln3B1p-f6A zq}Ik@X^M3iHSRLzWjbZ6dk*g<)ucK7sSszL`zAuZC!?*yaU02FZ%NMb5DXN+^zFBTr^U^9Y z!Pd&;xg7xJ1inZRPKv&KcV_E`N%Z*Fqfv_H`vK>No`oOfahgvTO?jmuIP7_C#l`}( zuG~tX&`~m4W1qJAdRx1ZX*erPRWC1$CMnj)-N@!6OK{sNtGr1<^F#N}Gm%Z&PUXkw z2zHK!iLd%w6AoPtxg#?r$5SY|kzTGlT85g38Cf3euAgXo2VL}etl;gD#t@^D5SrxW z=H=X6ex)xinV zu0Tn{pfC5)-pNm^leY7gnIl)!{HCwPba%1FD6U1Nn5K1n_!=%eA}Qyw#wB<4P$TyA z-ast!;kwDHfo`A5K}EREYR^Wljp$^Y&T;AZ0!_khD-j^nei&w%J8Mr_6U6k8R76W=LPN4CchN zDh=mW3_W_6MBH@OT}EJaiZ0R>4q=XbRRZ0#k{5nFPZTMjZf#&SBCTWBAo3t`B&9>6 zm|AQoJa;+8bu7!U`&4}OB%z9w^+C+!km|d4gQi0R=RZ^_%}}}YxsaBnPam>^$~HP= zXDME^cavwyliwdae3Kk%Umfke<5fDQoEHea_#%8ozjAq9bh|5uBhl+|!}iovZncd| z=N8;d*2~_WB+Kum;sel@pO%`M_5NEAHS>l7r32NC9V>5zSmTKkh0SD}I&HXv{a0S? z4i1+OPZG=A%mXe0s%A#E-or#-u{Rl zSkVBrpaiezZy=KW`KV*4Hy6ONY#N0fu^?Cub~hUry*r?&ej~bXpv*&L6pn$^6o@2o z{rnBUx%};aqU^8sY|H%k!+(!aQb&WEYj*qXdq6P07} zbAR-Z2I&l|zxaf1cvFg4Jcg$>SNiH50sRNo;FR)sc3pDWW^mQ>40b?aa~)Bk<2Tze zOF3T=9H4wAXSX^_LI(UpYu74nKjOGX|#St!bBy zTe)06a2X&`Afe#3^q;s7;=*tL5hnPqC-09>I>IRG@!nvSQK_>5BJEQQbCQ$=OIvw{ zoAF*9stQjPS1k$VqJk0NdRJ8Uv970V*4m8vEd)jhw_(yy_Zduu_lR1S z4F#ACmKf0!F-%y8c-$pKxYJZBe=Dl|W0&}=+uEQS%%^l`1*htLDcg#Ub>J!t&Hi`zvT;nF#@1=(!0PAAPLCe z&Q=e67FgLrVM#YC_z%Tre-5eH03o%P|2w31PUVc~HDOxv?6UW*tZ&U&zg&9VBEm8+ z;&d!HFQyrj!kDxkG(!F#PEyTb*q9acfN>DE*GP2qlk!Hiiv5Y}H_#o0&rfTx5pTbN zre=?oVRAg^)&qh6eTm-(+5}6plLQAYBY7j+o{lJ7^A2l+3!o{g8f<<)Zg;S);eqb1 zx|u%{9+-Gz4xO(sG3*@Hv0WX_K$pk|Fo2T`i>(0!5#5HZ93*~KQ4lnJzG&V6k_WZa*K8I zI=UTcPi*ykJGGi!J;p#qs(8-m22z>j*(uJZr#H6pF~Gjr{Z&x<*De43=)YgQObpOd zP7IQ~HrL?MfnyosEh)xI91|RIi?3WHhocXSh#X>=jyZw!H~_0&v$}1f1hyw@!fyFc_*285NV82 z#7fN1z5tSiq&nO9DaNfXw25)5hN@MqlPDZ|_t*+vaO(|~2;FKLS}96@C^gzJ_uG#B zg}(pz$uCwWG6Q6k&!#sgRsv1idV15`kIz*tX@JwX!TyTz^xeh?2465Rm2l$zK zS9dh=d}CtK#?vr3x!zHdPB7n%b7R_7j-+26yD(W_Grn&oMOd0tsysgYl%V!6X!YHI zL`k0+#<6>HjA1Xo5x%AILGkL77sXXf$Qh(W@IW%=mhheIgXyFxh}QgiN5Kgn?8BGt z26m&ke5vfDlaZ*fW$DZBqKidJL2f;2^}+E8(^xT&tD_7IlJ^8}?3q0xT)cGpD3NAK zi#bO;lD{In@+4Maal}noBu|u1Q{%yKR_V;p#e=E-V`@nNXuN0y*aaOtYWsx%%t)U- z;zb-$!uEAUfdkl)FhIOJv0XVOO1lcM2aN%vYk>-0tfznl6imASp(cQLSC|Z>*`;HX z04kqX^;cYg8ZCUDAAk|)P}pcu77h+yEdQCwr}YVt;_1h!0L(z?Dfe%nn|WafRN^ok z(+=Ix1{#JTcJ+Q@1{MH`IbQ*9FvrhaL)&`5e$#B9#VD`Cu#cjCagzYoP|Fd1^z|Dk z7I1sTK&ofppYxGBSoVD=?wZ2!NF2O>2b*Aw4TcwdKwyu6`vv;h1)j2pt=>nw;w~Hm z?bBtQT6e=%4spsqQ6WbRXK_G;cX0st_;1yu?{T{UjE?hOK=a}Ea8+i|uP5I?>_5{h z*GudHSs(bW6+2-jU@KCi;Q%tAJ%!k^sG5(E_=L_YN>1bu_*mwQTi`IHdLxMKjuCRs+!x{ zg-UO)pb|tVZb_<~F)-!KFs_>Hpp;swymy#=@v9?|R( zBcpux?Fnq6gs&f`Fe^CXO^M{R2)JE+WdFA!))Ox^tVGPgV3aYEtO{u>p^h?+nh)*o zoFR<{EHv^d<~G+eB_;?T*P8dT%bd_FGeL18U&jl`UTh6)g0po5{@7msBMA7X-;pNh zW`ry!$wl56uBc<+e!Cc>CM(0Fgh~+e7RJiLqjW~MC9k|`zn(b9m1F3YZ@5)AdOb}h z*)kB{eOGH7#90al2OS91*F5xSclm+F|8%(j!joiDMi;MSq-($&pcS0tHjuhi zvbmkLTT*%QzHg$~j#aW#*f!n_cJHMuOiCjqU#UaJY2?*kxS#*pPr#v=Mgznow4D~9 z$q5M$VCdyPkh|^Z1#}a48eSXVOLgb{;*~Ru+ZHtKJ0k1XAqc2Ds5pYZVggwC7FK!s zvU%hB?Y1_yms-yVWZVuFq0`c001Bt$HQ_frs=UtG#gvWv>=9rfl!XEO^_JZno3f5u!?lbU8^TGKC)-2zcQ z@3(TeZaWS!L|OQIil9zfj$QpdFXzbRS&196&|9*0HFfd!b|$(!(n|%BGI*8Pk`81h ze@wW4`Z@g_Ye>!_AuZ6YX+zB6Jgx@FG02N#i7>?tMnbPoX@p2`RcG1}(o#4RP3W0+ zU8`O4H`5R2QAkiEfe~X(qfQ)Vn_yIXqA0a+3sc61;^DeY5p!r~p3y`0Cf0PWt=9@b zX;^7?Pqx*KT7p5Fmw&(Nzv_i=MJGl|vZ4-e$F>;>k8KGjpE03}aaq=*-|oCbQW9cWoz&^m$aD?5O7h93WTR`gkK5JipffLl@cpyH za8~Y_Mtc1GlM#`J9vlIgmW^}+TavK(PaJ?=FE5KO-;=G&x|xC32DGR^;K2rR{vRyQ ze<{?!i$eAjx*2pnr|u7wG|SN45Z4;Vw^9D6tvkg?56&X^Xab}^kXsV;EMY9rrt|N< zHd48@x#h`)8w-5)m?K zUWQuHh<~9B4JmG;iRl`8qO;m>afLHOuZAHi&VqV*xOpURaN{FH+0V_+L^;_iMmI-& zjYYuBOwx~VE_7)eJovAA1IaWy5Y*C)SP6ml1%6sxt1%s8^u{B@9(O0N%hln+L(s?a zBH33|b6@HZyf&uBnq$Ie%`wmB2p0o4mZjLZzWV@@cd|+$mE@ zpQ!1%l;ywKiuzYTvi}+c`oGyRJkq7q+)Nw3h|?m`>qD85y5=%#ENKPZZp_D*K)WaD z6S4Cu_5H4Mb&NVqHLC5{{`1zcYtQT?V@AtFC$d-4(>RJ&?odm!Kjr>}DqZl72hvy( zTV(cH(u>|#P{ldhbK>VbI4YzkHfEES6O82zEYDuAIxTq;a(f6zzJd4rj{UxrC>%@B z^?vFb$m>%3QuG=#<%#P-LCxux*)xqy(>2(=8jP>wC7fE$a^8v1$!rjo9D-4TSsNcS zd!GYnR$+kWjC&Q=3wX%p0bxo4+y%ACL|ib`7lA?oF0k%eSOpA$fj5Hy*IVpC4v_f@ zp0mf^sDSU5L~Zu(;GifO*gV^5K77>|Ll5w|cxSPNS-^z=GRluD{TRI;GvZ(RK2>>- zj-?C3$Z%9^1s;ZO2=(_S7><+-oYSaoZ4V0H(v$V%-iGlmEhYl>we^~-3TJDge)z1c zNPDj(j84Uhp*Ci^`fL>j&!cDoM+5DMf?^^C1x8)Q(3T0=&rMY$&%a`tUjjr#=3iuy zz5$!eMZK6Mm8L%$bfa%NmX4D8{0*d3TT^XZ`Q@ZXtT!gz^^r{`TcwP1+z-#_zY6#M lkGF;YRq*OxZgKn=`Cs^3e~j)ASHzDu_5b>k0QolYzW@d4u7v;q literal 0 HcmV?d00001 diff --git a/samples/multiple-pipelines.ipynb b/samples/multiple-pipelines.ipynb deleted file mode 100644 index 3a5d253b02..0000000000 --- a/samples/multiple-pipelines.ipynb +++ /dev/null @@ -1,534 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "lesbian-springer", - "metadata": {}, - "source": [ - "## Seldon V2 Pipeline to Pipeline Examples\n", - "\n", - "This notebook illustrates a series of Pipelines that are joined together.\n", - "\n", - "### Models Used\n", - "\n", - " * `gs://seldon-models/triton/simple` an example Triton tensorflow model that takes 2 inputs INPUT0 and INPUT1 and adds them to produce OUTPUT0 and also subtracts INPUT1 from INPUT0 to produce OUTPUT1. See [here](https://github.com/triton-inference-server/server/tree/main/docs/examples/model_repository/simple) for the original source code and license.\n", - " * Other models can be found at https://github.com/SeldonIO/triton-python-examples" - ] - }, - { - "cell_type": "markdown", - "id": "running-antarctica", - "metadata": {}, - "source": [ - "### Pipeline pulling from one other Pipeline\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "0f2ab2a3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "apiVersion: mlops.seldon.io/v1alpha1\n", - "kind: Model\n", - "metadata:\n", - " name: tfsimple1\n", - "spec:\n", - " storageUri: \"gs://seldon-models/triton/simple\"\n", - " requirements:\n", - " - tensorflow\n", - " memory: 100Ki\n", - "apiVersion: mlops.seldon.io/v1alpha1\n", - "kind: Model\n", - "metadata:\n", - " name: tfsimple2\n", - "spec:\n", - " storageUri: \"gs://seldon-models/triton/simple\"\n", - " requirements:\n", - " - tensorflow\n", - " memory: 100Ki\n" - ] - } - ], - "source": [ - "!cat ./models/tfsimple1.yaml\n", - "!cat ./models/tfsimple2.yaml" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "f9e073d7", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{}\n", - "{}\n" - ] - } - ], - "source": [ - "!seldon model load -f ./models/tfsimple1.yaml \n", - "!seldon model load -f ./models/tfsimple2.yaml " - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "997b4028", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{}\n", - "{}\n" - ] - } - ], - "source": [ - "!seldon model status tfsimple1 -w ModelAvailable | jq -M .\n", - "!seldon model status tfsimple2 -w ModelAvailable | jq -M ." - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "3d017ede", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "apiVersion: mlops.seldon.io/v1alpha1\r\n", - "kind: Pipeline\r\n", - "metadata:\r\n", - " name: tfsimple\r\n", - "spec:\r\n", - " steps:\r\n", - " - name: tfsimple1\r\n", - " output:\r\n", - " steps:\r\n", - " - tfsimple1\r\n" - ] - } - ], - "source": [ - "!cat ./pipelines/tfsimple.yaml" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "following-winning", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{}\r\n" - ] - } - ], - "source": [ - "!seldon pipeline load -f ./pipelines/tfsimple.yaml" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "artistic-kentucky", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\r\n", - " \"pipelineName\": \"tfsimple\",\r\n", - " \"versions\": [\r\n", - " {\r\n", - " \"pipeline\": {\r\n", - " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"ceb2jt37778s739emas0\",\r\n", - " \"version\": 1,\r\n", - " \"steps\": [\r\n", - " {\r\n", - " \"name\": \"tfsimple1\"\r\n", - " }\r\n", - " ],\r\n", - " \"output\": {\r\n", - " \"steps\": [\r\n", - " \"tfsimple1.outputs\"\r\n", - " ]\r\n", - " },\r\n", - " \"kubernetesMeta\": {}\r\n", - " },\r\n", - " \"state\": {\r\n", - " \"pipelineVersion\": 1,\r\n", - " \"status\": \"PipelineReady\",\r\n", - " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-11T19:05:24.983237899Z\",\r\n", - " \"modelsReady\": true\r\n", - " }\r\n", - " }\r\n", - " ]\r\n", - "}\r\n" - ] - } - ], - "source": [ - "!seldon pipeline status tfsimple -w PipelineReady| jq -M ." - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "87f10a5c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\r\n", - " \"model_name\": \"\",\r\n", - " \"outputs\": [\r\n", - " {\r\n", - " \"data\": [\r\n", - " 2,\r\n", - " 4,\r\n", - " 6,\r\n", - " 8,\r\n", - " 10,\r\n", - " 12,\r\n", - " 14,\r\n", - " 16,\r\n", - " 18,\r\n", - " 20,\r\n", - " 22,\r\n", - " 24,\r\n", - " 26,\r\n", - " 28,\r\n", - " 30,\r\n", - " 32\r\n", - " ],\r\n", - " \"name\": \"OUTPUT0\",\r\n", - " \"shape\": [\r\n", - " 1,\r\n", - " 16\r\n", - " ],\r\n", - " \"datatype\": \"INT32\"\r\n", - " },\r\n", - " {\r\n", - " \"data\": [\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0\r\n", - " ],\r\n", - " \"name\": \"OUTPUT1\",\r\n", - " \"shape\": [\r\n", - " 1,\r\n", - " 16\r\n", - " ],\r\n", - " \"datatype\": \"INT32\"\r\n", - " }\r\n", - " ]\r\n", - "}\r\n" - ] - } - ], - "source": [ - "!seldon pipeline infer tfsimple \\\n", - " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "748d3f68", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "apiVersion: mlops.seldon.io/v1alpha1\r\n", - "kind: Pipeline\r\n", - "metadata:\r\n", - " name: tfsimple-extended\r\n", - "spec:\r\n", - " input:\r\n", - " externalInputs:\r\n", - " - tfsimple.outputs\r\n", - " tensorMap:\r\n", - " tfsimple.outputs.OUTPUT0: INPUT0\r\n", - " tfsimple.outputs.OUTPUT1: INPUT1\r\n", - " steps:\r\n", - " - name: tfsimple2\r\n", - " output:\r\n", - " steps:\r\n", - " - tfsimple2\r\n" - ] - } - ], - "source": [ - "!cat ./pipelines/tfsimple-extended.yaml" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "id": "2e2b275c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{}\r\n" - ] - } - ], - "source": [ - "!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "7410e21f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\r\n", - " \"pipelineName\": \"tfsimple-extended\",\r\n", - " \"versions\": [\r\n", - " {\r\n", - " \"pipeline\": {\r\n", - " \"name\": \"tfsimple-extended\",\r\n", - " \"uid\": \"ceb2jub7778s739emasg\",\r\n", - " \"version\": 1,\r\n", - " \"steps\": [\r\n", - " {\r\n", - " \"name\": \"tfsimple2\"\r\n", - " }\r\n", - " ],\r\n", - " \"output\": {\r\n", - " \"steps\": [\r\n", - " \"tfsimple2.outputs\"\r\n", - " ]\r\n", - " },\r\n", - " \"kubernetesMeta\": {},\r\n", - " \"input\": {\r\n", - " \"externalInputs\": [\r\n", - " \"tfsimple.outputs\"\r\n", - " ],\r\n", - " \"tensorMap\": {\r\n", - " \"tfsimple.outputs.OUTPUT0\": \"INPUT0\",\r\n", - " \"tfsimple.outputs.OUTPUT1\": \"INPUT1\"\r\n", - " }\r\n", - " }\r\n", - " },\r\n", - " \"state\": {\r\n", - " \"pipelineVersion\": 1,\r\n", - " \"status\": \"PipelineReady\",\r\n", - " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-11T19:05:29.772617037Z\",\r\n", - " \"modelsReady\": true\r\n", - " }\r\n", - " }\r\n", - " ]\r\n", - "}\r\n" - ] - } - ], - "source": [ - "!seldon pipeline status tfsimple-extended -w PipelineReady| jq -M ." - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "41f58a7d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\r\n", - " \"model_name\": \"\",\r\n", - " \"outputs\": [\r\n", - " {\r\n", - " \"data\": [\r\n", - " 2,\r\n", - " 4,\r\n", - " 6,\r\n", - " 8,\r\n", - " 10,\r\n", - " 12,\r\n", - " 14,\r\n", - " 16,\r\n", - " 18,\r\n", - " 20,\r\n", - " 22,\r\n", - " 24,\r\n", - " 26,\r\n", - " 28,\r\n", - " 30,\r\n", - " 32\r\n", - " ],\r\n", - " \"name\": \"OUTPUT0\",\r\n", - " \"shape\": [\r\n", - " 1,\r\n", - " 16\r\n", - " ],\r\n", - " \"datatype\": \"INT32\"\r\n", - " },\r\n", - " {\r\n", - " \"data\": [\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0,\r\n", - " 0\r\n", - " ],\r\n", - " \"name\": \"OUTPUT1\",\r\n", - " \"shape\": [\r\n", - " 1,\r\n", - " 16\r\n", - " ],\r\n", - " \"datatype\": \"INT32\"\r\n", - " }\r\n", - " ]\r\n", - "}\r\n" - ] - } - ], - "source": [ - "!seldon pipeline infer tfsimple \\\n", - " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "44f69abb", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "seldon.default.model.tfsimple2.inputs\tceb2jv5mlqdc7398nsu0\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-1b7b594c742bc3db-01\r\n", - "seldon.default.model.tfsimple2.outputs\tceb2jv5mlqdc7398nsu0\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-a1aba81e7ebf0398-01\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\tceb2jv5mlqdc7398nsu0\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-9e6954a3b7387bd7-01\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\tceb2jv5mlqdc7398nsu0\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tX-Forwarded-Proto=http\tX-Envoy-Expected-Rq-Timeout-Ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tx-request-id=ceb2jv40tkps73d9fdmg\tpipeline=tfsimple-extended\ttraceparent=00-f4e27231d55c8947497b462af7d509e3-6170594b79633430-01\r\n" - ] - } - ], - "source": [ - "!seldon pipeline inspect tfsimple-extended --verbose" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "dimensional-hours", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{}\n", - "{}\n" - ] - } - ], - "source": [ - "!seldon pipeline unload tfsimple-extended\n", - "!seldon pipeline unload tfsimple" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "outside-inspiration", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{}\n", - "{}\n" - ] - } - ], - "source": [ - "!seldon model unload tfsimple1\n", - "!seldon model unload tfsimple2" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/samples/pipeline-to-pipeline.ipynb b/samples/pipeline-to-pipeline.ipynb new file mode 100644 index 0000000000..cdcf0f371c --- /dev/null +++ b/samples/pipeline-to-pipeline.ipynb @@ -0,0 +1,1137 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "lesbian-springer", + "metadata": {}, + "source": [ + "## Seldon V2 Pipeline to Pipeline Examples\n", + "\n", + "This notebook illustrates a series of Pipelines that are joined together.\n", + "\n", + "### Models Used\n", + "\n", + " * `gs://seldon-models/triton/simple` an example Triton tensorflow model that takes 2 inputs INPUT0 and INPUT1 and adds them to produce OUTPUT0 and also subtracts INPUT1 from INPUT0 to produce OUTPUT1. See [here](https://github.com/triton-inference-server/server/tree/main/docs/examples/model_repository/simple) for the original source code and license.\n", + " * Other models can be found at https://github.com/SeldonIO/triton-python-examples" + ] + }, + { + "cell_type": "markdown", + "id": "running-antarctica", + "metadata": {}, + "source": [ + "### Pipeline pulling from one other Pipeline\n", + "\n", + "![pipeline-to-pipeline](img_pipeline1.jpg)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0f2ab2a3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple1\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple2\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n" + ] + } + ], + "source": [ + "!cat ./models/tfsimple1.yaml\n", + "!cat ./models/tfsimple2.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "f9e073d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model load -f ./models/tfsimple1.yaml \n", + "!seldon model load -f ./models/tfsimple2.yaml " + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "997b4028", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model status tfsimple1 -w ModelAvailable | jq -M .\n", + "!seldon model status tfsimple2 -w ModelAvailable | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "3d017ede", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple\r\n", + "spec:\r\n", + " steps:\r\n", + " - name: tfsimple1\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple1\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "following-winning", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "artistic-kentucky", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple\",\r\n", + " \"uid\": \"cebjfkev219s73a6oj9g\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple1\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple1.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {}\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-12T14:16:49.990318986Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "87f10a5c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"model_name\": \"\",\r\n", + " \"outputs\": [\r\n", + " {\r\n", + " \"data\": [\r\n", + " 2,\r\n", + " 4,\r\n", + " 6,\r\n", + " 8,\r\n", + " 10,\r\n", + " 12,\r\n", + " 14,\r\n", + " 16,\r\n", + " 18,\r\n", + " 20,\r\n", + " 22,\r\n", + " 24,\r\n", + " 26,\r\n", + " 28,\r\n", + " 30,\r\n", + " 32\r\n", + " ],\r\n", + " \"name\": \"OUTPUT0\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " },\r\n", + " {\r\n", + " \"data\": [\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0\r\n", + " ],\r\n", + " \"name\": \"OUTPUT1\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "00575d89", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple-extended\r\n", + "spec:\r\n", + " input:\r\n", + " externalInputs:\r\n", + " - tfsimple.outputs\r\n", + " tensorMap:\r\n", + " tfsimple.outputs.OUTPUT0: INPUT0\r\n", + " tfsimple.outputs.OUTPUT1: INPUT1\r\n", + " steps:\r\n", + " - name: tfsimple2\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple2\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple-extended.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "8fcd8947", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "5a69008c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple-extended\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple-extended\",\r\n", + " \"uid\": \"cebjflmv219s73a6oja0\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple2\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple2.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {},\r\n", + " \"input\": {\r\n", + " \"externalInputs\": [\r\n", + " \"tfsimple.outputs\"\r\n", + " ],\r\n", + " \"tensorMap\": {\r\n", + " \"tfsimple.outputs.OUTPUT0\": \"INPUT0\",\r\n", + " \"tfsimple.outputs.OUTPUT1\": \"INPUT1\"\r\n", + " }\r\n", + " }\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-12T14:16:55.036730791Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple-extended -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "e7e19259", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + "\t\"model_name\": \"\",\r\n", + "\t\"outputs\": [\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t2,\r\n", + "\t\t\t\t4,\r\n", + "\t\t\t\t6,\r\n", + "\t\t\t\t8,\r\n", + "\t\t\t\t10,\r\n", + "\t\t\t\t12,\r\n", + "\t\t\t\t14,\r\n", + "\t\t\t\t16,\r\n", + "\t\t\t\t18,\r\n", + "\t\t\t\t20,\r\n", + "\t\t\t\t22,\r\n", + "\t\t\t\t24,\r\n", + "\t\t\t\t26,\r\n", + "\t\t\t\t28,\r\n", + "\t\t\t\t30,\r\n", + "\t\t\t\t32\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT0\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t},\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT1\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t}\r\n", + "\t]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple --header x-request-id=test2 \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' " + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "7bc5413b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple1.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tpipeline=tfsimple\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-1cdabaffabc7d96d-01\r\n", + "seldon.default.model.tfsimple1.outputs\ttest2\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-seldon-route=:tfsimple1_1:\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-043cf8a6bb0435f9-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tpipeline=tfsimple\tx-envoy-upstream-service-time=2\r\n", + "seldon.default.pipeline.tfsimple.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tpipeline=tfsimple\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-1e032bc645fc52be-01\r\n", + "seldon.default.pipeline.tfsimple.outputs\ttest2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tx-envoy-upstream-service-time=2\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-293992b88fa30c11-01\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "46db0594", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-upstream-service-time=2\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-9213a2cc67967dde-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\r\n", + "seldon.default.model.tfsimple2.outputs\ttest2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-a43918d03e7bf97b-01\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-upstream-service-time=2\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-ace407a72595762d-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\ttest2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-4e22f204aa289413-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "dimensional-hours", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline unload tfsimple-extended\n", + "!seldon pipeline unload tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "outside-inspiration", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model unload tfsimple1\n", + "!seldon model unload tfsimple2" + ] + }, + { + "cell_type": "markdown", + "id": "334f19b3", + "metadata": {}, + "source": [ + "### Pipeline pulling from two other Pipelines\n", + "\n", + "![pipeline-to-pipeline](img_pipeline2.jpg)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "edd404e8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple1\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple2\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n" + ] + } + ], + "source": [ + "!cat ./models/tfsimple1.yaml\n", + "!cat ./models/tfsimple2.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "702cffa8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model load -f ./models/tfsimple1.yaml \n", + "!seldon model load -f ./models/tfsimple2.yaml " + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "911ac844", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model status tfsimple1 -w ModelAvailable | jq -M .\n", + "!seldon model status tfsimple2 -w ModelAvailable | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "2b6c16bd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple\r\n", + "spec:\r\n", + " steps:\r\n", + " - name: tfsimple1\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple1\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "64998ac5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "180abbd1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple\",\r\n", + " \"uid\": \"cebkrrev219s73a6ojd0\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple1\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple1.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {}\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-12T15:51:09.865398635Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "afc05068", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"model_name\": \"\",\r\n", + " \"outputs\": [\r\n", + " {\r\n", + " \"data\": [\r\n", + " 2,\r\n", + " 4,\r\n", + " 6,\r\n", + " 8,\r\n", + " 10,\r\n", + " 12,\r\n", + " 14,\r\n", + " 16,\r\n", + " 18,\r\n", + " 20,\r\n", + " 22,\r\n", + " 24,\r\n", + " 26,\r\n", + " 28,\r\n", + " 30,\r\n", + " 32\r\n", + " ],\r\n", + " \"name\": \"OUTPUT0\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " },\r\n", + " {\r\n", + " \"data\": [\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0\r\n", + " ],\r\n", + " \"name\": \"OUTPUT1\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "312819d6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-extended\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple.outputs\n", + " tensorMap:\n", + " tfsimple.outputs.OUTPUT0: INPUT0\n", + " tfsimple.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n", + "---\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-extended2\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple.outputs\n", + " tensorMap:\n", + " tfsimple.outputs.OUTPUT0: INPUT0\n", + " tfsimple.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n", + "---\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-combined\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple-extended.outputs.OUTPUT0\n", + " - tfsimple-extended2.outputs.OUTPUT1\n", + " tensorMap:\n", + " tfsimple-extended.outputs.OUTPUT0: INPUT0\n", + " tfsimple-extended2.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple-extended.yaml\n", + "!echo \"---\"\n", + "!cat ./pipelines/tfsimple-extended2.yaml\n", + "!echo \"---\"\n", + "!cat ./pipelines/tfsimple-combined.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "8a65c4b5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml\n", + "!seldon pipeline load -f ./pipelines/tfsimple-extended2.yaml\n", + "!seldon pipeline load -f ./pipelines/tfsimple-combined.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "065fdfb5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\"pipelineName\":\"tfsimple-extended\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\",\"uid\":\"cebkrsmv219s73a6ojdg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T15:51:15.052994356Z\",\"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\",\"uid\":\"cebkrsuv219s73a6oje0\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T15:51:15.239211192Z\",\"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined\",\"uid\":\"cebkrsuv219s73a6ojeg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple-extended.outputs.OUTPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\"],\"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T15:51:15.653101970Z\",\"modelsReady\":true}}]}\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple-extended -w PipelineReady\n", + "!seldon pipeline status tfsimple-extended2 -w PipelineReady\n", + "!seldon pipeline status tfsimple-combined -w PipelineReady" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "2646e24c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + "\t\"model_name\": \"\",\r\n", + "\t\"outputs\": [\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t2,\r\n", + "\t\t\t\t4,\r\n", + "\t\t\t\t6,\r\n", + "\t\t\t\t8,\r\n", + "\t\t\t\t10,\r\n", + "\t\t\t\t12,\r\n", + "\t\t\t\t14,\r\n", + "\t\t\t\t16,\r\n", + "\t\t\t\t18,\r\n", + "\t\t\t\t20,\r\n", + "\t\t\t\t22,\r\n", + "\t\t\t\t24,\r\n", + "\t\t\t\t26,\r\n", + "\t\t\t\t28,\r\n", + "\t\t\t\t30,\r\n", + "\t\t\t\t32\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT0\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t},\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT1\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t}\r\n", + "\t]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple --header x-request-id=test-id2 \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' " + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "c4de4c2a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple1.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tpipeline=tfsimple\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-8960bf9ddd1223b4-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n", + "seldon.default.model.tfsimple1.outputs\ttest-id2\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tpipeline=tfsimple\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-a835484a63f0d4c5-01\tx-request-id=test-id2\r\n", + "seldon.default.pipeline.tfsimple.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tpipeline=tfsimple\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-71e26fd10f248e48-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n", + "seldon.default.pipeline.tfsimple.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-94d4199b888a2c37-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "c63ad70f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-f2946c2615d48c61-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-586160b2ad04224d-01\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-4ee7f8ce8ad4cd95-01\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-5020c773962b9d4f-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "6608f79c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-f2946c2615d48c61-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-586160b2ad04224d-01\tx-request-id=test-id2\r\n", + "seldon.default.pipeline.tfsimple-extended2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended2\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-719e994252168715-01\r\n", + "seldon.default.pipeline.tfsimple-extended2.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended2\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-867ec2fe8a109fc7-01\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended2 --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "037ca036", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-f2946c2615d48c61-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-586160b2ad04224d-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\r\n", + "seldon.default.pipeline.tfsimple-combined.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-d7ba9e7f2dded2b2-01\r\n", + "seldon.default.pipeline.tfsimple-combined.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-b024ed95a190c77e-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-combined --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "66d4b676", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n", + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline unload tfsimple-extended\n", + "!seldon pipeline unload tfsimple-extended2\n", + "!seldon pipeline unload tfsimple-combined\n", + "!seldon pipeline unload tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "c5d60065", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model unload tfsimple1\n", + "!seldon model unload tfsimple2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42788eeb", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/samples/pipelines/tfsimple-combined.yaml b/samples/pipelines/tfsimple-combined.yaml new file mode 100644 index 0000000000..1274988835 --- /dev/null +++ b/samples/pipelines/tfsimple-combined.yaml @@ -0,0 +1,17 @@ +apiVersion: mlops.seldon.io/v1alpha1 +kind: Pipeline +metadata: + name: tfsimple-combined +spec: + input: + externalInputs: + - tfsimple-extended.outputs.OUTPUT0 + - tfsimple-extended2.outputs.OUTPUT1 + tensorMap: + tfsimple-extended.outputs.OUTPUT0: INPUT0 + tfsimple-extended2.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 diff --git a/samples/pipelines/tfsimple-extended2.yaml b/samples/pipelines/tfsimple-extended2.yaml new file mode 100644 index 0000000000..f81847d29a --- /dev/null +++ b/samples/pipelines/tfsimple-extended2.yaml @@ -0,0 +1,16 @@ +apiVersion: mlops.seldon.io/v1alpha1 +kind: Pipeline +metadata: + name: tfsimple-extended2 +spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 diff --git a/scheduler/pkg/kafka/pipeline/utils.go b/scheduler/pkg/kafka/pipeline/utils.go index 791da43470..70fa2da30d 100644 --- a/scheduler/pkg/kafka/pipeline/utils.go +++ b/scheduler/pkg/kafka/pipeline/utils.go @@ -51,7 +51,7 @@ func convertHttpHeadersToKafkaHeaders(httpHeaders http.Header) []kafka.Header { for k, vals := range httpHeaders { if strings.HasPrefix(strings.ToLower(k), resources.ExternalHeaderPrefix) { for _, headerValue := range vals { - kafkaHeaders = append(kafkaHeaders, kafka.Header{Key: k, Value: []byte(headerValue)}) + kafkaHeaders = append(kafkaHeaders, kafka.Header{Key: strings.ToLower(k), Value: []byte(headerValue)}) } } } From 949f9a523f75dca10b5f0f61b375ee4bae397a39 Mon Sep 17 00:00:00 2001 From: Clive Cox Date: Mon, 12 Dec 2022 18:49:23 +0000 Subject: [PATCH 03/18] add trigger example --- docs/source/contents/examples/index.md | 2 + .../contents/examples/pipeline-to-pipeline.md | 8 + docs/source/contents/pipelines/index.md | 29 + samples/img_pipeline3.jpg | Bin 0 -> 83299 bytes samples/pipeline-to-pipeline.ipynb | 759 +++++++++-- samples/pipeline-to-pipeline.md | 1170 +++++++++++++++++ .../pipelines/tfsimple-combined-trigger.yaml | 18 + 7 files changed, 1893 insertions(+), 93 deletions(-) create mode 100644 docs/source/contents/examples/pipeline-to-pipeline.md create mode 100644 samples/img_pipeline3.jpg create mode 100644 samples/pipeline-to-pipeline.md create mode 100644 samples/pipelines/tfsimple-combined-trigger.yaml diff --git a/docs/source/contents/examples/index.md b/docs/source/contents/examples/index.md index 4bfb1dc7b6..28a9e34f68 100644 --- a/docs/source/contents/examples/index.md +++ b/docs/source/contents/examples/index.md @@ -14,6 +14,7 @@ This section will provide some examples to allow operations with Seldon to be te ## Pipelines * [Pipeline examples](pipeline-examples.md) +* [Pipeline to pipeline examples](pipeline-to-pipeline.md) ## Explainers @@ -50,6 +51,7 @@ local-examples.md k8s-examples.md huggingface.md pipeline-examples.md +pipeline-to-pipeline.md explainer-examples.md local-experiments.md experiment-versions.md diff --git a/docs/source/contents/examples/pipeline-to-pipeline.md b/docs/source/contents/examples/pipeline-to-pipeline.md new file mode 100644 index 0000000000..ebace88f81 --- /dev/null +++ b/docs/source/contents/examples/pipeline-to-pipeline.md @@ -0,0 +1,8 @@ +# Pipeline to Pipeline Examples + +Run these examples from the `samples` folder. + + +```{include} ../../../../samples/pipeline-to-pipeline.md +:relative-images: +``` diff --git a/docs/source/contents/pipelines/index.md b/docs/source/contents/pipelines/index.md index 89dd65ba12..289ec88296 100644 --- a/docs/source/contents/pipelines/index.md +++ b/docs/source/contents/pipelines/index.md @@ -130,6 +130,35 @@ Here the `mul10` step is run if data is seen on the pipeline inputs in the `ok1` If we changed the `triggersJoinType` for `mul10` to `inner` then both `ok1` and `ok2` would need to appear before `mul10` is run. +### Pipeline Inputs + +Pipelines by default can be accessed synchronously via http/grpc or via the Kafka topic created for them. However, it's also possible to create a pipeline to take input from one or more other pipelines by specifying an `input` section. If for example we already have the `tfsimple` pipeline shown below: + +```{literalinclude} ../../../../samples/pipelines/tfsimple.yaml +:language: yaml +``` + +We can create another pipeline which takes its input from this pipeline, as shown below: + +```{literalinclude} ../../../../samples/pipelines/tfsimple-extended.yaml +:language: yaml +``` + +In this way pipelines can be built to extend existing running pipelines to allow extensibility and sharing of data flows. + +The spec follows the spec for a step except that references to other pipelines are contained in the `externalInputs` section which takes the form of pipeline or pipeline step references: + * `.(inputs|outputs).` + * `.(step)..` + +Tensor names are optional and only needed if you want to take just one tensor from an input or output. + +There is also an `externalTriggers` section which allows triggers from other pipelines. + +Further examples can be found in the [pipeline-to-pipeline examples](../examples/pipeline-to-pipeline.md). + +Present caveats: + * Circular dependencies are not detected. + * Pipeline status is local to each pipeline. ## Data Centric Implementation diff --git a/samples/img_pipeline3.jpg b/samples/img_pipeline3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c92882e5c747f57cc7aecc996fcb61e87e5ecff8 GIT binary patch literal 83299 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 EKNL$}82|tP literal 0 HcmV?d00001 diff --git a/samples/pipeline-to-pipeline.ipynb b/samples/pipeline-to-pipeline.ipynb index cdcf0f371c..22c444c0fd 100644 --- a/samples/pipeline-to-pipeline.ipynb +++ b/samples/pipeline-to-pipeline.ipynb @@ -27,7 +27,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 82, "id": "0f2ab2a3", "metadata": {}, "outputs": [ @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 118, "id": "f9e073d7", "metadata": {}, "outputs": [ @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 119, "id": "997b4028", "metadata": {}, "outputs": [ @@ -103,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 120, "id": "3d017ede", "metadata": {}, "outputs": [ @@ -130,7 +130,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 121, "id": "following-winning", "metadata": {}, "outputs": [ @@ -148,7 +148,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 122, "id": "artistic-kentucky", "metadata": {}, "outputs": [ @@ -162,7 +162,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cebjfkev219s73a6oj9g\",\r\n", + " \"uid\": \"cebnb8ev219s73a6ojk0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -180,7 +180,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-12T14:16:49.990318986Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-12T18:40:33.304154775Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -195,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 123, "id": "87f10a5c", "metadata": {}, "outputs": [ @@ -270,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 124, "id": "00575d89", "metadata": {}, "outputs": [ @@ -303,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 125, "id": "8fcd8947", "metadata": {}, "outputs": [ @@ -321,7 +321,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 126, "id": "5a69008c", "metadata": {}, "outputs": [ @@ -335,7 +335,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple-extended\",\r\n", - " \"uid\": \"cebjflmv219s73a6oja0\",\r\n", + " \"uid\": \"cebnb9mv219s73a6ojkg\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -362,7 +362,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-12T14:16:55.036730791Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-12T18:40:39.004261615Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -377,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 127, "id": "e7e19259", "metadata": {}, "outputs": [ @@ -446,34 +446,34 @@ } ], "source": [ - "!seldon pipeline infer tfsimple --header x-request-id=test2 \\\n", + "!seldon pipeline infer tfsimple \\\n", " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' " ] }, { "cell_type": "code", - "execution_count": 25, - "id": "7bc5413b", + "execution_count": 128, + "id": "e86c40b8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tpipeline=tfsimple\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-1cdabaffabc7d96d-01\r\n", - "seldon.default.model.tfsimple1.outputs\ttest2\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-seldon-route=:tfsimple1_1:\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-043cf8a6bb0435f9-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tpipeline=tfsimple\tx-envoy-upstream-service-time=2\r\n", - "seldon.default.pipeline.tfsimple.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tpipeline=tfsimple\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-1e032bc645fc52be-01\r\n", - "seldon.default.pipeline.tfsimple.outputs\ttest2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tx-envoy-upstream-service-time=2\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-293992b88fa30c11-01\r\n" + "seldon.default.model.tfsimple1.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\tcebnba9q03gs739pd0eg\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\tcebnba9q03gs739pd0eg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple --verbose" + "!seldon pipeline inspect tfsimple" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 129, "id": "46db0594", "metadata": {}, "outputs": [ @@ -481,20 +481,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-upstream-service-time=2\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-9213a2cc67967dde-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\r\n", - "seldon.default.model.tfsimple2.outputs\ttest2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-a43918d03e7bf97b-01\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\ttest2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-upstream-service-time=2\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-ace407a72595762d-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\ttest2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended\ttraceparent=00-c5a74829ee3dd8678d7f457387481ef7-4e22f204aa289413-01\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-request-id=test2\r\n" + "seldon.default.model.tfsimple2.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tcebnba9q03gs739pd0eg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tcebnba9q03gs739pd0eg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-extended --verbose" + "!seldon pipeline inspect tfsimple-extended" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 130, "id": "dimensional-hours", "metadata": {}, "outputs": [ @@ -514,7 +514,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 131, "id": "outside-inspiration", "metadata": {}, "outputs": [ @@ -534,7 +534,7 @@ }, { "cell_type": "markdown", - "id": "334f19b3", + "id": "097a1101", "metadata": {}, "source": [ "### Pipeline pulling from two other Pipelines\n", @@ -544,8 +544,8 @@ }, { "cell_type": "code", - "execution_count": 48, - "id": "edd404e8", + "execution_count": 97, + "id": "6b282f45", "metadata": {}, "outputs": [ { @@ -580,8 +580,8 @@ }, { "cell_type": "code", - "execution_count": 49, - "id": "702cffa8", + "execution_count": 98, + "id": "078e7ba6", "metadata": {}, "outputs": [ { @@ -600,8 +600,8 @@ }, { "cell_type": "code", - "execution_count": 50, - "id": "911ac844", + "execution_count": 99, + "id": "6e97299b", "metadata": {}, "outputs": [ { @@ -620,8 +620,8 @@ }, { "cell_type": "code", - "execution_count": 51, - "id": "2b6c16bd", + "execution_count": 100, + "id": "528d36ca", "metadata": {}, "outputs": [ { @@ -647,8 +647,8 @@ }, { "cell_type": "code", - "execution_count": 52, - "id": "64998ac5", + "execution_count": 101, + "id": "ce4efa1c", "metadata": {}, "outputs": [ { @@ -665,8 +665,8 @@ }, { "cell_type": "code", - "execution_count": 53, - "id": "180abbd1", + "execution_count": 102, + "id": "aa46faea", "metadata": {}, "outputs": [ { @@ -679,7 +679,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cebkrrev219s73a6ojd0\",\r\n", + " \"uid\": \"cebnacuv219s73a6oji0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -697,7 +697,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-12T15:51:09.865398635Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-12T18:38:43.317204867Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -712,8 +712,8 @@ }, { "cell_type": "code", - "execution_count": 54, - "id": "afc05068", + "execution_count": 103, + "id": "bd33da59", "metadata": {}, "outputs": [ { @@ -787,8 +787,8 @@ }, { "cell_type": "code", - "execution_count": 55, - "id": "312819d6", + "execution_count": 104, + "id": "3d7f0b28", "metadata": {}, "outputs": [ { @@ -859,8 +859,8 @@ }, { "cell_type": "code", - "execution_count": 56, - "id": "8a65c4b5", + "execution_count": 105, + "id": "4c44cfaf", "metadata": {}, "outputs": [ { @@ -881,17 +881,17 @@ }, { "cell_type": "code", - "execution_count": 57, - "id": "065fdfb5", + "execution_count": 106, + "id": "c762ac75", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{\"pipelineName\":\"tfsimple-extended\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\",\"uid\":\"cebkrsmv219s73a6ojdg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T15:51:15.052994356Z\",\"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-extended2\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\",\"uid\":\"cebkrsuv219s73a6oje0\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T15:51:15.239211192Z\",\"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-combined\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined\",\"uid\":\"cebkrsuv219s73a6ojeg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple-extended.outputs.OUTPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\"],\"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T15:51:15.653101970Z\",\"modelsReady\":true}}]}\n" + "{\"pipelineName\":\"tfsimple-extended\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\",\"uid\":\"cebnaemv219s73a6ojig\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:38:50.324389094Z\",\"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\",\"uid\":\"cebnaemv219s73a6ojj0\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:38:50.467839593Z\",\"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined\",\"uid\":\"cebnaemv219s73a6ojjg\",\"version\":2,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple-extended.outputs.OUTPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\"],\"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":2,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:38:50.718933075Z\",\"modelsReady\":true}}]}\n" ] } ], @@ -903,8 +903,8 @@ }, { "cell_type": "code", - "execution_count": 60, - "id": "2646e24c", + "execution_count": 107, + "id": "764ce126", "metadata": {}, "outputs": [ { @@ -972,98 +972,98 @@ } ], "source": [ - "!seldon pipeline infer tfsimple --header x-request-id=test-id2 \\\n", + "!seldon pipeline infer tfsimple \\\n", " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' " ] }, { "cell_type": "code", - "execution_count": 61, - "id": "c4de4c2a", + "execution_count": 112, + "id": "6f9b6b66", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tpipeline=tfsimple\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-8960bf9ddd1223b4-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n", - "seldon.default.model.tfsimple1.outputs\ttest-id2\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tpipeline=tfsimple\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-a835484a63f0d4c5-01\tx-request-id=test-id2\r\n", - "seldon.default.pipeline.tfsimple.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\t\tpipeline=tfsimple\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-71e26fd10f248e48-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n", - "seldon.default.pipeline.tfsimple.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-94d4199b888a2c37-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\r\n" + "seldon.default.model.tfsimple1.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple --verbose" + "!seldon pipeline inspect tfsimple" ] }, { "cell_type": "code", - "execution_count": 62, - "id": "c63ad70f", + "execution_count": 113, + "id": "b8f2ecb8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-f2946c2615d48c61-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-586160b2ad04224d-01\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-4ee7f8ce8ad4cd95-01\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-5020c773962b9d4f-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n" + "seldon.default.model.tfsimple2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-extended --verbose" + "!seldon pipeline inspect tfsimple-extended" ] }, { "cell_type": "code", - "execution_count": 63, - "id": "6608f79c", + "execution_count": 114, + "id": "e36bcbbe", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-f2946c2615d48c61-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-586160b2ad04224d-01\tx-request-id=test-id2\r\n", - "seldon.default.pipeline.tfsimple-extended2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple1_1:\tpipeline=tfsimple-extended2\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-719e994252168715-01\r\n", - "seldon.default.pipeline.tfsimple-extended2.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-extended2\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-867ec2fe8a109fc7-01\r\n" + "seldon.default.model.tfsimple2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-extended2 --verbose" + "!seldon pipeline inspect tfsimple-extended2" ] }, { "cell_type": "code", - "execution_count": 64, - "id": "037ca036", + "execution_count": 115, + "id": "a69e1bdf", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-f2946c2615d48c61-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id2\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-586160b2ad04224d-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\r\n", - "seldon.default.pipeline.tfsimple-combined.inputs\ttest-id2\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-d7ba9e7f2dded2b2-01\r\n", - "seldon.default.pipeline.tfsimple-combined.outputs\ttest-id2\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\t\tx-envoy-upstream-service-time=1\tx-seldon-route=:tfsimple2_1:\tpipeline=tfsimple-combined\ttraceparent=00-f0cd092652f5cdea2258b492ced2a07c-b024ed95a190c77e-01\tx-request-id=test-id2\tx-forwarded-proto=http\tx-envoy-expected-rq-timeout-ms=60000\r\n" + "seldon.default.model.tfsimple2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-combined.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-combined.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-combined --verbose" + "!seldon pipeline inspect tfsimple-combined" ] }, { "cell_type": "code", - "execution_count": 46, - "id": "66d4b676", + "execution_count": 116, + "id": "ffd757b8", "metadata": {}, "outputs": [ { @@ -1086,8 +1086,581 @@ }, { "cell_type": "code", - "execution_count": 47, - "id": "c5d60065", + "execution_count": 117, + "id": "d9163fc4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model unload tfsimple1\n", + "!seldon model unload tfsimple2" + ] + }, + { + "cell_type": "markdown", + "id": "4d09887b", + "metadata": {}, + "source": [ + "### Pipeline pullin from one pipeline with a trigger to another\n", + "\n", + "![pipeline-to-pipeline](img_pipeline3.jpg)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "id": "5484193c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple1\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple2\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n" + ] + } + ], + "source": [ + "!cat ./models/tfsimple1.yaml\n", + "!cat ./models/tfsimple2.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "id": "2e2d1413", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model load -f ./models/tfsimple1.yaml \n", + "!seldon model load -f ./models/tfsimple2.yaml " + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "id": "90ab831e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model status tfsimple1 -w ModelAvailable | jq -M .\n", + "!seldon model status tfsimple2 -w ModelAvailable | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "id": "26b37b90", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple\r\n", + "spec:\r\n", + " steps:\r\n", + " - name: tfsimple1\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple1\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "id": "2c2c6480", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "id": "b1417cba", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple\",\r\n", + " \"uid\": \"cebnbguv219s73a6ojl0\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple1\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple1.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {}\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-12T18:41:07.131448326Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "id": "a3071607", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"model_name\": \"\",\r\n", + " \"outputs\": [\r\n", + " {\r\n", + " \"data\": [\r\n", + " 2,\r\n", + " 4,\r\n", + " 6,\r\n", + " 8,\r\n", + " 10,\r\n", + " 12,\r\n", + " 14,\r\n", + " 16,\r\n", + " 18,\r\n", + " 20,\r\n", + " 22,\r\n", + " 24,\r\n", + " 26,\r\n", + " 28,\r\n", + " 30,\r\n", + " 32\r\n", + " ],\r\n", + " \"name\": \"OUTPUT0\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " },\r\n", + " {\r\n", + " \"data\": [\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0\r\n", + " ],\r\n", + " \"name\": \"OUTPUT1\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "id": "9c501d85", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-extended\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple.outputs\n", + " tensorMap:\n", + " tfsimple.outputs.OUTPUT0: INPUT0\n", + " tfsimple.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n", + "---\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-extended2\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple.outputs\n", + " tensorMap:\n", + " tfsimple.outputs.OUTPUT0: INPUT0\n", + " tfsimple.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n", + "---\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-combined-trigger\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple-extended.outputs\n", + " externalTriggers:\n", + " - tfsimple-extended2.outputs\n", + " tensorMap:\n", + " tfsimple-extended.outputs.OUTPUT0: INPUT0\n", + " tfsimple-extended.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple-extended.yaml\n", + "!echo \"---\"\n", + "!cat ./pipelines/tfsimple-extended2.yaml\n", + "!echo \"---\"\n", + "!cat ./pipelines/tfsimple-combined-trigger.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "id": "f67b698b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml\n", + "!seldon pipeline load -f ./pipelines/tfsimple-extended2.yaml\n", + "!seldon pipeline load -f ./pipelines/tfsimple-combined-trigger.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "id": "9d8d54d1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\"pipelineName\":\"tfsimple-extended\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\",\"uid\":\"cebnbimv219s73a6ojlg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:41:14.561905446Z\",\"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\",\"uid\":\"cebnbimv219s73a6ojm0\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:41:14.693285174Z\",\"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined-trigger\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined-trigger\",\"uid\":\"cebnbimv219s73a6ojmg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple-extended.outputs\"],\"externalTriggers\":[\"tfsimple-extended2.outputs\"],\"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple-extended.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:41:14.945627389Z\",\"modelsReady\":true}}]}\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple-extended -w PipelineReady\n", + "!seldon pipeline status tfsimple-extended2 -w PipelineReady\n", + "!seldon pipeline status tfsimple-combined-trigger -w PipelineReady" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "id": "22e95a26", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + "\t\"model_name\": \"\",\r\n", + "\t\"outputs\": [\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t2,\r\n", + "\t\t\t\t4,\r\n", + "\t\t\t\t6,\r\n", + "\t\t\t\t8,\r\n", + "\t\t\t\t10,\r\n", + "\t\t\t\t12,\r\n", + "\t\t\t\t14,\r\n", + "\t\t\t\t16,\r\n", + "\t\t\t\t18,\r\n", + "\t\t\t\t20,\r\n", + "\t\t\t\t22,\r\n", + "\t\t\t\t24,\r\n", + "\t\t\t\t26,\r\n", + "\t\t\t\t28,\r\n", + "\t\t\t\t30,\r\n", + "\t\t\t\t32\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT0\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t},\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT1\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t}\r\n", + "\t]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple --header x-request-id=test-id3 \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' " + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "id": "b69e9c58", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple1.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\ttest-id3\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "id": "4926208f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id1\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "id": "e7be9a2b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id1\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended2" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "id": "07a3643c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tcebki39q03gs739pd0ag\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-combined-trigger.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-combined-trigger.outputs\tcebjfl1q03gs739pd09g\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-combined-trigger" + ] + }, + { + "cell_type": "code", + "execution_count": 147, + "id": "59fd2fbe", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n", + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline unload tfsimple-extended\n", + "!seldon pipeline unload tfsimple-extended2\n", + "!seldon pipeline unload tfsimple-combined-trigger\n", + "!seldon pipeline unload tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 148, + "id": "0ff176d4", "metadata": {}, "outputs": [ { @@ -1107,7 +1680,7 @@ { "cell_type": "code", "execution_count": null, - "id": "42788eeb", + "id": "1af9d600", "metadata": {}, "outputs": [], "source": [] diff --git a/samples/pipeline-to-pipeline.md b/samples/pipeline-to-pipeline.md new file mode 100644 index 0000000000..e396c64bee --- /dev/null +++ b/samples/pipeline-to-pipeline.md @@ -0,0 +1,1170 @@ +## Seldon V2 Pipeline to Pipeline Examples + +This notebook illustrates a series of Pipelines that are joined together. + +### Models Used + + * `gs://seldon-models/triton/simple` an example Triton tensorflow model that takes 2 inputs INPUT0 and INPUT1 and adds them to produce OUTPUT0 and also subtracts INPUT1 from INPUT0 to produce OUTPUT1. See [here](https://github.com/triton-inference-server/server/tree/main/docs/examples/model_repository/simple) for the original source code and license. + * Other models can be found at https://github.com/SeldonIO/triton-python-examples + +### Pipeline pulling from one other Pipeline + +![pipeline-to-pipeline](img_pipeline1.jpg) + + + +```python +!cat ./models/tfsimple1.yaml +!cat ./models/tfsimple2.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple1 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple2 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + + + +```python +!seldon model load -f ./models/tfsimple1.yaml +!seldon model load -f ./models/tfsimple2.yaml +``` + + {} + {} + + + +```python +!seldon model status tfsimple1 -w ModelAvailable | jq -M . +!seldon model status tfsimple2 -w ModelAvailable | jq -M . +``` + + {} + {} + + + +```python +!cat ./pipelines/tfsimple.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple + spec: + steps: + - name: tfsimple1 + output: + steps: + - tfsimple1 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple.yaml +``` + + {} + + + +```python +!seldon pipeline status tfsimple -w PipelineReady| jq -M . +``` + + { + "pipelineName": "tfsimple", + "versions": [ + { + "pipeline": { + "name": "tfsimple", + "uid": "cebnb8ev219s73a6ojk0", + "version": 1, + "steps": [ + { + "name": "tfsimple1" + } + ], + "output": { + "steps": [ + "tfsimple1.outputs" + ] + }, + "kubernetesMeta": {} + }, + "state": { + "pipelineVersion": 1, + "status": "PipelineReady", + "reason": "created pipeline", + "lastChangeTimestamp": "2022-12-12T18:40:33.304154775Z", + "modelsReady": true + } + } + ] + } + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' | jq -M . +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!cat ./pipelines/tfsimple-extended.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended + spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml +``` + + {} + + + +```python +!seldon pipeline status tfsimple-extended -w PipelineReady| jq -M . +``` + + { + "pipelineName": "tfsimple-extended", + "versions": [ + { + "pipeline": { + "name": "tfsimple-extended", + "uid": "cebnb9mv219s73a6ojkg", + "version": 1, + "steps": [ + { + "name": "tfsimple2" + } + ], + "output": { + "steps": [ + "tfsimple2.outputs" + ] + }, + "kubernetesMeta": {}, + "input": { + "externalInputs": [ + "tfsimple.outputs" + ], + "tensorMap": { + "tfsimple.outputs.OUTPUT0": "INPUT0", + "tfsimple.outputs.OUTPUT1": "INPUT1" + } + } + }, + "state": { + "pipelineVersion": 1, + "status": "PipelineReady", + "reason": "created pipeline", + "lastChangeTimestamp": "2022-12-12T18:40:39.004261615Z", + "modelsReady": true + } + } + ] + } + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!seldon pipeline inspect tfsimple +``` + + seldon.default.model.tfsimple1.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} + seldon.default.model.tfsimple1.outputs cebnba9q03gs739pd0eg {"modelName":"tfsimple1_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} + seldon.default.pipeline.tfsimple.outputs cebnba9q03gs739pd0eg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + + + +```python +!seldon pipeline inspect tfsimple-extended +``` + + seldon.default.model.tfsimple2.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.model.tfsimple2.outputs cebnba9q03gs739pd0eg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + seldon.default.pipeline.tfsimple-extended.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended.outputs cebnba9q03gs739pd0eg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + + + +```python +!seldon pipeline unload tfsimple-extended +!seldon pipeline unload tfsimple +``` + + {} + {} + + + +```python +!seldon model unload tfsimple1 +!seldon model unload tfsimple2 +``` + + {} + {} + + +### Pipeline pulling from two other Pipelines + +![pipeline-to-pipeline](img_pipeline2.jpg) + + + +```python +!cat ./models/tfsimple1.yaml +!cat ./models/tfsimple2.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple1 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple2 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + + + +```python +!seldon model load -f ./models/tfsimple1.yaml +!seldon model load -f ./models/tfsimple2.yaml +``` + + {} + {} + + + +```python +!seldon model status tfsimple1 -w ModelAvailable | jq -M . +!seldon model status tfsimple2 -w ModelAvailable | jq -M . +``` + + {} + {} + + + +```python +!cat ./pipelines/tfsimple.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple + spec: + steps: + - name: tfsimple1 + output: + steps: + - tfsimple1 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple.yaml +``` + + {} + + + +```python +!seldon pipeline status tfsimple -w PipelineReady| jq -M . +``` + + { + "pipelineName": "tfsimple", + "versions": [ + { + "pipeline": { + "name": "tfsimple", + "uid": "cebnacuv219s73a6oji0", + "version": 1, + "steps": [ + { + "name": "tfsimple1" + } + ], + "output": { + "steps": [ + "tfsimple1.outputs" + ] + }, + "kubernetesMeta": {} + }, + "state": { + "pipelineVersion": 1, + "status": "PipelineReady", + "reason": "created pipeline", + "lastChangeTimestamp": "2022-12-12T18:38:43.317204867Z", + "modelsReady": true + } + } + ] + } + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' | jq -M . +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!cat ./pipelines/tfsimple-extended.yaml +!echo "---" +!cat ./pipelines/tfsimple-extended2.yaml +!echo "---" +!cat ./pipelines/tfsimple-combined.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended + spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + --- + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended2 + spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + --- + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-combined + spec: + input: + externalInputs: + - tfsimple-extended.outputs.OUTPUT0 + - tfsimple-extended2.outputs.OUTPUT1 + tensorMap: + tfsimple-extended.outputs.OUTPUT0: INPUT0 + tfsimple-extended2.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml +!seldon pipeline load -f ./pipelines/tfsimple-extended2.yaml +!seldon pipeline load -f ./pipelines/tfsimple-combined.yaml +``` + + {} + {} + {} + + + +```python +!seldon pipeline status tfsimple-extended -w PipelineReady +!seldon pipeline status tfsimple-extended2 -w PipelineReady +!seldon pipeline status tfsimple-combined -w PipelineReady +``` + + {"pipelineName":"tfsimple-extended","versions":[{"pipeline":{"name":"tfsimple-extended","uid":"cebnaemv219s73a6ojig","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:38:50.324389094Z","modelsReady":true}}]} + {"pipelineName":"tfsimple-extended2","versions":[{"pipeline":{"name":"tfsimple-extended2","uid":"cebnaemv219s73a6ojj0","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:38:50.467839593Z","modelsReady":true}}]} + {"pipelineName":"tfsimple-combined","versions":[{"pipeline":{"name":"tfsimple-combined","uid":"cebnaemv219s73a6ojjg","version":2,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple-extended.outputs.OUTPUT0","tfsimple-extended2.outputs.OUTPUT1"],"tensorMap":{"tfsimple-extended.outputs.OUTPUT0":"INPUT0","tfsimple-extended2.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":2,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:38:50.718933075Z","modelsReady":true}}]} + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!seldon pipeline inspect tfsimple +``` + + seldon.default.model.tfsimple1.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} + seldon.default.model.tfsimple1.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple1_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} + seldon.default.pipeline.tfsimple.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + + + +```python +!seldon pipeline inspect tfsimple-extended +``` + + seldon.default.model.tfsimple2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple-extended.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + + + +```python +!seldon pipeline inspect tfsimple-extended2 +``` + + seldon.default.model.tfsimple2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple-extended2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended2.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + + + +```python +!seldon pipeline inspect tfsimple-combined +``` + + seldon.default.model.tfsimple2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple-combined.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.pipeline.tfsimple-combined.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + + + +```python +!seldon pipeline unload tfsimple-extended +!seldon pipeline unload tfsimple-extended2 +!seldon pipeline unload tfsimple-combined +!seldon pipeline unload tfsimple +``` + + {} + {} + {} + {} + + + +```python +!seldon model unload tfsimple1 +!seldon model unload tfsimple2 +``` + + {} + {} + + +### Pipeline pullin from one pipeline with a trigger to another + +![pipeline-to-pipeline](img_pipeline3.jpg) + + + +```python +!cat ./models/tfsimple1.yaml +!cat ./models/tfsimple2.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple1 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple2 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + + + +```python +!seldon model load -f ./models/tfsimple1.yaml +!seldon model load -f ./models/tfsimple2.yaml +``` + + {} + {} + + + +```python +!seldon model status tfsimple1 -w ModelAvailable | jq -M . +!seldon model status tfsimple2 -w ModelAvailable | jq -M . +``` + + {} + {} + + + +```python +!cat ./pipelines/tfsimple.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple + spec: + steps: + - name: tfsimple1 + output: + steps: + - tfsimple1 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple.yaml +``` + + {} + + + +```python +!seldon pipeline status tfsimple -w PipelineReady| jq -M . +``` + + { + "pipelineName": "tfsimple", + "versions": [ + { + "pipeline": { + "name": "tfsimple", + "uid": "cebnbguv219s73a6ojl0", + "version": 1, + "steps": [ + { + "name": "tfsimple1" + } + ], + "output": { + "steps": [ + "tfsimple1.outputs" + ] + }, + "kubernetesMeta": {} + }, + "state": { + "pipelineVersion": 1, + "status": "PipelineReady", + "reason": "created pipeline", + "lastChangeTimestamp": "2022-12-12T18:41:07.131448326Z", + "modelsReady": true + } + } + ] + } + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' | jq -M . +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!cat ./pipelines/tfsimple-extended.yaml +!echo "---" +!cat ./pipelines/tfsimple-extended2.yaml +!echo "---" +!cat ./pipelines/tfsimple-combined-trigger.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended + spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + --- + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended2 + spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + --- + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-combined-trigger + spec: + input: + externalInputs: + - tfsimple-extended.outputs + externalTriggers: + - tfsimple-extended2.outputs + tensorMap: + tfsimple-extended.outputs.OUTPUT0: INPUT0 + tfsimple-extended.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml +!seldon pipeline load -f ./pipelines/tfsimple-extended2.yaml +!seldon pipeline load -f ./pipelines/tfsimple-combined-trigger.yaml +``` + + {} + {} + {} + + + +```python +!seldon pipeline status tfsimple-extended -w PipelineReady +!seldon pipeline status tfsimple-extended2 -w PipelineReady +!seldon pipeline status tfsimple-combined-trigger -w PipelineReady +``` + + {"pipelineName":"tfsimple-extended","versions":[{"pipeline":{"name":"tfsimple-extended","uid":"cebnbimv219s73a6ojlg","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:41:14.561905446Z","modelsReady":true}}]} + {"pipelineName":"tfsimple-extended2","versions":[{"pipeline":{"name":"tfsimple-extended2","uid":"cebnbimv219s73a6ojm0","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:41:14.693285174Z","modelsReady":true}}]} + {"pipelineName":"tfsimple-combined-trigger","versions":[{"pipeline":{"name":"tfsimple-combined-trigger","uid":"cebnbimv219s73a6ojmg","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple-extended.outputs"],"externalTriggers":["tfsimple-extended2.outputs"],"tensorMap":{"tfsimple-extended.outputs.OUTPUT0":"INPUT0","tfsimple-extended.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:41:14.945627389Z","modelsReady":true}}]} + + + +```python +!seldon pipeline infer tfsimple --header x-request-id=test-id3 \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!seldon pipeline inspect tfsimple +``` + + seldon.default.model.tfsimple1.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} + seldon.default.model.tfsimple1.outputs test-id3 {"modelName":"tfsimple1_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} + seldon.default.pipeline.tfsimple.outputs test-id3 {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + + + +```python +!seldon pipeline inspect tfsimple-extended +``` + + seldon.default.model.tfsimple2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs test-id1 {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple-extended.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended.outputs test-id3 {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + + + +```python +!seldon pipeline inspect tfsimple-extended2 +``` + + seldon.default.model.tfsimple2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs test-id1 {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple-extended2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended2.outputs test-id3 {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + + + +```python +!seldon pipeline inspect tfsimple-combined-trigger +``` + + seldon.default.model.tfsimple2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs cebki39q03gs739pd0ag {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.pipeline.tfsimple-combined-trigger.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.pipeline.tfsimple-combined-trigger.outputs cebjfl1q03gs739pd09g {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + + + +```python +!seldon pipeline unload tfsimple-extended +!seldon pipeline unload tfsimple-extended2 +!seldon pipeline unload tfsimple-combined-trigger +!seldon pipeline unload tfsimple +``` + + {} + {} + {} + {} + + + +```python +!seldon model unload tfsimple1 +!seldon model unload tfsimple2 +``` + + {} + {} + + + +```python + +``` diff --git a/samples/pipelines/tfsimple-combined-trigger.yaml b/samples/pipelines/tfsimple-combined-trigger.yaml new file mode 100644 index 0000000000..da07ff1940 --- /dev/null +++ b/samples/pipelines/tfsimple-combined-trigger.yaml @@ -0,0 +1,18 @@ +apiVersion: mlops.seldon.io/v1alpha1 +kind: Pipeline +metadata: + name: tfsimple-combined-trigger +spec: + input: + externalInputs: + - tfsimple-extended.outputs + externalTriggers: + - tfsimple-extended2.outputs + tensorMap: + tfsimple-extended.outputs.OUTPUT0: INPUT0 + tfsimple-extended.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 From b5aeddccb93baa366c76bad29c38e926d4bad383 Mon Sep 17 00:00:00 2001 From: Clive Cox Date: Mon, 12 Dec 2022 19:14:54 +0000 Subject: [PATCH 04/18] fix kafka header test - headers now lowercase --- scheduler/pkg/kafka/pipeline/utils_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scheduler/pkg/kafka/pipeline/utils_test.go b/scheduler/pkg/kafka/pipeline/utils_test.go index 89cdd45871..29602f47b2 100644 --- a/scheduler/pkg/kafka/pipeline/utils_test.go +++ b/scheduler/pkg/kafka/pipeline/utils_test.go @@ -96,8 +96,8 @@ func TestConvertHttpHeadersToKafkaHeaders(t *testing.T) { "X-foo2": []string{"bar2"}, }, expectedKafkaHeaders: map[string]kafka.Header{ - "X-foo": {Key: "x-foo", Value: []byte("bar")}, - "X-foo2": {Key: "x-foo2", Value: []byte("bar2")}, + "x-foo": {Key: "x-foo", Value: []byte("bar")}, + "x-foo2": {Key: "x-foo2", Value: []byte("bar2")}, }, }, } From f13e89a4d3bc2a584ff0819081d9db6fd2517ca9 Mon Sep 17 00:00:00 2001 From: Clive Cox Date: Wed, 14 Dec 2022 14:03:49 +0000 Subject: [PATCH 05/18] Fix cli x-seldon-route and also step tensor map and add step pipeline example --- operator/pkg/cli/kafka.go | 10 +- samples/img_pipeline4.jpg | Bin 0 -> 72798 bytes samples/pipeline-to-pipeline.ipynb | 805 ++++++++++++++---- samples/pipelines/tfsimple-extended-step.yaml | 16 + scheduler/pkg/kafka/gateway/consumer.go | 1 + scheduler/pkg/kafka/gateway/worker.go | 5 + scheduler/pkg/kafka/topics.go | 4 +- 7 files changed, 690 insertions(+), 151 deletions(-) create mode 100644 samples/img_pipeline4.jpg create mode 100644 samples/pipelines/tfsimple-extended-step.yaml diff --git a/operator/pkg/cli/kafka.go b/operator/pkg/cli/kafka.go index 8b89899b33..0e51d63d86 100644 --- a/operator/pkg/cli/kafka.go +++ b/operator/pkg/cli/kafka.go @@ -62,9 +62,9 @@ type KafkaInspectTopic struct { } type KafkaInspectTopicMessage struct { - Headers map[string]string `json:"headers"` - Key string `json:"key"` - Value json.RawMessage `json:"value"` + Headers map[string][]string `json:"headers"` + Key string `json:"key"` + Value json.RawMessage `json:"value"` } func NewKafkaClient(kafkaBroker string, kafkaBrokerIsSet bool, schedulerHost string, schedulerHostIsSet bool) (*KafkaClient, error) { @@ -323,9 +323,9 @@ func (kc *KafkaClient) createInspectTopic(topic string, tensor string, offset in } func addInspectHeaders(e *kafka.Message, kitm *KafkaInspectTopicMessage) { - kitm.Headers = make(map[string]string) + kitm.Headers = make(map[string][]string) for _, header := range e.Headers { - kitm.Headers[header.Key] = string(header.Value) + kitm.Headers[header.Key] = append(kitm.Headers[header.Key], string(header.Value)) } } diff --git a/samples/img_pipeline4.jpg b/samples/img_pipeline4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e61c78a4d9813eb017061a651640211ec224bc8d GIT binary patch literal 72798 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 Aq5uE@ literal 0 HcmV?d00001 diff --git a/samples/pipeline-to-pipeline.ipynb b/samples/pipeline-to-pipeline.ipynb index 22c444c0fd..e6a4d345b5 100644 --- a/samples/pipeline-to-pipeline.ipynb +++ b/samples/pipeline-to-pipeline.ipynb @@ -27,7 +27,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 241, "id": "0f2ab2a3", "metadata": {}, "outputs": [ @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 242, "id": "f9e073d7", "metadata": {}, "outputs": [ @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 243, "id": "997b4028", "metadata": {}, "outputs": [ @@ -103,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 244, "id": "3d017ede", "metadata": {}, "outputs": [ @@ -130,7 +130,7 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 245, "id": "following-winning", "metadata": {}, "outputs": [ @@ -148,7 +148,7 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": 246, "id": "artistic-kentucky", "metadata": {}, "outputs": [ @@ -162,7 +162,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cebnb8ev219s73a6ojk0\",\r\n", + " \"uid\": \"cecrig30nmls73b73kg0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -180,7 +180,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-12T18:40:33.304154775Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-14T11:53:36.535618227Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -195,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 247, "id": "87f10a5c", "metadata": {}, "outputs": [ @@ -270,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": 248, "id": "00575d89", "metadata": {}, "outputs": [ @@ -303,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 249, "id": "8fcd8947", "metadata": {}, "outputs": [ @@ -321,7 +321,7 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 250, "id": "5a69008c", "metadata": {}, "outputs": [ @@ -335,7 +335,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple-extended\",\r\n", - " \"uid\": \"cebnb9mv219s73a6ojkg\",\r\n", + " \"uid\": \"cecrihb0nmls73b73kgg\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -362,7 +362,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-12T18:40:39.004261615Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-14T11:53:41.567680282Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -377,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 127, + "execution_count": 251, "id": "e7e19259", "metadata": {}, "outputs": [ @@ -452,28 +452,28 @@ }, { "cell_type": "code", - "execution_count": 128, - "id": "e86c40b8", + "execution_count": 253, + "id": "7281ab34", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", - "seldon.default.model.tfsimple1.outputs\tcebnba9q03gs739pd0eg\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", - "seldon.default.pipeline.tfsimple.outputs\tcebnba9q03gs739pd0eg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" + "seldon.default.model.tfsimple1.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tpipeline=[tfsimple]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-9006f5af1aa03ad2-01]\r\n", + "seldon.default.model.tfsimple1.outputs\tcecrii7igtes73c78c3g\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tpipeline=[tfsimple]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-bc489a21816b4de6-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\r\n", + "seldon.default.pipeline.tfsimple.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-09ec163358b20783-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tpipeline=[tfsimple]\r\n", + "seldon.default.pipeline.tfsimple.outputs\tcecrii7igtes73c78c3g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-31fc61535669cf1f-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple" + "!seldon pipeline inspect tfsimple --verbose" ] }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 254, "id": "46db0594", "metadata": {}, "outputs": [ @@ -481,20 +481,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\tcebnba9q03gs739pd0eg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\tcebnba9q03gs739pd0eg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\tcebnba9q03gs739pd0eg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-e65a4b9b597a33ba-01]\r\n", + "seldon.default.model.tfsimple2.outputs\tcecrii7igtes73c78c3g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-2f1c33dae54c2d65-01]\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-4f4bd84b19a75095-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tcecrii7igtes73c78c3g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\tx-envoy-upstream-service-time=[0 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-29936337574a42e6-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-extended" + "!seldon pipeline inspect tfsimple-extended --verbose" ] }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 255, "id": "dimensional-hours", "metadata": {}, "outputs": [ @@ -514,7 +514,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 256, "id": "outside-inspiration", "metadata": {}, "outputs": [ @@ -534,7 +534,7 @@ }, { "cell_type": "markdown", - "id": "097a1101", + "id": "0ab97940", "metadata": {}, "source": [ "### Pipeline pulling from two other Pipelines\n", @@ -544,8 +544,8 @@ }, { "cell_type": "code", - "execution_count": 97, - "id": "6b282f45", + "execution_count": 257, + "id": "dbbd6dc9", "metadata": {}, "outputs": [ { @@ -580,8 +580,8 @@ }, { "cell_type": "code", - "execution_count": 98, - "id": "078e7ba6", + "execution_count": 258, + "id": "fe6ce429", "metadata": {}, "outputs": [ { @@ -600,8 +600,8 @@ }, { "cell_type": "code", - "execution_count": 99, - "id": "6e97299b", + "execution_count": 259, + "id": "068cb022", "metadata": {}, "outputs": [ { @@ -620,8 +620,8 @@ }, { "cell_type": "code", - "execution_count": 100, - "id": "528d36ca", + "execution_count": 260, + "id": "0677f86c", "metadata": {}, "outputs": [ { @@ -647,8 +647,8 @@ }, { "cell_type": "code", - "execution_count": 101, - "id": "ce4efa1c", + "execution_count": 261, + "id": "be0c8462", "metadata": {}, "outputs": [ { @@ -665,8 +665,8 @@ }, { "cell_type": "code", - "execution_count": 102, - "id": "aa46faea", + "execution_count": 262, + "id": "b89d8e0f", "metadata": {}, "outputs": [ { @@ -679,7 +679,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cebnacuv219s73a6oji0\",\r\n", + " \"uid\": \"cecrivr0nmls73b73kh0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -697,7 +697,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-12T18:38:43.317204867Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-14T11:54:39.247614694Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -712,8 +712,8 @@ }, { "cell_type": "code", - "execution_count": 103, - "id": "bd33da59", + "execution_count": 263, + "id": "b1f333d6", "metadata": {}, "outputs": [ { @@ -787,8 +787,8 @@ }, { "cell_type": "code", - "execution_count": 104, - "id": "3d7f0b28", + "execution_count": 264, + "id": "b52f2c54", "metadata": {}, "outputs": [ { @@ -859,8 +859,8 @@ }, { "cell_type": "code", - "execution_count": 105, - "id": "4c44cfaf", + "execution_count": 265, + "id": "9192d9ef", "metadata": {}, "outputs": [ { @@ -881,17 +881,17 @@ }, { "cell_type": "code", - "execution_count": 106, - "id": "c762ac75", + "execution_count": 266, + "id": "71f4a5aa", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{\"pipelineName\":\"tfsimple-extended\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\",\"uid\":\"cebnaemv219s73a6ojig\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:38:50.324389094Z\",\"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-extended2\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\",\"uid\":\"cebnaemv219s73a6ojj0\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:38:50.467839593Z\",\"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-combined\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined\",\"uid\":\"cebnaemv219s73a6ojjg\",\"version\":2,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple-extended.outputs.OUTPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\"],\"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple-extended2.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":2,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:38:50.718933075Z\",\"modelsReady\":true}}]}\n" + "{\"pipelineName\":\"tfsimple-extended\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\", \"uid\":\"cecrj1r0nmls73b73khg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T11:54:47.250505Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\", \"uid\":\"cecrj1r0nmls73b73ki0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T11:54:47.462376526Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined\", \"uid\":\"cecrj1r0nmls73b73kig\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple-extended.outputs.OUTPUT0\", \"tfsimple-extended2.outputs.OUTPUT1\"], \"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple-extended2.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T11:54:47.986862969Z\", \"modelsReady\":true}}]}\n" ] } ], @@ -903,8 +903,8 @@ }, { "cell_type": "code", - "execution_count": 107, - "id": "764ce126", + "execution_count": 267, + "id": "b703e8d7", "metadata": {}, "outputs": [ { @@ -978,18 +978,18 @@ }, { "cell_type": "code", - "execution_count": 112, - "id": "6f9b6b66", + "execution_count": 268, + "id": "5f0acd99", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", - "seldon.default.model.tfsimple1.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", - "seldon.default.pipeline.tfsimple.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" + "seldon.default.model.tfsimple1.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" ] } ], @@ -999,18 +999,18 @@ }, { "cell_type": "code", - "execution_count": 113, - "id": "b8f2ecb8", + "execution_count": 269, + "id": "a4d9470a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], @@ -1020,18 +1020,18 @@ }, { "cell_type": "code", - "execution_count": 114, - "id": "e36bcbbe", + "execution_count": 270, + "id": "68dbbe10", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-extended2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-extended2.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], @@ -1041,29 +1041,29 @@ }, { "cell_type": "code", - "execution_count": 115, - "id": "a69e1bdf", + "execution_count": 271, + "id": "c9f16d37", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\tcebnaf9q03gs739pd0dg\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-combined.inputs\tcebnaf9q03gs739pd0dg\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-combined.outputs\tcebnaf9q03gs739pd0dg\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-536d569bd501e083-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\r\n", + "seldon.default.model.tfsimple2.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-e4e3f79ae060dc87-01]\r\n", + "seldon.default.pipeline.tfsimple-combined.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-cca85cfe4ac46fdb-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n", + "seldon.default.pipeline.tfsimple-combined.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-5747b29ab0b3e8cc-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-combined" + "!seldon pipeline inspect tfsimple-combined --verbose" ] }, { "cell_type": "code", - "execution_count": 116, - "id": "ffd757b8", + "execution_count": 272, + "id": "f9f1ed62", "metadata": {}, "outputs": [ { @@ -1086,8 +1086,8 @@ }, { "cell_type": "code", - "execution_count": 117, - "id": "d9163fc4", + "execution_count": 273, + "id": "927a91ee", "metadata": {}, "outputs": [ { @@ -1106,7 +1106,7 @@ }, { "cell_type": "markdown", - "id": "4d09887b", + "id": "8d2972f8", "metadata": {}, "source": [ "### Pipeline pullin from one pipeline with a trigger to another\n", @@ -1116,8 +1116,8 @@ }, { "cell_type": "code", - "execution_count": 132, - "id": "5484193c", + "execution_count": 274, + "id": "836c030f", "metadata": {}, "outputs": [ { @@ -1152,8 +1152,8 @@ }, { "cell_type": "code", - "execution_count": 133, - "id": "2e2d1413", + "execution_count": 275, + "id": "e3a043a1", "metadata": {}, "outputs": [ { @@ -1172,8 +1172,8 @@ }, { "cell_type": "code", - "execution_count": 134, - "id": "90ab831e", + "execution_count": 276, + "id": "e9a1b794", "metadata": {}, "outputs": [ { @@ -1192,8 +1192,8 @@ }, { "cell_type": "code", - "execution_count": 135, - "id": "26b37b90", + "execution_count": 277, + "id": "6e3c6269", "metadata": {}, "outputs": [ { @@ -1219,8 +1219,8 @@ }, { "cell_type": "code", - "execution_count": 136, - "id": "2c2c6480", + "execution_count": 278, + "id": "4b9f7749", "metadata": {}, "outputs": [ { @@ -1237,8 +1237,8 @@ }, { "cell_type": "code", - "execution_count": 137, - "id": "b1417cba", + "execution_count": 279, + "id": "da51754d", "metadata": {}, "outputs": [ { @@ -1251,7 +1251,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cebnbguv219s73a6ojl0\",\r\n", + " \"uid\": \"cecscuj0nmls73b73kj0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -1269,7 +1269,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-12T18:41:07.131448326Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-14T12:50:02.622878714Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -1284,8 +1284,8 @@ }, { "cell_type": "code", - "execution_count": 138, - "id": "a3071607", + "execution_count": 280, + "id": "f215ec1c", "metadata": {}, "outputs": [ { @@ -1359,8 +1359,8 @@ }, { "cell_type": "code", - "execution_count": 139, - "id": "9c501d85", + "execution_count": 281, + "id": "016a11e1", "metadata": {}, "outputs": [ { @@ -1432,8 +1432,8 @@ }, { "cell_type": "code", - "execution_count": 140, - "id": "f67b698b", + "execution_count": 282, + "id": "1596b619", "metadata": {}, "outputs": [ { @@ -1454,17 +1454,17 @@ }, { "cell_type": "code", - "execution_count": 141, - "id": "9d8d54d1", + "execution_count": 283, + "id": "9ea7600e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{\"pipelineName\":\"tfsimple-extended\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\",\"uid\":\"cebnbimv219s73a6ojlg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:41:14.561905446Z\",\"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-extended2\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\",\"uid\":\"cebnbimv219s73a6ojm0\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple.outputs\"],\"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:41:14.693285174Z\",\"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-combined-trigger\",\"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined-trigger\",\"uid\":\"cebnbimv219s73a6ojmg\",\"version\":1,\"steps\":[{\"name\":\"tfsimple2\"}],\"output\":{\"steps\":[\"tfsimple2.outputs\"]},\"kubernetesMeta\":{},\"input\":{\"externalInputs\":[\"tfsimple-extended.outputs\"],\"externalTriggers\":[\"tfsimple-extended2.outputs\"],\"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\",\"tfsimple-extended.outputs.OUTPUT1\":\"INPUT1\"}}},\"state\":{\"pipelineVersion\":1,\"status\":\"PipelineReady\",\"reason\":\"created pipeline\",\"lastChangeTimestamp\":\"2022-12-12T18:41:14.945627389Z\",\"modelsReady\":true}}]}\n" + "{\"pipelineName\":\"tfsimple-extended\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\", \"uid\":\"cecsd030nmls73b73kjg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T12:50:08.337976173Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\", \"uid\":\"cecsd030nmls73b73kk0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T12:50:08.496882324Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined-trigger\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined-trigger\", \"uid\":\"cecsd030nmls73b73kkg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple-extended.outputs\"], \"externalTriggers\":[\"tfsimple-extended2.outputs\"], \"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple-extended.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T12:50:08.849182876Z\", \"modelsReady\":true}}]}\n" ] } ], @@ -1476,8 +1476,8 @@ }, { "cell_type": "code", - "execution_count": 142, - "id": "22e95a26", + "execution_count": 284, + "id": "772b0b7b", "metadata": {}, "outputs": [ { @@ -1551,18 +1551,18 @@ }, { "cell_type": "code", - "execution_count": 143, - "id": "b69e9c58", + "execution_count": 285, + "id": "c2fa96f9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", - "seldon.default.model.tfsimple1.outputs\ttest-id3\t{\"modelName\":\"tfsimple1_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]}\r\n", - "seldon.default.pipeline.tfsimple.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" + "seldon.default.model.tfsimple1.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\ttest-id3\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" ] } ], @@ -1572,18 +1572,18 @@ }, { "cell_type": "code", - "execution_count": 144, - "id": "4926208f", + "execution_count": 286, + "id": "c8cd42c9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id1\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id3\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], @@ -1593,18 +1593,18 @@ }, { "cell_type": "code", - "execution_count": 145, - "id": "e7be9a2b", + "execution_count": 287, + "id": "a5b99855", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id1\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-extended2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-extended2.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id3\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], @@ -1614,18 +1614,18 @@ }, { "cell_type": "code", - "execution_count": 146, - "id": "07a3643c", + "execution_count": 288, + "id": "e6914df0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\tcebki39q03gs739pd0ag\t{\"modelName\":\"tfsimple2_1\",\"modelVersion\":\"1\",\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-combined-trigger.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{\"name\":\"INPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],\"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\",\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-combined-trigger.outputs\tcebjfl1q03gs739pd09g\t{\"outputs\":[{\"name\":\"OUTPUT0\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{\"name\":\"OUTPUT1\",\"datatype\":\"INT32\",\"shape\":[\"1\",\"16\"],\"contents\":{\"intContents\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\ttest-id3\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-combined-trigger.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-combined-trigger.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" ] } ], @@ -1635,8 +1635,8 @@ }, { "cell_type": "code", - "execution_count": 147, - "id": "59fd2fbe", + "execution_count": 289, + "id": "d2aa8c52", "metadata": {}, "outputs": [ { @@ -1659,8 +1659,525 @@ }, { "cell_type": "code", - "execution_count": 148, - "id": "0ff176d4", + "execution_count": 290, + "id": "5d7d7548", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model unload tfsimple1\n", + "!seldon model unload tfsimple2" + ] + }, + { + "cell_type": "markdown", + "id": "b0b949ce", + "metadata": {}, + "source": [ + "### Pipeline pulling from one other Pipeline Step\n", + "\n", + "![pipeline-to-pipeline](img_pipeline4.jpg)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 304, + "id": "c7be74aa", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple1\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple2\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n" + ] + } + ], + "source": [ + "!cat ./models/tfsimple1.yaml\n", + "!cat ./models/tfsimple2.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 366, + "id": "ad0bcfd0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model load -f ./models/tfsimple1.yaml \n", + "!seldon model load -f ./models/tfsimple2.yaml " + ] + }, + { + "cell_type": "code", + "execution_count": 367, + "id": "67cfca28", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model status tfsimple1 -w ModelAvailable | jq -M .\n", + "!seldon model status tfsimple2 -w ModelAvailable | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 368, + "id": "0df0e2c6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple\r\n", + "spec:\r\n", + " steps:\r\n", + " - name: tfsimple1\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple1\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 369, + "id": "a020b898", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 370, + "id": "8eeed673", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple\",\r\n", + " \"uid\": \"cect0mehucqid0qof9p0\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple1\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple1.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {}\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-14T13:32:09.753016444Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 371, + "id": "3e59736d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"model_name\": \"\",\r\n", + " \"outputs\": [\r\n", + " {\r\n", + " \"data\": [\r\n", + " 2,\r\n", + " 4,\r\n", + " 6,\r\n", + " 8,\r\n", + " 10,\r\n", + " 12,\r\n", + " 14,\r\n", + " 16,\r\n", + " 18,\r\n", + " 20,\r\n", + " 22,\r\n", + " 24,\r\n", + " 26,\r\n", + " 28,\r\n", + " 30,\r\n", + " 32\r\n", + " ],\r\n", + " \"name\": \"OUTPUT0\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " },\r\n", + " {\r\n", + " \"data\": [\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0\r\n", + " ],\r\n", + " \"name\": \"OUTPUT1\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 372, + "id": "8a3de0b5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple-extended-step\r\n", + "spec:\r\n", + " input:\r\n", + " externalInputs:\r\n", + " - tfsimple.step.tfsimple1.outputs\r\n", + " tensorMap:\r\n", + " tfsimple.step.tfsimple1.outputs.OUTPUT0: INPUT0\r\n", + " tfsimple.step.tfsimple1.outputs.OUTPUT1: INPUT1\r\n", + " steps:\r\n", + " - name: tfsimple2\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple2\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple-extended-step.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 373, + "id": "9c8d2aca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple-extended-step.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 374, + "id": "6797960b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple-extended-step\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple-extended-step\",\r\n", + " \"uid\": \"cect0nmhucqid0qof9pg\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple2\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple2.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {},\r\n", + " \"input\": {\r\n", + " \"externalInputs\": [\r\n", + " \"tfsimple.step.tfsimple1.outputs\"\r\n", + " ],\r\n", + " \"tensorMap\": {\r\n", + " \"tfsimple.step.tfsimple1.outputs.OUTPUT0\": \"INPUT0\",\r\n", + " \"tfsimple.step.tfsimple1.outputs.OUTPUT1\": \"INPUT1\"\r\n", + " }\r\n", + " }\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-14T13:32:28.404734823Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple-extended-step -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 375, + "id": "9c9ef7bb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + "\t\"model_name\": \"\",\r\n", + "\t\"outputs\": [\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t2,\r\n", + "\t\t\t\t4,\r\n", + "\t\t\t\t6,\r\n", + "\t\t\t\t8,\r\n", + "\t\t\t\t10,\r\n", + "\t\t\t\t12,\r\n", + "\t\t\t\t14,\r\n", + "\t\t\t\t16,\r\n", + "\t\t\t\t18,\r\n", + "\t\t\t\t20,\r\n", + "\t\t\t\t22,\r\n", + "\t\t\t\t24,\r\n", + "\t\t\t\t26,\r\n", + "\t\t\t\t28,\r\n", + "\t\t\t\t30,\r\n", + "\t\t\t\t32\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT0\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t},\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT1\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t}\r\n", + "\t]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' " + ] + }, + { + "cell_type": "code", + "execution_count": 376, + "id": "420b1575", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple1.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-fede9d52a3717854-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tpipeline=[tfsimple]\r\n", + "seldon.default.model.tfsimple1.outputs\tcect0skvem6s73b81mig\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tpipeline=[tfsimple]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-a11f988f4ce9ed8e-01]\r\n", + "seldon.default.pipeline.tfsimple.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-91470ae8461f6e35-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tpipeline=[tfsimple]\r\n", + "seldon.default.pipeline.tfsimple.outputs\tcect0skvem6s73b81mig\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tpipeline=[tfsimple]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-dde201c08a1d60ae-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 377, + "id": "d401bc2d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\tpipeline=[tfsimple-extended-step]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-ae48015963a5ef57-01]\r\n", + "seldon.default.model.tfsimple2.outputs\tcect0skvem6s73b81mig\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\tpipeline=[tfsimple-extended-step]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-f3ad52da9360754e-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\r\n", + "seldon.default.pipeline.tfsimple-extended-step.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\tpipeline=[tfsimple-extended-step]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-3b2b42a783e0b6de-01]\tx-forwarded-proto=[http]\r\n", + "seldon.default.pipeline.tfsimple-extended-step.outputs\tcect0skvem6s73b81mig\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-9de647c35f7ac59a-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\tpipeline=[tfsimple-extended-step]\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended-step --verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 319, + "id": "3b688398", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "Error: rpc error: code = FailedPrecondition desc = pipeline tfsimple not found\n" + ] + } + ], + "source": [ + "!seldon pipeline unload tfsimple-extended-step\n", + "!seldon pipeline unload tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 320, + "id": "7ba195af", "metadata": {}, "outputs": [ { @@ -1680,7 +2197,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1af9d600", + "id": "4bfede4a", "metadata": {}, "outputs": [], "source": [] diff --git a/samples/pipelines/tfsimple-extended-step.yaml b/samples/pipelines/tfsimple-extended-step.yaml new file mode 100644 index 0000000000..5552f34745 --- /dev/null +++ b/samples/pipelines/tfsimple-extended-step.yaml @@ -0,0 +1,16 @@ +apiVersion: mlops.seldon.io/v1alpha1 +kind: Pipeline +metadata: + name: tfsimple-extended-step +spec: + input: + externalInputs: + - tfsimple.step.tfsimple1.outputs + tensorMap: + tfsimple.step.tfsimple1.outputs.OUTPUT0: INPUT0 + tfsimple.step.tfsimple1.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 diff --git a/scheduler/pkg/kafka/gateway/consumer.go b/scheduler/pkg/kafka/gateway/consumer.go index b9ff28d61d..ff298ecad7 100644 --- a/scheduler/pkg/kafka/gateway/consumer.go +++ b/scheduler/pkg/kafka/gateway/consumer.go @@ -308,6 +308,7 @@ func (kc *InferKafkaConsumer) Serve() { span.SetAttributes(attribute.String(util.RequestIdHeader, string(e.Key))) headers := collectHeaders(e.Headers) + logger.Debugf("Headers received from kafka for model %s %v", modelName, e.Headers) job := InferWork{ modelName: modelName, diff --git a/scheduler/pkg/kafka/gateway/worker.go b/scheduler/pkg/kafka/gateway/worker.go index 5852496dd6..27289ff141 100644 --- a/scheduler/pkg/kafka/gateway/worker.go +++ b/scheduler/pkg/kafka/gateway/worker.go @@ -229,6 +229,11 @@ func (iw *InferWorker) produce(ctx context.Context, job *InferWork, topic string } } } + if logger.Logger.IsLevelEnabled(log.DebugLevel) { + for _, h := range kafkaHeaders { + logger.Debugf("Adding kafka header for topic %s %s:%s", topic, h.Key, string(h.Value)) + } + } logger.Infof("Produce response to topic %s", topic) msg := &kafka.Message{ diff --git a/scheduler/pkg/kafka/topics.go b/scheduler/pkg/kafka/topics.go index b91bfa23d7..5e4b1379f2 100644 --- a/scheduler/pkg/kafka/topics.go +++ b/scheduler/pkg/kafka/topics.go @@ -115,8 +115,8 @@ func (tn *TopicNamer) GetFullyQualifiedPipelineTensorMap(tin map[string]string) switch len(parts) { case 3: kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, pipelineTopic, k) - case 5: - kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, k) + case 5: // take value after .step + kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, strings.Join(parts[2:], pipeline.StepNameSeperator)) } tout[kout] = v } From 969e0b2fd7571020b85c407cb4816bb54bd51338 Mon Sep 17 00:00:00 2001 From: Clive Cox Date: Sat, 17 Dec 2022 17:26:56 +0000 Subject: [PATCH 06/18] Update notebook --- samples/pipeline-to-pipeline.ipynb | 932 +++++++++++++++++++++++------ samples/pipeline-to-pipeline.md | 867 +++++++++++++++++++++++++-- 2 files changed, 1565 insertions(+), 234 deletions(-) diff --git a/samples/pipeline-to-pipeline.ipynb b/samples/pipeline-to-pipeline.ipynb index e6a4d345b5..b2de7179e7 100644 --- a/samples/pipeline-to-pipeline.ipynb +++ b/samples/pipeline-to-pipeline.ipynb @@ -27,7 +27,7 @@ }, { "cell_type": "code", - "execution_count": 241, + "execution_count": 83, "id": "0f2ab2a3", "metadata": {}, "outputs": [ @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 242, + "execution_count": 84, "id": "f9e073d7", "metadata": {}, "outputs": [ @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 243, + "execution_count": 85, "id": "997b4028", "metadata": {}, "outputs": [ @@ -103,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 244, + "execution_count": 86, "id": "3d017ede", "metadata": {}, "outputs": [ @@ -130,7 +130,7 @@ }, { "cell_type": "code", - "execution_count": 245, + "execution_count": 87, "id": "following-winning", "metadata": {}, "outputs": [ @@ -148,7 +148,7 @@ }, { "cell_type": "code", - "execution_count": 246, + "execution_count": 88, "id": "artistic-kentucky", "metadata": {}, "outputs": [ @@ -162,7 +162,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cecrig30nmls73b73kg0\",\r\n", + " \"uid\": \"ceevilesc0ns73er67kg\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -180,7 +180,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-14T11:53:36.535618227Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-17T17:16:05.915396256Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -195,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 247, + "execution_count": 89, "id": "87f10a5c", "metadata": {}, "outputs": [ @@ -270,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 248, + "execution_count": 90, "id": "00575d89", "metadata": {}, "outputs": [ @@ -303,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 249, + "execution_count": 91, "id": "8fcd8947", "metadata": {}, "outputs": [ @@ -321,7 +321,7 @@ }, { "cell_type": "code", - "execution_count": 250, + "execution_count": 92, "id": "5a69008c", "metadata": {}, "outputs": [ @@ -335,7 +335,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple-extended\",\r\n", - " \"uid\": \"cecrihb0nmls73b73kgg\",\r\n", + " \"uid\": \"ceevin6sc0ns73er67l0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -362,7 +362,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-14T11:53:41.567680282Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-17T17:16:12.837674035Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -377,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 251, + "execution_count": 93, "id": "e7e19259", "metadata": {}, "outputs": [ @@ -452,28 +452,28 @@ }, { "cell_type": "code", - "execution_count": 253, - "id": "7281ab34", + "execution_count": 96, + "id": "7e943b73", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tpipeline=[tfsimple]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-9006f5af1aa03ad2-01]\r\n", - "seldon.default.model.tfsimple1.outputs\tcecrii7igtes73c78c3g\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tpipeline=[tfsimple]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-bc489a21816b4de6-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\r\n", - "seldon.default.pipeline.tfsimple.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-09ec163358b20783-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tpipeline=[tfsimple]\r\n", - "seldon.default.pipeline.tfsimple.outputs\tcecrii7igtes73c78c3g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-31fc61535669cf1f-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n" + "seldon.default.model.tfsimple1.inputs\tceevins7aa7c73d9cfo0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\tceevins7aa7c73d9cfo0\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\tceevins7aa7c73d9cfo0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\tceevins7aa7c73d9cfo0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple --verbose" + "!seldon pipeline inspect tfsimple" ] }, { "cell_type": "code", - "execution_count": 254, + "execution_count": 97, "id": "46db0594", "metadata": {}, "outputs": [ @@ -481,20 +481,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-e65a4b9b597a33ba-01]\r\n", - "seldon.default.model.tfsimple2.outputs\tcecrii7igtes73c78c3g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-2f1c33dae54c2d65-01]\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\tcecrii7igtes73c78c3g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-4f4bd84b19a75095-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\tcecrii7igtes73c78c3g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\tx-envoy-upstream-service-time=[0 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrii0iavkc73dmvg7g]\tpipeline=[tfsimple-extended]\ttraceparent=[00-d8cc8473a6554e149c4a738654e92e25-29936337574a42e6-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\r\n" + "seldon.default.model.tfsimple2.inputs\tceevins7aa7c73d9cfo0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceevins7aa7c73d9cfo0\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tceevins7aa7c73d9cfo0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tceevins7aa7c73d9cfo0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-extended --verbose" + "!seldon pipeline inspect tfsimple-extended" ] }, { "cell_type": "code", - "execution_count": 255, + "execution_count": 98, "id": "dimensional-hours", "metadata": {}, "outputs": [ @@ -514,7 +514,7 @@ }, { "cell_type": "code", - "execution_count": 256, + "execution_count": 99, "id": "outside-inspiration", "metadata": {}, "outputs": [ @@ -534,7 +534,7 @@ }, { "cell_type": "markdown", - "id": "0ab97940", + "id": "ca596799", "metadata": {}, "source": [ "### Pipeline pulling from two other Pipelines\n", @@ -544,8 +544,8 @@ }, { "cell_type": "code", - "execution_count": 257, - "id": "dbbd6dc9", + "execution_count": 100, + "id": "2080d433", "metadata": {}, "outputs": [ { @@ -580,8 +580,8 @@ }, { "cell_type": "code", - "execution_count": 258, - "id": "fe6ce429", + "execution_count": 101, + "id": "bd345e86", "metadata": {}, "outputs": [ { @@ -600,8 +600,8 @@ }, { "cell_type": "code", - "execution_count": 259, - "id": "068cb022", + "execution_count": 102, + "id": "5cf517d3", "metadata": {}, "outputs": [ { @@ -620,8 +620,8 @@ }, { "cell_type": "code", - "execution_count": 260, - "id": "0677f86c", + "execution_count": 103, + "id": "61230cb9", "metadata": {}, "outputs": [ { @@ -647,8 +647,8 @@ }, { "cell_type": "code", - "execution_count": 261, - "id": "be0c8462", + "execution_count": 104, + "id": "3ddcd6c1", "metadata": {}, "outputs": [ { @@ -665,8 +665,8 @@ }, { "cell_type": "code", - "execution_count": 262, - "id": "b89d8e0f", + "execution_count": 105, + "id": "761c6bbd", "metadata": {}, "outputs": [ { @@ -679,7 +679,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cecrivr0nmls73b73kh0\",\r\n", + " \"uid\": \"ceevj2msc0ns73er67lg\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -697,7 +697,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-14T11:54:39.247614694Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-17T17:16:59.017037835Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -712,8 +712,8 @@ }, { "cell_type": "code", - "execution_count": 263, - "id": "b1f333d6", + "execution_count": 106, + "id": "7ac2e813", "metadata": {}, "outputs": [ { @@ -787,8 +787,8 @@ }, { "cell_type": "code", - "execution_count": 264, - "id": "b52f2c54", + "execution_count": 107, + "id": "ae92d1db", "metadata": {}, "outputs": [ { @@ -859,8 +859,8 @@ }, { "cell_type": "code", - "execution_count": 265, - "id": "9192d9ef", + "execution_count": 108, + "id": "0aca3e43", "metadata": {}, "outputs": [ { @@ -881,17 +881,17 @@ }, { "cell_type": "code", - "execution_count": 266, - "id": "71f4a5aa", + "execution_count": 109, + "id": "5a3cfc5d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{\"pipelineName\":\"tfsimple-extended\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\", \"uid\":\"cecrj1r0nmls73b73khg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T11:54:47.250505Z\", \"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-extended2\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\", \"uid\":\"cecrj1r0nmls73b73ki0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T11:54:47.462376526Z\", \"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-combined\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined\", \"uid\":\"cecrj1r0nmls73b73kig\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple-extended.outputs.OUTPUT0\", \"tfsimple-extended2.outputs.OUTPUT1\"], \"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple-extended2.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T11:54:47.986862969Z\", \"modelsReady\":true}}]}\n" + "{\"pipelineName\":\"tfsimple-extended\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\", \"uid\":\"ceevj3usc0ns73er67m0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:17:04.079245812Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\", \"uid\":\"ceevj46sc0ns73er67mg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:17:04.226769422Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined\", \"uid\":\"ceevj46sc0ns73er67n0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple-extended.outputs.OUTPUT0\", \"tfsimple-extended2.outputs.OUTPUT1\"], \"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple-extended2.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:17:04.466100483Z\", \"modelsReady\":true}}]}\n" ] } ], @@ -903,8 +903,8 @@ }, { "cell_type": "code", - "execution_count": 267, - "id": "b703e8d7", + "execution_count": 110, + "id": "6d48a725", "metadata": {}, "outputs": [ { @@ -978,18 +978,18 @@ }, { "cell_type": "code", - "execution_count": 268, - "id": "5f0acd99", + "execution_count": 111, + "id": "2232df0c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", - "seldon.default.model.tfsimple1.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", - "seldon.default.pipeline.tfsimple.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", - "seldon.default.pipeline.tfsimple.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" + "seldon.default.model.tfsimple1.inputs\tceevj4k7aa7c73d9cfp0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\tceevj4k7aa7c73d9cfp0\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\tceevj4k7aa7c73d9cfp0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\tceevj4k7aa7c73d9cfp0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" ] } ], @@ -999,18 +999,18 @@ }, { "cell_type": "code", - "execution_count": 269, - "id": "a4d9470a", + "execution_count": 112, + "id": "b583fc48", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-extended.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-extended.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\tceevj347aa7c73d9cfog\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceepua47aa7c73d9cfj0\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tceevj4k7aa7c73d9cfp0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tceevj4k7aa7c73d9cfp0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], @@ -1020,18 +1020,18 @@ }, { "cell_type": "code", - "execution_count": 270, - "id": "68dbbe10", + "execution_count": 113, + "id": "4da09374", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", - "seldon.default.pipeline.tfsimple-extended2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-extended2.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" + "seldon.default.model.tfsimple2.inputs\tceevj4k7aa7c73d9cfp0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceeq4ls7aa7c73d9cfk0\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.inputs\tceevj4k7aa7c73d9cfp0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.outputs\tceevj4k7aa7c73d9cfp0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], @@ -1041,29 +1041,29 @@ }, { "cell_type": "code", - "execution_count": 271, - "id": "c9f16d37", + "execution_count": 114, + "id": "95fe7d91", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-536d569bd501e083-01]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\r\n", - "seldon.default.model.tfsimple2.outputs\tcecrj2figtes73c78c4g\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-e4e3f79ae060dc87-01]\r\n", - "seldon.default.pipeline.tfsimple-combined.inputs\tcecrj2figtes73c78c4g\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-cca85cfe4ac46fdb-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n", - "seldon.default.pipeline.tfsimple-combined.outputs\tcecrj2figtes73c78c4g\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-forwarded-proto=[http]\tx-envoy-upstream-service-time=[1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cecrj28iavkc73dmvg9g]\tpipeline=[tfsimple-combined]\ttraceparent=[00-d1efb7128b0104e45899ce24383f567f-5747b29ab0b3e8cc-01]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n" + "seldon.default.model.tfsimple2.inputs\tceevj4k7aa7c73d9cfp0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceespfk7aa7c73d9cfmg\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-combined.inputs\tceevj4k7aa7c73d9cfp0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-combined.outputs\tceespfk7aa7c73d9cfmg\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-combined --verbose" + "!seldon pipeline inspect tfsimple-combined" ] }, { "cell_type": "code", - "execution_count": 272, - "id": "f9f1ed62", + "execution_count": 115, + "id": "7baed85b", "metadata": {}, "outputs": [ { @@ -1086,8 +1086,8 @@ }, { "cell_type": "code", - "execution_count": 273, - "id": "927a91ee", + "execution_count": 116, + "id": "e4e9c31c", "metadata": {}, "outputs": [ { @@ -1106,7 +1106,7 @@ }, { "cell_type": "markdown", - "id": "8d2972f8", + "id": "6e0ece15", "metadata": {}, "source": [ "### Pipeline pullin from one pipeline with a trigger to another\n", @@ -1116,8 +1116,8 @@ }, { "cell_type": "code", - "execution_count": 274, - "id": "836c030f", + "execution_count": 117, + "id": "2edfe335", "metadata": {}, "outputs": [ { @@ -1152,8 +1152,8 @@ }, { "cell_type": "code", - "execution_count": 275, - "id": "e3a043a1", + "execution_count": 118, + "id": "2cb492ce", "metadata": {}, "outputs": [ { @@ -1172,8 +1172,8 @@ }, { "cell_type": "code", - "execution_count": 276, - "id": "e9a1b794", + "execution_count": 119, + "id": "61177684", "metadata": {}, "outputs": [ { @@ -1192,8 +1192,8 @@ }, { "cell_type": "code", - "execution_count": 277, - "id": "6e3c6269", + "execution_count": 120, + "id": "2f05e948", "metadata": {}, "outputs": [ { @@ -1219,8 +1219,8 @@ }, { "cell_type": "code", - "execution_count": 278, - "id": "4b9f7749", + "execution_count": 121, + "id": "d51beb10", "metadata": {}, "outputs": [ { @@ -1237,8 +1237,8 @@ }, { "cell_type": "code", - "execution_count": 279, - "id": "da51754d", + "execution_count": 122, + "id": "754b5288", "metadata": {}, "outputs": [ { @@ -1251,7 +1251,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cecscuj0nmls73b73kj0\",\r\n", + " \"uid\": \"ceevja6sc0ns73er67ng\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -1269,7 +1269,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-14T12:50:02.622878714Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-17T17:17:29.011892538Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -1284,8 +1284,8 @@ }, { "cell_type": "code", - "execution_count": 280, - "id": "f215ec1c", + "execution_count": 123, + "id": "cf723042", "metadata": {}, "outputs": [ { @@ -1359,8 +1359,8 @@ }, { "cell_type": "code", - "execution_count": 281, - "id": "016a11e1", + "execution_count": 124, + "id": "54d4d628", "metadata": {}, "outputs": [ { @@ -1432,8 +1432,8 @@ }, { "cell_type": "code", - "execution_count": 282, - "id": "1596b619", + "execution_count": 125, + "id": "3d8db4fd", "metadata": {}, "outputs": [ { @@ -1454,17 +1454,17 @@ }, { "cell_type": "code", - "execution_count": 283, - "id": "9ea7600e", + "execution_count": 126, + "id": "1bb001e4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{\"pipelineName\":\"tfsimple-extended\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\", \"uid\":\"cecsd030nmls73b73kjg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T12:50:08.337976173Z\", \"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-extended2\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\", \"uid\":\"cecsd030nmls73b73kk0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T12:50:08.496882324Z\", \"modelsReady\":true}}]}\n", - "{\"pipelineName\":\"tfsimple-combined-trigger\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined-trigger\", \"uid\":\"cecsd030nmls73b73kkg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple-extended.outputs\"], \"externalTriggers\":[\"tfsimple-extended2.outputs\"], \"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple-extended.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-14T12:50:08.849182876Z\", \"modelsReady\":true}}]}\n" + "{\"pipelineName\":\"tfsimple-extended\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\", \"uid\":\"ceevjbmsc0ns73er67o0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:17:34.180121811Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\", \"uid\":\"ceevjbmsc0ns73er67og\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:17:34.307458250Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined-trigger\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined-trigger\", \"uid\":\"ceevjbmsc0ns73er67p0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple-extended.outputs\"], \"externalTriggers\":[\"tfsimple-extended2.outputs\"], \"tensorMap\":{\"tfsimple-extended.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple-extended.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:17:34.550045739Z\", \"modelsReady\":true}}]}\n" ] } ], @@ -1476,8 +1476,8 @@ }, { "cell_type": "code", - "execution_count": 284, - "id": "772b0b7b", + "execution_count": 127, + "id": "dac6c62c", "metadata": {}, "outputs": [ { @@ -1551,8 +1551,8 @@ }, { "cell_type": "code", - "execution_count": 285, - "id": "c2fa96f9", + "execution_count": 128, + "id": "965e5f92", "metadata": {}, "outputs": [ { @@ -1572,16 +1572,16 @@ }, { "cell_type": "code", - "execution_count": 286, - "id": "c8cd42c9", + "execution_count": 129, + "id": "079b4e27", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id3\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.model.tfsimple2.inputs\tceeq4ok7aa7c73d9cfkg\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceepua47aa7c73d9cfj0\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", "seldon.default.pipeline.tfsimple-extended.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", "seldon.default.pipeline.tfsimple-extended.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] @@ -1593,16 +1593,16 @@ }, { "cell_type": "code", - "execution_count": 287, - "id": "a5b99855", + "execution_count": 130, + "id": "233f42f3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id3\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.model.tfsimple2.inputs\tceeq4ok7aa7c73d9cfkg\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceeq4ok7aa7c73d9cfkg\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", "seldon.default.pipeline.tfsimple-extended2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", "seldon.default.pipeline.tfsimple-extended2.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] @@ -1614,18 +1614,18 @@ }, { "cell_type": "code", - "execution_count": 288, - "id": "e6914df0", + "execution_count": 131, + "id": "e674c8d5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.model.tfsimple2.outputs\ttest-id3\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.model.tfsimple2.inputs\tceepua47aa7c73d9cfj0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceeq4ls7aa7c73d9cfk0\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", "seldon.default.pipeline.tfsimple-combined-trigger.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", - "seldon.default.pipeline.tfsimple-combined-trigger.outputs\ttest-id3\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" + "seldon.default.pipeline.tfsimple-combined-trigger.outputs\tceespfk7aa7c73d9cfmg\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" ] } ], @@ -1635,8 +1635,8 @@ }, { "cell_type": "code", - "execution_count": 289, - "id": "d2aa8c52", + "execution_count": 132, + "id": "37e1399e", "metadata": {}, "outputs": [ { @@ -1659,8 +1659,8 @@ }, { "cell_type": "code", - "execution_count": 290, - "id": "5d7d7548", + "execution_count": 133, + "id": "81480753", "metadata": {}, "outputs": [ { @@ -1679,7 +1679,7 @@ }, { "cell_type": "markdown", - "id": "b0b949ce", + "id": "c2614d43", "metadata": {}, "source": [ "### Pipeline pulling from one other Pipeline Step\n", @@ -1689,8 +1689,8 @@ }, { "cell_type": "code", - "execution_count": 304, - "id": "c7be74aa", + "execution_count": 134, + "id": "d006d9b2", "metadata": {}, "outputs": [ { @@ -1725,8 +1725,8 @@ }, { "cell_type": "code", - "execution_count": 366, - "id": "ad0bcfd0", + "execution_count": 135, + "id": "30f4ad48", "metadata": {}, "outputs": [ { @@ -1745,8 +1745,8 @@ }, { "cell_type": "code", - "execution_count": 367, - "id": "67cfca28", + "execution_count": 136, + "id": "ae024817", "metadata": {}, "outputs": [ { @@ -1765,8 +1765,8 @@ }, { "cell_type": "code", - "execution_count": 368, - "id": "0df0e2c6", + "execution_count": 137, + "id": "e180a273", "metadata": {}, "outputs": [ { @@ -1792,8 +1792,8 @@ }, { "cell_type": "code", - "execution_count": 369, - "id": "a020b898", + "execution_count": 138, + "id": "48dde798", "metadata": {}, "outputs": [ { @@ -1810,8 +1810,8 @@ }, { "cell_type": "code", - "execution_count": 370, - "id": "8eeed673", + "execution_count": 142, + "id": "77ee161a", "metadata": {}, "outputs": [ { @@ -1824,7 +1824,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple\",\r\n", - " \"uid\": \"cect0mehucqid0qof9p0\",\r\n", + " \"uid\": \"ceevjh6sc0ns73er67pg\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -1842,7 +1842,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-14T13:32:09.753016444Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-17T17:17:56.809691365Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -1857,8 +1857,8 @@ }, { "cell_type": "code", - "execution_count": 371, - "id": "3e59736d", + "execution_count": 144, + "id": "86280675", "metadata": {}, "outputs": [ { @@ -1932,8 +1932,8 @@ }, { "cell_type": "code", - "execution_count": 372, - "id": "8a3de0b5", + "execution_count": 145, + "id": "b06ff6ab", "metadata": {}, "outputs": [ { @@ -1965,8 +1965,8 @@ }, { "cell_type": "code", - "execution_count": 373, - "id": "9c8d2aca", + "execution_count": 146, + "id": "008a1465", "metadata": {}, "outputs": [ { @@ -1983,8 +1983,8 @@ }, { "cell_type": "code", - "execution_count": 374, - "id": "6797960b", + "execution_count": 147, + "id": "7c5c2065", "metadata": {}, "outputs": [ { @@ -1997,7 +1997,7 @@ " {\r\n", " \"pipeline\": {\r\n", " \"name\": \"tfsimple-extended-step\",\r\n", - " \"uid\": \"cect0nmhucqid0qof9pg\",\r\n", + " \"uid\": \"ceevkf6sc0ns73er67q0\",\r\n", " \"version\": 1,\r\n", " \"steps\": [\r\n", " {\r\n", @@ -2024,7 +2024,7 @@ " \"pipelineVersion\": 1,\r\n", " \"status\": \"PipelineReady\",\r\n", " \"reason\": \"created pipeline\",\r\n", - " \"lastChangeTimestamp\": \"2022-12-14T13:32:28.404734823Z\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-17T17:19:56.669740116Z\",\r\n", " \"modelsReady\": true\r\n", " }\r\n", " }\r\n", @@ -2039,8 +2039,8 @@ }, { "cell_type": "code", - "execution_count": 375, - "id": "9c9ef7bb", + "execution_count": 148, + "id": "0706c855", "metadata": {}, "outputs": [ { @@ -2114,18 +2114,18 @@ }, { "cell_type": "code", - "execution_count": 376, - "id": "420b1575", + "execution_count": 149, + "id": "7d03514f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple1.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-fede9d52a3717854-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tpipeline=[tfsimple]\r\n", - "seldon.default.model.tfsimple1.outputs\tcect0skvem6s73b81mig\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tpipeline=[tfsimple]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-a11f988f4ce9ed8e-01]\r\n", - "seldon.default.pipeline.tfsimple.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-91470ae8461f6e35-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tpipeline=[tfsimple]\r\n", - "seldon.default.pipeline.tfsimple.outputs\tcect0skvem6s73b81mig\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tpipeline=[tfsimple]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-dde201c08a1d60ae-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\r\n" + "seldon.default.model.tfsimple1.inputs\tceevkfs7aa7c73d9cfs0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\tpipeline=[tfsimple]\ttraceparent=[00-01d19de78cff2a815a8f20ba38f7a009-c18e60cf70b2c9fa-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n", + "seldon.default.model.tfsimple1.outputs\tceevkfs7aa7c73d9cfs0\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tpipeline=[tfsimple]\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[ceevkfr9me5c73c9i7jg]\ttraceparent=[00-01d19de78cff2a815a8f20ba38f7a009-cafaccc7a3930447-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n", + "seldon.default.pipeline.tfsimple.inputs\tceevkfs7aa7c73d9cfs0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\t\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tpipeline=[tfsimple]\ttraceparent=[00-01d19de78cff2a815a8f20ba38f7a009-03db08cfee014b2c-01]\r\n", + "seldon.default.pipeline.tfsimple.outputs\tceevkfs7aa7c73d9cfs0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\t\tx-envoy-upstream-service-time=[0]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[ceevkfr9me5c73c9i7jg]\tpipeline=[tfsimple]\ttraceparent=[00-01d19de78cff2a815a8f20ba38f7a009-b4a87cbb29038c9c-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\r\n" ] } ], @@ -2135,29 +2135,29 @@ }, { "cell_type": "code", - "execution_count": 377, - "id": "d401bc2d", + "execution_count": 150, + "id": "36b2133e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "seldon.default.model.tfsimple2.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\tpipeline=[tfsimple-extended-step]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-ae48015963a5ef57-01]\r\n", - "seldon.default.model.tfsimple2.outputs\tcect0skvem6s73b81mig\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\tpipeline=[tfsimple-extended-step]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-f3ad52da9360754e-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\r\n", - "seldon.default.pipeline.tfsimple-extended-step.inputs\tcect0skvem6s73b81mig\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\t\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3]\tx-seldon-route=[:tfsimple1_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\tpipeline=[tfsimple-extended-step]\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-3b2b42a783e0b6de-01]\tx-forwarded-proto=[http]\r\n", - "seldon.default.pipeline.tfsimple-extended-step.outputs\tcect0skvem6s73b81mig\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\t\ttraceparent=[00-9abb65f0c94d473c9be195de73063777-9de647c35f7ac59a-01]\tx-forwarded-proto=[http]\tx-envoy-expected-rq-timeout-ms=[60000]\tx-envoy-upstream-service-time=[3 1]\tx-seldon-route=[:tfsimple1_1: :tfsimple2_1:]\tx-request-id=[cect0skvem6s73eqg5fg]\tpipeline=[tfsimple-extended-step]\r\n" + "seldon.default.model.tfsimple2.inputs\tceevkfs7aa7c73d9cfs0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceepucc7aa7c73d9cfjg\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended-step.inputs\tceevkfs7aa7c73d9cfs0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended-step.outputs\tceeq5ss7aa7c73d9cfm0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" ] } ], "source": [ - "!seldon pipeline inspect tfsimple-extended-step --verbose" + "!seldon pipeline inspect tfsimple-extended-step" ] }, { "cell_type": "code", - "execution_count": 319, - "id": "3b688398", + "execution_count": 151, + "id": "09e5293f", "metadata": {}, "outputs": [ { @@ -2165,7 +2165,7 @@ "output_type": "stream", "text": [ "{}\n", - "Error: rpc error: code = FailedPrecondition desc = pipeline tfsimple not found\n" + "{}\n" ] } ], @@ -2176,8 +2176,580 @@ }, { "cell_type": "code", - "execution_count": 320, - "id": "7ba195af", + "execution_count": 152, + "id": "dad54862", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model unload tfsimple1\n", + "!seldon model unload tfsimple2" + ] + }, + { + "cell_type": "markdown", + "id": "ec3fbaeb", + "metadata": {}, + "source": [ + "### Pipeline pulling from two other Pipeline steps from same model\n", + "\n", + "![pipeline-to-pipeline](img_pipeline5.jpg)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "id": "c5ff042a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple1\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Model\n", + "metadata:\n", + " name: tfsimple2\n", + "spec:\n", + " storageUri: \"gs://seldon-models/triton/simple\"\n", + " requirements:\n", + " - tensorflow\n", + " memory: 100Ki\n" + ] + } + ], + "source": [ + "!cat ./models/tfsimple1.yaml\n", + "!cat ./models/tfsimple2.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 154, + "id": "1218d50c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model load -f ./models/tfsimple1.yaml \n", + "!seldon model load -f ./models/tfsimple2.yaml " + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "id": "c853259a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon model status tfsimple1 -w ModelAvailable | jq -M .\n", + "!seldon model status tfsimple2 -w ModelAvailable | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 156, + "id": "e141244a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\r\n", + "kind: Pipeline\r\n", + "metadata:\r\n", + " name: tfsimple\r\n", + "spec:\r\n", + " steps:\r\n", + " - name: tfsimple1\r\n", + " output:\r\n", + " steps:\r\n", + " - tfsimple1\r\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 157, + "id": "2d4e1f37", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "id": "6adb818a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"pipelineName\": \"tfsimple\",\r\n", + " \"versions\": [\r\n", + " {\r\n", + " \"pipeline\": {\r\n", + " \"name\": \"tfsimple\",\r\n", + " \"uid\": \"ceevkk6sc0ns73er67qg\",\r\n", + " \"version\": 1,\r\n", + " \"steps\": [\r\n", + " {\r\n", + " \"name\": \"tfsimple1\"\r\n", + " }\r\n", + " ],\r\n", + " \"output\": {\r\n", + " \"steps\": [\r\n", + " \"tfsimple1.outputs\"\r\n", + " ]\r\n", + " },\r\n", + " \"kubernetesMeta\": {}\r\n", + " },\r\n", + " \"state\": {\r\n", + " \"pipelineVersion\": 1,\r\n", + " \"status\": \"PipelineReady\",\r\n", + " \"reason\": \"created pipeline\",\r\n", + " \"lastChangeTimestamp\": \"2022-12-17T17:20:16.765278466Z\",\r\n", + " \"modelsReady\": true\r\n", + " }\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple -w PipelineReady| jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 160, + "id": "d922d330", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"model_name\": \"\",\r\n", + " \"outputs\": [\r\n", + " {\r\n", + " \"data\": [\r\n", + " 2,\r\n", + " 4,\r\n", + " 6,\r\n", + " 8,\r\n", + " 10,\r\n", + " 12,\r\n", + " 14,\r\n", + " 16,\r\n", + " 18,\r\n", + " 20,\r\n", + " 22,\r\n", + " 24,\r\n", + " 26,\r\n", + " 28,\r\n", + " 30,\r\n", + " 32\r\n", + " ],\r\n", + " \"name\": \"OUTPUT0\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " },\r\n", + " {\r\n", + " \"data\": [\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0,\r\n", + " 0\r\n", + " ],\r\n", + " \"name\": \"OUTPUT1\",\r\n", + " \"shape\": [\r\n", + " 1,\r\n", + " 16\r\n", + " ],\r\n", + " \"datatype\": \"INT32\"\r\n", + " }\r\n", + " ]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' | jq -M ." + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "id": "00f60705", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-extended\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple.outputs\n", + " tensorMap:\n", + " tfsimple.outputs.OUTPUT0: INPUT0\n", + " tfsimple.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n", + "---\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-extended2\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple.outputs\n", + " tensorMap:\n", + " tfsimple.outputs.OUTPUT0: INPUT0\n", + " tfsimple.outputs.OUTPUT1: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n", + "---\n", + "apiVersion: mlops.seldon.io/v1alpha1\n", + "kind: Pipeline\n", + "metadata:\n", + " name: tfsimple-combined-step\n", + "spec:\n", + " input:\n", + " externalInputs:\n", + " - tfsimple-extended.step.tfsimple2.outputs.OUTPUT0\n", + " - tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0\n", + " tensorMap:\n", + " tfsimple-extended.step.tfsimple2.outputs.OUTPUT0: INPUT0\n", + " tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0: INPUT1\n", + " steps:\n", + " - name: tfsimple2\n", + " output:\n", + " steps:\n", + " - tfsimple2\n" + ] + } + ], + "source": [ + "!cat ./pipelines/tfsimple-extended.yaml\n", + "!echo \"---\"\n", + "!cat ./pipelines/tfsimple-extended2.yaml\n", + "!echo \"---\"\n", + "!cat ./pipelines/tfsimple-combined-step.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 162, + "id": "ff620079", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml\n", + "!seldon pipeline load -f ./pipelines/tfsimple-extended2.yaml\n", + "!seldon pipeline load -f ./pipelines/tfsimple-combined-step.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "id": "a9a381a1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\"pipelineName\":\"tfsimple-extended\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended\", \"uid\":\"ceevl7esc0ns73er67r0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:21:33.538468063Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-extended2\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-extended2\", \"uid\":\"ceevl7esc0ns73er67rg\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple.outputs\"], \"tensorMap\":{\"tfsimple.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple.outputs.OUTPUT1\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:21:33.681257781Z\", \"modelsReady\":true}}]}\n", + "{\"pipelineName\":\"tfsimple-combined-step\", \"versions\":[{\"pipeline\":{\"name\":\"tfsimple-combined-step\", \"uid\":\"ceevl7esc0ns73er67s0\", \"version\":1, \"steps\":[{\"name\":\"tfsimple2\"}], \"output\":{\"steps\":[\"tfsimple2.outputs\"]}, \"kubernetesMeta\":{}, \"input\":{\"externalInputs\":[\"tfsimple-extended.step.tfsimple2.outputs.OUTPUT0\", \"tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0\"], \"tensorMap\":{\"tfsimple-extended.step.tfsimple2.outputs.OUTPUT0\":\"INPUT0\", \"tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0\":\"INPUT1\"}}}, \"state\":{\"pipelineVersion\":1, \"status\":\"PipelineReady\", \"reason\":\"created pipeline\", \"lastChangeTimestamp\":\"2022-12-17T17:21:33.911798115Z\", \"modelsReady\":true}}]}\n" + ] + } + ], + "source": [ + "!seldon pipeline status tfsimple-extended -w PipelineReady\n", + "!seldon pipeline status tfsimple-extended2 -w PipelineReady\n", + "!seldon pipeline status tfsimple-combined-step -w PipelineReady" + ] + }, + { + "cell_type": "code", + "execution_count": 164, + "id": "b65a28de", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + "\t\"model_name\": \"\",\r\n", + "\t\"outputs\": [\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t2,\r\n", + "\t\t\t\t4,\r\n", + "\t\t\t\t6,\r\n", + "\t\t\t\t8,\r\n", + "\t\t\t\t10,\r\n", + "\t\t\t\t12,\r\n", + "\t\t\t\t14,\r\n", + "\t\t\t\t16,\r\n", + "\t\t\t\t18,\r\n", + "\t\t\t\t20,\r\n", + "\t\t\t\t22,\r\n", + "\t\t\t\t24,\r\n", + "\t\t\t\t26,\r\n", + "\t\t\t\t28,\r\n", + "\t\t\t\t30,\r\n", + "\t\t\t\t32\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT0\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t},\r\n", + "\t\t{\r\n", + "\t\t\t\"data\": [\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0,\r\n", + "\t\t\t\t0\r\n", + "\t\t\t],\r\n", + "\t\t\t\"name\": \"OUTPUT1\",\r\n", + "\t\t\t\"shape\": [\r\n", + "\t\t\t\t1,\r\n", + "\t\t\t\t16\r\n", + "\t\t\t],\r\n", + "\t\t\t\"datatype\": \"INT32\"\r\n", + "\t\t}\r\n", + "\t]\r\n", + "}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline infer tfsimple \\\n", + " '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}' " + ] + }, + { + "cell_type": "code", + "execution_count": 165, + "id": "bc1ad2dd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple1.inputs\tceevl847aa7c73d9cftg\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.model.tfsimple1.outputs\tceevl847aa7c73d9cftg\t{\"modelName\":\"tfsimple1_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple.inputs\tceevl847aa7c73d9cftg\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]}\r\n", + "seldon.default.pipeline.tfsimple.outputs\tceevl847aa7c73d9cftg\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 166, + "id": "2eb548ac", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\ttest-id3\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceepucc7aa7c73d9cfjg\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended.inputs\tceevl847aa7c73d9cftg\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended.outputs\tceevl847aa7c73d9cftg\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended" + ] + }, + { + "cell_type": "code", + "execution_count": 167, + "id": "108e2c24", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\tceepua47aa7c73d9cfj0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceepucc7aa7c73d9cfjg\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.inputs\tceevl847aa7c73d9cftg\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-extended2.outputs\tceevl847aa7c73d9cftg\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-extended2" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "id": "239a6b9d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldon.default.model.tfsimple2.inputs\tceeq4ls7aa7c73d9cfk0\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.model.tfsimple2.outputs\tceepucc7aa7c73d9cfjg\t{\"modelName\":\"tfsimple2_1\", \"modelVersion\":\"1\", \"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n", + "seldon.default.pipeline.tfsimple-combined-step.inputs\tceevl847aa7c73d9cftg\t{\"inputs\":[{\"name\":\"INPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {\"name\":\"INPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], \"rawInputContents\":[\"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\", \"AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==\"]}\r\n", + "seldon.default.pipeline.tfsimple-combined-step.outputs\tceepua47aa7c73d9cfj0\t{\"outputs\":[{\"name\":\"OUTPUT0\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {\"name\":\"OUTPUT1\", \"datatype\":\"INT32\", \"shape\":[\"1\", \"16\"], \"contents\":{\"intContents\":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]}\r\n" + ] + } + ], + "source": [ + "!seldon pipeline inspect tfsimple-combined-step" + ] + }, + { + "cell_type": "code", + "execution_count": 169, + "id": "840af9e6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{}\n", + "{}\n", + "{}\n" + ] + } + ], + "source": [ + "!seldon pipeline unload tfsimple-extended\n", + "!seldon pipeline unload tfsimple-extended2\n", + "!seldon pipeline unload tfsimple-combined-step\n", + "!seldon pipeline unload tfsimple" + ] + }, + { + "cell_type": "code", + "execution_count": 170, + "id": "3f2584b3", "metadata": {}, "outputs": [ { @@ -2197,7 +2769,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4bfede4a", + "id": "503c0778", "metadata": {}, "outputs": [], "source": [] diff --git a/samples/pipeline-to-pipeline.md b/samples/pipeline-to-pipeline.md index e396c64bee..c9f34ae6a4 100644 --- a/samples/pipeline-to-pipeline.md +++ b/samples/pipeline-to-pipeline.md @@ -94,7 +94,7 @@ This notebook illustrates a series of Pipelines that are joined together. { "pipeline": { "name": "tfsimple", - "uid": "cebnb8ev219s73a6ojk0", + "uid": "ceevilesc0ns73er67kg", "version": 1, "steps": [ { @@ -112,7 +112,7 @@ This notebook illustrates a series of Pipelines that are joined together. "pipelineVersion": 1, "status": "PipelineReady", "reason": "created pipeline", - "lastChangeTimestamp": "2022-12-12T18:40:33.304154775Z", + "lastChangeTimestamp": "2022-12-17T17:16:05.915396256Z", "modelsReady": true } } @@ -227,7 +227,7 @@ This notebook illustrates a series of Pipelines that are joined together. { "pipeline": { "name": "tfsimple-extended", - "uid": "cebnb9mv219s73a6ojkg", + "uid": "ceevin6sc0ns73er67l0", "version": 1, "steps": [ { @@ -254,7 +254,7 @@ This notebook illustrates a series of Pipelines that are joined together. "pipelineVersion": 1, "status": "PipelineReady", "reason": "created pipeline", - "lastChangeTimestamp": "2022-12-12T18:40:39.004261615Z", + "lastChangeTimestamp": "2022-12-17T17:16:12.837674035Z", "modelsReady": true } } @@ -332,10 +332,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple ``` - seldon.default.model.tfsimple1.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} - seldon.default.model.tfsimple1.outputs cebnba9q03gs739pd0eg {"modelName":"tfsimple1_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} - seldon.default.pipeline.tfsimple.outputs cebnba9q03gs739pd0eg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.model.tfsimple1.inputs ceevins7aa7c73d9cfo0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.model.tfsimple1.outputs ceevins7aa7c73d9cfo0 {"modelName":"tfsimple1_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple.inputs ceevins7aa7c73d9cfo0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.pipeline.tfsimple.outputs ceevins7aa7c73d9cfo0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} @@ -343,10 +343,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple-extended ``` - seldon.default.model.tfsimple2.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} - seldon.default.model.tfsimple2.outputs cebnba9q03gs739pd0eg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} - seldon.default.pipeline.tfsimple-extended.inputs cebnba9q03gs739pd0eg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} - seldon.default.pipeline.tfsimple-extended.outputs cebnba9q03gs739pd0eg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + seldon.default.model.tfsimple2.inputs ceevins7aa7c73d9cfo0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceevins7aa7c73d9cfo0 {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} + seldon.default.pipeline.tfsimple-extended.inputs ceevins7aa7c73d9cfo0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended.outputs ceevins7aa7c73d9cfo0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} @@ -456,7 +456,7 @@ This notebook illustrates a series of Pipelines that are joined together. { "pipeline": { "name": "tfsimple", - "uid": "cebnacuv219s73a6oji0", + "uid": "ceevj2msc0ns73er67lg", "version": 1, "steps": [ { @@ -474,7 +474,7 @@ This notebook illustrates a series of Pipelines that are joined together. "pipelineVersion": 1, "status": "PipelineReady", "reason": "created pipeline", - "lastChangeTimestamp": "2022-12-12T18:38:43.317204867Z", + "lastChangeTimestamp": "2022-12-17T17:16:59.017037835Z", "modelsReady": true } } @@ -628,9 +628,9 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline status tfsimple-combined -w PipelineReady ``` - {"pipelineName":"tfsimple-extended","versions":[{"pipeline":{"name":"tfsimple-extended","uid":"cebnaemv219s73a6ojig","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:38:50.324389094Z","modelsReady":true}}]} - {"pipelineName":"tfsimple-extended2","versions":[{"pipeline":{"name":"tfsimple-extended2","uid":"cebnaemv219s73a6ojj0","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:38:50.467839593Z","modelsReady":true}}]} - {"pipelineName":"tfsimple-combined","versions":[{"pipeline":{"name":"tfsimple-combined","uid":"cebnaemv219s73a6ojjg","version":2,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple-extended.outputs.OUTPUT0","tfsimple-extended2.outputs.OUTPUT1"],"tensorMap":{"tfsimple-extended.outputs.OUTPUT0":"INPUT0","tfsimple-extended2.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":2,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:38:50.718933075Z","modelsReady":true}}]} + {"pipelineName":"tfsimple-extended", "versions":[{"pipeline":{"name":"tfsimple-extended", "uid":"ceevj3usc0ns73er67m0", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple.outputs"], "tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0", "tfsimple.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:17:04.079245812Z", "modelsReady":true}}]} + {"pipelineName":"tfsimple-extended2", "versions":[{"pipeline":{"name":"tfsimple-extended2", "uid":"ceevj46sc0ns73er67mg", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple.outputs"], "tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0", "tfsimple.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:17:04.226769422Z", "modelsReady":true}}]} + {"pipelineName":"tfsimple-combined", "versions":[{"pipeline":{"name":"tfsimple-combined", "uid":"ceevj46sc0ns73er67n0", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple-extended.outputs.OUTPUT0", "tfsimple-extended2.outputs.OUTPUT1"], "tensorMap":{"tfsimple-extended.outputs.OUTPUT0":"INPUT0", "tfsimple-extended2.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:17:04.466100483Z", "modelsReady":true}}]} @@ -703,10 +703,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple ``` - seldon.default.model.tfsimple1.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} - seldon.default.model.tfsimple1.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple1_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} - seldon.default.pipeline.tfsimple.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.model.tfsimple1.inputs ceevj4k7aa7c73d9cfp0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.model.tfsimple1.outputs ceevj4k7aa7c73d9cfp0 {"modelName":"tfsimple1_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple.inputs ceevj4k7aa7c73d9cfp0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.pipeline.tfsimple.outputs ceevj4k7aa7c73d9cfp0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} @@ -714,10 +714,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple-extended ``` - seldon.default.model.tfsimple2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.model.tfsimple2.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple-extended.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} - seldon.default.pipeline.tfsimple-extended.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + seldon.default.model.tfsimple2.inputs ceevj347aa7c73d9cfog {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceepua47aa7c73d9cfj0 {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-extended.inputs ceevj4k7aa7c73d9cfp0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended.outputs ceevj4k7aa7c73d9cfp0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} @@ -725,10 +725,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple-extended2 ``` - seldon.default.model.tfsimple2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.model.tfsimple2.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple-extended2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} - seldon.default.pipeline.tfsimple-extended2.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + seldon.default.model.tfsimple2.inputs ceevj4k7aa7c73d9cfp0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceeq4ls7aa7c73d9cfk0 {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-extended2.inputs ceevj4k7aa7c73d9cfp0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended2.outputs ceevj4k7aa7c73d9cfp0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} @@ -736,10 +736,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple-combined ``` - seldon.default.model.tfsimple2.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.model.tfsimple2.outputs cebnaf9q03gs739pd0dg {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple-combined.inputs cebnaf9q03gs739pd0dg {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.pipeline.tfsimple-combined.outputs cebnaf9q03gs739pd0dg {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.model.tfsimple2.inputs ceevj4k7aa7c73d9cfp0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceespfk7aa7c73d9cfmg {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-combined.inputs ceevj4k7aa7c73d9cfp0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.pipeline.tfsimple-combined.outputs ceespfk7aa7c73d9cfmg {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} @@ -853,7 +853,7 @@ This notebook illustrates a series of Pipelines that are joined together. { "pipeline": { "name": "tfsimple", - "uid": "cebnbguv219s73a6ojl0", + "uid": "ceevja6sc0ns73er67ng", "version": 1, "steps": [ { @@ -871,7 +871,7 @@ This notebook illustrates a series of Pipelines that are joined together. "pipelineVersion": 1, "status": "PipelineReady", "reason": "created pipeline", - "lastChangeTimestamp": "2022-12-12T18:41:07.131448326Z", + "lastChangeTimestamp": "2022-12-17T17:17:29.011892538Z", "modelsReady": true } } @@ -1026,9 +1026,9 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline status tfsimple-combined-trigger -w PipelineReady ``` - {"pipelineName":"tfsimple-extended","versions":[{"pipeline":{"name":"tfsimple-extended","uid":"cebnbimv219s73a6ojlg","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:41:14.561905446Z","modelsReady":true}}]} - {"pipelineName":"tfsimple-extended2","versions":[{"pipeline":{"name":"tfsimple-extended2","uid":"cebnbimv219s73a6ojm0","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple.outputs"],"tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0","tfsimple.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:41:14.693285174Z","modelsReady":true}}]} - {"pipelineName":"tfsimple-combined-trigger","versions":[{"pipeline":{"name":"tfsimple-combined-trigger","uid":"cebnbimv219s73a6ojmg","version":1,"steps":[{"name":"tfsimple2"}],"output":{"steps":["tfsimple2.outputs"]},"kubernetesMeta":{},"input":{"externalInputs":["tfsimple-extended.outputs"],"externalTriggers":["tfsimple-extended2.outputs"],"tensorMap":{"tfsimple-extended.outputs.OUTPUT0":"INPUT0","tfsimple-extended.outputs.OUTPUT1":"INPUT1"}}},"state":{"pipelineVersion":1,"status":"PipelineReady","reason":"created pipeline","lastChangeTimestamp":"2022-12-12T18:41:14.945627389Z","modelsReady":true}}]} + {"pipelineName":"tfsimple-extended", "versions":[{"pipeline":{"name":"tfsimple-extended", "uid":"ceevjbmsc0ns73er67o0", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple.outputs"], "tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0", "tfsimple.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:17:34.180121811Z", "modelsReady":true}}]} + {"pipelineName":"tfsimple-extended2", "versions":[{"pipeline":{"name":"tfsimple-extended2", "uid":"ceevjbmsc0ns73er67og", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple.outputs"], "tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0", "tfsimple.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:17:34.307458250Z", "modelsReady":true}}]} + {"pipelineName":"tfsimple-combined-trigger", "versions":[{"pipeline":{"name":"tfsimple-combined-trigger", "uid":"ceevjbmsc0ns73er67p0", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple-extended.outputs"], "externalTriggers":["tfsimple-extended2.outputs"], "tensorMap":{"tfsimple-extended.outputs.OUTPUT0":"INPUT0", "tfsimple-extended.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:17:34.550045739Z", "modelsReady":true}}]} @@ -1101,10 +1101,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple ``` - seldon.default.model.tfsimple1.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} - seldon.default.model.tfsimple1.outputs test-id3 {"modelName":"tfsimple1_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}}]} - seldon.default.pipeline.tfsimple.outputs test-id3 {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.model.tfsimple1.inputs test-id3 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.model.tfsimple1.outputs test-id3 {"modelName":"tfsimple1_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple.inputs test-id3 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.pipeline.tfsimple.outputs test-id3 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} @@ -1112,10 +1112,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple-extended ``` - seldon.default.model.tfsimple2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.model.tfsimple2.outputs test-id1 {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple-extended.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} - seldon.default.pipeline.tfsimple-extended.outputs test-id3 {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + seldon.default.model.tfsimple2.inputs ceeq4ok7aa7c73d9cfkg {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceepua47aa7c73d9cfj0 {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-extended.inputs test-id3 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended.outputs test-id3 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} @@ -1123,10 +1123,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple-extended2 ``` - seldon.default.model.tfsimple2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.model.tfsimple2.outputs test-id1 {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple-extended2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} - seldon.default.pipeline.tfsimple-extended2.outputs test-id3 {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}]} + seldon.default.model.tfsimple2.inputs ceeq4ok7aa7c73d9cfkg {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceeq4ok7aa7c73d9cfkg {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-extended2.inputs test-id3 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended2.outputs test-id3 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} @@ -1134,10 +1134,10 @@ This notebook illustrates a series of Pipelines that are joined together. !seldon pipeline inspect tfsimple-combined-trigger ``` - seldon.default.model.tfsimple2.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.model.tfsimple2.outputs cebki39q03gs739pd0ag {"modelName":"tfsimple2_1","modelVersion":"1","outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} - seldon.default.pipeline.tfsimple-combined-trigger.inputs test-id3 {"inputs":[{"name":"INPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}},{"name":"INPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}}],"rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==","AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} - seldon.default.pipeline.tfsimple-combined-trigger.outputs cebjfl1q03gs739pd09g {"outputs":[{"name":"OUTPUT0","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64]}},{"name":"OUTPUT1","datatype":"INT32","shape":["1","16"],"contents":{"intContents":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}]} + seldon.default.model.tfsimple2.inputs ceepua47aa7c73d9cfj0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceeq4ls7aa7c73d9cfk0 {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-combined-trigger.inputs test-id3 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.pipeline.tfsimple-combined-trigger.outputs ceespfk7aa7c73d9cfmg {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} @@ -1155,6 +1155,765 @@ This notebook illustrates a series of Pipelines that are joined together. +```python +!seldon model unload tfsimple1 +!seldon model unload tfsimple2 +``` + + {} + {} + + +### Pipeline pulling from one other Pipeline Step + +![pipeline-to-pipeline](img_pipeline4.jpg) + + + +```python +!cat ./models/tfsimple1.yaml +!cat ./models/tfsimple2.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple1 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple2 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + + + +```python +!seldon model load -f ./models/tfsimple1.yaml +!seldon model load -f ./models/tfsimple2.yaml +``` + + {} + {} + + + +```python +!seldon model status tfsimple1 -w ModelAvailable | jq -M . +!seldon model status tfsimple2 -w ModelAvailable | jq -M . +``` + + {} + {} + + + +```python +!cat ./pipelines/tfsimple.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple + spec: + steps: + - name: tfsimple1 + output: + steps: + - tfsimple1 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple.yaml +``` + + {} + + + +```python +!seldon pipeline status tfsimple -w PipelineReady| jq -M . +``` + + { + "pipelineName": "tfsimple", + "versions": [ + { + "pipeline": { + "name": "tfsimple", + "uid": "ceevjh6sc0ns73er67pg", + "version": 1, + "steps": [ + { + "name": "tfsimple1" + } + ], + "output": { + "steps": [ + "tfsimple1.outputs" + ] + }, + "kubernetesMeta": {} + }, + "state": { + "pipelineVersion": 1, + "status": "PipelineReady", + "reason": "created pipeline", + "lastChangeTimestamp": "2022-12-17T17:17:56.809691365Z", + "modelsReady": true + } + } + ] + } + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' | jq -M . +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!cat ./pipelines/tfsimple-extended-step.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended-step + spec: + input: + externalInputs: + - tfsimple.step.tfsimple1.outputs + tensorMap: + tfsimple.step.tfsimple1.outputs.OUTPUT0: INPUT0 + tfsimple.step.tfsimple1.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple-extended-step.yaml +``` + + {} + + + +```python +!seldon pipeline status tfsimple-extended-step -w PipelineReady| jq -M . +``` + + { + "pipelineName": "tfsimple-extended-step", + "versions": [ + { + "pipeline": { + "name": "tfsimple-extended-step", + "uid": "ceevkf6sc0ns73er67q0", + "version": 1, + "steps": [ + { + "name": "tfsimple2" + } + ], + "output": { + "steps": [ + "tfsimple2.outputs" + ] + }, + "kubernetesMeta": {}, + "input": { + "externalInputs": [ + "tfsimple.step.tfsimple1.outputs" + ], + "tensorMap": { + "tfsimple.step.tfsimple1.outputs.OUTPUT0": "INPUT0", + "tfsimple.step.tfsimple1.outputs.OUTPUT1": "INPUT1" + } + } + }, + "state": { + "pipelineVersion": 1, + "status": "PipelineReady", + "reason": "created pipeline", + "lastChangeTimestamp": "2022-12-17T17:19:56.669740116Z", + "modelsReady": true + } + } + ] + } + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!seldon pipeline inspect tfsimple --verbose +``` + + seldon.default.model.tfsimple1.inputs ceevkfs7aa7c73d9cfs0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} pipeline=[tfsimple] traceparent=[00-01d19de78cff2a815a8f20ba38f7a009-c18e60cf70b2c9fa-01] x-forwarded-proto=[http] x-envoy-expected-rq-timeout-ms=[60000] + seldon.default.model.tfsimple1.outputs ceevkfs7aa7c73d9cfs0 {"modelName":"tfsimple1_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} pipeline=[tfsimple] x-envoy-upstream-service-time=[0] x-seldon-route=[:tfsimple1_1:] x-request-id=[ceevkfr9me5c73c9i7jg] traceparent=[00-01d19de78cff2a815a8f20ba38f7a009-cafaccc7a3930447-01] x-forwarded-proto=[http] x-envoy-expected-rq-timeout-ms=[60000] + seldon.default.pipeline.tfsimple.inputs ceevkfs7aa7c73d9cfs0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} x-forwarded-proto=[http] x-envoy-expected-rq-timeout-ms=[60000] pipeline=[tfsimple] traceparent=[00-01d19de78cff2a815a8f20ba38f7a009-03db08cfee014b2c-01] + seldon.default.pipeline.tfsimple.outputs ceevkfs7aa7c73d9cfs0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} x-envoy-upstream-service-time=[0] x-seldon-route=[:tfsimple1_1:] x-request-id=[ceevkfr9me5c73c9i7jg] pipeline=[tfsimple] traceparent=[00-01d19de78cff2a815a8f20ba38f7a009-b4a87cbb29038c9c-01] x-forwarded-proto=[http] x-envoy-expected-rq-timeout-ms=[60000] + + + +```python +!seldon pipeline inspect tfsimple-extended-step +``` + + seldon.default.model.tfsimple2.inputs ceevkfs7aa7c73d9cfs0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceepucc7aa7c73d9cfjg {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-extended-step.inputs ceevkfs7aa7c73d9cfs0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended-step.outputs ceeq5ss7aa7c73d9cfm0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} + + + +```python +!seldon pipeline unload tfsimple-extended-step +!seldon pipeline unload tfsimple +``` + + {} + {} + + + +```python +!seldon model unload tfsimple1 +!seldon model unload tfsimple2 +``` + + {} + {} + + +### Pipeline pulling from two other Pipeline steps from same model + +![pipeline-to-pipeline](img_pipeline5.jpg) + + + +```python +!cat ./models/tfsimple1.yaml +!cat ./models/tfsimple2.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple1 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + apiVersion: mlops.seldon.io/v1alpha1 + kind: Model + metadata: + name: tfsimple2 + spec: + storageUri: "gs://seldon-models/triton/simple" + requirements: + - tensorflow + memory: 100Ki + + + +```python +!seldon model load -f ./models/tfsimple1.yaml +!seldon model load -f ./models/tfsimple2.yaml +``` + + {} + {} + + + +```python +!seldon model status tfsimple1 -w ModelAvailable | jq -M . +!seldon model status tfsimple2 -w ModelAvailable | jq -M . +``` + + {} + {} + + + +```python +!cat ./pipelines/tfsimple.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple + spec: + steps: + - name: tfsimple1 + output: + steps: + - tfsimple1 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple.yaml +``` + + {} + + + +```python +!seldon pipeline status tfsimple -w PipelineReady| jq -M . +``` + + { + "pipelineName": "tfsimple", + "versions": [ + { + "pipeline": { + "name": "tfsimple", + "uid": "ceevkk6sc0ns73er67qg", + "version": 1, + "steps": [ + { + "name": "tfsimple1" + } + ], + "output": { + "steps": [ + "tfsimple1.outputs" + ] + }, + "kubernetesMeta": {} + }, + "state": { + "pipelineVersion": 1, + "status": "PipelineReady", + "reason": "created pipeline", + "lastChangeTimestamp": "2022-12-17T17:20:16.765278466Z", + "modelsReady": true + } + } + ] + } + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' | jq -M . +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!cat ./pipelines/tfsimple-extended.yaml +!echo "---" +!cat ./pipelines/tfsimple-extended2.yaml +!echo "---" +!cat ./pipelines/tfsimple-combined-step.yaml +``` + + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended + spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + --- + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-extended2 + spec: + input: + externalInputs: + - tfsimple.outputs + tensorMap: + tfsimple.outputs.OUTPUT0: INPUT0 + tfsimple.outputs.OUTPUT1: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + --- + apiVersion: mlops.seldon.io/v1alpha1 + kind: Pipeline + metadata: + name: tfsimple-combined-step + spec: + input: + externalInputs: + - tfsimple-extended.step.tfsimple2.outputs.OUTPUT0 + - tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0 + tensorMap: + tfsimple-extended.step.tfsimple2.outputs.OUTPUT0: INPUT0 + tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0: INPUT1 + steps: + - name: tfsimple2 + output: + steps: + - tfsimple2 + + + +```python +!seldon pipeline load -f ./pipelines/tfsimple-extended.yaml +!seldon pipeline load -f ./pipelines/tfsimple-extended2.yaml +!seldon pipeline load -f ./pipelines/tfsimple-combined-step.yaml +``` + + {} + {} + {} + + + +```python +!seldon pipeline status tfsimple-extended -w PipelineReady +!seldon pipeline status tfsimple-extended2 -w PipelineReady +!seldon pipeline status tfsimple-combined-step -w PipelineReady +``` + + {"pipelineName":"tfsimple-extended", "versions":[{"pipeline":{"name":"tfsimple-extended", "uid":"ceevl7esc0ns73er67r0", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple.outputs"], "tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0", "tfsimple.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:21:33.538468063Z", "modelsReady":true}}]} + {"pipelineName":"tfsimple-extended2", "versions":[{"pipeline":{"name":"tfsimple-extended2", "uid":"ceevl7esc0ns73er67rg", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple.outputs"], "tensorMap":{"tfsimple.outputs.OUTPUT0":"INPUT0", "tfsimple.outputs.OUTPUT1":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:21:33.681257781Z", "modelsReady":true}}]} + {"pipelineName":"tfsimple-combined-step", "versions":[{"pipeline":{"name":"tfsimple-combined-step", "uid":"ceevl7esc0ns73er67s0", "version":1, "steps":[{"name":"tfsimple2"}], "output":{"steps":["tfsimple2.outputs"]}, "kubernetesMeta":{}, "input":{"externalInputs":["tfsimple-extended.step.tfsimple2.outputs.OUTPUT0", "tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0"], "tensorMap":{"tfsimple-extended.step.tfsimple2.outputs.OUTPUT0":"INPUT0", "tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0":"INPUT1"}}}, "state":{"pipelineVersion":1, "status":"PipelineReady", "reason":"created pipeline", "lastChangeTimestamp":"2022-12-17T17:21:33.911798115Z", "modelsReady":true}}]} + + + +```python +!seldon pipeline infer tfsimple \ + '{"inputs":[{"name":"INPUT0","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]},{"name":"INPUT1","data":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"datatype":"INT32","shape":[1,16]}]}' +``` + + { + "model_name": "", + "outputs": [ + { + "data": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32 + ], + "name": "OUTPUT0", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + }, + { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "name": "OUTPUT1", + "shape": [ + 1, + 16 + ], + "datatype": "INT32" + } + ] + } + + + +```python +!seldon pipeline inspect tfsimple +``` + + seldon.default.model.tfsimple1.inputs ceevl847aa7c73d9cftg {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.model.tfsimple1.outputs ceevl847aa7c73d9cftg {"modelName":"tfsimple1_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple.inputs ceevl847aa7c73d9cftg {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}}]} + seldon.default.pipeline.tfsimple.outputs ceevl847aa7c73d9cftg {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + + + +```python +!seldon pipeline inspect tfsimple-extended +``` + + seldon.default.model.tfsimple2.inputs test-id3 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceepucc7aa7c73d9cfjg {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-extended.inputs ceevl847aa7c73d9cftg {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended.outputs ceevl847aa7c73d9cftg {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} + + + +```python +!seldon pipeline inspect tfsimple-extended2 +``` + + seldon.default.model.tfsimple2.inputs ceepua47aa7c73d9cfj0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceepucc7aa7c73d9cfjg {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-extended2.inputs ceevl847aa7c73d9cftg {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="]} + seldon.default.pipeline.tfsimple-extended2.outputs ceevl847aa7c73d9cftg {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}]} + + + +```python +!seldon pipeline inspect tfsimple-combined-step +``` + + seldon.default.model.tfsimple2.inputs ceeq4ls7aa7c73d9cfk0 {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.model.tfsimple2.outputs ceepucc7aa7c73d9cfjg {"modelName":"tfsimple2_1", "modelVersion":"1", "outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + seldon.default.pipeline.tfsimple-combined-step.inputs ceevl847aa7c73d9cftg {"inputs":[{"name":"INPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}, {"name":"INPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]}}], "rawInputContents":["AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA==", "AgAAAAQAAAAGAAAACAAAAAoAAAAMAAAADgAAABAAAAASAAAAFAAAABYAAAAYAAAAGgAAABwAAAAeAAAAIAAAAA=="]} + seldon.default.pipeline.tfsimple-combined-step.outputs ceepua47aa7c73d9cfj0 {"outputs":[{"name":"OUTPUT0", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64]}}, {"name":"OUTPUT1", "datatype":"INT32", "shape":["1", "16"], "contents":{"intContents":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}]} + + + +```python +!seldon pipeline unload tfsimple-extended +!seldon pipeline unload tfsimple-extended2 +!seldon pipeline unload tfsimple-combined-step +!seldon pipeline unload tfsimple +``` + + {} + {} + {} + {} + + + ```python !seldon model unload tfsimple1 !seldon model unload tfsimple2 From 83f91a52a18bcd316fee6337c54ba12c5fb296f8 Mon Sep 17 00:00:00 2001 From: Clive Cox Date: Sun, 18 Dec 2022 09:05:10 +0000 Subject: [PATCH 07/18] Ensure tensorMap works across pipelines by sending pipeline name in tensormap --- apis/go/mlops/chainer/chainer.pb.go | 273 ++- apis/mlops/chainer/chainer.proto | 8 +- .../mlops/chainer/ChainerOuterClass.java | 1809 +++++++++++++---- .../mlops/chainer/PipelineStepUpdateKt.kt | 97 +- .../mlops/chainer/PipelineTensorMappingKt.kt | 80 + samples/img_pipeline5.jpg | Bin 0 -> 84843 bytes samples/pipelines/tfsimple-combined-step.yaml | 17 + .../io/seldon/dataflow/kafka/Chainer.kt | 11 +- .../kotlin/io/seldon/dataflow/kafka/Joiner.kt | 11 +- .../io/seldon/dataflow/kafka/Pipeline.kt | 2 +- .../io/seldon/dataflow/kafka/PipelineStep.kt | 3 +- .../seldon/dataflow/kafka/StreamTransforms.kt | 18 +- .../dataflow/kafka/TriggerTransforms.kt | 2 +- .../seldon/dataflow/kafka/PipelineStepTest.kt | 6 +- scheduler/pkg/kafka/gateway/manager.go | 2 +- scheduler/pkg/kafka/topics.go | 38 +- scheduler/pkg/kafka/topics_test.go | 98 +- 17 files changed, 1871 insertions(+), 604 deletions(-) create mode 100644 apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTensorMappingKt.kt create mode 100644 samples/img_pipeline5.jpg create mode 100644 samples/pipelines/tfsimple-combined-step.yaml diff --git a/apis/go/mlops/chainer/chainer.pb.go b/apis/go/mlops/chainer/chainer.pb.go index 489dd7a047..bd60b4eb7e 100644 --- a/apis/go/mlops/chainer/chainer.pb.go +++ b/apis/go/mlops/chainer/chainer.pb.go @@ -261,10 +261,10 @@ type PipelineStepUpdate struct { Sink *PipelineTopic `protobuf:"bytes,3,opt,name=sink,proto3" json:"sink,omitempty"` InputJoinTy PipelineStepUpdate_PipelineJoinType `protobuf:"varint,4,opt,name=inputJoinTy,proto3,enum=seldon.mlops.chainer.PipelineStepUpdate_PipelineJoinType" json:"inputJoinTy,omitempty"` TriggersJoinTy PipelineStepUpdate_PipelineJoinType `protobuf:"varint,5,opt,name=triggersJoinTy,proto3,enum=seldon.mlops.chainer.PipelineStepUpdate_PipelineJoinType" json:"triggersJoinTy,omitempty"` - PassEmptyResponses bool `protobuf:"varint,6,opt,name=passEmptyResponses,proto3" json:"passEmptyResponses,omitempty"` // Forward empty response to following steps, default false - JoinWindowMs *uint32 `protobuf:"varint,7,opt,name=joinWindowMs,proto3,oneof" json:"joinWindowMs,omitempty"` // Join window millisecs, some nozero default (TBD) - TensorMap map[string]string `protobuf:"bytes,8,rep,name=tensorMap,proto3" json:"tensorMap,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // optional map of tensor name mappings - Batch *Batch `protobuf:"bytes,9,opt,name=batch,proto3" json:"batch,omitempty"` // Batch settings + PassEmptyResponses bool `protobuf:"varint,6,opt,name=passEmptyResponses,proto3" json:"passEmptyResponses,omitempty"` // Forward empty response to following steps, default false + JoinWindowMs *uint32 `protobuf:"varint,7,opt,name=joinWindowMs,proto3,oneof" json:"joinWindowMs,omitempty"` // Join window millisecs, some nozero default (TBD) + TensorMap []*PipelineTensorMapping `protobuf:"bytes,8,rep,name=tensorMap,proto3" json:"tensorMap,omitempty"` // optional list of tensor name mappings + Batch *Batch `protobuf:"bytes,9,opt,name=batch,proto3" json:"batch,omitempty"` // Batch settings } func (x *PipelineStepUpdate) Reset() { @@ -348,7 +348,7 @@ func (x *PipelineStepUpdate) GetJoinWindowMs() uint32 { return 0 } -func (x *PipelineStepUpdate) GetTensorMap() map[string]string { +func (x *PipelineStepUpdate) GetTensorMap() []*PipelineTensorMapping { if x != nil { return x.TensorMap } @@ -362,6 +362,69 @@ func (x *PipelineStepUpdate) GetBatch() *Batch { return nil } +type PipelineTensorMapping struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineName string `protobuf:"bytes,1,opt,name=pipelineName,proto3" json:"pipelineName,omitempty"` + TopicAndTensor string `protobuf:"bytes,2,opt,name=topicAndTensor,proto3" json:"topicAndTensor,omitempty"` + TensorName string `protobuf:"bytes,3,opt,name=tensorName,proto3" json:"tensorName,omitempty"` +} + +func (x *PipelineTensorMapping) Reset() { + *x = PipelineTensorMapping{} + if protoimpl.UnsafeEnabled { + mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PipelineTensorMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PipelineTensorMapping) ProtoMessage() {} + +func (x *PipelineTensorMapping) ProtoReflect() protoreflect.Message { + mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PipelineTensorMapping.ProtoReflect.Descriptor instead. +func (*PipelineTensorMapping) Descriptor() ([]byte, []int) { + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{3} +} + +func (x *PipelineTensorMapping) GetPipelineName() string { + if x != nil { + return x.PipelineName + } + return "" +} + +func (x *PipelineTensorMapping) GetTopicAndTensor() string { + if x != nil { + return x.TopicAndTensor + } + return "" +} + +func (x *PipelineTensorMapping) GetTensorName() string { + if x != nil { + return x.TensorName + } + return "" +} + type PipelineTopic struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -374,7 +437,7 @@ type PipelineTopic struct { func (x *PipelineTopic) Reset() { *x = PipelineTopic{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + mi := &file_mlops_chainer_chainer_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -387,7 +450,7 @@ func (x *PipelineTopic) String() string { func (*PipelineTopic) ProtoMessage() {} func (x *PipelineTopic) ProtoReflect() protoreflect.Message { - mi := &file_mlops_chainer_chainer_proto_msgTypes[3] + mi := &file_mlops_chainer_chainer_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -400,7 +463,7 @@ func (x *PipelineTopic) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineTopic.ProtoReflect.Descriptor instead. func (*PipelineTopic) Descriptor() ([]byte, []int) { - return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{3} + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{4} } func (x *PipelineTopic) GetPipelineName() string { @@ -430,7 +493,7 @@ type Batch struct { func (x *Batch) Reset() { *x = Batch{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_chainer_chainer_proto_msgTypes[4] + mi := &file_mlops_chainer_chainer_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -443,7 +506,7 @@ func (x *Batch) String() string { func (*Batch) ProtoMessage() {} func (x *Batch) ProtoReflect() protoreflect.Message { - mi := &file_mlops_chainer_chainer_proto_msgTypes[4] + mi := &file_mlops_chainer_chainer_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -456,7 +519,7 @@ func (x *Batch) ProtoReflect() protoreflect.Message { // Deprecated: Use Batch.ProtoReflect.Descriptor instead. func (*Batch) Descriptor() ([]byte, []int) { - return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{4} + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{5} } func (x *Batch) GetSize() uint32 { @@ -494,7 +557,7 @@ type PipelineUpdateStatusMessage struct { func (x *PipelineUpdateStatusMessage) Reset() { *x = PipelineUpdateStatusMessage{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_chainer_chainer_proto_msgTypes[5] + mi := &file_mlops_chainer_chainer_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -507,7 +570,7 @@ func (x *PipelineUpdateStatusMessage) String() string { func (*PipelineUpdateStatusMessage) ProtoMessage() {} func (x *PipelineUpdateStatusMessage) ProtoReflect() protoreflect.Message { - mi := &file_mlops_chainer_chainer_proto_msgTypes[5] + mi := &file_mlops_chainer_chainer_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -520,7 +583,7 @@ func (x *PipelineUpdateStatusMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineUpdateStatusMessage.ProtoReflect.Descriptor instead. func (*PipelineUpdateStatusMessage) Descriptor() ([]byte, []int) { - return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{5} + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{6} } func (x *PipelineUpdateStatusMessage) GetUpdate() *PipelineUpdateMessage { @@ -553,7 +616,7 @@ type PipelineUpdateStatusResponse struct { func (x *PipelineUpdateStatusResponse) Reset() { *x = PipelineUpdateStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mlops_chainer_chainer_proto_msgTypes[6] + mi := &file_mlops_chainer_chainer_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -566,7 +629,7 @@ func (x *PipelineUpdateStatusResponse) String() string { func (*PipelineUpdateStatusResponse) ProtoMessage() {} func (x *PipelineUpdateStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_mlops_chainer_chainer_proto_msgTypes[6] + mi := &file_mlops_chainer_chainer_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -579,7 +642,7 @@ func (x *PipelineUpdateStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PipelineUpdateStatusResponse.ProtoReflect.Descriptor instead. func (*PipelineUpdateStatusResponse) Descriptor() ([]byte, []int) { - return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{6} + return file_mlops_chainer_chainer_proto_rawDescGZIP(), []int{7} } var File_mlops_chainer_chainer_proto protoreflect.FileDescriptor @@ -610,7 +673,7 @@ var file_mlops_chainer_chainer_proto_rawDesc = []byte{ 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x10, 0x02, 0x22, 0xff, 0x05, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x65, 0x74, 0x65, 0x10, 0x02, 0x22, 0xb5, 0x05, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, @@ -640,71 +703,75 @@ var file_mlops_chainer_chainer_proto_rawDesc = []byte{ 0x08, 0x52, 0x12, 0x70, 0x61, 0x73, 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x6a, - 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x55, + 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x49, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x37, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, + 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, - 0x65, 0x53, 0x74, 0x65, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x65, 0x6e, 0x73, - 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, - 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x31, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, - 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, - 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3e, 0x0a, 0x10, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, - 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, - 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x10, 0x02, 0x12, 0x07, 0x0a, - 0x03, 0x41, 0x6e, 0x79, 0x10, 0x03, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x57, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x51, 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, - 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x6f, 0x70, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x71, 0x0a, 0x05, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x48, 0x00, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, - 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, - 0x52, 0x08, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x94, 0x01, - 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, - 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, - 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x1e, 0x0a, 0x1c, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x89, 0x02, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x12, 0x7e, 0x0a, 0x18, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x73, - 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, - 0x12, 0x7e, 0x0a, 0x13, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, - 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, - 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x32, 0x2e, 0x73, 0x65, 0x6c, - 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x42, 0x53, 0x0a, 0x17, 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, - 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5a, 0x38, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x69, 0x6f, - 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, - 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x09, + 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x31, 0x0a, 0x05, 0x62, 0x61, 0x74, + 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, + 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x22, 0x3e, 0x0a, 0x10, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, + 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x75, 0x74, 0x65, + 0x72, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x10, 0x03, 0x42, 0x0f, 0x0a, 0x0d, + 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x83, 0x01, + 0x0a, 0x15, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, + 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x74, + 0x6f, 0x70, 0x69, 0x63, 0x41, 0x6e, 0x64, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x41, 0x6e, 0x64, 0x54, 0x65, 0x6e, + 0x73, 0x6f, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0x51, 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, + 0x6f, 0x70, 0x69, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x69, + 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x71, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x08, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6c, + 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x6c, + 0x69, 0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x0b, 0x0a, 0x09, + 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x94, 0x01, 0x0a, 0x1b, 0x50, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, + 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x22, 0x1e, 0x0a, 0x1c, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x32, 0x89, 0x02, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x7e, 0x0a, 0x18, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, + 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x65, + 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x7e, 0x0a, 0x13, + 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, + 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x32, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, + 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x53, 0x0a, 0x17, + 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x69, 0x6f, 0x2f, 0x73, 0x65, 0x6c, + 0x64, 0x6f, 0x6e, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, + 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -727,27 +794,27 @@ var file_mlops_chainer_chainer_proto_goTypes = []interface{}{ (*PipelineSubscriptionRequest)(nil), // 2: seldon.mlops.chainer.PipelineSubscriptionRequest (*PipelineUpdateMessage)(nil), // 3: seldon.mlops.chainer.PipelineUpdateMessage (*PipelineStepUpdate)(nil), // 4: seldon.mlops.chainer.PipelineStepUpdate - (*PipelineTopic)(nil), // 5: seldon.mlops.chainer.PipelineTopic - (*Batch)(nil), // 6: seldon.mlops.chainer.Batch - (*PipelineUpdateStatusMessage)(nil), // 7: seldon.mlops.chainer.PipelineUpdateStatusMessage - (*PipelineUpdateStatusResponse)(nil), // 8: seldon.mlops.chainer.PipelineUpdateStatusResponse - nil, // 9: seldon.mlops.chainer.PipelineStepUpdate.TensorMapEntry + (*PipelineTensorMapping)(nil), // 5: seldon.mlops.chainer.PipelineTensorMapping + (*PipelineTopic)(nil), // 6: seldon.mlops.chainer.PipelineTopic + (*Batch)(nil), // 7: seldon.mlops.chainer.Batch + (*PipelineUpdateStatusMessage)(nil), // 8: seldon.mlops.chainer.PipelineUpdateStatusMessage + (*PipelineUpdateStatusResponse)(nil), // 9: seldon.mlops.chainer.PipelineUpdateStatusResponse } var file_mlops_chainer_chainer_proto_depIdxs = []int32{ 0, // 0: seldon.mlops.chainer.PipelineUpdateMessage.op:type_name -> seldon.mlops.chainer.PipelineUpdateMessage.PipelineOperation 4, // 1: seldon.mlops.chainer.PipelineUpdateMessage.updates:type_name -> seldon.mlops.chainer.PipelineStepUpdate - 5, // 2: seldon.mlops.chainer.PipelineStepUpdate.sources:type_name -> seldon.mlops.chainer.PipelineTopic - 5, // 3: seldon.mlops.chainer.PipelineStepUpdate.triggers:type_name -> seldon.mlops.chainer.PipelineTopic - 5, // 4: seldon.mlops.chainer.PipelineStepUpdate.sink:type_name -> seldon.mlops.chainer.PipelineTopic + 6, // 2: seldon.mlops.chainer.PipelineStepUpdate.sources:type_name -> seldon.mlops.chainer.PipelineTopic + 6, // 3: seldon.mlops.chainer.PipelineStepUpdate.triggers:type_name -> seldon.mlops.chainer.PipelineTopic + 6, // 4: seldon.mlops.chainer.PipelineStepUpdate.sink:type_name -> seldon.mlops.chainer.PipelineTopic 1, // 5: seldon.mlops.chainer.PipelineStepUpdate.inputJoinTy:type_name -> seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType 1, // 6: seldon.mlops.chainer.PipelineStepUpdate.triggersJoinTy:type_name -> seldon.mlops.chainer.PipelineStepUpdate.PipelineJoinType - 9, // 7: seldon.mlops.chainer.PipelineStepUpdate.tensorMap:type_name -> seldon.mlops.chainer.PipelineStepUpdate.TensorMapEntry - 6, // 8: seldon.mlops.chainer.PipelineStepUpdate.batch:type_name -> seldon.mlops.chainer.Batch + 5, // 7: seldon.mlops.chainer.PipelineStepUpdate.tensorMap:type_name -> seldon.mlops.chainer.PipelineTensorMapping + 7, // 8: seldon.mlops.chainer.PipelineStepUpdate.batch:type_name -> seldon.mlops.chainer.Batch 3, // 9: seldon.mlops.chainer.PipelineUpdateStatusMessage.update:type_name -> seldon.mlops.chainer.PipelineUpdateMessage 2, // 10: seldon.mlops.chainer.Chainer.SubscribePipelineUpdates:input_type -> seldon.mlops.chainer.PipelineSubscriptionRequest - 7, // 11: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:input_type -> seldon.mlops.chainer.PipelineUpdateStatusMessage + 8, // 11: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:input_type -> seldon.mlops.chainer.PipelineUpdateStatusMessage 3, // 12: seldon.mlops.chainer.Chainer.SubscribePipelineUpdates:output_type -> seldon.mlops.chainer.PipelineUpdateMessage - 8, // 13: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:output_type -> seldon.mlops.chainer.PipelineUpdateStatusResponse + 9, // 13: seldon.mlops.chainer.Chainer.PipelineUpdateEvent:output_type -> seldon.mlops.chainer.PipelineUpdateStatusResponse 12, // [12:14] is the sub-list for method output_type 10, // [10:12] is the sub-list for method input_type 10, // [10:10] is the sub-list for extension type_name @@ -798,7 +865,7 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineTopic); i { + switch v := v.(*PipelineTensorMapping); i { case 0: return &v.state case 1: @@ -810,7 +877,7 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Batch); i { + switch v := v.(*PipelineTopic); i { case 0: return &v.state case 1: @@ -822,7 +889,7 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PipelineUpdateStatusMessage); i { + switch v := v.(*Batch); i { case 0: return &v.state case 1: @@ -834,6 +901,18 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PipelineUpdateStatusMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mlops_chainer_chainer_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PipelineUpdateStatusResponse); i { case 0: return &v.state @@ -847,7 +926,7 @@ func file_mlops_chainer_chainer_proto_init() { } } file_mlops_chainer_chainer_proto_msgTypes[2].OneofWrappers = []interface{}{} - file_mlops_chainer_chainer_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_mlops_chainer_chainer_proto_msgTypes[5].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/apis/mlops/chainer/chainer.proto b/apis/mlops/chainer/chainer.proto index 727b42d7c0..5f9c62442d 100644 --- a/apis/mlops/chainer/chainer.proto +++ b/apis/mlops/chainer/chainer.proto @@ -39,10 +39,16 @@ message PipelineStepUpdate { PipelineJoinType triggersJoinTy = 5; bool passEmptyResponses = 6; // Forward empty response to following steps, default false optional uint32 joinWindowMs = 7; // Join window millisecs, some nozero default (TBD) - map tensorMap = 8; // optional map of tensor name mappings + repeated PipelineTensorMapping tensorMap = 8; // optional list of tensor name mappings Batch batch = 9; // Batch settings } +message PipelineTensorMapping { + string pipelineName = 1; + string topicAndTensor = 2; + string tensorName = 3; +} + message PipelineTopic { string pipelineName = 1; string topicName = 2; diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java index 4311e44f51..b84a9ee87c 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/ChainerOuterClass.java @@ -2094,57 +2094,47 @@ io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopicOrBuilder getTriggersOrBu /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - int getTensorMapCount(); + java.util.List + getTensorMapList(); /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; - */ - boolean containsTensorMap( - java.lang.String key); - /** - * Use {@link #getTensorMapMap()} instead. + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - @java.lang.Deprecated - java.util.Map - getTensorMap(); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping getTensorMap(int index); /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - java.util.Map - getTensorMapMap(); + int getTensorMapCount(); /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - /* nullable */ -java.lang.String getTensorMapOrDefault( - java.lang.String key, - /* nullable */ -java.lang.String defaultValue); + java.util.List + getTensorMapOrBuilderList(); /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - java.lang.String getTensorMapOrThrow( - java.lang.String key); + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMappingOrBuilder getTensorMapOrBuilder( + int index); /** *
@@ -2190,6 +2180,7 @@ private PipelineStepUpdate() {
       triggers_ = java.util.Collections.emptyList();
       inputJoinTy_ = 0;
       triggersJoinTy_ = 0;
+      tensorMap_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
@@ -2209,18 +2200,6 @@ protected java.lang.Object newInstance(
       return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineStepUpdate_descriptor;
     }
 
-    @SuppressWarnings({"rawtypes"})
-    @java.lang.Override
-    protected com.google.protobuf.MapField internalGetMapField(
-        int number) {
-      switch (number) {
-        case 8:
-          return internalGetTensorMap();
-        default:
-          throw new RuntimeException(
-              "Invalid map field number: " + number);
-      }
-    }
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
@@ -2573,98 +2552,64 @@ public int getJoinWindowMs() {
     }
 
     public static final int TENSORMAP_FIELD_NUMBER = 8;
-    private static final class TensorMapDefaultEntryHolder {
-      static final com.google.protobuf.MapEntry<
-          java.lang.String, java.lang.String> defaultEntry =
-              com.google.protobuf.MapEntry
-              .newDefaultInstance(
-                  io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_descriptor, 
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "");
-    }
     @SuppressWarnings("serial")
-    private com.google.protobuf.MapField<
-        java.lang.String, java.lang.String> tensorMap_;
-    private com.google.protobuf.MapField
-    internalGetTensorMap() {
-      if (tensorMap_ == null) {
-        return com.google.protobuf.MapField.emptyMapField(
-            TensorMapDefaultEntryHolder.defaultEntry);
-      }
-      return tensorMap_;
-    }
-    public int getTensorMapCount() {
-      return internalGetTensorMap().getMap().size();
-    }
+    private java.util.List tensorMap_;
     /**
      * 
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ @java.lang.Override - public boolean containsTensorMap( - java.lang.String key) { - if (key == null) { throw new NullPointerException("map key"); } - return internalGetTensorMap().getMap().containsKey(key); + public java.util.List getTensorMapList() { + return tensorMap_; } /** - * Use {@link #getTensorMapMap()} instead. + *
+     * optional list of tensor name mappings
+     * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ @java.lang.Override - @java.lang.Deprecated - public java.util.Map getTensorMap() { - return getTensorMapMap(); + public java.util.List + getTensorMapOrBuilderList() { + return tensorMap_; } /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ @java.lang.Override - public java.util.Map getTensorMapMap() { - return internalGetTensorMap().getMap(); + public int getTensorMapCount() { + return tensorMap_.size(); } /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ @java.lang.Override - public /* nullable */ -java.lang.String getTensorMapOrDefault( - java.lang.String key, - /* nullable */ -java.lang.String defaultValue) { - if (key == null) { throw new NullPointerException("map key"); } - java.util.Map map = - internalGetTensorMap().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping getTensorMap(int index) { + return tensorMap_.get(index); } /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ @java.lang.Override - public java.lang.String getTensorMapOrThrow( - java.lang.String key) { - if (key == null) { throw new NullPointerException("map key"); } - java.util.Map map = - internalGetTensorMap().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); - } - return map.get(key); + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMappingOrBuilder getTensorMapOrBuilder( + int index) { + return tensorMap_.get(index); } public static final int BATCH_FIELD_NUMBER = 9; @@ -2740,12 +2685,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (((bitField0_ & 0x00000001) != 0)) { output.writeUInt32(7, joinWindowMs_); } - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetTensorMap(), - TensorMapDefaultEntryHolder.defaultEntry, - 8); + for (int i = 0; i < tensorMap_.size(); i++) { + output.writeMessage(8, tensorMap_.get(i)); + } if (batch_ != null) { output.writeMessage(9, getBatch()); } @@ -2786,15 +2728,9 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeUInt32Size(7, joinWindowMs_); } - for (java.util.Map.Entry entry - : internalGetTensorMap().getMap().entrySet()) { - com.google.protobuf.MapEntry - tensorMap__ = TensorMapDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); + for (int i = 0; i < tensorMap_.size(); i++) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(8, tensorMap__); + .computeMessageSize(8, tensorMap_.get(i)); } if (batch_ != null) { size += com.google.protobuf.CodedOutputStream @@ -2833,8 +2769,8 @@ public boolean equals(final java.lang.Object obj) { if (getJoinWindowMs() != other.getJoinWindowMs()) return false; } - if (!internalGetTensorMap().equals( - other.internalGetTensorMap())) return false; + if (!getTensorMapList() + .equals(other.getTensorMapList())) return false; if (hasBatch() != other.hasBatch()) return false; if (hasBatch()) { if (!getBatch() @@ -2874,9 +2810,9 @@ public int hashCode() { hash = (37 * hash) + JOINWINDOWMS_FIELD_NUMBER; hash = (53 * hash) + getJoinWindowMs(); } - if (!internalGetTensorMap().getMap().isEmpty()) { + if (getTensorMapCount() > 0) { hash = (37 * hash) + TENSORMAP_FIELD_NUMBER; - hash = (53 * hash) + internalGetTensorMap().hashCode(); + hash = (53 * hash) + getTensorMapList().hashCode(); } if (hasBatch()) { hash = (37 * hash) + BATCH_FIELD_NUMBER; @@ -2989,28 +2925,6 @@ public static final class Builder extends return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineStepUpdate_descriptor; } - @SuppressWarnings({"rawtypes"}) - protected com.google.protobuf.MapField internalGetMapField( - int number) { - switch (number) { - case 8: - return internalGetTensorMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @SuppressWarnings({"rawtypes"}) - protected com.google.protobuf.MapField internalGetMutableMapField( - int number) { - switch (number) { - case 8: - return internalGetMutableTensorMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { @@ -3056,7 +2970,13 @@ public Builder clear() { triggersJoinTy_ = 0; passEmptyResponses_ = false; joinWindowMs_ = 0; - internalGetMutableTensorMap().clear(); + if (tensorMapBuilder_ == null) { + tensorMap_ = java.util.Collections.emptyList(); + } else { + tensorMap_ = null; + tensorMapBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000080); batch_ = null; if (batchBuilder_ != null) { batchBuilder_.dispose(); @@ -3113,6 +3033,15 @@ private void buildPartialRepeatedFields(io.seldon.mlops.chainer.ChainerOuterClas } else { result.triggers_ = triggersBuilder_.build(); } + if (tensorMapBuilder_ == null) { + if (((bitField0_ & 0x00000080) != 0)) { + tensorMap_ = java.util.Collections.unmodifiableList(tensorMap_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.tensorMap_ = tensorMap_; + } else { + result.tensorMap_ = tensorMapBuilder_.build(); + } } private void buildPartial0(io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate result) { @@ -3136,10 +3065,6 @@ private void buildPartial0(io.seldon.mlops.chainer.ChainerOuterClass.PipelineSte result.joinWindowMs_ = joinWindowMs_; to_bitField0_ |= 0x00000001; } - if (((from_bitField0_ & 0x00000080) != 0)) { - result.tensorMap_ = internalGetTensorMap(); - result.tensorMap_.makeImmutable(); - } if (((from_bitField0_ & 0x00000100) != 0)) { result.batch_ = batchBuilder_ == null ? batch_ @@ -3259,9 +3184,32 @@ public Builder mergeFrom(io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepU if (other.hasJoinWindowMs()) { setJoinWindowMs(other.getJoinWindowMs()); } - internalGetMutableTensorMap().mergeFrom( - other.internalGetTensorMap()); - bitField0_ |= 0x00000080; + if (tensorMapBuilder_ == null) { + if (!other.tensorMap_.isEmpty()) { + if (tensorMap_.isEmpty()) { + tensorMap_ = other.tensorMap_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureTensorMapIsMutable(); + tensorMap_.addAll(other.tensorMap_); + } + onChanged(); + } + } else { + if (!other.tensorMap_.isEmpty()) { + if (tensorMapBuilder_.isEmpty()) { + tensorMapBuilder_.dispose(); + tensorMapBuilder_ = null; + tensorMap_ = other.tensorMap_; + bitField0_ = (bitField0_ & ~0x00000080); + tensorMapBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getTensorMapFieldBuilder() : null; + } else { + tensorMapBuilder_.addAllMessages(other.tensorMap_); + } + } + } if (other.hasBatch()) { mergeBatch(other.getBatch()); } @@ -3345,12 +3293,16 @@ public Builder mergeFrom( break; } // case 56 case 66: { - com.google.protobuf.MapEntry - tensorMap__ = input.readMessage( - TensorMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - internalGetMutableTensorMap().getMutableMap().put( - tensorMap__.getKey(), tensorMap__.getValue()); - bitField0_ |= 0x00000080; + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping m = + input.readMessage( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.parser(), + extensionRegistry); + if (tensorMapBuilder_ == null) { + ensureTensorMapIsMutable(); + tensorMap_.add(m); + } else { + tensorMapBuilder_.addMessage(m); + } break; } // case 66 case 74: { @@ -4290,314 +4242,1322 @@ public Builder clearJoinWindowMs() { return this; } - private com.google.protobuf.MapField< - java.lang.String, java.lang.String> tensorMap_; - private com.google.protobuf.MapField - internalGetTensorMap() { - if (tensorMap_ == null) { - return com.google.protobuf.MapField.emptyMapField( - TensorMapDefaultEntryHolder.defaultEntry); + private java.util.List tensorMap_ = + java.util.Collections.emptyList(); + private void ensureTensorMapIsMutable() { + if (!((bitField0_ & 0x00000080) != 0)) { + tensorMap_ = new java.util.ArrayList(tensorMap_); + bitField0_ |= 0x00000080; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMappingOrBuilder> tensorMapBuilder_; + + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public java.util.List getTensorMapList() { + if (tensorMapBuilder_ == null) { + return java.util.Collections.unmodifiableList(tensorMap_); + } else { + return tensorMapBuilder_.getMessageList(); } - return tensorMap_; } - private com.google.protobuf.MapField - internalGetMutableTensorMap() { - if (tensorMap_ == null) { - tensorMap_ = com.google.protobuf.MapField.newMapField( - TensorMapDefaultEntryHolder.defaultEntry); + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public int getTensorMapCount() { + if (tensorMapBuilder_ == null) { + return tensorMap_.size(); + } else { + return tensorMapBuilder_.getCount(); } - if (!tensorMap_.isMutable()) { - tensorMap_ = tensorMap_.copy(); + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping getTensorMap(int index) { + if (tensorMapBuilder_ == null) { + return tensorMap_.get(index); + } else { + return tensorMapBuilder_.getMessage(index); } - bitField0_ |= 0x00000080; - onChanged(); - return tensorMap_; } - public int getTensorMapCount() { - return internalGetTensorMap().getMap().size(); + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public Builder setTensorMap( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping value) { + if (tensorMapBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTensorMapIsMutable(); + tensorMap_.set(index, value); + onChanged(); + } else { + tensorMapBuilder_.setMessage(index, value); + } + return this; } /** *
-       * optional map of tensor name mappings
+       * optional list of tensor name mappings
        * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - @java.lang.Override - public boolean containsTensorMap( - java.lang.String key) { - if (key == null) { throw new NullPointerException("map key"); } - return internalGetTensorMap().getMap().containsKey(key); + public Builder setTensorMap( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder builderForValue) { + if (tensorMapBuilder_ == null) { + ensureTensorMapIsMutable(); + tensorMap_.set(index, builderForValue.build()); + onChanged(); + } else { + tensorMapBuilder_.setMessage(index, builderForValue.build()); + } + return this; } /** - * Use {@link #getTensorMapMap()} instead. + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - @java.lang.Override - @java.lang.Deprecated - public java.util.Map getTensorMap() { - return getTensorMapMap(); + public Builder addTensorMap(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping value) { + if (tensorMapBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTensorMapIsMutable(); + tensorMap_.add(value); + onChanged(); + } else { + tensorMapBuilder_.addMessage(value); + } + return this; } /** *
-       * optional map of tensor name mappings
+       * optional list of tensor name mappings
        * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - @java.lang.Override - public java.util.Map getTensorMapMap() { - return internalGetTensorMap().getMap(); + public Builder addTensorMap( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping value) { + if (tensorMapBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTensorMapIsMutable(); + tensorMap_.add(index, value); + onChanged(); + } else { + tensorMapBuilder_.addMessage(index, value); + } + return this; } /** *
-       * optional map of tensor name mappings
+       * optional list of tensor name mappings
        * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - @java.lang.Override - public /* nullable */ -java.lang.String getTensorMapOrDefault( - java.lang.String key, - /* nullable */ -java.lang.String defaultValue) { - if (key == null) { throw new NullPointerException("map key"); } - java.util.Map map = - internalGetTensorMap().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; + public Builder addTensorMap( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder builderForValue) { + if (tensorMapBuilder_ == null) { + ensureTensorMapIsMutable(); + tensorMap_.add(builderForValue.build()); + onChanged(); + } else { + tensorMapBuilder_.addMessage(builderForValue.build()); + } + return this; } /** *
-       * optional map of tensor name mappings
+       * optional list of tensor name mappings
        * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - @java.lang.Override - public java.lang.String getTensorMapOrThrow( - java.lang.String key) { - if (key == null) { throw new NullPointerException("map key"); } - java.util.Map map = - internalGetTensorMap().getMap(); - if (!map.containsKey(key)) { - throw new java.lang.IllegalArgumentException(); + public Builder addTensorMap( + int index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder builderForValue) { + if (tensorMapBuilder_ == null) { + ensureTensorMapIsMutable(); + tensorMap_.add(index, builderForValue.build()); + onChanged(); + } else { + tensorMapBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public Builder addAllTensorMap( + java.lang.Iterable values) { + if (tensorMapBuilder_ == null) { + ensureTensorMapIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, tensorMap_); + onChanged(); + } else { + tensorMapBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public Builder clearTensorMap() { + if (tensorMapBuilder_ == null) { + tensorMap_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + } else { + tensorMapBuilder_.clear(); + } + return this; + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public Builder removeTensorMap(int index) { + if (tensorMapBuilder_ == null) { + ensureTensorMapIsMutable(); + tensorMap_.remove(index); + onChanged(); + } else { + tensorMapBuilder_.remove(index); + } + return this; + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder getTensorMapBuilder( + int index) { + return getTensorMapFieldBuilder().getBuilder(index); + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMappingOrBuilder getTensorMapOrBuilder( + int index) { + if (tensorMapBuilder_ == null) { + return tensorMap_.get(index); } else { + return tensorMapBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public java.util.List + getTensorMapOrBuilderList() { + if (tensorMapBuilder_ != null) { + return tensorMapBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(tensorMap_); + } + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder addTensorMapBuilder() { + return getTensorMapFieldBuilder().addBuilder( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.getDefaultInstance()); + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder addTensorMapBuilder( + int index) { + return getTensorMapFieldBuilder().addBuilder( + index, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.getDefaultInstance()); + } + /** + *
+       * optional list of tensor name mappings
+       * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + public java.util.List + getTensorMapBuilderList() { + return getTensorMapFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMappingOrBuilder> + getTensorMapFieldBuilder() { + if (tensorMapBuilder_ == null) { + tensorMapBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMappingOrBuilder>( + tensorMap_, + ((bitField0_ & 0x00000080) != 0), + getParentForChildren(), + isClean()); + tensorMap_ = null; + } + return tensorMapBuilder_; + } + + private io.seldon.mlops.chainer.ChainerOuterClass.Batch batch_; + private com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> batchBuilder_; + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + * @return Whether the batch field is set. + */ + public boolean hasBatch() { + return ((bitField0_ & 0x00000100) != 0); + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + * @return The batch. + */ + public io.seldon.mlops.chainer.ChainerOuterClass.Batch getBatch() { + if (batchBuilder_ == null) { + return batch_ == null ? io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; + } else { + return batchBuilder_.getMessage(); + } + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder setBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { + if (batchBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + batch_ = value; + } else { + batchBuilder_.setMessage(value); + } + bitField0_ |= 0x00000100; + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder setBatch( + io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder builderForValue) { + if (batchBuilder_ == null) { + batch_ = builderForValue.build(); + } else { + batchBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000100; + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder mergeBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { + if (batchBuilder_ == null) { + if (((bitField0_ & 0x00000100) != 0) && + batch_ != null && + batch_ != io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance()) { + getBatchBuilder().mergeFrom(value); + } else { + batch_ = value; + } + } else { + batchBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000100; + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public Builder clearBatch() { + bitField0_ = (bitField0_ & ~0x00000100); + batch_ = null; + if (batchBuilder_ != null) { + batchBuilder_.dispose(); + batchBuilder_ = null; + } + onChanged(); + return this; + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder getBatchBuilder() { + bitField0_ |= 0x00000100; + onChanged(); + return getBatchFieldBuilder().getBuilder(); + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + public io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder getBatchOrBuilder() { + if (batchBuilder_ != null) { + return batchBuilder_.getMessageOrBuilder(); + } else { + return batch_ == null ? + io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; + } + } + /** + *
+       * Batch settings
+       * 
+ * + * .seldon.mlops.chainer.Batch batch = 9; + */ + private com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> + getBatchFieldBuilder() { + if (batchBuilder_ == null) { + batchBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder>( + getBatch(), + getParentForChildren(), + isClean()); + batch_ = null; + } + return batchBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:seldon.mlops.chainer.PipelineStepUpdate) + } + + // @@protoc_insertion_point(class_scope:seldon.mlops.chainer.PipelineStepUpdate) + private static final io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate(); + } + + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PipelineStepUpdate parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PipelineTensorMappingOrBuilder extends + // @@protoc_insertion_point(interface_extends:seldon.mlops.chainer.PipelineTensorMapping) + com.google.protobuf.MessageOrBuilder { + + /** + * string pipelineName = 1; + * @return The pipelineName. + */ + java.lang.String getPipelineName(); + /** + * string pipelineName = 1; + * @return The bytes for pipelineName. + */ + com.google.protobuf.ByteString + getPipelineNameBytes(); + + /** + * string topicAndTensor = 2; + * @return The topicAndTensor. + */ + java.lang.String getTopicAndTensor(); + /** + * string topicAndTensor = 2; + * @return The bytes for topicAndTensor. + */ + com.google.protobuf.ByteString + getTopicAndTensorBytes(); + + /** + * string tensorName = 3; + * @return The tensorName. + */ + java.lang.String getTensorName(); + /** + * string tensorName = 3; + * @return The bytes for tensorName. + */ + com.google.protobuf.ByteString + getTensorNameBytes(); + } + /** + * Protobuf type {@code seldon.mlops.chainer.PipelineTensorMapping} + */ + public static final class PipelineTensorMapping extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:seldon.mlops.chainer.PipelineTensorMapping) + PipelineTensorMappingOrBuilder { + private static final long serialVersionUID = 0L; + // Use PipelineTensorMapping.newBuilder() to construct. + private PipelineTensorMapping(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PipelineTensorMapping() { + pipelineName_ = ""; + topicAndTensor_ = ""; + tensorName_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new PipelineTensorMapping(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTensorMapping_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTensorMapping_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.class, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder.class); + } + + public static final int PIPELINENAME_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private volatile java.lang.Object pipelineName_ = ""; + /** + * string pipelineName = 1; + * @return The pipelineName. + */ + @java.lang.Override + public java.lang.String getPipelineName() { + java.lang.Object ref = pipelineName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + pipelineName_ = s; + return s; + } + } + /** + * string pipelineName = 1; + * @return The bytes for pipelineName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getPipelineNameBytes() { + java.lang.Object ref = pipelineName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + pipelineName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TOPICANDTENSOR_FIELD_NUMBER = 2; + @SuppressWarnings("serial") + private volatile java.lang.Object topicAndTensor_ = ""; + /** + * string topicAndTensor = 2; + * @return The topicAndTensor. + */ + @java.lang.Override + public java.lang.String getTopicAndTensor() { + java.lang.Object ref = topicAndTensor_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + topicAndTensor_ = s; + return s; + } + } + /** + * string topicAndTensor = 2; + * @return The bytes for topicAndTensor. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getTopicAndTensorBytes() { + java.lang.Object ref = topicAndTensor_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + topicAndTensor_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TENSORNAME_FIELD_NUMBER = 3; + @SuppressWarnings("serial") + private volatile java.lang.Object tensorName_ = ""; + /** + * string tensorName = 3; + * @return The tensorName. + */ + @java.lang.Override + public java.lang.String getTensorName() { + java.lang.Object ref = tensorName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + tensorName_ = s; + return s; + } + } + /** + * string tensorName = 3; + * @return The bytes for tensorName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getTensorNameBytes() { + java.lang.Object ref = tensorName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + tensorName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(pipelineName_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, pipelineName_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(topicAndTensor_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, topicAndTensor_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(tensorName_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, tensorName_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(pipelineName_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, pipelineName_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(topicAndTensor_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, topicAndTensor_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(tensorName_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, tensorName_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping)) { + return super.equals(obj); + } + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping other = (io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping) obj; + + if (!getPipelineName() + .equals(other.getPipelineName())) return false; + if (!getTopicAndTensor() + .equals(other.getTopicAndTensor())) return false; + if (!getTensorName() + .equals(other.getTensorName())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + PIPELINENAME_FIELD_NUMBER; + hash = (53 * hash) + getPipelineName().hashCode(); + hash = (37 * hash) + TOPICANDTENSOR_FIELD_NUMBER; + hash = (53 * hash) + getTopicAndTensor().hashCode(); + hash = (37 * hash) + TENSORNAME_FIELD_NUMBER; + hash = (53 * hash) + getTensorName().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code seldon.mlops.chainer.PipelineTensorMapping} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:seldon.mlops.chainer.PipelineTensorMapping) + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMappingOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTensorMapping_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTensorMapping_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.class, io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder.class); + } + + // Construct using io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + pipelineName_ = ""; + topicAndTensor_ = ""; + tensorName_ = ""; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return io.seldon.mlops.chainer.ChainerOuterClass.internal_static_seldon_mlops_chainer_PipelineTensorMapping_descriptor; + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping getDefaultInstanceForType() { + return io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.getDefaultInstance(); + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping build() { + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping buildPartial() { + io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping result = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.pipelineName_ = pipelineName_; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.topicAndTensor_ = topicAndTensor_; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.tensorName_ = tensorName_; + } + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping) { + return mergeFrom((io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping other) { + if (other == io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.getDefaultInstance()) return this; + if (!other.getPipelineName().isEmpty()) { + pipelineName_ = other.pipelineName_; + bitField0_ |= 0x00000001; + onChanged(); + } + if (!other.getTopicAndTensor().isEmpty()) { + topicAndTensor_ = other.topicAndTensor_; + bitField0_ |= 0x00000002; + onChanged(); + } + if (!other.getTensorName().isEmpty()) { + tensorName_ = other.tensorName_; + bitField0_ |= 0x00000004; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + pipelineName_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: { + topicAndTensor_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 26: { + tensorName_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000004; + break; + } // case 26 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.lang.Object pipelineName_ = ""; + /** + * string pipelineName = 1; + * @return The pipelineName. + */ + public java.lang.String getPipelineName() { + java.lang.Object ref = pipelineName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + pipelineName_ = s; + return s; + } else { + return (java.lang.String) ref; } - return map.get(key); - } - public Builder clearTensorMap() { - bitField0_ = (bitField0_ & ~0x00000080); - internalGetMutableTensorMap().getMutableMap() - .clear(); - return this; } /** - *
-       * optional map of tensor name mappings
-       * 
- * - * map<string, string> tensorMap = 8; + * string pipelineName = 1; + * @return The bytes for pipelineName. */ - public Builder removeTensorMap( - java.lang.String key) { - if (key == null) { throw new NullPointerException("map key"); } - internalGetMutableTensorMap().getMutableMap() - .remove(key); - return this; + public com.google.protobuf.ByteString + getPipelineNameBytes() { + java.lang.Object ref = pipelineName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + pipelineName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } } /** - * Use alternate mutation accessors instead. + * string pipelineName = 1; + * @param value The pipelineName to set. + * @return This builder for chaining. */ - @java.lang.Deprecated - public java.util.Map - getMutableTensorMap() { - bitField0_ |= 0x00000080; - return internalGetMutableTensorMap().getMutableMap(); + public Builder setPipelineName( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + pipelineName_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; } /** - *
-       * optional map of tensor name mappings
-       * 
- * - * map<string, string> tensorMap = 8; + * string pipelineName = 1; + * @return This builder for chaining. */ - public Builder putTensorMap( - java.lang.String key, - java.lang.String value) { - if (key == null) { throw new NullPointerException("map key"); } - if (value == null) { throw new NullPointerException("map value"); } - internalGetMutableTensorMap().getMutableMap() - .put(key, value); - bitField0_ |= 0x00000080; + public Builder clearPipelineName() { + pipelineName_ = getDefaultInstance().getPipelineName(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); return this; } /** - *
-       * optional map of tensor name mappings
-       * 
- * - * map<string, string> tensorMap = 8; + * string pipelineName = 1; + * @param value The bytes for pipelineName to set. + * @return This builder for chaining. */ - public Builder putAllTensorMap( - java.util.Map values) { - internalGetMutableTensorMap().getMutableMap() - .putAll(values); - bitField0_ |= 0x00000080; + public Builder setPipelineNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + pipelineName_ = value; + bitField0_ |= 0x00000001; + onChanged(); return this; } - private io.seldon.mlops.chainer.ChainerOuterClass.Batch batch_; - private com.google.protobuf.SingleFieldBuilderV3< - io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> batchBuilder_; + private java.lang.Object topicAndTensor_ = ""; /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; - * @return Whether the batch field is set. + * string topicAndTensor = 2; + * @return The topicAndTensor. */ - public boolean hasBatch() { - return ((bitField0_ & 0x00000100) != 0); + public java.lang.String getTopicAndTensor() { + java.lang.Object ref = topicAndTensor_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + topicAndTensor_ = s; + return s; + } else { + return (java.lang.String) ref; + } } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; - * @return The batch. + * string topicAndTensor = 2; + * @return The bytes for topicAndTensor. */ - public io.seldon.mlops.chainer.ChainerOuterClass.Batch getBatch() { - if (batchBuilder_ == null) { - return batch_ == null ? io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; + public com.google.protobuf.ByteString + getTopicAndTensorBytes() { + java.lang.Object ref = topicAndTensor_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + topicAndTensor_ = b; + return b; } else { - return batchBuilder_.getMessage(); + return (com.google.protobuf.ByteString) ref; } } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string topicAndTensor = 2; + * @param value The topicAndTensor to set. + * @return This builder for chaining. */ - public Builder setBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { - if (batchBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - batch_ = value; - } else { - batchBuilder_.setMessage(value); - } - bitField0_ |= 0x00000100; + public Builder setTopicAndTensor( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + topicAndTensor_ = value; + bitField0_ |= 0x00000002; onChanged(); return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string topicAndTensor = 2; + * @return This builder for chaining. */ - public Builder setBatch( - io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder builderForValue) { - if (batchBuilder_ == null) { - batch_ = builderForValue.build(); - } else { - batchBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000100; + public Builder clearTopicAndTensor() { + topicAndTensor_ = getDefaultInstance().getTopicAndTensor(); + bitField0_ = (bitField0_ & ~0x00000002); onChanged(); return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string topicAndTensor = 2; + * @param value The bytes for topicAndTensor to set. + * @return This builder for chaining. */ - public Builder mergeBatch(io.seldon.mlops.chainer.ChainerOuterClass.Batch value) { - if (batchBuilder_ == null) { - if (((bitField0_ & 0x00000100) != 0) && - batch_ != null && - batch_ != io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance()) { - getBatchBuilder().mergeFrom(value); - } else { - batch_ = value; - } - } else { - batchBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000100; + public Builder setTopicAndTensorBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + topicAndTensor_ = value; + bitField0_ |= 0x00000002; onChanged(); return this; } + + private java.lang.Object tensorName_ = ""; /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string tensorName = 3; + * @return The tensorName. */ - public Builder clearBatch() { - bitField0_ = (bitField0_ & ~0x00000100); - batch_ = null; - if (batchBuilder_ != null) { - batchBuilder_.dispose(); - batchBuilder_ = null; + public java.lang.String getTensorName() { + java.lang.Object ref = tensorName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + tensorName_ = s; + return s; + } else { + return (java.lang.String) ref; } - onChanged(); - return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string tensorName = 3; + * @return The bytes for tensorName. */ - public io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder getBatchBuilder() { - bitField0_ |= 0x00000100; + public com.google.protobuf.ByteString + getTensorNameBytes() { + java.lang.Object ref = tensorName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + tensorName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string tensorName = 3; + * @param value The tensorName to set. + * @return This builder for chaining. + */ + public Builder setTensorName( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + tensorName_ = value; + bitField0_ |= 0x00000004; onChanged(); - return getBatchFieldBuilder().getBuilder(); + return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string tensorName = 3; + * @return This builder for chaining. */ - public io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder getBatchOrBuilder() { - if (batchBuilder_ != null) { - return batchBuilder_.getMessageOrBuilder(); - } else { - return batch_ == null ? - io.seldon.mlops.chainer.ChainerOuterClass.Batch.getDefaultInstance() : batch_; - } + public Builder clearTensorName() { + tensorName_ = getDefaultInstance().getTensorName(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; } /** - *
-       * Batch settings
-       * 
- * - * .seldon.mlops.chainer.Batch batch = 9; + * string tensorName = 3; + * @param value The bytes for tensorName to set. + * @return This builder for chaining. */ - private com.google.protobuf.SingleFieldBuilderV3< - io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder> - getBatchFieldBuilder() { - if (batchBuilder_ == null) { - batchBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - io.seldon.mlops.chainer.ChainerOuterClass.Batch, io.seldon.mlops.chainer.ChainerOuterClass.Batch.Builder, io.seldon.mlops.chainer.ChainerOuterClass.BatchOrBuilder>( - getBatch(), - getParentForChildren(), - isClean()); - batch_ = null; - } - return batchBuilder_; + public Builder setTensorNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + tensorName_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; } @java.lang.Override public final Builder setUnknownFields( @@ -4612,23 +5572,23 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:seldon.mlops.chainer.PipelineStepUpdate) + // @@protoc_insertion_point(builder_scope:seldon.mlops.chainer.PipelineTensorMapping) } - // @@protoc_insertion_point(class_scope:seldon.mlops.chainer.PipelineStepUpdate) - private static final io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:seldon.mlops.chainer.PipelineTensorMapping) + private static final io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate(); + DEFAULT_INSTANCE = new io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping(); } - public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstance() { + public static io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping getDefaultInstance() { return DEFAULT_INSTANCE; } - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public PipelineStepUpdate parsePartialFrom( + public PipelineTensorMapping parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -4647,17 +5607,17 @@ public PipelineStepUpdate parsePartialFrom( } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate getDefaultInstanceForType() { + public io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -7347,10 +8307,10 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineUpdateStatusResponse ge com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_seldon_mlops_chainer_PipelineStepUpdate_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor - internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_descriptor; + internal_static_seldon_mlops_chainer_PipelineTensorMapping_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_fieldAccessorTable; + internal_static_seldon_mlops_chainer_PipelineTensorMapping_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_seldon_mlops_chainer_PipelineTopic_descriptor; private static final @@ -7388,7 +8348,7 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineUpdateStatusResponse ge "\t\022\017\n\007version\030\003 \001(\r\022\013\n\003uid\030\004 \001(\t\0229\n\007updat" + "es\030\005 \003(\0132(.seldon.mlops.chainer.Pipeline" + "StepUpdate\"8\n\021PipelineOperation\022\013\n\007Unkno" + - "wn\020\000\022\n\n\006Create\020\001\022\n\n\006Delete\020\002\"\211\005\n\022Pipelin" + + "wn\020\000\022\n\n\006Create\020\001\022\n\n\006Delete\020\002\"\313\004\n\022Pipelin" + "eStepUpdate\0224\n\007sources\030\001 \003(\0132#.seldon.ml" + "ops.chainer.PipelineTopic\0225\n\010triggers\030\002 " + "\003(\0132#.seldon.mlops.chainer.PipelineTopic" + @@ -7398,30 +8358,31 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineUpdateStatusResponse ge "ineJoinType\022Q\n\016triggersJoinTy\030\005 \001(\01629.se" + "ldon.mlops.chainer.PipelineStepUpdate.Pi" + "pelineJoinType\022\032\n\022passEmptyResponses\030\006 \001" + - "(\010\022\031\n\014joinWindowMs\030\007 \001(\rH\000\210\001\001\022J\n\ttensorM" + - "ap\030\010 \003(\01327.seldon.mlops.chainer.Pipeline" + - "StepUpdate.TensorMapEntry\022*\n\005batch\030\t \001(\013" + - "2\033.seldon.mlops.chainer.Batch\0320\n\016TensorM" + - "apEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"" + - ">\n\020PipelineJoinType\022\013\n\007Unknown\020\000\022\t\n\005Inne" + - "r\020\001\022\t\n\005Outer\020\002\022\007\n\003Any\020\003B\017\n\r_joinWindowMs" + - "\"8\n\rPipelineTopic\022\024\n\014pipelineName\030\001 \001(\t\022" + - "\021\n\ttopicName\030\002 \001(\t\"X\n\005Batch\022\021\n\004size\030\001 \001(" + - "\rH\000\210\001\001\022\025\n\010windowMs\030\002 \001(\rH\001\210\001\001\022\017\n\007rolling" + - "\030\003 \001(\010B\007\n\005_sizeB\013\n\t_windowMs\"{\n\033Pipeline" + - "UpdateStatusMessage\022;\n\006update\030\001 \001(\0132+.se" + - "ldon.mlops.chainer.PipelineUpdateMessage" + - "\022\017\n\007success\030\002 \001(\010\022\016\n\006reason\030\003 \001(\t\"\036\n\034Pip" + - "elineUpdateStatusResponse2\211\002\n\007Chainer\022~\n" + - "\030SubscribePipelineUpdates\0221.seldon.mlops" + - ".chainer.PipelineSubscriptionRequest\032+.s" + - "eldon.mlops.chainer.PipelineUpdateMessag" + - "e\"\0000\001\022~\n\023PipelineUpdateEvent\0221.seldon.ml" + - "ops.chainer.PipelineUpdateStatusMessage\032" + - "2.seldon.mlops.chainer.PipelineUpdateSta" + - "tusResponse\"\000BS\n\027io.seldon.mlops.chainer" + - "Z8github.com/seldonio/seldon-core/apis/g" + - "o/v2/mlops/chainerb\006proto3" + "(\010\022\031\n\014joinWindowMs\030\007 \001(\rH\000\210\001\001\022>\n\ttensorM" + + "ap\030\010 \003(\0132+.seldon.mlops.chainer.Pipeline" + + "TensorMapping\022*\n\005batch\030\t \001(\0132\033.seldon.ml" + + "ops.chainer.Batch\">\n\020PipelineJoinType\022\013\n" + + "\007Unknown\020\000\022\t\n\005Inner\020\001\022\t\n\005Outer\020\002\022\007\n\003Any\020" + + "\003B\017\n\r_joinWindowMs\"Y\n\025PipelineTensorMapp" + + "ing\022\024\n\014pipelineName\030\001 \001(\t\022\026\n\016topicAndTen" + + "sor\030\002 \001(\t\022\022\n\ntensorName\030\003 \001(\t\"8\n\rPipelin" + + "eTopic\022\024\n\014pipelineName\030\001 \001(\t\022\021\n\ttopicNam" + + "e\030\002 \001(\t\"X\n\005Batch\022\021\n\004size\030\001 \001(\rH\000\210\001\001\022\025\n\010w" + + "indowMs\030\002 \001(\rH\001\210\001\001\022\017\n\007rolling\030\003 \001(\010B\007\n\005_" + + "sizeB\013\n\t_windowMs\"{\n\033PipelineUpdateStatu" + + "sMessage\022;\n\006update\030\001 \001(\0132+.seldon.mlops." + + "chainer.PipelineUpdateMessage\022\017\n\007success" + + "\030\002 \001(\010\022\016\n\006reason\030\003 \001(\t\"\036\n\034PipelineUpdate" + + "StatusResponse2\211\002\n\007Chainer\022~\n\030SubscribeP" + + "ipelineUpdates\0221.seldon.mlops.chainer.Pi" + + "pelineSubscriptionRequest\032+.seldon.mlops" + + ".chainer.PipelineUpdateMessage\"\0000\001\022~\n\023Pi" + + "pelineUpdateEvent\0221.seldon.mlops.chainer" + + ".PipelineUpdateStatusMessage\0322.seldon.ml" + + "ops.chainer.PipelineUpdateStatusResponse" + + "\"\000BS\n\027io.seldon.mlops.chainerZ8github.co" + + "m/seldonio/seldon-core/apis/go/v2/mlops/" + + "chainerb\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -7445,32 +8406,32 @@ public io.seldon.mlops.chainer.ChainerOuterClass.PipelineUpdateStatusResponse ge com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_PipelineStepUpdate_descriptor, new java.lang.String[] { "Sources", "Triggers", "Sink", "InputJoinTy", "TriggersJoinTy", "PassEmptyResponses", "JoinWindowMs", "TensorMap", "Batch", "JoinWindowMs", }); - internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_descriptor = - internal_static_seldon_mlops_chainer_PipelineStepUpdate_descriptor.getNestedTypes().get(0); - internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_fieldAccessorTable = new + internal_static_seldon_mlops_chainer_PipelineTensorMapping_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_seldon_mlops_chainer_PipelineTensorMapping_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_seldon_mlops_chainer_PipelineStepUpdate_TensorMapEntry_descriptor, - new java.lang.String[] { "Key", "Value", }); + internal_static_seldon_mlops_chainer_PipelineTensorMapping_descriptor, + new java.lang.String[] { "PipelineName", "TopicAndTensor", "TensorName", }); internal_static_seldon_mlops_chainer_PipelineTopic_descriptor = - getDescriptor().getMessageTypes().get(3); + getDescriptor().getMessageTypes().get(4); internal_static_seldon_mlops_chainer_PipelineTopic_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_PipelineTopic_descriptor, new java.lang.String[] { "PipelineName", "TopicName", }); internal_static_seldon_mlops_chainer_Batch_descriptor = - getDescriptor().getMessageTypes().get(4); + getDescriptor().getMessageTypes().get(5); internal_static_seldon_mlops_chainer_Batch_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_Batch_descriptor, new java.lang.String[] { "Size", "WindowMs", "Rolling", "Size", "WindowMs", }); internal_static_seldon_mlops_chainer_PipelineUpdateStatusMessage_descriptor = - getDescriptor().getMessageTypes().get(5); + getDescriptor().getMessageTypes().get(6); internal_static_seldon_mlops_chainer_PipelineUpdateStatusMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_PipelineUpdateStatusMessage_descriptor, new java.lang.String[] { "Update", "Success", "Reason", }); internal_static_seldon_mlops_chainer_PipelineUpdateStatusResponse_descriptor = - getDescriptor().getMessageTypes().get(6); + getDescriptor().getMessageTypes().get(7); internal_static_seldon_mlops_chainer_PipelineUpdateStatusResponse_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_seldon_mlops_chainer_PipelineUpdateStatusResponse_descriptor, diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt index 60c053d5af..c6c0131a44 100644 --- a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt +++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineStepUpdateKt.kt @@ -335,82 +335,97 @@ public object PipelineStepUpdateKt { public class TensorMapProxy private constructor() : com.google.protobuf.kotlin.DslProxy() /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; */ - public val tensorMap: com.google.protobuf.kotlin.DslMap + public val tensorMap: com.google.protobuf.kotlin.DslList @kotlin.jvm.JvmSynthetic - @JvmName("getTensorMapMap") - get() = com.google.protobuf.kotlin.DslMap( - _builder.getTensorMapMap() + get() = com.google.protobuf.kotlin.DslList( + _builder.getTensorMapList() ) /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + * @param value The tensorMap to add. */ - @JvmName("putTensorMap") - public fun com.google.protobuf.kotlin.DslMap - .put(key: kotlin.String, value: kotlin.String) { - _builder.putTensorMap(key, value) - } + @kotlin.jvm.JvmSynthetic + @kotlin.jvm.JvmName("addTensorMap") + public fun com.google.protobuf.kotlin.DslList.add(value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping) { + _builder.addTensorMap(value) + } /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + * @param value The tensorMap to add. */ @kotlin.jvm.JvmSynthetic - @JvmName("setTensorMap") + @kotlin.jvm.JvmName("plusAssignTensorMap") @Suppress("NOTHING_TO_INLINE") - public inline operator fun com.google.protobuf.kotlin.DslMap - .set(key: kotlin.String, value: kotlin.String) { - put(key, value) - } + public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping) { + add(value) + } /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + * @param values The tensorMap to add. */ @kotlin.jvm.JvmSynthetic - @JvmName("removeTensorMap") - public fun com.google.protobuf.kotlin.DslMap - .remove(key: kotlin.String) { - _builder.removeTensorMap(key) - } + @kotlin.jvm.JvmName("addAllTensorMap") + public fun com.google.protobuf.kotlin.DslList.addAll(values: kotlin.collections.Iterable) { + _builder.addAllTensorMap(values) + } /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + * @param values The tensorMap to add. */ @kotlin.jvm.JvmSynthetic - @JvmName("putAllTensorMap") - public fun com.google.protobuf.kotlin.DslMap - .putAll(map: kotlin.collections.Map) { - _builder.putAllTensorMap(map) - } + @kotlin.jvm.JvmName("plusAssignAllTensorMap") + @Suppress("NOTHING_TO_INLINE") + public inline operator fun com.google.protobuf.kotlin.DslList.plusAssign(values: kotlin.collections.Iterable) { + addAll(values) + } /** *
-     * optional map of tensor name mappings
+     * optional list of tensor name mappings
      * 
* - * map<string, string> tensorMap = 8; + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + * @param index The index to set the value at. + * @param value The tensorMap to set. */ @kotlin.jvm.JvmSynthetic - @JvmName("clearTensorMap") - fun com.google.protobuf.kotlin.DslMap - .clear() { - _builder.clearTensorMap() - } + @kotlin.jvm.JvmName("setTensorMap") + public operator fun com.google.protobuf.kotlin.DslList.set(index: kotlin.Int, value: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping) { + _builder.setTensorMap(index, value) + } + /** + *
+     * optional list of tensor name mappings
+     * 
+ * + * repeated .seldon.mlops.chainer.PipelineTensorMapping tensorMap = 8; + */ + @kotlin.jvm.JvmSynthetic + @kotlin.jvm.JvmName("clearTensorMap") + public fun com.google.protobuf.kotlin.DslList.clear() { + _builder.clearTensorMap() + } + /** *
diff --git a/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTensorMappingKt.kt b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTensorMappingKt.kt
new file mode 100644
index 0000000000..728ed6e31a
--- /dev/null
+++ b/apis/mlops/chainer/kotlin/io/seldon/mlops/chainer/PipelineTensorMappingKt.kt
@@ -0,0 +1,80 @@
+//Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: chainer.proto
+
+package io.seldon.mlops.chainer;
+
+@kotlin.jvm.JvmName("-initializepipelineTensorMapping")
+public inline fun pipelineTensorMapping(block: io.seldon.mlops.chainer.PipelineTensorMappingKt.Dsl.() -> kotlin.Unit): io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping =
+  io.seldon.mlops.chainer.PipelineTensorMappingKt.Dsl._create(io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.newBuilder()).apply { block() }._build()
+public object PipelineTensorMappingKt {
+  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
+  @com.google.protobuf.kotlin.ProtoDslMarker
+  public class Dsl private constructor(
+    private val _builder: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder
+  ) {
+    public companion object {
+      @kotlin.jvm.JvmSynthetic
+      @kotlin.PublishedApi
+      internal fun _create(builder: io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.Builder): Dsl = Dsl(builder)
+    }
+
+    @kotlin.jvm.JvmSynthetic
+    @kotlin.PublishedApi
+    internal fun _build(): io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping = _builder.build()
+
+    /**
+     * string pipelineName = 1;
+     */
+    public var pipelineName: kotlin.String
+      @JvmName("getPipelineName")
+      get() = _builder.getPipelineName()
+      @JvmName("setPipelineName")
+      set(value) {
+        _builder.setPipelineName(value)
+      }
+    /**
+     * string pipelineName = 1;
+     */
+    public fun clearPipelineName() {
+      _builder.clearPipelineName()
+    }
+
+    /**
+     * string topicAndTensor = 2;
+     */
+    public var topicAndTensor: kotlin.String
+      @JvmName("getTopicAndTensor")
+      get() = _builder.getTopicAndTensor()
+      @JvmName("setTopicAndTensor")
+      set(value) {
+        _builder.setTopicAndTensor(value)
+      }
+    /**
+     * string topicAndTensor = 2;
+     */
+    public fun clearTopicAndTensor() {
+      _builder.clearTopicAndTensor()
+    }
+
+    /**
+     * string tensorName = 3;
+     */
+    public var tensorName: kotlin.String
+      @JvmName("getTensorName")
+      get() = _builder.getTensorName()
+      @JvmName("setTensorName")
+      set(value) {
+        _builder.setTensorName(value)
+      }
+    /**
+     * string tensorName = 3;
+     */
+    public fun clearTensorName() {
+      _builder.clearTensorName()
+    }
+  }
+}
+@kotlin.jvm.JvmSynthetic
+public inline fun io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping.copy(block: io.seldon.mlops.chainer.PipelineTensorMappingKt.Dsl.() -> kotlin.Unit): io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping =
+  io.seldon.mlops.chainer.PipelineTensorMappingKt.Dsl._create(this.toBuilder()).apply { block() }._build()
+
diff --git a/samples/img_pipeline5.jpg b/samples/img_pipeline5.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7e471c7dfc9856b238353d583f3f5f29e500f2c7
GIT binary patch
literal 84843
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�z_j;02jp{4_5*Hz87f>9r5z#+
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%0A{fzV5
za+f*P%BL(RwfY$~?#ew71YPLl52WBfk=OR+hWI2sY*yo$f*KN8NOC2{WY>p9Dp)h?
znb^OCOg}W^zF%4S;(NraavdeuLT1SF>Ct}cr2>ZAKrfH;Klz~iFWJ7{&~{`P?}c=u
zQeqoE<*M6UI{idtMHQ25B!tmEq`EWrGhjO$HXsD#7(3sPVs~PE#L@IdG`%gz@M&&h
zHr7PJ5SuTkIj&JvS6+kasu^6LyZWH=L--bVf0beUA>(run4-~}eC?{vXuwiriw
zVY}t@3K8$f=QbVm^Ox1BeG0D6%=@)3F{yEExm1@Vq4McryBe(ItKu~Dw7g3
z05O5qXRr7M_4!Ev
zd(0)WhG~V&6NeBjTDX#uli&+|iOjY{L!8`>FUm0oueL1ecd01RndxVWno^AZL21tK
zNZ;Rk)H}mF{zA%wqLuY-`jvy*hwLf7uM6{yF1(FVH=P;_%%IOov6s7gMnS(tn*d&e
zOU$hF!5<>2hg&ATY8F#(L^sNvzDdtXCp))*3VY)^VZ&!W-h6jhEWnqn?9b)m;$rW@
zlAXoaLUrMN8?yroBdF03XbWKn8D~(%{|E2*_nzi|>u=yhk}i?OdXDFTShyAKr~uxs
zRp`Pqql2S(m63J6fpIcrNNqKMV^R9aTU~WjKK`wlLbj`H5UApx4%D{MyxrHa@TP>vQp`xB9gf9#Si0M$92
zlOzCS@%5_kHL3un72C>1j4r-Cg7)K(vxd%U@<}Syx`8tF%K^^A_1ua#Hm1zHC{L;q
zFXCn*%_^&7VD{&1rHiu)pJX9UblE5+K=
zt*6u0;aH!s59OpA@BwccT-
zm@^=O3Ex_Dw=rMmIu=KDQRzh0Iz#^I0~P3G)rZcSvW>uEe${BT$c5tITyt~NAX5N>
zFJFP<5ETpHE-Pr`x6yP3uP~MFs!IV=4(!(4EqSDf(?nlnW+k)+dDBkP;$JFuPE)|tbQk9QKQBqCFZcv>JU3B#q0ZhY-Y1}SZSE(mO_@En_y7kt=0vs+3
z{9)LnHJfZ?2YQWVcIqL0up$2B^^T*(>IUV2w;BWQz5UrHPe!~YkKQi%s-S^?>I#dt
z=X|3KShWEIKv<+91^`MCT?Hd;0s#2LZB8Q49Po4v=p9A@;9k15AaeU(VEC7$@lil(
zemouM70W!llI}@y6mw|)1Jvh;Wh0-ggpn12QIu9G54m;$^^q~!EJk8;K$3h=tKUB+j~!Ejm(-ZCEutF6Gw?f33N$7U)qM>GwL
z$k|#009axO`CxFp5%wPAh&-V41F(RaJb@ruM;^H+cPjAbP5)f!|0ml+Q5y5?+{~ej
z0qoG~U-mT11H9OpSN^;XAqkrk4e^CgO-%xA<480fc_};Twq;}9OnG&Cs@GnC)Dhb6
zUSIWeRErPq>&&@P$5)Hb1B4w-X7e;wgQ~O1olxp~DO^85><Lf&&aW^-n8
zJhY+M6e=L(tX^4X-wZub%3GadZ}uR{hBZ0Uex!=^G2MIfiEHoG*tZS!Ku{GU>Vp4V
on&58*)<01e{v7(}tNOX!{ywe$)AIT$8GcHJ|8|lA^5g6O2k5>mQ~&?~

literal 0
HcmV?d00001

diff --git a/samples/pipelines/tfsimple-combined-step.yaml b/samples/pipelines/tfsimple-combined-step.yaml
new file mode 100644
index 0000000000..eed03e39c1
--- /dev/null
+++ b/samples/pipelines/tfsimple-combined-step.yaml
@@ -0,0 +1,17 @@
+apiVersion: mlops.seldon.io/v1alpha1
+kind: Pipeline
+metadata:
+  name: tfsimple-combined-step
+spec:
+  input:
+    externalInputs:
+      - tfsimple-extended.step.tfsimple2.outputs.OUTPUT0
+      - tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0
+    tensorMap:
+      tfsimple-extended.step.tfsimple2.outputs.OUTPUT0: INPUT0
+      tfsimple-extended2.step.tfsimple2.outputs.OUTPUT0: INPUT1
+  steps:
+    - name: tfsimple2
+  output:
+    steps:
+    - tfsimple2
diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt
index e07a625a44..4afa208a4c 100644
--- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt
+++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Chainer.kt
@@ -18,6 +18,7 @@ package io.seldon.dataflow.kafka
 
 import io.klogging.noCoLogger
 import io.seldon.mlops.chainer.ChainerOuterClass
+import io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping
 import org.apache.kafka.streams.StreamsBuilder
 
 /**
@@ -29,7 +30,7 @@ class Chainer(
     internal val outputTopic: TopicForPipeline,
     internal val tensors: Set?,
     internal val pipelineName: String,
-    internal val tensorRenaming: Map,
+    internal val tensorRenaming: List,
     internal val batchProperties: ChainerOuterClass.Batch,
     private val kafkaDomainParams: KafkaDomainParams,
     internal val inputTriggerTopics: Set,
@@ -78,7 +79,7 @@ class Chainer(
             .stream(inputTopic.topicName, consumerSerde)
             .filterForPipeline(inputTopic.pipelineName)
             .unmarshallInferenceV2Request()
-            .convertToResponse(inputTopic.topicName, tensors, tensorRenaming)
+            .convertToResponse(inputTopic.pipelineName, inputTopic.topicName, tensors, tensorRenaming)
             // handle cases where there are no tensors we want
             .filter { _, value -> value.outputsList.size != 0 }
             .marshallInferenceV2Response()
@@ -101,7 +102,7 @@ class Chainer(
             .stream(inputTopic.topicName, consumerSerde)
             .filterForPipeline(inputTopic.pipelineName)
             .unmarshallInferenceV2Response()
-            .filterResponses(inputTopic.topicName, tensors, tensorRenaming)
+            .filterResponses(inputTopic.pipelineName, inputTopic.topicName, tensors, tensorRenaming)
             // handle cases where there are no tensors we want
             .filter { _, value -> value.outputsList.size != 0 }
             .marshallInferenceV2Response()
@@ -124,7 +125,7 @@ class Chainer(
             .stream(inputTopic.topicName, consumerSerde)
             .filterForPipeline(inputTopic.pipelineName)
             .unmarshallInferenceV2Response()
-            .convertToRequest(inputTopic.topicName, tensors, tensorRenaming)
+            .convertToRequest(inputTopic.pipelineName, inputTopic.topicName, tensors, tensorRenaming)
             // handle cases where there are no tensors we want
             .filter { _, value -> value.inputsList.size != 0 }
             .batchMessages(batchProperties)
@@ -148,7 +149,7 @@ class Chainer(
             .stream(inputTopic.topicName, consumerSerde)
             .filterForPipeline(inputTopic.pipelineName)
             .unmarshallInferenceV2Request()
-            .filterRequests(inputTopic.topicName, tensors, tensorRenaming)
+            .filterRequests(inputTopic.pipelineName, inputTopic.topicName, tensors, tensorRenaming)
             // handle cases where there are no tensors we want
             .filter { _, value -> value.inputsList.size != 0 }
             .batchMessages(batchProperties)
diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt
index 5e1d09b708..52df7029ac 100644
--- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt
+++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Joiner.kt
@@ -18,6 +18,7 @@ package io.seldon.dataflow.kafka
 
 import io.klogging.noCoLogger
 import io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate.PipelineJoinType
+import io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping
 import io.seldon.mlops.inference.v2.V2Dataplane
 import org.apache.kafka.streams.StreamsBuilder
 import org.apache.kafka.streams.kstream.JoinWindows
@@ -33,7 +34,7 @@ class Joiner(
     internal val outputTopic: TopicForPipeline,
     internal val tensorsByTopic: Map>?,
     internal val pipelineName: String,
-    internal val tensorRenaming: Map,
+    internal val tensorRenaming: List,
     internal val kafkaDomainParams: KafkaDomainParams,
     internal val joinType: PipelineJoinType,
     internal val inputTriggerTopics: Set,
@@ -147,7 +148,7 @@ class Joiner(
             .stream(topic.topicName, consumerSerde)
             .filterForPipeline(topic.pipelineName)
             .unmarshallInferenceV2Request()
-            .convertToResponse(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
+            .convertToResponse(topic.pipelineName, topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
             // handle cases where there are no tensors we want
             .filter { _, value -> value.outputsList.size != 0 }
             .marshallInferenceV2Response()
@@ -158,7 +159,7 @@ class Joiner(
             .stream(topic.topicName, consumerSerde)
             .filterForPipeline(topic.pipelineName)
             .unmarshallInferenceV2Response()
-            .filterResponses(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
+            .filterResponses(topic.pipelineName, topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
             // handle cases where there are no tensors we want
             .filter { _, value -> value.outputsList.size != 0 }
             .marshallInferenceV2Response()
@@ -169,7 +170,7 @@ class Joiner(
             .stream(topic.topicName, consumerSerde)
             .filterForPipeline(topic.pipelineName)
             .unmarshallInferenceV2Response()
-            .convertToRequest(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
+            .convertToRequest(topic.pipelineName, topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
             .marshallInferenceV2Request()
     }
 
@@ -178,7 +179,7 @@ class Joiner(
             .stream(topic.topicName, consumerSerde)
             .filterForPipeline(topic.pipelineName)
             .unmarshallInferenceV2Request()
-            .filterRequests(topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
+            .filterRequests(topic.pipelineName,topic.topicName, tensorsByTopic?.get(topic), tensorRenaming)
             // handle cases where there are no tensors we want
             .filter { _, value -> value.inputsList.size != 0 }
             .marshallInferenceV2Request()
diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Pipeline.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Pipeline.kt
index 43b8ced192..dab65ed9b7 100644
--- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Pipeline.kt
+++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/Pipeline.kt
@@ -102,7 +102,7 @@ class Pipeline(
                         metadata.name,
                         it.sourcesList,
                         it.triggersList,
-                        it.tensorMapMap,
+                        it.tensorMapList,
                         it.sink,
                         it.inputJoinTy,
                         it.triggersJoinTy,
diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt
index eb8ff13eeb..05eb19eb74 100644
--- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt
+++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/PipelineStep.kt
@@ -18,6 +18,7 @@ package io.seldon.dataflow.kafka
 
 import io.seldon.mlops.chainer.ChainerOuterClass.Batch
 import io.seldon.mlops.chainer.ChainerOuterClass.PipelineStepUpdate.PipelineJoinType
+import io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping
 import io.seldon.mlops.chainer.ChainerOuterClass.PipelineTopic
 import org.apache.kafka.streams.StreamsBuilder
 
@@ -38,7 +39,7 @@ fun stepFor(
     pipelineName: String,
     sources: List,
     triggerSources: List,
-    tensorMap: Map,
+    tensorMap: List,
     sink: PipelineTopic,
     joinType: PipelineJoinType,
     triggerJoinType: PipelineJoinType,
diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt
index 358c2874ee..77402aceba 100644
--- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt
+++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/StreamTransforms.kt
@@ -19,9 +19,11 @@ package io.seldon.dataflow.kafka
 import io.seldon.dataflow.kafka.headers.PipelineNameFilter
 import io.seldon.dataflow.kafka.headers.AlibiDetectRemover
 import io.seldon.dataflow.kafka.headers.PipelineHeaderSetter
+import io.seldon.mlops.chainer.ChainerOuterClass.PipelineTensorMapping
 import io.seldon.mlops.chainer.ChainerOuterClass.Batch
 import io.seldon.mlops.inference.v2.V2Dataplane.ModelInferRequest
 import io.seldon.mlops.inference.v2.V2Dataplane.ModelInferResponse
+import jdk.incubator.vector.VectorOperators.Test
 import org.apache.kafka.streams.kstream.KStream
 import org.apache.kafka.streams.kstream.ValueTransformerSupplier
 
@@ -63,10 +65,12 @@ fun  KStream.marshallInferenceV2Response(): KStream KStream.convertToRequest(
+    inputPipeline: String,
     inputTopic: TopicName,
     desiredTensors: Set?,
-    tensorRenaming: Map
+    tensorRenamingList: List
 ): KStream {
+    val tensorRenaming = tensorRenamingList.filter { it.pipelineName.equals(inputPipeline) }.map { it.topicAndTensor to it.tensorName }.toMap()
     return this
         .mapValues { inferResponse ->
             convertToRequest(
@@ -145,10 +149,12 @@ private fun convertOutputToInputTensor(
 }
 
 fun  KStream.filterRequests(
+    inputPipeline: String,
     inputTopic: TopicName,
     desiredTensors: Set?,
-    tensorRenaming: Map
+    tensorRenamingList: List
 ): KStream {
+    val tensorRenaming = tensorRenamingList.filter { it.pipelineName.equals(inputPipeline) }.map { it.topicAndTensor to it.tensorName }.toMap()
     return this
         .mapValues { inferResponse ->
             filterRequest(
@@ -214,10 +220,12 @@ private fun createInputTensor(
 
 
 fun  KStream.filterResponses(
+    inputPipeline: String,
     inputTopic: TopicName,
     desiredTensors: Set?,
-    tensorRenaming: Map
+    tensorRenamingList: List
 ): KStream {
+    val tensorRenaming = tensorRenamingList.filter { it.pipelineName.equals(inputPipeline) }.map { it.topicAndTensor to it.tensorName }.toMap()
     return this
         .mapValues { inferResponse ->
             filterResponse(
@@ -282,10 +290,12 @@ private fun createOutputTensor(
 }
 
 fun  KStream.convertToResponse(
+    inputPipeline: String,
     inputTopic: TopicName,
     desiredTensors: Set?,
-    tensorRenaming: Map
+    tensorRenamingList: List
 ): KStream {
+    val tensorRenaming = tensorRenamingList.filter { it.pipelineName.equals(inputPipeline) }.map { it.topicAndTensor to it.tensorName }.toMap()
     return this
         .mapValues { inferResponse ->
             convertToResponse(
diff --git a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt
index 1547d80e7f..8e31fea0a5 100644
--- a/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt
+++ b/scheduler/data-flow/src/main/kotlin/io/seldon/dataflow/kafka/TriggerTransforms.kt
@@ -51,7 +51,7 @@ fun addTriggerTopology(
         .stream(topic.topicName, consumerSerde)
         .filterForPipeline(topic.pipelineName)
         .unmarshallInferenceV2Response()
-        .convertToRequest(topic.topicName, tensorsByTopic?.get(topic), emptyMap())
+        .convertToRequest(topic.pipelineName, topic.topicName, tensorsByTopic?.get(topic), emptyList())
         // handle cases where there are no tensors we want
         .filter { _, value -> value.inputsList.size != 0}
         .marshallInferenceV2Request()
diff --git a/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt b/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt
index fcf3395519..5bc96fb15d 100644
--- a/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt
+++ b/scheduler/data-flow/src/test/kotlin/io/seldon/dataflow/kafka/PipelineStepTest.kt
@@ -44,7 +44,7 @@ internal class PipelineStepTest {
                 defaultPipelineName,
                 sources,
                 emptyList(),
-                emptyMap(),
+                emptyList(),
                 defaultPipelineTopic,
                 ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Inner,
                 ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Inner,
@@ -157,7 +157,7 @@ internal class PipelineStepTest {
                 tensors = tensors,
                 pipelineName = defaultPipelineName,
                 outputTopic = defaultSink,
-                tensorRenaming = emptyMap(),
+                tensorRenaming = emptyList(),
                 kafkaDomainParams = kafkaDomainParams,
                 inputTriggerTopics = emptySet(),
                 triggerJoinType = ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Inner,
@@ -175,7 +175,7 @@ internal class PipelineStepTest {
                 tensorsByTopic = tensorsByTopic,
                 pipelineName = defaultPipelineName,
                 outputTopic = defaultSink,
-                tensorRenaming = emptyMap(),
+                tensorRenaming = emptyList(),
                 kafkaDomainParams = kafkaDomainParams,
                 joinType = ChainerOuterClass.PipelineStepUpdate.PipelineJoinType.Inner,
                 inputTriggerTopics = emptySet(),
diff --git a/scheduler/pkg/kafka/gateway/manager.go b/scheduler/pkg/kafka/gateway/manager.go
index 200dd165ee..f00855352a 100644
--- a/scheduler/pkg/kafka/gateway/manager.go
+++ b/scheduler/pkg/kafka/gateway/manager.go
@@ -99,7 +99,7 @@ func (cm *ConsumerManager) stopEmptyConsumer(ic *InferKafkaConsumer) {
 	logger := cm.logger.WithField("func", "stopEmptyConsumer")
 	numModelsInConsumer := ic.GetNumModels()
 	if numModelsInConsumer == 0 {
-		logger.Debugf("Deleting consumer with no models wit bucket id %s", ic.consumerName)
+		logger.Debugf("Deleting consumer with no models with bucket id %s", ic.consumerName)
 		ic.Stop()
 		delete(cm.consumers, ic.consumerName)
 	}
diff --git a/scheduler/pkg/kafka/topics.go b/scheduler/pkg/kafka/topics.go
index 5e4b1379f2..e864ee1b4c 100644
--- a/scheduler/pkg/kafka/topics.go
+++ b/scheduler/pkg/kafka/topics.go
@@ -20,6 +20,8 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/seldonio/seldon-core/apis/go/v2/mlops/chainer"
+
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/pipeline"
 )
 
@@ -92,35 +94,43 @@ func (tn *TopicNamer) GetModelOrPipelineTopic(pipelineName string, stepReference
 
 }
 
-func (tn *TopicNamer) GetFullyQualifiedTensorMap(pipelineName string, tin map[string]string) map[string]string {
-	tout := make(map[string]string)
+func (tn *TopicNamer) GetFullyQualifiedTensorMap(pipelineName string, tin map[string]string) []*chainer.PipelineTensorMapping {
+	var mappings []*chainer.PipelineTensorMapping
 	for k, v := range tin {
 		stepName := strings.Split(k, pipeline.StepNameSeperator)[0]
-		var kout string
+		var topicAndTensor string
 		if stepName == pipelineName {
-			kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, pipelineTopic, k)
+			topicAndTensor = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, pipelineTopic, k)
 		} else {
-			kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, k)
+			topicAndTensor = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, k)
 		}
-		tout[kout] = v
+		mappings = append(mappings, &chainer.PipelineTensorMapping{
+			PipelineName:   pipelineName,
+			TopicAndTensor: topicAndTensor,
+			TensorName:     v,
+		})
 	}
-	return tout
+	return mappings
 }
 
-func (tn *TopicNamer) GetFullyQualifiedPipelineTensorMap(tin map[string]string) map[string]string {
-	tout := make(map[string]string)
+func (tn *TopicNamer) GetFullyQualifiedPipelineTensorMap(tin map[string]string) []*chainer.PipelineTensorMapping {
+	var mappings []*chainer.PipelineTensorMapping
 	for k, v := range tin {
 		parts := strings.Split(k, pipeline.StepNameSeperator)
-		var kout string
+		var topicAndTensor string
 		switch len(parts) {
 		case 3:
-			kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, pipelineTopic, k)
+			topicAndTensor = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, pipelineTopic, k)
 		case 5: // take value after .step
-			kout = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, strings.Join(parts[2:], pipeline.StepNameSeperator))
+			topicAndTensor = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, strings.Join(parts[2:], pipeline.StepNameSeperator))
 		}
-		tout[kout] = v
+		mappings = append(mappings, &chainer.PipelineTensorMapping{
+			PipelineName:   parts[0],
+			TopicAndTensor: topicAndTensor,
+			TensorName:     v,
+		})
 	}
-	return tout
+	return mappings
 }
 
 func (tn *TopicNamer) GetPipelineNameFromInput(inputSpecifier string) string {
diff --git a/scheduler/pkg/kafka/topics_test.go b/scheduler/pkg/kafka/topics_test.go
index 5a09a1b479..0ae116e303 100644
--- a/scheduler/pkg/kafka/topics_test.go
+++ b/scheduler/pkg/kafka/topics_test.go
@@ -19,6 +19,8 @@ package kafka
 import (
 	"testing"
 
+	"github.com/seldonio/seldon-core/apis/go/v2/mlops/chainer"
+
 	. "github.com/onsi/gomega"
 )
 
@@ -79,7 +81,7 @@ func TestGetFullyQualifiedTensorMap(t *testing.T) {
 		pipelineName string
 		topicNamer   *TopicNamer
 		in           map[string]string
-		expected     map[string]string
+		expected     []*chainer.PipelineTensorMapping
 	}
 
 	tests := []test{
@@ -88,23 +90,107 @@ func TestGetFullyQualifiedTensorMap(t *testing.T) {
 			pipelineName: "test",
 			topicNamer:   NewTopicNamer("default"),
 			in:           map[string]string{"step.inputs.t1": "t1in", "step.inputs.t2": "t2in"},
-			expected:     map[string]string{"seldon.default.model.step.inputs.t1": "t1in", "seldon.default.model.step.inputs.t2": "t2in"},
+			expected: []*chainer.PipelineTensorMapping{
+				{
+					PipelineName:   "test",
+					TopicAndTensor: "seldon.default.model.step.inputs.t1",
+					TensorName:     "t1in",
+				},
+				{
+					PipelineName:   "test",
+					TopicAndTensor: "seldon.default.model.step.inputs.t2",
+					TensorName:     "t2in",
+				},
+			},
 		},
 		{
 			name:         "pipeline references",
 			pipelineName: "test",
 			topicNamer:   NewTopicNamer("default"),
 			in:           map[string]string{"test.inputs.t1": "t1"},
-			expected:     map[string]string{"seldon.default.pipeline.test.inputs.t1": "t1"},
+			expected: []*chainer.PipelineTensorMapping{
+				{
+					PipelineName:   "test",
+					TopicAndTensor: "seldon.default.pipeline.test.inputs.t1",
+					TensorName:     "t1",
+				},
+			},
 		},
 	}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			res := test.topicNamer.GetFullyQualifiedTensorMap(test.pipelineName, test.in)
-			for k, v := range res {
-				g.Expect(v).To(Equal(test.expected[k]))
+			results := test.topicNamer.GetFullyQualifiedTensorMap(test.pipelineName, test.in)
+			for _, tm := range results {
+				found := false
+				for _, exp := range test.expected {
+					if tm.PipelineName == exp.PipelineName &&
+						tm.TopicAndTensor == exp.TopicAndTensor &&
+						tm.TensorName == exp.TensorName {
+						found = true
+						break
+					}
+				}
+				g.Expect(found).To(BeTrue())
 			}
+		})
+	}
+}
+
+func TestGetFullyQualifiedPipelineTensorMap(t *testing.T) {
+	g := NewGomegaWithT(t)
 
+	type test struct {
+		name       string
+		topicNamer *TopicNamer
+		in         map[string]string
+		expected   *chainer.PipelineTensorMapping
+	}
+
+	tests := []test{
+		{
+			name:       "pipeline inputs",
+			topicNamer: NewTopicNamer("default"),
+			in: map[string]string{
+				"pipeline1.inputs.input1": "t1in",
+			},
+			expected: &chainer.PipelineTensorMapping{
+				PipelineName:   "pipeline1",
+				TopicAndTensor: "seldon.default.pipeline.pipeline1.inputs.input1",
+				TensorName:     "t1in",
+			},
+		},
+		{
+			name:       "pipeline outputs",
+			topicNamer: NewTopicNamer("default"),
+			in: map[string]string{
+				"pipeline2.outputs.output1": "output2",
+			},
+			expected: &chainer.PipelineTensorMapping{
+				PipelineName:   "pipeline2",
+				TopicAndTensor: "seldon.default.pipeline.pipeline2.outputs.output1",
+				TensorName:     "output2",
+			},
+		},
+		{
+			name:       "basic",
+			topicNamer: NewTopicNamer("default"),
+			in: map[string]string{
+				"pipeline3.steps.model1.outputs.output1": "output2",
+			},
+			expected: &chainer.PipelineTensorMapping{
+				PipelineName:   "pipeline3",
+				TopicAndTensor: "seldon.default.model.model1.outputs.output1",
+				TensorName:     "output2",
+			},
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			results := test.topicNamer.GetFullyQualifiedPipelineTensorMap(test.in)
+			result := results[0]
+			g.Expect(result.PipelineName).To(Equal(test.expected.PipelineName))
+			g.Expect(result.TopicAndTensor).To(Equal(test.expected.TopicAndTensor))
+			g.Expect(result.TensorName).To(Equal(test.expected.TensorName))
 		})
 	}
 }

From f84a73c21cd19e7e0df4b751983a66d16003228f Mon Sep 17 00:00:00 2001
From: cliveseldon 
Date: Tue, 20 Dec 2022 17:32:27 +0000
Subject: [PATCH 08/18] Update docs/source/contents/pipelines/index.md

Co-authored-by: Sherif Akoush 
---
 docs/source/contents/pipelines/index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/source/contents/pipelines/index.md b/docs/source/contents/pipelines/index.md
index 289ec88296..5456a32592 100644
--- a/docs/source/contents/pipelines/index.md
+++ b/docs/source/contents/pipelines/index.md
@@ -132,7 +132,7 @@ If we changed the `triggersJoinType` for `mul10` to `inner` then both `ok1` and
 
 ### Pipeline Inputs
 
-Pipelines by default can be accessed synchronously via http/grpc or via the Kafka topic created for them. However, it's also possible to create a pipeline to take input from one or more other pipelines by specifying an `input` section. If for example we already have the `tfsimple` pipeline shown below:
+Pipelines by default can be accessed synchronously via http/grpc or asynchronously via the Kafka topic created for them. However, it's also possible to create a pipeline to take input from one or more other pipelines by specifying an `input` section. If for example we already have the `tfsimple` pipeline shown below:
 
 ```{literalinclude} ../../../../samples/pipelines/tfsimple.yaml
 :language: yaml

From a5fd2ddb0cc04d0fe8f855f7702664d4b80a9c0b Mon Sep 17 00:00:00 2001
From: cliveseldon 
Date: Tue, 20 Dec 2022 17:32:35 +0000
Subject: [PATCH 09/18] Update docs/source/contents/pipelines/index.md

Co-authored-by: Sherif Akoush 
---
 docs/source/contents/pipelines/index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/source/contents/pipelines/index.md b/docs/source/contents/pipelines/index.md
index 5456a32592..4d269fbc52 100644
--- a/docs/source/contents/pipelines/index.md
+++ b/docs/source/contents/pipelines/index.md
@@ -146,7 +146,7 @@ We can create another pipeline which takes its input from this pipeline, as show
 
 In this way pipelines can be built to extend existing running pipelines to allow extensibility and sharing of data flows.
 
-The spec follows the spec for a step except that references to other pipelines are contained in the `externalInputs` section which takes the form of pipeline or pipeline step references:
+The spec follows the same spec for a step except that references to other pipelines are contained in the `externalInputs` section which takes the form of pipeline or pipeline.step references:
   * `.(inputs|outputs).`
   * `.(step)..`
 

From 907c2417a21de66ac78fa958b458263c23d515c7 Mon Sep 17 00:00:00 2001
From: Alex Rakowski <20504869+agrski@users.noreply.github.com>
Date: Tue, 13 Dec 2022 18:13:56 +0000
Subject: [PATCH 10/18] [SCv2] Improve inference docs re routing and headers
 (#4481)

* Capitalise Seldon when used as proper noun

* Formatting, capitalisation, etc.

* Add detail to inference docs page

* Formatting and typo fixes

* Use consistent capitalisation of model & pipeline through inference docs page

* Fix typo in inference docs for Kafka topics

* Specify use of inference v2 protocol high up in inference docs

* Add mention of headers to sync inference introduction

* Formatting + minor rewording for clarity

* Use tabs for Compose vs. k8s methods for finding the seldon-mesh endpoint

* Add note on port-forwarding seldon-mesh svc for inference requests

* Add note on service meshes for sending inference requests

* Add section on inference request routing with headers

* Add section on path-based routing for inference endpoints

* Add subsection header for Seldon routing (vs. ingress routing)

* Add section on routing from ingress -> seldon-mesh for inference calls

* Add links to RFCs for host & authority headers

* Update link to RFC for  HTTP/1 Host header

RFC-7230 obsoletes RFC-2616, the previous link.

* Add line describing virtual hosts vs. physical ones

* Use tabs for alternate ways of making inference requests

* Add inference request example with Seldon CLI

* Use consistent capitalisation of v2 for inference protocol

* Add note on Kafka headers for pipelines

* Use ordinal numbering for bullet points

* Update URI for consistency and to avoid confusion

* Move section on making requests above section on routing

* Use interpolation syntax to clarify usage of path-based routing in Seldon mesh

* Add second form of path-based routing for pipelines in Seldon mesh

* Clarify wording re virtual endpoints in SCv2

* Add section for header-based routing examples

This section builds on the examples from the prior section on making inference requests.

* Update basic examples to exclude routing headers

Routing headers are then given in the examples relevant to that section.

* Formatting

* Use group-tabs for example requests with different clients

* Add emphasis to header lines in examples for header-based routing

* Add notes on support for subdomain-based routing

* Add example snippets for subdomain routing

* Add Open Inference schema for iris model for examples

* Move pipeline inference tip lower for better flow

* Fix datatype for iris model inputs
---
 docs/source/contents/inference/index.md | 375 +++++++++++++++++++++---
 1 file changed, 335 insertions(+), 40 deletions(-)

diff --git a/docs/source/contents/inference/index.md b/docs/source/contents/inference/index.md
index 3d1e78a9a5..87e64c4b88 100644
--- a/docs/source/contents/inference/index.md
+++ b/docs/source/contents/inference/index.md
@@ -1,107 +1,402 @@
 # Inference
 
-This section will discuss how to make inference calls against your seldon models or pipelines.
+This section will discuss how to make inference calls against your Seldon models or pipelines.
 
 You can make synchronous inference requests via REST or gRPC or asynchronous requests via Kafka topics.
+The content of your request should be an [inference v2 protocol payload](../apis/inference/v2.md):
+* REST payloads will generally be in the JSON v2 protocol format.
+* gRPC and Kafka payloads **must** be in the Protobuf v2 protocol format.
 
-## Synchronous requests
+## Synchronous Requests
 
-  1. Find the Seldon service endpoint
-  2. Make requests via REST or gRPC
+For making synchronous requests, the process will generally be:
+1. Find the appropriate service endpoint (IP address and port) for accessing the installation of Seldon Core v2.
+2. Determine the appropriate headers/metadata for the request.
+3. Make requests via REST or gRPC.
 
-### Find Seldon service endpoint
+### Find the Seldon Service Endpoint
 
- 1. If you are running Seldon locally via Docker compose by default the endpoint will be `0.0.0.0:9000`
- 2. If you are running in Kubernetes Seldon creates a single Service `seldon-mesh` in the namespace Seldon is installed to, usually `seldon-mesh`. If this has be exposed via a load balancer this can be found via:
+`````{tabs}
 
- ```bash
- kubectl get svc seldon-mesh -n seldon-mesh -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
- ```
+````{tab} Docker Compose
 
-### Make inference requests
+In the default Docker Compose setup, container ports are accessible from the host machine.
+This means you can use `localhost` or `0.0.0.0` as the hostname.
 
-Seldon routes requests to to the correct enpoint via headers in HTTP calls. You should set the header `seldon-model` as follow:
+The default port for sending inference requests to the Seldon system is `9000`.
+This is controlled by the `ENVOY_DATA_PORT` environment variable for Compose.
 
- * For Models: use the model name, e.g. for a Model names `mymodel`, `seldon-model: mymodel`
- * For Pipelines: use the Pipeline name with the suffix `.pipeline`, e.g. for a Pipeline named `mypipeline`, `seldon-model: mypipeline.pipeline`
+Putting this together, you can send inference requests to `0.0.0.0:9000`.
+````
 
-The content of your request should be a [V2 protocol payload](../apis/inference/v2.md).
+````{tab} Kubernetes
 
-The `seldon` CLI can be used to easily send requests to your deployed resources. See the [examples](../examples/index) and the [seldon CLI docs](../cli/index.md).
+In Kubernetes, Seldon creates a single `Service` called `seldon-mesh` in the namespace it is installed into.
+By default, this namespace is also called `seldon-mesh`.
 
-An example curl request might look like for a Model called `iris`:
+If this `Service` is exposed via a load balancer, the appropriate address and port can be found via:
 
+```bash
+kubectl get svc seldon-mesh -n seldon-mesh -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
 ```
-curl -v http://0.0.0.0:9000/v2/models/iris/infer -H "Content-Type: application/json" -H "seldon-model: iris"\
+
+If you are not using a `LoadBalancer` for the `seldon-mesh` `Service`, you can still send inference requests.
+
+For development and testing purposes, you can port-forward the `Service` locally using the below.
+Inference requests can then be sent to `localhost:8080`.
+
+```
+kubectl port-forward svc/seldon-mesh -n seldon-mesh 8080:80
+```
+
+If you are using a service mesh like Istio or Ambassador, you will need to use the IP address of the service mesh ingress and determine the appropriate port.
+````
+
+`````
+
+### Make Inference Requests
+
+Let us imagine making inference requests to a model called `iris`.
+
+This `iris` model has the following schema, which can be set in a `model-settings.json` file for MLServer:
+
+```
+{
+    "name": "iris",
+    "implementation": "mlserver_sklearn.SKLearnModel",
+    "inputs": [
+        {
+            "name": "predict",
+            "datatype": "FP32",
+            "shape": [-1, 4]
+        }
+    ],
+    "outputs": [
+        {
+            "name": "predict",
+            "datatype": "INT64",
+            "shape": [-1, 1]
+        }
+    ],
+    "parameters": {
+        "version": "1"
+    }
+}
+```
+
+Examples are given below for some common tools for making requests.
+
+`````{tabs}
+
+````{group-tab} Seldon CLI
+
+An example `seldon` request might look like this:
+
+```
+seldon model infer iris \
+        '{"inputs": [{"name": "predict", "shape": [1, 4], "datatype": "FP32", "data": [[1, 2, 3, 4]]}]}'
+```
+
+The default inference mode is REST, but you can also send gRPC requests like this:
+
+```
+seldon model infer iris \
+        --inference-mode grpc \
+        '{"model_name":"iris","inputs":[{"name":"input","contents":{"fp32_contents":[1,2,3,4]},"datatype":"FP32","shape":[1,4]}]}'
+```
+````
+
+````{group-tab} cURL
+
+An example `curl` request might look like this:
+
+```
+curl -v http://0.0.0.0:9000/v2/models/iris/infer \
+        -H "Content-Type: application/json" \
         -d '{"inputs": [{"name": "predict", "shape": [1, 4], "datatype": "FP32", "data": [[1, 2, 3, 4]]}]}'
 ```
+````
+
+````{group-tab} grpcurl
 
-A similar gRPC request using grpcurl to the same model might look like:
+An example `grpcurl` request might look like this:
 
 ```
-grpcurl -d '{"model_name":"iris","inputs":[{"name":"input","contents":{"fp32_contents":[1,2,3,4]},"datatype":"FP32","shape":[1,4]}]}' \
-        -plaintext \
+grpcurl \
+	-d '{"model_name":"iris","inputs":[{"name":"input","contents":{"fp32_contents":[1,2,3,4]},"datatype":"FP32","shape":[1,4]}]}' \
+	-plaintext \
 	-import-path apis \
 	-proto apis/mlops/v2_dataplane/v2_dataplane.proto \
-	-rpc-header seldon-model:iris \
 	0.0.0.0:9000 inference.GRPCInferenceService/ModelInfer
 ```
 
-The above request was run from the project root folder allowing reference to the protos defined in the apis folder.
+The above request was run from the project root folder allowing reference to the Protobuf manifests defined in the `apis/` folder.
+````
 
-For Pipelines a synchronous request is possible if the Pipeline has an outputs section in the spec.
+````{group-tab} Python tritonclient
 
-### Using Python Tritonclient
+You can use the Python [tritonclient](https://github.com/triton-inference-server/client) package to send inference requests.
 
-You can also use Python [tritonclient](https://github.com/triton-inference-server/client) package to send inference requests.
+A short, self-contained example is:
 
-A short self-contained example corresponding to the above requests is
 ```python
 import tritonclient.http as httpclient
 import numpy as np
 
 client = httpclient.InferenceServerClient(
-    url=f"172.19.255.9:80",
+    url="localhost:8080",
     verbose=False,
 )
 
 inputs = [httpclient.InferInput("predict", (1, 4), "FP64")]
-inputs[0].set_data_from_numpy(np.array([[1, 2, 3, 4]]).astype("float64"), binary_data=False)
+inputs[0].set_data_from_numpy(
+    np.array([[1, 2, 3, 4]]).astype("float64"),
+    binary_data=False,
+)
 
 result = client.infer("iris", inputs)
 print("result is:", result.as_numpy("predict"))
 ```
+````
+`````
+
+```{tip}
+For pipelines, a synchronous request is possible if the pipeline has an `outputs` section defined in its spec.
+```
+
+### Request Routing
+
+#### Seldon Routes
+
+Seldon needs to determine where to route requests to, as models and pipelines might have the same name.
+There are two ways of doing this: header-based routing (preferred) and path-based routing.
+
+`````{tabs}
+
+````{tab} Headers
+
+Seldon can route requests to the correct endpoint via headers in HTTP calls, both for REST (HTTP/1.1) and gRPC (HTTP/2).
+
+Use the `Seldon-Model` header as follows:
+* For models, use the model name as the value.
+  For example, to send requests to a model named `foo` use the header `Seldon-Model: foo`.
+* For pipelines, use the pipeline name followed by `.pipeline` as the value.
+  For example, to send requests to a pipeline named `foo` use the header `Seldon-Model: foo.pipeline`.
+
+The `seldon` CLI is aware of these rules and can be used to easily send requests to your deployed resources.
+See the [examples](../examples/index) and the [Seldon CLI docs](../cli/index.md) for more information.
+````
+
+````{tab} Paths
+
+The inference v2 protocol is only aware of models, thus has no concept of pipelines.
+Seldon works around this limitation by introducing _virtual_ endpoints for pipelines.
+Virtual means that Seldon understands them, but other v2 protocol-compatible components like inference servers do not.
+
+Use the following rules for paths to route to models and pipelines:
+* For models, use the path prefix `/v2/models/{model name}`.
+  This is normal usage of the inference v2 protocol.
+* For pipelines, you can use the path prefix `/v2/pipelines/{pipeline name}`.
+  Otherwise calling pipelines looks just like the inference v2 protocol for models.
+  Do **not** use any suffix for the pipeline name as you would for routing headers.
+* For pipelines, you can also use the path prefix `/v2/models/{pipeline name}.pipeline`.
+  Again, this form looks just like the inference v2 protocol for models.
+````
+
+`````
+
+Extending our examples from [above](#make-inference-requests), the requests may look like the below when using header-based routing.
+
+`````{tabs}
+
+````{group-tab} Seldon CLI
+
+No changes are required as the `seldon` CLI already understands how to set the appropriate gRPC and REST headers.
+
+````
+
+````{group-tab} cURL
+
+Note the header in the last line:
+
+```{code-block}
+:emphasize-lines: 4
+
+curl -v http://0.0.0.0:9000/v2/models/iris/infer \
+        -H "Content-Type: application/json" \
+        -d '{"inputs": [{"name": "predict", "shape": [1, 4], "datatype": "FP32", "data": [[1, 2, 3, 4]]}]}' \
+        -H "Seldon-Model: iris"
+```
+````
+
+````{group-tab} grpcurl
+
+Note the `rpc-header` flag in the penultimate line:
+
+```{code-block}
+:emphasize-lines: 6
+
+grpcurl \
+	-d '{"model_name":"iris","inputs":[{"name":"input","contents":{"fp32_contents":[1,2,3,4]},"datatype":"FP32","shape":[1,4]}]}' \
+	-plaintext \
+	-import-path apis \
+	-proto apis/mlops/v2_dataplane/v2_dataplane.proto \
+	-rpc-header seldon-model:iris \
+	0.0.0.0:9000 inference.GRPCInferenceService/ModelInfer
+```
+````
+
+````{group-tab} Python tritonclient
+
+Note the `headers` dictionary in the `client.infer()` call:
+
+```{code-block}
+:emphasize-lines: 18
+
+import tritonclient.http as httpclient
+import numpy as np
+
+client = httpclient.InferenceServerClient(
+    url="localhost:8080",
+    verbose=False,
+)
+
+inputs = [httpclient.InferInput("predict", (1, 4), "FP64")]
+inputs[0].set_data_from_numpy(
+    np.array([[1, 2, 3, 4]]).astype("float64"),
+    binary_data=False,
+)
+
+result = client.infer(
+    "iris",
+    inputs,
+    headers={"Seldon-Model": "iris"},
+)
+print("result is:", result.as_numpy("predict"))
+```
+````
+
+`````
+
+#### Ingress Routes
+
+If you are using an ingress controller to make inference requests with Seldon, you will need to configure the routing rules correctly.
+
+There are many ways to do this, but custom path prefixes will not work with gRPC.
+This is because gRPC determines the path based on the Protobuf definition.
+Some gRPC implementations permit manipulating paths when sending requests, but this is by no means universal.
+
+If you want to expose your inference endpoints via gRPC and REST in a consistent way, you should use virtual hosts, subdomains, or headers.
+
+The downside of using only paths is that you cannot differentiate between different installations of Seldon Core v2 or between traffic to Seldon and any other inference endpoints you may have exposed via the same ingress.
+
+You might want to use a mixture of these methods; the choice is yours.
+
+`````{tabs}
+
+````{tab} Virtual Hosts
+
+Virtual hosts are a way of differentiating between logical services accessed via the same physical machine(s).
+
+Virtual hosts are defined by the `Host` header for [HTTP/1](https://www.rfc-editor.org/rfc/rfc7230#section-5.4) and the `:authority` pseudo-header for [HTTP/2](https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1).
+These represent the same thing, and the HTTP/2 specification defines how to translate these when converting between protocol versions.
+
+Many tools and libraries treat these headers as special and have particular ways of handling them.
+Some common ones are given below:
+
+* The `seldon` CLI has an `--authority` flag which applies to both REST and gRPC inference calls.
+* `curl` accepts `Host` as a normal header.
+* `grpcurl` has an `-authority` flag.
+* In Go, the standard library's `http.Request` struct has a `Host` field and ignores attempts to set this value via headers.
+* In Python, the `requests` library accepts the host as a normal header.
+
+Be sure to check the documentation for how to set this with your preferred tools and languages.
+````
+
+````{tab} Subdomains
+
+Subdomain names constitute a part of the overall host name.
+As such, specifying a subdomain name for requests will involve setting the appropriate host in the URI.
+
+For example, you may expose inference services in the namespaces `seldon-1` and `seldon-2` as in the following snippets:
+
+```
+curl https://seldon-1.example.com/v2/models/iris/infer ...
+
+seldon model infer --inference-host https://seldon-2.example.com/v2/models/iris/infer ...
+```
 
-## Asynchronous requests
+Many popular ingresses support subdomain-based routing, including Istio and Nginx.
+Please refer to the documentation for your ingress of choice for further information.
+````
 
-The Seldon architetcure uses Kafka and therefore asynchronous requests can be sent by pushing V2 proto payloads to the appropriate topic.
+````{tab} Headers
+
+Many ingress controllers and service meshes support routing on headers.
+You can use whatever headers you prefer, so long as they do not conflict with any Seldon relies upon.
+
+Many tools and libraries support adding custom headers to requests.
+Some common ones are given below:
+* The `seldon` CLI accepts headers using the `--header` flag, which can be specified multiple times.
+* `curl` accepts headers using the `-H` or `--header` flags.
+* `grpcurl` accepts headers using the `-H` flag, which can be specified multiple times.
+````
+
+````{tab} Paths
+
+It is possible to route on paths by using well-known path prefixes defined by the inference v2 protocol.
+For gRPC, the full path (or "method") for an inference call is:
+```
+/inference.GRPCInferenceService/ModelInfer
+```
+
+This corresponds to the package (`inference`), service (`GRPCInferenceService`), and RPC name (`ModelInfer`) in the Protobuf definition of the inference v2 protocol.
+
+You could use an exact match or a regex like `.*inference.*` to match this path, for example.
+````
+
+`````
+
+## Asynchronous Requests
+
+The Seldon architecture uses Kafka and therefore asynchronous requests can be sent by pushing inference v2 protocol payloads to the appropriate topic.
+Topics have the following form:
 
 ```
 seldon....
 ```
 
+```{note}
+If writing to a pipeline topic, you will need to include a Kafka header with the key `pipeline` and the value being the name of the pipeline.
+```
+
 ### Model Inference
 
-For a local install if you have a Model `iris`, you would be able to send a prediction request by pushing to the topic: `seldon.default.model.iris.inputs`. The response will appear on `seldon.default.model.iris.outputs`.
+For a local install if you have a model `iris`, you would be able to send a prediction request by pushing to the topic: `seldon.default.model.iris.inputs`.
+The response will appear on `seldon.default.model.iris.outputs`.
 
-For a Kubernetes install in `seldon-mesh` if you have a Model `iris`, you would be able to send a prediction request by pushing to the topic: `seldon.seldon-mesh.model.iris.inputs`. The response will appear on `seldon.seldon-mesh.model.iris.outputs`.
+For a Kubernetes install in `seldon-mesh` if you have a model `iris`, you would be able to send a prediction request by pushing to the topic: `seldon.seldon-mesh.model.iris.inputs`.
+The response will appear on `seldon.seldon-mesh.model.iris.outputs`.
 
 
 ### Pipeline Inference
 
-For a local install if you have a Pipeline `mypipeline`, you would be able to send a prediction request by pushing to the topic: `seldon.default.pipeline.mypipeline.inputs`. The response will appear on `seldon.default.pipeline.mypipeline.outputs`.
+For a local install if you have a pipeline `mypipeline`, you would be able to send a prediction request by pushing to the topic: `seldon.default.pipeline.mypipeline.inputs`. The response will appear on `seldon.default.pipeline.mypipeline.outputs`.
 
-For a Kubernetes install in `seldon-mesh` if you have a Pipeline `pipeline`, you would be able to send a prediction request by pushing to the topic: `seldon.seldon-mesh.pipeline.mypipeline.inputs`. The response will appear on `seldon.seldon-mesh.pipeline.mypipeline.outputs`.
+For a Kubernetes install in `seldon-mesh` if you have a pipeline `mypipeline`, you would be able to send a prediction request by pushing to the topic: `seldon.seldon-mesh.pipeline.mypipeline.inputs`. The response will appear on `seldon.seldon-mesh.pipeline.mypipeline.outputs`.
 
 
 ## Pipeline Metadata
 
-It may be useful to send metadata alongside your inference. If using Kafka directly as described above you can attach kafka metadata to your request which will be passed oround the graph. When making synchronous requests to your pipeline with REST or gRPC you can also do this.
+It may be useful to send metadata alongside your inference.
+
+If using Kafka directly as described above, you can attach Kafka metadata to your request, which will be passed around the graph.
+When making synchronous requests to your pipeline with REST or gRPC you can also do this.
 
- * For REST requests add HTTP headers prefixe with `X-`
- * For gRPC requests add meatdata with keys starting with `X-`
+ * For REST requests add HTTP headers prefixed with `X-`
+ * For gRPC requests add metadata with keys starting with `X-`
 
-You can also do this with the seldon CLI by setting headers with the `--header` argument (and also showing response headers with the `--show-headers` argument)
+You can also do this with the Seldon CLI by setting headers with the `--header` argument (and also showing response headers with the `--show-headers` argument)
 
 ```
 seldon pipeline infer --show-headers --header X-foo=bar tfsimples \
@@ -122,4 +417,4 @@ The `--offset` parameter specifies how many messages (from the latest) you want
 
 If `x-request-id` is passed in by the caller then this will be used. It is the caller's responsibility to ensure it is unique.
 
-The IDs generated are [XIDs](https://github.com/rs/xid).
\ No newline at end of file
+The IDs generated are [XIDs](https://github.com/rs/xid).

From bc85dbd290522a333f06a821d07ee384889679eb Mon Sep 17 00:00:00 2001
From: Adrian Gonzalez-Martin 
Date: Fri, 16 Dec 2022 20:17:03 +0000
Subject: [PATCH 11/18] Bump MLServer version to 1.2.1 (#4503)

---
 k8s/Makefile                                              | 2 +-
 k8s/helm-charts/seldon-core-v2-setup/values.yaml          | 2 +-
 k8s/helm-charts/seldon-core-v2-setup/values.yaml.template | 2 +-
 k8s/yaml/seldon-v2-components.yaml                        | 2 +-
 operator/config/serverconfigs/kustomization.yaml          | 2 +-
 scheduler/Makefile                                        | 2 +-
 scheduler/env.all                                         | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/k8s/Makefile b/k8s/Makefile
index d793accb16..801e900824 100644
--- a/k8s/Makefile
+++ b/k8s/Makefile
@@ -12,7 +12,7 @@ PIPELINEGATEWAY_IMG ?= ${DOCKERHUB_USERNAME}/seldon-pipelinegateway:${CUSTOM_IMA
 RCLONE_IMG ?= ${DOCKERHUB_USERNAME}/seldon-rclone:${CUSTOM_IMAGE_TAG}
 SCHEDULER_IMG ?= ${DOCKERHUB_USERNAME}/seldon-scheduler:${CUSTOM_IMAGE_TAG}
 
-MLSERVER_IMG ?= seldonio/mlserver:1.2.0
+MLSERVER_IMG ?= seldonio/mlserver:1.2.1
 TRITON_IMG ?= nvcr.io/nvidia/tritonserver:22.05-py3
 
 .PHONY: create
diff --git a/k8s/helm-charts/seldon-core-v2-setup/values.yaml b/k8s/helm-charts/seldon-core-v2-setup/values.yaml
index 4986968cba..b63d944a37 100644
--- a/k8s/helm-charts/seldon-core-v2-setup/values.yaml
+++ b/k8s/helm-charts/seldon-core-v2-setup/values.yaml
@@ -237,7 +237,7 @@ serverConfig:
       pullPolicy: IfNotPresent
       registry: docker.io
       repository: seldonio/mlserver
-      tag: 1.2.0
+      tag: 1.2.1
     serverCapabilities: "mlserver,alibi-detect,alibi-explain,huggingface,lightgbm,mlflow,python,sklearn,spark-mlib,xgboost"
     modelVolumeStorage: 1Gi
     resources:
diff --git a/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template b/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template
index a674c33abb..a4bc526364 100644
--- a/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template
+++ b/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template
@@ -237,7 +237,7 @@ serverConfig:
       pullPolicy: IfNotPresent
       registry: docker.io
       repository: seldonio/mlserver
-      tag: 1.2.0
+      tag: 1.2.1
     serverCapabilities: "mlserver,alibi-detect,alibi-explain,huggingface,lightgbm,mlflow,python,sklearn,spark-mlib,xgboost"
     modelVolumeStorage: 1Gi
     resources:
diff --git a/k8s/yaml/seldon-v2-components.yaml b/k8s/yaml/seldon-v2-components.yaml
index d833fed832..e080a17d27 100644
--- a/k8s/yaml/seldon-v2-components.yaml
+++ b/k8s/yaml/seldon-v2-components.yaml
@@ -1102,7 +1102,7 @@ spec:
         value: "1"
       - name: MLSERVER_LOAD_MODELS_AT_STARTUP
         value: "false"
-      image: seldonio/mlserver:1.2.0
+      image: seldonio/mlserver:1.2.1
       imagePullPolicy: IfNotPresent
       lifecycle:
         preStop:
diff --git a/operator/config/serverconfigs/kustomization.yaml b/operator/config/serverconfigs/kustomization.yaml
index 237fc65212..731dec10b9 100644
--- a/operator/config/serverconfigs/kustomization.yaml
+++ b/operator/config/serverconfigs/kustomization.yaml
@@ -13,7 +13,7 @@ images:
   newTag: latest
 - name: mlserver
   newName: seldonio/mlserver
-  newTag: 1.2.0
+  newTag: 1.2.1
 - name: rclone
   newName: seldonio/seldon-rclone
   newTag: latest
diff --git a/scheduler/Makefile b/scheduler/Makefile
index 321de2c7b8..dd40746664 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -8,7 +8,7 @@ ENVOY_IMG ?= ${DOCKERHUB_USERNAME}/seldon-envoy:${CUSTOM_IMAGE_TAG}
 GRAFANA_IMG ?= ${DOCKERHUB_USERNAME}/seldon-grafana:${CUSTOM_IMAGE_TAG}
 HODOMETER_IMG ?= ${DOCKERHUB_USERNAME}/seldon-hodometer:${CUSTOM_IMAGE_TAG}
 KAFKA_IMG ?= docker.io/bitnami/kafka:3.3
-MLSERVER_IMG ?= seldonio/mlserver:1.2.0
+MLSERVER_IMG ?= seldonio/mlserver:1.2.1
 MODELGATEWAY_IMG ?= ${DOCKERHUB_USERNAME}/seldon-modelgateway:${CUSTOM_IMAGE_TAG}
 OTELCOL_IMG ?= otel/opentelemetry-collector-contrib-dev:latest
 PIPELINEGATEWAY_IMG ?= ${DOCKERHUB_USERNAME}/seldon-pipelinegateway:${CUSTOM_IMAGE_TAG}
diff --git a/scheduler/env.all b/scheduler/env.all
index 3ce0a5a1d3..4b9e289fb1 100644
--- a/scheduler/env.all
+++ b/scheduler/env.all
@@ -37,7 +37,7 @@ HODOMETER_IMAGE_AND_TAG=seldonio/seldon-hodometer:latest
 RCLONE_IMAGE_AND_TAG=seldonio/seldon-rclone:latest
 MODELGATEWAY_IMAGE_AND_TAG=seldonio/seldon-modelgateway:latest
 PIPELINEGATEWAY_IMAGE_AND_TAG=seldonio/seldon-pipelinegateway:latest
-SERVER_MLSERVER_IMAGE_AND_TAG=seldonio/mlserver:1.2.0
+SERVER_MLSERVER_IMAGE_AND_TAG=seldonio/mlserver:1.2.1
 SERVER_TRITON_IMAGE_AND_TAG=nvcr.io/nvidia/tritonserver:22.05-py3
 SCHEDULER_IMAGE_AND_TAG=seldonio/seldon-scheduler:latest
 KAFKA_IMAGE_AND_TAG=docker.io/bitnami/kafka:3.3

From 39fdf0441626b477a5ad492c0c3818f1fb8226b8 Mon Sep 17 00:00:00 2001
From: Sherif Akoush 
Date: Sat, 17 Dec 2022 09:44:55 +0000
Subject: [PATCH 12/18] add a notebook test for changing model replicas (#4504)

---
 .../notebooks/k8s-envoy-change-test.ipynb     | 291 ++++++++++++++++++
 1 file changed, 291 insertions(+)
 create mode 100644 scheduler/notebooks/k8s-envoy-change-test.ipynb

diff --git a/scheduler/notebooks/k8s-envoy-change-test.ipynb b/scheduler/notebooks/k8s-envoy-change-test.ipynb
new file mode 100644
index 0000000000..648a22747e
--- /dev/null
+++ b/scheduler/notebooks/k8s-envoy-change-test.ipynb
@@ -0,0 +1,291 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "id": "thousand-market",
+   "metadata": {},
+   "source": [
+    "# K8s Envoy Test with Changing Model Replica\n",
+    "\n",
+    "In this test we change the number of replicas to a given model and then look at whether inference requests are being served still.\n",
+    "\n",
+    "So far we can expect 503 due to the way we do envoy updates.\n",
+    "\n",
+    "## Prerequisites\n",
+    "\n",
+    "- (KinD) cluster with 3 triton replica servers. \n",
+    "    - One way to do so is to increase triton server `Replicas` to 3 in `k8s/yaml/seldon-v2-servers.yaml` and then apply the manifest \n",
+    "    - via `kubectl apply -f k8s/yaml/seldon-v2-servers.yaml -n seldon-mesh`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "representative-intersection",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SCHEDULER_IP=!kubectl get svc seldon-scheduler -n seldon-mesh -o jsonpath='{.status.loadBalancer.ingress[0].ip}'\n",
+    "SCHEDULER_IP=SCHEDULER_IP[0]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "delayed-resort",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "MESH_IP=!kubectl get svc seldon-mesh -n seldon-mesh -o jsonpath='{.status.loadBalancer.ingress[0].ip}'\n",
+    "MESH_IP=MESH_IP[0]"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "id": "described-girlfriend",
+   "metadata": {},
+   "source": [
+    "## Deploy single replica `tfsimple` model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 110,
+   "id": "asian-roller",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "!grpcurl -d '{\"model\":{ \\\n",
+    "              \"meta\":{\"name\":\"tfsimple\"},\\\n",
+    "              \"modelSpec\":{\"uri\":\"gs://seldon-models/triton/simple\",\\\n",
+    "                           \"requirements\":[\"tensorflow\"],\\\n",
+    "                           \"memoryBytes\":500},\\\n",
+    "              \"deploymentSpec\":{\"replicas\":1}}}' \\\n",
+    "         -plaintext \\\n",
+    "         -import-path ../../apis \\\n",
+    "         -proto ../../apis/mlops/scheduler/scheduler.proto  ${SCHEDULER_IP}:9004 seldon.mlops.scheduler.Scheduler/LoadModel"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 111,
+   "id": "waiting-accordance",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{}\n"
+     ]
+    }
+   ],
+   "source": [
+    "!seldon model status tfsimple -w ModelAvailable --scheduler-host \"$SCHEDULER_IP:9004\" | jq -M ."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "id": "ec673015",
+   "metadata": {},
+   "source": [
+    "## Scaling up"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 118,
+   "id": "bfcefb5b",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Increasing replica count\n",
+      "Done\n",
+      "{\n",
+      "  \n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%bash\n",
+    "for i in {1..1000}; \n",
+    "do\n",
+    "\n",
+    "url=http://${MESH_IP}/v2/models/tfsimple/infer \n",
+    "ret=`curl -s -o /dev/null -w \"%{http_code}\" curl -s -o /dev/null -w \"%{http_code}\" \"${url}\" -H \"Content-Type: application/json\" \\\n",
+    "        -d '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}'` \\\n",
+    "&& if [ $ret -ne 200 ]; then echo \"Failed with code ${ret}\"; fi &\n",
+    "\n",
+    "if [[ $i -eq 500 ]]; then\n",
+    "    echo \"Increasing replica count\"\n",
+    "    grpcurl -d '{\"model\":{ \n",
+    "              \"meta\":{\"name\":\"tfsimple\"},\n",
+    "              \"modelSpec\":{\"uri\":\"gs://seldon-models/triton/simple\",\n",
+    "                           \"requirements\":[\"tensorflow\"],\n",
+    "                           \"memoryBytes\":500},\n",
+    "              \"deploymentSpec\":{\"replicas\":3}}}' \\\n",
+    "         -plaintext \\\n",
+    "         -import-path ../../apis \\\n",
+    "         -proto ../../apis/mlops/scheduler/scheduler.proto  $SCHEDULER_IP:9004 seldon.mlops.scheduler.Scheduler/LoadModel &\n",
+    "fi\n",
+    "\n",
+    "done\n",
+    "echo \"Done\""
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "id": "a05b0546",
+   "metadata": {},
+   "source": [
+    "## Scaling down"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 119,
+   "id": "e6319047",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Decrease replica count\n",
+      "{\n",
+      "  \n",
+      "}\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000503\n",
+      "Failed with code 000404\n",
+      "Failed with code 000404\n",
+      "Failed with code 000404\n",
+      "Failed with code 000404\n",
+      "Failed with code 000404\n",
+      "Done\n",
+      "Failed with code 000404\n",
+      "Failed with code 000503\n",
+      "Failed with code 000404\n",
+      "Failed with code 000404\n",
+      "Failed with code 000404\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%bash\n",
+    "for i in {1..1000}; \n",
+    "do\n",
+    "\n",
+    "url=http://${MESH_IP}/v2/models/tfsimple/infer \n",
+    "ret=`curl -s -o /dev/null -w \"%{http_code}\" curl -s -o /dev/null -w \"%{http_code}\" \"${url}\" -H \"Content-Type: application/json\" \\\n",
+    "        -d '{\"inputs\":[{\"name\":\"INPUT0\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]},{\"name\":\"INPUT1\",\"data\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"datatype\":\"INT32\",\"shape\":[1,16]}]}'` \\\n",
+    "&& if [ $ret -ne 200 ]; then echo \"Failed with code ${ret}\"; fi &\n",
+    "\n",
+    "if [[ $i -eq 500 ]]; then\n",
+    "    echo \"Decrease replica count\"\n",
+    "    grpcurl -d '{\"model\":{ \n",
+    "              \"meta\":{\"name\":\"tfsimple\"},\n",
+    "              \"modelSpec\":{\"uri\":\"gs://seldon-models/triton/simple\",\n",
+    "                           \"requirements\":[\"tensorflow\"],\n",
+    "                           \"memoryBytes\":500},\n",
+    "              \"deploymentSpec\":{\"replicas\":1}}}' \\\n",
+    "         -plaintext \\\n",
+    "         -import-path ../../apis \\\n",
+    "         -proto ../../apis/mlops/scheduler/scheduler.proto  $SCHEDULER_IP:9004 seldon.mlops.scheduler.Scheduler/LoadModel &\n",
+    "fi\n",
+    "\n",
+    "done\n",
+    "echo \"Done\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 109,
+   "id": "3a081743",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "!grpcurl -d '{\"model\": {\"name\" : \"tfsimple\"}}' \\\n",
+    "         -plaintext \\\n",
+    "         -import-path ../../apis/ \\\n",
+    "         -proto ../../apis/mlops/scheduler/scheduler.proto  ${SCHEDULER_IP}:9004 seldon.mlops.scheduler.Scheduler/UnloadModel"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "4dbd697a",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "seldon-core-v2-python-3.8",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.12"
+  },
+  "vscode": {
+   "interpreter": {
+    "hash": "dc8b7b3d3b143757bd161269cf4ea949ead8c2ebc12155bae9e3cf57923f4a90"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}

From b54d6d178ae03d685d75fd5f472ff885b949e308 Mon Sep 17 00:00:00 2001
From: Sherif Akoush 
Date: Sat, 17 Dec 2022 09:46:46 +0000
Subject: [PATCH 13/18] Disable autoscaling tracking on agent for models that
 are fixed (#4501)

* add flag for autoscaling in grpc msg

* autogen files

* extract helper function

* adjust comment

* wire up autoscaling flag in server

* wire up autoscaling in agent client

* set thresholds for scaling in local deployment

* add autoscaling flag to scheduler

* add a toggle for autoscaling service

* revert autoscaling envs set in local deployment

* disable scaling for local deployment

* use a disable toggle instead

* do not disable by default scaling service
---
 apis/go/mlops/agent/agent.pb.go      | 21 ++++++++---
 apis/go/mlops/agent/agent_grpc.pb.go |  2 +-
 apis/mlops/agent/agent.proto         |  1 +
 scheduler/all-host-network.yaml      |  1 +
 scheduler/all-internal.yaml          |  1 +
 scheduler/cmd/scheduler/main.go      | 10 ++++--
 scheduler/pkg/agent/client.go        | 12 ++++---
 scheduler/pkg/agent/client_test.go   | 39 +++++++++++++++++---
 scheduler/pkg/agent/server.go        | 54 ++++++++++++++++++----------
 scheduler/pkg/agent/server_test.go   | 49 ++++++++++++++++++++++++-
 scheduler/pkg/proxy/server.go        |  6 ++--
 11 files changed, 157 insertions(+), 39 deletions(-)

diff --git a/apis/go/mlops/agent/agent.pb.go b/apis/go/mlops/agent/agent.pb.go
index 3e36cd3f9f..1ce99795e4 100644
--- a/apis/go/mlops/agent/agent.pb.go
+++ b/apis/go/mlops/agent/agent.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.28.1
-// 	protoc        v3.21.10
+// 	protoc        v3.19.6
 // source: mlops/agent/agent.proto
 
 package agent
@@ -730,8 +730,9 @@ type ModelOperationMessage struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Operation    ModelOperationMessage_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=seldon.mlops.agent.ModelOperationMessage_Operation" json:"operation,omitempty"`
-	ModelVersion *ModelVersion                   `protobuf:"bytes,2,opt,name=modelVersion,proto3" json:"modelVersion,omitempty"`
+	Operation          ModelOperationMessage_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=seldon.mlops.agent.ModelOperationMessage_Operation" json:"operation,omitempty"`
+	ModelVersion       *ModelVersion                   `protobuf:"bytes,2,opt,name=modelVersion,proto3" json:"modelVersion,omitempty"`
+	AutoscalingEnabled bool                            `protobuf:"varint,3,opt,name=autoscalingEnabled,proto3" json:"autoscalingEnabled,omitempty"`
 }
 
 func (x *ModelOperationMessage) Reset() {
@@ -780,6 +781,13 @@ func (x *ModelOperationMessage) GetModelVersion() *ModelVersion {
 	return nil
 }
 
+func (x *ModelOperationMessage) GetAutoscalingEnabled() bool {
+	if x != nil {
+		return x.AutoscalingEnabled
+	}
+	return false
+}
+
 type ModelVersion struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -947,7 +955,7 @@ var file_mlops_agent_agent_proto_rawDesc = []byte{
 	0x73, 0x12, 0x32, 0x0a, 0x14, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50,
 	0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52,
 	0x14, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x65, 0x72, 0x63, 0x65,
-	0x6e, 0x74, 0x61, 0x67, 0x65, 0x22, 0xf2, 0x01, 0x0a, 0x15, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x4f,
+	0x6e, 0x74, 0x61, 0x67, 0x65, 0x22, 0xa2, 0x02, 0x0a, 0x15, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x4f,
 	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
 	0x51, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
 	0x28, 0x0e, 0x32, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70,
@@ -958,7 +966,10 @@ var file_mlops_agent_agent_proto_rawDesc = []byte{
 	0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
 	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x6f,
 	0x64, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6d, 0x6f, 0x64, 0x65,
-	0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x40, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72,
+	0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x6f,
+	0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e,
+	0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x40, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72,
 	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
 	0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x4f, 0x41, 0x44,
 	0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x4c, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x4c, 0x4f,
diff --git a/apis/go/mlops/agent/agent_grpc.pb.go b/apis/go/mlops/agent/agent_grpc.pb.go
index f5ea789141..f20384413f 100644
--- a/apis/go/mlops/agent/agent_grpc.pb.go
+++ b/apis/go/mlops/agent/agent_grpc.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
 // - protoc-gen-go-grpc v1.2.0
-// - protoc             v3.21.10
+// - protoc             v3.19.6
 // source: mlops/agent/agent.proto
 
 package agent
diff --git a/apis/mlops/agent/agent.proto b/apis/mlops/agent/agent.proto
index 1d377b0ead..7b6fb12d67 100644
--- a/apis/mlops/agent/agent.proto
+++ b/apis/mlops/agent/agent.proto
@@ -86,6 +86,7 @@ message ModelOperationMessage {
   }
   Operation operation = 1;
   ModelVersion modelVersion = 2;
+  bool autoscalingEnabled = 3;
 }
 
 message ModelVersion {
diff --git a/scheduler/all-host-network.yaml b/scheduler/all-host-network.yaml
index 01170b15b2..d33d949dda 100644
--- a/scheduler/all-host-network.yaml
+++ b/scheduler/all-host-network.yaml
@@ -164,6 +164,7 @@ services:
       - "/mnt/config/tracing-internal.json"
       - --db-path
       - "${DB_PATH_COMPOSE}"
+      - --disable-autoscaling
     volumes:
       - type: bind
         source: ./config
diff --git a/scheduler/all-internal.yaml b/scheduler/all-internal.yaml
index b0db1afd3a..2736ff45c4 100644
--- a/scheduler/all-internal.yaml
+++ b/scheduler/all-internal.yaml
@@ -203,6 +203,7 @@ services:
       - "/mnt/config/tracing-internal.json"
       - --db-path
       - ${DB_PATH_COMPOSE}
+      - --disable-autoscaling
     volumes:
       - type: bind
         source: ./config
diff --git a/scheduler/cmd/scheduler/main.go b/scheduler/cmd/scheduler/main.go
index 892e14e402..1633863152 100644
--- a/scheduler/cmd/scheduler/main.go
+++ b/scheduler/cmd/scheduler/main.go
@@ -64,8 +64,8 @@ var (
 	tracingConfigPath       string
 	dbPath                  string
 	nodeID                  string
-	//scheduler server
-	allowPlaintxt bool
+	allowPlaintxt           bool //scheduler server
+	autoscalingDisabled     bool
 )
 
 func init() {
@@ -104,6 +104,9 @@ func init() {
 
 	// Allow plaintext servers
 	flag.BoolVar(&allowPlaintxt, "allow-plaintxt", true, "Allow plain text scheduler server")
+
+	// Whether to enable autoscaling, default is true
+	flag.BoolVar(&autoscalingDisabled, "disable-autoscaling", false, "Disable autoscaling feature")
 }
 
 func getNamespace() string {
@@ -188,7 +191,8 @@ func main() {
 		ss,
 		scheduler.DefaultSchedulerConfig(ss),
 	)
-	as := agent.NewAgentServer(logger, ss, sched, eventHub)
+	logger.Infof("Autoscaling service is set to %t", !autoscalingDisabled)
+	as := agent.NewAgentServer(logger, ss, sched, eventHub, !autoscalingDisabled)
 
 	dataFlowLoadBalancer := util.NewRingLoadBalancer(1)
 	cs := dataflow.NewChainerServer(logger, eventHub, ps, namespace, dataFlowLoadBalancer)
diff --git a/scheduler/pkg/agent/client.go b/scheduler/pkg/agent/client.go
index 7152aedda5..28eaeeb5a9 100644
--- a/scheduler/pkg/agent/client.go
+++ b/scheduler/pkg/agent/client.go
@@ -524,11 +524,14 @@ func (c *Client) LoadModel(request *agent.ModelOperationMessage) error {
 		return err
 	}
 
-	// add pointers in model scaling stats
+	// if scheduler ask for autoscaling, add pointers in model scaling stats
 	// we have done it via the scaling service as not to expose here all the model scaling stats that we have and then call Add on
 	// each one of them
-	if err := c.modelScalingService.(*modelscaling.StatsAnalyserService).AddModel(modelWithVersion); err != nil {
-		logger.WithError(err).Warnf("Cannot add model %s to scaling service", modelWithVersion)
+	if request.AutoscalingEnabled {
+		logger.Debugf("Enabling autoscaling checks for model %s", modelWithVersion)
+		if err := c.modelScalingService.(*modelscaling.StatsAnalyserService).AddModel(modelWithVersion); err != nil {
+			logger.WithError(err).Warnf("Cannot add model %s to scaling service", modelWithVersion)
+		}
 	}
 
 	logger.Infof("Load model %s:%d success", modelName, modelVersion)
@@ -560,8 +563,9 @@ func (c *Client) UnloadModel(request *agent.ModelOperationMessage) error {
 	// remove pointers in model scaling stats
 	// we have done it via the scaling service as not to expose here all the model scaling stats that we have and then call Delete on
 	// each one of them
+	// note that we do not check if the model is already enabled for autoscaling, should we?
 	if err := c.modelScalingService.(*modelscaling.StatsAnalyserService).DeleteModel(modelWithVersion); err != nil {
-		logger.WithError(err).Warnf("Cannot delete model %s from scaling service", modelWithVersion)
+		logger.WithError(err).Warnf("Cannot delete model %s from scaling service, likely that it was not enabled in the first place", modelWithVersion)
 	}
 
 	err := c.ModelRepository.RemoveModelVersion(modelWithVersion)
diff --git a/scheduler/pkg/agent/client_test.go b/scheduler/pkg/agent/client_test.go
index e7b7f8aa6f..5c65f9fc7f 100644
--- a/scheduler/pkg/agent/client_test.go
+++ b/scheduler/pkg/agent/client_test.go
@@ -161,6 +161,7 @@ func (m *mockAgentV2Server) Subscribe(request *pb.AgentSubscribeRequest, server
 					ModelSpec: &pbs.ModelSpec{Uri: "gs://model"},
 				},
 			},
+			AutoscalingEnabled: false,
 		})
 		if err != nil {
 			m.errors++
@@ -256,6 +257,7 @@ func TestLoadModel(t *testing.T) {
 		v2Status                int
 		modelRepoErr            error
 		success                 bool
+		autoscalingEnabled      bool
 	}
 	smallMemory := uint64(500)
 	largeMemory := uint64(2000)
@@ -278,6 +280,26 @@ func TestLoadModel(t *testing.T) {
 			expectedAvailableMemory: 500,
 			v2Status:                200,
 			success:                 true}, // Success
+		{
+			name:   "simple - autoscaling enabled",
+			models: []string{"iris"},
+			op: &pb.ModelOperationMessage{
+				Operation: pb.ModelOperationMessage_LOAD_MODEL,
+				ModelVersion: &pb.ModelVersion{
+					Model: &pbs.Model{
+						Meta: &pbs.MetaData{
+							Name: "iris",
+						},
+						ModelSpec: &pbs.ModelSpec{Uri: "gs://model", MemoryBytes: &smallMemory},
+					},
+				},
+				AutoscalingEnabled: true,
+			},
+			replicaConfig:           &pb.ReplicaConfig{MemoryBytes: 1000},
+			expectedAvailableMemory: 500,
+			v2Status:                200,
+			success:                 true,
+			autoscalingEnabled:      true}, // Success
 		{
 			name:   "V2Fail",
 			models: []string{"iris"},
@@ -364,12 +386,19 @@ func TestLoadModel(t *testing.T) {
 				loadedVersions := client.stateManager.modelVersions.getVersionsForAllModels()
 				// we have only one version in the test
 				g.Expect(proto.Clone(loadedVersions[0])).To(Equal(proto.Clone(test.op.ModelVersion)))
-				// we have set model stats state
+				// we have set model stats state if autoscaling is enabled
 				versionedModelName := util.GetVersionedModelName(test.op.GetModelVersion().Model.Meta.Name, test.op.GetModelVersion().GetVersion())
-				_, err := lags.Stats.Get(versionedModelName)
-				g.Expect(err).To(BeNil())
-				_, err = lastUsed.Stats.Get(versionedModelName)
-				g.Expect(err).To(BeNil())
+				if test.autoscalingEnabled {
+					_, err := lags.Stats.Get(versionedModelName)
+					g.Expect(err).To(BeNil())
+					_, err = lastUsed.Stats.Get(versionedModelName)
+					g.Expect(err).To(BeNil())
+				} else {
+					_, err := lags.Stats.Get(versionedModelName)
+					g.Expect(err).ToNot(BeNil())
+					_, err = lastUsed.Stats.Get(versionedModelName)
+					g.Expect(err).ToNot(BeNil())
+				}
 			} else {
 				g.Expect(err).ToNot(BeNil())
 				g.Expect(mockAgentV2Server.loadedEvents).To(Equal(0))
diff --git a/scheduler/pkg/agent/server.go b/scheduler/pkg/agent/server.go
index 8fef30cf2d..ff514f1530 100644
--- a/scheduler/pkg/agent/server.go
+++ b/scheduler/pkg/agent/server.go
@@ -112,12 +112,13 @@ type ServerKey struct {
 type Server struct {
 	mutex sync.RWMutex
 	pb.UnimplementedAgentServiceServer
-	logger           log.FieldLogger
-	agents           map[ServerKey]*AgentSubscriber
-	store            store.ModelStore
-	scheduler        scheduler.Scheduler
-	certificateStore *seldontls.CertificateStore
-	waiter           *modelRelocatedWaiter // waiter for when we want to drain a particular server replica
+	logger                    log.FieldLogger
+	agents                    map[ServerKey]*AgentSubscriber
+	store                     store.ModelStore
+	scheduler                 scheduler.Scheduler
+	certificateStore          *seldontls.CertificateStore
+	waiter                    *modelRelocatedWaiter // waiter for when we want to drain a particular server replica
+	autoscalingServiceEnabled bool
 }
 
 type SchedulerAgent interface {
@@ -135,13 +136,15 @@ func NewAgentServer(
 	store store.ModelStore,
 	scheduler scheduler.Scheduler,
 	hub *coordinator.EventHub,
+	autoscalingServiceEnabled bool,
 ) *Server {
 	s := &Server{
-		logger:    logger.WithField("source", "AgentServer"),
-		agents:    make(map[ServerKey]*AgentSubscriber),
-		store:     store,
-		scheduler: scheduler,
-		waiter:    newModelRelocatedWaiter(),
+		logger:                    logger.WithField("source", "AgentServer"),
+		agents:                    make(map[ServerKey]*AgentSubscriber),
+		store:                     store,
+		scheduler:                 scheduler,
+		waiter:                    newModelRelocatedWaiter(),
+		autoscalingServiceEnabled: autoscalingServiceEnabled,
 	}
 
 	hub.RegisterModelEventHandler(
@@ -264,8 +267,9 @@ func (s *Server) Sync(modelName string) {
 
 			as.mutex.Lock()
 			err = as.stream.Send(&pb.ModelOperationMessage{
-				Operation:    pb.ModelOperationMessage_LOAD_MODEL,
-				ModelVersion: &pb.ModelVersion{Model: latestModel.GetModel(), Version: latestModel.GetVersion()},
+				Operation:          pb.ModelOperationMessage_LOAD_MODEL,
+				ModelVersion:       &pb.ModelVersion{Model: latestModel.GetModel(), Version: latestModel.GetVersion()},
+				AutoscalingEnabled: AutoscalingEnabled(latestModel.GetModel()) && s.autoscalingServiceEnabled,
 			})
 			as.mutex.Unlock()
 			if err != nil {
@@ -570,14 +574,13 @@ func calculateDesiredNumReplicas(model *pbs.Model, trigger pb.ModelScalingTrigge
 // which is hidden in this logic unfortunately as we reject the scaling up / down event.
 // a side effect is that we do not go below 1 replica of a model
 func checkModelScalingWithinRange(model *pbs.Model, targetNumReplicas int) error {
-	minReplicas := model.DeploymentSpec.GetMinReplicas()
-	maxReplicas := model.DeploymentSpec.GetMaxReplicas()
-
-	if (minReplicas == 0) && (maxReplicas == 0) {
-		// no autoscaling
+	if !AutoscalingEnabled(model) {
 		return fmt.Errorf("No autoscaling for model %s", model.GetMeta().GetName())
 	}
 
+	minReplicas := model.DeploymentSpec.GetMinReplicas()
+	maxReplicas := model.DeploymentSpec.GetMaxReplicas()
+
 	if targetNumReplicas < int(minReplicas) || (targetNumReplicas < 1) {
 		return fmt.Errorf("Violating min replicas %d / %d for model %s", minReplicas, targetNumReplicas, model.GetMeta().GetName())
 	}
@@ -588,3 +591,18 @@ func checkModelScalingWithinRange(model *pbs.Model, targetNumReplicas int) error
 
 	return nil
 }
+
+// if min and max replicas are not set, we do not allow autoscaling
+// we check that they are not set if they are equal to zero as per
+// `GetMinReplicas` and `GetMaxReplicas` definition
+func AutoscalingEnabled(model *pbs.Model) bool {
+	minReplicas := model.DeploymentSpec.GetMinReplicas()
+	maxReplicas := model.DeploymentSpec.GetMaxReplicas()
+
+	if (minReplicas == 0) && (maxReplicas == 0) {
+		// no autoscaling
+		return false
+	} else {
+		return true
+	}
+}
diff --git a/scheduler/pkg/agent/server_test.go b/scheduler/pkg/agent/server_test.go
index 23e1bd7718..dc340dab33 100644
--- a/scheduler/pkg/agent/server_test.go
+++ b/scheduler/pkg/agent/server_test.go
@@ -244,7 +244,7 @@ func TestSync(t *testing.T) {
 			logger := log.New()
 			eventHub, err := coordinator.NewEventHub(logger)
 			g.Expect(err).To(BeNil())
-			server := NewAgentServer(logger, test.store, nil, eventHub)
+			server := NewAgentServer(logger, test.store, nil, eventHub, false)
 			server.agents = test.agents
 			server.Sync(test.modelName)
 			model, err := test.store.GetModel(test.modelName)
@@ -844,3 +844,50 @@ func TestModelRelocatedWaiterSmoke(t *testing.T) {
 	}
 
 }
+
+func TestAutoscalingEnabled(t *testing.T) {
+	log.SetLevel(log.DebugLevel)
+	g := NewGomegaWithT(t)
+
+	dummyModelName := "iris"
+
+	type test struct {
+		name    string
+		model   *pbs.Model
+		enabled bool
+	}
+	tests := []test{
+		{
+			name: "enabled - minreplica set",
+			model: &pbs.Model{
+				Meta:           &pbs.MetaData{Name: dummyModelName},
+				DeploymentSpec: &pbs.DeploymentSpec{Replicas: 2, MinReplicas: 1},
+			},
+			enabled: true,
+		},
+		{
+			name: "enabled - maxreplica set",
+			model: &pbs.Model{
+				Meta:           &pbs.MetaData{Name: dummyModelName},
+				DeploymentSpec: &pbs.DeploymentSpec{Replicas: 2, MaxReplicas: 3},
+			},
+			enabled: true,
+		},
+		{
+			name: "disabled",
+			model: &pbs.Model{
+				Meta:           &pbs.MetaData{Name: dummyModelName},
+				DeploymentSpec: &pbs.DeploymentSpec{Replicas: 2},
+			},
+			enabled: false,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			enabled := AutoscalingEnabled(test.model)
+			g.Expect(enabled).To(Equal(test.enabled))
+		})
+	}
+
+}
diff --git a/scheduler/pkg/proxy/server.go b/scheduler/pkg/proxy/server.go
index fd7fd823ea..5e84f7a5b5 100644
--- a/scheduler/pkg/proxy/server.go
+++ b/scheduler/pkg/proxy/server.go
@@ -25,6 +25,7 @@ import (
 	pba "github.com/seldonio/seldon-core/apis/go/v2/mlops/agent"
 	pb "github.com/seldonio/seldon-core/apis/go/v2/mlops/proxy"
 	pbs "github.com/seldonio/seldon-core/apis/go/v2/mlops/scheduler"
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/agent"
 	log "github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
 )
@@ -62,8 +63,9 @@ func (p *ProxyServer) Start(port uint) error {
 func (p *ProxyServer) LoadModel(ctx context.Context, r *pb.LoadModelRequest) (*pb.LoadModelResponse, error) {
 	m := ModelEvent{
 		ModelOperationMessage: &pba.ModelOperationMessage{
-			Operation:    pba.ModelOperationMessage_LOAD_MODEL,
-			ModelVersion: &pba.ModelVersion{Model: r.GetRequest().GetModel(), Version: r.GetVersion()},
+			Operation:          pba.ModelOperationMessage_LOAD_MODEL,
+			ModelVersion:       &pba.ModelVersion{Model: r.GetRequest().GetModel(), Version: r.GetVersion()},
+			AutoscalingEnabled: agent.AutoscalingEnabled(r.GetRequest().GetModel()),
 		},
 	}
 	p.modelEvents <- m

From 3732cf4fa21ad96a1f750d5485533f7d61ade0d5 Mon Sep 17 00:00:00 2001
From: Saeid 
Date: Sat, 17 Dec 2022 05:04:02 -0500
Subject: [PATCH 14/18] Upgrading docker compose CLI command (#4498)

Not sure if this is necessary but it actually took me some time to figure it out as I was sure that I have `docker compose` already installed. According to the [Docker documentation](https://docs.docker.com/compose/reference/) the spaced version looks like the newer one and maybe the makefile should be updated for that.
---
 scheduler/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scheduler/Makefile b/scheduler/Makefile
index dd40746664..a37698ab3b 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -277,7 +277,7 @@ ifneq ($(DOCKER_COMPOSE_BUILD_IMAGES),)
 	DOCKER_COMPOSE_BUILD_IMAGES := --build
 endif
 
-DOCKER_COMPOSE_BASE_COMMAND = docker-compose --env-file env.all -f all-base.yaml
+DOCKER_COMPOSE_BASE_COMMAND = docker compose --env-file env.all -f all-base.yaml
 ifeq ($(GPU_ENABLED),1)
 	DOCKER_COMPOSE_BASE_COMMAND := $(DOCKER_COMPOSE_BASE_COMMAND) -f all-gpu.yaml
 endif

From 5663bacde6767a0e47cb772104543711c2774a8a Mon Sep 17 00:00:00 2001
From: cliveseldon 
Date: Sun, 18 Dec 2022 11:41:44 +0000
Subject: [PATCH 15/18] Ensure x-request-id header matches kafka key (#4511)

---
 scheduler/pkg/kafka/pipeline/kafkamanager.go |  1 +
 scheduler/pkg/kafka/pipeline/utils.go        | 20 ++++++-
 scheduler/pkg/kafka/pipeline/utils_test.go   | 55 ++++++++++++++++++++
 3 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/scheduler/pkg/kafka/pipeline/kafkamanager.go b/scheduler/pkg/kafka/pipeline/kafkamanager.go
index 264c974aeb..e4cde63306 100644
--- a/scheduler/pkg/kafka/pipeline/kafkamanager.go
+++ b/scheduler/pkg/kafka/pipeline/kafkamanager.go
@@ -196,6 +196,7 @@ func (km *KafkaManager) Infer(ctx context.Context, resourceName string, isModel
 	}
 	logger.Debugf("Produce on topic %s with key %s", outputTopic, key)
 	kafkaHeaders := append(headers, kafka.Header{Key: resources.SeldonPipelineHeader, Value: []byte(resourceName)})
+	kafkaHeaders = addRequestIdToKafkaHeadersIfMissing(kafkaHeaders, requestId)
 
 	msg := &kafka.Message{
 		TopicPartition: kafka.TopicPartition{Topic: &outputTopic, Partition: kafka.PartitionAny},
diff --git a/scheduler/pkg/kafka/pipeline/utils.go b/scheduler/pkg/kafka/pipeline/utils.go
index 70fa2da30d..ea1beb4542 100644
--- a/scheduler/pkg/kafka/pipeline/utils.go
+++ b/scheduler/pkg/kafka/pipeline/utils.go
@@ -21,6 +21,8 @@ import (
 	"net/http"
 	"strings"
 
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/util"
+
 	"github.com/confluentinc/confluent-kafka-go/kafka"
 	"google.golang.org/grpc/metadata"
 
@@ -46,12 +48,26 @@ func createResourceNameFromHeader(header string) (string, bool, error) {
 		"Bad or missing header %s %s", resources.SeldonModelHeader, header)
 }
 
+func addRequestIdToKafkaHeadersIfMissing(headers []kafka.Header, requestId string) []kafka.Header {
+	for _, kafkaHeader := range headers {
+		if kafkaHeader.Key == util.RequestIdHeader { //already exists
+			return headers
+		}
+	}
+	return append(headers, kafka.Header{
+		Key:   util.RequestIdHeader,
+		Value: []byte(requestId),
+	})
+}
+
+// We ensure the Kafka headers are lower case as http headers may have been canonical uppercased
 func convertHttpHeadersToKafkaHeaders(httpHeaders http.Header) []kafka.Header {
 	var kafkaHeaders []kafka.Header
 	for k, vals := range httpHeaders {
-		if strings.HasPrefix(strings.ToLower(k), resources.ExternalHeaderPrefix) {
+		key := strings.ToLower(k)
+		if strings.HasPrefix(key, resources.ExternalHeaderPrefix) {
 			for _, headerValue := range vals {
-				kafkaHeaders = append(kafkaHeaders, kafka.Header{Key: strings.ToLower(k), Value: []byte(headerValue)})
+				kafkaHeaders = append(kafkaHeaders, kafka.Header{Key: key, Value: []byte(headerValue)})
 			}
 		}
 	}
diff --git a/scheduler/pkg/kafka/pipeline/utils_test.go b/scheduler/pkg/kafka/pipeline/utils_test.go
index 29602f47b2..0ce47d7380 100644
--- a/scheduler/pkg/kafka/pipeline/utils_test.go
+++ b/scheduler/pkg/kafka/pipeline/utils_test.go
@@ -20,6 +20,8 @@ import (
 	"net/http"
 	"testing"
 
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/util"
+
 	"github.com/confluentinc/confluent-kafka-go/kafka"
 	"google.golang.org/grpc/metadata"
 
@@ -212,3 +214,56 @@ func TestConvertKafkaHeadersToGrpcMetadata(t *testing.T) {
 		})
 	}
 }
+
+func TestAddRequestIdToKafkaHeaders(t *testing.T) {
+	g := NewGomegaWithT(t)
+
+	type test struct {
+		name              string
+		requestId         string
+		headers           []kafka.Header
+		expectedRequestId string
+	}
+
+	tests := []test{
+		{
+			name:      "request id header exists",
+			requestId: "foo",
+			headers: []kafka.Header{
+				{
+					Key:   "a",
+					Value: []byte("v1"),
+				},
+				{
+					Key:   util.RequestIdHeader,
+					Value: []byte("bar"),
+				},
+			},
+			expectedRequestId: "bar",
+		},
+		{
+			name:      "request id header does not exists",
+			requestId: "foo",
+			headers: []kafka.Header{
+				{
+					Key:   "a",
+					Value: []byte("v1"),
+				},
+			},
+			expectedRequestId: "foo",
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			httpHeaders := addRequestIdToKafkaHeadersIfMissing(test.headers, test.requestId)
+			requestId := ""
+			for _, v := range httpHeaders {
+				if v.Key == util.RequestIdHeader {
+					requestId = string(v.Value)
+				}
+			}
+			g.Expect(requestId).To(Equal(test.expectedRequestId))
+		})
+	}
+}

From e1930d27dcddf48439d7e4749013d8e25d90375f Mon Sep 17 00:00:00 2001
From: cliveseldon 
Date: Mon, 19 Dec 2022 16:10:30 +0000
Subject: [PATCH 16/18] Fix possible SIGSEV after producer close in
 modelgateway (#4515)

* Fix possible SIGSEV after producer close in modelgateway

* Set running after setup

* review comments
---
 .../kafka/gateway/{consumer.go => infer.go}   | 49 ++++++++++++++-----
 scheduler/pkg/kafka/gateway/manager.go        | 10 ++--
 scheduler/pkg/kafka/gateway/worker.go         |  6 +--
 scheduler/pkg/kafka/gateway/worker_test.go    |  8 +--
 4 files changed, 49 insertions(+), 24 deletions(-)
 rename scheduler/pkg/kafka/gateway/{consumer.go => infer.go} (87%)

diff --git a/scheduler/pkg/kafka/gateway/consumer.go b/scheduler/pkg/kafka/gateway/infer.go
similarity index 87%
rename from scheduler/pkg/kafka/gateway/consumer.go
rename to scheduler/pkg/kafka/gateway/infer.go
index ff298ecad7..85bc090380 100644
--- a/scheduler/pkg/kafka/gateway/consumer.go
+++ b/scheduler/pkg/kafka/gateway/infer.go
@@ -19,7 +19,9 @@ package gateway
 import (
 	"context"
 	"encoding/json"
+	"fmt"
 	"sync"
+	"sync/atomic"
 	"time"
 
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/util"
@@ -45,7 +47,7 @@ const (
 	defaultNumPartitions        = 1
 )
 
-type InferKafkaConsumer struct {
+type InferKafkaHandler struct {
 	logger            log.FieldLogger
 	mu                sync.RWMutex
 	loadedModels      map[string]bool
@@ -62,9 +64,11 @@ type InferKafkaConsumer struct {
 	replicationFactor int
 	numPartitions     int
 	tlsClientOptions  *util.TLSOptions
+	producerMu        sync.RWMutex
+	producerActive    atomic.Bool
 }
 
-func NewInferKafkaConsumer(logger log.FieldLogger, consumerConfig *ConsumerConfig, consumerName string) (*InferKafkaConsumer, error) {
+func NewInferKafkaHandler(logger log.FieldLogger, consumerConfig *ConsumerConfig, consumerName string) (*InferKafkaHandler, error) {
 	replicationFactor, err := util.GetIntEnvar(envDefaultReplicationFactor, defaultReplicationFactor)
 	if err != nil {
 		return nil, err
@@ -77,7 +81,7 @@ func NewInferKafkaConsumer(logger log.FieldLogger, consumerConfig *ConsumerConfi
 	if err != nil {
 		return nil, err
 	}
-	ic := &InferKafkaConsumer{
+	ic := &InferKafkaHandler{
 		logger:            logger.WithField("source", "InferConsumer"),
 		done:              make(chan bool),
 		tracer:            consumerConfig.TraceProvider.GetTraceProvider().Tracer("Worker"),
@@ -93,7 +97,7 @@ func NewInferKafkaConsumer(logger log.FieldLogger, consumerConfig *ConsumerConfi
 	return ic, ic.setup()
 }
 
-func (kc *InferKafkaConsumer) setup() error {
+func (kc *InferKafkaHandler) setup() error {
 	logger := kc.logger.WithField("func", "setup")
 	var err error
 
@@ -115,6 +119,7 @@ func (kc *InferKafkaConsumer) setup() error {
 	if err != nil {
 		return err
 	}
+	kc.producerActive.Store(true)
 	logger.Infof("Created producer %s", kc.producer.String())
 
 	consumerConfig := config.CloneKafkaConfigMap(kc.consumerConfig.KafkaConfig.Consumer)
@@ -169,11 +174,30 @@ func collectHeaders(kheaders []kafka.Header) map[string]string {
 	return headers
 }
 
-func (kc *InferKafkaConsumer) Stop() {
+func (kc *InferKafkaHandler) Produce(msg *kafka.Message, deliveryChan chan kafka.Event) error {
+	logger := kc.logger.WithField("func", "Produce")
+	kc.producerMu.RLock()
+	defer kc.producerMu.RUnlock()
+	if kc.producerActive.Load() {
+		return kc.producer.Produce(msg, deliveryChan)
+	} else {
+		err := fmt.Errorf("The infer producer %s is no longer running", kc.producer.String())
+		logger.WithError(err).Error("Failed to produce kafka message")
+		return err
+	}
+}
+
+func (kc *InferKafkaHandler) closeProducer() {
+	kc.producerMu.Lock()
+	defer kc.producerMu.Unlock()
+	kc.producer.Close()
+}
+
+func (kc *InferKafkaHandler) Stop() {
 	close(kc.done)
 }
 
-func (kc *InferKafkaConsumer) subscribeTopics() error {
+func (kc *InferKafkaHandler) subscribeTopics() error {
 	topics := make([]string, len(kc.subscribedTopics))
 	idx := 0
 	for k := range kc.subscribedTopics {
@@ -184,13 +208,13 @@ func (kc *InferKafkaConsumer) subscribeTopics() error {
 	return err
 }
 
-func (kc *InferKafkaConsumer) GetNumModels() int {
+func (kc *InferKafkaHandler) GetNumModels() int {
 	kc.mu.RLock()
 	defer kc.mu.RUnlock()
 	return len(kc.loadedModels)
 }
 
-func (kc *InferKafkaConsumer) createTopics(topicNames []string) error {
+func (kc *InferKafkaHandler) createTopics(topicNames []string) error {
 	logger := kc.logger.WithField("func", "createTopics")
 	if kc.adminClient == nil {
 		logger.Warnf("Can't create topics %v as no admin client", topicNames)
@@ -218,7 +242,7 @@ func (kc *InferKafkaConsumer) createTopics(topicNames []string) error {
 	return nil
 }
 
-func (kc *InferKafkaConsumer) AddModel(modelName string) error {
+func (kc *InferKafkaHandler) AddModel(modelName string) error {
 	kc.mu.Lock()
 	defer kc.mu.Unlock()
 	kc.loadedModels[modelName] = true
@@ -239,7 +263,7 @@ func (kc *InferKafkaConsumer) AddModel(modelName string) error {
 	return nil
 }
 
-func (kc *InferKafkaConsumer) RemoveModel(modelName string) error {
+func (kc *InferKafkaHandler) RemoveModel(modelName string) error {
 	kc.mu.Lock()
 	defer kc.mu.Unlock()
 	delete(kc.loadedModels, modelName)
@@ -254,7 +278,7 @@ func (kc *InferKafkaConsumer) RemoveModel(modelName string) error {
 	return nil
 }
 
-func (kc *InferKafkaConsumer) Serve() {
+func (kc *InferKafkaHandler) Serve() {
 	logger := kc.logger.WithField("func", "Serve").WithField("consumerName", kc.consumerName)
 	run := true
 	// create a cancel and job channel
@@ -269,6 +293,7 @@ func (kc *InferKafkaConsumer) Serve() {
 		select {
 		case <-kc.done:
 			logger.Infof("Stopping")
+			kc.producerActive.Store(false)
 			run = false
 		default:
 			ev := kc.consumer.Poll(pollTimeoutMillisecs)
@@ -329,6 +354,6 @@ func (kc *InferKafkaConsumer) Serve() {
 
 	logger.Info("Closing consumer")
 	close(cancelChan)
-	kc.producer.Close()
+	kc.closeProducer()
 	_ = kc.consumer.Close()
 }
diff --git a/scheduler/pkg/kafka/gateway/manager.go b/scheduler/pkg/kafka/gateway/manager.go
index f00855352a..95d8c366f4 100644
--- a/scheduler/pkg/kafka/gateway/manager.go
+++ b/scheduler/pkg/kafka/gateway/manager.go
@@ -35,7 +35,7 @@ type ConsumerManager struct {
 	logger log.FieldLogger
 	mu     sync.Mutex
 	// all consumers we have
-	consumers       map[string]*InferKafkaConsumer
+	consumers       map[string]*InferKafkaHandler
 	consumerConfig  *ConsumerConfig
 	maxNumConsumers int
 }
@@ -52,12 +52,12 @@ func NewConsumerManager(logger log.FieldLogger, consumerConfig *ConsumerConfig,
 	return &ConsumerManager{
 		logger:          logger.WithField("source", "ConsumerManager"),
 		consumerConfig:  consumerConfig,
-		consumers:       make(map[string]*InferKafkaConsumer),
+		consumers:       make(map[string]*InferKafkaHandler),
 		maxNumConsumers: maxNumConsumers,
 	}
 }
 
-func (cm *ConsumerManager) getInferKafkaConsumer(modelName string, create bool) (*InferKafkaConsumer, error) {
+func (cm *ConsumerManager) getInferKafkaConsumer(modelName string, create bool) (*InferKafkaHandler, error) {
 	logger := cm.logger.WithField("func", "getInferKafkaConsumer")
 	consumerBucketId := util.GetKafkaConsumerName(modelName, modelGatewayConsumerNamePrefix, cm.maxNumConsumers)
 	ic, ok := cm.consumers[consumerBucketId]
@@ -68,7 +68,7 @@ func (cm *ConsumerManager) getInferKafkaConsumer(modelName string, create bool)
 
 	if !ok {
 		var err error
-		ic, err = NewInferKafkaConsumer(cm.logger, cm.consumerConfig, consumerBucketId)
+		ic, err = NewInferKafkaHandler(cm.logger, cm.consumerConfig, consumerBucketId)
 		if err != nil {
 			return nil, err
 		}
@@ -95,7 +95,7 @@ func (cm *ConsumerManager) AddModel(modelName string) error {
 	return nil
 }
 
-func (cm *ConsumerManager) stopEmptyConsumer(ic *InferKafkaConsumer) {
+func (cm *ConsumerManager) stopEmptyConsumer(ic *InferKafkaHandler) {
 	logger := cm.logger.WithField("func", "stopEmptyConsumer")
 	numModelsInConsumer := ic.GetNumModels()
 	if numModelsInConsumer == 0 {
diff --git a/scheduler/pkg/kafka/gateway/worker.go b/scheduler/pkg/kafka/gateway/worker.go
index 27289ff141..4b68d9bb0c 100644
--- a/scheduler/pkg/kafka/gateway/worker.go
+++ b/scheduler/pkg/kafka/gateway/worker.go
@@ -58,7 +58,7 @@ type InferWorker struct {
 	logger      log.FieldLogger
 	grpcClient  v2.GRPCInferenceServiceClient
 	httpClient  *http.Client
-	consumer    *InferKafkaConsumer
+	consumer    *InferKafkaHandler
 	tracer      trace.Tracer
 	callOptions []grpc.CallOption
 	topicNamer  *kafka2.TopicNamer
@@ -74,7 +74,7 @@ type V2Error struct {
 	Error string `json:"error"`
 }
 
-func NewInferWorker(consumer *InferKafkaConsumer, logger log.FieldLogger, traceProvider *seldontracer.TracerProvider, topicNamer *kafka2.TopicNamer) (*InferWorker, error) {
+func NewInferWorker(consumer *InferKafkaHandler, logger log.FieldLogger, traceProvider *seldontracer.TracerProvider, topicNamer *kafka2.TopicNamer) (*InferWorker, error) {
 	opts := []grpc.CallOption{
 		grpc.MaxCallSendMsgSize(math.MaxInt32),
 		grpc.MaxCallRecvMsgSize(math.MaxInt32),
@@ -249,7 +249,7 @@ func (iw *InferWorker) produce(ctx context.Context, job *InferWork, topic string
 	otel.GetTextMapPropagator().Inject(ctx, carrierOut)
 
 	deliveryChan := make(chan kafka.Event)
-	err := iw.consumer.producer.Produce(msg, deliveryChan)
+	err := iw.consumer.Produce(msg, deliveryChan)
 	if err != nil {
 		iw.logger.WithError(err).Errorf("Failed to produce response for model %s", topic)
 		return err
diff --git a/scheduler/pkg/kafka/gateway/worker_test.go b/scheduler/pkg/kafka/gateway/worker_test.go
index 263140da48..3fd7c5a040 100644
--- a/scheduler/pkg/kafka/gateway/worker_test.go
+++ b/scheduler/pkg/kafka/gateway/worker_test.go
@@ -89,7 +89,7 @@ func TestRestRequest(t *testing.T) {
 			tp, err := seldontracer.NewTraceProvider("test", nil, logger)
 			g.Expect(err).To(BeNil())
 			config := &ConsumerConfig{KafkaConfig: &config.KafkaConfig{}, Namespace: "default", InferenceServerConfig: &kafkaServerConfig, TraceProvider: tp, NumWorkers: 0}
-			ic, err := NewInferKafkaConsumer(logger, config, "dummy")
+			ic, err := NewInferKafkaHandler(logger, config, "dummy")
 			g.Expect(err).To(BeNil())
 			tn := kafka2.NewTopicNamer("default")
 			iw, err := NewInferWorker(ic, logger, tp, tn)
@@ -135,7 +135,7 @@ func TestProcessRequestRest(t *testing.T) {
 			tp, err := seldontracer.NewTraceProvider("test", nil, logger)
 			g.Expect(err).To(BeNil())
 			config := &ConsumerConfig{KafkaConfig: &config.KafkaConfig{}, Namespace: "default", InferenceServerConfig: &kafkaServerConfig, TraceProvider: tp, NumWorkers: 0}
-			ic, err := NewInferKafkaConsumer(logger, config, "dummy")
+			ic, err := NewInferKafkaHandler(logger, config, "dummy")
 			g.Expect(err).To(BeNil())
 			tn := kafka2.NewTopicNamer("default")
 			iw, err := NewInferWorker(ic, logger, tp, tn)
@@ -201,14 +201,14 @@ func createInferWorkerWithMockConn(
 	logger log.FieldLogger,
 	serverConfig *InferenceServerConfig,
 	modelConfig *KafkaModelConfig,
-	g *WithT) (*InferKafkaConsumer, *InferWorker) {
+	g *WithT) (*InferKafkaHandler, *InferWorker) {
 	conn, _ := grpc.DialContext(context.TODO(), "", grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
 		return grpcServer.listener.Dial()
 	}), grpc.WithTransportCredentials(insecure.NewCredentials()))
 	tp, err := seldontracer.NewTraceProvider("test", nil, logger)
 	g.Expect(err).To(BeNil())
 	config := &ConsumerConfig{KafkaConfig: &config.KafkaConfig{}, Namespace: "default", InferenceServerConfig: serverConfig, TraceProvider: tp, NumWorkers: 0}
-	ic, err := NewInferKafkaConsumer(logger, config, "dummy")
+	ic, err := NewInferKafkaHandler(logger, config, "dummy")
 	g.Expect(err).To(BeNil())
 	iw := &InferWorker{
 		logger:     logger,

From 16b5d5fb5ddeae674e64e4c1675ff43e425cc04c Mon Sep 17 00:00:00 2001
From: RafalSkolasinski 
Date: Mon, 19 Dec 2022 17:24:10 +0000
Subject: [PATCH 17/18] Link how to install docker compose v2 from github
 releases (#4516)

* link compose github for easier installation

* Update docs/source/contents/getting-started/docker-installation/index.md

Co-authored-by: Alex Rakowski <20504869+agrski@users.noreply.github.com>

Co-authored-by: Alex Rakowski <20504869+agrski@users.noreply.github.com>
---
 .../contents/getting-started/docker-installation/index.md   | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/source/contents/getting-started/docker-installation/index.md b/docs/source/contents/getting-started/docker-installation/index.md
index 9c693adeaf..7181498f84 100644
--- a/docs/source/contents/getting-started/docker-installation/index.md
+++ b/docs/source/contents/getting-started/docker-installation/index.md
@@ -4,7 +4,7 @@
 
  1. `git clone https://github.com/SeldonIO/seldon-core --branch=v2`
  2. Build [Seldon CLI](../cli.md)
- 3. Install [Docker Compose](https://docs.docker.com/compose/install/).
+ 3. Install [Docker Compose](https://docs.docker.com/compose/install/) (or directly from GitHub [release](https://github.com/docker/compose#linux) if not using Docker Desktop).
  4. Install `make`. This will depend on your version of Linux, for example on Ubuntu run `sudo apt-get install build-essential`.
 
 
@@ -31,7 +31,7 @@ make deploy-local
 
 ### GPU support
 
-To enable GPU on servers: 
+To enable GPU on servers:
 
 1. Make sure that `nvidia-container-runtime` is installed, follow [link](https://docs.docker.com/config/containers/resource_constraints/#gpu)
 2. Enable GPU: `export GPU_ENABLED=1`
@@ -48,7 +48,7 @@ make deploy-local
 
 This folder will be mounted at `/mnt/models`. You can then specify models as shown below:
 
-```{literalinclude} ../../../../../samples/models/sklearn-iris-local.yaml 
+```{literalinclude} ../../../../../samples/models/sklearn-iris-local.yaml
 :language: yaml
 ```
 

From 29f1aa4e74a86aefd7068204bead07bf0cbbf531 Mon Sep 17 00:00:00 2001
From: Clive Cox 
Date: Thu, 29 Dec 2022 14:58:43 +0000
Subject: [PATCH 18/18] review comments

---
 docs/source/contents/pipelines/index.md    |  2 +-
 scheduler/pkg/kafka/dataflow/server.go     |  4 ++++
 scheduler/pkg/kafka/topics.go              | 13 ++++++++----
 scheduler/pkg/store/pipeline/utils_test.go | 24 ++++++++++++++++++++++
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/docs/source/contents/pipelines/index.md b/docs/source/contents/pipelines/index.md
index 4d269fbc52..ae61b56893 100644
--- a/docs/source/contents/pipelines/index.md
+++ b/docs/source/contents/pipelines/index.md
@@ -157,7 +157,7 @@ There is also an `externalTriggers` section which allows triggers from other pip
 Further examples can be found in the [pipeline-to-pipeline examples](../examples/pipeline-to-pipeline.md).
 
 Present caveats:
- * Circular dependencies are not detected.
+ * Circular dependencies are not presently detected.
  * Pipeline status is local to each pipeline.
 
 ## Data Centric Implementation
diff --git a/scheduler/pkg/kafka/dataflow/server.go b/scheduler/pkg/kafka/dataflow/server.go
index 49d417bc26..c1b835fa2f 100644
--- a/scheduler/pkg/kafka/dataflow/server.go
+++ b/scheduler/pkg/kafka/dataflow/server.go
@@ -168,10 +168,14 @@ func (c *ChainerServer) StopSendPipelineEvents() {
 	}
 }
 
+// Create the topics for pipeline inputs
+// This will be pipeline inputs/outputs or model topics
 func (c *ChainerServer) createPipelineTopicSources(inputs []string) []*chainer.PipelineTopic {
 	var pipelineTopics []*chainer.PipelineTopic
 	for _, inp := range inputs {
+		// The pipeline name being referred to by the input specification
 		pipelineName := c.topicNamer.GetPipelineNameFromInput(inp)
+		// The topic being referred to: either pipeline or model
 		source := c.topicNamer.GetModelOrPipelineTopic(pipelineName, c.topicNamer.CreateStepReferenceFromPipelineInput(inp))
 		pipelineTopics = append(pipelineTopics, &chainer.PipelineTopic{PipelineName: pipelineName, TopicName: source})
 	}
diff --git a/scheduler/pkg/kafka/topics.go b/scheduler/pkg/kafka/topics.go
index e864ee1b4c..73e73728ad 100644
--- a/scheduler/pkg/kafka/topics.go
+++ b/scheduler/pkg/kafka/topics.go
@@ -94,9 +94,9 @@ func (tn *TopicNamer) GetModelOrPipelineTopic(pipelineName string, stepReference
 
 }
 
-func (tn *TopicNamer) GetFullyQualifiedTensorMap(pipelineName string, tin map[string]string) []*chainer.PipelineTensorMapping {
+func (tn *TopicNamer) GetFullyQualifiedTensorMap(pipelineName string, userTensorMap map[string]string) []*chainer.PipelineTensorMapping {
 	var mappings []*chainer.PipelineTensorMapping
-	for k, v := range tin {
+	for k, v := range userTensorMap {
 		stepName := strings.Split(k, pipeline.StepNameSeperator)[0]
 		var topicAndTensor string
 		if stepName == pipelineName {
@@ -119,9 +119,10 @@ func (tn *TopicNamer) GetFullyQualifiedPipelineTensorMap(tin map[string]string)
 		parts := strings.Split(k, pipeline.StepNameSeperator)
 		var topicAndTensor string
 		switch len(parts) {
-		case 3:
+		case 3: // A pipeline reference ..
 			topicAndTensor = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, pipelineTopic, k)
-		case 5: // take value after .step
+		case 5: // A fully qualified pipeline step tensor  .step...
+			// take value after .step
 			topicAndTensor = fmt.Sprintf("%s.%s.%s.%s", seldonTopicPrefix, tn.namespace, modelTopic, strings.Join(parts[2:], pipeline.StepNameSeperator))
 		}
 		mappings = append(mappings, &chainer.PipelineTensorMapping{
@@ -133,10 +134,14 @@ func (tn *TopicNamer) GetFullyQualifiedPipelineTensorMap(tin map[string]string)
 	return mappings
 }
 
+// Always the initial part for pipeline inputs
+// . etc
 func (tn *TopicNamer) GetPipelineNameFromInput(inputSpecifier string) string {
 	return strings.Split(inputSpecifier, pipeline.StepNameSeperator)[0]
 }
 
+// if pipelineInput return it: .
+// If pipeline step return stepName (which is a model reference) onwards: .step...(tensorName)?
 func (tn *TopicNamer) CreateStepReferenceFromPipelineInput(pipelineInputs string) string {
 	parts := strings.Split(pipelineInputs, pipeline.StepNameSeperator)
 	switch parts[1] {
diff --git a/scheduler/pkg/store/pipeline/utils_test.go b/scheduler/pkg/store/pipeline/utils_test.go
index d9af0df517..cba0cdd685 100644
--- a/scheduler/pkg/store/pipeline/utils_test.go
+++ b/scheduler/pkg/store/pipeline/utils_test.go
@@ -375,5 +375,29 @@ func TestCreatePipelineFromProto(t *testing.T) {
 			}
 		})
 	}
+}
+
+func TestUpdateExternalInputSteps(t *testing.T) {
+	g := NewGomegaWithT(t)
+	type test struct {
+		name         string
+		pipelineName string
+		inputs       []string
+		expected     []string
+	}
 
+	tests := []test{
+		{
+			name:         "test update external inputs",
+			pipelineName: "pipeline",
+			inputs:       []string{"p1", "p1.outputs", "p1.inputs", "p1.inputs.t1", "p1.step.m1", "p1.step.m1.outputs.t1"},
+			expected:     []string{"p1.outputs", "p1.outputs", "p1.inputs", "p1.inputs.t1", "p1.step.m1.outputs", "p1.step.m1.outputs.t1"},
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			updated := updateExternalInputSteps(test.inputs)
+			g.Expect(updated).To(Equal(test.expected))
+		})
+	}
 }