diff --git a/pkg/apis/manager/v1beta1/api.pb.go b/pkg/apis/manager/v1beta1/api.pb.go index 31c7c1d449b..5599ceb9405 100644 --- a/pkg/apis/manager/v1beta1/api.pb.go +++ b/pkg/apis/manager/v1beta1/api.pb.go @@ -41,6 +41,8 @@ It has these top-level messages: GetEarlyStoppingRulesRequest GetEarlyStoppingRulesReply EarlyStoppingRule + ValidateEarlyStoppingSettingsRequest + ValidateEarlyStoppingSettingsReply SetTrialStatusRequest SetTrialStatusReply */ @@ -1214,6 +1216,36 @@ func (m *EarlyStoppingRule) GetStartStep() int32 { return 0 } +type ValidateEarlyStoppingSettingsRequest struct { + EarlyStoppingSpec *EarlyStoppingSpec `protobuf:"bytes,1,opt,name=early_stopping_spec,json=earlyStoppingSpec" json:"early_stopping_spec,omitempty"` +} + +func (m *ValidateEarlyStoppingSettingsRequest) Reset() { *m = ValidateEarlyStoppingSettingsRequest{} } +func (m *ValidateEarlyStoppingSettingsRequest) String() string { return proto.CompactTextString(m) } +func (*ValidateEarlyStoppingSettingsRequest) ProtoMessage() {} +func (*ValidateEarlyStoppingSettingsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{33} +} + +func (m *ValidateEarlyStoppingSettingsRequest) GetEarlyStoppingSpec() *EarlyStoppingSpec { + if m != nil { + return m.EarlyStoppingSpec + } + return nil +} + +// * +// Return INVALID_ARGUMENT Error if Early Stopping Settings are not Valid +type ValidateEarlyStoppingSettingsReply struct { +} + +func (m *ValidateEarlyStoppingSettingsReply) Reset() { *m = ValidateEarlyStoppingSettingsReply{} } +func (m *ValidateEarlyStoppingSettingsReply) String() string { return proto.CompactTextString(m) } +func (*ValidateEarlyStoppingSettingsReply) ProtoMessage() {} +func (*ValidateEarlyStoppingSettingsReply) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{34} +} + type SetTrialStatusRequest struct { TrialName string `protobuf:"bytes,1,opt,name=trial_name,json=trialName" json:"trial_name,omitempty"` } @@ -1221,7 +1253,7 @@ type SetTrialStatusRequest struct { func (m *SetTrialStatusRequest) Reset() { *m = SetTrialStatusRequest{} } func (m *SetTrialStatusRequest) String() string { return proto.CompactTextString(m) } func (*SetTrialStatusRequest) ProtoMessage() {} -func (*SetTrialStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } +func (*SetTrialStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } func (m *SetTrialStatusRequest) GetTrialName() string { if m != nil { @@ -1236,7 +1268,7 @@ type SetTrialStatusReply struct { func (m *SetTrialStatusReply) Reset() { *m = SetTrialStatusReply{} } func (m *SetTrialStatusReply) String() string { return proto.CompactTextString(m) } func (*SetTrialStatusReply) ProtoMessage() {} -func (*SetTrialStatusReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } +func (*SetTrialStatusReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } func init() { proto.RegisterType((*Experiment)(nil), "api.v1.beta1.Experiment") @@ -1277,6 +1309,8 @@ func init() { proto.RegisterType((*GetEarlyStoppingRulesRequest)(nil), "api.v1.beta1.GetEarlyStoppingRulesRequest") proto.RegisterType((*GetEarlyStoppingRulesReply)(nil), "api.v1.beta1.GetEarlyStoppingRulesReply") proto.RegisterType((*EarlyStoppingRule)(nil), "api.v1.beta1.EarlyStoppingRule") + proto.RegisterType((*ValidateEarlyStoppingSettingsRequest)(nil), "api.v1.beta1.ValidateEarlyStoppingSettingsRequest") + proto.RegisterType((*ValidateEarlyStoppingSettingsReply)(nil), "api.v1.beta1.ValidateEarlyStoppingSettingsReply") proto.RegisterType((*SetTrialStatusRequest)(nil), "api.v1.beta1.SetTrialStatusRequest") proto.RegisterType((*SetTrialStatusReply)(nil), "api.v1.beta1.SetTrialStatusReply") proto.RegisterEnum("api.v1.beta1.ParameterType", ParameterType_name, ParameterType_value) @@ -1543,6 +1577,7 @@ var _Suggestion_serviceDesc = grpc.ServiceDesc{ type EarlyStoppingClient interface { GetEarlyStoppingRules(ctx context.Context, in *GetEarlyStoppingRulesRequest, opts ...grpc.CallOption) (*GetEarlyStoppingRulesReply, error) SetTrialStatus(ctx context.Context, in *SetTrialStatusRequest, opts ...grpc.CallOption) (*SetTrialStatusReply, error) + ValidateEarlyStoppingSettings(ctx context.Context, in *ValidateEarlyStoppingSettingsRequest, opts ...grpc.CallOption) (*ValidateEarlyStoppingSettingsReply, error) } type earlyStoppingClient struct { @@ -1571,11 +1606,21 @@ func (c *earlyStoppingClient) SetTrialStatus(ctx context.Context, in *SetTrialSt return out, nil } +func (c *earlyStoppingClient) ValidateEarlyStoppingSettings(ctx context.Context, in *ValidateEarlyStoppingSettingsRequest, opts ...grpc.CallOption) (*ValidateEarlyStoppingSettingsReply, error) { + out := new(ValidateEarlyStoppingSettingsReply) + err := grpc.Invoke(ctx, "/api.v1.beta1.EarlyStopping/ValidateEarlyStoppingSettings", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for EarlyStopping service type EarlyStoppingServer interface { GetEarlyStoppingRules(context.Context, *GetEarlyStoppingRulesRequest) (*GetEarlyStoppingRulesReply, error) SetTrialStatus(context.Context, *SetTrialStatusRequest) (*SetTrialStatusReply, error) + ValidateEarlyStoppingSettings(context.Context, *ValidateEarlyStoppingSettingsRequest) (*ValidateEarlyStoppingSettingsReply, error) } func RegisterEarlyStoppingServer(s *grpc.Server, srv EarlyStoppingServer) { @@ -1618,6 +1663,24 @@ func _EarlyStopping_SetTrialStatus_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _EarlyStopping_ValidateEarlyStoppingSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidateEarlyStoppingSettingsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EarlyStoppingServer).ValidateEarlyStoppingSettings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.v1.beta1.EarlyStopping/ValidateEarlyStoppingSettings", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EarlyStoppingServer).ValidateEarlyStoppingSettings(ctx, req.(*ValidateEarlyStoppingSettingsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _EarlyStopping_serviceDesc = grpc.ServiceDesc{ ServiceName: "api.v1.beta1.EarlyStopping", HandlerType: (*EarlyStoppingServer)(nil), @@ -1630,6 +1693,10 @@ var _EarlyStopping_serviceDesc = grpc.ServiceDesc{ MethodName: "SetTrialStatus", Handler: _EarlyStopping_SetTrialStatus_Handler, }, + { + MethodName: "ValidateEarlyStoppingSettings", + Handler: _EarlyStopping_ValidateEarlyStoppingSettings_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api.proto", @@ -1638,120 +1705,123 @@ var _EarlyStopping_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("api.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 1826 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdd, 0x72, 0x1b, 0x49, - 0x15, 0xce, 0xe8, 0xc7, 0xce, 0x1c, 0x59, 0xf2, 0xa4, 0x2d, 0x67, 0x65, 0x67, 0xd9, 0x38, 0x03, - 0x64, 0xb3, 0x49, 0x4a, 0x24, 0x06, 0x52, 0xa1, 0x36, 0x14, 0xc8, 0xd2, 0xc4, 0xa5, 0xac, 0x2c, - 0x39, 0x2d, 0x19, 0xb2, 0x2c, 0x55, 0x53, 0x6d, 0xa9, 0xa3, 0x9d, 0x30, 0x7f, 0xcc, 0xb4, 0x52, - 0x11, 0x5c, 0x52, 0xcb, 0x1d, 0x17, 0x54, 0x71, 0xc5, 0x2b, 0x70, 0xc9, 0x0b, 0x70, 0xc5, 0x03, - 0x50, 0x5c, 0x70, 0xcb, 0x03, 0xf0, 0x0e, 0x54, 0xf7, 0x8c, 0xe6, 0x4f, 0x23, 0xc5, 0xf6, 0xc2, - 0xde, 0x4d, 0x9f, 0xf3, 0x9d, 0xee, 0xf3, 0xd3, 0xe7, 0xa7, 0x07, 0x64, 0xe2, 0x1a, 0x4d, 0xd7, - 0x73, 0x98, 0x83, 0xb6, 0xf8, 0xe7, 0xdb, 0xc7, 0xcd, 0x73, 0xca, 0xc8, 0x63, 0x15, 0x03, 0x68, - 0xef, 0x5c, 0xea, 0x19, 0x16, 0xb5, 0x19, 0x42, 0x50, 0xb2, 0x89, 0x45, 0x1b, 0xd2, 0x81, 0x74, - 0x4f, 0xc6, 0xe2, 0x1b, 0x3d, 0x82, 0x92, 0xef, 0xd2, 0x71, 0xa3, 0x70, 0x20, 0xdd, 0xab, 0x1c, - 0x7e, 0xd8, 0x4c, 0x8a, 0x37, 0x63, 0xd9, 0xa1, 0x4b, 0xc7, 0x58, 0x20, 0xd5, 0xaf, 0x4a, 0x50, - 0x4b, 0x33, 0xd0, 0x08, 0xb6, 0x5d, 0xe2, 0x11, 0x8b, 0x32, 0xea, 0xe9, 0x1c, 0xe4, 0x8b, 0x33, - 0x2a, 0x87, 0x0f, 0xd6, 0xed, 0xd7, 0x3c, 0x5d, 0xc8, 0xf0, 0x95, 0x8f, 0x6b, 0x6e, 0x6a, 0x8d, - 0x7e, 0x04, 0xb2, 0x73, 0xfe, 0x86, 0x8e, 0x99, 0xf1, 0x96, 0x86, 0xfa, 0xdd, 0x4a, 0xef, 0x37, - 0x58, 0xb0, 0x85, 0x7a, 0x31, 0x9a, 0x8b, 0x12, 0x73, 0xea, 0x78, 0x06, 0xfb, 0xd2, 0x6a, 0x14, - 0xf3, 0x44, 0x5b, 0x0b, 0x76, 0x20, 0x1a, 0xa1, 0xd1, 0x73, 0xa8, 0x51, 0xe2, 0x99, 0x73, 0xdd, - 0x67, 0x8e, 0xeb, 0x1a, 0xf6, 0xb4, 0x51, 0x12, 0xf2, 0xb7, 0x33, 0xa6, 0x70, 0xcc, 0x30, 0x84, - 0x88, 0x3d, 0xaa, 0x34, 0x49, 0x42, 0x8f, 0xa0, 0xce, 0xed, 0x31, 0x4d, 0x6a, 0xea, 0xcc, 0x33, - 0x88, 0xa9, 0x8f, 0x9d, 0x99, 0xcd, 0x1a, 0xe5, 0x03, 0xe9, 0x5e, 0x19, 0xa3, 0x05, 0x6f, 0xc4, - 0x59, 0x6d, 0xce, 0x41, 0x77, 0x61, 0xdb, 0x22, 0xef, 0x52, 0xe0, 0x0d, 0x01, 0xae, 0x5a, 0xe4, - 0x5d, 0x02, 0xf7, 0x04, 0xc0, 0x26, 0xbe, 0x3e, 0x76, 0xec, 0xd7, 0xc6, 0xb4, 0xb1, 0x29, 0xb4, - 0xfb, 0x20, 0xad, 0x5d, 0x9f, 0xf8, 0x6d, 0xc1, 0xc6, 0xb2, 0xbd, 0xf8, 0xdc, 0x3f, 0x81, 0x5a, - 0xda, 0xe3, 0xe8, 0x53, 0x80, 0xc8, 0xe7, 0x3c, 0x64, 0xc5, 0x65, 0x3f, 0xa5, 0x24, 0x70, 0x02, - 0xae, 0xfe, 0x45, 0x82, 0x6a, 0x8a, 0x9b, 0x7b, 0xbf, 0x8e, 0x20, 0x0e, 0xab, 0xce, 0xe6, 0x6e, - 0x10, 0xc9, 0xda, 0xca, 0x63, 0x46, 0x73, 0x97, 0xe2, 0xaa, 0x9b, 0x5c, 0xf2, 0x3d, 0x5e, 0x53, - 0xe2, 0x1b, 0xe7, 0x26, 0xd5, 0x7d, 0x97, 0x8c, 0x69, 0x7e, 0x48, 0x9f, 0x87, 0x98, 0x21, 0x87, - 0xe0, 0xea, 0xeb, 0xe4, 0x52, 0xfd, 0x02, 0xaa, 0x29, 0x3e, 0x52, 0xa0, 0x68, 0x91, 0x77, 0xa1, - 0xae, 0xfc, 0x53, 0x50, 0x0c, 0x5b, 0xe8, 0xc7, 0x29, 0x86, 0xcd, 0x0d, 0x32, 0x0d, 0x9f, 0x35, - 0x8a, 0x07, 0x45, 0x6e, 0x10, 0xff, 0xe6, 0x34, 0x9f, 0x51, 0x57, 0xdc, 0x0a, 0x19, 0x8b, 0x6f, - 0xf5, 0x6f, 0x12, 0x54, 0x53, 0x77, 0x11, 0x7d, 0x0f, 0x4a, 0xc2, 0x58, 0x29, 0xcf, 0xd8, 0x08, - 0x2a, 0x8c, 0x15, 0x40, 0xbe, 0xed, 0xd4, 0x21, 0xa6, 0x38, 0x5d, 0xc2, 0xe2, 0x1b, 0x1d, 0xc2, - 0x6e, 0x74, 0xa5, 0x75, 0x8b, 0x32, 0xcf, 0x18, 0xeb, 0xc2, 0xc1, 0x45, 0x71, 0xf6, 0x4e, 0xc4, - 0x3c, 0x11, 0xbc, 0x3e, 0xf7, 0xf7, 0x13, 0xf8, 0x80, 0x4c, 0x26, 0x06, 0x33, 0x1c, 0x9b, 0x98, - 0x49, 0x21, 0xbf, 0x51, 0x12, 0x56, 0xec, 0xc6, 0xec, 0x58, 0xcc, 0x57, 0xbf, 0x92, 0xa0, 0x9a, - 0xca, 0x09, 0xf4, 0x5d, 0xa8, 0x45, 0x59, 0xa1, 0x27, 0xe2, 0x5a, 0x8d, 0xa8, 0xe2, 0xc0, 0x13, - 0x40, 0x31, 0xcc, 0xa7, 0x8c, 0x19, 0xf6, 0xd4, 0x6f, 0x14, 0xc4, 0x5d, 0xfa, 0x68, 0x55, 0xce, - 0x05, 0x30, 0x7c, 0x83, 0x64, 0x28, 0xbe, 0xfa, 0x0c, 0x94, 0x2c, 0x2c, 0xf7, 0x5e, 0xd5, 0xa1, - 0xfc, 0x96, 0x98, 0x33, 0x1a, 0x86, 0x2b, 0x58, 0xa8, 0x7f, 0x90, 0xe0, 0xc6, 0x52, 0x66, 0x5e, - 0xd4, 0x92, 0x97, 0x6b, 0x2c, 0x51, 0xd7, 0x65, 0xff, 0x6a, 0x6b, 0x7e, 0x0a, 0xf5, 0x3c, 0xe8, - 0x25, 0x2c, 0xfa, 0x87, 0x04, 0x72, 0x94, 0xcd, 0xe8, 0x19, 0x6c, 0x4d, 0x3d, 0xe2, 0x7e, 0xb9, - 0x48, 0xfe, 0xa0, 0xca, 0xee, 0xa5, 0x95, 0x3b, 0xe6, 0x88, 0x30, 0xfd, 0x2b, 0xd3, 0x78, 0x81, - 0x8e, 0x00, 0x1c, 0x97, 0x7a, 0x84, 0x47, 0xdf, 0x0f, 0x2b, 0xaa, 0xba, 0xa2, 0x70, 0x34, 0x07, - 0x11, 0x12, 0x27, 0xa4, 0xf6, 0xdb, 0x00, 0x31, 0x07, 0xfd, 0x10, 0xe4, 0x88, 0x17, 0xd6, 0x8f, - 0x4c, 0x25, 0x8a, 0xc0, 0x38, 0x46, 0xaa, 0x2e, 0x54, 0x12, 0x4a, 0xa2, 0x6f, 0x01, 0xd8, 0x33, - 0x4b, 0x37, 0xc9, 0x3c, 0x28, 0x43, 0xbc, 0xe6, 0xc9, 0xf6, 0xcc, 0xea, 0x09, 0x02, 0xba, 0x0d, - 0x15, 0xc3, 0x76, 0x67, 0x4c, 0xf7, 0x8d, 0xdf, 0xd0, 0x20, 0x20, 0x65, 0x0c, 0x82, 0x34, 0xe4, - 0x14, 0x74, 0x07, 0xb6, 0x9c, 0x19, 0x8b, 0x11, 0x45, 0x81, 0xa8, 0x04, 0x34, 0x01, 0x11, 0x6e, - 0x8c, 0x54, 0xe1, 0x17, 0x22, 0x52, 0x46, 0x8f, 0xf2, 0x54, 0xc6, 0xd5, 0x88, 0x2a, 0xea, 0xce, - 0x60, 0xb9, 0xad, 0x05, 0x4e, 0xbb, 0xbb, 0xc2, 0xc6, 0xf7, 0x74, 0xb4, 0xff, 0x75, 0x05, 0xfe, - 0x2d, 0x94, 0x45, 0x5b, 0xc8, 0xbd, 0x4e, 0x0f, 0x52, 0x8d, 0x3d, 0x13, 0x15, 0x21, 0x16, 0xf7, - 0x74, 0xf4, 0x18, 0x36, 0x7c, 0x46, 0xd8, 0xcc, 0x0f, 0x2b, 0xeb, 0x5e, 0x1e, 0x5c, 0x00, 0x70, - 0x08, 0x54, 0x7f, 0x5f, 0x00, 0x39, 0xda, 0xe6, 0xeb, 0xf4, 0x6a, 0x02, 0xbb, 0xb1, 0x97, 0x89, - 0xef, 0x1b, 0x53, 0x9b, 0x4f, 0x08, 0x0b, 0x55, 0x1e, 0xae, 0xd0, 0x3c, 0xf6, 0x4b, 0x2b, 0x96, - 0xc1, 0x75, 0x37, 0x87, 0xba, 0xff, 0x05, 0xd4, 0xf3, 0xd0, 0xa8, 0x0d, 0x95, 0xe4, 0x81, 0x81, - 0xfb, 0xef, 0xac, 0x70, 0x7f, 0x2c, 0x88, 0x93, 0x52, 0xea, 0x4f, 0x60, 0x27, 0x07, 0x73, 0x89, - 0x14, 0xff, 0x67, 0x01, 0x2a, 0x09, 0x0f, 0xf3, 0x74, 0xf0, 0x19, 0xf1, 0x98, 0xce, 0x8c, 0x48, - 0x5e, 0x16, 0x94, 0x91, 0x61, 0x51, 0xf4, 0x31, 0x6c, 0x8f, 0x1d, 0xcb, 0x35, 0x69, 0x70, 0x7b, - 0x39, 0x26, 0xd8, 0xae, 0x16, 0x93, 0x05, 0xf0, 0x05, 0xc8, 0x63, 0xc7, 0x0e, 0x8a, 0xbd, 0x70, - 0x66, 0x2d, 0xdf, 0x99, 0xe2, 0xd4, 0x66, 0x38, 0x60, 0x84, 0x78, 0xd1, 0x99, 0x62, 0x71, 0xf4, - 0x29, 0x54, 0x9c, 0x73, 0x9f, 0x7a, 0x6f, 0x83, 0x54, 0x2f, 0xe5, 0xdd, 0x92, 0x41, 0x0c, 0xc0, - 0x49, 0xb4, 0xca, 0x00, 0x2d, 0xef, 0x8e, 0x2a, 0xb0, 0xd9, 0xc6, 0x5a, 0x6b, 0xa4, 0x75, 0x94, - 0x6b, 0x7c, 0x81, 0xcf, 0xfa, 0xfd, 0x6e, 0xff, 0x58, 0x91, 0x50, 0x15, 0xe4, 0xe1, 0x59, 0xbb, - 0xad, 0x69, 0x1d, 0xad, 0xa3, 0x14, 0x10, 0xc0, 0xc6, 0x67, 0xdd, 0x5e, 0x4f, 0xeb, 0x28, 0x45, - 0xfe, 0xfd, 0xbc, 0xd5, 0xe5, 0xdf, 0x25, 0xa4, 0xc0, 0x96, 0xd6, 0xc2, 0xbd, 0xcf, 0x87, 0xa3, - 0xc1, 0xe9, 0xa9, 0xd6, 0x51, 0xca, 0x7c, 0x97, 0xb3, 0xfe, 0x67, 0xfd, 0xc1, 0xcf, 0xfb, 0xca, - 0x86, 0xfa, 0x63, 0xa8, 0x24, 0x34, 0x42, 0x4d, 0xd8, 0x0c, 0xba, 0xe1, 0x22, 0xce, 0xf5, 0xb4, - 0xf6, 0x41, 0x33, 0xc4, 0x0b, 0x90, 0x7a, 0x08, 0x1b, 0x01, 0xe9, 0x12, 0x91, 0xfc, 0x9d, 0x04, - 0xb7, 0x30, 0x75, 0x1d, 0x8f, 0x25, 0x4e, 0xee, 0x39, 0x53, 0x4c, 0x7f, 0x3d, 0xa3, 0x3e, 0xe3, - 0x91, 0x0d, 0xa6, 0xbb, 0xc4, 0x7e, 0xb2, 0xa0, 0x88, 0x06, 0xa4, 0xc1, 0x76, 0xc2, 0x6d, 0xba, - 0xe9, 0x4c, 0xf3, 0xc7, 0xf2, 0xcc, 0xe6, 0x35, 0x27, 0xb5, 0x56, 0x6f, 0xc1, 0x5e, 0xbe, 0x12, - 0xae, 0x39, 0x57, 0x5f, 0x40, 0x2d, 0x4d, 0x46, 0x4f, 0xa1, 0x12, 0x8e, 0x09, 0xa6, 0x33, 0xf5, - 0xf3, 0xab, 0x78, 0xe0, 0x09, 0xbe, 0x09, 0x58, 0x8b, 0x4f, 0x5f, 0x7d, 0x05, 0x72, 0xc4, 0x10, - 0xb6, 0x19, 0x16, 0xd5, 0x7d, 0x46, 0x2c, 0x37, 0xb2, 0xcd, 0xb0, 0xe8, 0x90, 0x13, 0xd0, 0x43, - 0xd8, 0x08, 0x24, 0x43, 0x93, 0xf2, 0xbd, 0x1f, 0x62, 0xd4, 0x3f, 0x49, 0xd0, 0x38, 0xa6, 0x57, - 0xf3, 0xe2, 0xed, 0xc8, 0x1e, 0xc1, 0x0f, 0x02, 0x14, 0xaa, 0x2d, 0x00, 0xe9, 0xfc, 0x2a, 0x66, - 0xf3, 0x6b, 0x0f, 0xae, 0x53, 0x7b, 0x12, 0x30, 0x83, 0x21, 0x6f, 0x93, 0xda, 0x13, 0xce, 0x52, - 0x75, 0xb8, 0x99, 0xa3, 0x95, 0x6b, 0xce, 0xf3, 0x42, 0x27, 0x5d, 0x21, 0x74, 0xcf, 0xe0, 0x56, - 0x87, 0x9a, 0x94, 0xd1, 0xab, 0x58, 0xce, 0x03, 0x9f, 0x2f, 0xcd, 0x03, 0xff, 0xc7, 0x02, 0xec, - 0x1e, 0x53, 0x36, 0x9c, 0x4d, 0xa7, 0xd4, 0x0f, 0xfa, 0x7a, 0xb8, 0xeb, 0x53, 0x00, 0x1a, 0x3d, - 0xcc, 0x42, 0xb5, 0x1b, 0xab, 0x1e, 0x6e, 0x38, 0x81, 0x45, 0x0f, 0x60, 0x43, 0x9c, 0xbe, 0x98, - 0x92, 0x76, 0x72, 0xca, 0x0b, 0x0e, 0x21, 0xe8, 0x13, 0xa8, 0x79, 0xc1, 0x89, 0xba, 0x3d, 0xb3, - 0xce, 0xa9, 0x27, 0x5c, 0x5f, 0x3e, 0x2a, 0x34, 0x24, 0x5c, 0x0d, 0x39, 0x7d, 0xc1, 0x40, 0x3f, - 0x80, 0x9b, 0xe3, 0x99, 0xe7, 0x51, 0x9b, 0xe9, 0x19, 0x91, 0x92, 0x18, 0x0e, 0xea, 0x21, 0x17, - 0xa7, 0xa4, 0x1e, 0x41, 0x9d, 0x39, 0x8c, 0x98, 0x59, 0x99, 0xf0, 0xc5, 0x25, 0x78, 0x29, 0x09, - 0xf5, 0x3f, 0x05, 0xd8, 0xc9, 0xfa, 0x84, 0x47, 0xf3, 0x57, 0xab, 0x5a, 0x52, 0x90, 0x1c, 0x4f, - 0x32, 0xf3, 0xd6, 0xf2, 0x0e, 0x97, 0x68, 0x4e, 0xe9, 0xb7, 0x6a, 0xe1, 0x52, 0x6f, 0xd5, 0x97, - 0x50, 0x4f, 0xbf, 0x55, 0x75, 0x6f, 0x66, 0x86, 0x03, 0xd0, 0xfa, 0x17, 0x2b, 0x9e, 0x99, 0x14, - 0x23, 0x9a, 0x25, 0xfd, 0x9f, 0x5b, 0xe5, 0x2f, 0xe1, 0xe0, 0x67, 0xc4, 0x34, 0x26, 0x84, 0xd1, - 0xec, 0x90, 0xff, 0xf5, 0x6f, 0xa3, 0x7a, 0x00, 0x1f, 0xad, 0xd9, 0x9d, 0xe7, 0xc0, 0x5f, 0x25, - 0xf8, 0xf0, 0x98, 0xb2, 0x25, 0x4f, 0x7c, 0xd3, 0xa9, 0xf0, 0x10, 0xd0, 0xe4, 0x5c, 0xb7, 0x88, - 0x4d, 0xa6, 0xfc, 0x82, 0x4d, 0x26, 0x1e, 0xf5, 0xfd, 0xb0, 0x12, 0x29, 0x93, 0xf3, 0x93, 0x80, - 0xd1, 0x0a, 0xe8, 0xaa, 0x03, 0xfb, 0x2b, 0x94, 0xe6, 0x77, 0x75, 0xd5, 0x1d, 0x90, 0xae, 0x7c, - 0x07, 0xd4, 0x3f, 0x67, 0x5f, 0x51, 0x9c, 0x7c, 0xf1, 0x36, 0x88, 0x9e, 0x01, 0xf0, 0x51, 0x84, - 0x78, 0x86, 0x1f, 0x4d, 0x1e, 0x99, 0x3a, 0xd8, 0x8e, 0xf8, 0x62, 0xd2, 0x48, 0xe0, 0xe3, 0xf2, - 0x1c, 0x3d, 0xb3, 0xcb, 0x61, 0x79, 0x1e, 0xf2, 0xb7, 0xf6, 0x13, 0xd8, 0x1d, 0x52, 0x96, 0x9c, - 0x48, 0x2f, 0x56, 0x1c, 0x77, 0x61, 0x27, 0x2b, 0xe7, 0x9a, 0xf3, 0xfb, 0x67, 0x89, 0x9f, 0x18, - 0x62, 0x2c, 0x51, 0x60, 0x2b, 0x9c, 0x21, 0xf4, 0xd1, 0xe7, 0xa7, 0x9a, 0x72, 0x8d, 0xcf, 0x1c, - 0x9d, 0xc1, 0xd9, 0x51, 0x4f, 0x53, 0x24, 0xb4, 0x09, 0xc5, 0x6e, 0x7f, 0xa4, 0x14, 0xd0, 0x16, - 0x5c, 0xef, 0x74, 0x87, 0x6d, 0xac, 0x8d, 0x34, 0xa5, 0x88, 0xb6, 0xa1, 0xd2, 0x6e, 0x8d, 0xb4, - 0xe3, 0x01, 0xee, 0xb6, 0x5b, 0x3d, 0xa5, 0x74, 0xff, 0x69, 0xe2, 0x87, 0xc0, 0x62, 0xda, 0x59, - 0x8c, 0x26, 0xd7, 0xb8, 0xf0, 0x49, 0xb7, 0xdf, 0x3d, 0xe9, 0xfe, 0x82, 0xef, 0xc9, 0x57, 0xad, - 0x57, 0xc1, 0xaa, 0x70, 0xff, 0x05, 0xd4, 0xd2, 0xce, 0x41, 0x37, 0x01, 0x2d, 0x34, 0x6a, 0x0f, - 0x4e, 0x4e, 0x5b, 0xb8, 0x3b, 0x1c, 0xf0, 0x5d, 0x64, 0x28, 0x6b, 0x2f, 0xcf, 0x5a, 0x3d, 0x45, - 0x42, 0xd7, 0xa1, 0xd4, 0xd3, 0x86, 0x43, 0xa5, 0xc0, 0xcf, 0x39, 0x16, 0x53, 0x15, 0x56, 0x8a, - 0x87, 0x7f, 0x2f, 0x80, 0xdc, 0x39, 0x0a, 0xaf, 0x13, 0x7a, 0x03, 0xf5, 0xbc, 0xb9, 0x00, 0x7d, - 0x92, 0x0e, 0xcd, 0x9a, 0x01, 0x66, 0xff, 0xe3, 0x8b, 0x40, 0xf9, 0xad, 0x24, 0x70, 0x63, 0xa9, - 0x53, 0xa2, 0xbb, 0x4b, 0x75, 0x33, 0xff, 0x94, 0xef, 0xbc, 0x17, 0xc7, 0x8f, 0x78, 0x03, 0xf5, - 0xbc, 0x6e, 0x97, 0x35, 0x67, 0x4d, 0x3f, 0xcd, 0x9a, 0xb3, 0xb2, 0x79, 0x1e, 0xfe, 0x5b, 0x02, - 0x88, 0x6b, 0x3c, 0x7a, 0x05, 0xb5, 0x74, 0xd1, 0x47, 0xdf, 0x5e, 0xdf, 0x12, 0x82, 0xe3, 0xee, - 0xbc, 0xb7, 0x6f, 0xa0, 0x39, 0xec, 0xad, 0xac, 0x61, 0xa8, 0x99, 0x96, 0x7f, 0x5f, 0x29, 0xdd, - 0x7f, 0x78, 0x61, 0x3c, 0xb7, 0xf1, 0x5f, 0x12, 0x54, 0x53, 0x59, 0x8f, 0x2c, 0x31, 0x31, 0x2c, - 0x17, 0x1e, 0x74, 0x7f, 0xc9, 0x90, 0x95, 0x25, 0x75, 0xff, 0xde, 0x85, 0xb0, 0xdc, 0xf6, 0x57, - 0x50, 0x4b, 0x67, 0x68, 0xd6, 0xab, 0xb9, 0x79, 0x9f, 0xf5, 0x6a, 0x4e, 0x92, 0x9f, 0x6f, 0x88, - 0x7f, 0xe3, 0xdf, 0xff, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf7, 0xad, 0xf8, 0x9d, 0x28, 0x17, - 0x00, 0x00, + // 1879 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xdd, 0x72, 0x1b, 0x49, + 0x15, 0xce, 0x48, 0xb2, 0x9d, 0x39, 0xb2, 0xe4, 0x49, 0x5b, 0xce, 0xca, 0xce, 0xee, 0xc6, 0x19, + 0x42, 0x36, 0x9b, 0xa4, 0x44, 0x62, 0x20, 0x15, 0x6a, 0x43, 0x81, 0x2c, 0x4d, 0x5c, 0xca, 0xca, + 0x92, 0xd3, 0x92, 0x21, 0xcb, 0x52, 0x35, 0xd5, 0x96, 0x3a, 0xda, 0x09, 0xf3, 0xc7, 0x4c, 0x2b, + 0x44, 0x70, 0x49, 0x85, 0x3b, 0x2e, 0xa8, 0xe2, 0x8a, 0x57, 0xe0, 0x92, 0x17, 0xe0, 0x8a, 0x07, + 0xa0, 0x78, 0x00, 0x78, 0x00, 0xde, 0x81, 0xea, 0x9e, 0xd1, 0xfc, 0x69, 0x24, 0xdb, 0x09, 0x70, + 0x37, 0x7d, 0xce, 0x77, 0xba, 0xcf, 0x4f, 0x9f, 0x9f, 0x96, 0x40, 0x26, 0xae, 0xd1, 0x70, 0x3d, + 0x87, 0x39, 0x68, 0x93, 0x7f, 0xbe, 0x79, 0xd4, 0x38, 0xa3, 0x8c, 0x3c, 0x52, 0x31, 0x80, 0xf6, + 0xd6, 0xa5, 0x9e, 0x61, 0x51, 0x9b, 0x21, 0x04, 0x25, 0x9b, 0x58, 0xb4, 0x2e, 0xed, 0x4b, 0x77, + 0x65, 0x2c, 0xbe, 0xd1, 0x43, 0x28, 0xf9, 0x2e, 0x1d, 0xd5, 0x0b, 0xfb, 0xd2, 0xdd, 0xf2, 0xc1, + 0xc7, 0x8d, 0xa4, 0x78, 0x23, 0x96, 0x1d, 0xb8, 0x74, 0x84, 0x05, 0x52, 0x7d, 0x57, 0x82, 0x6a, + 0x9a, 0x81, 0x86, 0xb0, 0xe5, 0x12, 0x8f, 0x58, 0x94, 0x51, 0x4f, 0xe7, 0x20, 0x5f, 0x9c, 0x51, + 0x3e, 0xb8, 0xbf, 0x6a, 0xbf, 0xc6, 0xc9, 0x5c, 0x86, 0xaf, 0x7c, 0x5c, 0x75, 0x53, 0x6b, 0xf4, + 0x03, 0x90, 0x9d, 0xb3, 0xd7, 0x74, 0xc4, 0x8c, 0x37, 0x34, 0xd4, 0xef, 0x46, 0x7a, 0xbf, 0xfe, + 0x9c, 0x2d, 0xd4, 0x8b, 0xd1, 0x5c, 0x94, 0x98, 0x13, 0xc7, 0x33, 0xd8, 0x37, 0x56, 0xbd, 0x98, + 0x27, 0xda, 0x9c, 0xb3, 0x03, 0xd1, 0x08, 0x8d, 0x9e, 0x41, 0x95, 0x12, 0xcf, 0x9c, 0xe9, 0x3e, + 0x73, 0x5c, 0xd7, 0xb0, 0x27, 0xf5, 0x92, 0x90, 0xbf, 0x99, 0x31, 0x85, 0x63, 0x06, 0x21, 0x44, + 0xec, 0x51, 0xa1, 0x49, 0x12, 0x7a, 0x08, 0x35, 0x6e, 0x8f, 0x69, 0x52, 0x53, 0x67, 0x9e, 0x41, + 0x4c, 0x7d, 0xe4, 0x4c, 0x6d, 0x56, 0x5f, 0xdb, 0x97, 0xee, 0xae, 0x61, 0x34, 0xe7, 0x0d, 0x39, + 0xab, 0xc5, 0x39, 0xe8, 0x0e, 0x6c, 0x59, 0xe4, 0x6d, 0x0a, 0xbc, 0x2e, 0xc0, 0x15, 0x8b, 0xbc, + 0x4d, 0xe0, 0x1e, 0x03, 0xd8, 0xc4, 0xd7, 0x47, 0x8e, 0xfd, 0xca, 0x98, 0xd4, 0x37, 0x84, 0x76, + 0x1f, 0xa5, 0xb5, 0xeb, 0x11, 0xbf, 0x25, 0xd8, 0x58, 0xb6, 0xe7, 0x9f, 0x7b, 0xc7, 0x50, 0x4d, + 0x7b, 0x1c, 0x7d, 0x01, 0x10, 0xf9, 0x9c, 0x87, 0xac, 0xb8, 0xe8, 0xa7, 0x94, 0x04, 0x4e, 0xc0, + 0xd5, 0x3f, 0x4b, 0x50, 0x49, 0x71, 0x73, 0xef, 0xd7, 0x21, 0xc4, 0x61, 0xd5, 0xd9, 0xcc, 0x0d, + 0x22, 0x59, 0x5d, 0x7a, 0xcc, 0x70, 0xe6, 0x52, 0x5c, 0x71, 0x93, 0x4b, 0xbe, 0xc7, 0x2b, 0x4a, + 0x7c, 0xe3, 0xcc, 0xa4, 0xba, 0xef, 0x92, 0x11, 0xcd, 0x0f, 0xe9, 0xb3, 0x10, 0x33, 0xe0, 0x10, + 0x5c, 0x79, 0x95, 0x5c, 0xaa, 0x5f, 0x43, 0x25, 0xc5, 0x47, 0x0a, 0x14, 0x2d, 0xf2, 0x36, 0xd4, + 0x95, 0x7f, 0x0a, 0x8a, 0x61, 0x0b, 0xfd, 0x38, 0xc5, 0xb0, 0xb9, 0x41, 0xa6, 0xe1, 0xb3, 0x7a, + 0x71, 0xbf, 0xc8, 0x0d, 0xe2, 0xdf, 0x9c, 0xe6, 0x33, 0xea, 0x8a, 0x5b, 0x21, 0x63, 0xf1, 0xad, + 0xfe, 0x55, 0x82, 0x4a, 0xea, 0x2e, 0xa2, 0xef, 0x40, 0x49, 0x18, 0x2b, 0xe5, 0x19, 0x1b, 0x41, + 0x85, 0xb1, 0x02, 0xc8, 0xb7, 0x9d, 0x38, 0xc4, 0x14, 0xa7, 0x4b, 0x58, 0x7c, 0xa3, 0x03, 0xd8, + 0x89, 0xae, 0xb4, 0x6e, 0x51, 0xe6, 0x19, 0x23, 0x5d, 0x38, 0xb8, 0x28, 0xce, 0xde, 0x8e, 0x98, + 0xc7, 0x82, 0xd7, 0xe3, 0xfe, 0x7e, 0x0c, 0x1f, 0x91, 0xf1, 0xd8, 0x60, 0x86, 0x63, 0x13, 0x33, + 0x29, 0xe4, 0xd7, 0x4b, 0xc2, 0x8a, 0x9d, 0x98, 0x1d, 0x8b, 0xf9, 0xea, 0x3b, 0x09, 0x2a, 0xa9, + 0x9c, 0x40, 0xdf, 0x86, 0x6a, 0x94, 0x15, 0x7a, 0x22, 0xae, 0x95, 0x88, 0x2a, 0x0e, 0x3c, 0x06, + 0x14, 0xc3, 0x7c, 0xca, 0x98, 0x61, 0x4f, 0xfc, 0x7a, 0x41, 0xdc, 0xa5, 0x4f, 0x97, 0xe5, 0x5c, + 0x00, 0xc3, 0xd7, 0x48, 0x86, 0xe2, 0xab, 0x4f, 0x41, 0xc9, 0xc2, 0x72, 0xef, 0x55, 0x0d, 0xd6, + 0xde, 0x10, 0x73, 0x4a, 0xc3, 0x70, 0x05, 0x0b, 0xf5, 0xf7, 0x12, 0x5c, 0x5b, 0xc8, 0xcc, 0x8b, + 0x5a, 0xf2, 0x62, 0x85, 0x25, 0xea, 0xaa, 0xec, 0x5f, 0x6e, 0xcd, 0x8f, 0xa1, 0x96, 0x07, 0xbd, + 0x84, 0x45, 0x7f, 0x97, 0x40, 0x8e, 0xb2, 0x19, 0x3d, 0x85, 0xcd, 0x89, 0x47, 0xdc, 0x6f, 0xe6, + 0xc9, 0x1f, 0x54, 0xd9, 0xdd, 0xb4, 0x72, 0x47, 0x1c, 0x11, 0xa6, 0x7f, 0x79, 0x12, 0x2f, 0xd0, + 0x21, 0x80, 0xe3, 0x52, 0x8f, 0xf0, 0xe8, 0xfb, 0x61, 0x45, 0x55, 0x97, 0x14, 0x8e, 0x46, 0x3f, + 0x42, 0xe2, 0x84, 0xd4, 0x5e, 0x0b, 0x20, 0xe6, 0xa0, 0xef, 0x83, 0x1c, 0xf1, 0xc2, 0xfa, 0x91, + 0xa9, 0x44, 0x11, 0x18, 0xc7, 0x48, 0xd5, 0x85, 0x72, 0x42, 0x49, 0xf4, 0x09, 0x80, 0x3d, 0xb5, + 0x74, 0x93, 0xcc, 0x82, 0x32, 0xc4, 0x6b, 0x9e, 0x6c, 0x4f, 0xad, 0xae, 0x20, 0xa0, 0x9b, 0x50, + 0x36, 0x6c, 0x77, 0xca, 0x74, 0xdf, 0xf8, 0x35, 0x0d, 0x02, 0xb2, 0x86, 0x41, 0x90, 0x06, 0x9c, + 0x82, 0x6e, 0xc1, 0xa6, 0x33, 0x65, 0x31, 0xa2, 0x28, 0x10, 0xe5, 0x80, 0x26, 0x20, 0xc2, 0x8d, + 0x91, 0x2a, 0xfc, 0x42, 0x44, 0xca, 0xe8, 0x51, 0x9e, 0xca, 0xb8, 0x12, 0x51, 0x45, 0xdd, 0xe9, + 0x2f, 0xb6, 0xb5, 0xc0, 0x69, 0x77, 0x96, 0xd8, 0x78, 0x4e, 0x47, 0xfb, 0x6f, 0x57, 0xe0, 0xdf, + 0xc0, 0x9a, 0x68, 0x0b, 0xb9, 0xd7, 0xe9, 0x7e, 0xaa, 0xb1, 0x67, 0xa2, 0x22, 0xc4, 0xe2, 0x9e, + 0x8e, 0x1e, 0xc1, 0xba, 0xcf, 0x08, 0x9b, 0xfa, 0x61, 0x65, 0xdd, 0xcd, 0x83, 0x0b, 0x00, 0x0e, + 0x81, 0xea, 0xef, 0x0a, 0x20, 0x47, 0xdb, 0x7c, 0x48, 0xaf, 0x26, 0xb0, 0x13, 0x7b, 0x99, 0xf8, + 0xbe, 0x31, 0xb1, 0xf9, 0x84, 0x30, 0x57, 0xe5, 0xc1, 0x12, 0xcd, 0x63, 0xbf, 0x34, 0x63, 0x19, + 0x5c, 0x73, 0x73, 0xa8, 0x7b, 0x5f, 0x43, 0x2d, 0x0f, 0x8d, 0x5a, 0x50, 0x4e, 0x1e, 0x18, 0xb8, + 0xff, 0xd6, 0x12, 0xf7, 0xc7, 0x82, 0x38, 0x29, 0xa5, 0xfe, 0x08, 0xb6, 0x73, 0x30, 0x97, 0x48, + 0xf1, 0x7f, 0x14, 0xa0, 0x9c, 0xf0, 0x30, 0x4f, 0x07, 0x9f, 0x11, 0x8f, 0xe9, 0xcc, 0x88, 0xe4, + 0x65, 0x41, 0x19, 0x1a, 0x16, 0x45, 0x9f, 0xc1, 0xd6, 0xc8, 0xb1, 0x5c, 0x93, 0x06, 0xb7, 0x97, + 0x63, 0x82, 0xed, 0xaa, 0x31, 0x59, 0x00, 0x9f, 0x83, 0x3c, 0x72, 0xec, 0xa0, 0xd8, 0x0b, 0x67, + 0x56, 0xf3, 0x9d, 0x29, 0x4e, 0x6d, 0x84, 0x03, 0x46, 0x88, 0x17, 0x9d, 0x29, 0x16, 0x47, 0x5f, + 0x40, 0xd9, 0x39, 0xf3, 0xa9, 0xf7, 0x26, 0x48, 0xf5, 0x52, 0xde, 0x2d, 0xe9, 0xc7, 0x00, 0x9c, + 0x44, 0xab, 0x0c, 0xd0, 0xe2, 0xee, 0xa8, 0x0c, 0x1b, 0x2d, 0xac, 0x35, 0x87, 0x5a, 0x5b, 0xb9, + 0xc2, 0x17, 0xf8, 0xb4, 0xd7, 0xeb, 0xf4, 0x8e, 0x14, 0x09, 0x55, 0x40, 0x1e, 0x9c, 0xb6, 0x5a, + 0x9a, 0xd6, 0xd6, 0xda, 0x4a, 0x01, 0x01, 0xac, 0x7f, 0xd9, 0xe9, 0x76, 0xb5, 0xb6, 0x52, 0xe4, + 0xdf, 0xcf, 0x9a, 0x1d, 0xfe, 0x5d, 0x42, 0x0a, 0x6c, 0x6a, 0x4d, 0xdc, 0xfd, 0x6a, 0x30, 0xec, + 0x9f, 0x9c, 0x68, 0x6d, 0x65, 0x8d, 0xef, 0x72, 0xda, 0xfb, 0xb2, 0xd7, 0xff, 0x69, 0x4f, 0x59, + 0x57, 0x7f, 0x08, 0xe5, 0x84, 0x46, 0xa8, 0x01, 0x1b, 0x41, 0x37, 0x9c, 0xc7, 0xb9, 0x96, 0xd6, + 0x3e, 0x68, 0x86, 0x78, 0x0e, 0x52, 0x0f, 0x60, 0x3d, 0x20, 0x5d, 0x22, 0x92, 0xbf, 0x95, 0xe0, + 0x06, 0xa6, 0xae, 0xe3, 0xb1, 0xc4, 0xc9, 0x5d, 0x67, 0x82, 0xe9, 0x2f, 0xa7, 0xd4, 0x67, 0x3c, + 0xb2, 0xc1, 0x74, 0x97, 0xd8, 0x4f, 0x16, 0x14, 0xd1, 0x80, 0x34, 0xd8, 0x4a, 0xb8, 0x4d, 0x37, + 0x9d, 0x49, 0xfe, 0x58, 0x9e, 0xd9, 0xbc, 0xea, 0xa4, 0xd6, 0xea, 0x0d, 0xd8, 0xcd, 0x57, 0xc2, + 0x35, 0x67, 0xea, 0x73, 0xa8, 0xa6, 0xc9, 0xe8, 0x09, 0x94, 0xc3, 0x31, 0xc1, 0x74, 0x26, 0x7e, + 0x7e, 0x15, 0x0f, 0x3c, 0xc1, 0x37, 0x01, 0x6b, 0xfe, 0xe9, 0xab, 0x2f, 0x41, 0x8e, 0x18, 0xc2, + 0x36, 0xc3, 0xa2, 0xba, 0xcf, 0x88, 0xe5, 0x46, 0xb6, 0x19, 0x16, 0x1d, 0x70, 0x02, 0x7a, 0x00, + 0xeb, 0x81, 0x64, 0x68, 0x52, 0xbe, 0xf7, 0x43, 0x8c, 0xfa, 0x47, 0x09, 0xea, 0x47, 0xf4, 0xfd, + 0xbc, 0x78, 0x33, 0xb2, 0x47, 0xf0, 0x83, 0x00, 0x85, 0x6a, 0x0b, 0x40, 0x3a, 0xbf, 0x8a, 0xd9, + 0xfc, 0xda, 0x85, 0xab, 0xd4, 0x1e, 0x07, 0xcc, 0x60, 0xc8, 0xdb, 0xa0, 0xf6, 0x98, 0xb3, 0x54, + 0x1d, 0xae, 0xe7, 0x68, 0xe5, 0x9a, 0xb3, 0xbc, 0xd0, 0x49, 0xef, 0x11, 0xba, 0xa7, 0x70, 0xa3, + 0x4d, 0x4d, 0xca, 0xe8, 0xfb, 0x58, 0xce, 0x03, 0x9f, 0x2f, 0xcd, 0x03, 0xff, 0x87, 0x02, 0xec, + 0x1c, 0x51, 0x36, 0x98, 0x4e, 0x26, 0xd4, 0x0f, 0xfa, 0x7a, 0xb8, 0xeb, 0x13, 0x00, 0x1a, 0x3d, + 0xcc, 0x42, 0xb5, 0xeb, 0xcb, 0x1e, 0x6e, 0x38, 0x81, 0x45, 0xf7, 0x61, 0x5d, 0x9c, 0x3e, 0x9f, + 0x92, 0xb6, 0x73, 0xca, 0x0b, 0x0e, 0x21, 0xe8, 0x73, 0xa8, 0x7a, 0xc1, 0x89, 0xba, 0x3d, 0xb5, + 0xce, 0xa8, 0x27, 0x5c, 0xbf, 0x76, 0x58, 0xa8, 0x4b, 0xb8, 0x12, 0x72, 0x7a, 0x82, 0x81, 0xbe, + 0x07, 0xd7, 0x47, 0x53, 0xcf, 0xa3, 0x36, 0xd3, 0x33, 0x22, 0x25, 0x31, 0x1c, 0xd4, 0x42, 0x2e, + 0x4e, 0x49, 0x3d, 0x84, 0x1a, 0x73, 0x18, 0x31, 0xb3, 0x32, 0xe1, 0x8b, 0x4b, 0xf0, 0x52, 0x12, + 0xea, 0xbf, 0x0b, 0xb0, 0x9d, 0xf5, 0x09, 0x8f, 0xe6, 0x2f, 0x96, 0xb5, 0xa4, 0x20, 0x39, 0x1e, + 0x67, 0xe6, 0xad, 0xc5, 0x1d, 0x2e, 0xd1, 0x9c, 0xd2, 0x6f, 0xd5, 0xc2, 0xa5, 0xde, 0xaa, 0x2f, + 0xa0, 0x96, 0x7e, 0xab, 0xea, 0xde, 0xd4, 0x0c, 0x07, 0xa0, 0xd5, 0x2f, 0x56, 0x3c, 0x35, 0x29, + 0x46, 0x34, 0x4b, 0xfa, 0x1f, 0xb7, 0xca, 0x9f, 0xc3, 0xfe, 0x4f, 0x88, 0x69, 0x8c, 0x09, 0xa3, + 0xd9, 0x21, 0xff, 0xc3, 0x6f, 0xa3, 0xba, 0x0f, 0x9f, 0xae, 0xd8, 0x9d, 0xe7, 0xc0, 0x5f, 0x24, + 0xf8, 0xf8, 0x88, 0xb2, 0x05, 0x4f, 0xfc, 0xbf, 0x53, 0xe1, 0x01, 0xa0, 0xf1, 0x99, 0x6e, 0x11, + 0x9b, 0x4c, 0xf8, 0x05, 0x1b, 0x8f, 0x3d, 0xea, 0xfb, 0x61, 0x25, 0x52, 0xc6, 0x67, 0xc7, 0x01, + 0xa3, 0x19, 0xd0, 0x55, 0x07, 0xf6, 0x96, 0x28, 0xcd, 0xef, 0xea, 0xb2, 0x3b, 0x20, 0xbd, 0xf7, + 0x1d, 0x50, 0xff, 0x94, 0x7d, 0x45, 0x71, 0xf2, 0xc5, 0xdb, 0x20, 0x7a, 0x0a, 0xc0, 0x47, 0x11, + 0xe2, 0x19, 0x7e, 0x34, 0x79, 0x64, 0xea, 0x60, 0x2b, 0xe2, 0x8b, 0x49, 0x23, 0x81, 0x8f, 0xcb, + 0x73, 0xf4, 0xcc, 0x5e, 0x0b, 0xcb, 0xf3, 0x80, 0xbf, 0xb5, 0x7f, 0x05, 0xb7, 0xe7, 0x51, 0xce, + 0x7b, 0x5a, 0x45, 0xa1, 0xec, 0xc3, 0x76, 0xc6, 0x2f, 0x62, 0x1c, 0x96, 0x2e, 0xf6, 0x63, 0xce, + 0x35, 0x9a, 0x25, 0xa9, 0xb7, 0x41, 0x3d, 0xe7, 0x60, 0x7e, 0xc5, 0x1e, 0xc3, 0xce, 0x80, 0xb2, + 0xe4, 0xc0, 0x7c, 0xb1, 0xda, 0xbd, 0x03, 0xdb, 0x59, 0x39, 0xd7, 0x9c, 0xdd, 0x3b, 0x4d, 0xfc, + 0xc6, 0x22, 0xa6, 0x26, 0x05, 0x36, 0xc3, 0x11, 0x47, 0x1f, 0x7e, 0x75, 0xa2, 0x29, 0x57, 0xf8, + 0x48, 0xd4, 0xee, 0x9f, 0x1e, 0x76, 0x35, 0x45, 0x42, 0x1b, 0x50, 0xec, 0xf4, 0x86, 0x4a, 0x01, + 0x6d, 0xc2, 0xd5, 0x76, 0x67, 0xd0, 0xc2, 0xda, 0x50, 0x53, 0x8a, 0x68, 0x0b, 0xca, 0xad, 0xe6, + 0x50, 0x3b, 0xea, 0xe3, 0x4e, 0xab, 0xd9, 0x55, 0x4a, 0xf7, 0x9e, 0x24, 0x7e, 0xaf, 0x98, 0x0f, + 0x63, 0xf3, 0xc9, 0xe9, 0x0a, 0x17, 0x3e, 0xee, 0xf4, 0x3a, 0xc7, 0x9d, 0x9f, 0xf1, 0x3d, 0xf9, + 0xaa, 0xf9, 0x32, 0x58, 0x15, 0xee, 0x3d, 0x87, 0x6a, 0x3a, 0x76, 0xe8, 0x3a, 0xa0, 0xb9, 0x46, + 0xad, 0xfe, 0xf1, 0x49, 0x13, 0x77, 0x06, 0x7d, 0xbe, 0x8b, 0x0c, 0x6b, 0xda, 0x8b, 0xd3, 0x66, + 0x57, 0x91, 0xd0, 0x55, 0x28, 0x75, 0xb5, 0xc1, 0x40, 0x29, 0xf0, 0x73, 0x8e, 0xc4, 0xd0, 0x87, + 0x95, 0xe2, 0xc1, 0xdf, 0x0a, 0x20, 0xb7, 0x0f, 0xc3, 0xdb, 0x8e, 0x5e, 0x43, 0x2d, 0x6f, 0x6c, + 0x41, 0x9f, 0xa7, 0x63, 0xb5, 0x62, 0xbe, 0xda, 0xfb, 0xec, 0x22, 0x50, 0x9e, 0x34, 0x04, 0xae, + 0x2d, 0x34, 0x72, 0x74, 0x67, 0xa1, 0xac, 0xe7, 0x9f, 0x72, 0xfb, 0x5c, 0x1c, 0x3f, 0xe2, 0x35, + 0xd4, 0xf2, 0x9a, 0x71, 0xd6, 0x9c, 0x15, 0xed, 0x3e, 0x6b, 0xce, 0xd2, 0xde, 0x7e, 0xf0, 0x2f, + 0x09, 0x20, 0x6e, 0x41, 0xe8, 0x25, 0x54, 0xd3, 0x3d, 0x09, 0x7d, 0x6b, 0x75, 0xc7, 0x0a, 0x8e, + 0xbb, 0x75, 0x6e, 0x5b, 0x43, 0x33, 0xd8, 0x5d, 0x5a, 0x62, 0x51, 0x23, 0x2d, 0x7f, 0x5e, 0xa5, + 0xdf, 0x7b, 0x70, 0x61, 0x3c, 0xb7, 0xf1, 0x9f, 0x05, 0xa8, 0xa4, 0xf2, 0x0e, 0x59, 0x62, 0xa0, + 0x59, 0xac, 0x8b, 0xe8, 0xde, 0x82, 0x21, 0x4b, 0x2b, 0xfe, 0xde, 0xdd, 0x0b, 0x61, 0xb9, 0xed, + 0x2f, 0xa1, 0x9a, 0xce, 0xd0, 0xac, 0x57, 0x73, 0xf3, 0x3e, 0xeb, 0xd5, 0x9c, 0x24, 0x47, 0xef, + 0x24, 0xf8, 0x64, 0x65, 0x69, 0x41, 0x07, 0xf9, 0xae, 0x5a, 0x55, 0x00, 0xf7, 0x1e, 0x5e, 0x4a, + 0xc6, 0x35, 0x67, 0x67, 0xeb, 0xe2, 0x2f, 0x84, 0xef, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0x45, + 0x6e, 0x90, 0xc6, 0x4f, 0x18, 0x00, 0x00, } diff --git a/pkg/apis/manager/v1beta1/api.proto b/pkg/apis/manager/v1beta1/api.proto index 8655cbc6424..92b4e8f898b 100644 --- a/pkg/apis/manager/v1beta1/api.proto +++ b/pkg/apis/manager/v1beta1/api.proto @@ -42,6 +42,7 @@ service Suggestion { service EarlyStopping { rpc GetEarlyStoppingRules(GetEarlyStoppingRulesRequest) returns (GetEarlyStoppingRulesReply); rpc SetTrialStatus(SetTrialStatusRequest) returns (SetTrialStatusReply); + rpc ValidateEarlyStoppingSettings(ValidateEarlyStoppingSettingsRequest) returns (ValidateEarlyStoppingSettingsReply); } /** @@ -339,6 +340,16 @@ message EarlyStoppingRule { int32 start_step = 4; } +message ValidateEarlyStoppingSettingsRequest { + EarlyStoppingSpec early_stopping_spec = 1; +} + +/** + * Return INVALID_ARGUMENT Error if Early Stopping Settings are not Valid + */ +message ValidateEarlyStoppingSettingsReply { +} + enum ComparisonType { UNKNOWN_COMPARISON = 0; // Unknown comparison, not used EQUAL = 1; // Equal comparison, e.g. accuracy = 0.7 diff --git a/pkg/apis/manager/v1beta1/gen-doc/api.md b/pkg/apis/manager/v1beta1/gen-doc/api.md index 7956fb9cfde..348f326a04c 100644 --- a/pkg/apis/manager/v1beta1/gen-doc/api.md +++ b/pkg/apis/manager/v1beta1/gen-doc/api.md @@ -44,6 +44,8 @@ - [TrialStatus](#api.v1.beta1.TrialStatus) - [ValidateAlgorithmSettingsReply](#api.v1.beta1.ValidateAlgorithmSettingsReply) - [ValidateAlgorithmSettingsRequest](#api.v1.beta1.ValidateAlgorithmSettingsRequest) + - [ValidateEarlyStoppingSettingsReply](#api.v1.beta1.ValidateEarlyStoppingSettingsReply) + - [ValidateEarlyStoppingSettingsRequest](#api.v1.beta1.ValidateEarlyStoppingSettingsRequest) - [ComparisonType](#api.v1.beta1.ComparisonType) - [ObjectiveType](#api.v1.beta1.ObjectiveType) @@ -696,6 +698,31 @@ Return INVALID_ARGUMENT Error if Algorithm Settings are not Valid + + + +### ValidateEarlyStoppingSettingsReply +Return INVALID_ARGUMENT Error if Early Stopping Settings are not Valid + + + + + + + + +### ValidateEarlyStoppingSettingsRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| early_stopping_spec | [EarlyStoppingSpec](#api.v1.beta1.EarlyStoppingSpec) | | | + + + + + @@ -784,6 +811,7 @@ EarlyStopping service defines APIs to manage Katib Early Stopping algorithms | ----------- | ------------ | ------------- | ------------| | GetEarlyStoppingRules | [GetEarlyStoppingRulesRequest](#api.v1.beta1.GetEarlyStoppingRulesRequest) | [GetEarlyStoppingRulesReply](#api.v1.beta1.GetEarlyStoppingRulesReply) | | | SetTrialStatus | [SetTrialStatusRequest](#api.v1.beta1.SetTrialStatusRequest) | [SetTrialStatusReply](#api.v1.beta1.SetTrialStatusReply) | | +| ValidateEarlyStoppingSettings | [ValidateEarlyStoppingSettingsRequest](#api.v1.beta1.ValidateEarlyStoppingSettingsRequest) | [ValidateEarlyStoppingSettingsReply](#api.v1.beta1.ValidateEarlyStoppingSettingsReply) | | diff --git a/pkg/apis/manager/v1beta1/gen-doc/index.html b/pkg/apis/manager/v1beta1/gen-doc/index.html index cda9bbe46d4..df72991bab8 100644 --- a/pkg/apis/manager/v1beta1/gen-doc/index.html +++ b/pkg/apis/manager/v1beta1/gen-doc/index.html @@ -338,6 +338,14 @@

Table of Contents

MValidateAlgorithmSettingsRequest +
  • + MValidateEarlyStoppingSettingsReply +
  • + +
  • + MValidateEarlyStoppingSettingsRequest +
  • +
  • EComparisonType @@ -1630,6 +1638,37 @@

    ValidateAlgorithmSettings +

    ValidateEarlyStoppingSettingsReply

    +

    Return INVALID_ARGUMENT Error if Early Stopping Settings are not Valid

    + + + + + +

    ValidateEarlyStoppingSettingsRequest

    +

    + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    early_stopping_specEarlyStoppingSpec

    + + + + +

    ComparisonType

    @@ -1852,6 +1891,13 @@

    EarlyStopping

    + + ValidateEarlyStoppingSettings + ValidateEarlyStoppingSettingsRequest + ValidateEarlyStoppingSettingsReply +

    + + diff --git a/pkg/apis/manager/v1beta1/python/api_pb2.py b/pkg/apis/manager/v1beta1/python/api_pb2.py index 37a89c091b8..ee3a04821d7 100644 --- a/pkg/apis/manager/v1beta1/python/api_pb2.py +++ b/pkg/apis/manager/v1beta1/python/api_pb2.py @@ -20,7 +20,7 @@ name='api.proto', package='api.v1.beta1', syntax='proto3', - serialized_pb=_b('\n\tapi.proto\x12\x0c\x61pi.v1.beta1\"F\n\nExperiment\x12\x0c\n\x04name\x18\x01 \x01(\t\x12*\n\x04spec\x18\x02 \x01(\x0b\x32\x1c.api.v1.beta1.ExperimentSpec\"\x96\x03\n\x0e\x45xperimentSpec\x12\x44\n\x0fparameter_specs\x18\x01 \x01(\x0b\x32+.api.v1.beta1.ExperimentSpec.ParameterSpecs\x12.\n\tobjective\x18\x02 \x01(\x0b\x32\x1b.api.v1.beta1.ObjectiveSpec\x12.\n\talgorithm\x18\x03 \x01(\x0b\x32\x1b.api.v1.beta1.AlgorithmSpec\x12\x37\n\x0e\x65\x61rly_stopping\x18\x04 \x01(\x0b\x32\x1f.api.v1.beta1.EarlyStoppingSpec\x12\x1c\n\x14parallel_trial_count\x18\x05 \x01(\x05\x12\x17\n\x0fmax_trial_count\x18\x06 \x01(\x05\x12+\n\nnas_config\x18\x07 \x01(\x0b\x32\x17.api.v1.beta1.NasConfig\x1a\x41\n\x0eParameterSpecs\x12/\n\nparameters\x18\x01 \x03(\x0b\x32\x1b.api.v1.beta1.ParameterSpec\"\x87\x01\n\rParameterSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x33\n\x0eparameter_type\x18\x02 \x01(\x0e\x32\x1b.api.v1.beta1.ParameterType\x12\x33\n\x0e\x66\x65\x61sible_space\x18\x03 \x01(\x0b\x32\x1b.api.v1.beta1.FeasibleSpace\"E\n\rFeasibleSpace\x12\x0b\n\x03max\x18\x01 \x01(\t\x12\x0b\n\x03min\x18\x02 \x01(\t\x12\x0c\n\x04list\x18\x03 \x03(\t\x12\x0c\n\x04step\x18\x04 \x01(\t\"\x88\x01\n\rObjectiveSpec\x12)\n\x04type\x18\x01 \x01(\x0e\x32\x1b.api.v1.beta1.ObjectiveType\x12\x0c\n\x04goal\x18\x02 \x01(\x01\x12\x1d\n\x15objective_metric_name\x18\x03 \x01(\t\x12\x1f\n\x17\x61\x64\x64itional_metric_names\x18\x04 \x03(\t\"c\n\rAlgorithmSpec\x12\x16\n\x0e\x61lgorithm_name\x18\x01 \x01(\t\x12:\n\x12\x61lgorithm_settings\x18\x02 \x03(\x0b\x32\x1e.api.v1.beta1.AlgorithmSetting\"/\n\x10\x41lgorithmSetting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"k\n\x11\x45\x61rlyStoppingSpec\x12\x16\n\x0e\x61lgorithm_name\x18\x01 \x01(\t\x12>\n\x12\x61lgorithm_settings\x18\x02 \x03(\x0b\x32\".api.v1.beta1.EarlyStoppingSetting\"3\n\x14\x45\x61rlyStoppingSetting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xae\x01\n\tNasConfig\x12/\n\x0cgraph_config\x18\x01 \x01(\x0b\x32\x19.api.v1.beta1.GraphConfig\x12\x36\n\noperations\x18\x02 \x01(\x0b\x32\".api.v1.beta1.NasConfig.Operations\x1a\x38\n\nOperations\x12*\n\toperation\x18\x01 \x03(\x0b\x32\x17.api.v1.beta1.Operation\"L\n\x0bGraphConfig\x12\x12\n\nnum_layers\x18\x01 \x01(\x05\x12\x13\n\x0binput_sizes\x18\x02 \x03(\x05\x12\x14\n\x0coutput_sizes\x18\x03 \x03(\x05\"\xa7\x01\n\tOperation\x12\x16\n\x0eoperation_type\x18\x01 \x01(\t\x12?\n\x0fparameter_specs\x18\x02 \x01(\x0b\x32&.api.v1.beta1.Operation.ParameterSpecs\x1a\x41\n\x0eParameterSpecs\x12/\n\nparameters\x18\x01 \x03(\x0b\x32\x1b.api.v1.beta1.ParameterSpec\"g\n\x05Trial\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x04spec\x18\x02 \x01(\x0b\x32\x17.api.v1.beta1.TrialSpec\x12)\n\x06status\x18\x03 \x01(\x0b\x32\x19.api.v1.beta1.TrialStatus\"\xd8\x01\n\tTrialSpec\x12.\n\tobjective\x18\x02 \x01(\x0b\x32\x1b.api.v1.beta1.ObjectiveSpec\x12K\n\x15parameter_assignments\x18\x03 \x01(\x0b\x32,.api.v1.beta1.TrialSpec.ParameterAssignments\x1aN\n\x14ParameterAssignments\x12\x36\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32!.api.v1.beta1.ParameterAssignment\"2\n\x13ParameterAssignment\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xa1\x02\n\x0bTrialStatus\x12\x12\n\nstart_time\x18\x01 \x01(\t\x12\x17\n\x0f\x63ompletion_time\x18\x02 \x01(\t\x12?\n\tcondition\x18\x03 \x01(\x0e\x32,.api.v1.beta1.TrialStatus.TrialConditionType\x12.\n\x0bobservation\x18\x04 \x01(\x0b\x32\x19.api.v1.beta1.Observation\"t\n\x12TrialConditionType\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07RUNNING\x10\x01\x12\r\n\tSUCCEEDED\x10\x02\x12\n\n\x06KILLED\x10\x03\x12\n\n\x06\x46\x41ILED\x10\x04\x12\x10\n\x0c\x45\x41RLYSTOPPED\x10\x05\x12\x0b\n\x07UNKNOWN\x10\x06\"4\n\x0bObservation\x12%\n\x07metrics\x18\x01 \x03(\x0b\x32\x14.api.v1.beta1.Metric\"%\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"h\n\x1bReportObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\x12\x35\n\x0fobservation_log\x18\x02 \x01(\x0b\x32\x1c.api.v1.beta1.ObservationLog\"\x1b\n\x19ReportObservationLogReply\">\n\x0eObservationLog\x12,\n\x0bmetric_logs\x18\x01 \x03(\x0b\x32\x17.api.v1.beta1.MetricLog\"E\n\tMetricLog\x12\x12\n\ntime_stamp\x18\x01 \x01(\t\x12$\n\x06metric\x18\x02 \x01(\x0b\x32\x14.api.v1.beta1.Metric\"i\n\x18GetObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\x12\x13\n\x0bmetric_name\x18\x02 \x01(\t\x12\x12\n\nstart_time\x18\x03 \x01(\t\x12\x10\n\x08\x65nd_time\x18\x04 \x01(\t\"O\n\x16GetObservationLogReply\x12\x35\n\x0fobservation_log\x18\x01 \x01(\x0b\x32\x1c.api.v1.beta1.ObservationLog\"1\n\x1b\x44\x65leteObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\"\x1b\n\x19\x44\x65leteObservationLogReply\"\xc4\x01\n\x15GetSuggestionsRequest\x12,\n\nexperiment\x18\x01 \x01(\x0b\x32\x18.api.v1.beta1.Experiment\x12#\n\x06trials\x18\x02 \x03(\x0b\x32\x13.api.v1.beta1.Trial\x12\x1a\n\x0erequest_number\x18\x03 \x01(\x05\x42\x02\x18\x01\x12\x1e\n\x16\x63urrent_request_number\x18\x04 \x01(\x05\x12\x1c\n\x14total_request_number\x18\x05 \x01(\x05\"\xab\x02\n\x13GetSuggestionsReply\x12U\n\x15parameter_assignments\x18\x01 \x03(\x0b\x32\x36.api.v1.beta1.GetSuggestionsReply.ParameterAssignments\x12.\n\talgorithm\x18\x02 \x01(\x0b\x32\x1b.api.v1.beta1.AlgorithmSpec\x12=\n\x14\x65\x61rly_stopping_rules\x18\x03 \x03(\x0b\x32\x1f.api.v1.beta1.EarlyStoppingRule\x1aN\n\x14ParameterAssignments\x12\x36\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32!.api.v1.beta1.ParameterAssignment\"P\n ValidateAlgorithmSettingsRequest\x12,\n\nexperiment\x18\x01 \x01(\x0b\x32\x18.api.v1.beta1.Experiment\" \n\x1eValidateAlgorithmSettingsReply\"\x8d\x01\n\x1cGetEarlyStoppingRulesRequest\x12,\n\nexperiment\x18\x01 \x01(\x0b\x32\x18.api.v1.beta1.Experiment\x12#\n\x06trials\x18\x02 \x03(\x0b\x32\x13.api.v1.beta1.Trial\x12\x1a\n\x12\x64\x62_manager_address\x18\x03 \x01(\t\"[\n\x1aGetEarlyStoppingRulesReply\x12=\n\x14\x65\x61rly_stopping_rules\x18\x01 \x03(\x0b\x32\x1f.api.v1.beta1.EarlyStoppingRule\"v\n\x11\x45\x61rlyStoppingRule\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12\x30\n\ncomparison\x18\x03 \x01(\x0e\x32\x1c.api.v1.beta1.ComparisonType\x12\x12\n\nstart_step\x18\x04 \x01(\x05\"+\n\x15SetTrialStatusRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\"\x15\n\x13SetTrialStatusReply*U\n\rParameterType\x12\x10\n\x0cUNKNOWN_TYPE\x10\x00\x12\n\n\x06\x44OUBLE\x10\x01\x12\x07\n\x03INT\x10\x02\x12\x0c\n\x08\x44ISCRETE\x10\x03\x12\x0f\n\x0b\x43\x41TEGORICAL\x10\x04*8\n\rObjectiveType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0c\n\x08MINIMIZE\x10\x01\x12\x0c\n\x08MAXIMIZE\x10\x02*J\n\x0e\x43omparisonType\x12\x16\n\x12UNKNOWN_COMPARISON\x10\x00\x12\t\n\x05\x45QUAL\x10\x01\x12\x08\n\x04LESS\x10\x02\x12\x0b\n\x07GREATER\x10\x03\x32\xc6\x02\n\tDBManager\x12j\n\x14ReportObservationLog\x12).api.v1.beta1.ReportObservationLogRequest\x1a\'.api.v1.beta1.ReportObservationLogReply\x12\x61\n\x11GetObservationLog\x12&.api.v1.beta1.GetObservationLogRequest\x1a$.api.v1.beta1.GetObservationLogReply\x12j\n\x14\x44\x65leteObservationLog\x12).api.v1.beta1.DeleteObservationLogRequest\x1a\'.api.v1.beta1.DeleteObservationLogReply2\xe1\x01\n\nSuggestion\x12X\n\x0eGetSuggestions\x12#.api.v1.beta1.GetSuggestionsRequest\x1a!.api.v1.beta1.GetSuggestionsReply\x12y\n\x19ValidateAlgorithmSettings\x12..api.v1.beta1.ValidateAlgorithmSettingsRequest\x1a,.api.v1.beta1.ValidateAlgorithmSettingsReply2\xd8\x01\n\rEarlyStopping\x12m\n\x15GetEarlyStoppingRules\x12*.api.v1.beta1.GetEarlyStoppingRulesRequest\x1a(.api.v1.beta1.GetEarlyStoppingRulesReply\x12X\n\x0eSetTrialStatus\x12#.api.v1.beta1.SetTrialStatusRequest\x1a!.api.v1.beta1.SetTrialStatusReplyb\x06proto3') + serialized_pb=_b('\n\tapi.proto\x12\x0c\x61pi.v1.beta1\"F\n\nExperiment\x12\x0c\n\x04name\x18\x01 \x01(\t\x12*\n\x04spec\x18\x02 \x01(\x0b\x32\x1c.api.v1.beta1.ExperimentSpec\"\x96\x03\n\x0e\x45xperimentSpec\x12\x44\n\x0fparameter_specs\x18\x01 \x01(\x0b\x32+.api.v1.beta1.ExperimentSpec.ParameterSpecs\x12.\n\tobjective\x18\x02 \x01(\x0b\x32\x1b.api.v1.beta1.ObjectiveSpec\x12.\n\talgorithm\x18\x03 \x01(\x0b\x32\x1b.api.v1.beta1.AlgorithmSpec\x12\x37\n\x0e\x65\x61rly_stopping\x18\x04 \x01(\x0b\x32\x1f.api.v1.beta1.EarlyStoppingSpec\x12\x1c\n\x14parallel_trial_count\x18\x05 \x01(\x05\x12\x17\n\x0fmax_trial_count\x18\x06 \x01(\x05\x12+\n\nnas_config\x18\x07 \x01(\x0b\x32\x17.api.v1.beta1.NasConfig\x1a\x41\n\x0eParameterSpecs\x12/\n\nparameters\x18\x01 \x03(\x0b\x32\x1b.api.v1.beta1.ParameterSpec\"\x87\x01\n\rParameterSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x33\n\x0eparameter_type\x18\x02 \x01(\x0e\x32\x1b.api.v1.beta1.ParameterType\x12\x33\n\x0e\x66\x65\x61sible_space\x18\x03 \x01(\x0b\x32\x1b.api.v1.beta1.FeasibleSpace\"E\n\rFeasibleSpace\x12\x0b\n\x03max\x18\x01 \x01(\t\x12\x0b\n\x03min\x18\x02 \x01(\t\x12\x0c\n\x04list\x18\x03 \x03(\t\x12\x0c\n\x04step\x18\x04 \x01(\t\"\x88\x01\n\rObjectiveSpec\x12)\n\x04type\x18\x01 \x01(\x0e\x32\x1b.api.v1.beta1.ObjectiveType\x12\x0c\n\x04goal\x18\x02 \x01(\x01\x12\x1d\n\x15objective_metric_name\x18\x03 \x01(\t\x12\x1f\n\x17\x61\x64\x64itional_metric_names\x18\x04 \x03(\t\"c\n\rAlgorithmSpec\x12\x16\n\x0e\x61lgorithm_name\x18\x01 \x01(\t\x12:\n\x12\x61lgorithm_settings\x18\x02 \x03(\x0b\x32\x1e.api.v1.beta1.AlgorithmSetting\"/\n\x10\x41lgorithmSetting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"k\n\x11\x45\x61rlyStoppingSpec\x12\x16\n\x0e\x61lgorithm_name\x18\x01 \x01(\t\x12>\n\x12\x61lgorithm_settings\x18\x02 \x03(\x0b\x32\".api.v1.beta1.EarlyStoppingSetting\"3\n\x14\x45\x61rlyStoppingSetting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xae\x01\n\tNasConfig\x12/\n\x0cgraph_config\x18\x01 \x01(\x0b\x32\x19.api.v1.beta1.GraphConfig\x12\x36\n\noperations\x18\x02 \x01(\x0b\x32\".api.v1.beta1.NasConfig.Operations\x1a\x38\n\nOperations\x12*\n\toperation\x18\x01 \x03(\x0b\x32\x17.api.v1.beta1.Operation\"L\n\x0bGraphConfig\x12\x12\n\nnum_layers\x18\x01 \x01(\x05\x12\x13\n\x0binput_sizes\x18\x02 \x03(\x05\x12\x14\n\x0coutput_sizes\x18\x03 \x03(\x05\"\xa7\x01\n\tOperation\x12\x16\n\x0eoperation_type\x18\x01 \x01(\t\x12?\n\x0fparameter_specs\x18\x02 \x01(\x0b\x32&.api.v1.beta1.Operation.ParameterSpecs\x1a\x41\n\x0eParameterSpecs\x12/\n\nparameters\x18\x01 \x03(\x0b\x32\x1b.api.v1.beta1.ParameterSpec\"g\n\x05Trial\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x04spec\x18\x02 \x01(\x0b\x32\x17.api.v1.beta1.TrialSpec\x12)\n\x06status\x18\x03 \x01(\x0b\x32\x19.api.v1.beta1.TrialStatus\"\xd8\x01\n\tTrialSpec\x12.\n\tobjective\x18\x02 \x01(\x0b\x32\x1b.api.v1.beta1.ObjectiveSpec\x12K\n\x15parameter_assignments\x18\x03 \x01(\x0b\x32,.api.v1.beta1.TrialSpec.ParameterAssignments\x1aN\n\x14ParameterAssignments\x12\x36\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32!.api.v1.beta1.ParameterAssignment\"2\n\x13ParameterAssignment\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xa1\x02\n\x0bTrialStatus\x12\x12\n\nstart_time\x18\x01 \x01(\t\x12\x17\n\x0f\x63ompletion_time\x18\x02 \x01(\t\x12?\n\tcondition\x18\x03 \x01(\x0e\x32,.api.v1.beta1.TrialStatus.TrialConditionType\x12.\n\x0bobservation\x18\x04 \x01(\x0b\x32\x19.api.v1.beta1.Observation\"t\n\x12TrialConditionType\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07RUNNING\x10\x01\x12\r\n\tSUCCEEDED\x10\x02\x12\n\n\x06KILLED\x10\x03\x12\n\n\x06\x46\x41ILED\x10\x04\x12\x10\n\x0c\x45\x41RLYSTOPPED\x10\x05\x12\x0b\n\x07UNKNOWN\x10\x06\"4\n\x0bObservation\x12%\n\x07metrics\x18\x01 \x03(\x0b\x32\x14.api.v1.beta1.Metric\"%\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"h\n\x1bReportObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\x12\x35\n\x0fobservation_log\x18\x02 \x01(\x0b\x32\x1c.api.v1.beta1.ObservationLog\"\x1b\n\x19ReportObservationLogReply\">\n\x0eObservationLog\x12,\n\x0bmetric_logs\x18\x01 \x03(\x0b\x32\x17.api.v1.beta1.MetricLog\"E\n\tMetricLog\x12\x12\n\ntime_stamp\x18\x01 \x01(\t\x12$\n\x06metric\x18\x02 \x01(\x0b\x32\x14.api.v1.beta1.Metric\"i\n\x18GetObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\x12\x13\n\x0bmetric_name\x18\x02 \x01(\t\x12\x12\n\nstart_time\x18\x03 \x01(\t\x12\x10\n\x08\x65nd_time\x18\x04 \x01(\t\"O\n\x16GetObservationLogReply\x12\x35\n\x0fobservation_log\x18\x01 \x01(\x0b\x32\x1c.api.v1.beta1.ObservationLog\"1\n\x1b\x44\x65leteObservationLogRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\"\x1b\n\x19\x44\x65leteObservationLogReply\"\xc4\x01\n\x15GetSuggestionsRequest\x12,\n\nexperiment\x18\x01 \x01(\x0b\x32\x18.api.v1.beta1.Experiment\x12#\n\x06trials\x18\x02 \x03(\x0b\x32\x13.api.v1.beta1.Trial\x12\x1a\n\x0erequest_number\x18\x03 \x01(\x05\x42\x02\x18\x01\x12\x1e\n\x16\x63urrent_request_number\x18\x04 \x01(\x05\x12\x1c\n\x14total_request_number\x18\x05 \x01(\x05\"\xab\x02\n\x13GetSuggestionsReply\x12U\n\x15parameter_assignments\x18\x01 \x03(\x0b\x32\x36.api.v1.beta1.GetSuggestionsReply.ParameterAssignments\x12.\n\talgorithm\x18\x02 \x01(\x0b\x32\x1b.api.v1.beta1.AlgorithmSpec\x12=\n\x14\x65\x61rly_stopping_rules\x18\x03 \x03(\x0b\x32\x1f.api.v1.beta1.EarlyStoppingRule\x1aN\n\x14ParameterAssignments\x12\x36\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32!.api.v1.beta1.ParameterAssignment\"P\n ValidateAlgorithmSettingsRequest\x12,\n\nexperiment\x18\x01 \x01(\x0b\x32\x18.api.v1.beta1.Experiment\" \n\x1eValidateAlgorithmSettingsReply\"\x8d\x01\n\x1cGetEarlyStoppingRulesRequest\x12,\n\nexperiment\x18\x01 \x01(\x0b\x32\x18.api.v1.beta1.Experiment\x12#\n\x06trials\x18\x02 \x03(\x0b\x32\x13.api.v1.beta1.Trial\x12\x1a\n\x12\x64\x62_manager_address\x18\x03 \x01(\t\"[\n\x1aGetEarlyStoppingRulesReply\x12=\n\x14\x65\x61rly_stopping_rules\x18\x01 \x03(\x0b\x32\x1f.api.v1.beta1.EarlyStoppingRule\"v\n\x11\x45\x61rlyStoppingRule\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12\x30\n\ncomparison\x18\x03 \x01(\x0e\x32\x1c.api.v1.beta1.ComparisonType\x12\x12\n\nstart_step\x18\x04 \x01(\x05\"d\n$ValidateEarlyStoppingSettingsRequest\x12<\n\x13\x65\x61rly_stopping_spec\x18\x01 \x01(\x0b\x32\x1f.api.v1.beta1.EarlyStoppingSpec\"$\n\"ValidateEarlyStoppingSettingsReply\"+\n\x15SetTrialStatusRequest\x12\x12\n\ntrial_name\x18\x01 \x01(\t\"\x15\n\x13SetTrialStatusReply*U\n\rParameterType\x12\x10\n\x0cUNKNOWN_TYPE\x10\x00\x12\n\n\x06\x44OUBLE\x10\x01\x12\x07\n\x03INT\x10\x02\x12\x0c\n\x08\x44ISCRETE\x10\x03\x12\x0f\n\x0b\x43\x41TEGORICAL\x10\x04*8\n\rObjectiveType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0c\n\x08MINIMIZE\x10\x01\x12\x0c\n\x08MAXIMIZE\x10\x02*J\n\x0e\x43omparisonType\x12\x16\n\x12UNKNOWN_COMPARISON\x10\x00\x12\t\n\x05\x45QUAL\x10\x01\x12\x08\n\x04LESS\x10\x02\x12\x0b\n\x07GREATER\x10\x03\x32\xc6\x02\n\tDBManager\x12j\n\x14ReportObservationLog\x12).api.v1.beta1.ReportObservationLogRequest\x1a\'.api.v1.beta1.ReportObservationLogReply\x12\x61\n\x11GetObservationLog\x12&.api.v1.beta1.GetObservationLogRequest\x1a$.api.v1.beta1.GetObservationLogReply\x12j\n\x14\x44\x65leteObservationLog\x12).api.v1.beta1.DeleteObservationLogRequest\x1a\'.api.v1.beta1.DeleteObservationLogReply2\xe1\x01\n\nSuggestion\x12X\n\x0eGetSuggestions\x12#.api.v1.beta1.GetSuggestionsRequest\x1a!.api.v1.beta1.GetSuggestionsReply\x12y\n\x19ValidateAlgorithmSettings\x12..api.v1.beta1.ValidateAlgorithmSettingsRequest\x1a,.api.v1.beta1.ValidateAlgorithmSettingsReply2\xe0\x02\n\rEarlyStopping\x12m\n\x15GetEarlyStoppingRules\x12*.api.v1.beta1.GetEarlyStoppingRulesRequest\x1a(.api.v1.beta1.GetEarlyStoppingRulesReply\x12X\n\x0eSetTrialStatus\x12#.api.v1.beta1.SetTrialStatusRequest\x1a!.api.v1.beta1.SetTrialStatusReply\x12\x85\x01\n\x1dValidateEarlyStoppingSettings\x12\x32.api.v1.beta1.ValidateEarlyStoppingSettingsRequest\x1a\x30.api.v1.beta1.ValidateEarlyStoppingSettingsReplyb\x06proto3') ) _PARAMETERTYPE = _descriptor.EnumDescriptor( @@ -52,8 +52,8 @@ ], containing_type=None, options=None, - serialized_start=3934, - serialized_end=4019, + serialized_start=4074, + serialized_end=4159, ) _sym_db.RegisterEnumDescriptor(_PARAMETERTYPE) @@ -79,8 +79,8 @@ ], containing_type=None, options=None, - serialized_start=4021, - serialized_end=4077, + serialized_start=4161, + serialized_end=4217, ) _sym_db.RegisterEnumDescriptor(_OBJECTIVETYPE) @@ -110,8 +110,8 @@ ], containing_type=None, options=None, - serialized_start=4079, - serialized_end=4153, + serialized_start=4219, + serialized_end=4293, ) _sym_db.RegisterEnumDescriptor(_COMPARISONTYPE) @@ -1655,6 +1655,61 @@ ) +_VALIDATEEARLYSTOPPINGSETTINGSREQUEST = _descriptor.Descriptor( + name='ValidateEarlyStoppingSettingsRequest', + full_name='api.v1.beta1.ValidateEarlyStoppingSettingsRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='early_stopping_spec', full_name='api.v1.beta1.ValidateEarlyStoppingSettingsRequest.early_stopping_spec', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3866, + serialized_end=3966, +) + + +_VALIDATEEARLYSTOPPINGSETTINGSREPLY = _descriptor.Descriptor( + name='ValidateEarlyStoppingSettingsReply', + full_name='api.v1.beta1.ValidateEarlyStoppingSettingsReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3968, + serialized_end=4004, +) + + _SETTRIALSTATUSREQUEST = _descriptor.Descriptor( name='SetTrialStatusRequest', full_name='api.v1.beta1.SetTrialStatusRequest', @@ -1681,8 +1736,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3866, - serialized_end=3909, + serialized_start=4006, + serialized_end=4049, ) @@ -1705,8 +1760,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3911, - serialized_end=3932, + serialized_start=4051, + serialized_end=4072, ) _EXPERIMENT.fields_by_name['spec'].message_type = _EXPERIMENTSPEC @@ -1755,6 +1810,7 @@ _GETEARLYSTOPPINGRULESREQUEST.fields_by_name['trials'].message_type = _TRIAL _GETEARLYSTOPPINGRULESREPLY.fields_by_name['early_stopping_rules'].message_type = _EARLYSTOPPINGRULE _EARLYSTOPPINGRULE.fields_by_name['comparison'].enum_type = _COMPARISONTYPE +_VALIDATEEARLYSTOPPINGSETTINGSREQUEST.fields_by_name['early_stopping_spec'].message_type = _EARLYSTOPPINGSPEC DESCRIPTOR.message_types_by_name['Experiment'] = _EXPERIMENT DESCRIPTOR.message_types_by_name['ExperimentSpec'] = _EXPERIMENTSPEC DESCRIPTOR.message_types_by_name['ParameterSpec'] = _PARAMETERSPEC @@ -1788,6 +1844,8 @@ DESCRIPTOR.message_types_by_name['GetEarlyStoppingRulesRequest'] = _GETEARLYSTOPPINGRULESREQUEST DESCRIPTOR.message_types_by_name['GetEarlyStoppingRulesReply'] = _GETEARLYSTOPPINGRULESREPLY DESCRIPTOR.message_types_by_name['EarlyStoppingRule'] = _EARLYSTOPPINGRULE +DESCRIPTOR.message_types_by_name['ValidateEarlyStoppingSettingsRequest'] = _VALIDATEEARLYSTOPPINGSETTINGSREQUEST +DESCRIPTOR.message_types_by_name['ValidateEarlyStoppingSettingsReply'] = _VALIDATEEARLYSTOPPINGSETTINGSREPLY DESCRIPTOR.message_types_by_name['SetTrialStatusRequest'] = _SETTRIALSTATUSREQUEST DESCRIPTOR.message_types_by_name['SetTrialStatusReply'] = _SETTRIALSTATUSREPLY DESCRIPTOR.enum_types_by_name['ParameterType'] = _PARAMETERTYPE @@ -2066,6 +2124,20 @@ )) _sym_db.RegisterMessage(EarlyStoppingRule) +ValidateEarlyStoppingSettingsRequest = _reflection.GeneratedProtocolMessageType('ValidateEarlyStoppingSettingsRequest', (_message.Message,), dict( + DESCRIPTOR = _VALIDATEEARLYSTOPPINGSETTINGSREQUEST, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:api.v1.beta1.ValidateEarlyStoppingSettingsRequest) + )) +_sym_db.RegisterMessage(ValidateEarlyStoppingSettingsRequest) + +ValidateEarlyStoppingSettingsReply = _reflection.GeneratedProtocolMessageType('ValidateEarlyStoppingSettingsReply', (_message.Message,), dict( + DESCRIPTOR = _VALIDATEEARLYSTOPPINGSETTINGSREPLY, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:api.v1.beta1.ValidateEarlyStoppingSettingsReply) + )) +_sym_db.RegisterMessage(ValidateEarlyStoppingSettingsReply) + SetTrialStatusRequest = _reflection.GeneratedProtocolMessageType('SetTrialStatusRequest', (_message.Message,), dict( DESCRIPTOR = _SETTRIALSTATUSREQUEST, __module__ = 'api_pb2' @@ -2090,8 +2162,8 @@ file=DESCRIPTOR, index=0, options=None, - serialized_start=4156, - serialized_end=4482, + serialized_start=4296, + serialized_end=4622, methods=[ _descriptor.MethodDescriptor( name='ReportObservationLog', @@ -2132,8 +2204,8 @@ file=DESCRIPTOR, index=1, options=None, - serialized_start=4485, - serialized_end=4710, + serialized_start=4625, + serialized_end=4850, methods=[ _descriptor.MethodDescriptor( name='GetSuggestions', @@ -2165,8 +2237,8 @@ file=DESCRIPTOR, index=2, options=None, - serialized_start=4713, - serialized_end=4929, + serialized_start=4853, + serialized_end=5205, methods=[ _descriptor.MethodDescriptor( name='GetEarlyStoppingRules', @@ -2186,6 +2258,15 @@ output_type=_SETTRIALSTATUSREPLY, options=None, ), + _descriptor.MethodDescriptor( + name='ValidateEarlyStoppingSettings', + full_name='api.v1.beta1.EarlyStopping.ValidateEarlyStoppingSettings', + index=2, + containing_service=None, + input_type=_VALIDATEEARLYSTOPPINGSETTINGSREQUEST, + output_type=_VALIDATEEARLYSTOPPINGSETTINGSREPLY, + options=None, + ), ]) _sym_db.RegisterServiceDescriptor(_EARLYSTOPPING) @@ -2367,6 +2448,11 @@ def __init__(self, channel): request_serializer=SetTrialStatusRequest.SerializeToString, response_deserializer=SetTrialStatusReply.FromString, ) + self.ValidateEarlyStoppingSettings = channel.unary_unary( + '/api.v1.beta1.EarlyStopping/ValidateEarlyStoppingSettings', + request_serializer=ValidateEarlyStoppingSettingsRequest.SerializeToString, + response_deserializer=ValidateEarlyStoppingSettingsReply.FromString, + ) class EarlyStoppingServicer(object): @@ -2388,6 +2474,13 @@ def SetTrialStatus(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def ValidateEarlyStoppingSettings(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_EarlyStoppingServicer_to_server(servicer, server): rpc_method_handlers = { @@ -2401,6 +2494,11 @@ def add_EarlyStoppingServicer_to_server(servicer, server): request_deserializer=SetTrialStatusRequest.FromString, response_serializer=SetTrialStatusReply.SerializeToString, ), + 'ValidateEarlyStoppingSettings': grpc.unary_unary_rpc_method_handler( + servicer.ValidateEarlyStoppingSettings, + request_deserializer=ValidateEarlyStoppingSettingsRequest.FromString, + response_serializer=ValidateEarlyStoppingSettingsReply.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'api.v1.beta1.EarlyStopping', rpc_method_handlers) @@ -2619,6 +2717,10 @@ def SetTrialStatus(self, request, context): # missing associated documentation comment in .proto file pass context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def ValidateEarlyStoppingSettings(self, request, context): + # missing associated documentation comment in .proto file + pass + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) class BetaEarlyStoppingStub(object): @@ -2640,6 +2742,11 @@ def SetTrialStatus(self, request, timeout, metadata=None, with_call=False, proto pass raise NotImplementedError() SetTrialStatus.future = None + def ValidateEarlyStoppingSettings(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + # missing associated documentation comment in .proto file + pass + raise NotImplementedError() + ValidateEarlyStoppingSettings.future = None def beta_create_EarlyStopping_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): @@ -2651,14 +2758,17 @@ def beta_create_EarlyStopping_server(servicer, pool=None, pool_size=None, defaul request_deserializers = { ('api.v1.beta1.EarlyStopping', 'GetEarlyStoppingRules'): GetEarlyStoppingRulesRequest.FromString, ('api.v1.beta1.EarlyStopping', 'SetTrialStatus'): SetTrialStatusRequest.FromString, + ('api.v1.beta1.EarlyStopping', 'ValidateEarlyStoppingSettings'): ValidateEarlyStoppingSettingsRequest.FromString, } response_serializers = { ('api.v1.beta1.EarlyStopping', 'GetEarlyStoppingRules'): GetEarlyStoppingRulesReply.SerializeToString, ('api.v1.beta1.EarlyStopping', 'SetTrialStatus'): SetTrialStatusReply.SerializeToString, + ('api.v1.beta1.EarlyStopping', 'ValidateEarlyStoppingSettings'): ValidateEarlyStoppingSettingsReply.SerializeToString, } method_implementations = { ('api.v1.beta1.EarlyStopping', 'GetEarlyStoppingRules'): face_utilities.unary_unary_inline(servicer.GetEarlyStoppingRules), ('api.v1.beta1.EarlyStopping', 'SetTrialStatus'): face_utilities.unary_unary_inline(servicer.SetTrialStatus), + ('api.v1.beta1.EarlyStopping', 'ValidateEarlyStoppingSettings'): face_utilities.unary_unary_inline(servicer.ValidateEarlyStoppingSettings), } server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) return beta_implementations.server(method_implementations, options=server_options) @@ -2673,14 +2783,17 @@ def beta_create_EarlyStopping_stub(channel, host=None, metadata_transformer=None request_serializers = { ('api.v1.beta1.EarlyStopping', 'GetEarlyStoppingRules'): GetEarlyStoppingRulesRequest.SerializeToString, ('api.v1.beta1.EarlyStopping', 'SetTrialStatus'): SetTrialStatusRequest.SerializeToString, + ('api.v1.beta1.EarlyStopping', 'ValidateEarlyStoppingSettings'): ValidateEarlyStoppingSettingsRequest.SerializeToString, } response_deserializers = { ('api.v1.beta1.EarlyStopping', 'GetEarlyStoppingRules'): GetEarlyStoppingRulesReply.FromString, ('api.v1.beta1.EarlyStopping', 'SetTrialStatus'): SetTrialStatusReply.FromString, + ('api.v1.beta1.EarlyStopping', 'ValidateEarlyStoppingSettings'): ValidateEarlyStoppingSettingsReply.FromString, } cardinalities = { 'GetEarlyStoppingRules': cardinality.Cardinality.UNARY_UNARY, 'SetTrialStatus': cardinality.Cardinality.UNARY_UNARY, + 'ValidateEarlyStoppingSettings': cardinality.Cardinality.UNARY_UNARY, } stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) return beta_implementations.dynamic_stub(channel, 'api.v1.beta1.EarlyStopping', cardinalities, options=stub_options) diff --git a/pkg/apis/manager/v1beta1/python/api_pb2_grpc.py b/pkg/apis/manager/v1beta1/python/api_pb2_grpc.py index 59a494edc5a..7d5cbf79006 100644 --- a/pkg/apis/manager/v1beta1/python/api_pb2_grpc.py +++ b/pkg/apis/manager/v1beta1/python/api_pb2_grpc.py @@ -170,6 +170,11 @@ def __init__(self, channel): request_serializer=api__pb2.SetTrialStatusRequest.SerializeToString, response_deserializer=api__pb2.SetTrialStatusReply.FromString, ) + self.ValidateEarlyStoppingSettings = channel.unary_unary( + '/api.v1.beta1.EarlyStopping/ValidateEarlyStoppingSettings', + request_serializer=api__pb2.ValidateEarlyStoppingSettingsRequest.SerializeToString, + response_deserializer=api__pb2.ValidateEarlyStoppingSettingsReply.FromString, + ) class EarlyStoppingServicer(object): @@ -191,6 +196,13 @@ def SetTrialStatus(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def ValidateEarlyStoppingSettings(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_EarlyStoppingServicer_to_server(servicer, server): rpc_method_handlers = { @@ -204,6 +216,11 @@ def add_EarlyStoppingServicer_to_server(servicer, server): request_deserializer=api__pb2.SetTrialStatusRequest.FromString, response_serializer=api__pb2.SetTrialStatusReply.SerializeToString, ), + 'ValidateEarlyStoppingSettings': grpc.unary_unary_rpc_method_handler( + servicer.ValidateEarlyStoppingSettings, + request_deserializer=api__pb2.ValidateEarlyStoppingSettingsRequest.FromString, + response_serializer=api__pb2.ValidateEarlyStoppingSettingsReply.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'api.v1.beta1.EarlyStopping', rpc_method_handlers) diff --git a/pkg/controller.v1beta1/suggestion/suggestion_controller.go b/pkg/controller.v1beta1/suggestion/suggestion_controller.go index 0c746588161..60c6057deb5 100644 --- a/pkg/controller.v1beta1/suggestion/suggestion_controller.go +++ b/pkg/controller.v1beta1/suggestion/suggestion_controller.go @@ -275,6 +275,15 @@ func (r *ReconcileSuggestion) ReconcileSuggestion(instance *suggestionsv1beta1.S // return nil since it is a terminal condition return nil } + if instance.Spec.EarlyStopping != nil && instance.Spec.EarlyStopping.AlgorithmName != "" { + if err = r.ValidateEarlyStoppingSettings(instance, experiment); err != nil { + logger.Error(err, "Marking suggestion failed as early stopping settings validation failed") + msg := fmt.Sprintf("Validation failed: %v", err) + instance.MarkSuggestionStatusFailed(SuggestionFailedReason, msg) + // return nil since it is a terminal condition + return nil + } + } msg := "Suggestion is running" instance.MarkSuggestionStatusRunning(corev1.ConditionTrue, SuggestionRunningReason, msg) } diff --git a/pkg/controller.v1beta1/suggestion/suggestion_controller_test.go b/pkg/controller.v1beta1/suggestion/suggestion_controller_test.go index 4e29636e5ef..75b5bf3c160 100644 --- a/pkg/controller.v1beta1/suggestion/suggestion_controller_test.go +++ b/pkg/controller.v1beta1/suggestion/suggestion_controller_test.go @@ -19,6 +19,8 @@ package suggestion import ( "context" "encoding/json" + "fmt" + "strings" "sync" "testing" "time" @@ -47,12 +49,14 @@ import ( ) const ( - suggestionName = "test-suggestion" - resourceName = "test-suggestion-random" - namespace = "kubeflow" - suggestionImage = "test-image" - katibConfigName = "katib-config" - timeout = time.Second * 40 + suggestionName = "test-suggestion" + resourceName = "test-suggestion-random" + namespace = "kubeflow" + suggestionImage = "test-image" + katibConfigName = "katib-config" + timeout = time.Second * 40 + invalidAlgorithmSettingsSuggestionName = "invalid-algorithm-settings" + invalidEarlyStoppingSettingsSuggestionName = "invalid-earlystopping-settings" ) func init() { @@ -100,7 +104,20 @@ func TestReconcile(t *testing.T) { g.Expect(mgr.Start(context.TODO())).NotTo(gomega.HaveOccurred()) }() - mockSuggestionClient.EXPECT().ValidateAlgorithmSettings(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + mockSuggestionClient.EXPECT().ValidateAlgorithmSettings(gomock.Any(), gomock.Any()).DoAndReturn( + func(instance *suggestionsv1beta1.Suggestion, e *experimentsv1beta1.Experiment) error { + if e.Name == invalidAlgorithmSettingsSuggestionName { + return fmt.Errorf("ValidateAlgorithmSettings Error") + } + return nil + }).AnyTimes() + mockSuggestionClient.EXPECT().ValidateEarlyStoppingSettings(gomock.Any(), gomock.Any()).DoAndReturn( + func(instance *suggestionsv1beta1.Suggestion, e *experimentsv1beta1.Experiment) error { + if e.Name == invalidEarlyStoppingSettingsSuggestionName { + return fmt.Errorf("ValidateEarlyStoppingSettings Error") + } + return nil + }).AnyTimes() mockSuggestionClient.EXPECT().SyncAssignments(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() instance := newFakeInstance() @@ -130,6 +147,7 @@ func TestReconcile(t *testing.T) { Name: namespace, }, } + g.Expect(c.Create(context.TODO(), kubeflowNS)).NotTo(gomega.HaveOccurred()) // Test 1 - Early stopping suggestion run // Create ConfigMap with suggestion and early stopping data. @@ -265,6 +283,123 @@ func TestReconcile(t *testing.T) { // Test 4 - Update status condition for empty experiment g.Expect(r.updateStatusCondition(&suggestionsv1beta1.Suggestion{}, oldS)).To(gomega.HaveOccurred()) + // Delete the experiment + g.Expect(c.Delete(context.TODO(), experiment)).NotTo(gomega.HaveOccurred()) + + // Expect that experiment is deleted + g.Eventually(func() bool { + return errors.IsNotFound(c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: suggestionName}, &experimentsv1beta1.Experiment{})) + }, timeout).Should(gomega.BeTrue()) + + // Test 5 - ValidateAlgorithmSettings returns error + experiment = &experimentsv1beta1.Experiment{ + ObjectMeta: metav1.ObjectMeta{ + Name: invalidAlgorithmSettingsSuggestionName, + Namespace: namespace, + }, + } + instance = newFakeInstance() + instance.Name = invalidAlgorithmSettingsSuggestionName + invalidResourceName := strings.Join([]string{invalidAlgorithmSettingsSuggestionName, "random"}, "-") + suggestionDeploy = &appsv1.Deployment{} + + // Create the suggestion + g.Expect(c.Create(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) + // Create experiment + g.Expect(c.Create(context.TODO(), experiment)).NotTo(gomega.HaveOccurred()) + + // Expect deployment with appropriate name is created + g.Eventually(func() error { + return c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: invalidResourceName}, suggestionDeploy) + }, timeout).Should(gomega.Succeed()) + + // Manually change ready deployment status + suggestionDeploy.Status = appsv1.DeploymentStatus{ + Conditions: []appsv1.DeploymentCondition{ + { + Type: appsv1.DeploymentAvailable, + Status: corev1.ConditionTrue, + }, + }, + } + + g.Expect(c.Status().Update(context.TODO(), suggestionDeploy)).NotTo(gomega.HaveOccurred()) + + // Expect that suggestion status is failed + suggestion = &suggestionsv1beta1.Suggestion{} + g.Eventually(func() bool { + if err = c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: invalidAlgorithmSettingsSuggestionName}, suggestion); err != nil { + return false + } + return suggestion.IsFailed() + }, timeout).Should(gomega.BeTrue()) + + // Delete the experiment + g.Expect(c.Delete(context.TODO(), experiment)).NotTo(gomega.HaveOccurred()) + + // Expect that experiment is deleted + g.Eventually(func() bool { + return errors.IsNotFound(c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: invalidAlgorithmSettingsSuggestionName}, &experimentsv1beta1.Experiment{})) + }, timeout).Should(gomega.BeTrue()) + + // Delete the suggestion + g.Expect(c.Delete(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) + + // Expect that suggestion is deleted + g.Eventually(func() bool { + return errors.IsNotFound(c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: invalidAlgorithmSettingsSuggestionName}, &suggestionsv1beta1.Suggestion{})) + }, timeout).Should(gomega.BeTrue()) + + // Delete the deployment is deleted + g.Expect(c.Delete(context.TODO(), suggestionDeploy)).NotTo(gomega.HaveOccurred()) + + // Expect that deployment is deleted + g.Eventually(func() bool { + return errors.IsNotFound(c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: invalidResourceName}, &appsv1.Deployment{})) + }, timeout).Should(gomega.BeTrue()) + + // Test 6 - ValidateEarlyStoppingSettings returns error + experiment = &experimentsv1beta1.Experiment{ + ObjectMeta: metav1.ObjectMeta{ + Name: invalidEarlyStoppingSettingsSuggestionName, + Namespace: namespace, + }, + } + instance = newFakeInstance() + instance.Name = invalidEarlyStoppingSettingsSuggestionName + invalidResourceName = strings.Join([]string{invalidEarlyStoppingSettingsSuggestionName, "random"}, "-") + + // Create the suggestion + g.Expect(c.Create(context.TODO(), instance)).NotTo(gomega.HaveOccurred()) + // Create experiment + g.Expect(c.Create(context.TODO(), experiment)).NotTo(gomega.HaveOccurred()) + + // Expect deployment with appropriate name is created + g.Eventually(func() error { + return c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: invalidResourceName}, suggestionDeploy) + }, timeout).Should(gomega.Succeed()) + + // Manually change ready deployment status + suggestionDeploy.Status = appsv1.DeploymentStatus{ + Conditions: []appsv1.DeploymentCondition{ + { + Type: appsv1.DeploymentAvailable, + Status: corev1.ConditionTrue, + }, + }, + } + + g.Expect(c.Status().Update(context.TODO(), suggestionDeploy)).NotTo(gomega.HaveOccurred()) + + // Expect that suggestion status is failed + suggestion = &suggestionsv1beta1.Suggestion{} + g.Eventually(func() bool { + if err = c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: invalidEarlyStoppingSettingsSuggestionName}, suggestion); err != nil { + return false + } + return suggestion.IsFailed() + }, timeout).Should(gomega.BeTrue()) + } func newFakeInstance() *suggestionsv1beta1.Suggestion { diff --git a/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient.go b/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient.go index f64c3255227..47864ce1497 100644 --- a/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient.go +++ b/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient.go @@ -60,6 +60,7 @@ type SuggestionClient interface { ts []trialsv1beta1.Trial) error ValidateAlgorithmSettings(instance *suggestionsv1beta1.Suggestion, e *experimentsv1beta1.Experiment) error + ValidateEarlyStoppingSettings(instance *suggestionsv1beta1.Suggestion, e *experimentsv1beta1.Experiment) error } // General is the implementation for SuggestionClient. @@ -231,6 +232,58 @@ func (g *General) ValidateAlgorithmSettings(instance *suggestionsv1beta1.Suggest return nil } +// ValidateEarlyStoppingSettings validates if the algorithm specific configurations for early stopping are valid. +func (g *General) ValidateEarlyStoppingSettings(instance *suggestionsv1beta1.Suggestion, e *experimentsv1beta1.Experiment) error { + logger := log.WithValues("EarlyStopping", types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}) + endpoint := util.GetEarlyStoppingEndpoint(instance) + + callOpts := []grpc_retry.CallOption{ + grpc_retry.WithBackoff(grpc_retry.BackoffLinear(consts.DefaultGRPCRetryPeriod)), + grpc_retry.WithMax(consts.DefaultGRPCRetryAttempts), + } + conn, err := grpc.Dial(endpoint, grpc.WithInsecure(), + grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(callOpts...)), + grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(callOpts...)), + ) + if err != nil { + return err + } + defer conn.Close() + + rpcClient := getRPCClientEarlyStopping(conn) + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + request := &suggestionapi.ValidateEarlyStoppingSettingsRequest{ + EarlyStoppingSpec: g.ConvertExperiment(e).Spec.EarlyStopping, + } + + // See https://github.com/grpc/grpc-go/issues/2636 + // See https://github.com/grpc/grpc-go/pull/2503 + _, err = rpcClient.ValidateEarlyStoppingSettings(ctx, request, grpc.WaitForReady(true)) + statusCode, _ := status.FromError(err) + + // validation error + if statusCode.Code() == codes.InvalidArgument || statusCode.Code() == codes.Unknown { + logger.Error(err, "ValidateEarlyStoppingSettings error") + return fmt.Errorf("ValidateEarlyStoppingSettings Error: %v", statusCode.Message()) + } + + // Connection error + if statusCode.Code() == codes.Unavailable { + logger.Error(err, "Connection to EarlyStopping algorithm service currently unavailable") + return err + } + + // Validate to true as function is not implemented + if statusCode.Code() == codes.Unimplemented { + logger.Info("Method ValidateEarlyStoppingSettings not found", "EarlyStopping service", e.Spec.EarlyStopping.AlgorithmName) + return nil + } + logger.Info("EarlyStopping settings validated") + return nil +} + // ConvertExperiment converts CRD to the GRPC definition. func (g *General) ConvertExperiment(e *experimentsv1beta1.Experiment) *suggestionapi.Experiment { res := &suggestionapi.Experiment{} diff --git a/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient_test.go b/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient_test.go index 506e82a4274..9e1cdacf474 100644 --- a/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient_test.go +++ b/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient_test.go @@ -330,6 +330,85 @@ func TestValidateAlgorithmSettings(t *testing.T) { } } +func TestValidateEarlyStoppingSettings(t *testing.T) { + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + rpcClientEarlyStopping := suggestionapimock.NewMockEarlyStoppingClient(mockCtrl) + + getRPCClientEarlyStopping = func(conn *grpc.ClientConn) suggestionapi.EarlyStoppingClient { + return rpcClientEarlyStopping + } + + expectedRequest := &suggestionapi.ValidateEarlyStoppingSettingsRequest{ + EarlyStoppingSpec: newFakeRequest().Experiment.Spec.EarlyStopping, + } + + validRun := rpcClientEarlyStopping.EXPECT().ValidateEarlyStoppingSettings(gomock.Any(), k8sMatcher{expectedRequest}, gomock.Any()).Return(nil, nil) + + invalidExperiment := rpcClientEarlyStopping.EXPECT().ValidateEarlyStoppingSettings(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, + status.Error(codes.InvalidArgument, "Invalid experiment parameter")) + connectionError := rpcClientEarlyStopping.EXPECT().ValidateEarlyStoppingSettings(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, + status.Error(codes.Unavailable, "Unable to connect")) + unimplementedMethod := rpcClientEarlyStopping.EXPECT().ValidateEarlyStoppingSettings(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, + status.Error(codes.Unimplemented, "Method not implemented")) + + suggestionClient := New() + + exp := newFakeExperiment() + sug := newFakeSuggestion() + + gomock.InOrder( + validRun, + invalidExperiment, + connectionError, + unimplementedMethod) + + tcs := []struct { + Experiment *experimentsv1beta1.Experiment + Suggestion *suggestionsv1beta1.Suggestion + Err bool + TestDescription string + }{ + // validRun case + { + Experiment: exp, + Suggestion: sug, + Err: false, + TestDescription: "ValidateEarlyStoppingSettings valid run", + }, + // invalidExperiment case + { + Experiment: exp, + Suggestion: sug, + Err: true, + TestDescription: "Invalid argument return in Experiment validation", + }, + // connectionError case + { + Experiment: exp, + Suggestion: sug, + Err: true, + TestDescription: "Connection to early stopping service error", + }, + // unimplementedMethod case + { + Experiment: exp, + Suggestion: sug, + Err: false, + TestDescription: "Unimplemented ValidateEarlyStoppingSettings method", + }, + } + for _, tc := range tcs { + err := suggestionClient.ValidateEarlyStoppingSettings(tc.Suggestion, tc.Experiment) + if !tc.Err && err != nil { + t.Errorf("Case: %v failed. Expected nil, got %v", tc.TestDescription, err) + } else if tc.Err && err == nil { + t.Errorf("Case: %v failed. Expected err, got nil", tc.TestDescription) + } + } +} + func TestConvertTrialConditionType(t *testing.T) { tcs := []struct { diff --git a/pkg/earlystopping/v1beta1/medianstop/service.py b/pkg/earlystopping/v1beta1/medianstop/service.py index 0952491b0eb..c985104c889 100644 --- a/pkg/earlystopping/v1beta1/medianstop/service.py +++ b/pkg/earlystopping/v1beta1/medianstop/service.py @@ -64,6 +64,39 @@ def __init__(self): self.api_instance = client.CustomObjectsApi() + def ValidateEarlyStoppingSettings(self, request, context): + is_valid, message = self.validate_early_stopping_spec(request.early_stopping_spec) + if not is_valid: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(message) + logger.error(message) + return api_pb2.ValidateEarlyStoppingSettingsReply() + + def validate_early_stopping_spec(self, early_stopping_spec): + algorithm_name = early_stopping_spec.algorithm_name + if algorithm_name == "medianstop": + return self.validate_medianstop_setting(early_stopping_spec.algorithm_settings) + else: + return False, "unknown algorithm name {}".format(algorithm_name) + + @staticmethod + def validate_medianstop_setting(early_stopping_settings): + for setting in early_stopping_settings: + try: + if setting.name == "min_trials_required": + if not (int(setting.value) >= 0): + return False, "min_trials_required must be greater or equal than zero (>=0)" + elif setting.name == "start_step": + if not (int(setting.value) >= 1): + return False, "start_step must be greater or equal than one (>=1)" + else: + return False, "unknown setting {} for algorithm medianstop".format(setting.name) + + except Exception as e: + return False, "failed to validate {}({}): {}".format(setting.name, setting.value, e) + + return True, "" + def GetEarlyStoppingRules(self, request, context): logger.info("Get new early stopping rules") @@ -71,7 +104,7 @@ def GetEarlyStoppingRules(self, request, context): if self.is_first_run: self.is_first_run = False # Get early stopping settings. - self.getEarlyStoppingSettings(request.experiment.spec.early_stopping.algorithm_settings) + self.get_early_stopping_settings(request.experiment.spec.early_stopping.algorithm_settings) logger.info("Median stopping settings are: min_trials_required: {}, start_step: {}".format( self.min_trials_required, self.start_step)) @@ -90,7 +123,7 @@ def GetEarlyStoppingRules(self, request, context): early_stopping_rules = [] - median = self.getMedianValue(request.trials) + median = self.get_median_value(request.trials) if median is not None: early_stopping_rules.append(api_pb2.EarlyStoppingRule( name=self.objective_metric, @@ -104,14 +137,14 @@ def GetEarlyStoppingRules(self, request, context): early_stopping_rules=early_stopping_rules ) - def getEarlyStoppingSettings(self, early_stopping_settings): + def get_early_stopping_settings(self, early_stopping_settings): for setting in early_stopping_settings: if setting.name == "min_trials_required": self.min_trials_required = int(setting.value) elif setting.name == "start_step": self.start_step = int(setting.value) - def getMedianValue(self, trials): + def get_median_value(self, trials): for trial in trials: # Get metrics only for the new succeeded Trials. if trial.name not in self.trials_avg_history and trial.status.condition == SUCCEEDED_TRIAL: diff --git a/pkg/mock/v1beta1/api/earlystopping.go b/pkg/mock/v1beta1/api/earlystopping.go index be5eaf77d85..416269d6eaf 100644 --- a/pkg/mock/v1beta1/api/earlystopping.go +++ b/pkg/mock/v1beta1/api/earlystopping.go @@ -75,3 +75,23 @@ func (mr *MockEarlyStoppingClientMockRecorder) SetTrialStatus(arg0, arg1 interfa varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrialStatus", reflect.TypeOf((*MockEarlyStoppingClient)(nil).SetTrialStatus), varargs...) } + +// ValidateEarlyStoppingSettings mocks base method. +func (m *MockEarlyStoppingClient) ValidateEarlyStoppingSettings(arg0 context.Context, arg1 *api_v1_beta1.ValidateEarlyStoppingSettingsRequest, arg2 ...grpc.CallOption) (*api_v1_beta1.ValidateEarlyStoppingSettingsReply, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ValidateEarlyStoppingSettings", varargs...) + ret0, _ := ret[0].(*api_v1_beta1.ValidateEarlyStoppingSettingsReply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ValidateEarlyStoppingSettings indicates an expected call of ValidateEarlyStoppingSettings. +func (mr *MockEarlyStoppingClientMockRecorder) ValidateEarlyStoppingSettings(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateEarlyStoppingSettings", reflect.TypeOf((*MockEarlyStoppingClient)(nil).ValidateEarlyStoppingSettings), varargs...) +} diff --git a/pkg/mock/v1beta1/suggestion/suggestionclient/suggestionclient.go b/pkg/mock/v1beta1/suggestion/suggestionclient/suggestionclient.go index 400e3740bf5..f6ef886d773 100644 --- a/pkg/mock/v1beta1/suggestion/suggestionclient/suggestionclient.go +++ b/pkg/mock/v1beta1/suggestion/suggestionclient/suggestionclient.go @@ -63,3 +63,17 @@ func (mr *MockSuggestionClientMockRecorder) ValidateAlgorithmSettings(arg0, arg1 mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAlgorithmSettings", reflect.TypeOf((*MockSuggestionClient)(nil).ValidateAlgorithmSettings), arg0, arg1) } + +// ValidateEarlyStoppingSettings mocks base method. +func (m *MockSuggestionClient) ValidateEarlyStoppingSettings(arg0 *v1beta10.Suggestion, arg1 *v1beta1.Experiment) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidateEarlyStoppingSettings", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ValidateEarlyStoppingSettings indicates an expected call of ValidateEarlyStoppingSettings. +func (mr *MockSuggestionClientMockRecorder) ValidateEarlyStoppingSettings(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateEarlyStoppingSettings", reflect.TypeOf((*MockSuggestionClient)(nil).ValidateEarlyStoppingSettings), arg0, arg1) +} diff --git a/test/unit/v1beta1/earlystopping/test_medianstop_service.py b/test/unit/v1beta1/earlystopping/test_medianstop_service.py index 5da7e00cdc9..96035c08fb3 100644 --- a/test/unit/v1beta1/earlystopping/test_medianstop_service.py +++ b/test/unit/v1beta1/earlystopping/test_medianstop_service.py @@ -21,6 +21,8 @@ from pkg.earlystopping.v1beta1.medianstop.service import MedianStopService +import utils + class TestMedianStop(unittest.TestCase): def setUp(self): @@ -37,8 +39,78 @@ def setUp(self): self.test_server = grpc_testing.server_from_dictionary( servicers, grpc_testing.strict_real_time()) - def test_get_earlystopping_rules(self): + def test_validate_early_stopping_settings(self): + # Valid cases + early_stopping_spec = api_pb2.EarlyStoppingSpec( + algorithm_name="medianstop", + algorithm_settings=[ + api_pb2.EarlyStoppingSetting( + name="min_trials_required", + value="2", + ), + api_pb2.EarlyStoppingSetting( + name="start_step", + value="5", + ), + ], + ) + + _, _, code, _ = utils.call_validate(self.test_server, early_stopping_spec) + self.assertEqual(code, grpc.StatusCode.OK) + + # Invalid cases + # Unknown algorithm name + early_stopping_spec = api_pb2.EarlyStoppingSpec(algorithm_name="unknown") + + _, _, code, details = utils.call_validate(self.test_server, early_stopping_spec) + self.assertEqual(code, grpc.StatusCode.INVALID_ARGUMENT) + self.assertEqual(details, "unknown algorithm name unknown") + + # Unknown config name + early_stopping_spec = api_pb2.EarlyStoppingSpec( + algorithm_name="medianstop", + algorithm_settings=[ + api_pb2.EarlyStoppingSetting( + name="unknown_conf", + value="100", + ), + ], + ) + + _, _, code, details = utils.call_validate(self.test_server, early_stopping_spec) + self.assertEqual(code, grpc.StatusCode.INVALID_ARGUMENT) + self.assertEqual(details, "unknown setting unknown_conf for algorithm medianstop") + + # Wrong min_trials_required + early_stopping_spec = api_pb2.EarlyStoppingSpec( + algorithm_name="medianstop", + algorithm_settings=[ + api_pb2.EarlyStoppingSetting( + name="min_trials_required", + value="-1", + ), + ], + ) + _, _, code, details = utils.call_validate(self.test_server, early_stopping_spec) + self.assertEqual(code, grpc.StatusCode.INVALID_ARGUMENT) + self.assertEqual(details, "min_trials_required must be greater or equal than zero (>=0)") + + # Wrong start_step + early_stopping_spec = api_pb2.EarlyStoppingSpec( + algorithm_name="medianstop", + algorithm_settings=[ + api_pb2.EarlyStoppingSetting( + name="start_step", + value="0", + ), + ], + ) + _, _, code, details = utils.call_validate(self.test_server, early_stopping_spec) + self.assertEqual(code, grpc.StatusCode.INVALID_ARGUMENT) + self.assertEqual(details, "start_step must be greater or equal than one (>=1)") + + def test_get_earlystopping_rules(self): # TODO (andreyvelich): Add more informative tests. trials = [ api_pb2.Trial( @@ -61,8 +133,8 @@ def test_get_earlystopping_rules(self): get_earlystopping_rules = self.test_server.invoke_unary_unary( method_descriptor=(api_pb2.DESCRIPTOR - .services_by_name['EarlyStopping'] - .methods_by_name['GetEarlyStoppingRules']), + .services_by_name['EarlyStopping'] + .methods_by_name['GetEarlyStoppingRules']), invocation_metadata={}, request=request, timeout=1) diff --git a/test/unit/v1beta1/earlystopping/utils.py b/test/unit/v1beta1/earlystopping/utils.py new file mode 100644 index 00000000000..7498c8e66c3 --- /dev/null +++ b/test/unit/v1beta1/earlystopping/utils.py @@ -0,0 +1,16 @@ + +from pkg.apis.manager.v1beta1.python import api_pb2 + + +def call_validate(test_server, early_stopping_spec): + request = api_pb2.ValidateEarlyStoppingSettingsRequest(early_stopping_spec=early_stopping_spec) + validate_early_stopping_settings = test_server.invoke_unary_unary( + method_descriptor=(api_pb2.DESCRIPTOR + .services_by_name['EarlyStopping'] + .methods_by_name['ValidateEarlyStoppingSettings']), + invocation_metadata={}, + request=request, timeout=1) + + response, metadata, code, details = validate_early_stopping_settings.termination() + + return response, metadata, code, details